You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(compositor): macOS export encodes — first MP4 out of the Metal engine
Export had never produced a frame on macOS. Three things stood between it and one.
**`send_composited` sent an empty frame.** It called `render_nv12()` and then handed
the encoder `self.sw` — a buffer nothing had ever written — with no pts. It now reads
the composed NV12 back into the frame's planes via `read_nv12_scaled` and stamps the
timestamp. The old body even carried `let _ = w; let _ = h; let _ = pts;`, which is
the shape of code written to satisfy a signature rather than to do the work.
**The clip walk was hand-rolled.** It decoded 1:1 while advancing `t` by `1/fps`, so
it ignored speed regions, per-clip scene windowing and the cursor. That is precisely
the slow-motion truncation `walk_composited_timeline`'s own doc records having cost
once — "a GIF driven by its own loop is how the bug happened". It now calls the shared
walk, so MP4, GIF and both backends agree on which source frame belongs at output
frame N.
**The encoder was configured for a pool that never existed.** The candidate list asked
`h264_videotoolbox` for `AV_PIX_FMT_VIDEOTOOLBOX` and built a fresh `hw_frames_ctx`
per export. But `ffmpeg -h encoder=h264_videotoolbox` reports
`videotoolbox_vld nv12 yuv420p`: it takes SOFTWARE NV12 and uploads internally — and
NV12 is exactly what the compositor produces. The candidate now asks for NV12 and the
whole `hw_frames_ctx` construction is deleted. An entire layer of hardware-pool
plumbing that had never run, replaced by the format both sides already speak.
Measured on an M-series Mac against a real recording: 120 frames at **73 fps**,
1280x720, `h264_videotoolbox`. `ffmpeg -f null -` decodes it clean, and the frames
carry the whole composition — background, padding, rounded corners, drop shadow and
the circular PiP camera.
Still absent from the export: audio (`audio.rs` is portable and compiles, but the
muxing path has not been exercised on macOS).
0 commit comments