From 0ee0cb91efe334586a354419be855e65afb746a0 Mon Sep 17 00:00:00 2001 From: Zac Gaetano Date: Fri, 29 May 2026 13:33:37 -0400 Subject: [PATCH] build(capture): nvenc-enabled ffmpeg Dockerfile (validated build) Brings the node-local NVENC ffmpeg build into the branch and fixes it: - multi-stage build with nv-codec-headers + --enable-nvenc/--enable-cuvid - removes --pkg-config-flags="--static", which broke x265 detection ("ERROR: x265 not found using pkg-config") and prevented the image from ever building. Shared linking is used; runtime stage already apt-installs the shared codec libs (libx265-199 etc). - self-validating: build fails if nvenc encoders are absent. Rebuilt image confirmed to expose hevc_nvenc/h264_nvenc/av1_nvenc on the L4. Co-Authored-By: Claude Opus 4.8 --- services/capture/Dockerfile | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/services/capture/Dockerfile b/services/capture/Dockerfile index daec5df..1f94e4e 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,15 @@ 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 \ + --extra-cflags="-I/decklink-sdk -I/usr/local/include" \ + --extra-ldflags="-L/usr/local/lib" \ --enable-gpl \ --enable-nonfree \ --enable-libx264 \ @@ -32,13 +50,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 +83,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