-- An MPEG-2 elementary stream shows the frame a search names. testScripts/esFrames.m2v is twelve -- flat gray frames, frame k at luma 32 + 16k, coded as I, P, and B frames (IBBPBBIBBPBI), made by -- -- python3 -c "import sys; [sys.stdout.buffer.write(bytes([32 + 16 * k]) * 19200 + bytes([128]) * 9600) for k in range(12)]" | -- ffmpeg -f rawvideo -pix_fmt yuv420p -s 160x120 -r 25 -i - -c:v mpeg2video -g 6 -bf 2 -q:v 1 -f mpeg2video esFrames.m2v -- -- Such a stream times its I and P frames by decode time alone, and the decoder hands each one over a -- frame later than that: a search to frame k showed frame k - 1, a search to the first frame of a -- segment never seen showed nothing, and with B frames some searches landed far off. Whatever disc -- it was given, the scene runs itself again with the clip for a disc, searches to every frame out of -- order, and reads the picture back with vldpGetYUVPixel. Each check prints "ESFRAMES ok" or -- "ESFRAMES FAIL". dofile("Singe/Framework.singe") local CLIP = "testScripts/esFrames.m2v" local FRAMES = 12 local BASE = 32 -- Luma of frame 0 local STEP = 16 -- Luma added for each frame after it local SETTLE = 8 -- Frames a search is given to show local ORDER = { 5, 0, 11, 1, 7, 2, 10, 3, 9, 4, 8, 6, 0 } local frames = 0 local turn = 0 local due = 2 local failures = 0 local function check(name, ok, detail) if ok then debugPrint("ESFRAMES ok " .. name) else failures = failures + 1 debugPrint("ESFRAMES FAIL " .. name .. (detail and (" (" .. detail .. ")") or "")) end end function onOverlayUpdate() local luma = 0 local seen = 0 frames = frames + 1 overlayClear() if discGetFrameCount() ~= FRAMES then -- Not the clip yet: again, with the clip for a disc. if frames == 1 then scriptExecute({ SCRIPT = "testScripts/scene105.singe", VIDEO = CLIP }) end return OVERLAY_UPDATED end if frames < due then return OVERLAY_UPDATED end if turn > 0 then luma = vldpGetYUVPixel(overlayGetWidth() / 2, overlayGetHeight() / 2) seen = math.floor((luma - BASE) / STEP + 0.5) check("search to " .. ORDER[turn], (seen == ORDER[turn]) and (discGetFrame() == ORDER[turn]), "picture " .. seen .. ", disc " .. discGetFrame()) end turn = turn + 1 if turn > #ORDER then singeScreenshot("last") debugPrint(string.format("ESFRAMES RESULT failures=%d", failures)) singeQuit() else discSearch(ORDER[turn]) due = frames + SETTLE end return OVERLAY_UPDATED end