diff mbox series

[FFmpeg-devel,2/3] libavcodec/vaapi_encode: Add new API adaption to vaapi_encode

Message ID 20211027085705.4114165-2-wenbin.chen@intel.com
State New
Headers show
Series [FFmpeg-devel,1/3] libavcodec/vaapi_encode: Change the way to call async to increase performance
Related show

Checks

Context Check Description
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished
andriy/make_ppc success Make finished
andriy/make_fate_ppc success Make fate finished

Commit Message

Wenbin Chen Oct. 27, 2021, 8:57 a.m. UTC
Add vaSyncBuffer to VAAPI encoder. Old version API vaSyncSurface wait
surface to complete. When surface is used for multiple operation, it
wait all operation 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 ready return 0, if still in progress
return EAGAIN.

Signed-off-by: Wenbin Chen <wenbin.chen@intel.com>
---
 libavcodec/vaapi_encode.c | 47 +++++++++++++++++++++++++++++++++------
 1 file changed, 40 insertions(+), 7 deletions(-)

Comments

Wenbin Chen Nov. 1, 2021, 2:13 a.m. UTC | #1
> Add vaSyncBuffer to VAAPI encoder. Old version API vaSyncSurface wait
> surface to complete. When surface is used for multiple operation, it
> wait all operation 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 ready return 0, if still in progress
> return EAGAIN.
> 
> Signed-off-by: Wenbin Chen <wenbin.chen@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 5927849233..db0ae136a1 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);
> +    } 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 "
> --
> 2.25.1

ping
diff mbox series

Patch

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index 5927849233..db0ae136a1 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);
+    } 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 "