dragonflight/services/capture
ZGaetano 80d8b15e8c fix(bridge): JOINED single-slot capture — embed audio with each video frame
Re-architect the Deltacast bridge from two independently-buffered VHD
streams (DISJOINED_VIDEO + a separate DISJOINED_ANC audio stream) to a
single VHD_SDI_STPROC_JOINED RX stream per port. Each locked slot now
carries both the video frame and that frame's SDI-embedded audio, so
audio is extracted (VHD_SlotExtractAudio) from the SAME slot the video
came from — eliminating the constant "audio ahead of video" offset at
its root instead of papering over it with --audio-delay-ms.

This mirrors Deltacast's own FFmpeg fork (libavdevice/videomaster_common.c):
open JOINED, then per frame LockSlot -> GetSlotBuffer(VIDEO) ->
SlotExtractAudio(same slot) -> Unlock.

Changes (main.c):
- main(): RX stream opened with VHD_SDI_STPROC_JOINED (was
  VHD_SDI_STPROC_DISJOINED_VIDEO). SDI interface still propagated so
  audio extraction yields real samples.
- video_thread(): becomes the single per-frame consumer. After locking
  each JOINED slot it extracts the embedded audio (audio_extract_slot)
  and pushes de-interleaved s16le stereo PCM into a new lock-free SPSC
  ring (ApcmRing), then writes the video frame to the framecache ring
  (or legacy video FIFO). Audio is extracted on BOTH the framecache and
  legacy-FIFO paths, before the video packing check so it is never
  dropped on a rare packing mismatch.
- audio_thread(): no longer opens any VHD stream. It is now purely the
  audio-FIFO sink: drains the ApcmRing into the named audio FIFO
  (ffmpeg input 1), flushes the ring to the live edge on reader attach,
  survives ffmpeg restarts (EPIPE -> reopen), and emits wall-clock-paced
  silence when the ring is empty (preserves the silence-fallback when the
  signal carries no embedded audio).
- Audio stays 48 kHz stereo s16le to match ffmpeg's expectations.
- --audio-delay-ms / FC_AUDIO_DELAY_MS retained but now unnecessary
  (should be left at 0); kept for compatibility / emergency tuning.

Compiles clean (only pre-existing %lu/ULONG format warnings in main()).
Not installed, not deployed — branch only.
2026-06-05 12:15:47 +00:00
..
decklink-bridge fix(decklink-bridge): prevent redundant fc_writer_open loops via last_format tracking 2026-06-04 01:10:47 +00:00
deltacast-bridge fix(bridge): JOINED single-slot capture — embed audio with each video frame 2026-06-05 12:15:47 +00:00
sdk chore(capture): commit Blackmagic DeckLink SDK 16.0 Linux headers 2026-05-31 18:07:12 -04:00
src feat: per-recorder audio_offset_ms dial for A/V alignment 2026-06-05 11:24:11 +00:00
.dockerignore build(capture): add .dockerignore to keep stale bridge build/ out of image context 2026-06-02 15:23:03 +00:00
decklink-sdk16.patch fix(capture): proper SDK 16 patch via upstream FFmpeg master diff 2026-05-22 00:53:03 +00:00
Dockerfile revert(capture): Dockerfile copy paths to root-relative for compose build 2026-06-04 00:39:24 +00:00
package.json add services/capture/package.json 2026-04-07 21:58:29 -04:00
patch_decklink.py fix(capture): proper SDK 16 patch via upstream FFmpeg master diff 2026-05-22 00:53:03 +00:00