From 6c2621799cf915c26c88eaa2eebb4b30442d300f Mon Sep 17 00:00:00 2001 From: Nick Mowen Date: Sat, 20 May 2023 15:27:01 -0600 Subject: [PATCH] Add separate ffmpeg preset for timelapse --- frigate/ffmpeg_presets.py | 37 +++++++++++++++++++++++++++++++------ frigate/record/export.py | 10 ++++++++-- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/frigate/ffmpeg_presets.py b/frigate/ffmpeg_presets.py index d78cd72ef..8274a2a48 100644 --- a/frigate/ffmpeg_presets.py +++ b/frigate/ffmpeg_presets.py @@ -2,6 +2,8 @@ import logging import os + +from enum import Enum from typing import Any from frigate.const import BTBN_PATH @@ -116,7 +118,7 @@ PRESETS_HW_ACCEL_SCALE = { "default": "-r {0} -s {1}x{2}", } -PRESETS_HW_ACCEL_ENCODE = { +PRESETS_HW_ACCEL_ENCODE_BIRDSEYE = { "preset-rpi-32-h264": "ffmpeg -hide_banner {0} -c:v h264_v4l2m2m {1}", "preset-rpi-64-h264": "ffmpeg -hide_banner {0} -c:v h264_v4l2m2m {1}", "preset-vaapi": "ffmpeg -hide_banner -hwaccel vaapi -hwaccel_output_format vaapi -hwaccel_device {2} {0} -c:v h264_vaapi -g 50 -bf 0 -profile:v high -level:v 4.1 -sei:v 0 -an -vf format=vaapi|nv12,hwupload {1}", @@ -127,6 +129,17 @@ PRESETS_HW_ACCEL_ENCODE = { "default": "ffmpeg -hide_banner {0} -c:v libx264 -g 50 -profile:v high -level:v 4.1 -preset:v superfast -tune:v zerolatency {1}", } +PRESETS_HW_ACCEL_ENCODE_TIMELAPSE = { + "preset-rpi-32-h264": "ffmpeg -hide_banner {0} -c:v h264_v4l2m2m {1}", + "preset-rpi-64-h264": "ffmpeg -hide_banner {0} -c:v h264_v4l2m2m {1}", + "preset-vaapi": "ffmpeg -hide_banner -hwaccel vaapi -hwaccel_output_format vaapi -hwaccel_device {2} {0} -c:v h264_vaapi {1}", + "preset-intel-qsv-h264": "ffmpeg -hide_banner {0} -c:v h264_qsv -g 50 -bf 0 -profile:v high -level:v 4.1 -async_depth:v 1 {1}", + "preset-intel-qsv-h265": "ffmpeg -hide_banner {0} -c:v hevc_qsv -g 50 -bf 0 -profile:v high -level:v 4.1 -async_depth:v 1 {1}", + "preset-nvidia-h264": "ffmpeg -hide_banner -hwaccel cuda -hwaccel_output_format cuda -extra_hw_frames 8 {0} -c:v h264_nvenc {1}", + "preset-nvidia-h265": "ffmpeg -hide_banner -hwaccel cuda -hwaccel_output_format cuda -extra_hw_frames 8 {0} -c:v hevc_nvenc {1}", + "default": "ffmpeg -hide_banner {0} -c:v libx264 -preset:v ultrafast -tune:v zerolatency {1}", +} + def parse_preset_hardware_acceleration_decode(arg: Any) -> list[str]: """Return the correct preset if in preset format otherwise return None.""" @@ -161,12 +174,24 @@ def parse_preset_hardware_acceleration_scale( return scale -def parse_preset_hardware_acceleration_encode(arg: Any, input: str, output: str) -> str: - """Return the correct scaling preset or default preset if none is set.""" - if not isinstance(arg, str): - return PRESETS_HW_ACCEL_ENCODE["default"].format(input, output) +class EncodeTypeEnum(str, Enum): + birdseye = "birdseye" + timelapse = "timelapse" - return PRESETS_HW_ACCEL_ENCODE.get(arg, PRESETS_HW_ACCEL_ENCODE["default"]).format( + +def parse_preset_hardware_acceleration_encode( + arg: Any, input: str, output: str, type: EncodeTypeEnum = EncodeTypeEnum.birdseye +) -> str: + """Return the correct scaling preset or default preset if none is set.""" + if type == EncodeTypeEnum.birdseye: + arg_map = PRESETS_HW_ACCEL_ENCODE_BIRDSEYE + elif type == EncodeTypeEnum.timelapse: + arg_map = PRESETS_HW_ACCEL_ENCODE_TIMELAPSE + + if not isinstance(arg, str): + return arg_map["default"].format(input, output) + + return arg_map.get(arg, arg_map["default"]).format( input, output, _gpu_selector.get_selected_gpu(), diff --git a/frigate/record/export.py b/frigate/record/export.py index efaeb01f1..56a7a122a 100644 --- a/frigate/record/export.py +++ b/frigate/record/export.py @@ -10,7 +10,10 @@ import subprocess as sp from frigate.config import FrigateConfig from frigate.const import EXPORT_DIR, MAX_PLAYLIST_SECONDS -from frigate.ffmpeg_presets import parse_preset_hardware_acceleration_encode +from frigate.ffmpeg_presets import ( + EncodeTypeEnum, + parse_preset_hardware_acceleration_encode, +) logger = logging.getLogger(__name__) @@ -76,6 +79,7 @@ class RecordingExporter(threading.Thread): self.config.ffmpeg.hwaccel_args, ffmpeg_input, f"-vf setpts=0.04*PTS -r 30 -an {file_name}", + EncodeTypeEnum.timelapse, ) ).split(" ") @@ -87,7 +91,9 @@ class RecordingExporter(threading.Thread): ) if p.returncode != 0: - logger.error(f"Failed to export recording for command {' '.join(ffmpeg_cmd)}") + logger.error( + f"Failed to export recording for command {' '.join(ffmpeg_cmd)}" + ) logger.error(p.stderr) return