summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHyunjun Ko <zzoon@igalia.com>2018-02-13 13:51:18 -0900
committerSreerenj Balachandran <sreerenj.balachandran@intel.com>2018-02-13 13:51:18 -0900
commitf2b35abcabeafe5de0bc78bfcde4e5615deb166d (patch)
tree978e1693f8254be6b24ea27e1018ecd07d9f629f
parentdc82ccb9a295862346d785d6496939e6ab2e8139 (diff)
downloadgstreamer-plugins-bad-f2b35abcabeafe5de0bc78bfcde4e5615deb166d.tar.gz
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
-rw-r--r--sys/msdk/gstmsdkdec.c84
-rw-r--r--sys/msdk/gstmsdkdec.h1
-rw-r--r--sys/msdk/gstmsdkenc.c80
-rw-r--r--sys/msdk/gstmsdkenc.h1
4 files changed, 133 insertions, 33 deletions
diff --git a/sys/msdk/gstmsdkdec.c b/sys/msdk/gstmsdkdec.c
index a4ed46503..916b3d22c 100644
--- a/sys/msdk/gstmsdkdec.c
+++ b/sys/msdk/gstmsdkdec.c
@@ -39,6 +39,7 @@
#include "gstmsdkbufferpool.h"
#include "gstmsdkvideomemory.h"
#include "gstmsdksystemmemory.h"
+#include "gstmsdkcontextutil.h"
GST_DEBUG_CATEGORY_EXTERN (gst_msdkdec_debug);
#define GST_CAT_DEFAULT gst_msdkdec_debug
@@ -203,10 +204,11 @@ gst_msdkdec_close_decoder (GstMsdkDec * thiz)
{
mfxStatus status;
- if (!thiz->context)
+ if (!thiz->context || !thiz->initialized)
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)
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_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));
+ 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
@@ -234,20 +250,19 @@ gst_msdkdec_init_decoder (GstMsdkDec * thiz)
mfxStatus status;
mfxFrameAllocRequest request;
- if (!thiz->input_state) {
- GST_DEBUG_OBJECT (thiz, "Have no input state yet");
+ if (thiz->initialized)
+ return TRUE;
+
+ if (!thiz->context) {
+ GST_WARNING_OBJECT (thiz, "No MSDK Context");
return FALSE;
}
- 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");
+ if (!thiz->input_state) {
+ GST_DEBUG_OBJECT (thiz, "Have no input state yet");
return FALSE;
}
+ info = &thiz->input_state->info;
GST_OBJECT_LOCK (thiz);
@@ -346,12 +361,11 @@ gst_msdkdec_init_decoder (GstMsdkDec * thiz)
GST_OBJECT_UNLOCK (thiz);
+ thiz->initialized = TRUE;
return TRUE;
failed:
GST_OBJECT_UNLOCK (thiz);
- gst_object_replace ((GstObject **) & thiz->context, NULL);
- thiz->context = NULL;
return FALSE;
}
@@ -474,6 +488,39 @@ gst_msdkdec_finish_task (GstMsdkDec * thiz, MsdkDecTask * task)
}
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
gst_msdkdec_close (GstVideoDecoder * decoder)
{
GstMsdkDec *thiz = GST_MSDKDEC (decoder);
@@ -498,6 +545,8 @@ gst_msdkdec_stop (GstVideoDecoder * decoder)
}
gst_video_info_init (&thiz->output_info);
gst_video_info_init (&thiz->pool_info);
+
+ gst_msdkdec_close_decoder (thiz);
return TRUE;
}
@@ -853,7 +902,7 @@ gst_msdkdec_drain (GstVideoDecoder * decoder)
mfxStatus status;
guint i;
- if (!thiz->context)
+ if (!thiz->initialized)
return GST_FLOW_OK;
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->finalize = gst_msdkdec_finalize;
+ element_class->set_context = gst_msdkdec_set_context;
+
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->set_format = GST_DEBUG_FUNCPTR (gst_msdkdec_set_format);
decoder_class->finish = GST_DEBUG_FUNCPTR (gst_msdkdec_finish);
diff --git a/sys/msdk/gstmsdkdec.h b/sys/msdk/gstmsdkdec.h
index ec386daaf..8488b42bc 100644
--- a/sys/msdk/gstmsdkdec.h
+++ b/sys/msdk/gstmsdkdec.h
@@ -67,6 +67,7 @@ struct _GstMsdkDec
GstVideoInfo pool_info;
mfxFrameAllocResponse alloc_resp;
gboolean use_video_memory;
+ gboolean initialized;
/* MFX context */
GstMsdkContext *context;
diff --git a/sys/msdk/gstmsdkenc.c b/sys/msdk/gstmsdkenc.c
index 602e66f72..50edcc3c3 100644
--- a/sys/msdk/gstmsdkenc.c
+++ b/sys/msdk/gstmsdkenc.c
@@ -48,7 +48,7 @@
#include "gstmsdkbufferpool.h"
#include "gstmsdkvideomemory.h"
#include "gstmsdksystemmemory.h"
-#include "gstmsdkallocator.h"
+#include "gstmsdkcontextutil.h"
static inline void *
_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
gst_msdkenc_init_encoder (GstMsdkEnc * thiz)
{
@@ -160,20 +175,19 @@ gst_msdkenc_init_encoder (GstMsdkEnc * thiz)
mfxFrameAllocRequest request[2];
guint i;
- if (!thiz->input_state) {
- GST_DEBUG_OBJECT (thiz, "Have no input state yet");
+ if (thiz->initialized)
+ return TRUE;
+
+ if (!thiz->context) {
+ GST_WARNING_OBJECT (thiz, "No MSDK Context");
return FALSE;
}
- 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");
+ if (!thiz->input_state) {
+ GST_DEBUG_OBJECT (thiz, "Have no input state yet");
return FALSE;
}
+ info = &thiz->input_state->info;
GST_OBJECT_LOCK (thiz);
session = gst_msdk_context_get_session (thiz->context);
@@ -346,6 +360,9 @@ gst_msdkenc_init_encoder (GstMsdkEnc * thiz)
msdk_status_to_string (status));
}
+ if (thiz->has_vpp)
+ request[0].NumFrameSuggested += thiz->num_vpp_surfaces + 1 - 4;
+
if (thiz->use_video_memory)
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->reconfig = FALSE;
+ thiz->initialized = TRUE;
GST_OBJECT_UNLOCK (thiz);
@@ -408,8 +426,6 @@ gst_msdkenc_init_encoder (GstMsdkEnc * thiz)
no_vpp:
failed:
GST_OBJECT_UNLOCK (thiz);
- if (thiz->context)
- gst_object_replace ((GstObject **) & thiz->context, NULL);
return FALSE;
}
@@ -419,10 +435,11 @@ gst_msdkenc_close_encoder (GstMsdkEnc * thiz)
guint i;
mfxStatus status;
- if (!thiz->context)
+ if (!thiz->context || !thiz->initialized)
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_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));
thiz->num_extra_params = 0;
+ thiz->initialized = FALSE;
}
typedef struct
@@ -1115,6 +1130,33 @@ invalid_frame:
static gboolean
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
the dts at the start of the stream from needing to be
negative. */
@@ -1136,6 +1178,8 @@ gst_msdkenc_stop (GstVideoEncoder * encoder)
gst_video_codec_state_unref (thiz->input_state);
thiz->input_state = NULL;
+ gst_object_replace ((GstObject **) & thiz->context, NULL);
+
return TRUE;
}
@@ -1360,6 +1404,8 @@ gst_msdkenc_class_init (GstMsdkEncClass * klass)
gobject_class->get_property = gst_msdkenc_get_property;
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->handle_frame = GST_DEBUG_FUNCPTR (gst_msdkenc_handle_frame);
gstencoder_class->start = GST_DEBUG_FUNCPTR (gst_msdkenc_start);
diff --git a/sys/msdk/gstmsdkenc.h b/sys/msdk/gstmsdkenc.h
index ae4f94c21..d59158587 100644
--- a/sys/msdk/gstmsdkenc.h
+++ b/sys/msdk/gstmsdkenc.h
@@ -91,6 +91,7 @@ struct _GstMsdkEnc
GstBufferPool *msdk_converted_pool;
GstVideoInfo aligned_info;
gboolean use_video_memory;
+ gboolean initialized;
/* element properties */
gboolean hardware;