From 5ae6290446f6d85e2b79adb5ac73674404fdb344 Mon Sep 17 00:00:00 2001 From: David Rosca Date: Thu, 23 Jan 2025 16:05:03 +0100 Subject: [PATCH] frontends/va: Cleanup CreateContext Also create video processor here, instead of when processing first picture. Reviewed-by: Ruijing Dong Part-of: --- src/gallium/frontends/va/context.c | 195 ++++++++++++++--------------- 1 file changed, 94 insertions(+), 101 deletions(-) diff --git a/src/gallium/frontends/va/context.c b/src/gallium/frontends/va/context.c index cc91b9b4da3..b541b5dbd04 100644 --- a/src/gallium/frontends/va/context.c +++ b/src/gallium/frontends/va/context.c @@ -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);