[FFmpeg-devel] [PATCH 5/5] vaapi: add support for new config options.

Gwenole Beauchesne gb.devel at gmail.com
Tue Aug 18 17:27:00 CEST 2015


Add support for modern and flexible config options for vaapi decoders.
Accessors are available to handle those:
- av_vaapi_set_display():
  Binds a user supplied VA display to a codec context
- av_vaapi_set_config():
  Configures the VA-API decoder with a key/value pair
- av_vaapi_set_config_int():
  Configures the VA-API decoder with a key/value pair(int).

The current set of config options is:
- "display": the VA display handle (pointer)
- "config": the VA config id (uint32_t)
- "context": the VA context (pipeline) id (uint32_t)

The whole vaapi_context structure is now not needed, and thus deprecated.

Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne at intel.com>
---
 doc/APIchanges              |  6 ++++
 libavcodec/vaapi.c          | 66 ++++++++++++++++++++++++++++++++++++----
 libavcodec/vaapi.h          | 73 +++++++++++++++++++++++++++++++++++++++++++--
 libavcodec/vaapi_internal.h |  1 +
 4 files changed, 139 insertions(+), 7 deletions(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index cce2ddb..6d05b8b 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -15,6 +15,12 @@ libavutil:     2014-08-09
 
 API changes, most recent first:
 
+2015-xx-xx - lavc 56.58.0 - vaapi.h
+  Add new APIs to configure hwaccel/vaapi decoders: av_vaapi_set_display(),
+  av_vaapi_set_config(), av_vaapi_set_config_str().
+  Deprecate vaapi_context structure, which is no longer used for
+  initializing a VA-API decode pipeline.
+
 2015-xx-xx - lavu 54.30.0
   xxxxxxx -  Add av_blowfish_alloc().
   xxxxxxx -  Add av_rc4_alloc().
diff --git a/libavcodec/vaapi.c b/libavcodec/vaapi.c
index 1ae71a5..f73a42e 100644
--- a/libavcodec/vaapi.c
+++ b/libavcodec/vaapi.c
@@ -41,19 +41,75 @@ static void destroy_buffers(VADisplay display, VABufferID *buffers, unsigned int
     }
 }
 
+#define OFFSET(x) offsetof(FFVAContext, x)
+static const AVOption FFVAContextOptions[] = {
+    { AV_VAAPI_CONFIG_OPTION_DISPLAY, "VA display handle", OFFSET(display),
+      AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, UINTPTR_MAX },
+    { AV_VAAPI_CONFIG_OPTION_CONFIG, "VA config id", OFFSET(config_id),
+      AV_OPT_TYPE_INT, { .i64 = VA_INVALID_ID }, 0, UINT32_MAX },
+    { AV_VAAPI_CONFIG_OPTION_CONTEXT, "VA context id", OFFSET(context_id),
+      AV_OPT_TYPE_INT, { .i64 = VA_INVALID_ID }, 0, UINT32_MAX },
+    { NULL, }
+};
+#undef OFFSET
+
+static const AVClass FFVAContextClass = {
+    .class_name = "FFVAContext",
+    .item_name  = av_default_item_name,
+    .option     = FFVAContextOptions,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+static const AVOption *get_option(const char *key, const char *unit)
+{
+    const AVClass *klass = &FFVAContextClass;
+
+    return av_opt_find2(&klass, key, unit, 0, AV_OPT_SEARCH_FAKE_OBJ, NULL);
+}
+
+int av_vaapi_set_display(AVCodecContext *avctx, VADisplay display)
+{
+    return av_vaapi_set_config_int(avctx, AV_VAAPI_CONFIG_OPTION_DISPLAY,
+                                   (int64_t)(intptr_t)display);
+}
+
+int av_vaapi_set_config(AVCodecContext *avctx, const char *key,
+                        const char *value)
+{
+    if (!get_option(key, NULL))
+        return AVERROR(EINVAL);
+    return av_dict_set(&avctx->internal->hwaccel_config, key, value, 0);
+}
+
+int av_vaapi_set_config_int(AVCodecContext *avctx, const char *key,
+                            int64_t value)
+{
+    if (!get_option(key, NULL))
+        return AVERROR(EINVAL);
+    return av_dict_set_int(&avctx->internal->hwaccel_config, key, value, 0);
+}
+
 int ff_vaapi_context_init(AVCodecContext *avctx)
 {
     FFVAContext * const vactx = ff_vaapi_get_context(avctx);
-    const struct vaapi_context * const user_vactx = avctx->hwaccel_context;
 
-    vactx->display              = user_vactx->display;
-    vactx->config_id            = user_vactx->config_id;
-    vactx->context_id           = user_vactx->context_id;
+    vactx->klass = &FFVAContextClass;
+    av_opt_set_defaults(vactx);
+
+#if FF_API_VAAPI_CONTEXT
+    if (avctx->hwaccel_context) {
+        const struct vaapi_context * const user_vactx = avctx->hwaccel_context;
+        vactx->display          = user_vactx->display;
+        vactx->config_id        = user_vactx->config_id;
+        vactx->context_id       = user_vactx->context_id;
+    }
+#endif
 
     vactx->pic_param_buf_id     = VA_INVALID_ID;
     vactx->iq_matrix_buf_id     = VA_INVALID_ID;
     vactx->bitplane_buf_id      = VA_INVALID_ID;
-    return 0;
+
+    return av_opt_set_dict(vactx, &avctx->internal->hwaccel_config);
 }
 
 int ff_vaapi_context_fini(AVCodecContext *avctx)
diff --git a/libavcodec/vaapi.h b/libavcodec/vaapi.h
index 4448a2e..22b9336 100644
--- a/libavcodec/vaapi.h
+++ b/libavcodec/vaapi.h
@@ -32,7 +32,9 @@
 
 #include <stdint.h>
 #include <libavutil/attributes.h>
+#include <va/va.h>
 #include "version.h"
+#include "avcodec.h"
 
 /**
  * @defgroup lavc_codec_hwaccel_vaapi VA API Decoding
@@ -48,7 +50,12 @@
  * during initialization or through each AVCodecContext.get_buffer()
  * function call. In any case, they must be valid prior to calling
  * decoding functions.
+ *
+ * This structure is deprecated. Please refer to config options and
+ * associated accessors: av_vaapi_set_display(), av_vaapi_set_config_int(),
+ * av_vaapi_set_config().
  */
+#if FF_API_VAAPI_CONTEXT
 struct vaapi_context {
     /**
      * Window system dependent data
@@ -56,6 +63,7 @@ struct vaapi_context {
      * - encoding: unused
      * - decoding: Set by user
      */
+    attribute_deprecated
     void *display;
 
     /**
@@ -64,6 +72,7 @@ struct vaapi_context {
      * - encoding: unused
      * - decoding: Set by user
      */
+    attribute_deprecated
     uint32_t config_id;
 
     /**
@@ -72,9 +81,9 @@ struct vaapi_context {
      * - encoding: unused
      * - decoding: Set by user
      */
+    attribute_deprecated
     uint32_t context_id;
 
-#if FF_API_VAAPI_CONTEXT
     /**
      * VAPictureParameterBuffer ID
      *
@@ -181,8 +190,68 @@ struct vaapi_context {
      */
     attribute_deprecated
     uint32_t slice_data_size;
-#endif
 };
+#endif
+
+/** @name VA-API pipeline config options */
+/**@{*/
+/** @brief VA display (pointer) */
+#define AV_VAAPI_CONFIG_OPTION_DISPLAY          "display"
+/** @brief VA configuration id (uint32_t) */
+#define AV_VAAPI_CONFIG_OPTION_CONFIG           "config"
+/** @brief VA context id (uint32_t) */
+#define AV_VAAPI_CONFIG_OPTION_CONTEXT          "context"
+/**@}*/
+
+/**
+ * Binds a user supplied VA display to a codec context
+ *
+ * This function binds the supplied VA @a display to a codec context
+ * @a avctx. The user retains full ownership of the display, and thus
+ * shall ensure the VA-API subsystem was initialized with vaInitialize(),
+ * make due diligence to keep it live until it is no longer needed,
+ * and dispose the associated resources with vaTerminate() whenever
+ * appropriate.
+ *
+ * @note This function has no effect if it is called outside of an
+ * AVCodecContext.get_format() hook.
+ *
+ * @param[in] avctx the codec context being used for decoding the stream
+ * @param[in] display the VA display handle to use for decoding
+ * @return 0 on success, an AVERROR code on failure.
+ */
+int av_vaapi_set_display(AVCodecContext *avctx, VADisplay display);
+
+/**
+ * Configures the VA-API decoder with a key/value pair, overwriting a
+ * previous entry.
+ *
+ * @note This function has no effect if it is called outside of an
+ * AVCodecContext.get_format() hook.
+ *
+ * @param[in] avctx the codec context being used for decoding the stream
+ * @param[in] key config option key (string)
+ * @param[in] value config option value (string). Passing a NULL value
+ *   will cause an existing entry to be deleted.
+ * @return 0 on success, an AVERROR code on failure.
+ */
+int av_vaapi_set_config(AVCodecContext *avctx, const char *key,
+                        const char *value);
+
+/**
+ * Configures the VA-API decoder with a key/value pair, overwriting a
+ *   previous entry.
+ *
+ * @note This function has no effect if it is called outside of an
+ * AVCodecContext.get_format() hook.
+ *
+ * @param[in] avctx the codec context being used for decoding the stream
+ * @param[in] key config option key (string)
+ * @param[in] value config option value (int)
+ * @return 0 on success, an AVERROR code on failure.
+ */
+int av_vaapi_set_config_int(AVCodecContext *avctx, const char *key,
+                            int64_t value);
 
 /* @} */
 
diff --git a/libavcodec/vaapi_internal.h b/libavcodec/vaapi_internal.h
index 29f46ab..832bc5e 100644
--- a/libavcodec/vaapi_internal.h
+++ b/libavcodec/vaapi_internal.h
@@ -36,6 +36,7 @@
  */
 
 typedef struct {
+    const void *klass;
     VADisplay display;                  ///< Windowing system dependent handle
     VAConfigID config_id;               ///< Configuration ID
     VAContextID context_id;             ///< Context ID (video decode pipeline)
-- 
1.9.1



More information about the ffmpeg-devel mailing list