msdkdec/enc: query GstContext to share GstMsdkContext

How to share/create GstMsdkcontext is the following:

- Search GstMsdkContext if there's in the pipeline.
  - If found, check if it's decoder, encoder or vpp by job type.
    - If it's same job type, it creates another instance of
GstMsdkContext
     with joined-session.
    - Otherwise just use the shared GstMsdkContext.
  - If not found, just creates new instance of GstMsdkContext.

https://bugzilla.gnome.org/show_bug.cgi?id=790752
This commit is contained in:
Hyunjun Ko 2018-02-13 13:51:18 -09:00 committed by Sreerenj Balachandran
parent dc82ccb9a2
commit f2b35abcab
4 changed files with 133 additions and 33 deletions

View file

@ -39,6 +39,7 @@
#include "gstmsdkbufferpool.h" #include "gstmsdkbufferpool.h"
#include "gstmsdkvideomemory.h" #include "gstmsdkvideomemory.h"
#include "gstmsdksystemmemory.h" #include "gstmsdksystemmemory.h"
#include "gstmsdkcontextutil.h"
GST_DEBUG_CATEGORY_EXTERN (gst_msdkdec_debug); GST_DEBUG_CATEGORY_EXTERN (gst_msdkdec_debug);
#define GST_CAT_DEFAULT gst_msdkdec_debug #define GST_CAT_DEFAULT gst_msdkdec_debug
@ -203,10 +204,11 @@ gst_msdkdec_close_decoder (GstMsdkDec * thiz)
{ {
mfxStatus status; mfxStatus status;
if (!thiz->context) if (!thiz->context || !thiz->initialized)
return; return;
GST_DEBUG_OBJECT (thiz, "Closing decoder 0x%p", thiz->context); GST_DEBUG_OBJECT (thiz, "Closing decoder with context %" GST_PTR_FORMAT,
thiz->context);
if (thiz->use_video_memory) if (thiz->use_video_memory)
gst_msdk_frame_free (thiz->context, &thiz->alloc_resp); gst_msdk_frame_free (thiz->context, &thiz->alloc_resp);
@ -220,9 +222,23 @@ gst_msdkdec_close_decoder (GstMsdkDec * thiz)
g_array_set_size (thiz->tasks, 0); g_array_set_size (thiz->tasks, 0);
g_ptr_array_set_size (thiz->extra_params, 0); g_ptr_array_set_size (thiz->extra_params, 0);
if (thiz->context)
gst_object_replace ((GstObject **) & thiz->context, NULL);
memset (&thiz->param, 0, sizeof (thiz->param)); memset (&thiz->param, 0, sizeof (thiz->param));
thiz->initialized = FALSE;
}
static void
gst_msdkdec_set_context (GstElement * element, GstContext * context)
{
GstMsdkContext *msdk_context = NULL;
GstMsdkDec *thiz = GST_MSDKDEC (element);
if (gst_msdk_context_get_context (context, &msdk_context)) {
gst_object_replace ((GstObject **) & thiz->context,
(GstObject *) msdk_context);
gst_object_unref (msdk_context);
}
GST_ELEMENT_CLASS (parent_class)->set_context (element, context);
} }
static gboolean static gboolean
@ -234,21 +250,20 @@ gst_msdkdec_init_decoder (GstMsdkDec * thiz)
mfxStatus status; mfxStatus status;
mfxFrameAllocRequest request; mfxFrameAllocRequest request;
if (thiz->initialized)
return TRUE;
if (!thiz->context) {
GST_WARNING_OBJECT (thiz, "No MSDK Context");
return FALSE;
}
if (!thiz->input_state) { if (!thiz->input_state) {
GST_DEBUG_OBJECT (thiz, "Have no input state yet"); GST_DEBUG_OBJECT (thiz, "Have no input state yet");
return FALSE; return FALSE;
} }
info = &thiz->input_state->info; info = &thiz->input_state->info;
/* make sure that the decoder is closed */
gst_msdkdec_close_decoder (thiz);
thiz->context = gst_msdk_context_new (thiz->hardware, GST_MSDK_JOB_DECODER);
if (!thiz->context) {
GST_ERROR_OBJECT (thiz, "Context creation failed");
return FALSE;
}
GST_OBJECT_LOCK (thiz); GST_OBJECT_LOCK (thiz);
if (thiz->use_video_memory) { if (thiz->use_video_memory) {
@ -346,12 +361,11 @@ gst_msdkdec_init_decoder (GstMsdkDec * thiz)
GST_OBJECT_UNLOCK (thiz); GST_OBJECT_UNLOCK (thiz);
thiz->initialized = TRUE;
return TRUE; return TRUE;
failed: failed:
GST_OBJECT_UNLOCK (thiz); GST_OBJECT_UNLOCK (thiz);
gst_object_replace ((GstObject **) & thiz->context, NULL);
thiz->context = NULL;
return FALSE; return FALSE;
} }
@ -473,6 +487,39 @@ gst_msdkdec_finish_task (GstMsdkDec * thiz, MsdkDecTask * task)
return GST_FLOW_OK; return GST_FLOW_OK;
} }
static gboolean
gst_msdkdec_start (GstVideoDecoder * decoder)
{
GstMsdkDec *thiz = GST_MSDKDEC (decoder);
if (gst_msdk_context_prepare (GST_ELEMENT_CAST (thiz), &thiz->context)) {
GST_INFO_OBJECT (thiz, "Found context %" GST_PTR_FORMAT " from neighbour",
thiz->context);
if (gst_msdk_context_get_job_type (thiz->context) & GST_MSDK_JOB_DECODER) {
GstMsdkContext *parent_context;
parent_context = thiz->context;
thiz->context = gst_msdk_context_new_with_parent (parent_context);
gst_object_unref (parent_context);
GST_INFO_OBJECT (thiz,
"Creating new context %" GST_PTR_FORMAT " with joined session",
thiz->context);
} else {
gst_msdk_context_add_job_type (thiz->context, GST_MSDK_JOB_DECODER);
}
} else {
gst_msdk_context_ensure_context (GST_ELEMENT_CAST (thiz), thiz->hardware,
GST_MSDK_JOB_DECODER);
GST_INFO_OBJECT (thiz, "Creating new context %" GST_PTR_FORMAT,
thiz->context);
}
return TRUE;
}
static gboolean static gboolean
gst_msdkdec_close (GstVideoDecoder * decoder) gst_msdkdec_close (GstVideoDecoder * decoder)
{ {
@ -498,6 +545,8 @@ gst_msdkdec_stop (GstVideoDecoder * decoder)
} }
gst_video_info_init (&thiz->output_info); gst_video_info_init (&thiz->output_info);
gst_video_info_init (&thiz->pool_info); gst_video_info_init (&thiz->pool_info);
gst_msdkdec_close_decoder (thiz);
return TRUE; return TRUE;
} }
@ -853,7 +902,7 @@ gst_msdkdec_drain (GstVideoDecoder * decoder)
mfxStatus status; mfxStatus status;
guint i; guint i;
if (!thiz->context) if (!thiz->initialized)
return GST_FLOW_OK; return GST_FLOW_OK;
session = gst_msdk_context_get_session (thiz->context); session = gst_msdk_context_get_session (thiz->context);
@ -1017,7 +1066,10 @@ gst_msdkdec_class_init (GstMsdkDecClass * klass)
gobject_class->get_property = gst_msdkdec_get_property; gobject_class->get_property = gst_msdkdec_get_property;
gobject_class->finalize = gst_msdkdec_finalize; gobject_class->finalize = gst_msdkdec_finalize;
element_class->set_context = gst_msdkdec_set_context;
decoder_class->close = GST_DEBUG_FUNCPTR (gst_msdkdec_close); decoder_class->close = GST_DEBUG_FUNCPTR (gst_msdkdec_close);
decoder_class->start = GST_DEBUG_FUNCPTR (gst_msdkdec_start);
decoder_class->stop = GST_DEBUG_FUNCPTR (gst_msdkdec_stop); decoder_class->stop = GST_DEBUG_FUNCPTR (gst_msdkdec_stop);
decoder_class->set_format = GST_DEBUG_FUNCPTR (gst_msdkdec_set_format); decoder_class->set_format = GST_DEBUG_FUNCPTR (gst_msdkdec_set_format);
decoder_class->finish = GST_DEBUG_FUNCPTR (gst_msdkdec_finish); decoder_class->finish = GST_DEBUG_FUNCPTR (gst_msdkdec_finish);

View file

@ -67,6 +67,7 @@ struct _GstMsdkDec
GstVideoInfo pool_info; GstVideoInfo pool_info;
mfxFrameAllocResponse alloc_resp; mfxFrameAllocResponse alloc_resp;
gboolean use_video_memory; gboolean use_video_memory;
gboolean initialized;
/* MFX context */ /* MFX context */
GstMsdkContext *context; GstMsdkContext *context;

View file

@ -48,7 +48,7 @@
#include "gstmsdkbufferpool.h" #include "gstmsdkbufferpool.h"
#include "gstmsdkvideomemory.h" #include "gstmsdkvideomemory.h"
#include "gstmsdksystemmemory.h" #include "gstmsdksystemmemory.h"
#include "gstmsdkallocator.h" #include "gstmsdkcontextutil.h"
static inline void * static inline void *
_aligned_alloc (size_t alignment, size_t size) _aligned_alloc (size_t alignment, size_t size)
@ -150,6 +150,21 @@ gst_msdkenc_add_extra_param (GstMsdkEnc * thiz, mfxExtBuffer * param)
} }
} }
static void
gst_msdkenc_set_context (GstElement * element, GstContext * context)
{
GstMsdkContext *msdk_context = NULL;
GstMsdkEnc *thiz = GST_MSDKENC (element);
if (gst_msdk_context_get_context (context, &msdk_context)) {
gst_object_replace ((GstObject **) & thiz->context,
(GstObject *) msdk_context);
gst_object_unref (msdk_context);
}
GST_ELEMENT_CLASS (parent_class)->set_context (element, context);
}
static gboolean static gboolean
gst_msdkenc_init_encoder (GstMsdkEnc * thiz) gst_msdkenc_init_encoder (GstMsdkEnc * thiz)
{ {
@ -160,21 +175,20 @@ gst_msdkenc_init_encoder (GstMsdkEnc * thiz)
mfxFrameAllocRequest request[2]; mfxFrameAllocRequest request[2];
guint i; guint i;
if (thiz->initialized)
return TRUE;
if (!thiz->context) {
GST_WARNING_OBJECT (thiz, "No MSDK Context");
return FALSE;
}
if (!thiz->input_state) { if (!thiz->input_state) {
GST_DEBUG_OBJECT (thiz, "Have no input state yet"); GST_DEBUG_OBJECT (thiz, "Have no input state yet");
return FALSE; return FALSE;
} }
info = &thiz->input_state->info; info = &thiz->input_state->info;
/* make sure that the encoder is closed */
gst_msdkenc_close_encoder (thiz);
thiz->context = gst_msdk_context_new (thiz->hardware, GST_MSDK_JOB_ENCODER);
if (!thiz->context) {
GST_ERROR_OBJECT (thiz, "Context creation failed");
return FALSE;
}
GST_OBJECT_LOCK (thiz); GST_OBJECT_LOCK (thiz);
session = gst_msdk_context_get_session (thiz->context); session = gst_msdk_context_get_session (thiz->context);
@ -346,6 +360,9 @@ gst_msdkenc_init_encoder (GstMsdkEnc * thiz)
msdk_status_to_string (status)); msdk_status_to_string (status));
} }
if (thiz->has_vpp)
request[0].NumFrameSuggested += thiz->num_vpp_surfaces + 1 - 4;
if (thiz->use_video_memory) if (thiz->use_video_memory)
gst_msdk_frame_alloc (thiz->context, &(request[0]), &thiz->alloc_resp); gst_msdk_frame_alloc (thiz->context, &(request[0]), &thiz->alloc_resp);
@ -400,6 +417,7 @@ gst_msdkenc_init_encoder (GstMsdkEnc * thiz)
thiz->next_task = 0; thiz->next_task = 0;
thiz->reconfig = FALSE; thiz->reconfig = FALSE;
thiz->initialized = TRUE;
GST_OBJECT_UNLOCK (thiz); GST_OBJECT_UNLOCK (thiz);
@ -408,8 +426,6 @@ gst_msdkenc_init_encoder (GstMsdkEnc * thiz)
no_vpp: no_vpp:
failed: failed:
GST_OBJECT_UNLOCK (thiz); GST_OBJECT_UNLOCK (thiz);
if (thiz->context)
gst_object_replace ((GstObject **) & thiz->context, NULL);
return FALSE; return FALSE;
} }
@ -419,10 +435,11 @@ gst_msdkenc_close_encoder (GstMsdkEnc * thiz)
guint i; guint i;
mfxStatus status; mfxStatus status;
if (!thiz->context) if (!thiz->context || !thiz->initialized)
return; return;
GST_DEBUG_OBJECT (thiz, "Closing encoder 0x%p", thiz->context); GST_DEBUG_OBJECT (thiz, "Closing encoder with context %" GST_PTR_FORMAT,
thiz->context);
gst_object_replace ((GstObject **) & thiz->msdk_pool, NULL); gst_object_replace ((GstObject **) & thiz->msdk_pool, NULL);
gst_object_replace ((GstObject **) & thiz->msdk_converted_pool, NULL); gst_object_replace ((GstObject **) & thiz->msdk_converted_pool, NULL);
@ -460,11 +477,9 @@ gst_msdkenc_close_encoder (GstMsdkEnc * thiz)
} }
} }
if (thiz->context)
gst_object_replace ((GstObject **) & thiz->context, NULL);
memset (&thiz->param, 0, sizeof (thiz->param)); memset (&thiz->param, 0, sizeof (thiz->param));
thiz->num_extra_params = 0; thiz->num_extra_params = 0;
thiz->initialized = FALSE;
} }
typedef struct typedef struct
@ -1115,6 +1130,33 @@ invalid_frame:
static gboolean static gboolean
gst_msdkenc_start (GstVideoEncoder * encoder) gst_msdkenc_start (GstVideoEncoder * encoder)
{ {
GstMsdkEnc *thiz = GST_MSDKENC (encoder);
if (gst_msdk_context_prepare (GST_ELEMENT_CAST (thiz), &thiz->context)) {
GST_INFO_OBJECT (thiz, "Found context %" GST_PTR_FORMAT " from neighbour",
thiz->context);
if (gst_msdk_context_get_job_type (thiz->context) & GST_MSDK_JOB_ENCODER) {
GstMsdkContext *parent_context;
parent_context = thiz->context;
thiz->context = gst_msdk_context_new_with_parent (parent_context);
gst_object_unref (parent_context);
GST_INFO_OBJECT (thiz,
"Creating new context %" GST_PTR_FORMAT " with joined session",
thiz->context);
} else {
gst_msdk_context_add_job_type (thiz->context, GST_MSDK_JOB_ENCODER);
}
} else {
gst_msdk_context_ensure_context (GST_ELEMENT_CAST (thiz), thiz->hardware,
GST_MSDK_JOB_ENCODER);
GST_INFO_OBJECT (thiz, "Creating new context %" GST_PTR_FORMAT,
thiz->context);
}
/* Set the minimum pts to some huge value (1000 hours). This keeps /* Set the minimum pts to some huge value (1000 hours). This keeps
the dts at the start of the stream from needing to be the dts at the start of the stream from needing to be
negative. */ negative. */
@ -1136,6 +1178,8 @@ gst_msdkenc_stop (GstVideoEncoder * encoder)
gst_video_codec_state_unref (thiz->input_state); gst_video_codec_state_unref (thiz->input_state);
thiz->input_state = NULL; thiz->input_state = NULL;
gst_object_replace ((GstObject **) & thiz->context, NULL);
return TRUE; return TRUE;
} }
@ -1360,6 +1404,8 @@ gst_msdkenc_class_init (GstMsdkEncClass * klass)
gobject_class->get_property = gst_msdkenc_get_property; gobject_class->get_property = gst_msdkenc_get_property;
gobject_class->finalize = gst_msdkenc_finalize; gobject_class->finalize = gst_msdkenc_finalize;
element_class->set_context = gst_msdkenc_set_context;
gstencoder_class->set_format = GST_DEBUG_FUNCPTR (gst_msdkenc_set_format); gstencoder_class->set_format = GST_DEBUG_FUNCPTR (gst_msdkenc_set_format);
gstencoder_class->handle_frame = GST_DEBUG_FUNCPTR (gst_msdkenc_handle_frame); gstencoder_class->handle_frame = GST_DEBUG_FUNCPTR (gst_msdkenc_handle_frame);
gstencoder_class->start = GST_DEBUG_FUNCPTR (gst_msdkenc_start); gstencoder_class->start = GST_DEBUG_FUNCPTR (gst_msdkenc_start);

View file

@ -91,6 +91,7 @@ struct _GstMsdkEnc
GstBufferPool *msdk_converted_pool; GstBufferPool *msdk_converted_pool;
GstVideoInfo aligned_info; GstVideoInfo aligned_info;
gboolean use_video_memory; gboolean use_video_memory;
gboolean initialized;
/* element properties */ /* element properties */
gboolean hardware; gboolean hardware;