summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libhb/enc_qsv.c70
-rw-r--r--libhb/qsv_common.c88
-rw-r--r--libhb/qsv_common.h4
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);