From patchwork Tue Aug 16 10:10:02 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nablet Developer X-Patchwork-Id: 194 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.140.67 with SMTP id o64csp2035089vsd; Tue, 16 Aug 2016 03:16:52 -0700 (PDT) X-Received: by 10.194.148.232 with SMTP id tv8mr43182358wjb.113.1471342612413; Tue, 16 Aug 2016 03:16:52 -0700 (PDT) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id gy6si24614852wjc.176.2016.08.16.03.16.52; Tue, 16 Aug 2016 03:16:52 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 0CA82689B06; Tue, 16 Aug 2016 13:16:47 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mout.kundenserver.de (mout.kundenserver.de [217.72.192.74]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 2677B689AC5 for ; Tue, 16 Aug 2016 13:16:39 +0300 (EEST) Received: from localhost.localdomain ([91.216.211.197]) by mrelayeu.kundenserver.de (mreue103) with ESMTPSA (Nemesis) id 0LdL6H-1arhww2E65-00iQuI; Tue, 16 Aug 2016 12:11:23 +0200 From: Nablet Developer To: ffmpeg-devel@ffmpeg.org Date: Tue, 16 Aug 2016 17:10:02 +0700 Message-Id: <1471342207-11982-2-git-send-email-sdk@nablet.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1471342207-11982-1-git-send-email-sdk@nablet.com> References: <1471342207-11982-1-git-send-email-sdk@nablet.com> X-Provags-ID: V03:K0:N03Te+8k6h19MLNj1u5Z3VV46tLBercEDcbTuwer/yIomQyV2W8 61dFtpyNP3JGmWNtFbP94a8qUFKubDQC4XcGqmidulF2+QXSscDu7jW2NWKX1luo5luea5Y Gqn1zGqcnXXzqq9ULcKEI9l8gpsJd0W2GerctyfnTYO0qNZGm8x7MmXS1On4cavMEeGU0dY hYaEmjNfdHqpD9JB8BSaw== X-UI-Out-Filterresults: notjunk:1; V01:K0:XKDP0Zw6060=:4p8dNEAM5aOI16gUsjKAq/ KUa04K4S0J00fQ4jHQ8W/PGi6P0JeYQNJrrqTZ0xwzKCa9gdSlLjLp+vJNe3fbsSrpqPQB1Ey Ye+d8uXCaWgbb+ptFihwlcTxRAxY0xWF8/CNTEBvftWYrjZZEYVAS5eKZhxI+ph9Lvns/3NuZ 5Pba7rtD5k7u4rXJrJ96IKphN2dS1tSKu4ZAEINW+eUqEeGQD1iijCdpF75lldnFSLEUor1k2 ouo7XQSLtQBT3/7XX3LUmcIczuKFZ+uv3qOUm8HwVLliVh9PqhvVJTnWpVngZ6Q1gmLn7EvwS 2K+EjzlMKKTboNSzR6z7a9hhHn5Cft+cUNhTedihJ0CM+DVmiqV/JxBmCckknSm2TLgkp/Ehx bmKvQh1onImxqrjZuzeUQLjixJ6CN2o/8S1q0nVfTutcqUKPTrYI9rHqTXXg58054X81V6oj6 rMfMbFeAOZVyGVQytCcdomTDKalzw9+tJG2fQ7maF+RwvTfoajQWQ7roygiYuq8cIC0Wtzwry AUmqRJqJc3+Wbh8m1dMIvT6Ov23bUQc6qw46MhfYImZj8bknuOVQvNWvZU6Xd6rXgjtKej8/S SiEnztFAlk6X7jOVr560o6+PvgkjPzrSpUPNKdzClHfr30mcB+LgqNSny72Uq54zUsztcK8Fl wWw/ZCQiDa7VQuq2QCTE6x8fJ55cnnOlBVPCgrZgCOGennTga/VsRNFv7xTmIqhXXu1NrgFby WfNbMSVFXzrT/VPK Subject: [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. X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: ChaoX A Liu MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: ChaoX A Liu Signed-off-by: ChaoX A Liu --- 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 },