msdk: context: add job type to figure out if joining session is necessary

According to the driver's instruction, if there are two or more encoders
or decoders in a process, the session should be joined by
MFXJoinSession.

To achieve this successfully by GstContext, this patch adds job type
specified if it's encoder, decoder or vpp.

If a msdk element gets to know if joining session is needed by the
shared context,
it should create another instance of GstContext with joined session,
which
is not shared.

https://bugzilla.gnome.org/show_bug.cgi?id=790752
This commit is contained in:
Hyunjun Ko 2018-02-13 13:50:48 -09:00 committed by Sreerenj Balachandran
parent dddb84897f
commit dc82ccb9a2
6 changed files with 85 additions and 9 deletions

View file

@ -53,6 +53,9 @@ struct _GstMsdkContextPrivate
{
mfxSession session;
GList *cached_alloc_responses;
gboolean hardware;
gboolean is_joined;
GstMsdkContextJobType job_type;
#ifndef _WIN32
gint fd;
VADisplay dpy;
@ -113,10 +116,13 @@ failed:
#endif
static gboolean
gst_msdk_context_open (GstMsdkContext * context, gboolean hardware)
gst_msdk_context_open (GstMsdkContext * context, gboolean hardware,
GstMsdkContextJobType job_type)
{
GstMsdkContextPrivate *priv = context->priv;
priv->job_type = job_type;
priv->hardware = hardware;
priv->session = msdk_open_session (hardware);
if (!priv->session)
goto failed;
@ -151,6 +157,12 @@ gst_msdk_context_finalize (GObject * obj)
{
GstMsdkContext *context = GST_MSDK_CONTEXT_CAST (obj);
GstMsdkContextPrivate *priv = context->priv;
if (priv->is_joined) {
MFXDisjoinSession (priv->session);
goto done;
}
msdk_close_session (priv->session);
#ifndef _WIN32
@ -160,6 +172,7 @@ gst_msdk_context_finalize (GObject * obj)
close (priv->fd);
#endif
done:
G_OBJECT_CLASS (parent_class)->finalize (obj);
}
@ -173,11 +186,11 @@ gst_msdk_context_class_init (GstMsdkContextClass * klass)
}
GstMsdkContext *
gst_msdk_context_new (gboolean hardware)
gst_msdk_context_new (gboolean hardware, GstMsdkContextJobType job_type)
{
GstMsdkContext *obj = g_object_new (GST_TYPE_MSDK_CONTEXT, NULL);
if (obj && !gst_msdk_context_open (obj, hardware)) {
if (obj && !gst_msdk_context_open (obj, hardware, job_type)) {
if (obj)
gst_object_unref (obj);
return NULL;
@ -186,6 +199,42 @@ gst_msdk_context_new (gboolean hardware)
return obj;
}
GstMsdkContext *
gst_msdk_context_new_with_parent (GstMsdkContext * parent)
{
mfxStatus status;
GstMsdkContext *obj = g_object_new (GST_TYPE_MSDK_CONTEXT, NULL);
GstMsdkContextPrivate *priv = obj->priv;
GstMsdkContextPrivate *parent_priv = parent->priv;
status = MFXCloneSession (parent_priv->session, &priv->session);
if (status != MFX_ERR_NONE) {
GST_ERROR ("Failed to clone mfx session");
return NULL;
}
status = MFXJoinSession (parent_priv->session, priv->session);
if (status != MFX_ERR_NONE) {
GST_ERROR ("Failed to join mfx session");
return NULL;
}
priv->is_joined = TRUE;
priv->hardware = parent_priv->hardware;
priv->job_type = parent_priv->job_type;
#ifndef _WIN32
priv->dpy = parent_priv->dpy;
priv->fd = parent_priv->fd;
if (priv->hardware) {
status = MFXVideoCORE_SetHandle (priv->session, MFX_HANDLE_VA_DISPLAY,
(mfxHDL) parent_priv->dpy);
}
#endif
return obj;
}
mfxSession
gst_msdk_context_get_session (GstMsdkContext * context)
{
@ -286,3 +335,16 @@ gst_msdk_context_remove_alloc_response (GstMsdkContext * context,
return TRUE;
}
GstMsdkContextJobType
gst_msdk_context_get_job_type (GstMsdkContext * context)
{
return context->priv->job_type;
}
void
gst_msdk_context_add_job_type (GstMsdkContext * context,
GstMsdkContextJobType job_type)
{
context->priv->job_type |= job_type;
}

View file

@ -58,6 +58,12 @@ typedef struct _GstMsdkContext GstMsdkContext;
typedef struct _GstMsdkContextClass GstMsdkContextClass;
typedef struct _GstMsdkContextPrivate GstMsdkContextPrivate;
typedef enum {
GST_MSDK_JOB_DECODER = 0x01,
GST_MSDK_JOB_ENCODER = 0x02,
GST_MSDK_JOB_VPP = 0x04,
} GstMsdkContextJobType;
/*
* GstMsdkContext:
*/
@ -78,7 +84,8 @@ struct _GstMsdkContextClass
GType gst_msdk_context_get_type (void);
GstMsdkContext * gst_msdk_context_new (gboolean hardware);
GstMsdkContext * gst_msdk_context_new (gboolean hardware, GstMsdkContextJobType job_type);
GstMsdkContext * gst_msdk_context_new_with_parent (GstMsdkContext * parent);
mfxSession gst_msdk_context_get_session (GstMsdkContext * context);
gpointer gst_msdk_context_get_handle (GstMsdkContext * context);
@ -112,6 +119,12 @@ gboolean
gst_msdk_context_remove_alloc_response (GstMsdkContext * context,
mfxFrameAllocResponse * resp);
GstMsdkContextJobType
gst_msdk_context_get_job_type (GstMsdkContext * context);
void
gst_msdk_context_add_job_type (GstMsdkContext * context, GstMsdkContextJobType job_type);
G_END_DECLS
#endif /* GST_MSDK_CONTEXT_H */

View file

@ -215,11 +215,12 @@ gst_msdk_context_propagate (GstElement * element, GstMsdkContext * msdk_context)
}
gboolean
gst_msdk_context_ensure_context (GstElement * element, gboolean hardware)
gst_msdk_context_ensure_context (GstElement * element, gboolean hardware,
GstMsdkContextJobType job)
{
GstMsdkContext *msdk_context;
msdk_context = gst_msdk_context_new (hardware);
msdk_context = gst_msdk_context_new (hardware, job);
if (!msdk_context) {
GST_ERROR_OBJECT (element, "Context creation failed");
return FALSE;

View file

@ -50,7 +50,7 @@ gboolean
gst_msdk_context_get_context (GstContext * context, GstMsdkContext ** msdk_context);
gboolean
gst_msdk_context_ensure_context (GstElement * element, gboolean hardware);
gst_msdk_context_ensure_context (GstElement * element, gboolean hardware, GstMsdkContextJobType job);
G_END_DECLS

View file

@ -243,7 +243,7 @@ gst_msdkdec_init_decoder (GstMsdkDec * thiz)
/* make sure that the decoder is closed */
gst_msdkdec_close_decoder (thiz);
thiz->context = gst_msdk_context_new (thiz->hardware);
thiz->context = gst_msdk_context_new (thiz->hardware, GST_MSDK_JOB_DECODER);
if (!thiz->context) {
GST_ERROR_OBJECT (thiz, "Context creation failed");
return FALSE;

View file

@ -169,7 +169,7 @@ gst_msdkenc_init_encoder (GstMsdkEnc * thiz)
/* make sure that the encoder is closed */
gst_msdkenc_close_encoder (thiz);
thiz->context = gst_msdk_context_new (thiz->hardware);
thiz->context = gst_msdk_context_new (thiz->hardware, GST_MSDK_JOB_ENCODER);
if (!thiz->context) {
GST_ERROR_OBJECT (thiz, "Context creation failed");
return FALSE;