[FFmpeg-devel] [PATCH V3 1/3] libavcodec/vaapi_encode: Add new API adaption to vaapi_encode
Xiang, Haihao
haihao.xiang at intel.com
Fri Feb 11 06:07:22 EET 2022
On Tue, 2022-02-08 at 11:05 +0800, Wenbin Chen wrote:
> Add vaSyncBuffer to VAAPI encoder. Old version API vaSyncSurface wait
> surface to complete. When surface is used for multiple operation, it
> waits all operations to finish. vaSyncBuffer only wait one channel to
> finish.
>
> Add wait param to vaapi_encode_wait() to prepare for the async_depth
> option. "wait=1" means wait until operation ready. "wait=0" means
> query operation's status. If it is ready return 0, if it is still
> in progress return EAGAIN.
>
> Signed-off-by: Wenbin Chen <wenbin.chen at intel.com>
> ---
> libavcodec/vaapi_encode.c | 47 +++++++++++++++++++++++++++++++++------
> 1 file changed, 40 insertions(+), 7 deletions(-)
>
> diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
> index 3bf379b1a0..b87b58a42b 100644
> --- a/libavcodec/vaapi_encode.c
> +++ b/libavcodec/vaapi_encode.c
> @@ -134,7 +134,8 @@ static int
> vaapi_encode_make_misc_param_buffer(AVCodecContext *avctx,
> }
>
> static int vaapi_encode_wait(AVCodecContext *avctx,
> - VAAPIEncodePicture *pic)
> + VAAPIEncodePicture *pic,
> + uint8_t wait)
> {
> VAAPIEncodeContext *ctx = avctx->priv_data;
> VAStatus vas;
> @@ -150,11 +151,43 @@ static int vaapi_encode_wait(AVCodecContext *avctx,
> "(input surface %#x).\n", pic->display_order,
> pic->encode_order, pic->input_surface);
>
> - vas = vaSyncSurface(ctx->hwctx->display, pic->input_surface);
> - if (vas != VA_STATUS_SUCCESS) {
> - av_log(avctx, AV_LOG_ERROR, "Failed to sync to picture completion: "
> - "%d (%s).\n", vas, vaErrorStr(vas));
> +#if VA_CHECK_VERSION(1, 9, 0)
> + // Try vaSyncBuffer.
> + vas = vaSyncBuffer(ctx->hwctx->display,
> + pic->output_buffer,
> + wait ? VA_TIMEOUT_INFINITE : 0);
> + if (vas == VA_STATUS_ERROR_TIMEDOUT) {
> + return AVERROR(EAGAIN);
> + } else if (vas != VA_STATUS_SUCCESS && vas !=
> VA_STATUS_ERROR_UNIMPLEMENTED) {
> + av_log(avctx, AV_LOG_ERROR, "Failed to sync to output buffer
> completion: "
> + "%d (%s).\n", vas, vaErrorStr(vas));
> return AVERROR(EIO);
We may add has_sync_buffer_func flag in this patch, and run the above code when
ctx->has_sync_buffer_func is true. If so, we needn't check whether vaSyncBuffer
is implemented again.
Thanks
Haihao
> + } else if (vas == VA_STATUS_ERROR_UNIMPLEMENTED)
> + // If vaSyncBuffer is not implemented, try old version API.
> +#endif
> + {
> + if (!wait) {
> + VASurfaceStatus surface_status;
> + vas = vaQuerySurfaceStatus(ctx->hwctx->display,
> + pic->input_surface,
> + &surface_status);
> + if (vas == VA_STATUS_SUCCESS &&
> + surface_status != VASurfaceReady &&
> + surface_status != VASurfaceSkipped) {
> + return AVERROR(EAGAIN);
> + } else if (vas != VA_STATUS_SUCCESS) {
> + av_log(avctx, AV_LOG_ERROR, "Failed to query surface status:
> "
> + "%d (%s).\n", vas, vaErrorStr(vas));
> + return AVERROR(EIO);
> + }
> + } else {
> + vas = vaSyncSurface(ctx->hwctx->display, pic->input_surface);
> + if (vas != VA_STATUS_SUCCESS) {
> + av_log(avctx, AV_LOG_ERROR, "Failed to sync to picture
> completion: "
> + "%d (%s).\n", vas, vaErrorStr(vas));
> + return AVERROR(EIO);
> + }
> + }
> }
>
> // Input is definitely finished with now.
> @@ -633,7 +666,7 @@ static int vaapi_encode_output(AVCodecContext *avctx,
> uint8_t *ptr;
> int err;
>
> - err = vaapi_encode_wait(avctx, pic);
> + err = vaapi_encode_wait(avctx, pic, 1);
> if (err < 0)
> return err;
>
> @@ -695,7 +728,7 @@ fail:
> static int vaapi_encode_discard(AVCodecContext *avctx,
> VAAPIEncodePicture *pic)
> {
> - vaapi_encode_wait(avctx, pic);
> + vaapi_encode_wait(avctx, pic, 1);
>
> if (pic->output_buffer_ref) {
> av_log(avctx, AV_LOG_DEBUG, "Discard output for pic "
More information about the ffmpeg-devel
mailing list