iter38 close: multi-device probe — 5/5 codecs in one libva session
Closes the last architectural open item from iter37 campaign-close. VA_DRIVER_INIT now opens BOTH rkvdec and hantro fds when no env override is set. RequestQueryConfigProfiles enumerates the union (via any_fd_supports_output_format helper). RequestCreateConfig calls request_switch_device_for_profile to retarget the active fd to the device that serves the profile; tears down output_pool + capture_pool + video_format cache on switch so the next RequestCreateContext rebuilds them on the new device. Bonus iter38b: fixed latent bounds-check bug in RequestQueryConfigProfiles — profile array bounds checks should use MAX_PROFILES (11), not MAX_CONFIG_ATTRIBUTES (10). Pre-iter38 single- device probes never returned more than 9 profiles so the off-by-one never bit. iter38's 10-profile union surfaced it. Result: 5/5 codecs PASS bit-exact vs kdirect with NO env override. $ vainfo (no env) v4l2-request: auto-selected: /dev/video3 + /dev/media1 v4l2-request: iter38: also opened hantro at /dev/video2 + /dev/media0 → all 10 profiles enumerated (MPEG2+H264+HEVC+VP8+VP9) Backend tip 7ac934e.
This commit is contained in:
@@ -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.
|
||||
Reference in New Issue
Block a user