[FFmpeg-devel] [PATCH 1/6] lavc/qsv(hevc): Change default plugin from hevc_sw to hevc_default, which will load hevc_hw first, due to newly released MSDK.

Nablet Developer sdk at nablet.com
Tue Aug 16 13:10:02 EEST 2016


From: ChaoX A Liu <chaox.a.liu at intel.com>

Signed-off-by: ChaoX A Liu <chaox.a.liu at intel.com>
---
 libavcodec/qsv.c          | 89 ++++++++++++++++++++++++++++-------------------
 libavcodec/qsv_internal.h |  6 ++--
 libavcodec/qsvdec.c       | 16 ++++++---
 libavcodec/qsvdec_h2645.c | 17 ++++++---
 libavcodec/qsvenc.c       | 12 +++++--
 libavcodec/qsvenc_hevc.c  | 19 +++++-----
 6 files changed, 104 insertions(+), 55 deletions(-)

diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c
index 11d453d..b505e14 100644
--- a/libavcodec/qsv.c
+++ b/libavcodec/qsv.c
@@ -168,8 +168,7 @@ static int ff_qsv_set_display_handle(AVCodecContext *avctx, QSVSession *qs)
  * @param avctx    ffmpeg metadata for this codec context
  * @param session  the MSDK session used
  */
-int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs,
-                                 const char *load_plugins)
+int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs)
 {
     mfxIMPL impl   = MFX_IMPL_AUTO_ANY;
     mfxVersion ver = { { QSV_VERSION_MINOR, QSV_VERSION_MAJOR } };
@@ -187,67 +186,87 @@ int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs,
     if (ret < 0)
         return ret;
 
+    MFXQueryIMPL(qs->session, &impl);
+
+    switch (MFX_IMPL_BASETYPE(impl)) {
+    case MFX_IMPL_SOFTWARE:
+        desc = "software";
+        break;
+    case MFX_IMPL_HARDWARE:
+    case MFX_IMPL_HARDWARE2:
+    case MFX_IMPL_HARDWARE3:
+    case MFX_IMPL_HARDWARE4:
+        desc = "hardware accelerated";
+        break;
+    default:
+        desc = "unknown";
+    }
+
+    av_log(avctx, AV_LOG_VERBOSE,
+           "Initialized an internal MFX session using %s implementation\n",
+           desc);
+
+    return 0;
+}
+
+/**
+ * @brief Load plugins for a MSDK session
+ *
+ * Media SDK may need external plugins to decode/encode,
+ * such as hevc_dec and hevc_enc. So it's necessary to load
+ * proper plugins.
+ *
+ * @param session       the MSDK session used
+ * @param load_plugins  the load_plugins to be loaded.
+ */
+int ff_qsv_load_plugins(mfxSession session, const char *load_plugins)
+{
+    int err = 0, load_num = 0, i;
+
     if (load_plugins && *load_plugins) {
         while (*load_plugins) {
             mfxPluginUID uid;
-            int i, err = 0;
 
             char *plugin = av_get_token(&load_plugins, ":");
             if (!plugin)
                 return AVERROR(ENOMEM);
             if (strlen(plugin) != 2 * sizeof(uid.Data)) {
-                av_log(avctx, AV_LOG_ERROR, "Invalid plugin UID length\n");
                 err = AVERROR(EINVAL);
                 goto load_plugin_fail;
             }
+            if (*load_plugins == ':')
+                load_plugins ++;
 
             for (i = 0; i < sizeof(uid.Data); i++) {
                 err = sscanf(plugin + 2 * i, "%2hhx", uid.Data + i);
                 if (err != 1) {
-                    av_log(avctx, AV_LOG_ERROR, "Invalid plugin UID\n");
                     err = AVERROR(EINVAL);
                     goto load_plugin_fail;
                 }
-
             }
 
-            ret = MFXVideoUSER_Load(qs->session, &uid, 1);
-            if (ret < 0) {
-                av_log(avctx, AV_LOG_ERROR, "Could not load the requested plugin: %s\n",
-                       plugin);
-                err = ff_qsv_error(ret);
+            err = MFXVideoUSER_Load(session, &uid, 1);
+            if (err < 0) {
+                err = ff_qsv_error(err);
                 goto load_plugin_fail;
             }
+            load_num ++;
 
-            if (*load_plugins)
-                load_plugins++;
 load_plugin_fail:
             av_freep(&plugin);
-            if (err < 0)
-                return err;
+            /*
+             * If more plugins are going to be loaded,
+             * ignore current error and continue.
+             */
+            if (*load_plugins == ':') {
+                load_plugins ++;
+                err = 0;
+            }
         }
+        if (!load_num)
+            return err;
     }
 
-    MFXQueryIMPL(qs->session, &impl);
-
-    switch (MFX_IMPL_BASETYPE(impl)) {
-    case MFX_IMPL_SOFTWARE:
-        desc = "software";
-        break;
-    case MFX_IMPL_HARDWARE:
-    case MFX_IMPL_HARDWARE2:
-    case MFX_IMPL_HARDWARE3:
-    case MFX_IMPL_HARDWARE4:
-        desc = "hardware accelerated";
-        break;
-    default:
-        desc = "unknown";
-    }
-
-    av_log(avctx, AV_LOG_VERBOSE,
-           "Initialized an internal MFX session using %s implementation\n",
-           desc);
-
     return 0;
 }
 
diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h
index f289a2b..59d1336 100644
--- a/libavcodec/qsv_internal.h
+++ b/libavcodec/qsv_internal.h
@@ -80,8 +80,10 @@ int ff_qsv_error(int mfx_err);
 
 int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id);
 
-int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs,
-                                 const char *load_plugins);
+int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs);
+
+int ff_qsv_load_plugins(mfxSession session, const char *load_plugins);
+
 int ff_qsv_close_internal_session(QSVSession *qs);
 
 #endif /* AVCODEC_QSV_INTERNAL_H */
diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index 98585e3..b9de0af 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -51,7 +51,7 @@ int ff_qsv_map_pixfmt(enum AVPixelFormat format)
 
 static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q, AVPacket *avpkt)
 {
-    mfxVideoParam param = { { 0 } };
+    mfxVideoParam param = { 0 };
     mfxBitstream bs   = { { { 0 } } };
     int ret;
     enum AVPixelFormat pix_fmts[3] = { AV_PIX_FMT_QSV,
@@ -75,8 +75,7 @@ static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q, AVPacket *avpkt
     }
     if (!q->session) {
         if (!q->internal_qs.session) {
-            ret = ff_qsv_init_internal_session(avctx, &q->internal_qs,
-                                               q->load_plugins);
+            ret = ff_qsv_init_internal_session(avctx, &q->internal_qs);
             if (ret < 0)
                 return ret;
         }
@@ -84,6 +83,15 @@ static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q, AVPacket *avpkt
         q->session = q->internal_qs.session;
     }
 
+    if (q->load_plugins) {
+        ret = ff_qsv_load_plugins(q->session, q->load_plugins);
+        if (ret < 0) {
+            av_log(avctx, AV_LOG_ERROR, "Failed to load plugins %s, ret = %s\n",
+                    q->load_plugins, av_err2str(ret));
+            return ff_qsv_error(ret);
+        }
+    }
+
     if (avpkt->size) {
         bs.Data       = avpkt->data;
         bs.DataLength = avpkt->size;
@@ -529,7 +537,7 @@ void ff_qsv_decode_reset(AVCodecContext *avctx, QSVContext *q)
     QSVFrame *cur;
     AVPacket pkt;
     int ret = 0;
-    mfxVideoParam param = { { 0 } };
+    mfxVideoParam param = { 0 };
 
     if (q->reinit_pending) {
         close_decoder(q);
diff --git a/libavcodec/qsvdec_h2645.c b/libavcodec/qsvdec_h2645.c
index 98a1952..208302b 100755
--- a/libavcodec/qsvdec_h2645.c
+++ b/libavcodec/qsvdec_h2645.c
@@ -38,6 +38,8 @@
 enum LoadPlugin {
     LOAD_PLUGIN_NONE,
     LOAD_PLUGIN_HEVC_SW,
+    LOAD_PLUGIN_HEVC_HW,
+    LOAD_PLUGIN_DEFAULT,
 };
 
 typedef struct QSVH2645Context {
@@ -67,6 +69,13 @@ static void qsv_clear_buffers(QSVH2645Context *s)
     av_packet_unref(&s->pkt_filtered);
 }
 
+static const char* hevc_plugins[] = {
+    NULL,
+    "15dd936825ad475ea34e35f3f54217a6", /*LOAD_PLUGIN_HEVC_SW*/
+    "33a61c0b4c27454ca8d85dde757c6f8e", /*LOAD_PLUGIN_HEVC_HW*/
+    "33a61c0b4c27454ca8d85dde757c6f8e:15dd936825ad475ea34e35f3f54217a6", /*LOAD_PLUGIN_HEVC_DEFAULT*/
+};
+
 static av_cold int qsv_decode_close(AVCodecContext *avctx)
 {
     QSVH2645Context *s = avctx->priv_data;
@@ -86,15 +95,13 @@ static av_cold int qsv_decode_init(AVCodecContext *avctx)
     int ret;
 
     if (avctx->codec_id == AV_CODEC_ID_HEVC && s->load_plugin != LOAD_PLUGIN_NONE) {
-        static const char *uid_hevcenc_sw = "15dd936825ad475ea34e35f3f54217a6";
-
         if (s->qsv.load_plugins[0]) {
             av_log(avctx, AV_LOG_WARNING,
                    "load_plugins is not empty, but load_plugin is not set to 'none'."
                    "The load_plugin value will be ignored.\n");
         } else {
             av_freep(&s->qsv.load_plugins);
-            s->qsv.load_plugins = av_strdup(uid_hevcenc_sw);
+            s->qsv.load_plugins = av_strdup(hevc_plugins[s->load_plugin]);
             if (!s->qsv.load_plugins)
                 return AVERROR(ENOMEM);
         }
@@ -233,9 +240,11 @@ AVHWAccel ff_hevc_qsv_hwaccel = {
 static const AVOption hevc_options[] = {
     { "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = ASYNC_DEPTH_DEFAULT }, 0, INT_MAX, VD },
 
-    { "load_plugin", "A user plugin to load in an internal session", OFFSET(load_plugin), AV_OPT_TYPE_INT, { .i64 = LOAD_PLUGIN_HEVC_SW }, LOAD_PLUGIN_NONE, LOAD_PLUGIN_HEVC_SW, VD, "load_plugin" },
+    { "load_plugin", "A user plugin to load in an internal session", OFFSET(load_plugin), AV_OPT_TYPE_INT, { .i64 = LOAD_PLUGIN_DEFAULT }, LOAD_PLUGIN_NONE, LOAD_PLUGIN_DEFAULT, VD, "load_plugin" },
     { "none",     NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_NONE },    0, 0, VD, "load_plugin" },
     { "hevc_sw",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_HEVC_SW }, 0, 0, VD, "load_plugin" },
+    { "hevc_hw",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_HEVC_HW }, 0, 0, VD, "load_plugin" },
+    { "default",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_DEFAULT }, 0, 0, VD, "load_plugin" },
 
     { "load_plugins", "A :-separate list of hexadecimal plugin UIDs to load in an internal session",
         OFFSET(qsv.load_plugins), AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, VD },
diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index f56cb61..81b8f6f 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -696,14 +696,22 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
     }
 
     if (!q->session) {
-        ret = ff_qsv_init_internal_session(avctx, &q->internal_qs,
-                                           q->load_plugins);
+        ret = ff_qsv_init_internal_session(avctx, &q->internal_qs);
         if (ret < 0)
             return ret;
 
         q->session = q->internal_qs.session;
     }
 
+    if (q->load_plugins) {
+        ret = ff_qsv_load_plugins(q->session, q->load_plugins);
+        if (ret < 0) {
+            av_log(avctx, AV_LOG_ERROR, "Failed to load plugins %s, ret = %s\n",
+                    q->load_plugins, av_err2str(ret));
+            return ff_qsv_error(ret);
+        }
+    }
+
     ret = init_video_param(avctx, q);
     if (ret < 0)
         return ret;
diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c
index 1d1e801..2b757dc 100644
--- a/libavcodec/qsvenc_hevc.c
+++ b/libavcodec/qsvenc_hevc.c
@@ -41,6 +41,14 @@ enum LoadPlugin {
     LOAD_PLUGIN_NONE,
     LOAD_PLUGIN_HEVC_SW,
     LOAD_PLUGIN_HEVC_HW,
+    LOAD_PLUGIN_DEFAULT,
+};
+
+static const char* hevc_plugins[] = {
+    NULL,
+    "2fca99749fdb49aeb121a5b63ef568f7", /*LOAD_PLUGIN_HEVC_SW*/
+    "6fadc791a0c2eb479ab6dcd5ea9da347", /*LOAD_PLUGIN_HEVC_HW*/
+    "6fadc791a0c2eb479ab6dcd5ea9da347:2fca99749fdb49aeb121a5b63ef568f7", /*LOAD_PLUGIN_HEVC_DEFAULT*/
 };
 
 typedef struct QSVHEVCEncContext {
@@ -160,9 +168,6 @@ static av_cold int qsv_enc_init(AVCodecContext *avctx)
     int ret;
 
     if (q->load_plugin != LOAD_PLUGIN_NONE) {
-        static const char *uid_hevcenc_sw = "2fca99749fdb49aeb121a5b63ef568f7";
-        static const char *uid_hevcenc_hw = "6fadc791a0c2eb479ab6dcd5ea9da347";
-
         if (q->qsv.load_plugins[0]) {
             av_log(avctx, AV_LOG_WARNING,
                    "load_plugins is not empty, but load_plugin is not set to 'none'."
@@ -170,10 +175,7 @@ static av_cold int qsv_enc_init(AVCodecContext *avctx)
         } else {
             av_freep(&q->qsv.load_plugins);
 
-            if (q->load_plugin == LOAD_PLUGIN_HEVC_SW)
-                q->qsv.load_plugins = av_strdup(uid_hevcenc_sw);
-            else
-                q->qsv.load_plugins = av_strdup(uid_hevcenc_hw);
+            q->qsv.load_plugins = av_strdup(hevc_plugins[q->load_plugin]);
 
             if (!q->qsv.load_plugins)
                 return AVERROR(ENOMEM);
@@ -213,10 +215,11 @@ static av_cold int qsv_enc_close(AVCodecContext *avctx)
 static const AVOption options[] = {
     QSV_COMMON_OPTS
 
-    { "load_plugin", "A user plugin to load in an internal session", OFFSET(load_plugin), AV_OPT_TYPE_INT, { .i64 = LOAD_PLUGIN_HEVC_SW }, LOAD_PLUGIN_NONE, LOAD_PLUGIN_HEVC_HW, VE, "load_plugin" },
+    { "load_plugin", "A user plugin to load in an internal session", OFFSET(load_plugin), AV_OPT_TYPE_INT, { .i64 = LOAD_PLUGIN_DEFAULT }, LOAD_PLUGIN_NONE, LOAD_PLUGIN_DEFAULT, VE, "load_plugin" },
     { "none",     NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_NONE },    0, 0, VE, "load_plugin" },
     { "hevc_sw",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_HEVC_SW }, 0, 0, VE, "load_plugin" },
     { "hevc_hw",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_HEVC_HW }, 0, 0, VE, "load_plugin" },
+    { "default",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_DEFAULT }, 0, 0, VE, "load_plugin" },
 
     { "load_plugins", "A :-separate list of hexadecimal plugin UIDs to load in an internal session",
         OFFSET(qsv.load_plugins), AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, VE },
-- 
2.5.0



More information about the ffmpeg-devel mailing list