[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