diff options
-rw-r--r-- | libhb/enc_qsv.c | 70 | ||||
-rw-r--r-- | libhb/qsv_common.c | 88 | ||||
-rw-r--r-- | libhb/qsv_common.h | 4 |
3 files changed, 115 insertions, 47 deletions
diff --git a/libhb/enc_qsv.c b/libhb/enc_qsv.c index 27cd378e7..2f19b36f0 100644 --- a/libhb/enc_qsv.c +++ b/libhb/enc_qsv.c @@ -102,6 +102,8 @@ struct hb_work_private_s hb_list_t *delayed_processing; hb_list_t *encoded_frames; + + hb_list_t *loaded_plugins; }; // used in delayed_chapters list @@ -277,7 +279,9 @@ int qsv_enc_init(hb_work_private_t *pv) { av_qsv_context *qsv = pv->job->qsv.ctx; hb_job_t *job = pv->job; + mfxVersion version; mfxStatus sts; + mfxIMPL impl; int i; if (pv->init_done) @@ -440,19 +444,6 @@ int qsv_enc_init(hb_work_private_t *pv) AV_QSV_CHECK_POINTER(qsv_encode->p_syncp[i]->p_sync, MFX_ERR_MEMORY_ALLOC); } - // initialize the encoder - sts = MFXVideoENCODE_Init(qsv->mfx_session, pv->param.videoParam); - if (sts < MFX_ERR_NONE) // ignore warnings - { - hb_error("qsv_enc_init: MFXVideoENCODE_Init failed (%d)", sts); - *job->done_error = HB_ERROR_INIT; - *job->die = 1; - return -1; - } - qsv_encode->is_init_done = 1; - - mfxIMPL impl; - mfxVersion version; // log actual implementation details now that we know them if ((MFXQueryIMPL (qsv->mfx_session, &impl) == MFX_ERR_NONE) && (MFXQueryVersion(qsv->mfx_session, &version) == MFX_ERR_NONE)) @@ -465,6 +456,30 @@ int qsv_enc_init(hb_work_private_t *pv) hb_log("qsv_enc_init: MFXQueryIMPL/MFXQueryVersion failure"); } + // if not re-using encqsvInit's MFX session, load required plug-ins here + if (pv->loaded_plugins == NULL) + { + pv->loaded_plugins = hb_qsv_load_plugins(pv->qsv_info, qsv->mfx_session, version); + if (pv->loaded_plugins == NULL) + { + hb_error("qsv_enc_init: hb_qsv_load_plugins failed"); + *job->done_error = HB_ERROR_INIT; + *job->die = 1; + return -1; + } + } + + // initialize the encoder + sts = MFXVideoENCODE_Init(qsv->mfx_session, pv->param.videoParam); + if (sts < MFX_ERR_NONE) // ignore warnings + { + hb_error("qsv_enc_init: MFXVideoENCODE_Init failed (%d)", sts); + *job->done_error = HB_ERROR_INIT; + *job->die = 1; + return -1; + } + qsv_encode->is_init_done = 1; + pv->init_done = 1; return 0; } @@ -874,6 +889,25 @@ int encqsvInit(hb_work_object_t *w, hb_job_t *job) hb_error("encqsvInit: MFXInit failed (%d)", err); return -1; } + + /* Query the API version for hb_qsv_load_plugins */ + err = MFXQueryVersion(session, &version); + if (err != MFX_ERR_NONE) + { + hb_error("encqsvInit: MFXQueryVersion failed (%d)", err); + MFXClose(session); + return -1; + } + + /* Load required MFX plug-ins */ + pv->loaded_plugins = hb_qsv_load_plugins(pv->qsv_info, session, version); + if (pv->loaded_plugins == NULL) + { + hb_error("encqsvInit: hb_qsv_load_plugins failed"); + MFXClose(session); + return -1; + } + err = MFXVideoENCODE_Init(session, pv->param.videoParam); // workaround for the early 15.33.x driver, should be removed later #define HB_DRIVER_FIX_33 @@ -890,6 +924,7 @@ int encqsvInit(hb_work_object_t *w, hb_job_t *job) if (err < MFX_ERR_NONE) // ignore warnings { hb_error("encqsvInit: MFXVideoENCODE_Init failed (%d)", err); + hb_qsv_unload_plugins(&pv->loaded_plugins, session, version); MFXClose(session); return -1; } @@ -938,6 +973,7 @@ int encqsvInit(hb_work_object_t *w, hb_job_t *job) else { hb_error("encqsvInit: MFXVideoENCODE_GetVideoParam failed (%d)", err); + hb_qsv_unload_plugins(&pv->loaded_plugins, session, version); MFXClose(session); return -1; } @@ -959,6 +995,7 @@ int encqsvInit(hb_work_object_t *w, hb_job_t *job) } else { + hb_qsv_unload_plugins(&pv->loaded_plugins, session, version); MFXClose(session); } @@ -1158,6 +1195,7 @@ int encqsvInit(hb_work_object_t *w, hb_job_t *job) void encqsvClose(hb_work_object_t *w) { hb_work_private_t *pv = w->private_data; + mfxVersion version; int i; if (pv != NULL && pv->job != NULL && pv->job->qsv.ctx != NULL && @@ -1211,6 +1249,12 @@ void encqsvClose(hb_work_object_t *w) if (qsv_ctx != NULL) { + /* Unload MFX plug-ins */ + if (MFXQueryVersion(qsv_ctx->mfx_session, &version) == MFX_ERR_NONE) + { + hb_qsv_unload_plugins(&pv->loaded_plugins, qsv_ctx->mfx_session, version); + } + /* QSV context cleanup and MFXClose */ av_qsv_context_clean(qsv_ctx); diff --git a/libhb/qsv_common.c b/libhb/qsv_common.c index 3b8179886..a34eb67d8 100644 --- a/libhb/qsv_common.c +++ b/libhb/qsv_common.c @@ -249,26 +249,10 @@ static int query_capabilities(mfxSession session, mfxVersion version, hb_qsv_inf /* Reset capabilities before querying */ info->capabilities = 0; - /* Load optional codec plug-ins */ - if (HB_CHECK_MFX_VERSION(version, 1, 8)) + /* Load required MFX plug-ins */ + if ((mfxPluginList = hb_qsv_load_plugins(info, session, version)) == NULL) { - if ((mfxPluginList = hb_list_init()) == NULL) - { - hb_log("query_capabilities: hb_list_init() failed"); - return 0; - } - - if (!qsv_implementation_is_hardware(info->implementation)) - { - if (info->codec_id == MFX_CODEC_HEVC) - { - if (MFXVideoUSER_Load(session, &MFX_PLUGINID_HEVCE_SW, 0) < MFX_ERR_NONE) - { - return 0; // mandatory plugin, this encoder is unavailable - } - hb_list_add(mfxPluginList, &MFX_PLUGINID_HEVCE_SW); - } - } + return 0; // the required plugin(s) couldn't be loaded } /* @@ -578,21 +562,8 @@ static int query_capabilities(mfxSession session, mfxVersion version, hb_qsv_inf } } - /* Unload optional codec plug-ins */ - if (HB_CHECK_MFX_VERSION(version, 1, 8)) - { - mfxPluginUID *pluginUID; - - for (int i = 0; i < hb_list_count(mfxPluginList); i++) - { - if ((pluginUID = hb_list_item(mfxPluginList, i)) != NULL) - { - MFXVideoUSER_UnLoad(session, pluginUID); - } - } - - hb_list_close(&mfxPluginList); - } + /* Unload MFX plug-ins */ + hb_qsv_unload_plugins(&mfxPluginList, session, version); return 0; } @@ -814,6 +785,55 @@ hb_qsv_info_t* hb_qsv_info_get(int encoder) } } +hb_list_t* hb_qsv_load_plugins(hb_qsv_info_t *info, mfxSession session, mfxVersion version) +{ + hb_list_t *mfxPluginList = hb_list_init(); + if (mfxPluginList == NULL) + { + hb_log("hb_qsv_load_plugins: hb_list_init() failed"); + goto fail; + } + + if (HB_CHECK_MFX_VERSION(version, 1, 8)) + { + if (info->codec_id == MFX_CODEC_HEVC) + { + if (HB_CHECK_MFX_VERSION(version, 1, 15)) + { + if (MFXVideoUSER_Load(session, &MFX_PLUGINID_HEVCE_SW, 0) < MFX_ERR_NONE) + { + goto fail; + } + hb_list_add(mfxPluginList, (void*)&MFX_PLUGINID_HEVCE_SW); + } + } + } + + return mfxPluginList; + +fail: + hb_list_close(&mfxPluginList); + return NULL; +} + +void hb_qsv_unload_plugins(hb_list_t **_l, mfxSession session, mfxVersion version) +{ + mfxPluginUID *pluginUID; + hb_list_t *mfxPluginList = *_l; + + if (mfxPluginList != NULL && HB_CHECK_MFX_VERSION(version, 1, 8)) + { + for (int i = 0; i < hb_list_count(mfxPluginList); i++) + { + if ((pluginUID = hb_list_item(mfxPluginList, i)) != NULL) + { + MFXVideoUSER_UnLoad(session, pluginUID); + } + } + } + hb_list_close(_l); +} + const char* hb_qsv_decode_get_codec_name(enum AVCodecID codec_id) { switch (codec_id) diff --git a/libhb/qsv_common.h b/libhb/qsv_common.h index da045422e..b1adc5c5a 100644 --- a/libhb/qsv_common.h +++ b/libhb/qsv_common.h @@ -71,6 +71,10 @@ int hb_qsv_info_init(); void hb_qsv_info_print(); hb_qsv_info_t* hb_qsv_info_get(int encoder); +/* Automatically load and unload any required MFX plug-ins */ +hb_list_t* hb_qsv_load_plugins (hb_qsv_info_t *info, mfxSession session, mfxVersion version); +void hb_qsv_unload_plugins(hb_list_t **_l, mfxSession session, mfxVersion version); + /* Intel Quick Sync Video DECODE utilities */ const char* hb_qsv_decode_get_codec_name(enum AVCodecID codec_id); int hb_qsv_decode_is_enabled(hb_job_t *job); |