}
gboolean
-gst_msdk_context_prepare (GstElement * element, GstMsdkContext ** context_ptr)
+gst_msdk_context_find (GstElement * element, GstMsdkContext ** context_ptr)
{
g_return_val_if_fail (element != NULL, FALSE);
g_return_val_if_fail (context_ptr != NULL, FALSE);
G_BEGIN_DECLS
gboolean
-gst_msdk_context_prepare (GstElement * element, GstMsdkContext ** context_ptr);
+gst_msdk_context_find (GstElement * element, GstMsdkContext ** context_ptr);
gboolean
gst_msdk_context_get_context (GstContext * context, GstMsdkContext ** msdk_context);
}
static gboolean
-gst_msdkdec_start (GstVideoDecoder * decoder)
+gst_msdkdec_context_prepare (GstMsdkDec * thiz)
{
- 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);
+ /* Try to find an existing context from the pipeline. This may (indirectly)
+ * invoke gst_msdkdec_set_context, which will set thiz->context. */
+ if (!gst_msdk_context_find (GST_ELEMENT_CAST (thiz), &thiz->context))
+ return FALSE;
- /* TODO: Currently d3d allocator is not implemented.
- * So decoder uses system memory by default on Windows.
- */
+ /* TODO: Currently d3d allocator is not implemented.
+ * So decoder uses system memory by default on Windows.
+ */
#ifndef _WIN32
- thiz->use_video_memory = TRUE;
+ thiz->use_video_memory = TRUE;
#else
- thiz->use_video_memory = FALSE;
+ thiz->use_video_memory = FALSE;
#endif
- if (gst_msdk_context_get_job_type (thiz->context) & GST_MSDK_JOB_DECODER) {
- GstMsdkContext *parent_context, *msdk_context;
-
- parent_context = thiz->context;
- msdk_context = gst_msdk_context_new_with_parent (parent_context);
+ GST_INFO_OBJECT (thiz, "Found context %" GST_PTR_FORMAT " from neighbour",
+ thiz->context);
- if (!msdk_context) {
- GST_ERROR_OBJECT (thiz, "Context creation failed");
- return FALSE;
- }
+ if (!gst_msdk_context_get_job_type (thiz->context) & GST_MSDK_JOB_DECODER) {
+ gst_msdk_context_add_job_type (thiz->context, GST_MSDK_JOB_DECODER);
+ return TRUE;
+ }
- thiz->context = msdk_context;
+ /* Found an existing context that's already being used as a decoder, clone
+ * the MFX session inside it to create a new one */
+ {
+ GstMsdkContext *parent_context, *msdk_context;
- gst_msdk_context_add_shared_async_depth (thiz->context,
- gst_msdk_context_get_shared_async_depth (parent_context));
- gst_object_unref (parent_context);
+ GST_INFO_OBJECT (thiz, "Creating new context %" GST_PTR_FORMAT " with "
+ "joined session", thiz->context);
+ parent_context = thiz->context;
+ msdk_context = gst_msdk_context_new_with_parent (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);
+ if (!msdk_context) {
+ GST_ERROR_OBJECT (thiz, "Failed to create a context with parent context "
+ "as %" GST_PTR_FORMAT, parent_context);
+ return FALSE;
}
- } else {
+
+ thiz->context = msdk_context;
+ gst_msdk_context_add_shared_async_depth (thiz->context,
+ gst_msdk_context_get_shared_async_depth (parent_context));
+ gst_object_unref (parent_context);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+gst_msdkdec_start (GstVideoDecoder * decoder)
+{
+ GstMsdkDec *thiz = GST_MSDKDEC (decoder);
+
+ if (!gst_msdkdec_context_prepare (thiz)) {
if (!gst_msdk_context_ensure_context (GST_ELEMENT_CAST (thiz),
thiz->hardware, GST_MSDK_JOB_DECODER))
return FALSE;
}
static gboolean
-gst_msdkenc_start (GstVideoEncoder * encoder)
+gst_msdkenc_context_prepare (GstMsdkEnc * thiz)
{
- 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);
+ /* Try to find an existing context from the pipeline. This may (indirectly)
+ * invoke gst_msdkenc_set_context, which will set thiz->context. */
+ if (!gst_msdk_context_find (GST_ELEMENT_CAST (thiz), &thiz->context))
+ return FALSE;
- /* Check GST_MSDK_JOB_VPP and GST_MSDK_JOB_ENCODER together to avoid sharing context
- * between VPP and ENCODER
- * Example:
- * gst-launch-1.0 videotestsrc ! video/x-raw,format=I420 ! msdkh264enc ! \
- * msdkh264dec ! msdkvpp ! video/x-raw,format=YUY2 ! fakesink
- */
- if (gst_msdk_context_get_job_type (thiz->context) & (GST_MSDK_JOB_VPP |
- GST_MSDK_JOB_ENCODER)) {
- GstMsdkContext *parent_context, *msdk_context;
+ GST_INFO_OBJECT (thiz, "Found context %" GST_PTR_FORMAT " from neighbour",
+ thiz->context);
- parent_context = thiz->context;
- msdk_context = gst_msdk_context_new_with_parent (parent_context);
+ /* Check GST_MSDK_JOB_VPP and GST_MSDK_JOB_ENCODER together to avoid sharing context
+ * between VPP and ENCODER
+ * Example:
+ * gst-launch-1.0 videotestsrc ! video/x-raw,format=I420 ! msdkh264enc ! \
+ * msdkh264dec ! msdkvpp ! video/x-raw,format=YUY2 ! fakesink
+ */
+ if (!gst_msdk_context_get_job_type (thiz->context) & (GST_MSDK_JOB_VPP |
+ GST_MSDK_JOB_ENCODER)) {
+ gst_msdk_context_add_job_type (thiz->context, GST_MSDK_JOB_ENCODER);
+ return TRUE;
+ }
- if (!msdk_context) {
- GST_ERROR_OBJECT (thiz, "Context creation failed");
- return FALSE;
- }
+ /* Found an existing context that's already being used as an encoder, clone
+ * the MFX session inside it to create a new one */
+ {
+ GstMsdkContext *parent_context, *msdk_context;
- thiz->context = msdk_context;
- gst_object_unref (parent_context);
+ GST_INFO_OBJECT (thiz, "Creating new context %" GST_PTR_FORMAT " with "
+ "joined session", thiz->context);
+ parent_context = thiz->context;
+ msdk_context = gst_msdk_context_new_with_parent (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);
+ if (!msdk_context) {
+ GST_ERROR_OBJECT (thiz, "Failed to create a context with parent context "
+ "as %" GST_PTR_FORMAT, parent_context);
+ return FALSE;
}
- } else {
+
+ thiz->context = msdk_context;
+ gst_object_unref (parent_context);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+gst_msdkenc_start (GstVideoEncoder * encoder)
+{
+ GstMsdkEnc *thiz = GST_MSDKENC (encoder);
+
+ if (!gst_msdkenc_context_prepare (thiz)) {
if (!gst_msdk_context_ensure_context (GST_ELEMENT_CAST (thiz),
thiz->hardware, GST_MSDK_JOB_ENCODER))
return FALSE;
}
static gboolean
-ensure_context (GstBaseTransform * trans)
+gst_msdkvpp_context_prepare (GstMsdkVPP * thiz)
{
- GstMsdkVPP *thiz = GST_MSDKVPP (trans);
-
- if (gst_msdk_context_prepare (GST_ELEMENT_CAST (thiz), &thiz->context)) {
- GST_INFO_OBJECT (thiz, "Found context from neighbour %" GST_PTR_FORMAT,
- thiz->context);
+ /* Try to find an existing context from the pipeline. This may (indirectly)
+ * invoke gst_msdkvpp_set_context, which will set thiz->context. */
+ if (!gst_msdk_context_find (GST_ELEMENT_CAST (thiz), &thiz->context))
+ return FALSE;
- /* Check GST_MSDK_JOB_VPP and GST_MSDK_JOB_ENCODER together to avoid sharing context
- * between VPP and ENCODER
- * Example:
- * gst-launch-1.0 videotestsrc ! msdkvpp ! video/x-raw,format=YUY2 ! msdkh264enc ! fakesink
- */
- if (gst_msdk_context_get_job_type (thiz->context) & (GST_MSDK_JOB_ENCODER |
- GST_MSDK_JOB_VPP)) {
- GstMsdkContext *parent_context, *msdk_context;
+ GST_INFO_OBJECT (thiz, "Found context %" GST_PTR_FORMAT " from neighbour",
+ thiz->context);
- parent_context = thiz->context;
- msdk_context = gst_msdk_context_new_with_parent (parent_context);
+ /* Check GST_MSDK_JOB_VPP and GST_MSDK_JOB_ENCODER together to avoid sharing context
+ * between VPP and ENCODER
+ * Example:
+ * gst-launch-1.0 videotestsrc ! msdkvpp ! video/x-raw,format=YUY2 ! msdkh264enc ! fakesink
+ */
+ if (!gst_msdk_context_get_job_type (thiz->context) & (GST_MSDK_JOB_VPP |
+ GST_MSDK_JOB_ENCODER)) {
+ gst_msdk_context_add_job_type (thiz->context, GST_MSDK_JOB_VPP);
+ return TRUE;
+ }
- if (!msdk_context) {
- GST_ERROR_OBJECT (thiz, "Context creation failed");
- return FALSE;
- }
+ /* Found an existing context that's already being used as VPP, so clone the
+ * MFX session inside it to create a new one */
+ {
+ GstMsdkContext *parent_context, *msdk_context;
- thiz->context = msdk_context;
- gst_object_unref (parent_context);
+ GST_INFO_OBJECT (thiz, "Creating new context %" GST_PTR_FORMAT " with "
+ "joined session", thiz->context);
+ parent_context = thiz->context;
+ msdk_context = gst_msdk_context_new_with_parent (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_VPP);
+ if (!msdk_context) {
+ GST_ERROR_OBJECT (thiz, "Failed to create a context with parent context "
+ "as %" GST_PTR_FORMAT, parent_context);
+ return FALSE;
}
- } else {
+
+ thiz->context = msdk_context;
+ gst_object_unref (parent_context);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+ensure_context (GstBaseTransform * trans)
+{
+ GstMsdkVPP *thiz = GST_MSDKVPP (trans);
+
+ if (!gst_msdkvpp_context_prepare (thiz)) {
if (!gst_msdk_context_ensure_context (GST_ELEMENT_CAST (thiz),
thiz->hardware, GST_MSDK_JOB_VPP))
return FALSE;