From fd5d8f9be482e3ac087d656d2c76d17dca3d5bbc Mon Sep 17 00:00:00 2001 From: nulledy <254504350+nulledy@users.noreply.github.com> Date: Sun, 15 Feb 2026 10:35:41 -0500 Subject: [PATCH] ffmpeg Preview Segment Optimization for "high" and "very_high" (#21996) * Introduce qmax parameter for ffmpeg preview encoding Added PREVIEW_QMAX_PARAM to control ffmpeg encoding quality. * formatting * Fix spacing in qmax parameters for preview quality --- frigate/output/preview.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/frigate/output/preview.py b/frigate/output/preview.py index f16bb3bd7..b66c1298a 100644 --- a/frigate/output/preview.py +++ b/frigate/output/preview.py @@ -47,6 +47,15 @@ PREVIEW_QUALITY_BIT_RATES = { RecordQualityEnum.high: 9864, RecordQualityEnum.very_high: 10096, } +# the -qmax param for ffmpeg prevents the encoder from overly compressing frames while still trying to hit the bitrate target +# lower values are higher quality. This is especially important for iniitial frames in the segment +PREVIEW_QMAX_PARAM = { + RecordQualityEnum.very_low: "", + RecordQualityEnum.low: "", + RecordQualityEnum.medium: "", + RecordQualityEnum.high: " -qmax 25", + RecordQualityEnum.very_high: " -qmax 25", +} def get_cache_image_name(camera: str, frame_time: float) -> str: @@ -125,7 +134,7 @@ class FFMpegConverter(threading.Thread): config.ffmpeg.ffmpeg_path, "default", input="-f concat -y -protocol_whitelist pipe,file -safe 0 -threads 1 -i /dev/stdin", - output=f"-threads 1 -g {PREVIEW_KEYFRAME_INTERVAL} -bf 0 -b:v {PREVIEW_QUALITY_BIT_RATES[self.config.record.preview.quality]} {FPS_VFR_PARAM} -movflags +faststart -pix_fmt yuv420p {self.path}", + output=f"-threads 1 -g {PREVIEW_KEYFRAME_INTERVAL} -bf 0 -b:v {PREVIEW_QUALITY_BIT_RATES[self.config.record.preview.quality]}{PREVIEW_QMAX_PARAM[self.config.record.preview.quality]} {FPS_VFR_PARAM} -movflags +faststart -pix_fmt yuv420p {self.path}", type=EncodeTypeEnum.preview, )