frontends/va: Cleanup CreateContext

Also create video processor here, instead of when processing first
picture.

Reviewed-by: Ruijing Dong <ruijing.dong@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36755>
This commit is contained in:
David Rosca
2025-01-23 16:05:03 +01:00
committed by Marge Bot
parent 5e01ec4bd0
commit 5ae6290446
+94 -101
View File
@@ -282,9 +282,9 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width,
vlVaDriver *drv;
vlVaContext *context;
vlVaConfig *config;
int is_vpp;
int min_supported_width, min_supported_height;
int max_supported_width, max_supported_height;
bool create_decoder;
if (!ctx)
return VA_STATUS_ERROR_INVALID_CONTEXT;
@@ -297,105 +297,77 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width,
if (!config)
return VA_STATUS_ERROR_INVALID_CONFIG;
is_vpp = config->profile == PIPE_VIDEO_PROFILE_UNKNOWN && !picture_width &&
!picture_height && !flag && !render_targets && !num_render_targets;
bool is_decode = config->entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM;
bool is_encode = config->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE;
bool is_vpp = config->entrypoint == PIPE_VIDEO_ENTRYPOINT_PROCESSING;
if (!(picture_width && picture_height) && !is_vpp)
return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
create_decoder = is_encode;
if (is_vpp && drv->vscreen->pscreen->get_video_param(drv->vscreen->pscreen,
PIPE_VIDEO_PROFILE_UNKNOWN,
PIPE_VIDEO_ENTRYPOINT_PROCESSING,
PIPE_VIDEO_CAP_SUPPORTED))
create_decoder = true;
if (!is_vpp) {
min_supported_width = drv->vscreen->pscreen->get_video_param(drv->vscreen->pscreen,
config->profile, config->entrypoint,
PIPE_VIDEO_CAP_MIN_WIDTH);
min_supported_height = drv->vscreen->pscreen->get_video_param(drv->vscreen->pscreen,
config->profile, config->entrypoint,
PIPE_VIDEO_CAP_MIN_HEIGHT);
max_supported_width = drv->vscreen->pscreen->get_video_param(drv->vscreen->pscreen,
config->profile, config->entrypoint,
PIPE_VIDEO_CAP_MAX_WIDTH);
max_supported_height = drv->vscreen->pscreen->get_video_param(drv->vscreen->pscreen,
config->profile, config->entrypoint,
PIPE_VIDEO_CAP_MAX_HEIGHT);
if (picture_width < min_supported_width || picture_height < min_supported_height ||
picture_width > max_supported_width || picture_height > max_supported_height)
return VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
}
context = CALLOC(1, sizeof(vlVaContext));
if (!context)
return VA_STATUS_ERROR_ALLOCATION_FAILED;
if (is_vpp && !drv->vscreen->pscreen->get_video_param(drv->vscreen->pscreen,
PIPE_VIDEO_PROFILE_UNKNOWN,
PIPE_VIDEO_ENTRYPOINT_PROCESSING,
PIPE_VIDEO_CAP_SUPPORTED)) {
context->decoder = NULL;
} else {
if (config->entrypoint != PIPE_VIDEO_ENTRYPOINT_PROCESSING) {
min_supported_width = drv->vscreen->pscreen->get_video_param(drv->vscreen->pscreen,
config->profile, config->entrypoint,
PIPE_VIDEO_CAP_MIN_WIDTH);
min_supported_height = drv->vscreen->pscreen->get_video_param(drv->vscreen->pscreen,
config->profile, config->entrypoint,
PIPE_VIDEO_CAP_MIN_HEIGHT);
max_supported_width = drv->vscreen->pscreen->get_video_param(drv->vscreen->pscreen,
config->profile, config->entrypoint,
PIPE_VIDEO_CAP_MAX_WIDTH);
max_supported_height = drv->vscreen->pscreen->get_video_param(drv->vscreen->pscreen,
config->profile, config->entrypoint,
PIPE_VIDEO_CAP_MAX_HEIGHT);
if (picture_width < min_supported_width || picture_height < min_supported_height ||
picture_width > max_supported_width || picture_height > max_supported_height) {
FREE(context);
return VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
}
}
context->templat.profile = config->profile;
context->templat.entrypoint = config->entrypoint;
context->templat.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420;
context->templat.width = picture_width;
context->templat.height = picture_height;
context->templat.expect_chunked_decode = true;
if (config->entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM)
context->desc.base.protected_playback = flag & VL_VA_CREATE_CONTEXT_PROTECTED;
switch (u_reduce_video_profile(context->templat.profile)) {
case PIPE_VIDEO_FORMAT_MPEG12:
case PIPE_VIDEO_FORMAT_VC1:
case PIPE_VIDEO_FORMAT_MPEG4:
context->templat.max_references = 2;
break;
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
context->templat.max_references = 0;
if (config->entrypoint != PIPE_VIDEO_ENTRYPOINT_ENCODE) {
context->desc.h264.pps = CALLOC_STRUCT(pipe_h264_pps);
if (!context->desc.h264.pps) {
FREE(context);
return VA_STATUS_ERROR_ALLOCATION_FAILED;
}
context->desc.h264.pps->sps = CALLOC_STRUCT(pipe_h264_sps);
if (!context->desc.h264.pps->sps) {
FREE(context->desc.h264.pps);
FREE(context);
return VA_STATUS_ERROR_ALLOCATION_FAILED;
}
}
break;
case PIPE_VIDEO_FORMAT_HEVC:
if (config->entrypoint != PIPE_VIDEO_ENTRYPOINT_ENCODE) {
context->desc.h265.pps = CALLOC_STRUCT(pipe_h265_pps);
if (!context->desc.h265.pps) {
FREE(context);
return VA_STATUS_ERROR_ALLOCATION_FAILED;
}
context->desc.h265.pps->sps = CALLOC_STRUCT(pipe_h265_sps);
if (!context->desc.h265.pps->sps) {
FREE(context->desc.h265.pps);
FREE(context);
return VA_STATUS_ERROR_ALLOCATION_FAILED;
}
}
break;
case PIPE_VIDEO_FORMAT_VP9:
break;
default:
break;
}
}
context->templat.profile = config->profile;
context->templat.entrypoint = config->entrypoint;
context->templat.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420;
context->templat.width = picture_width;
context->templat.height = picture_height;
context->templat.expect_chunked_decode = true;
context->desc.base.profile = config->profile;
context->desc.base.entry_point = config->entrypoint;
if (config->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) {
switch (u_reduce_video_profile(context->templat.profile)) {
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
if (config->entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM)
context->desc.base.protected_playback = flag & VL_VA_CREATE_CONTEXT_PROTECTED;
switch (u_reduce_video_profile(context->templat.profile)) {
case PIPE_VIDEO_FORMAT_MPEG12:
case PIPE_VIDEO_FORMAT_VC1:
case PIPE_VIDEO_FORMAT_MPEG4:
context->templat.max_references = 2;
break;
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
if (is_decode) {
context->desc.h264.pps = CALLOC_STRUCT(pipe_h264_pps);
if (!context->desc.h264.pps) {
FREE(context);
return VA_STATUS_ERROR_ALLOCATION_FAILED;
}
context->desc.h264.pps->sps = CALLOC_STRUCT(pipe_h264_sps);
if (!context->desc.h264.pps->sps) {
FREE(context->desc.h264.pps);
FREE(context);
return VA_STATUS_ERROR_ALLOCATION_FAILED;
}
} else if (is_encode) {
context->templat.max_references = PIPE_H264_MAX_REFERENCES;
for (unsigned i = 0; i < ARRAY_SIZE(context->desc.h264enc.rate_ctrl); i++) {
context->desc.h264enc.rate_ctrl[i].rate_ctrl_method = config->rc;
@@ -409,8 +381,23 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width,
}
context->desc.h264enc.frame_idx = util_hash_table_create_ptr_keys();
util_dynarray_init(&context->desc.h264enc.raw_headers, NULL);
break;
case PIPE_VIDEO_FORMAT_HEVC:
}
break;
case PIPE_VIDEO_FORMAT_HEVC:
if (is_decode) {
context->desc.h265.pps = CALLOC_STRUCT(pipe_h265_pps);
if (!context->desc.h265.pps) {
FREE(context);
return VA_STATUS_ERROR_ALLOCATION_FAILED;
}
context->desc.h265.pps->sps = CALLOC_STRUCT(pipe_h265_sps);
if (!context->desc.h265.pps->sps) {
FREE(context->desc.h265.pps);
FREE(context);
return VA_STATUS_ERROR_ALLOCATION_FAILED;
}
} else if (is_encode) {
context->templat.max_references = PIPE_H265_MAX_REFERENCES;
for (unsigned i = 0; i < ARRAY_SIZE(context->desc.h265enc.rc); i++) {
context->desc.h265enc.rc[i].rate_ctrl_method = config->rc;
@@ -424,8 +411,11 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width,
}
context->desc.h265enc.frame_idx = util_hash_table_create_ptr_keys();
util_dynarray_init(&context->desc.h265enc.raw_headers, NULL);
break;
case PIPE_VIDEO_FORMAT_AV1:
}
break;
case PIPE_VIDEO_FORMAT_AV1:
if (is_encode) {
context->templat.max_references = PIPE_AV1_MAX_REFERENCES;
for (unsigned i = 0; i < ARRAY_SIZE(context->desc.av1enc.rc); i++) {
context->desc.av1enc.rc[i].rate_ctrl_method = config->rc;
@@ -438,11 +428,18 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width,
context->desc.av1enc.rc[i].frame_rate_num = 30;
context->desc.av1enc.rc[i].frame_rate_den = 1;
}
break;
default:
break;
}
break;
default:
break;
}
mtx_init(&context->mutex, mtx_plain);
context->surfaces = _mesa_set_create(NULL, _mesa_hash_pointer, _mesa_key_pointer_equal);
context->buffers = _mesa_set_create(NULL, _mesa_hash_pointer, _mesa_key_pointer_equal);
if (create_decoder) {
mtx_lock(&drv->mutex);
context->decoder = drv->pipe->create_video_codec(drv->pipe, &context->templat);
mtx_unlock(&drv->mutex);
@@ -450,10 +447,6 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width,
return VA_STATUS_ERROR_ALLOCATION_FAILED;
}
mtx_init(&context->mutex, mtx_plain);
context->surfaces = _mesa_set_create(NULL, _mesa_hash_pointer, _mesa_key_pointer_equal);
context->buffers = _mesa_set_create(NULL, _mesa_hash_pointer, _mesa_key_pointer_equal);
mtx_lock(&drv->mutex);
*context_id = handle_table_add(drv->htab, context);
mtx_unlock(&drv->mutex);