From f52b69949378941558aafc7fcab6989632d2715d Mon Sep 17 00:00:00 2001 From: arch1t3cht Date: Tue, 20 Feb 2024 15:02:59 +0100 Subject: [PATCH] lua: Add function to get raw frame data This can be useful when scripts want to read the entire frame and pass it on somewhere else (say, write it to a file or use some library function on it). --- automation/v4-docs/get-frame.txt | 22 ++++++++++++++++++++++ src/auto4_lua.cpp | 11 +++++++++++ 2 files changed, 33 insertions(+) diff --git a/automation/v4-docs/get-frame.txt b/automation/v4-docs/get-frame.txt index 99342ac4a..ad60b70d0 100644 --- a/automation/v4-docs/get-frame.txt +++ b/automation/v4-docs/get-frame.txt @@ -69,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. + +--- diff --git a/src/auto4_lua.cpp b/src/auto4_lua.cpp index 449a27989..f6632971d 100644 --- a/src/auto4_lua.cpp +++ b/src/auto4_lua.cpp @@ -259,6 +259,16 @@ namespace { return 1; } + int FrameData(lua_State *L) { + std::shared_ptr 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 *frame = check_VideoFrame(L); frame->~shared_ptr(); @@ -283,6 +293,7 @@ namespace { {"height", FrameHeight}, {"getPixel", FramePixel}, {"getPixelFormatted", FramePixelFormatted}, + {"data", FrameData}, {"__gc", FrameDestroy}, {NULL, NULL} };