Radxa AICore AX-M1: frigate-x86-axcl-70a0545.tar (v0.17-axcl) missing ffmpeg AXCL hwaccel
I've been migrating from frigate-x86-axcl-319c2f8.tar (v0.16-x86-axcl) to frigate-x86-axcl-70a0545.tar (v0.17-axcl) and ran into a blocking issue: the 0.17 image appears to be missing AXCL ffmpeg integration entirely. Been using Claude to help, so don't mind the AI description below.
Environment:
Host: Proxmox VE 9.1 (kernel 6.17.2-1-pve), x86_64
AXCL host driver V3.10.2 installed via user_installation.sh from this repo
Card: AX8850 β axcl-smi confirms working, NPU + memory healthy
Frigate runs in Docker inside an LXC with /dev/axcl_host, /dev/ax_mmb_dev, /dev/msg_userdev passed through and /usr/lib/axcl + /usr/bin/axcl bind-mounted from host
axengine detector loads correctly:
Available providers: ['AXCLRTExecutionProvider'] β
frigate-yolov9-tiny model loads fine β
Inference via the AX8850 NPU works β
The core problem β video decode:
In the 0.16 image, /usr/lib/ffmpeg/axcl/ffmpeg was an AXCL-aware ffmpeg build (~21 MB, AXERA SDK V3.6.5). Cameras used hwaccel_args: preset-axera-h265 (or -h264) and decoded on the AX8850 VPU.
In the 0.17 image:
No AXCL ffmpeg binary. Only stock ffmpeg at /usr/lib/ffmpeg/7.0/bin/ffmpeg and /usr/lib/ffmpeg/5.0/bin/ffmpeg. No /usr/lib/ffmpeg/axcl/ directory at all.
Stock ffmpeg has no AXCL support compiled in:
$ docker exec frigate /usr/lib/ffmpeg/7.0/bin/ffmpeg -hwaccels
Hardware acceleration methods:
cuda
vaapi
qsv
drm
opencl
vulkan
No axcl or axera. Decoders list also has nothing AXCL-related.
No preset-axera-* in ffmpeg_presets.py. Inspecting /opt/frigate/frigate/ffmpeg_presets.py in the container, the PRESETS_HW_ACCEL_DECODE dict has entries for RPI, VAAPI, QSV, NVIDIA, Jetson, RKMPP, Vulkan, AMF β but no AXERA/AXCL entries. Same for the SCALE and ENCODE preset dicts.
Resulting behavior:
When hwaccel_args: preset-axera-h265 is set in config (carried over from 0.16), the preset name doesn't resolve, so the literal string is passed to ffmpeg as an argument. ffmpeg then interprets it as an output file path:
[AVFormatContext @ ...] Unable to choose an output format for 'preset-axera-h265';
use a standard extension for the filename or specify the format manually.
[out#0 @ ...] Error initializing the muxer for preset-axera-h265: Invalid argument
Error opening output file preset-axera-h265.
Error opening output files: Invalid argument
All capture threads die, watchdog restarts them in a loop, eventually frigate.watchdog INFO: Detection appears to have stopped. Exiting Frigate...
If hwaccel_args is removed from the config entirely, all 16 of my camera streams come up cleanly using software decode β confirming the rest of the pipeline (model, detector, capture, recording) works. But software decoding 8 cameras Γ 2 streams across 4 vCPUs hits the LXC's CPU hard, defeating the purpose of the M.2 accelerator.
Other notes:
rk-README.md and rpi-README.md exist on the branch but x86-README.md's example docker-compose.yml still references the 0.17 image as drop-in. The deployment doc seems to assume AXCL hwaccel works.
The 0.16 image (319c2f8) continues to work correctly with the same hardware, drivers, and config (just preset-axera-h265 and preset-axera-h264 per camera). I've rolled back and 0.16 is solid.
The axengine detector plugin update is the headline 0.17 win on x86, but without ffmpeg AXCL hwaccel the upgrade isn't viable for production use.
Questions:
Is the missing AXCL ffmpeg + presets in frigate-x86-axcl-70a0545.tar a known issue, or did I miss a setup step?
Is there a planned rebuild of the x86 image with AXCL ffmpeg integration restored?
For users wanting to track progress, is there a more detailed roadmap or branch where this is being worked on?
Happy to test prereleases or provide additional logs/diagnostics if useful. The 0.16 β 0.17 migration is otherwise smooth (config migrates cleanly, DB migrates cleanly, inference works) β just the video-decode side that's blocked.
Side note on host driver install (user_installation.sh):
The kernel module build fails on kernel 6.17 because the Proxmox kernel build config promotes -Wdate-time to an error, and axcl_module_version.h uses DATE / TIME macros for version stamping:
../include/axcl_module_version.h:15:66: error: macro "DATE" might prevent reproducible builds [-Werror=date-time]
../include/axcl_module_version.h:14:92: error: macro "TIME" might prevent reproducible builds [-Werror=date-time]
cc1: some warnings being treated as errors
Two workarounds that work:
Option 1: pass the flag through to kernel build
KCFLAGS="-Wno-error=date-time" dpkg -i axcl.deb
Option 2: patch the macros to literal strings before install
sed -i 's/DATE/"Date"/g' /usr/src/axcl/include/axcl_module_version.h
sed -i 's/TIME/"Time"/g' /usr/src/axcl/include/axcl_module_version.h
Worth fixing in source β replacing DATE/TIME with a build-time-injected version string (e.g., from a VERSION file or git SHA) would make the module build reproducibly and pass strict-warning kernel configs cleanly.
Also, user_installation.sh uses sudo throughout, but on Proxmox sudo isn't installed by default (root-only environment). The script aborts with sudo: command not found. Either install sudo first, or strip the prefix (sed -i 's/sudo //g' user_installation.sh).
Solved this today on the same setup (Proxmox + LXC + x86 AX650).
The 0.17 image does include AXCL ffmpeg β it's just not where you'd expect. The binary is at /usr/bin/axcl/ffmpeg/ffmpeg (bind-mounted from the host via /usr/bin/axcl:/usr/bin/axcl:ro), and there's a wrapper script at /usr/local/bin/ffmpeg-axcl on the host that sets LD_LIBRARY_PATH and calls it.
The issue is that get_ffmpeg_path.py constructs {path}/bin/ffmpeg, so you can't point path directly at the wrapper script. The fix:
Create a proper directory structure on the host:
bashmkdir -p /usr/local/lib/ffmpeg-axcl/bin
cat > /usr/local/lib/ffmpeg-axcl/bin/ffmpeg << 'EOF'
#!/bin/bash
export LD_LIBRARY_PATH=/usr/lib/axcl/ffmpeg:/usr/lib/axcl:$LD_LIBRARY_PATH
exec /usr/bin/axcl/ffmpeg/ffmpeg "$@"
EOF
chmod +x /usr/local/lib/ffmpeg-axcl/bin/ffmpeg
Add volume to docker-compose.yml:
yaml- /usr/local/lib/ffmpeg-axcl:/usr/local/lib/ffmpeg-axcl:ro
In Frigate config:
yamlffmpeg:
path: /usr/local/lib/ffmpeg-axcl
hwaccel_args: -c:v hevc_axdec
preset-axera-h265 doesn't exist in 0.17 β use -c:v hevc_axdec or -c:v h264_axdec directly.
After docker compose down && docker compose up -d (not just restart), /usr/bin/axcl/ffmpeg/ffmpeg runs with hevc_axdec confirmed via ps aux
Thanks for following up on this. I should have replied earlier as I made a similar fix a couple days after this post. Your solution confirms what I landed on independently, and the wrapper-script approach you describe is cleaner than what I did (I bind-mounted the binary and libs to separate paths inside the container and set LD_LIBRARY_PATH via Docker env). Functionally equivalent, your version is more portable for invoking the AXCL ffmpeg outside the container.
For anyone hitting this trail behind us, a few things worth documenting:
Hwaccel args β preset-axera-h265 and preset-axera-h264 don't exist in the 0.17 image's ffmpeg_presets.py. Use the decoders directly:
ffmpeg:
hwaccel_args:
- -c:v
- h264_axdec # or hevc_axdec for H.265
ffmpeg figures out the axmm hwaccel implicitly from the decoder choice.
Kernel 7.0+ requires a source patch. If you're on Proxmox 9.x (PVE kernel 7.x) running AXCL on the host, the AXCL driver fails to build because pci_resize_resource() got a fourth argument (an exclude_bars mask). One-liner fix before running dpkg -i:
sed -i 's/pci_resize_resource(pdev, BAR_4, SZ_1M)/pci_resize_resource(pdev, BAR_4, SZ_1M, 0)/g' \
/usr/src/axcl/drv/pcie/driver/host_dev/ax_pcie_dev_host.c
Passing 0 means "exclude no BARs from the resize" β same behavior as the old API. You also need KCFLAGS="-Wno-error=date-time" set during dpkg -i for the kernel module build, since __DATE__/__TIME__ macros in axcl_module_version.h trip -Werror=date-time on newer kernels.
For making this survive future kernel updates, I keep a rebuild script at /root/rebuild-axcl-modules.sh that runs apt install -y linux-headers-$(uname -r). Takes 30 seconds to run after any kernel update.
The host=x86 make argument is critical. Without it the build defaults to ARM64 cross-compile (ax650 target) and fails with aarch64-none-linux-gnu-gcc: not found β config.mak's ifeq ($(host),x86) selector reads the lowercase host make variable.
Architecture recommendation: VM with PCIe passthrough, not LXC. I started on LXC because shared kernel meant easy bind-mounts and lower overhead. Then Proxmox auto-updated the host kernel from 6.17 to 7.0 and broke everything: modules silently unloaded, /dev/axcl_host disappeared, Frigate crashed. Since AXCL doesn't ship DKMS, every host kernel update requires manual driver rebuild on LXC setups. Migrated to a Debian 12 VM with the AX-M1 passed through (single IOMMU group, clean). Now host kernel updates don't touch AXCL, and the AXCL .deb installs cleanly against Debian's stable 6.1/6.12 kernel without the kernel 7 patches. Performance overhead is negligible.
Hope this saves someone the day I spent on it.
Also another issue I ran into with no real solution is the VPU has some codec limitations. Specifically I have some Annke dual-sensor cameras emit yuvj420p (full-range JPEG-style) substreams that the AXCL VPU can't decode cleanly, produces green/magenta banding artifacts. Confirmed via ffprobe across both FCD600 and FCD800 models, multiple H.264 profiles, and MJPEG. Annke firmware seems to hardcode full-range output. For these cameras I have to fall back to CPU decode which is not ideal. My other cameras, mostly Hikvision native and Amcrest, decode fine on AXCL since they output standard yuv420p with TV-range color.
This appears to be a camera firmware limitation rather than an AXCL issue, as the VPU's pixel format support covers axmm, nv12, yuv420p, nv21, p010le (per hevc_axdec -h), and standard yuv420p decodes cleanly. The Annkes specifically emit non-standard yuvj420p and there's no toggle in their web UI to change it.