From 68c8f47c8faa9f0737caf5bb8c540339bfbb3fe2 Mon Sep 17 00:00:00 2001 From: ZGaetano Date: Fri, 29 May 2026 00:51:56 -0400 Subject: [PATCH] feat(capture): rebuild ffmpeg w/ nv-codec-headers + NVENC/CUVID for All-Intra HEVC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The custom FFmpeg 7.1 in this image previously had NO nvenc — only prores_ks/dnxhd/libx264/libx265. The All-Intra HEVC ingest plan (docs/design/2026-05-29-all-intra-hevc-ingest.md §4.1) needs hevc_nvenc / h264_nvenc to offload the per-signal encode from CPU to the L4, so we rebuild ffmpeg's configure stage with: --enable-ffnvcodec --enable-nvenc --enable-cuvid nv-codec-headers (pinned n12.1.14.0) is cloned + installed before configure so ffmpeg picks up the ffnvcodec pkg-config. Full CUDA toolkit is omitted — only needed for GPU filters like yadif_cuda. Adds a sanity-check RUN that fails the build if hevc_nvenc/h264_nvenc don't appear in 'ffmpeg -encoders' so a broken NVENC build can't silently ship. Creates /live and /growing as empty dirs since the node-agent binds them at sidecar start. --- services/capture/Dockerfile | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/services/capture/Dockerfile b/services/capture/Dockerfile index daec5df..a9217da 100644 --- a/services/capture/Dockerfile +++ b/services/capture/Dockerfile @@ -1,4 +1,10 @@ -# ── Stage 1: Build FFmpeg with DeckLink support ───────────────────────────── +# ── Stage 1: Build FFmpeg with DeckLink + NVENC (HEVC/H264) support ───────── +# All-Intra HEVC NVENC is the master codec for growing-file ingest (see +# docs/design/2026-05-29-all-intra-hevc-ingest.md). This stage gets the +# nv-codec-headers (header-only, no driver / no full CUDA toolkit needed) +# so ffmpeg's configure can light up hevc_nvenc / h264_nvenc / cuvid. +# At runtime, /dev/nvidia* + the host driver libs (via the NVIDIA Container +# Toolkit) supply the actual encoder. FROM debian:bookworm AS ffmpeg-builder RUN apt-get update && apt-get install -y --no-install-recommends \ @@ -13,6 +19,11 @@ COPY sdk/ /decklink-sdk/ COPY patch_decklink.py /patch_decklink.py COPY decklink-sdk16.patch /decklink-sdk16.patch +# nv-codec-headers — just the ffnvcodec public headers + a pkg-config file. +# Pin to a tag known to work with FFmpeg 7.1 (n12.x series). +RUN git clone --depth=1 --branch n12.1.14.0 https://github.com/FFmpeg/nv-codec-headers.git /nv-codec-headers \ + && make -C /nv-codec-headers PREFIX=/usr/local install + # Pull FFmpeg 7.1 source RUN git clone --depth=1 --branch release/7.1 https://git.ffmpeg.org/ffmpeg.git /ffmpeg @@ -20,8 +31,16 @@ RUN git clone --depth=1 --branch release/7.1 https://git.ffmpeg.org/ffmpeg.git / RUN python3 /patch_decklink.py WORKDIR /ffmpeg +# NVENC adds: --enable-nvenc (encoder), --enable-cuvid (decoder), --enable-ffnvcodec. +# We deliberately do NOT enable --enable-cuda-nvcc / --enable-libnpp here — those +# require the full ~3GB CUDA toolkit and are only needed for GPU filters like +# yadif_cuda / scale_cuda. If §5's GPU deinterlace stretch goal goes ahead, +# rebuild this image off nvidia/cuda:12.x-devel and flip those flags on. RUN ./configure \ --prefix=/usr/local \ + --pkg-config-flags="--static" \ + --extra-cflags="-I/decklink-sdk -I/usr/local/include" \ + --extra-ldflags="-L/usr/local/lib" \ --enable-gpl \ --enable-nonfree \ --enable-libx264 \ @@ -32,13 +51,20 @@ RUN ./configure \ --enable-libsrt \ --enable-libzmq \ --enable-decklink \ - --extra-cflags="-I/decklink-sdk" \ + --enable-ffnvcodec \ + --enable-nvenc \ + --enable-cuvid \ --disable-doc \ --disable-debug \ --disable-ffplay \ && make -j$(nproc) \ && make install +# Sanity-check: hevc_nvenc and h264_nvenc must be present in the encoder list, +# otherwise the resulting image is useless for the All-Intra HEVC pipeline. +RUN /usr/local/bin/ffmpeg -hide_banner -encoders 2>&1 | grep -E 'nvenc' \ + || (echo 'FATAL: nvenc encoders missing from ffmpeg build' && exit 1) + # ── Stage 2: Runtime image ─────────────────────────────────────────────────── FROM node:20-bookworm @@ -58,6 +84,11 @@ COPY lib/libDeckLinkAPI.so /usr/lib/libDeckLinkAPI.so COPY lib/libDeckLinkPreviewAPI.so /usr/lib/libDeckLinkPreviewAPI.so RUN ldconfig +# Mount points the recorder lifecycle expects to exist. +# /live — HLS preview output (bound from host LIVE_DIR by node-agent) +# /growing — growing-file master output (bound from host /mnt/NVME/MAM/growing) +RUN mkdir -p /live /growing + WORKDIR /app COPY package*.json ./ RUN npm install --omit=dev