Bug: frigate.output.preview module broken β FFmpeg build missing libx264, h264_axenc segfaults without hw_device_ctx

The preview-generation module (frigate/output/preview.py) hard-codes -c:v libx264 for encoding hourly preview clips. The AXCL FFmpeg build shipped in this image (frigate:x86-axcl-70a0545) does not include libx264 at all, so every preview-generation attempt fails once per hour, per camera. This produces empty/corrupted preview MP4 files, which surface as visible garbage/artifacts (shifted or noisy image blocks) in the Frigate dashboard grid and in review/alert thumbnails β even though the actual recorded footage (record role) is unaffected.
Environment
- Image:
frigate:x86-axcl-70a0545 - Frigate version: 0.17.0-70a0545
- Host: Proxmox LXC (privileged), AXCL passthrough, AX8850 NPU cards
- FFmpeg (custom AXCL build) version info:
Note: noffmpeg version 7.1 Copyright (c) 2000-2024 the FFmpeg developers built with gcc 9 (Ubuntu 9.4.0-1ubuntu1~18.04) configuration: --prefix=.../axcl/3rdparty/ffmpeg/out/x64 --enable-cross-compile --arch=x86_64 --host-os=linux --target-os=linux --cc=gcc --enable-shared --disable-static --enable-gpl --enable-muxer=mp4 --enable-muxer=flv --enable-muxer=h264 --enable-muxer=hevc --enable-demuxer=flv --enable-demuxer=h264 --enable-demuxer=hevc --enable-demuxer=rtsp --enable-parser=hevc --enable-ffmpeg --enable-swscale --disable-avdevice --enable-encoders --enable-filters --enable-axmm --disable-large-tests --disable-doc --enable-pic --disable-x86asm --disable-libxcb --disable-zlib --disable-bzlib --disable-libxcb_shm --disable-lzma --disable-logging--enable-libx264in the configure flags.
Steps to reproduce
- Run Frigate normally with 2 cameras (H.265 main streams, restreamed through go2rtc).
- Wait for the top of the hour (preview clips are generated on a fixed 1-hour cadence,
PREVIEW_SEGMENT_DURATION = 3600infrigate/output/preview.py). - Observe the container logs.
Actual behavior (logs)
error | 2026-08-18 09:00:00 | frigate.output.preview | Error saving preview for lewa :: Unrecognized option 'preset:v'.
unknown | 2026-08-18 07:00:00 | unknown | Error splitting the argument list: Option not found
error | 2026-08-18 09:00:00 | frigate.output.preview | Error saving preview for prawa :: Unrecognized option 'preset:v'.
unknown | 2026-08-18 07:00:00 | unknown | Error splitting the argument list: Option not found
This repeats every hour, on both cameras simultaneously. The resulting preview MP4 for that hour is missing/empty, which the frontend then renders as a visibly corrupted/garbled thumbnail in:
- the live dashboard camera grid preview,
- the Review/Alerts thumbnail list.
The actual recording files under /media/frigate/recordings/... are not affected β verified by pulling a recording segment directly and inspecting frames, which were clean. This is purely a preview-generation bug, but it is confusing/alarming to end users because it visually looks like a camera/decoding fault.
Root cause analysis
Traced end-to-end:
frigate/output/preview.pybuilds the encode command via:self.ffmpeg_cmd = parse_preset_hardware_acceleration_encode( 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 {...} {FPS_VFR_PARAM} -movflags +faststart -pix_fmt yuv420p {self.path}", type=EncodeTypeEnum.preview, )It always passes the literal string
"default"β there is no way to override this via user config.frigate/ffmpeg_presets.pydefines:PRESETS_HW_ACCEL_ENCODE_PREVIEW = { "default": "{0} -hide_banner {1} -c:v libx264 -profile:v baseline -preset:v ultrafast {2}", }This is unconditional β there is no AXCL/hwaccel-aware branch for
EncodeTypeEnum.preview, unlikePRESETS_HW_ACCEL_ENCODE_BIRDSEYEandPRESETS_HW_ACCEL_ENCODE_TIMELAPSE, which both have hardware-specific entries.The resulting command string is split naively with
.split(" ")inpreview.py(lines ~109, ~120) and executed via theffmpeg-axclwrapper (/usr/local/lib/ffmpeg-axcl/bin/ffmpeg), which is a thin shell wrapper:#!/bin/bash export LD_LIBRARY_PATH=/usr/lib/axcl/ffmpeg:/usr/lib/axcl:$LD_LIBRARY_PATH exec /usr/bin/axcl/ffmpeg/ffmpeg "$@"The wrapper passes arguments through unmodified (
"$@"), so it is not the source of the malformed-looking error message.The actual binary,
/usr/bin/axcl/ffmpeg/ffmpeg, does not recognizelibx264:$ ffmpeg -h encoder=libx264 Codec 'libx264' is not recognized by FFmpeg.Confirmed via
-encoders:$ ffmpeg -encoders | grep 264 V..... h264_axenc AX H.264 encoder (codec h264) V..... h264_v4l2m2m V4L2 mem2mem H.264 encoder wrapper (codec h264)Because FFmpeg cannot resolve
-c:v libx264to a known encoder, it cannot associate the subsequent-preset:v ultrafastwith any encoder-specific option table, and the option is reported back malformed ('preset:v', missing the leading dash) in the error message β this is what produces the confusing "Unrecognized option 'preset:v'" log line. The real problem is the missinglibx264, not a literal typo anywhere in the Python code (verified βffmpeg_presets.pyin the image has the dash present, exactly matching upstream).Tried swapping to the available hardware encoder
h264_axencmanually, replicating the exactpreview.pycommand shape:ffmpeg -hide_banner -f concat -y -protocol_whitelist pipe,file -safe 0 -threads 1 \ -i test_concat.txt -c:v h264_axenc -profile 66 -threads 1 -g 60 -bf 0 -b:v 200k \ -movflags +faststart -pix_fmt nv12 test_preview.mp4Result:
[h264_axenc @ ...] ff_h264_axenc_init format(nv12) requires hw_device_ctx must be set Segmentation fault (core dumped)h264_axencrequires a properly initialized AXCL hardware device context (comparable to-init_hw_device/-hwaccelused elsewhere in the decode pipeline) β it cannot be used as a drop-in replacement forlibx264by simply changing the codec name. Without that context it segfaults rather than failing gracefully.
Impact
- Preview clip generation (
frigate/output/preview.py) is completely non-functional on this image, for every camera, every hour. - This degrades the review/alert timeline UX (broken/garbled thumbnails) and could confuse users into thinking their camera feed or decoder is corrupted (as happened in our case β we spent significant time ruling out network jitter,
hevc_axdecdecode issues, and disk space before isolating this). - Actual recordings (
recordrole, main NVR functionality) are unaffected β this is purely cosmetic/UX, but the misleading error message and visual symptom make it very easy to misdiagnose as a hardware/decode/network problem.
Suggested fixes (any of)
- Preferred: Add an AXCL-specific entry to
PRESETS_HW_ACCEL_ENCODE_PREVIEWinffmpeg_presets.py(mirroring what's already done forPRESETS_HW_ACCEL_ENCODE_BIRDSEYE/_TIMELAPSE), targetingh264_axenc, including whatever-init_hw_device/hwuploadfilter chain is required to avoid thehw_device_ctxsegfault. Since preview frames are just periodic low-res webp stills being concatenated, this doesn't need to be fast β correctness matters more than performance here. - Alternative: Ship a static/software
libx264in the AXCL FFmpeg build (even if not used for the main decode/detect/record pipelines) purely to satisfy modules likeoutput/preview.pyandoutput/birdseye.py's"default"fallback that assume software x264 is always available. - Minimum viable fix: At minimum, the segfault on
h264_axencwithouthw_device_ctxshould be hardened to fail gracefully (return an error Frigate can catch/log) rather than crashing the encode subprocess β this affects anyone who tries to useh264_axencoutside of a fully-wired hwaccel context.
Additional notes
ffmpeg_presets.pyitself (as shipped in this image) is otherwise unmodified/identical to upstreamblakeblackshear/frigatefor the preview section β the bug is an omission (no AXCL-aware preview preset), not a code regression introduced by the AXERA fork.- Happy to provide full logs, the exact recording/preview cache directory listing, or test further changes if a patch is proposed β this is a home-lab deployment, not time-critical, but the misdiagnosis risk for others hitting this silently (thinking it's a camera/network fault) seems worth flagging clearly.
Update: found the fix already exists in source β commit 896794f on axera-dev adds preset-axera-h264/h265 entries to PRESETS_HW_ACCEL_ENCODE_PREVIEW with proper -init_hw_device axmm:axmm,alloc_blk=1 init. But the published x86-axcl image (branch v0.17-axcl on HF, tag 70a0545) doesn't include it yet β verified by inspecting ffmpeg_presets.py inside the tar directly. Could you cut a new x86-axcl build with this commit included?
@RATMANrush Yes. The fix is available in the public axera-dev branch:
https://github.com/AXERA-TECH/frigate/tree/axera-dev
https://github.com/AXERA-TECH/frigate/actions/runs/33721655977
Please make sure the camera configuration uses either:
hwaccel_args: preset-axera-h264
or:
hwaccel_args: preset-axera-h265
The previously published frigate:x86-axcl-70a0545 image predates this fix.
Follow-up: separate issue, not the same as the original preview.py bug
Confirmed the preset-axera-h265 fix works for hourly preview generation β thanks. However, while testing (both on our own axera-dev build and the official CI artifact from run 33721655977, commit 36e1176), we found a separate, unrelated issue with live MSE preview in the dashboard, which we initially misdiagnosed as camera/network instability before isolating it properly.
Symptom: On a fresh MSE WebSocket connection (opening a camera's live view), the rendered image shows horizontal-banded corruption (magenta/green noise) for a few seconds, then self-corrects. Reproduced on two independent Frigate images, ruling out our build process as the cause.
Root cause (confirmed via ffmpeg -vf showinfo against the local RTSP restream):
A fresh connection starts decoding mid-GOP, before receiving an I-frame. Keyframe interval on our camera is ~4.3s. All frames before the first I-frame show flat/uniform pixel data (mean ~128,128,128), consistent with the decoder rendering from an uninitialized reference buffer rather than failing gracefully.
On the eventual keyframe, showinfo reports conflicting metadata on the same frame: pict_type: P alongside iskey:1 type:I. This inconsistency appears to originate in hevc_axdec itself, not in Frigate or go2rtc (both showed clean logs throughout β no decode errors reported anywhere in the stack).
Environment: same as original report (AX8850, AXCL passthrough, x86). Camera: H.265 main stream via go2rtc. Happy to share full showinfo output or reproduce with different keyframe intervals if useful β this seems like it could affect anyone using hevc_axdec for live MSE preview, not just our setup.
Full command used: ffmpeg -v info -i rtsp://127.0.0.1:8554/lewa_1 -vf showinfo -f null -t 15 -, run inside the frigate container against the local go2rtc restream.
Raw evidence (ffmpeg -vf showinfo against local RTSP restream, fresh connection):
First frames after connect β no I-frame yet, uniform/flat pixel data:
[Parsed_showinfo_0] n: 33 pts_time:2.666667 fmt:yuvj420p s:3840x2160 i:P iskey:0 type:P checksum:03701C4D mean:[128 128 128] stdev:[22.6 2.5 3.0]
[Parsed_showinfo_0] n: 34 pts_time:2.75 fmt:yuvj420p s:3840x2160 i:P iskey:0 type:P checksum:FFD1AAD3 mean:[128 128 128] stdev:[22.8 2.5 3.0]
[Parsed_showinfo_0] n: 41 pts_time:3.333333 fmt:yuvj420p s:3840x2160 i:P iskey:0 type:P checksum:E363E9F3 mean:[128 128 128] stdev:[23.7 2.6 3.3]
[Parsed_showinfo_0] n: 49 pts_time:4 fmt:yuvj420p s:3840x2160 i:P iskey:0 type:P checksum:EE93E8E1 mean:[128 128 128] stdev:[24.8 2.8 3.6]
Note mean:[128 128 128] held constant across ~1.3s / 16 frames β consistent with an uninitialized/flat reference buffer, not real image content.
First keyframe (~4.3s after connect) β conflicting type metadata on the same frame:
[Parsed_showinfo_0] n: 53 pts_time:4.333333 fmt:yuvj420p s:3840x2160 i:P iskey:1 type:I checksum:89D03FBC mean:[120 126 123] stdev:[57.8 7.4 10.4]
pict_type reports P while the same frame is flagged iskey:1 type:I β and stdev jumps to values consistent with real image content only at this point.
Thanks for the detailed report. Weβll try to reproduce this issue as soon as possible and will update this discussion with our findings.