dragonflight/services/framecache
Zac Gaetano 97267aa857 fix(framecache): single-input streaming AVI muxer in fc_pipe (kills 2-pipe ffmpeg deadlock)
fc_pipe now muxes video + that frame's embedded audio into ONE streaming AVI
container on stdout, so ffmpeg reads a SINGLE input (-f avi -i pipe:0) instead
of a raw video pipe + a separate live audio FIFO. The two-live-pipe design
deadlocked ffmpeg (it stalled forever probing input 0); a single interleaved
stream removes that failure mode entirely.

fc_pipe.c:
  - New AVI mode (argv[3] == "--avi"/"avi"). Writes RIFF('AVI ') + LIST(hdrl)
    { avih + strl(vids: strh+BITMAPINFOHEADER UYVY 16bpp) + strl(auds:
    strh+WAVEFORMATEX PCM s16le 48k 2ch) } + LIST(movi) once, then per ring
    entry a '00dc' video chunk followed by a '01wb' audio chunk (LE sizes,
    even-pad). RIFF/movi sizes use the 0x7FFFFFFF streaming sentinel (pipe is
    unseekable); dwFlags has NO index bits. Frame-coupled by construction: both
    chunks come from the SAME ring entry in one read-loop iteration.
  - dwScale/dwRate = fps_den/fps_num (video) and nBlockAlign/nAvgBytesPerSec
    (audio). If a frame has audio_size 0, emits one frame-interval of silence
    (round(48000*fps_den/fps_num) samples) so the audio timeline tracks video
    and ffmpeg never starves on the audio demuxer.
  - Legacy raw video-only mode retained when no avi flag is given. The old
    split-stdout/audio-FIFO threaded path is removed (it was the deadlock).

fc_client.{h,c}:
  - Add fc_consumer_info() / fc_stream_info_t to expose the slot header's
    width/height/fps/audio params to fc_pipe for the AVI header.

capture-manager.js (_buildInputArgs deltacast/sdi framecache branch):
  - Spawn fc_pipe with "--avi" (no audio FIFO). Remove the mkfifo + audio-FIFO
    creation for this path.
  - inputArgs: ONE input  -thread_queue_size 512 -f avi [AUDIO_OFFSET_MS] -i pipe:0
    (was: -f rawvideo -i pipe:0  AND  -f s16le -ar 48000 -ac 2 -i <fifo>).
  - audioInputIndex 0, audioFifo null. Growing VC-3/HEVC builders already map
    [0:v] and audioMap 0🅰️0?; with one AVI input that resolves to 0:v / 0:a.

Validated on zampp3 against the LIVE deltacast-0-0 slot: fc_pipe --avi | ffmpeg
-f avi -i pipe:0 -> dnxhd/pcm_s24le MXF gives 360 video / 360 audio packets in
6.006s (no stall at 2 frames). A synthetic 1 kHz sine slot through the same
path yields mean_volume -9 dB / max -6 dB, proving the muxer carries real audio
end-to-end (the live SDI input currently carries no embedded audio, so the
bridge's silence fallback reads -91 dB — upstream of the muxer).
2026-06-05 14:06:35 +00:00
..
client fix(framecache): single-input streaming AVI muxer in fc_pipe (kills 2-pipe ffmpeg deadlock) 2026-06-05 14:06:35 +00:00
src fix(framecache): frame-coupled audio — video+audio in ONE ring entry 2026-06-05 12:46:22 +00:00
CMakeLists.txt fix(framecache): single-input streaming AVI muxer in fc_pipe (kills 2-pipe ffmpeg deadlock) 2026-06-05 14:06:35 +00:00
Dockerfile fix(framecache): install wget for healthcheck; make node-agent devices optional 2026-06-03 18:21:30 +00:00