Adds a general mechanism for setting driver quirks, and detects the
driver name to set them.

When the i965 driver is being used, destroy all parameter buffers
explicitly after use despite passing them to vaRenderPicture().
---
An alternative approach to solving the same problem as the previous patch.  
Maybe this is actually better once we start detecting the driver anyway?

 libavcodec/vaapi_encode.c | 28 +++++++++++++++++++++++++++-
 libavcodec/vaapi_encode.h |  7 +++++++
 2 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index 45f5e57..df23ad9 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -389,7 +389,23 @@ static int vaapi_encode_issue(AVCodecContext *avctx,
         av_log(avctx, AV_LOG_ERROR, "Failed to end picture encode issue: "
                "%d (%s).\n", vas, vaErrorStr(vas));
         err = AVERROR(EIO);
-        goto fail_at_end;
+        if (ctx->driver_quirks & DRIVER_QUIRK_DESTROY_PARAM_BUFFERS)
+            goto fail;
+        else
+            goto fail_at_end;
+    }
+
+    if (ctx->driver_quirks & DRIVER_QUIRK_DESTROY_PARAM_BUFFERS) {
+        for (i = 0; i < pic->nb_param_buffers; i++) {
+            vas = vaDestroyBuffer(ctx->hwctx->display,
+                                  pic->param_buffers[i]);
+            if (vas != VA_STATUS_SUCCESS) {
+                av_log(avctx, AV_LOG_ERROR, "Failed to destroy "
+                       "param buffer %#x: %d (%s).\n",
+                       pic->param_buffers[i], vas, vaErrorStr(vas));
+                // And ignore - it will leak.
+            }
+        }
     }

     pic->encode_issued = 1;
@@ -1034,6 +1050,7 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx,
     AVHWFramesConstraints *constraints = NULL;
     enum AVPixelFormat recon_format;
     VAStatus vas;
+    const char *vendor_string;
     int err, i;

     if (!avctx->hw_frames_ctx) {
@@ -1069,6 +1086,15 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx,
     ctx->device = (AVHWDeviceContext*)ctx->device_ref->data;
     ctx->hwctx = ctx->device->hwctx;

+    vendor_string = vaQueryVendorString(ctx->hwctx->display);
+    if (vendor_string) {
+        if (strstr(vendor_string, "i965")) {
+            av_log(avctx, AV_LOG_VERBOSE, "Detected i965 driver: "
+                   "enabling some driver-specific behaviour.\n");
+            ctx->driver_quirks |= DRIVER_QUIRK_DESTROY_PARAM_BUFFERS;
+        }
+    }
+
     err = ctx->codec->init(avctx);
     if (err < 0)
         goto fail;
diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h
index 85f3a0c..a2cb447 100644
--- a/libavcodec/vaapi_encode.h
+++ b/libavcodec/vaapi_encode.h
@@ -58,6 +58,12 @@ enum {
     ISSUE_MODE_MINIMISE_LATENCY,
 };

+enum {
+    // Driver requires vaDestroyBuffers() to be called on all parameter
+    // buffers, even if they were passed to vaRenderPicture().
+    DRIVER_QUIRK_DESTROY_PARAM_BUFFERS = 0x01,
+};
+
 typedef struct VAAPIEncodeSlice {
     void           *priv_data;
     void           *codec_slice_params;
@@ -115,6 +121,7 @@ typedef struct VAAPIEncodeContext {
     AVBufferRef    *device_ref;
     AVHWDeviceContext *device;
     AVVAAPIDeviceContext *hwctx;
+    unsigned int    driver_quirks;

     AVBufferRef    *input_frames_ref;
     AVHWFramesContext *input_frames;
-- 
2.8.1

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to