From d498fabe726a6768ae74f6695662e4f5567b6090 Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Thu, 19 Sep 2024 13:29:58 -0600 Subject: [PATCH] Update ffmpeg to 7 and update intel hwaccel docs (#13834) * Update ffmpeg to 7 and update intel hwaccel docs * Formatting * Redo early gen naming * Add gamma back in * Fix table * Add link to intel docs * Add hwaccel arg for disabling gamma * Formatting * Fix tests * Formatting * Fix nvidia --- docker/main/install_deps.sh | 16 +++++----- .../rootfs/usr/local/go2rtc/create_config.py | 16 +++++----- docker/rockchip/Dockerfile | 1 + .../configuration/hardware_acceleration.md | 29 ++++++++++++------- frigate/config.py | 20 ++++++------- frigate/const.py | 4 ++- frigate/ffmpeg_presets.py | 13 +++++++-- frigate/test/test_ffmpeg_presets.py | 2 +- 8 files changed, 60 insertions(+), 41 deletions(-) diff --git a/docker/main/install_deps.sh b/docker/main/install_deps.sh index 327053edd..9664c4574 100755 --- a/docker/main/install_deps.sh +++ b/docker/main/install_deps.sh @@ -40,25 +40,25 @@ apt-get -qq install --no-install-recommends --no-install-suggests -y \ # btbn-ffmpeg -> amd64 if [[ "${TARGETARCH}" == "amd64" ]]; then mkdir -p /usr/lib/ffmpeg/5.0 - mkdir -p /usr/lib/ffmpeg/6.0 + mkdir -p /usr/lib/ffmpeg/7.0 wget -qO btbn-ffmpeg.tar.xz "https://github.com/NickM-27/FFmpeg-Builds/releases/download/autobuild-2022-07-31-12-37/ffmpeg-n5.1-2-g915ef932a3-linux64-gpl-5.1.tar.xz" tar -xf btbn-ffmpeg.tar.xz -C /usr/lib/ffmpeg/5.0 --strip-components 1 rm -rf btbn-ffmpeg.tar.xz /usr/lib/ffmpeg/5.0/doc /usr/lib/ffmpeg/5.0/bin/ffplay - wget -qO btbn-ffmpeg.tar.xz "https://github.com/BtbN/FFmpeg-Builds/releases/download/autobuild-2024-08-31-12-50/ffmpeg-n6.1.2-2-gb534cc666e-linux64-gpl-6.1.tar.xz" - tar -xf btbn-ffmpeg.tar.xz -C /usr/lib/ffmpeg/6.0 --strip-components 1 - rm -rf btbn-ffmpeg.tar.xz /usr/lib/ffmpeg/6.0/doc /usr/lib/ffmpeg/6.0/bin/ffplay + wget -qO btbn-ffmpeg.tar.xz "https://github.com/BtbN/FFmpeg-Builds/releases/download/autobuild-2024-09-19-12-51/ffmpeg-n7.0.2-18-g3e6cec1286-linux64-gpl-7.0.tar.xz" + tar -xf btbn-ffmpeg.tar.xz -C /usr/lib/ffmpeg/7.0 --strip-components 1 + rm -rf btbn-ffmpeg.tar.xz /usr/lib/ffmpeg/7.0/doc /usr/lib/ffmpeg/7.0/bin/ffplay fi # ffmpeg -> arm64 if [[ "${TARGETARCH}" == "arm64" ]]; then mkdir -p /usr/lib/ffmpeg/5.0 - mkdir -p /usr/lib/ffmpeg/6.0 + mkdir -p /usr/lib/ffmpeg/7.0 wget -qO btbn-ffmpeg.tar.xz "https://github.com/NickM-27/FFmpeg-Builds/releases/download/autobuild-2022-07-31-12-37/ffmpeg-n5.1-2-g915ef932a3-linuxarm64-gpl-5.1.tar.xz" tar -xf btbn-ffmpeg.tar.xz -C /usr/lib/ffmpeg/5.0 --strip-components 1 rm -rf btbn-ffmpeg.tar.xz /usr/lib/ffmpeg/5.0/doc /usr/lib/ffmpeg/5.0/bin/ffplay - wget -qO btbn-ffmpeg.tar.xz "https://github.com/BtbN/FFmpeg-Builds/releases/download/autobuild-2024-08-31-12-50/ffmpeg-n6.1.2-2-gb534cc666e-linuxarm64-gpl-6.1.tar.xz" - tar -xf btbn-ffmpeg.tar.xz -C /usr/lib/ffmpeg/6.0 --strip-components 1 - rm -rf btbn-ffmpeg.tar.xz /usr/lib/ffmpeg/6.0/doc /usr/lib/ffmpeg/6.0/bin/ffplay + wget -qO btbn-ffmpeg.tar.xz "hhttps://github.com/BtbN/FFmpeg-Builds/releases/download/autobuild-2024-09-19-12-51/ffmpeg-n7.0.2-18-g3e6cec1286-linuxarm64-gpl-7.0.tar.xz" + tar -xf btbn-ffmpeg.tar.xz -C /usr/lib/ffmpeg/7.0 --strip-components 1 + rm -rf btbn-ffmpeg.tar.xz /usr/lib/ffmpeg/7.0/doc /usr/lib/ffmpeg/7.0/bin/ffplay fi # arch specific packages diff --git a/docker/main/rootfs/usr/local/go2rtc/create_config.py b/docker/main/rootfs/usr/local/go2rtc/create_config.py index d33e4da9e..a9abbe1d1 100644 --- a/docker/main/rootfs/usr/local/go2rtc/create_config.py +++ b/docker/main/rootfs/usr/local/go2rtc/create_config.py @@ -9,10 +9,12 @@ from pathlib import Path import yaml sys.path.insert(0, "/opt/frigate") -from frigate.const import BIRDSEYE_PIPE # noqa: E402 -from frigate.ffmpeg_presets import ( # noqa: E402 - parse_preset_hardware_acceleration_encode, +from frigate.const import ( + BIRDSEYE_PIPE, + DEFAULT_FFMPEG_VERSION, + INCLUDED_FFMPEG_VERSIONS, ) +from frigate.ffmpeg_presets import parse_preset_hardware_acceleration_encode sys.path.remove("/opt/frigate") @@ -110,13 +112,11 @@ else: path = config.get("ffmpeg", {}).get("path", "default") if path == "default": if shutil.which("ffmpeg") is None: - ffmpeg_path = "/usr/lib/ffmpeg/6.0/bin/ffmpeg" + ffmpeg_path = f"/usr/lib/ffmpeg/{DEFAULT_FFMPEG_VERSION}/bin/ffmpeg" else: ffmpeg_path = "ffmpeg" -elif path == "6.0": - ffmpeg_path = "/usr/lib/ffmpeg/6.0/bin/ffmpeg" -elif path == "5.0": - ffmpeg_path = "/usr/lib/ffmpeg/5.0/bin/ffmpeg" +elif path in INCLUDED_FFMPEG_VERSIONS: + ffmpeg_path = f"/usr/lib/ffmpeg/{path}/bin/ffmpeg" else: ffmpeg_path = f"{path}/bin/ffmpeg" diff --git a/docker/rockchip/Dockerfile b/docker/rockchip/Dockerfile index 9087efcd2..e1b43c255 100644 --- a/docker/rockchip/Dockerfile +++ b/docker/rockchip/Dockerfile @@ -24,3 +24,4 @@ RUN rm -rf /usr/lib/btbn-ffmpeg/bin/ffmpeg RUN rm -rf /usr/lib/btbn-ffmpeg/bin/ffprobe ADD --chmod=111 https://github.com/MarcA711/Rockchip-FFmpeg-Builds/releases/download/6.1-5/ffmpeg /usr/lib/ffmpeg/6.0/bin/ ADD --chmod=111 https://github.com/MarcA711/Rockchip-FFmpeg-Builds/releases/download/6.1-5/ffprobe /usr/lib/ffmpeg/6.0/bin/ +ENV PATH="/usr/lib/ffmpeg/6.0/bin/:${PATH}" diff --git a/docs/docs/configuration/hardware_acceleration.md b/docs/docs/configuration/hardware_acceleration.md index 0b62a0f08..867d555d8 100644 --- a/docs/docs/configuration/hardware_acceleration.md +++ b/docs/docs/configuration/hardware_acceleration.md @@ -65,24 +65,33 @@ Or map in all the `/dev/video*` devices. ## Intel-based CPUs +**Recommended hwaccel Preset** + +| CPU Generation | Intel Driver | Recommended Preset | Notes | +| -------------- | ------------ | ------------------ | ----------------------------------- | +| gen1 - gen7 | i965 | preset-vaapi | qsv is not supported | +| gen8 - gen12 | iHD | preset-vaapi | preset-intel-qsv-* can also be used | +| gen13+ | iHD / Xe | preset-intel-qsv-* | | +| Intel Arc GPU | iHD / Xe | preset-intel-qsv-* | | + +:::note + +The default driver is `iHD`. You may need to change the driver to `i965` by adding the following environment variable `LIBVA_DRIVER_NAME=i965` to your docker-compose file or [in the `frigate.yaml` for HA OS users](advanced.md#environment_vars). + +See [The Intel Docs](https://www.intel.com/content/www/us/en/support/articles/000005505/processors.html to figure out what generation your CPU is.) + +::: + ### Via VAAPI -VAAPI supports automatic profile selection so it will work automatically with both H.264 and H.265 streams. VAAPI is recommended for all generations of Intel-based CPUs. +VAAPI supports automatic profile selection so it will work automatically with both H.264 and H.265 streams. ```yaml ffmpeg: hwaccel_args: preset-vaapi ``` -:::note - -With some of the processors, like the J4125, the default driver `iHD` doesn't seem to work correctly for hardware acceleration. You may need to change the driver to `i965` by adding the following environment variable `LIBVA_DRIVER_NAME=i965` to your docker-compose file or [in the `frigate.yaml` for HA OS users](advanced.md#environment_vars). - -::: - -### Via Quicksync (>=10th Generation only) - -If VAAPI does not work for you, you can try QSV if your processor supports it. QSV must be set specifically based on the video encoding of the stream. +### Via Quicksync #### H.264 streams diff --git a/frigate/config.py b/frigate/config.py index ad96cebef..b1af9c51b 100644 --- a/frigate/config.py +++ b/frigate/config.py @@ -26,7 +26,9 @@ from frigate.const import ( CACHE_DIR, CACHE_SEGMENT_FORMAT, DEFAULT_DB_PATH, + DEFAULT_FFMPEG_VERSION, FREQUENCY_STATS_POINTS, + INCLUDED_FFMPEG_VERSIONS, MAX_PRE_CAPTURE, REGEX_CAMERA_NAME, YAML_EXT, @@ -896,27 +898,23 @@ class FfmpegConfig(FrigateBaseModel): def ffmpeg_path(self) -> str: if self.path == "default": if shutil.which("ffmpeg") is None: - return "/usr/lib/ffmpeg/6.0/bin/ffmpeg" + return f"/usr/lib/ffmpeg/{DEFAULT_FFMPEG_VERSION}/bin/ffmpeg" else: return "ffmpeg" - elif self.path == "6.0": - return "/usr/lib/ffmpeg/6.0/bin/ffmpeg" - elif self.path == "5.0": - return "/usr/lib/ffmpeg/5.0/bin/ffmpeg" + elif self.path in INCLUDED_FFMPEG_VERSIONS: + return f"/usr/lib/ffmpeg/{self.path}/bin/ffmpeg" else: return f"{self.path}/bin/ffmpeg" @property def ffprobe_path(self) -> str: if self.path == "default": - if int(os.getenv("LIBAVFORMAT_VERSION_MAJOR", "59")) >= 59: - return "/usr/lib/ffmpeg/6.0/bin/ffprobe" + if shutil.which("ffprobe") is None: + return f"/usr/lib/ffmpeg/{DEFAULT_FFMPEG_VERSION}/bin/ffprobe" else: return "ffprobe" - elif self.path == "6.0": - return "/usr/lib/ffmpeg/6.0/bin/ffprobe" - elif self.path == "5.0": - return "/usr/lib/ffmpeg/5.0/bin/ffprobe" + elif self.path in INCLUDED_FFMPEG_VERSIONS: + return f"/usr/lib/ffmpeg/{self.path}/bin/ffprobe" else: return f"{self.path}/bin/ffprobe" diff --git a/frigate/const.py b/frigate/const.py index c5cc41b3e..a0066774b 100644 --- a/frigate/const.py +++ b/frigate/const.py @@ -43,8 +43,10 @@ AUDIO_MIN_CONFIDENCE = 0.5 MAX_WAL_SIZE = 10 # MB -# Ffmpeg Presets +# Ffmpeg constants +DEFAULT_FFMPEG_VERSION = "7.0" +INCLUDED_FFMPEG_VERSIONS = ["7.0", "5.0"] FFMPEG_HWACCEL_NVIDIA = "preset-nvidia" FFMPEG_HWACCEL_VAAPI = "preset-vaapi" FFMPEG_HWACCEL_VULKAN = "preset-vulkan" diff --git a/frigate/ffmpeg_presets.py b/frigate/ffmpeg_presets.py index 25dd809cb..574dc0177 100644 --- a/frigate/ffmpeg_presets.py +++ b/frigate/ffmpeg_presets.py @@ -91,10 +91,10 @@ PRESETS_HW_ACCEL_DECODE["preset-nvidia-mjpeg"] = PRESETS_HW_ACCEL_DECODE[ PRESETS_HW_ACCEL_SCALE = { "preset-rpi-64-h264": "-r {0} -vf fps={0},scale={1}:{2}", "preset-rpi-64-h265": "-r {0} -vf fps={0},scale={1}:{2}", - FFMPEG_HWACCEL_VAAPI: "-r {0} -vf fps={0},scale_vaapi=w={1}:h={2}:format=nv12,hwdownload,format=nv12,format=yuv420p", + FFMPEG_HWACCEL_VAAPI: "-r {0} -vf fps={0},scale_vaapi=w={1}:h={2},hwdownload,format=nv12,eq=gamma=1.05", "preset-intel-qsv-h264": "-r {0} -vf vpp_qsv=framerate={0}:w={1}:h={2}:format=nv12,hwdownload,format=nv12,format=yuv420p", "preset-intel-qsv-h265": "-r {0} -vf vpp_qsv=framerate={0}:w={1}:h={2}:format=nv12,hwdownload,format=nv12,format=yuv420p", - FFMPEG_HWACCEL_NVIDIA: "-r {0} -vf fps={0},scale_cuda=w={1}:h={2}:format=nv12,hwdownload,format=nv12,format=yuv420p", + FFMPEG_HWACCEL_NVIDIA: "-r {0} -vf fps={0},scale_cuda=w={1}:h={2},hwdownload,format=nv12,eq=gamma=1.05", "preset-jetson-h264": "-r {0}", # scaled in decoder "preset-jetson-h265": "-r {0}", # scaled in decoder "preset-rk-h264": "-r {0} -vf scale_rkrga=w={1}:h={2}:format=yuv420p:force_original_aspect_ratio=0,hwmap=mode=read,format=yuv420p", @@ -185,6 +185,15 @@ def parse_preset_hardware_acceleration_scale( else: scale = PRESETS_HW_ACCEL_SCALE.get(arg, PRESETS_HW_ACCEL_SCALE["default"]) + if ( + ",hwdownload,format=nv12,eq=gamma=1.05" in scale + and os.environ.get("FFMPEG_DISABLE_GAMMA_EQUALIZER") is not None + ): + scale.replace( + ",hwdownload,format=nv12,eq=gamma=1.05", + ":format=nv12,hwdownload,format=nv12,format=yuv420p", + ) + scale = scale.format(fps, width, height).split(" ") scale.extend(detect_args) return scale diff --git a/frigate/test/test_ffmpeg_presets.py b/frigate/test/test_ffmpeg_presets.py index ac5e30a2d..0275469cd 100644 --- a/frigate/test/test_ffmpeg_presets.py +++ b/frigate/test/test_ffmpeg_presets.py @@ -78,7 +78,7 @@ class TestFfmpegPresets(unittest.TestCase): " ".join(frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"]) ) assert ( - "fps=10,scale_cuda=w=2560:h=1920:format=nv12,hwdownload,format=nv12,format=yuv420p" + "fps=10,scale_cuda=w=2560:h=1920,hwdownload,format=nv12,eq=gamma=1.05" in (" ".join(frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"])) )