Commit graph

2 commits

Author SHA1 Message Date
2f37119379 fix(framecache): frame-coupled audio — video+audio in ONE ring entry
Re-engineer the framecache so each video frame carries its own SDI-embedded
audio through ONE transport, eliminating the "audio ahead of video" offset at
the root: there is no longer a second independent audio buffer/FIFO that can
race ahead of video.

slot.h (FC_VERSION 1 -> 2):
  - Per ring entry data region is now [video frame_size][audio FC_MAX_AUDIO_BYTES].
  - fc_frame_t: the former _pad u32 is REUSED as audio_size (header still 24B).
  - Header gains audio_max_bytes / audio_rate / audio_channels (self-describing).
  - New fc_entry_stride()/fc_frame_audio() helpers; shm size includes audio.
  - Readers/writer check version == FC_VERSION and FAIL SAFE on mismatch so an
    old reader against a new writer (or vice-versa) refuses rather than misparses.

slot.c: populate audio header fields; add fc_slot_write_av(); version gate in open.
fc_client.[ch]: fc_frame_ref_t gains audio/audio_size; copy buffer holds
  video+audio; both copied from the SAME entry in one read -> frame-locked.
fc_pipe.c: now <slot_id> <wait_ms> <audio_fifo_path>; per ring entry writes
  video -> stdout AND that frame's audio -> the audio FIFO IN LOCKSTEP from one
  cursor read (no second buffer to drift). Auto-reattaches FIFO on EPIPE.

deltacast-bridge:
  - SILENT-AUDIO FIX: audio_extract_init now configures ONLY pAudioChannels[0]
    of group 0 as one stereo pair (Mode=STEREO, BufferFormat=AF_16, pData=buf),
    leaving pAudioChannels[1] ZEROED, exactly like Deltacast's own FFmpeg fork
    (libavdevice/videomaster_common.c init_audio_info). The prior JOINED code
    ALSO set channel[1].Mode/BufferFormat=STEREO/AF_16, declaring a second pair
    the signal does not carry -> VHD_SlotExtractAudio returned zero samples ->
    -91 dB silent audio. DataSize is (re)set to capacity before each extract.
  - VHD_SDI_SP_INTERFACE now set from the channel-detected interface
    (VHD_SDI_CP_INTERFACE) before StartStream, per the same fork — required for
    embedded-audio extraction on JOINED SDI streams.
  - fc_writer.[ch]: add fc_writer_write_av(); struct/stride bumped to v2.
  - video_thread (framecache path) extracts each frame's audio from the SAME
    locked JOINED slot and writes BOTH via fc_writer_write_av. Silence fallback
    at the source: a frame with no embedded audio gets one frame-interval of
    silence so the audio timeline length always equals the video timeline length.
  - The separate audio FIFO + audio_thread + apcm ring are retained ONLY for the
    legacy (-DLEGACY_FIFO / framecache-unreachable) fallback; on the primary
    framecache path the bridge no longer owns the audio FIFO.

capture-manager.js: deltacast/sdi framecache branch now CREATES the audio FIFO
  and passes its path to fc_pipe (argv[3]); ffmpeg keeps two raw inputs
  (rawvideo pipe:0 + s16le 48k input 1) but both are now fed frame-locked from
  the same ring entry. Stale-audio pre-flush retained as harmless safety.

All changes versioned; mismatched binaries refuse to attach (fail safe).
2026-06-05 12:46:22 +00:00
Wild Dragon Dev
0d479d043d feat(framecache): phase 2 — deltacast-bridge writes to shm ring
- fc_writer.h/fc_writer.c: new framecache slot writer module
  - Registers slot via POST /slots to framecache HTTP API on signal lock
  - Opens shm file returned by API (O_RDWR + mmap MAP_SHARED)
  - fc_writer_write(): atomic write_cursor advance + sem_post per frame
  - fc_writer_close(): DELETE /slots/:id + munmap + sem_close
  - HTTP calls via raw POSIX sockets (no libcurl dependency)
  - Parses host:port from FC_URL env var or --fc-url arg

- main.c changes:
  - PortState gains slot_id, fc_url, fc_writer fields
  - --fc-url CLI arg + FC_URL env var (default http://localhost:7435)
  - On signal lock: fc_writer_open() before thread launch;
    falls back to FIFO if framecache unreachable (fc_writer == NULL)
  - video_thread: shm path primary (fc_writer != NULL),
    FIFO path fallback (fc_writer == NULL or LEGACY_FIFO=1)
  - Format JSON now includes slot_id field for node-agent consumption
  - Cleanup: fc_writer_close() before VHD_CloseBoardHandle

- CMakeLists.txt:
  - Add fc_writer.c to build
  - Link rt (shm_open, sem_open)
  - LEGACY_FIFO option (OFF by default) for nodes without framecache

Audio thread unchanged — audio stays in FIFO (shm audio is roadmap).
2026-06-03 15:13:20 +00:00