From: ChaoX A Liu <chaox.a....@intel.com> Signed-off-by: ChaoX A Liu <chaox.a....@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 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel