aml-gst-rs
GStreamer plugin providing hardware-accelerated video encoding and decoding for Amlogic A311D2 SoCs (Khadas VIM4). Wraps the amvenc_* API from libamvenc.so and the V4L2 stateful decoder.
Elements:
amlvenc_rs - H265/H264 hardware encoder codec h265 (default) or h264 bitrate 100000-50000000 (default 2000000), changeable during playback gop 1-1000 (default 30)
amlvdec_rs - H264 hardware decoder framerate 1-240 (default 25) Wraps v4l2h264dec and fixes two kernel driver bugs: - framerate=0/1 in output caps - NV12 height alignment (1080 -> 1088) causing wrong UV plane offset
Build (natively on the target):
cargo build --release
sudo cp target/release/libgstamlvenc.so
/usr/lib/aarch64-linux-gnu/gstreamer-1.0/libgstamlvenc_rs.so
rm -f ~/.cache/gstreamer-1.0/registry.*.bin
Requires Rust 1.70+, GStreamer 1.20+ dev libraries, and libamvenc.so on the target system.
Usage:
gst-launch-1.0 videotestsrc num-buffers=300
! video/x-raw,format=NV12,width=1920,height=1080,framerate=25/1
! amlvenc_rs codec=h265 bitrate=2000000
! filesink location=out.h265
gst-launch-1.0 filesrc location=input.h264
! h264parse ! amlvdec_rs framerate=25
! amlvenc_rs codec=h265 bitrate=2000000
! filesink location=out.h265
gst-launch-1.0 rtspsrc location=rtsp://... latency=100
! rtph264depay ! h264parse
! amlvdec_rs framerate=25
! amlvenc_rs codec=h265
! filesink location=out.h265
Performance (1080p NV12, 2Mbps H265, 1000 frames):
Encode-only: 11.3s wall, 2.3s CPU (matches aml_enc_test) HW transcode: 15.7s wall, 9.0s CPU (decode + encode) Per-frame: 15.7ms encode, 2.5x real-time headroom at 25fps
The V4L2 decoder driver accounts for most of the transcode overhead (8.5ms/frame in ioctl calls). The encoder itself has no measurable overhead vs the vendor CLI tool.
Known issues:
If the encoder process is killed (SIGKILL, timeout, OOM), the VPU hardware enters a broken state that persists until reboot. Always stop pipelines with SIGINT. Delete /tmp/vpu_mutex.map after crashes.