lavfi/vaapi: remove duplicated code

Add a ff_ function to handle mulitple pipeline parameters. No functional
changes.

Signed-off-by: Haihao Xiang <haihao.xiang@intel.com>
This commit is contained in:
Haihao Xiang 2023-01-13 12:38:30 +08:00
parent f5f1c1fd6b
commit f1a8d3b0b6
3 changed files with 77 additions and 140 deletions

View File

@ -588,17 +588,53 @@ int ff_vaapi_vpp_make_param_buffers(AVFilterContext *avctx,
return 0; return 0;
} }
static int vaapi_vpp_render_single_pipeline_buffer(AVFilterContext *avctx,
VAProcPipelineParameterBuffer *params,
VABufferID *params_id)
{
VAAPIVPPContext *ctx = avctx->priv;
VAStatus vas;
int ff_vaapi_vpp_render_picture(AVFilterContext *avctx, vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
VAProcPipelineParameterBuffer *params, VAProcPipelineParameterBufferType,
AVFrame *output_frame) sizeof(*params), 1, params, params_id);
if (vas != VA_STATUS_SUCCESS) {
av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer: "
"%d (%s).\n", vas, vaErrorStr(vas));
*params_id = VA_INVALID_ID;
return AVERROR(EIO);
}
av_log(avctx, AV_LOG_DEBUG, "Pipeline parameter buffer is %#x.\n", *params_id);
vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context, params_id, 1);
if (vas != VA_STATUS_SUCCESS) {
av_log(avctx, AV_LOG_ERROR, "Failed to render parameter buffer: "
"%d (%s).\n", vas, vaErrorStr(vas));
return AVERROR(EIO);
}
return 0;
}
int ff_vaapi_vpp_render_pictures(AVFilterContext *avctx,
VAProcPipelineParameterBuffer *params_list,
int cout,
AVFrame *output_frame)
{ {
VAAPIVPPContext *ctx = avctx->priv; VAAPIVPPContext *ctx = avctx->priv;
VASurfaceID output_surface; VASurfaceID output_surface;
VABufferID params_id; VABufferID *params_ids;
VAStatus vas; VAStatus vas;
int err; int err;
params_ids = (VABufferID *)av_malloc_array(cout, sizeof(VABufferID));
if (!params_ids)
return AVERROR(ENOMEM);
for (int i = 0; i < cout; i++)
params_ids[i] = VA_INVALID_ID;
output_surface = (VASurfaceID)(uintptr_t)output_frame->data[3]; output_surface = (VASurfaceID)(uintptr_t)output_frame->data[3];
vas = vaBeginPicture(ctx->hwctx->display, vas = vaBeginPicture(ctx->hwctx->display,
@ -610,25 +646,10 @@ int ff_vaapi_vpp_render_picture(AVFilterContext *avctx,
goto fail; goto fail;
} }
vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context, for (int i = 0; i < cout; i++) {
VAProcPipelineParameterBufferType, err = vaapi_vpp_render_single_pipeline_buffer(avctx, &params_list[i], &params_ids[i]);
sizeof(*params), 1, params, &params_id); if (err)
if (vas != VA_STATUS_SUCCESS) { goto fail_after_begin;
av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer: "
"%d (%s).\n", vas, vaErrorStr(vas));
err = AVERROR(EIO);
goto fail_after_begin;
}
av_log(avctx, AV_LOG_DEBUG, "Pipeline parameter buffer is %#x.\n",
params_id);
vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,
&params_id, 1);
if (vas != VA_STATUS_SUCCESS) {
av_log(avctx, AV_LOG_ERROR, "Failed to render parameter buffer: "
"%d (%s).\n", vas, vaErrorStr(vas));
err = AVERROR(EIO);
goto fail_after_begin;
} }
vas = vaEndPicture(ctx->hwctx->display, ctx->va_context); vas = vaEndPicture(ctx->hwctx->display, ctx->va_context);
@ -641,14 +662,17 @@ int ff_vaapi_vpp_render_picture(AVFilterContext *avctx,
if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks & if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks &
AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS) { AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS) {
vas = vaDestroyBuffer(ctx->hwctx->display, params_id); for (int i = 0; i < cout && params_ids[i] != VA_INVALID_ID; i++) {
if (vas != VA_STATUS_SUCCESS) { vas = vaDestroyBuffer(ctx->hwctx->display, params_ids[i]);
av_log(avctx, AV_LOG_ERROR, "Failed to free parameter buffer: " if (vas != VA_STATUS_SUCCESS) {
"%d (%s).\n", vas, vaErrorStr(vas)); av_log(avctx, AV_LOG_ERROR, "Failed to free parameter buffer: "
// And ignore. "%d (%s).\n", vas, vaErrorStr(vas));
// And ignore.
}
} }
} }
av_freep(&params_ids);
return 0; return 0;
// We want to make sure that if vaBeginPicture has been called, we also // We want to make sure that if vaBeginPicture has been called, we also
@ -656,13 +680,21 @@ int ff_vaapi_vpp_render_picture(AVFilterContext *avctx,
// do something else nasty, but once we're in this failure case there // do something else nasty, but once we're in this failure case there
// isn't much else we can do. // isn't much else we can do.
fail_after_begin: fail_after_begin:
vaRenderPicture(ctx->hwctx->display, ctx->va_context, &params_id, 1); vaRenderPicture(ctx->hwctx->display, ctx->va_context, &params_ids[0], 1);
fail_after_render: fail_after_render:
vaEndPicture(ctx->hwctx->display, ctx->va_context); vaEndPicture(ctx->hwctx->display, ctx->va_context);
fail: fail:
av_freep(&params_ids);
return err; return err;
} }
int ff_vaapi_vpp_render_picture(AVFilterContext *avctx,
VAProcPipelineParameterBuffer *params,
AVFrame *output_frame)
{
return ff_vaapi_vpp_render_pictures(avctx, params, 1, output_frame);
}
void ff_vaapi_vpp_ctx_init(AVFilterContext *avctx) void ff_vaapi_vpp_ctx_init(AVFilterContext *avctx)
{ {
int i; int i;

View File

@ -83,4 +83,9 @@ int ff_vaapi_vpp_render_picture(AVFilterContext *avctx,
VAProcPipelineParameterBuffer *params, VAProcPipelineParameterBuffer *params,
AVFrame *output_frame); AVFrame *output_frame);
int ff_vaapi_vpp_render_pictures(AVFilterContext *avctx,
VAProcPipelineParameterBuffer *params_list,
int count,
AVFrame *output_frame);
#endif /* AVFILTER_VAAPI_VPP_H */ #endif /* AVFILTER_VAAPI_VPP_H */

View File

@ -159,106 +159,6 @@ static int overlay_vaapi_build_filter_params(AVFilterContext *avctx)
return 0; return 0;
} }
static int overlay_vaapi_render_picture(AVFilterContext *avctx,
VAProcPipelineParameterBuffer *params,
VAProcPipelineParameterBuffer *subpic_params,
AVFrame *output_frame)
{
VAAPIVPPContext *ctx = avctx->priv;
VASurfaceID output_surface;
VABufferID params_id;
VABufferID subpic_params_id;
VAStatus vas;
int err = 0;
output_surface = (VASurfaceID)(uintptr_t)output_frame->data[3];
vas = vaBeginPicture(ctx->hwctx->display,
ctx->va_context, output_surface);
if (vas != VA_STATUS_SUCCESS) {
av_log(avctx, AV_LOG_ERROR, "Failed to attach new picture: "
"%d (%s).\n", vas, vaErrorStr(vas));
err = AVERROR(EIO);
goto fail;
}
vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
VAProcPipelineParameterBufferType,
sizeof(*params), 1, params, &params_id);
if (vas != VA_STATUS_SUCCESS) {
av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer: "
"%d (%s).\n", vas, vaErrorStr(vas));
err = AVERROR(EIO);
goto fail_after_begin;
}
av_log(avctx, AV_LOG_DEBUG, "Pipeline parameter buffer is %#x.\n",
params_id);
vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,
&params_id, 1);
if (vas != VA_STATUS_SUCCESS) {
av_log(avctx, AV_LOG_ERROR, "Failed to render parameter buffer: "
"%d (%s).\n", vas, vaErrorStr(vas));
err = AVERROR(EIO);
goto fail_after_begin;
}
if (subpic_params) {
vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
VAProcPipelineParameterBufferType,
sizeof(*subpic_params), 1, subpic_params, &subpic_params_id);
if (vas != VA_STATUS_SUCCESS) {
av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer: "
"%d (%s).\n", vas, vaErrorStr(vas));
err = AVERROR(EIO);
goto fail_after_begin;
}
av_log(avctx, AV_LOG_DEBUG, "Pipeline subpic parameter buffer is %#x.\n",
subpic_params_id);
vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,
&subpic_params_id, 1);
if (vas != VA_STATUS_SUCCESS) {
av_log(avctx, AV_LOG_ERROR, "Failed to render subpic parameter buffer: "
"%d (%s).\n", vas, vaErrorStr(vas));
err = AVERROR(EIO);
goto fail_after_begin;
}
}
vas = vaEndPicture(ctx->hwctx->display, ctx->va_context);
if (vas != VA_STATUS_SUCCESS) {
av_log(avctx, AV_LOG_ERROR, "Failed to start picture processing: "
"%d (%s).\n", vas, vaErrorStr(vas));
err = AVERROR(EIO);
goto fail_after_render;
}
if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks &
AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS) {
vas = vaDestroyBuffer(ctx->hwctx->display, params_id);
if (vas != VA_STATUS_SUCCESS) {
av_log(avctx, AV_LOG_ERROR, "Failed to free parameter buffer: "
"%d (%s).\n", vas, vaErrorStr(vas));
// And ignore.
}
}
return 0;
// We want to make sure that if vaBeginPicture has been called, we also
// call vaRenderPicture and vaEndPicture. These calls may well fail or
// do something else nasty, but once we're in this failure case there
// isn't much else we can do.
fail_after_begin:
vaRenderPicture(ctx->hwctx->display, ctx->va_context, &params_id, 1);
fail_after_render:
vaEndPicture(ctx->hwctx->display, ctx->va_context);
fail:
return err;
}
static int overlay_vaapi_blend(FFFrameSync *fs) static int overlay_vaapi_blend(FFFrameSync *fs)
{ {
AVFilterContext *avctx = fs->parent; AVFilterContext *avctx = fs->parent;
@ -267,7 +167,7 @@ static int overlay_vaapi_blend(FFFrameSync *fs)
VAAPIVPPContext *vpp_ctx = avctx->priv; VAAPIVPPContext *vpp_ctx = avctx->priv;
AVFrame *input_main, *input_overlay; AVFrame *input_main, *input_overlay;
AVFrame *output; AVFrame *output;
VAProcPipelineParameterBuffer params, subpic_params; VAProcPipelineParameterBuffer params[2];
VABlendState blend_state = { 0 }; /**< Blend State */ VABlendState blend_state = { 0 }; /**< Blend State */
VARectangle overlay_region, output_region; VARectangle overlay_region, output_region;
int err; int err;
@ -296,7 +196,7 @@ static int overlay_vaapi_blend(FFFrameSync *fs)
if (err < 0) if (err < 0)
goto fail; goto fail;
err = ff_vaapi_vpp_init_params(avctx, &params, err = ff_vaapi_vpp_init_params(avctx, &params[0],
input_main, output); input_main, output);
if (err < 0) if (err < 0)
goto fail; goto fail;
@ -308,11 +208,11 @@ static int overlay_vaapi_blend(FFFrameSync *fs)
.height = output->height, .height = output->height,
}; };
params.filters = &vpp_ctx->filter_buffers[0]; params[0].filters = &vpp_ctx->filter_buffers[0];
params.num_filters = vpp_ctx->nb_filter_buffers; params[0].num_filters = vpp_ctx->nb_filter_buffers;
params.output_region = &output_region; params[0].output_region = &output_region;
params.output_background_color = VAAPI_VPP_BACKGROUND_BLACK; params[0].output_background_color = VAAPI_VPP_BACKGROUND_BLACK;
if (input_overlay) { if (input_overlay) {
av_log(avctx, AV_LOG_DEBUG, "Filter overlay: %s, %ux%u (%"PRId64").\n", av_log(avctx, AV_LOG_DEBUG, "Filter overlay: %s, %ux%u (%"PRId64").\n",
@ -333,17 +233,17 @@ static int overlay_vaapi_blend(FFFrameSync *fs)
"will crop the overlay image according based on the main image.\n"); "will crop the overlay image according based on the main image.\n");
} }
memcpy(&subpic_params, &params, sizeof(subpic_params)); memcpy(&params[1], &params[0], sizeof(params[0]));
blend_state.flags = ctx->blend_flags; blend_state.flags = ctx->blend_flags;
blend_state.global_alpha = ctx->blend_alpha; blend_state.global_alpha = ctx->blend_alpha;
subpic_params.blend_state = &blend_state; params[1].blend_state = &blend_state;
subpic_params.surface = (VASurfaceID)(uintptr_t)input_overlay->data[3]; params[1].surface = (VASurfaceID)(uintptr_t)input_overlay->data[3];
subpic_params.output_region = &overlay_region; params[1].output_region = &overlay_region;
} }
err = overlay_vaapi_render_picture(avctx, &params, input_overlay ? &subpic_params : NULL, output); err = ff_vaapi_vpp_render_pictures(avctx, params, input_overlay ? 2 : 1, output);
if (err < 0) if (err < 0)
goto fail; goto fail;