diff --git a/src/context.c b/src/context.c index 04ba9a6..13662ed 100644 --- a/src/context.c +++ b/src/context.c @@ -104,7 +104,7 @@ VAStatus RequestCreateContext(VADriverContextP context, VAConfigID config_id, case VAProfileH264ConstrainedBaseline: case VAProfileH264MultiviewHigh: case VAProfileH264StereoHigh: - pixelformat = V4L2_PIX_FMT_H264_SLICE_RAW; + pixelformat = V4L2_PIX_FMT_H264_SLICE; break; case VAProfileHEVCMain: diff --git a/src/surface.c b/src/surface.c index a6abb9b..2b83304 100644 --- a/src/surface.c +++ b/src/surface.c @@ -73,17 +73,29 @@ VAStatus RequestCreateSurfaces2(VADriverContextP context, unsigned int format, if (!driver_data->video_format) { + /* Single-plane CAPTURE first (the original sunxi-cedrus path) */ found = v4l2_find_format(driver_data->video_fd, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_PIX_FMT_SUNXI_TILED_NV12); if (found) - video_format = video_format_find(V4L2_PIX_FMT_SUNXI_TILED_NV12); + video_format = video_format_find(V4L2_PIX_FMT_SUNXI_TILED_NV12, false); - found = v4l2_find_format(driver_data->video_fd, - V4L2_BUF_TYPE_VIDEO_CAPTURE, - V4L2_PIX_FMT_NV12); - if (found) - video_format = video_format_find(V4L2_PIX_FMT_NV12); + if (video_format == NULL) { + found = v4l2_find_format(driver_data->video_fd, + V4L2_BUF_TYPE_VIDEO_CAPTURE, + V4L2_PIX_FMT_NV12); + if (found) + video_format = video_format_find(V4L2_PIX_FMT_NV12, false); + } + + /* Multi-plane CAPTURE fallback (Rockchip hantro / RK3588 VDPU381) */ + if (video_format == NULL) { + found = v4l2_find_format(driver_data->video_fd, + V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, + V4L2_PIX_FMT_NV12); + if (found) + video_format = video_format_find(V4L2_PIX_FMT_NV12, true); + } if (video_format == NULL) return VA_STATUS_ERROR_OPERATION_FAILED; diff --git a/src/video.c b/src/video.c index 3ccbb29..4e521f5 100644 --- a/src/video.c +++ b/src/video.c @@ -45,6 +45,16 @@ static struct video_format formats[] = { .planes_count = 2, .bpp = 16, }, + { + .description = "NV12 YUV (multi-plane)", + .v4l2_format = V4L2_PIX_FMT_NV12, + .v4l2_buffers_count = 1, + .v4l2_mplane = true, + .drm_format = DRM_FORMAT_NV12, + .drm_modifier = DRM_FORMAT_MOD_NONE, + .planes_count = 2, + .bpp = 16, + }, { .description = "Sunxi tiled NV12 YUV", .v4l2_format = V4L2_PIX_FMT_SUNXI_TILED_NV12, @@ -59,12 +69,13 @@ static struct video_format formats[] = { static unsigned int formats_count = sizeof(formats) / sizeof(formats[0]); -struct video_format *video_format_find(unsigned int pixelformat) +struct video_format *video_format_find(unsigned int pixelformat, bool mplane) { unsigned int i; for (i = 0; i < formats_count; i++) - if (formats[i].v4l2_format == pixelformat) + if (formats[i].v4l2_format == pixelformat && + formats[i].v4l2_mplane == mplane) return &formats[i]; return NULL; diff --git a/src/video.h b/src/video.h index 1996fd5..f82aed6 100644 --- a/src/video.h +++ b/src/video.h @@ -38,7 +38,7 @@ struct video_format { unsigned int bpp; }; -struct video_format *video_format_find(unsigned int pixelformat); +struct video_format *video_format_find(unsigned int pixelformat, bool mplane); bool video_format_is_linear(struct video_format *format); #endif