From 75aedd2b8804e33b6371113b0575f91e93a4ae28 Mon Sep 17 00:00:00 2001 From: Nick Mowen Date: Thu, 29 Dec 2022 14:56:04 -0700 Subject: [PATCH] Add hardware encoding for birdseye based on ffmpeg preset --- frigate/ffmpeg_presets.py | 110 ++++++++++++++++++++++++++++++++++++++ frigate/output.py | 13 ++--- frigate/restream.py | 3 +- 3 files changed, 117 insertions(+), 9 deletions(-) diff --git a/frigate/ffmpeg_presets.py b/frigate/ffmpeg_presets.py index 938359a5a..2d25a6f0e 100644 --- a/frigate/ffmpeg_presets.py +++ b/frigate/ffmpeg_presets.py @@ -322,6 +322,108 @@ PRESETS_INPUT = { } +PRESETS_HW_ACCEL_ENCODE = { + "preset-intel-vaapi": [ + "-c:v", + "h264_vaapi", + "-g", + "50", + "-bf", + "0", + "-profile:v", + "high", + "-level:v", + "4.1", + "-sei:v", + "0", + ], + "preset-intel-qsv-h264": [ + "-c:v", + "h264_qsv", + "-g", + "50", + "-bf", + "0", + "-profile:v", + "high", + "-level:v", + "4.1", + "-async_depth:v", + "1", + ], + "preset-intel-qsv-h265": [ + "-c:v", + "h264_qsv", + "-g", + "50", + "-bf", + "0", + "-profile:v", + "high", + "-level:v", + "4.1", + "-async_depth:v", + "1", + ], + "preset-amd-vaapi": [ + "-c:v", + "h264_vaapi", + "-g", + "50", + "-bf", + "0", + "-profile:v", + "high", + "-level:v", + "4.1", + "-sei:v", + "0", + ], + "preset-nvidia-h264": [ + "-c:v", + "h264_nvenc", + "-g", + "50", + "-profile:v", + "high", + "-level:v", + "auto", + "-preset:v", + "p2", + "-tune:v", + "ll", + ], + "preset-nvidia-h265": [ + "-c:v", + "h264_nvenc", + "-g", + "50", + "-profile:v", + "high", + "-level:v", + "auto", + "-preset:v", + "p2", + "-tune:v", + "ll", + ], + "default": [ + "-c:v", + "libx264", + "-g", + "50", + "-profile:v", + "high", + "-level:v", + "4.1", + "-preset:v", + "superfast", + "-tune:v", + "zerolatency", + ], +} + + def parse_preset_input(arg: Any, detect_fps: int) -> list[str]: """Return the correct preset if in preset format otherwise return None.""" if not isinstance(arg, str): @@ -335,6 +437,14 @@ def parse_preset_input(arg: Any, detect_fps: int) -> list[str]: return PRESETS_INPUT.get(arg, None) +def parse_preset_hardware_acceleration_encode(arg: Any) -> list[str]: + """Return the correct scaling preset or default preset if none is set.""" + if not isinstance(arg, str): + return PRESETS_HW_ACCEL_ENCODE["default"] + + return PRESETS_HW_ACCEL_ENCODE.get(arg, PRESETS_HW_ACCEL_ENCODE["default"]) + + PRESETS_RECORD_OUTPUT = { "preset-record-generic": [ "-f", diff --git a/frigate/output.py b/frigate/output.py index 52b51fd55..b64611bfb 100644 --- a/frigate/output.py +++ b/frigate/output.py @@ -39,14 +39,10 @@ class FFMpegConverter: birdseye_rtsp: bool = False, ): if birdseye_rtsp: - try: - os.mkfifo(BIRDSEYE_PIPE, mode=0o777) - stdin = os.open(BIRDSEYE_PIPE, os.O_RDONLY | os.O_NONBLOCK) - self.bd_pipe = os.open(BIRDSEYE_PIPE, os.O_WRONLY) - os.close(stdin) - except Exception as e: - print(f"The exception is {e}") - self.bd_pipe = None + os.mkfifo(BIRDSEYE_PIPE, mode=0o777) + stdin = os.open(BIRDSEYE_PIPE, os.O_RDONLY | os.O_NONBLOCK) + self.bd_pipe = os.open(BIRDSEYE_PIPE, os.O_WRONLY) + os.close(stdin) else: self.bd_pipe = None @@ -100,6 +96,7 @@ class FFMpegConverter: def exit(self): if self.bd_pipe: os.close(self.bd_pipe) + os.remove(BIRDSEYE_PIPE) self.process.terminate() try: diff --git a/frigate/restream.py b/frigate/restream.py index 9c894f56e..8f4857926 100644 --- a/frigate/restream.py +++ b/frigate/restream.py @@ -7,6 +7,7 @@ from frigate.util import escape_special_characters from frigate.config import FrigateConfig from frigate.const import BIRDSEYE_PIPE +from frigate.ffmpeg_presets import parse_preset_hardware_acceleration_encode logger = logging.getLogger(__name__) @@ -46,7 +47,7 @@ class RestreamApi: if self.config.restream.birdseye: self.relays[ "birdseye" - ] = f"exec:ffmpeg -hide_banner -f rawvideo -pix_fmt yuv420p -s {self.config.birdseye.width}x{self.config.birdseye.height} -i {BIRDSEYE_PIPE} -tune zerolatency -preset ultrafast -c:v libx264 -rtsp_transport tcp -f rtsp {{output}}" + ] = f"exec:ffmpeg -hide_banner -f rawvideo -pix_fmt yuv420p -s {self.config.birdseye.width}x{self.config.birdseye.height} -i {BIRDSEYE_PIPE} {' '.join(parse_preset_hardware_acceleration_encode(self.config.ffmpeg.hwaccel_args))} -rtsp_transport tcp -f rtsp {{output}}" for name, path in self.relays.items(): params = {"src": path, "name": name}