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

Wenbin Chen wenbin.chen at intel.com
Wed Oct 27 11:57:04 EEST 2021


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 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 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



More information about the ffmpeg-devel mailing list