# V4L2 inventory findings — fresnel 2026-05-07 Companion to [`v4l2_inventory.txt`](v4l2_inventory.txt) (raw `v4l2-ctl` / `media-ctl` / sysfs output captured 2026-05-07T22:34 CEST). ## Verified facts ### Two decode blocks, six v4l2 nodes total | Node | Driver | DT compatible | Function | |---|---|---|---| | `/dev/video0` | `rockchip-rga` | `rockchip,rk3399-rga` | RGA scaler/converter (out of scope) | | `/dev/video1` | `uvcvideo` | — | USB camera capture | | `/dev/video2` | `uvcvideo` | — | USB camera metadata | | `/dev/video3` | `rkvdec` | `rockchip,rk3399-vdec` | Stateless decoder (3 codecs) | | `/dev/video4` | `hantro-vpu` | `rockchip,rk3399-vpu` | Encoder (JPEG only) | | `/dev/video5` | `hantro-vpu` | `rockchip,rk3399-vpu` | Stateless decoder (2 codecs) | `/dev/video4` and `/dev/video5` share the parent platform device `ff650000.video-codec` — same hantro IP, two function instances (enc + dec). ### Decoder codec surface (authoritative — from `--list-formats-out`) **`/dev/video3` (rkvdec)** — three codecs: ``` [0]: 'S265' (HEVC Parsed Slice Data, compressed) [1]: 'S264' (H.264 Parsed Slice Data, compressed) [2]: 'VP9F' (VP9 Frame, compressed) ``` CAPTURE: NV12 only. **`/dev/video5` (hantro-vpu-dec)** — two codecs: ``` [0]: 'MG2S' (MPEG-2 Parsed Slice Data, compressed) [1]: 'VP8F' (VP8 Frame, compressed) ``` CAPTURE: NV12 only. ### Profile/level menus (from `--list-ctrls-menus`) rkvdec exposes: - **H.264 profiles**: Constrained Baseline, Main, **High**, High 10, High 422, High 10 Intra, High 422 Intra. Levels 1 through 5.1 (16 entries). Note: 10-bit/422 entries listed are kernel-driver enumeration, not necessarily silicon-supported — the rkvdec driver may reject these at request submission. - **HEVC profiles**: Main, Main Still Picture, **Main 10**. Levels 1 through 5.1 (9 entries). - **VP9 profile**: 0 only (8-bit 4:2:0). No profile-2 (10-bit), profile-1 (4:4:4), or profile-3 listed. hantro-vpu-dec exposes **no** profile/level menus — MPEG-2 and VP8 don't need them. ### Stateless control payloads rkvdec accepts: - H.264: `H264_DECODE_MODE` (Frame-Based), `H264_START_CODE` (Annex B), SPS, PPS, scaling matrix, decode params. - HEVC: `HEVC_DECODE_MODE` (Frame-Based), `HEVC_START_CODE` (Annex B), SPS, PPS, slice params (dynamic-array, max 600 elems), scaling matrix, decode params. - VP9: `VP9_FRAME` (frame decode params), `VP9_PROBABILITIES_UPDATES` (control type 260). hantro-vpu-dec accepts: - VP8: `VP8_FRAME` (frame decode params). - MPEG-2: `MPEG_2_SEQUENCE_HEADER`, `MPEG_2_PICTURE_HEADER`, `MPEG_2_QUANTISATION_MATRICES`. Both drivers report `value=unsupported payload type` from `v4l2-ctl` for compound controls — normal; v4l2-ctl can't serialize them, the kernel ABI uses `VIDIOC_S_EXT_CTRLS` with `V4L2_CTRL_WHICH_REQUEST_VAL`. ### Media controller topology - `/dev/media0` → uvcvideo (USB cam), entities 1/4/8/11/14. - `/dev/media1` → rkvdec, simple source→proc→sink (3 entities). - `/dev/media2` → hantro-vpu, holds **both** enc and dec sub-pipelines under one media device. Decode sub-pipeline: entities 15/17/20 (`rockchip,rk3399-vpu-dec-source` → `-proc` → `-sink`). Encode sub-pipeline: entities 1/3/6. For per-codec `media_path` resolution the libva backend can use either fixed device-node paths (simple) or media-controller graph traversal (matches Bootlin sunxi-cedrus pattern). Phase 4 design decision. ## Corrections required in locked Phase 0 docs `phase0_findings.md` lines 26–28 and `README.md:24–28` claim hantro-vpu-dec on RK3399 supports H.264 (`V4L2_PIX_FMT_H264_SLICE`). **This is wrong on the running kernel `6.19.9-99-eos-arm`.** The actual surface is MPEG-2 + VP8 only. Implications: 1. **Open Question #2 from `phase0_findings.md` is null** — there's no two-block H.264 routing decision to make. H.264 only goes to rkvdec on RK3399. The libva backend's device-selection logic for H.264 has exactly one valid bind target. 2. The "test cells per codec" sentence ("Two test cells per codec: rkvdec-bound H.264 and hantro-vpu-dec-bound H.264.") should be reduced to one cell. 3. Codec scope as locked stays correct in **count** — five codecs, just routed differently: - rkvdec: H.264, HEVC, VP9 - hantro-vpu-dec: MPEG-2, VP8 These corrections should land as a follow-up commit on this campaign repo. Not done in this file to keep evidence and source-of-truth separable. ## Why the doc was wrong Likely carryover from RK3568 (ohm) hantro, which does support H.264 (DT compatible `rockchip,rk3568-vpu`). The RK3399 hantro IP / kernel variant in `drivers/media/platform/verisilicon/` registers a different codec list. The phase0_findings.md table was written without empirical enumeration on this kernel. ## Gaps left for Phase 1+ - Resolution range per codec — not enumerated by `v4l2-ctl --list-formats-out` directly. Will need `v4l2-ctl --try-fmt-out-mplane` probes against rkvdec to find min/max width/height per codec, especially HEVC (4K+ would matter for VP9 but the panel is 1080p so probably moot). - Per-codec slice-mode vs. frame-mode capability — both decoders advertise frame-based only (`*_DECODE_MODE menu min=1 max=1 default=1 (Frame-Based)`). This matches the libva-v4l2-request-fourier fork's slice-buffer accumulation pattern from libva-multiplanar iter4. - Bit-depth limits — `H264_HIGH_10` profile is enumerated on rkvdec but RK3399 silicon doesn't do 10-bit H.264. Test will reveal whether the driver rejects 10-bit submission or just silently produces garbage.