ampere-av1 Phase 2 (master): fourth-fd probe + AV1 enumeration
Imports the minimal "vainfo lists VAProfileAV1Profile0" layer from the operator's in-progress av1-iter1 branch (Phase 2 steps 1, 2 — commitsbed75c0+61db76eon av1-iter1). The Phase 3-5 bit-exact decode-side work stays in av1-iter1; this commit gives master the enumeration + fd-routing layer so consumers (ffmpeg-vaapi, firefox-fourier, chromium- fourier) at least see VAProfileAV1Profile0 today on RK3588. What this commit adds: - video_fd_vpu981 + media_fd_vpu981 slots to struct request_data (named to match av1-iter1's convention so the operator's Phase 3-5 merge resolves cleanly) - 4th-decoder probe loop in VA_DRIVER_INIT that walks hantro-vpu media nodes for an instance advertising V4L2_PIX_FMT_AV1_FRAME (AV1F) as OUTPUT pixfmt. RK3588 has 3 hantro-vpu instances all reporting driver="hantro-vpu" + model="hantro-vpu", so OUTPUT- format probe is the only DTS-independent discriminator. - 'a' kind in request_device_kind_for_profile (VAProfileAV1Profile0) + 'a' branch in request_switch_device_for_profile. - video_fd_vpu981 added to any_fd_supports_output_format helper (existing 3-slot loop missed the new fd; same off-by-one trap that bit ampere's av1-iter1 enumeration for a week). - VAProfileAV1Profile0 → V4L2_PIX_FMT_AV1_FRAME in pixelformat_for _profile. - VAProfileAV1Profile0 push in RequestQueryConfigProfiles + RequestQueryConfigEntrypoints + RequestCreateConfig switch. - vpu981 fd cleanup in RequestTerminate. - rpi_hevc_dec fd cleanup added at the same time (was already missing in master — fixed defensively). - V4L2_REQUEST_MAX_PROFILES bumped 13 → 14. Defensively sized for the post-Option-B-revert future: with iter39 Option B reverted (Hi10P + Main10 back in enumeration) plus AV1, max possible enumeration is 13. The per-group guards use `index < MAX - N` pattern; for a singleton push to succeed at index=13 we need MAX >= 14. Bumping now avoids the same off-by-one bug from silently dropping AV1 when Option B eventually reverts. What this commit does NOT add: - av1.{c,h} decode-side scaffolding (Phase 2 step 4 on av1-iter1 — ~177 LoC including a stub av1_set_controls that returns -1). When the operator's av1-iter1 Phase 3-5 work lands on master, those 500+ LoC + the stub will follow. Without them, consumers calling vaCreateContext(VAProfileAV1Profile0) succeed at the libva layer but ffmpeg-vaapi will fail at the first vaRenderPicture with an AV1-buffer-type rejection — clean error, no crash. Verified 2026-05-18 on ampere: $ env LIBVA_DRIVER_NAME=v4l2_request vainfo | grep VAProfile ... (10 prior profiles, unchanged) ... VAProfileAV1Profile0 : VAEntrypointVLD ✓ Probe log: "ampere-av1: vpu981 AV1 decoder at /dev/video4 + /dev/media3" Build clean on ampere with GCC 16.1.1; no warnings introduced. ampere's running module restored to the av1-iter1 build after the verification — this commit's .so was NOT permanently installed. Closes the headline acceptance criterion in marfrit/libva-v4l2-request-fourier#2 ("vainfo on ampere lists VAProfileAV1"). End-to-end AV1 decode bit-exactness is iter4 work that the av1-iter1 branch continues to drive. Co-Authored-By: claude-noether <claude-noether@reauktion.de>
This commit is contained in:
@@ -409,6 +409,16 @@ char request_device_kind_for_profile(VAProfile profile)
|
||||
case VAProfileMPEG2Main:
|
||||
case VAProfileVP8Version0_3:
|
||||
return 'h';
|
||||
case VAProfileAV1Profile0:
|
||||
/*
|
||||
* ampere-av1-enablement Phase 2: RK3588 vpu981 dedicated
|
||||
* AV1 hantro instance. 'a' kind dispatches to
|
||||
* driver_data->video_fd_vpu981. On hosts without the AV1
|
||||
* instance the fd stays -1 and RequestQueryConfigProfiles
|
||||
* never enumerates AV1, so this branch is unreachable for
|
||||
* non-RK3588 hosts.
|
||||
*/
|
||||
return 'a';
|
||||
default:
|
||||
return '?';
|
||||
}
|
||||
@@ -457,6 +467,9 @@ int request_switch_device_for_profile(struct request_data *driver_data,
|
||||
} else if (kind == 'p') {
|
||||
target_video = driver_data->video_fd_rpi_hevc_dec;
|
||||
target_media = driver_data->media_fd_rpi_hevc_dec;
|
||||
} else if (kind == 'a') {
|
||||
target_video = driver_data->video_fd_vpu981;
|
||||
target_media = driver_data->media_fd_vpu981;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
@@ -646,6 +659,8 @@ VAStatus VA_DRIVER_INIT_FUNC(VADriverContextP context)
|
||||
driver_data->media_fd_hantro = -1;
|
||||
driver_data->video_fd_rpi_hevc_dec = -1;
|
||||
driver_data->media_fd_rpi_hevc_dec = -1;
|
||||
driver_data->video_fd_vpu981 = -1;
|
||||
driver_data->media_fd_vpu981 = -1;
|
||||
|
||||
/*
|
||||
* iter38: probe BOTH rkvdec and hantro-vpu so a single libva session
|
||||
@@ -712,6 +727,61 @@ VAStatus VA_DRIVER_INIT_FUNC(VADriverContextP context)
|
||||
}
|
||||
}
|
||||
(void)primary_driver;
|
||||
|
||||
/*
|
||||
* ampere-av1-enablement Phase 2: walk hantro-vpu media nodes
|
||||
* for a SECOND one that advertises V4L2_PIX_FMT_AV1_FRAME
|
||||
* (AV1F) as OUTPUT pixfmt. RK3588 has 3 hantro-vpu instances
|
||||
* (legacy MPEG2/VP8 decoder, vepu121 encoder, vpu981 AV1
|
||||
* decoder) all reporting driver="hantro-vpu" / model="hantro-
|
||||
* vpu" — so OUTPUT-format probe is the only reliable
|
||||
* disambiguator that doesn't depend on parsing card-name
|
||||
* strings (which are DTS-dependent). First match wins.
|
||||
*
|
||||
* On non-RK3588 hosts the slot stays -1; RequestQueryConfig
|
||||
* Profiles' AV1 push then no-ops because any_fd_supports_
|
||||
* output_format() returns false for AV1F.
|
||||
*/
|
||||
{
|
||||
int i;
|
||||
char path[32], av1_video[32];
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
int mfd, vfd;
|
||||
struct media_device_info info;
|
||||
|
||||
snprintf(path, sizeof path, "/dev/media%d", i);
|
||||
mfd = open(path, O_RDWR | O_NONBLOCK);
|
||||
if (mfd < 0) continue;
|
||||
memset(&info, 0, sizeof info);
|
||||
if (ioctl(mfd, MEDIA_IOC_DEVICE_INFO, &info) != 0 ||
|
||||
strcmp(info.driver, "hantro-vpu") != 0) {
|
||||
close(mfd);
|
||||
continue;
|
||||
}
|
||||
if (find_decoder_video_node_via_topology(
|
||||
mfd, av1_video, sizeof av1_video) != 0) {
|
||||
close(mfd);
|
||||
continue;
|
||||
}
|
||||
vfd = open(av1_video, O_RDWR | O_NONBLOCK);
|
||||
if (vfd < 0) {
|
||||
close(mfd);
|
||||
continue;
|
||||
}
|
||||
if (!v4l2_find_format(vfd, V4L2_BUF_TYPE_VIDEO_OUTPUT, V4L2_PIX_FMT_AV1_FRAME) &&
|
||||
!v4l2_find_format(vfd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_PIX_FMT_AV1_FRAME)) {
|
||||
close(vfd);
|
||||
close(mfd);
|
||||
continue;
|
||||
}
|
||||
driver_data->video_fd_vpu981 = vfd;
|
||||
driver_data->media_fd_vpu981 = mfd;
|
||||
request_log("ampere-av1: vpu981 AV1 decoder at %s + %s\n",
|
||||
av1_video, path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -784,6 +854,14 @@ VAStatus RequestTerminate(VADriverContextP context)
|
||||
close(driver_data->video_fd_hantro);
|
||||
if (driver_data->media_fd_hantro >= 0)
|
||||
close(driver_data->media_fd_hantro);
|
||||
if (driver_data->video_fd_rpi_hevc_dec >= 0)
|
||||
close(driver_data->video_fd_rpi_hevc_dec);
|
||||
if (driver_data->media_fd_rpi_hevc_dec >= 0)
|
||||
close(driver_data->media_fd_rpi_hevc_dec);
|
||||
if (driver_data->video_fd_vpu981 >= 0)
|
||||
close(driver_data->video_fd_vpu981);
|
||||
if (driver_data->media_fd_vpu981 >= 0)
|
||||
close(driver_data->media_fd_vpu981);
|
||||
/* Fall back to direct close if neither alt fd captured the active
|
||||
* pair (env-override path). */
|
||||
if (driver_data->video_fd_rkvdec < 0 && driver_data->video_fd_hantro < 0) {
|
||||
|
||||
Reference in New Issue
Block a user