msdk: use a new method to create mfx session when using oneVPL dispatcher

In oneVPL, MFXLoad() and MFXCreateSession() are required to create a
workable mfx session[1]

[1] https://spec.oneapi.com/versions/latest/elements/oneVPL/source/programming_guide/VPL_prg_session.html#onevpl-dispatcher

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1503>
This commit is contained in:
Haihao Xiang 2021-02-04 15:27:13 +08:00
parent beda9a7333
commit cd3a3534c4
3 changed files with 205 additions and 29 deletions

View file

@ -44,7 +44,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_debug_msdkcontext);
struct _GstMsdkContextPrivate
{
mfxSession session;
MsdkSession session;
GList *cached_alloc_responses;
gboolean hardware;
gboolean is_joined;
@ -178,7 +178,7 @@ gst_msdk_context_use_vaapi (GstMsdkContext * context)
goto failed;
}
status = MFXVideoCORE_SetHandle (priv->session, MFX_HANDLE_VA_DISPLAY,
status = MFXVideoCORE_SetHandle (priv->session.session, MFX_HANDLE_VA_DISPLAY,
(mfxHDL) va_dpy);
if (status != MFX_ERR_NONE) {
GST_ERROR ("Setting VAAPI handle failed (%s)",
@ -205,12 +205,15 @@ gst_msdk_context_open (GstMsdkContext * context, gboolean hardware,
{
mfxU16 codename;
GstMsdkContextPrivate *priv = context->priv;
MsdkSession msdk_session;
priv->job_type = job_type;
priv->hardware = hardware;
priv->session =
msdk_session =
msdk_open_session (hardware ? MFX_IMPL_HARDWARE_ANY : MFX_IMPL_SOFTWARE);
if (!priv->session)
priv->session = msdk_session;
if (!priv->session.session)
goto failed;
#ifndef _WIN32
@ -222,7 +225,7 @@ gst_msdk_context_open (GstMsdkContext * context, gboolean hardware,
}
#endif
codename = msdk_get_platform_codename (priv->session);
codename = msdk_get_platform_codename (priv->session.session);
if (codename != MFX_PLATFORM_UNKNOWN)
GST_INFO ("Detected MFX platform with device code %d", codename);
@ -254,7 +257,7 @@ release_child_session (gpointer session)
status = MFXDisjoinSession (_session);
if (status != MFX_ERR_NONE)
GST_WARNING ("failed to disjoin (%s)", msdk_status_to_string (status));
msdk_close_session (_session);
msdk_close_mfx_session (_session);
}
static void
@ -269,7 +272,7 @@ gst_msdk_context_finalize (GObject * obj)
else
g_list_free_full (priv->child_session_list, release_child_session);
msdk_close_session (priv->session);
msdk_close_session (&priv->session);
g_mutex_clear (&priv->mutex);
#ifndef _WIN32
@ -313,24 +316,28 @@ gst_msdk_context_new_with_parent (GstMsdkContext * parent)
GstMsdkContextPrivate *priv = obj->priv;
GstMsdkContextPrivate *parent_priv = parent->priv;
status = MFXCloneSession (parent_priv->session, &priv->session);
status =
MFXCloneSession (parent_priv->session.session, &priv->session.session);
if (status != MFX_ERR_NONE) {
GST_ERROR ("Failed to clone mfx session");
g_object_unref (obj);
return NULL;
}
/* Set loader to NULL for child session */
priv->session.loader = NULL;
priv->is_joined = TRUE;
priv->hardware = parent_priv->hardware;
priv->job_type = parent_priv->job_type;
parent_priv->child_session_list =
g_list_prepend (parent_priv->child_session_list, priv->session);
g_list_prepend (parent_priv->child_session_list, priv->session.session);
#ifndef _WIN32
priv->dpy = parent_priv->dpy;
priv->fd = parent_priv->fd;
if (priv->hardware) {
status = MFXVideoCORE_SetHandle (priv->session, MFX_HANDLE_VA_DISPLAY,
status =
MFXVideoCORE_SetHandle (priv->session.session, MFX_HANDLE_VA_DISPLAY,
(mfxHDL) parent_priv->dpy);
if (status != MFX_ERR_NONE) {
@ -349,7 +356,7 @@ gst_msdk_context_new_with_parent (GstMsdkContext * parent)
mfxSession
gst_msdk_context_get_session (GstMsdkContext * context)
{
return context->priv->session;
return context->priv->session.session;
}
gpointer
@ -658,7 +665,7 @@ gst_msdk_context_set_frame_allocator (GstMsdkContext * context,
if (!priv->has_frame_allocator) {
mfxStatus status;
status = MFXVideoCORE_SetFrameAllocator (priv->session, allocator);
status = MFXVideoCORE_SetFrameAllocator (priv->session.session, allocator);
if (status != MFX_ERR_NONE)
GST_ERROR ("Failed to set frame allocator");

View file

@ -174,8 +174,149 @@ msdk_get_platform_codename (mfxSession session)
return codename;
}
#if (MFX_VERSION >= 2000)
mfxStatus
msdk_init_msdk_session (mfxIMPL impl, mfxVersion * pver,
MsdkSession * msdk_session)
{
mfxStatus sts = MFX_ERR_NONE;
mfxLoader loader = NULL;
mfxSession session = NULL;
uint32_t impl_idx = 0;
mfxConfig cfg;
mfxVariant impl_value;
loader = msdk_session->loader;
if (!loader) {
loader = MFXLoad ();
GST_INFO ("Use the Intel oneVPL SDK to create MFX session");
if (!loader) {
GST_ERROR ("Failed to create a MFX loader");
return MFX_ERR_UNKNOWN;
}
/* Create configurations for implementation */
cfg = MFXCreateConfig (loader);
if (!cfg) {
GST_ERROR ("Failed to create a MFX configuration");
MFXUnload (loader);
return MFX_ERR_UNKNOWN;
}
impl_value.Type = MFX_VARIANT_TYPE_U32;
impl_value.Data.U32 =
(impl ==
MFX_IMPL_SOFTWARE) ? MFX_IMPL_TYPE_SOFTWARE : MFX_IMPL_TYPE_HARDWARE;
sts =
MFXSetConfigFilterProperty (cfg,
(const mfxU8 *) "mfxImplDescription.Impl", impl_value);
if (sts != MFX_ERR_NONE) {
GST_ERROR ("Failed to add an additional MFX configuration (%s)",
msdk_status_to_string (sts));
MFXUnload (loader);
return sts;
}
impl_value.Type = MFX_VARIANT_TYPE_U32;
impl_value.Data.U32 = pver->Version;
sts =
MFXSetConfigFilterProperty (cfg,
(const mfxU8 *) "mfxImplDescription.ApiVersion.Version", impl_value);
if (sts != MFX_ERR_NONE) {
GST_ERROR ("Failed to add an additional MFX configuration (%s)",
msdk_status_to_string (sts));
MFXUnload (loader);
return sts;
}
}
while (1) {
/* Enumerate all implementations */
mfxImplDescription *impl_desc;
sts = MFXEnumImplementations (loader, impl_idx,
MFX_IMPLCAPS_IMPLDESCSTRUCTURE, (mfxHDL *) & impl_desc);
/* Failed to find an available implementation */
if (sts == MFX_ERR_NOT_FOUND)
break;
else if (sts != MFX_ERR_NONE) {
impl_idx++;
continue;
}
sts = MFXCreateSession (loader, impl_idx, &session);
MFXDispReleaseImplDescription (loader, impl_desc);
if (sts == MFX_ERR_NONE)
break;
impl_idx++;
}
if (sts != MFX_ERR_NONE) {
GST_ERROR ("Failed to create a MFX session (%s)",
msdk_status_to_string (sts));
if (!msdk_session->loader)
MFXUnload (loader);
return sts;
}
msdk_session->session = session;
msdk_session->loader = loader;
return MFX_ERR_NONE;
}
#else
mfxStatus
msdk_init_msdk_session (mfxIMPL impl, mfxVersion * pver,
MsdkSession * msdk_session)
{
mfxStatus status;
mfxSession session = NULL;
mfxInitParam init_par = { impl, *pver };
GST_INFO ("Use the Intel Media SDK to create MFX session");
#if (MFX_VERSION >= 1025)
init_par.GPUCopy = 1;
#endif
status = MFXInitEx (init_par, &session);
if (status != MFX_ERR_NONE) {
GST_ERROR ("Failed to initialize a MFX session (%s)",
msdk_status_to_string (status));
return status;
}
msdk_session->session = session;
msdk_session->loader = NULL;
return MFX_ERR_NONE;
}
void
msdk_close_session (mfxSession session)
MFXUnload (mfxLoader loader)
{
g_assert (loader == NULL);
}
#endif
void
msdk_close_mfx_session (mfxSession session)
{
mfxStatus status;
@ -187,31 +328,36 @@ msdk_close_session (mfxSession session)
GST_ERROR ("Close failed (%s)", msdk_status_to_string (status));
}
mfxSession
void
msdk_close_session (MsdkSession * msdk_session)
{
msdk_close_mfx_session (msdk_session->session);
MFXUnload (msdk_session->loader);
}
MsdkSession
msdk_open_session (mfxIMPL impl)
{
mfxSession session = NULL;
mfxVersion version = { {1, 1}
};
mfxInitParam init_par = { impl, version };
mfxIMPL implementation;
mfxStatus status;
MsdkSession msdk_session;
static const gchar *implementation_names[] = {
"AUTO", "SOFTWARE", "HARDWARE", "AUTO_ANY", "HARDWARE_ANY", "HARDWARE2",
"HARDWARE3", "HARDWARE4", "RUNTIME"
};
#if (MFX_VERSION >= 1025)
init_par.GPUCopy = 1;
#endif
msdk_session.session = NULL;
msdk_session.loader = NULL;
status = msdk_init_msdk_session (impl, &version, &msdk_session);
status = MFXInitEx (init_par, &session);
if (status != MFX_ERR_NONE) {
GST_ERROR ("Intel Media SDK not available (%s)",
msdk_status_to_string (status));
goto failed;
}
if (status != MFX_ERR_NONE)
return msdk_session;
else
session = msdk_session.session;
status = MFXQueryIMPL (session, &implementation);
if (status != MFX_ERR_NONE) {
@ -230,11 +376,13 @@ msdk_open_session (mfxIMPL impl)
implementation_names[MFX_IMPL_BASETYPE (implementation)]);
GST_INFO ("MFX version: %d.%d", version.Major, version.Minor);
return session;
return msdk_session;
failed:
msdk_close_session (session);
return NULL;
msdk_close_session (&msdk_session);
msdk_session.session = NULL;
msdk_session.loader = NULL;
return msdk_session;
}
gboolean

View file

@ -47,6 +47,8 @@
#if (MFX_VERSION < 2000)
#include <mfxplugin.h>
#else
#include <mfxdispatcher.h>
#define mfxPluginUID char
static const char MFX_PLUGINID_HEVCD_SW;
static const char MFX_PLUGINID_HEVCD_HW;
@ -75,8 +77,23 @@ G_BEGIN_DECLS
GST_MSDK_CAPS_MAKE (format) "; " \
GST_MSDK_CAPS_MAKE_WITH_DMABUF_FEATURE (dmaformat)
mfxSession msdk_open_session (mfxIMPL impl);
void msdk_close_session (mfxSession session);
#if (MFX_VERSION < 2000)
typedef void * mfxLoader;
void MFXUnload (mfxLoader loader);
#endif
typedef struct _MsdkSession MsdkSession;
struct _MsdkSession
{
mfxSession session;
mfxLoader loader;
};
MsdkSession msdk_open_session (mfxIMPL impl);
void msdk_close_mfx_session (mfxSession session);
void msdk_close_session (MsdkSession * session);
gboolean msdk_is_available (void);
@ -119,6 +136,10 @@ gst_msdk_load_plugin (mfxSession session, const mfxPluginUID * uid,
mfxU16
msdk_get_platform_codename (mfxSession session);
mfxStatus
msdk_init_msdk_session (mfxIMPL impl, mfxVersion * pver,
MsdkSession * msdk_session);
G_END_DECLS
#endif /* __MSDK_H__ */