[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