]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/qsv.c
lavc: add Intel libmfx-based MPEG2 decoder.
[ffmpeg] / libavcodec / qsv.c
index bd9e18d43e71bc6f8d1069c68fc4cf34e0b65ee1..ee6b262f31c806893cfce290e666da222ebab063 100644 (file)
  */
 
 #include <mfx/mfxvideo.h>
+#include <mfx/mfxplugin.h>
 
+#include <stdio.h>
+#include <string.h>
+
+#include "libavutil/avstring.h"
 #include "libavutil/error.h"
 
 #include "avcodec.h"
@@ -30,6 +35,10 @@ int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id)
     switch (codec_id) {
     case AV_CODEC_ID_H264:
         return MFX_CODEC_AVC;
+#if QSV_VERSION_ATLEAST(1, 8)
+    case AV_CODEC_ID_HEVC:
+        return MFX_CODEC_HEVC;
+#endif
     case AV_CODEC_ID_MPEG1VIDEO:
     case AV_CODEC_ID_MPEG2VIDEO:
         return MFX_CODEC_MPEG2;
@@ -77,7 +86,8 @@ int ff_qsv_error(int mfx_err)
     }
 }
 
-int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session)
+int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session,
+                                 const char *load_plugins)
 {
     mfxIMPL impl   = MFX_IMPL_AUTO_ANY;
     mfxVersion ver = { { QSV_VERSION_MINOR, QSV_VERSION_MAJOR } };
@@ -107,6 +117,45 @@ int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session)
         desc = "unknown";
     }
 
+    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;
+            }
+
+            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(*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);
+                goto load_plugin_fail;
+            }
+
+load_plugin_fail:
+            av_freep(&plugin);
+            if (err < 0)
+                return err;
+        }
+    }
+
     av_log(avctx, AV_LOG_VERBOSE,
            "Initialized an internal MFX session using %s implementation\n",
            desc);