mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-08 23:42:28 +00:00
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:
parent
dc82ccb9a2
commit
f2b35abcab
4 changed files with 133 additions and 33 deletions
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue