mirror of https://github.com/odrling/Aegisub
Merge branches 'lua_api' and 'misc' into feature
This commit is contained in:
commit
dcca721543
|
@ -40,7 +40,7 @@ Returns: number
|
||||||
|
|
||||||
Get RGB pixel value at a certain position of frame object.
|
Get RGB pixel value at a certain position of frame object.
|
||||||
|
|
||||||
function frame:frame:getPixel(x, y)
|
function frame:getPixel(x, y)
|
||||||
|
|
||||||
@x (number)
|
@x (number)
|
||||||
Pixel to retrieve on the x-axis
|
Pixel to retrieve on the x-axis
|
||||||
|
@ -48,8 +48,10 @@ function frame:frame:getPixel(x, y)
|
||||||
@y (number)
|
@y (number)
|
||||||
Pixel to retrieve on the y-axis
|
Pixel to retrieve on the y-axis
|
||||||
|
|
||||||
Returns: number
|
Returns: 3 values, all numbers
|
||||||
Integer value representing the RGB pixel value.
|
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&"
|
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"));
|
auto framePtr = static_cast<std::shared_ptr<VideoFrame>*>(luaL_checkudata(L, 1, "VideoFrame"));
|
||||||
return *framePtr;
|
return framePtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FrameWidth(lua_State *L) {
|
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);
|
push_value(L, frame->width);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FrameHeight(lua_State *L) {
|
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);
|
push_value(L, frame->height);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FramePixel(lua_State *L) {
|
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 x = lua_tointeger(L, -2);
|
||||||
size_t y = lua_tointeger(L, -1);
|
size_t y = lua_tointeger(L, -1);
|
||||||
lua_pop(L, 2);
|
lua_pop(L, 2);
|
||||||
|
@ -227,16 +227,17 @@ namespace {
|
||||||
|
|
||||||
size_t pos = y * frame->pitch + x * 4;
|
size_t pos = y * frame->pitch + x * 4;
|
||||||
// VideoFrame is stored as BGRA, but we want to return RGB
|
// 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, frame->data[pos+2]);
|
||||||
push_value(L, pixelValue);
|
push_value(L, frame->data[pos+1]);
|
||||||
|
push_value(L, frame->data[pos]);
|
||||||
} else {
|
} else {
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
}
|
}
|
||||||
return 1;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FramePixelFormatted(lua_State *L) {
|
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 x = lua_tointeger(L, -2);
|
||||||
size_t y = lua_tointeger(L, -1);
|
size_t y = lua_tointeger(L, -1);
|
||||||
lua_pop(L, 2);
|
lua_pop(L, 2);
|
||||||
|
@ -255,9 +256,19 @@ namespace {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FrameDestory(lua_State *L) {
|
int FrameData(lua_State *L) {
|
||||||
std::shared_ptr<VideoFrame> frame = check_VideoFrame(L);
|
std::shared_ptr<VideoFrame> frame = *check_VideoFrame(L);
|
||||||
frame.~shared_ptr<VideoFrame>();
|
|
||||||
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,7 +290,8 @@ namespace {
|
||||||
{"height", FrameHeight},
|
{"height", FrameHeight},
|
||||||
{"getPixel", FramePixel},
|
{"getPixel", FramePixel},
|
||||||
{"getPixelFormatted", FramePixelFormatted},
|
{"getPixelFormatted", FramePixelFormatted},
|
||||||
{"__gc", FrameDestory},
|
{"data", FrameData},
|
||||||
|
{"__gc", FrameDestroy},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -205,9 +205,14 @@ struct GridColumnStartTime final : GridColumnTime {
|
||||||
|
|
||||||
int Width(const agi::Context *c, WidthHelper &helper) const override {
|
int Width(const agi::Context *c, WidthHelper &helper) const override {
|
||||||
agi::Time max_time = max_value(&AssDialogue::Start, c->ass->Events);
|
agi::Time max_time = max_value(&AssDialogue::Start, c->ass->Events);
|
||||||
if (!by_frame)
|
std::string value = by_frame ? std::to_string(c->videoController->FrameAtTime(max_time, agi::vfr::START)) : max_time.GetAssFormatted();
|
||||||
return helper(max_time.GetAssFormatted());
|
|
||||||
return helper(std::to_wstring(c->videoController->FrameAtTime(max_time, agi::vfr::START)));
|
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 {
|
int Width(const agi::Context *c, WidthHelper &helper) const override {
|
||||||
agi::Time max_time = max_value(&AssDialogue::End, c->ass->Events);
|
agi::Time max_time = max_value(&AssDialogue::End, c->ass->Events);
|
||||||
if (!by_frame)
|
std::string value = by_frame ? std::to_string(c->videoController->FrameAtTime(max_time, agi::vfr::END)) : max_time.GetAssFormatted();
|
||||||
return helper(max_time.GetAssFormatted());
|
|
||||||
return helper(std::to_wstring(c->videoController->FrameAtTime(max_time, agi::vfr::END)));
|
for (char &c : value) {
|
||||||
|
if (c >= '0' && c <= '9')
|
||||||
|
c = '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
return helper(value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue