The driver being used is detected inside av_hwdevice_ctx_init() and
the quirks field then set from a table of known device.  If this
behaviour is unwanted, the user can also set the quirks field
manually.

Also adds the Intel i965 driver quirk (it does not destroy parameter
buffers used in a call to vaRenderPicture()) and detects that driver
to set it.
---
On 23/06/16 20:54, Anton Khirnov wrote:
> Quoting Mark Thompson (2016-06-22 00:26:49)
>> Do we want an explicit way to disable the autodetection and let the
>> user set the quirks field?  Currently it works for the user to just
>> overwrite it after calling av_hwdevice_ctx_init().
> 
> Setting it after init feels a bit unclean to me, since the intent was
> for the device context to be constant after init (to avoid
> synchronization issues). It's not a problem in practice though, if the
> caller does it right after.
> So I'll leave the decision up to you, it probably does not matter much
> either way.
> 
> Patch looks fine to me, assuming you add an APIchanges entry and a minor
> bump on push.

How about this?  (Now also including APIchanges.)

 doc/APIchanges              |  4 ++++
 libavutil/hwcontext_vaapi.c | 39 +++++++++++++++++++++++++++++++++++++++
 libavutil/hwcontext_vaapi.h | 22 ++++++++++++++++++++++
 libavutil/version.h         |  2 +-
 4 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index 1caa1b7..cba3fb5 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -13,6 +13,10 @@ libavutil:     2015-08-28

 API changes, most recent first:

+2016-xx-xx - xxxxxxx - lavu 55.17.0 - hwcontext_vaapi.h
+  Add driver quirks field to VAAPI-specific hwdevice and enum with
+  members AV_VAAPI_DRIVER_QUIRKS_* to represent its values.
+
 2016-xx-xx - xxxxxxx - lavc 57.24.0 - avcodec.h
   Decoders now export the frame timestamp as AVFrame.pts. It was
   previously exported as AVFrame.pkt_pts, which is now deprecated.
diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
index 1bdc4cb..4c991be 100644
--- a/libavutil/hwcontext_vaapi.c
+++ b/libavutil/hwcontext_vaapi.c
@@ -263,12 +263,25 @@ fail:
     return err;
 }

+static const struct {
+    const char *friendly_name;
+    const char *match_string;
+    unsigned int quirks;
+} vaapi_driver_quirks_table[] = {
+    {
+        "Intel i965 (Quick Sync)",
+        "i965",
+        AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS,
+    },
+};
+
 static int vaapi_device_init(AVHWDeviceContext *hwdev)
 {
     VAAPIDeviceContext *ctx = hwdev->internal->priv;
     AVVAAPIDeviceContext *hwctx = hwdev->hwctx;
     VAImageFormat *image_list = NULL;
     VAStatus vas;
+    const char *vendor_string;
     int err, i, image_count;
     enum AVPixelFormat pix_fmt;
     unsigned int fourcc;
@@ -310,6 +323,32 @@ static int vaapi_device_init(AVHWDeviceContext *hwdev)
         }
     }

+    if (hwctx->driver_quirks & AV_VAAPI_DRIVER_QUIRK_USER_SET) {
+        av_log(hwdev, AV_LOG_VERBOSE, "Not detecting driver: "
+               "quirks set by user.\n");
+    } else {
+        // Detect the driver in use and set quirk flags if necessary.
+        vendor_string = vaQueryVendorString(hwctx->display);
+        hwctx->driver_quirks = 0;
+        if (vendor_string) {
+            for (i = 0; i < FF_ARRAY_ELEMS(vaapi_driver_quirks_table); i++) {
+                if (strstr(vendor_string,
+                           vaapi_driver_quirks_table[i].match_string)) {
+                    av_log(hwdev, AV_LOG_VERBOSE, "Matched \"%s\" as known "
+                           "driver \"%s\".\n", vendor_string,
+                           vaapi_driver_quirks_table[i].friendly_name);
+                    hwctx->driver_quirks |=
+                        vaapi_driver_quirks_table[i].quirks;
+                    break;
+                }
+            }
+            if (!(i < FF_ARRAY_ELEMS(vaapi_driver_quirks_table))) {
+                av_log(hwdev, AV_LOG_VERBOSE, "Unknown driver \"%s\", "
+                       "assuming standard behaviour.\n", vendor_string);
+            }
+        }
+    }
+
     av_free(image_list);
     return 0;
 fail:
diff --git a/libavutil/hwcontext_vaapi.h b/libavutil/hwcontext_vaapi.h
index 1c87f5d..0ac4caa 100644
--- a/libavutil/hwcontext_vaapi.h
+++ b/libavutil/hwcontext_vaapi.h
@@ -33,6 +33,20 @@
  * with the data pointer set to a VASurfaceID.
  */

+enum {
+    /**
+     * The quirks field has been set by the user and should not be detected
+     * automatically by av_hwdevice_ctx_init().
+     */
+    AV_VAAPI_DRIVER_QUIRK_USER_SET = (1 << 0),
+    /**
+     * The driver does not destroy parameter buffers when they are used by
+     * vaRenderPicture().  Additional code will be required to destroy them
+     * separately afterwards.
+     */
+    AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS = (1 << 1),
+};
+
 /**
  * VAAPI connection details.
  *
@@ -43,6 +57,14 @@ typedef struct AVVAAPIDeviceContext {
      * The VADisplay handle, to be filled by the user.
      */
     VADisplay display;
+    /**
+     * Driver quirks to apply - this is filled by av_hwdevice_ctx_init(),
+     * with reference to a table of known drivers, unless the
+     * AV_VAAPI_DRIVER_QUIRK_USER_SET bit is already present.  The user
+     * may need to refer to this field when performing any later
+     * operations using VAAPI with the same VADisplay.
+     */
+    unsigned int driver_quirks;
 } AVVAAPIDeviceContext;

 /**
diff --git a/libavutil/version.h b/libavutil/version.h
index 40745da..e24b30d 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -54,7 +54,7 @@
  */

 #define LIBAVUTIL_VERSION_MAJOR 55
-#define LIBAVUTIL_VERSION_MINOR 16
+#define LIBAVUTIL_VERSION_MINOR 17
 #define LIBAVUTIL_VERSION_MICRO  0

 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
-- 
2.8.1

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

Reply via email to