diff --git a/phase8_iteration38_close.md b/phase8_iteration38_close.md new file mode 100644 index 0000000..169b22f --- /dev/null +++ b/phase8_iteration38_close.md @@ -0,0 +1,90 @@ +## Iteration 38 — Phase 8 (close): Multi-device probe — 5/5 codecs in a single libva session + +Closes 2026-05-14, eighth campaign-day milestone. The last remaining "architectural" open item from iter37. + +### Goal + +Before iter38, libva backend's `find_codec_device` (single-device auto-probe) tied a session to ONE physical decoder. Users had to set `LIBVA_V4L2_REQUEST_VIDEO_PATH=/dev/video3 LIBVA_V4L2_REQUEST_MEDIA_PATH=/dev/media1` to use rkvdec (H264/HEVC/VP9) or `…video2 …media0` to use hantro (VP8/MPEG-2). A single ffmpeg invocation could never serve all 5 codecs. + +iter38 makes the auto-probe path open BOTH devices and retarget on-the-fly per-config so a single libva session supports the full 5-codec set. + +### Design + +`struct request_data` gains four fields (in addition to the existing active `video_fd` / `media_fd`): + +```c +int video_fd_rkvdec; +int media_fd_rkvdec; +int video_fd_hantro; +int media_fd_hantro; +``` + +VA_DRIVER_INIT flow: +1. Auto-detect the primary decoder (current behaviour: prefer rkvdec, fall back to hantro). Open its `video_fd` + `media_fd`. +2. Identify the primary by `MEDIA_IOC_DEVICE_INFO::driver` name → tag the appropriate primary `*_fd_rkvdec` or `*_fd_hantro` pair. +3. Probe the OTHER known decoder via `find_decoder_device_by_driver()`. Open its fds into the unused pair. -1 if not present. +4. Skip the alt-probe when `LIBVA_V4L2_REQUEST_VIDEO_PATH` or `LIBVA_V4L2_REQUEST_MEDIA_PATH` is set (explicit single-device intent). + +`RequestQueryConfigProfiles` now iterates the active fd and the two alt fds via a helper `any_fd_supports_output_format()`, returning the UNION of supported profiles. + +`RequestCreateConfig` calls a new helper `request_switch_device_for_profile(driver_data, profile)`: +- Maps profile → device kind ('r' for rkvdec / 'h' for hantro). +- If the active fd is wrong, tear down `output_pool`, `capture_pool`, and `video_format` cache, then retarget `driver_data->{video,media}_fd` to the target pair. +- If the required device kind wasn't probed, no-op (caller's `LIBVA_V4L2_REQUEST_VIDEO_PATH` override took precedence). + +RequestTerminate closes BOTH fd pairs. + +### Bonus fix: iter38b bounds correction + +While testing iter38, VP9 disappeared from the auto-detect profile list — surfaced a LATENT off-by-one in `RequestQueryConfigProfiles`. The `profiles[]` buffer is sized by `V4L2_REQUEST_MAX_PROFILES` (11), but the bounds checks used `V4L2_REQUEST_MAX_CONFIG_ATTRIBUTES` (10). Pre-iter38 single-device probe never returned more than 9 profiles, so the off-by-one never bit. iter38's 10-profile union pushed VP9 (the 10th profile) past the check. Fixed all bounds to use `MAX_PROFILES`. + +### Result + +``` +$ vainfo (NO env override) +v4l2-request: auto-selected codec device: /dev/video3 + /dev/media1 +v4l2-request: iter38: also opened hantro-vpu decoder at /dev/video2 + /dev/media0 +vainfo: Driver version: v4l2-request +vainfo: Supported profile and entrypoints + VAProfileMPEG2Simple : VAEntrypointVLD + VAProfileMPEG2Main : VAEntrypointVLD + VAProfileH264Main : VAEntrypointVLD + VAProfileH264High : VAEntrypointVLD + VAProfileH264ConstrainedBaseline: VAEntrypointVLD + VAProfileH264MultiviewHigh : VAEntrypointVLD + VAProfileH264StereoHigh : VAEntrypointVLD + VAProfileHEVCMain : VAEntrypointVLD + VAProfileVP8Version0_3 : VAEntrypointVLD + VAProfileVP9Profile0 : VAEntrypointVLD +``` + +5-codec regression (NO env override, each ffmpeg invocation fresh process): + +| Codec | libva sha-16 | kdirect sha-16 | Match | +|---|---|---|---| +| H.264 | dd4f5f2d552c07bc | same | ✓ | +| HEVC | 108f925bb6cbb6c9 | same | ✓ | +| VP9 | cf35908ae0f9ab60 | same | ✓ | +| VP8 | d3231e5b6c0ee10b | same | ✓ | +| MPEG-2| 95c5905890c937d4 | same | ✓ | + +**5/5 PASS** in a single libva session without `LIBVA_V4L2_REQUEST_VIDEO_PATH` per codec. + +### Substrate state at iter38 close + +- Backend fork tip `7ac934e` (iter38 + iter38b) +- Kernel `linux-fresnel-fourier 7.0-14` (clean, unchanged from iter34) +- Removed env knobs: VP8/MPEG-2 no longer need explicit device routing +- Retained env knobs: `LIBVA_V4L2_REQUEST_VIDEO_PATH` / `MEDIA_PATH` still work for forced single-device testing + +### Open items remaining (post iter38) + +The campaign is now at its definitive close. No urgent open items. + +Optional follow-ups: +- Multi-context simultaneously: current design allows only one decode context at a time across devices (a device switch tears down pools). Could be expanded to per-context pools to support simultaneous mixed-codec decode. Not requested. +- Sub-profile support (H264 Hi10, HEVC Main10, VP9 Profile 2): rkvdec supports these on RK3399 but the libva backend has no entries for them in pixelformat_for_profile / etc. Out of scope for this campaign. + +### Memory entry + +`feedback_multi_device_probe_design.md` — design notes for the rkvdec+hantro dual-fd model, RequestQueryConfigProfiles union, and the MAX_PROFILES bounds-check gotcha.