Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions benchmarking/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ RUN apt-get update \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

# Add video benchmark codec support to the benchmark image.
RUN bash /opt/Curator/docker/common/install_h264_support.sh --with-libopenh264

# Ensure all extras and dependency groups (including test) are synced
RUN cd /opt/Curator \
&& uv sync --extra all --all-groups \
Expand Down
8 changes: 8 additions & 0 deletions benchmarking/nightly-benchmark.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,7 @@ entries:
--video-dir={dataset:videos,mp4}
--model-dir={dataset:videos_model_weights,files}
--video-limit=1000
--transcode-encoder=libopenh264
timeout_s: 800
sink_data:
- name: slack
Expand All @@ -900,6 +901,7 @@ entries:
--video-dir={dataset:videos,mp4}
--model-dir={dataset:videos_model_weights,files}
--video-limit=1000
--transcode-encoder=libopenh264
timeout_s: 800
sink_data:
- name: slack
Expand All @@ -923,6 +925,7 @@ entries:
--no-generate-embeddings
--video-dir={dataset:videos,mp4}
--video-limit=1000
--transcode-encoder=libopenh264
timeout_s: 400
sink_data:
- name: slack
Expand All @@ -947,6 +950,7 @@ entries:
--no-generate-embeddings
--video-dir={dataset:videos,mp4}
--video-limit=1000
--transcode-encoder=libopenh264
timeout_s: 800
sink_data:
- name: slack
Expand Down Expand Up @@ -974,6 +978,7 @@ entries:
--no-generate-embeddings
--enhance-captions
--video-limit=256
--transcode-encoder=libopenh264
timeout_s: 1800
sink_data:
- name: slack
Expand All @@ -1000,6 +1005,7 @@ entries:
--no-generate-embeddings
--enhance-captions
--video-limit=256
--transcode-encoder=libopenh264
timeout_s: 1800
sink_data:
- name: slack
Expand Down Expand Up @@ -1089,6 +1095,7 @@ entries:
--aesthetic-threshold=3.5
--transnetv2-frame-decoder-mode ffmpeg_cpu
--video-limit=1000
--transcode-encoder=libopenh264
timeout_s: 800
sink_data:
- name: slack
Expand Down Expand Up @@ -1116,6 +1123,7 @@ entries:
--aesthetic-threshold=3.5
--transnetv2-frame-decoder-mode ffmpeg_cpu
--video-limit=1000
--transcode-encoder=libopenh264
timeout_s: 1800
sink_data:
- name: slack
Expand Down
2 changes: 1 addition & 1 deletion benchmarking/tools/ci_benchmark_launcher.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ apt-get update -qq && apt-get install -y --no-install-recommends lynx
if [[ "${ENTRY_NAME}" == audio_* ]]; then
apt-get install -y --no-install-recommends ffmpeg
elif [[ "${ENTRY_NAME}" == video_* ]]; then
bash /opt/Curator/docker/common/install_ffmpeg.sh
bash /opt/Curator/docker/common/install_h264_support.sh --with-libopenh264
fi

cd /opt/Curator
Expand Down
79 changes: 45 additions & 34 deletions docker/common/install_ffmpeg.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,62 +31,73 @@ done
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y \
libcrypt-dev \
autoconf \
automake \
build-essential \
ca-certificates \
cmake \
libaom-dev \
libass-dev \
libdav1d-dev \
libdrm-dev \
libfreetype6-dev \
libgnutls28-dev \
libcrypt-dev \
libnuma-dev \
libopenh264-dev \
libtool \
libva-dev \
libvorbis-dev \
libvpx-dev \
libwebp-dev \
nasm \
pkg-config \
vainfo \
wget \
yasm \
zlib1g-dev

# Install NVCODEC
# Install nv-codec-headers (NVENC + NVDEC bridge to the NVIDIA driver)
wget -O /tmp/nv-codec-headers.tar.gz https://github.com/FFmpeg/nv-codec-headers/releases/download/n${NVCODEC_VERSION}/nv-codec-headers-${NVCODEC_VERSION}.tar.gz
tar xzvf /tmp/nv-codec-headers.tar.gz -C /tmp/
cd /tmp/nv-codec-headers-${NVCODEC_VERSION}
make
make install

# Install FFMPEG
wget -O /tmp/ffmpeg-snapshot.tar.bz2 https://www.ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.bz2
# Build FFmpeg ${FFMPEG_VERSION} from the upstream release tarball:
# - --disable-everything strips ALL components by default (encoders,
# decoders, muxers, demuxers, parsers, bsfs, hwaccels, filters, protocols)
# and we re-enable only what's needed.
# - --enable-version3 selects LGPLv3+.
# - Encoders: only NVENC (h264/hevc/av1) and libvpx-vp9 + rawvideo.
# - Decoders: NVDEC variants for h264/hevc/av1/vp9 + software vp8/vp9 +
# mpeg1/2/4 + libvpx_vp9 + rawvideo. NO software h264/hevc/av1.
# - Shared-linked: installs libav*.so to /usr/local/lib for command-line
# tools and any optional source-built consumers.
cd /tmp
wget -O /tmp/ffmpeg-snapshot.tar.bz2 "https://www.ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.bz2"
tar xjvf /tmp/ffmpeg-snapshot.tar.bz2 -C /tmp/
cd /tmp/ffmpeg-${FFMPEG_VERSION}
PATH="/usr/local/cuda/bin:$PATH" ./configure \
--prefix=/usr/local \
--enable-nonfree \
--enable-cuda-nvcc \
--enable-libnpp \
--enable-libopenh264 \
--enable-libaom \
--enable-libdav1d \
--enable-libvorbis \
--enable-libvpx \
--enable-libwebp \
--enable-vaapi \
--extra-cflags=-I/usr/local/cuda/include \
--extra-ldflags=-L/usr/local/cuda/lib64 \
--extra-libs=-lpthread \
--extra-libs=-lm \
--disable-static \
cd "/tmp/ffmpeg-${FFMPEG_VERSION}"
PKG_CONFIG_PATH="/usr/local/lib/pkgconfig" ./configure \
--prefix="/usr/local" \
--enable-shared \
--disable-static \
--extra-cflags="-I/usr/local/cuda/include" \
--extra-ldflags="-L/usr/local/cuda/lib64" \
--extra-libs="-lpthread -lm" \
--ld="g++" \
--enable-version3 \
--disable-everything \
--disable-network \
--disable-doc \
--disable-debug
--disable-ffplay \
--disable-vaapi \
--disable-vdpau \
--disable-dxva2 \
--disable-libdrm \
--enable-encoder=rawvideo,libvpx_vp9,h264_nvenc,hevc_nvenc,av1_nvenc \
--enable-decoder=rawvideo,libvpx_vp9,vp9,vp8,h264_cuvid,hevc_cuvid,av1_cuvid,mpeg1video,mpeg2video,mpeg4 \
--enable-muxer=mp4,rawvideo,image2pipe \
--enable-demuxer=mov,mp4,m4a,3gp,3g2,mj2,avi,matroska,webm,image2,image2pipe \
--enable-parser=h264,hevc,av1,vp8,vp9 \
--enable-bsf=h264_mp4toannexb,hevc_mp4toannexb \
--enable-protocol=file,pipe \
--enable-filter=scale,format,null,copy \
--enable-libvpx \
--enable-cuda \
--enable-cuvid \
--enable-nvdec \
--enable-nvenc \
--enable-ffnvcodec
make -j$(nproc)
make install
ldconfig
Expand Down
178 changes: 178 additions & 0 deletions docker/common/install_h264_support.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
#!/bin/bash
# Copyright (c) 2026, NVIDIA CORPORATION. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Opt-in installer that adds software h264/hevc/av1 decoder support to a
# Curator container by building FFmpeg from source with those decoders added
# to the strict allowlist.
#
# The release Curator image may omit system ffmpeg entirely. When installed
# with install_ffmpeg.sh, Curator's strict FFmpeg build routes h264/hevc/av1
# decode through NVDEC only. That breaks ffprobe-based metadata extraction in
# CPU-only Ray actors (VideoReader, ClipWriter), which is why this opt-in
# exists.
#
# Run inside a running container, e.g.:
# docker exec <container> bash /opt/Curator/docker/common/install_h264_support.sh
#
# Behaviour:
# - Builds FFmpeg from the upstream release tarball, same version as install_ffmpeg.sh,
# with the existing allowlist plus --enable-decoder=h264,hevc,av1.
# - Optionally also enables the libopenh264 software h264 ENCODER (Cisco's
# free-license OpenH264 binary; opt-in via --with-libopenh264).
# - Replaces /usr/local/bin/{ffmpeg,ffprobe} in place.
# - Default stays LGPLv3 (only FFmpeg-internal native decoders); with
# --with-libopenh264 the resulting binary additionally links Cisco's
# OpenH264 (BSD-2-Clause; see https://www.openh264.org/BINARY_LICENSE.txt).
# - Takes ~5-10 min.
#
# Keep FFMPEG_VERSION and NVCODEC_VERSION in sync with docker/common/install_ffmpeg.sh.

set -euo pipefail

FFMPEG_VERSION=8.0.1
NVCODEC_VERSION=12.1.14.0
WITH_LIBOPENH264=0

usage() {
cat <<'EOF'
Usage: install_h264_support.sh [--with-libopenh264] [--FFMPEG_VERSION=<version>]
[--NVCODEC_VERSION=<ver>]

Builds FFmpeg from source with software h264/hevc/av1 decoders enabled.

Options:
--with-libopenh264 Also enable the libopenh264 software h264 ENCODER
(Cisco's OpenH264 binary; required by Curator's
--transcode-encoder=libopenh264 path).
--FFMPEG_VERSION=<version> FFmpeg upstream release version (default: 8.0.1).
--NVCODEC_VERSION=<ver> nv-codec-headers release version (default: 12.1.14.0).
-h, --help Show this help.

License notice:
Default mode enables only FFmpeg's internal h264/hevc/av1 decoders (LGPL).
With --with-libopenh264 the build additionally links Cisco's OpenH264
binary (BSD-2-Clause + Cisco-distributed binary license; see
https://www.openh264.org/BINARY_LICENSE.txt). By running this script you
are responsible for any license obligations the resulting binaries impose
on your distribution.
EOF
}

for arg in "$@"; do
case $arg in
--with-libopenh264) WITH_LIBOPENH264=1 ;;
--FFMPEG_VERSION=?*) FFMPEG_VERSION="${arg#*=}" ;;
--NVCODEC_VERSION=?*) NVCODEC_VERSION="${arg#*=}" ;;
-h|--help) usage; exit 0 ;;
*) echo "Unknown argument: $arg" >&2; usage >&2; exit 2 ;;
esac
done

if [ "$(id -u)" -ne 0 ]; then
echo "ERROR: must be run as root inside the container." >&2
exit 1
fi

echo "==> install_h264_support.sh: rebuilding ffmpeg ${FFMPEG_VERSION}"
echo " Decoders added: h264, hevc, av1 (software)"
if [ "$WITH_LIBOPENH264" -eq 1 ]; then
echo " Encoder added: libopenh264 (Cisco OpenH264 binary)"
fi
echo " NOTE: This expands the container's codec footprint beyond Curator's"
echo " default strict FFmpeg allowlist. License obligations of the resulting binaries"
echo " are the user's responsibility."
echo
Comment on lines +90 to +96

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 NOTE message always prints regardless of --with-libopenh264

The three echo lines for the NOTE (lines 93–95) are outside the if [ "$WITH_LIBOPENH264" -eq 1 ] block — the fi closes it on line 91. The indentation is misleading: the message about "License obligations of the resulting binaries are the user's responsibility" fires unconditionally, even when running without --with-libopenh264. This directly contradicts usage(), which clearly states the default (LGPL-only decoders) path has no special license obligations beyond LGPL itself. Users who run the script in its default mode will receive an alarming license warning that doesn't apply to them.


export DEBIAN_FRONTEND=noninteractive
apt-get update
apt_packages=(
autoconf automake build-essential ca-certificates cmake
libcrypt-dev libnuma-dev libtool libvpx-dev nasm pkg-config
wget yasm zlib1g-dev
)
if [ "$WITH_LIBOPENH264" -eq 1 ]; then
apt_packages+=(libopenh264-dev)
fi
apt-get install -y "${apt_packages[@]}"

if [ ! -f /usr/local/include/ffnvcodec/dynlink_loader.h ]; then
wget -O /tmp/nv-codec-headers.tar.gz \
"https://github.com/FFmpeg/nv-codec-headers/releases/download/n${NVCODEC_VERSION}/nv-codec-headers-${NVCODEC_VERSION}.tar.gz"
tar xzf /tmp/nv-codec-headers.tar.gz -C /tmp/
(cd "/tmp/nv-codec-headers-${NVCODEC_VERSION}" && make && make install)
fi

cd /tmp
rm -rf "ffmpeg-${FFMPEG_VERSION}" ffmpeg-snapshot.tar.bz2
wget -O /tmp/ffmpeg-snapshot.tar.bz2 \
"https://www.ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.bz2"
tar xjvf /tmp/ffmpeg-snapshot.tar.bz2 -C /tmp/
cd "/tmp/ffmpeg-${FFMPEG_VERSION}"

# Configure mirrors install_ffmpeg.sh exactly, with the decoder allowlist
# extended to include software h264/hevc/av1, and optionally the libopenh264
# software h264 encoder.
encoder_list="rawvideo,libvpx_vp9,h264_nvenc,hevc_nvenc,av1_nvenc"
extra_configure_flags=()
if [ "$WITH_LIBOPENH264" -eq 1 ]; then
encoder_list="${encoder_list},libopenh264"
extra_configure_flags+=(--enable-libopenh264)
fi

PKG_CONFIG_PATH="/usr/local/lib/pkgconfig" ./configure \
--prefix="/usr/local" \
--enable-shared \
--disable-static \
--extra-cflags="-I/usr/local/cuda/include" \
--extra-ldflags="-L/usr/local/cuda/lib64" \
--extra-libs="-lpthread -lm" \
--ld="g++" \
--enable-version3 \
--disable-everything \
--disable-network \
--disable-doc \
--disable-ffplay \
--disable-vaapi \
--disable-vdpau \
--disable-dxva2 \
--disable-libdrm \
--enable-encoder="${encoder_list}" \
--enable-decoder=rawvideo,libvpx_vp9,vp9,vp8,h264_cuvid,hevc_cuvid,av1_cuvid,mpeg1video,mpeg2video,mpeg4,h264,hevc,av1 \
--enable-muxer=mp4,rawvideo,image2pipe \
--enable-demuxer=mov,mp4,m4a,3gp,3g2,mj2,avi,matroska,webm,image2,image2pipe \
--enable-parser=h264,hevc,av1,vp8,vp9 \
--enable-bsf=h264_mp4toannexb,hevc_mp4toannexb \
--enable-protocol=file,pipe \
--enable-filter=scale,format,null,copy \
--enable-libvpx \
--enable-cuda \
--enable-cuvid \
--enable-nvdec \
--enable-nvenc \
--enable-ffnvcodec \
"${extra_configure_flags[@]}"
make -j"$(nproc)"
make install
ldconfig

cd /
rm -rf /tmp/ffmpeg* /tmp/nv-codec-headers*
echo
if [ "$WITH_LIBOPENH264" -eq 1 ]; then
echo "==> Done. /usr/local/bin/{ffmpeg,ffprobe} now include software h264/hevc/av1"
echo " decoders and the libopenh264 software h264 encoder."
else
echo "==> Done. /usr/local/bin/{ffmpeg,ffprobe} now include software h264/hevc/av1 decoders."
fi
Loading
Loading