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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user