- A recording killed mid-way had wrong timestamps in players: its fragmented MP4's header gives a
length of 0, and one cut short never gets the index a clean stop writes. modules/Screen_Record's
record_remux now copies every recording's packets, as they are, into a regular MP4 (one header
first with the length and every frame's index; faststart) before it goes into the library;
should that fail, the fragmented MP4 goes in as it was.
- Keyframes were every 60 frames, which, with frames written only on change, could span minutes
of time, and a crash could lose a fragment that long. One is now forced every 2 s of time
(forced-idr for NVENC and libx264).
- A crash's leftover no longer claims a region at 0, 0 in its capture.json.
- record-probe -remux IN OUT. Tests: a recording cut at its last fragment, as a crash cuts it,
goes in as a regular MP4 of the time before the cut.
- Checked on the recording that showed it: its MP4, cut mid-fragment, rewrites to 76 frames
(5.2 s) with positive frame durations. A 12 s still recording now fragments every ~2 s, and
the app killed 10 s into a recording leaves 8.1 s.
- modules/Screen_Record: a region of one screen to H.264 in a fragmented MP4. A capture thread
duplicates the screen (DuplicateOutput1, else DuplicateOutput) on a D3D11 device of its own on
the screen's adapter, copies the region on the GPU, reads it back through three staging
textures and draws the cursor in (colour, masked colour and monochrome shapes). An encoder
thread feeds FFmpeg: h264_nvenc, else h264_amf, h264_qsv, h264_mf, libx264, each tried in turn;
BGRA straight to NVENC, swscale to NV12 or YUV 4:2:0 (BT.709) for the rest. A frame is sent
when the screen or cursor changed and its turn on an fps schedule is due, with a repeat each
second of an unchanged screen; the encoder falling 8 frames behind drops the oldest. A lost
duplication (mode change, secure desktop) is made again and recording goes on. record_start
says fall_back when duplication cannot run (unsupported, too many, rotated screen). Regions
under 240 x 180 are refused, then sizes are rounded down to even; a process whose view of the
desktop is scaled is refused.
- tools/record_probe.jai (jai first.jai - record_probe): lists the screens, records a screen or
region and reports source, encoder, frames captured, sent, written and dropped, time per stage
and file size; -legacy, -cuda, -exclude-test, -animate, -snapshot DIR, -check FILE.
- On the RTX 5080 laptop: 60 s of 4K at 30 fps, 1802 frames, none dropped, 18 MB a minute; every
change kept at 60 fps; plain DuplicateOutput works when DPI aware; a CUDA context changes
nothing; WDA_EXCLUDEFROMCAPTURE is respected; QSV, Media Foundation and libx264 keep up too;
a recording killed mid-way still plays. The two-GPU failure was not reproduced: the screens are
on the NVIDIA GPU in this mode. The plan records the results.