STUDY.md: checkpoint after first-day port work

Update with current state: library builds clean, vainfo enumerates
profiles, vaCreateContext succeeds on Brave (with STREAMON deferred as
WIP unblocker), next failure is frame pool initialization in
vaCreateSurfaces2. Documents the 12-step diff stack vs bootlin upstream
and what still needs to happen to actually decode a frame.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-25 22:10:11 +00:00
parent 44a73271ae
commit f2c3a4c32f
+60 -16
View File
@@ -23,26 +23,70 @@ a working libva-v4l2-request to bridge.
## State today
Initial commits applied to bootlin tip `a3c2476`:
Bootlin tip is `a3c2476`. Stack of WIP commits on top:
1. `V4L2_PIX_FMT_H264_SLICE_RAW``V4L2_PIX_FMT_H264_SLICE` (kernel UAPI rename).
2. `src/h264.c`: missing `#include "utils.h"` for `request_log()` (GCC 14 fatal).
3. HEVC stripped — h265.c/h265.h excluded from `meson.build`, hevc-ctrls.h
replaced by passthrough to `<linux/v4l2-controls.h>`, four HEVC case blocks
removed from `picture.c` (kernel `V4L2_CID_MPEG_VIDEO_HEVC_*` was renamed
to `V4L2_CID_STATELESS_HEVC_*`; ohm has no HW HEVC anyway).
4. `src/config.c`: profile probe falls back to `V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE`
when single-plane returns no formats. **`vainfo` now lists H.264 + MPEG-2
profiles on ohm**, and Brave's GPU process picks them up via VAAPI.
### Build cleanly against current kernel UAPI
Failure mode reached and stuck on:
1. `V4L2_PIX_FMT_H264_SLICE_RAW``V4L2_PIX_FMT_H264_SLICE` rename.
2. `src/h264.c`: missing `#include "utils.h"` for `request_log()`.
3. HEVC stripped — `h265.c`/`h265.h` excluded from `meson.build`,
`hevc-ctrls.h` replaced by passthrough to `<linux/v4l2-controls.h>`,
four HEVC case blocks removed from `picture.c`.
4. `include/h264-ctrls.h` made into a passthrough shim to
`<linux/v4l2-controls.h>` plus `V4L2_CID_MPEG_VIDEO_H264_* →
V4L2_CID_STATELESS_H264_*` aliases (kernel renamed during upstreaming).
5. `src/h264.c` shape updates to track the upstreamed `struct
v4l2_ctrl_h264_slice_params`: drop `.size`, use `struct
v4l2_h264_reference {fields, index}` for `ref_pic_list*`, move
`pred_weight_table` out to its own `V4L2_CID_STATELESS_H264_PRED_WEIGHTS`
control, drop `decode_params.num_slices` (kernel infers from queued
controls).
6. `src/tiled_yuv.S`: aarch64 stub of `tiled_to_planar` — the ARMv7 NEON
body is `#ifndef __aarch64__`-guarded; without a stub the `.so` had
an undefined symbol and dlopen failed.
```
ERROR:media/gpu/vaapi/vaapi_wrapper.cc:2407] vaCreateContext failed,
VA error: operation failed
```
Library now builds clean (~265 KB `.so`) and `vainfo` enumerates H.264 +
MPEG-2 profiles.
That's the next-phase boundary — the real port work below.
### Probe + control flow fixes
7. `src/video.c`: add NV12 multi-plane format entry; `video_format_find()`
takes `bool mplane` so single- and multi-plane NV12 entries don't
collide on pixelformat.
8. `src/surface.c`: probe block tries `V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE`
as a fallback after single-plane probes fail.
9. **Eager probe in `RequestInit`** — Chromium's vaapi_video_decoder calls
`vaCreateContext` *before* `vaCreateSurfaces2`, so the original lazy
"set `driver_data->video_format` in `RequestCreateSurfaces`" path was
too late. Promoted the probe into `video_format_probe()` in
`video.c` and call it at init time.
10. `src/context.c`: same `V4L2_PIX_FMT_H264_SLICE_RAW → _SLICE` rename
that was missed in the first pass.
11. **WIP**: defer `STREAMON` calls in `RequestCreateContext`. The V4L2
stateless protocol on hantro requires OUTPUT format → SPS controls →
first slice queued → THEN `STREAMON`. Deferring lets `vaCreateContext`
succeed; proper sequencing is the next phase.
### Diagnostic logging (will revert before final)
12. `src/utils.c`: `request_log()` tees to `/tmp/libva-fourier.log` so
sandboxed Chromium GPU processes don't swallow the trace output.
### Failure mode reached now (2026-04-26)
`vainfo` works fully. Brave on ohm with the patched `.so` reaches deeper:
- Init: detects NV12 multi-plane CAPTURE format ✓
- vaCreateContext: profile=H264Main 1920×1088, S_FMT + CREATE_BUFS pass ✓
- vaCreateContext: STREAMON OUTPUT returned EINVAL ← deferred to unblock
- Now stuck at: `failed Initialize()ing the frame pool` from
`vaapi_video_decoder.cc`
That's the next-phase boundary. `vaCreateSurfaces2` (frame-pool init) is
where Chromium discovers buffer geometry for output frames; the library
needs to do CAPTURE-side `S_FMT` + `REQBUFS` + `EXPBUF` without single-
plane assumptions on a freshly-created context, and the V4L2 stateless
protocol's source-change-event dance probably needs implementing too.
## Port plan