dragonflight/services
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
..
capture fix(bridge): JOINED single-slot capture — embed audio with each video frame 2026-06-05 12:15:47 +00:00
framecache fix: declare all slot functions in slot.h to prevent 64-bit pointer truncation 2026-06-03 20:16:35 +00:00
mam-api feat: per-recorder audio_offset_ms dial for A/V alignment 2026-06-05 11:24:11 +00:00
node-agent fix(capture): pin NVENC to a GPU with ffmpeg -gpu N (privileged bypasses env) 2026-06-04 16:07:59 +00:00
playout feat(playout): redesigned MCR screen + SCTE-35 end-to-end 2026-05-31 19:58:02 -04:00
premiere-plugin diag(premiere-plugin): v1.2.5 — no-op IIFE writes to Documents/ + reports lf.open result 2026-05-28 03:59:40 +00:00
premiere-plugin-uxp fix(uxp): remove broken v2.2.3 ccx — stay on v2.2.2 2026-06-03 16:07:32 +00:00
web-ui feat: per-recorder audio_offset_ms dial for A/V alignment 2026-06-05 11:24:11 +00:00
worker fix(promotion): heal dead CIFS mounts + retry file lookup; reset orphans on failure 2026-06-05 11:45:10 +00:00