Merge branches 'lua_api' and 'misc' into feature
This commit is contained in:
commit
dcca721543
3 changed files with 68 additions and 22 deletions
|
@ -40,7 +40,7 @@ Returns: number
|
|||
|
||||
Get RGB pixel value at a certain position of frame object.
|
||||
|
||||
function frame:frame:getPixel(x, y)
|
||||
function frame:getPixel(x, y)
|
||||
|
||||
@x (number)
|
||||
Pixel to retrieve on the x-axis
|
||||
|
@ -48,8 +48,10 @@ function frame:frame:getPixel(x, y)
|
|||
@y (number)
|
||||
Pixel to retrieve on the y-axis
|
||||
|
||||
Returns: number
|
||||
Integer value representing the RGB pixel value.
|
||||
Returns: 3 values, all numbers
|
||||
1. R value of the pixel
|
||||
2. G value of the pixel
|
||||
3. B value of the pixel
|
||||
|
||||
---
|
||||
|
||||
|
@ -67,3 +69,25 @@ Returns: string
|
|||
String in ASS format representing the pixel value. e.g. "&H0073FF&"
|
||||
|
||||
---
|
||||
|
||||
Get raw BGRA (alpha being irrelevant) data of frame object, whose pixel values
|
||||
can then be accessed via LuaJIT's FFI.
|
||||
|
||||
The frame data is valid until the frame object is garbage-collected.
|
||||
|
||||
Example usage (which does not account for flipped frames for simplicity)
|
||||
|
||||
data, pitch = frame:data()
|
||||
buf = require("ffi").cast("unsigned char *", data)
|
||||
-- Get the R value of the pixel at coordinates (42, 34)
|
||||
pix_val = buf[34 * pitch + 4 * 42 + 2]
|
||||
|
||||
function frame:data()
|
||||
|
||||
Returns: 3 values - a lightuserdata, a number, and a boolean
|
||||
1. Lightuserdata object which can be cast to "unsigned char *" via ffi.cast, a pointer
|
||||
to the raw frame data.
|
||||
2. The pitch of the frame data.
|
||||
3. Whether the frame is flipped upside-down.
|
||||
|
||||
---
|
||||
|
|
|
@ -198,25 +198,25 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<VideoFrame> check_VideoFrame(lua_State *L) {
|
||||
std::shared_ptr<VideoFrame> *check_VideoFrame(lua_State *L) {
|
||||
auto framePtr = static_cast<std::shared_ptr<VideoFrame>*>(luaL_checkudata(L, 1, "VideoFrame"));
|
||||
return *framePtr;
|
||||
return framePtr;
|
||||
}
|
||||
|
||||
int FrameWidth(lua_State *L) {
|
||||
std::shared_ptr<VideoFrame> frame = check_VideoFrame(L);
|
||||
std::shared_ptr<VideoFrame> frame = *check_VideoFrame(L);
|
||||
push_value(L, frame->width);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int FrameHeight(lua_State *L) {
|
||||
std::shared_ptr<VideoFrame> frame = check_VideoFrame(L);
|
||||
std::shared_ptr<VideoFrame> frame = *check_VideoFrame(L);
|
||||
push_value(L, frame->height);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int FramePixel(lua_State *L) {
|
||||
std::shared_ptr<VideoFrame> frame = check_VideoFrame(L);
|
||||
std::shared_ptr<VideoFrame> frame = *check_VideoFrame(L);
|
||||
size_t x = lua_tointeger(L, -2);
|
||||
size_t y = lua_tointeger(L, -1);
|
||||
lua_pop(L, 2);
|
||||
|
@ -227,16 +227,17 @@ namespace {
|
|||
|
||||
size_t pos = y * frame->pitch + x * 4;
|
||||
// VideoFrame is stored as BGRA, but we want to return RGB
|
||||
int pixelValue = frame->data[pos+2] * 65536 + frame->data[pos+1] * 256 + frame->data[pos];
|
||||
push_value(L, pixelValue);
|
||||
push_value(L, frame->data[pos+2]);
|
||||
push_value(L, frame->data[pos+1]);
|
||||
push_value(L, frame->data[pos]);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
return 1;
|
||||
return 3;
|
||||
}
|
||||
|
||||
int FramePixelFormatted(lua_State *L) {
|
||||
std::shared_ptr<VideoFrame> frame = check_VideoFrame(L);
|
||||
std::shared_ptr<VideoFrame> frame = *check_VideoFrame(L);
|
||||
size_t x = lua_tointeger(L, -2);
|
||||
size_t y = lua_tointeger(L, -1);
|
||||
lua_pop(L, 2);
|
||||
|
@ -255,9 +256,19 @@ namespace {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int FrameDestory(lua_State *L) {
|
||||
std::shared_ptr<VideoFrame> frame = check_VideoFrame(L);
|
||||
frame.~shared_ptr<VideoFrame>();
|
||||
int FrameData(lua_State *L) {
|
||||
std::shared_ptr<VideoFrame> frame = *check_VideoFrame(L);
|
||||
|
||||
push_value(L, frame->data.data());
|
||||
push_value(L, frame->pitch);
|
||||
push_value(L, frame->flipped);
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
int FrameDestroy(lua_State *L) {
|
||||
std::shared_ptr<VideoFrame> *frame = check_VideoFrame(L);
|
||||
frame->~shared_ptr<VideoFrame>();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -279,7 +290,8 @@ namespace {
|
|||
{"height", FrameHeight},
|
||||
{"getPixel", FramePixel},
|
||||
{"getPixelFormatted", FramePixelFormatted},
|
||||
{"__gc", FrameDestory},
|
||||
{"data", FrameData},
|
||||
{"__gc", FrameDestroy},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
|
|
@ -205,9 +205,14 @@ struct GridColumnStartTime final : GridColumnTime {
|
|||
|
||||
int Width(const agi::Context *c, WidthHelper &helper) const override {
|
||||
agi::Time max_time = max_value(&AssDialogue::Start, c->ass->Events);
|
||||
if (!by_frame)
|
||||
return helper(max_time.GetAssFormatted());
|
||||
return helper(std::to_wstring(c->videoController->FrameAtTime(max_time, agi::vfr::START)));
|
||||
std::string value = by_frame ? std::to_string(c->videoController->FrameAtTime(max_time, agi::vfr::START)) : max_time.GetAssFormatted();
|
||||
|
||||
for (char &c : value) {
|
||||
if (c >= '0' && c <= '9')
|
||||
c = '0';
|
||||
}
|
||||
|
||||
return helper(value);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -223,9 +228,14 @@ struct GridColumnEndTime final : GridColumnTime {
|
|||
|
||||
int Width(const agi::Context *c, WidthHelper &helper) const override {
|
||||
agi::Time max_time = max_value(&AssDialogue::End, c->ass->Events);
|
||||
if (!by_frame)
|
||||
return helper(max_time.GetAssFormatted());
|
||||
return helper(std::to_wstring(c->videoController->FrameAtTime(max_time, agi::vfr::END)));
|
||||
std::string value = by_frame ? std::to_string(c->videoController->FrameAtTime(max_time, agi::vfr::END)) : max_time.GetAssFormatted();
|
||||
|
||||
for (char &c : value) {
|
||||
if (c >= '0' && c <= '9')
|
||||
c = '0';
|
||||
}
|
||||
|
||||
return helper(value);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue