summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVíctor Manuel Jáquez Leal <victorx.jaquez@intel.com>2015-11-11 19:04:25 +0100
committerVíctor Manuel Jáquez Leal <victorx.jaquez@intel.com>2015-11-16 16:07:07 +0100
commitbd4395ce9f2bf037a86cd9597b4b22b652e61e8c (patch)
tree2e3cbfacb6e48933eaf516aefa8ee98c2f7c269d
parentce3d1a6203330d6a2110797dc89709605c4c9282 (diff)
downloadgst-vaapi-bd4395ce9f2bf037a86cd9597b4b22b652e61e8c.tar.gz
vaapidecodebin: add postprocessor dynamically
The former approach to left the bin unfinished has some problems: the context cannot be shared because the vaapidecode is unlinked in many cases, leading to creating a VADisplay twice. Initially the bin is fully functional, constructed as (-----------------------------------) | vaapidecodebin | | (-------------) (-------) | |<--| vaapidecode |--->| queue |--->| | (-------------) (-------) | (-----------------------------------) When the context is shared and the VADisplay has VPP capabilities, before changing to READY state, the bin is reconfigured dynamically, adding the vaapipostproc element afeter the queue: (--------------------------------------------------------) | vaapidecodebin | | (-------------) (-------) (---------------) | |<--| vaapidecode |--->| queue |--->| vaapipostproc |--->| | (-------------) (-------) (---------------) | (--------------------------------------------------------) Signed-off-by: Víctor Manuel Jáquez Leal <victorx.jaquez@intel.com> https://bugzilla.gnome.org/show_bug.cgi?id=757957
-rw-r--r--gst/vaapi/gstvaapidecodebin.c107
-rw-r--r--gst/vaapi/gstvaapidecodebin.h2
2 files changed, 66 insertions, 43 deletions
diff --git a/gst/vaapi/gstvaapidecodebin.c b/gst/vaapi/gstvaapidecodebin.c
index edde5c80..635cdf3b 100644
--- a/gst/vaapi/gstvaapidecodebin.c
+++ b/gst/vaapi/gstvaapidecodebin.c
@@ -124,15 +124,16 @@ post_missing_element_message (GstVaapiDecodeBin * vaapidecbin,
static gboolean
activate_vpp (GstVaapiDecodeBin * vaapidecbin)
{
- GstElement *src;
+ GstPad *queue_srcpad, *srcpad, *vpp_sinkpad, *vpp_srcpad;
+ gboolean res;
- if (vaapidecbin->ghost_pad_src || vaapidecbin->postproc)
+ if (vaapidecbin->postproc)
return TRUE;
- if (vaapidecbin->has_vpp != HAS_VPP_YES || vaapidecbin->disable_vpp) {
- src = vaapidecbin->queue;
- goto connect_src_ghost_pad;
- }
+ if (vaapidecbin->has_vpp != HAS_VPP_YES || vaapidecbin->disable_vpp)
+ return TRUE;
+
+ GST_DEBUG_OBJECT (vaapidecbin, "Enabling VPP");
/* create the postproc */
vaapidecbin->postproc =
@@ -144,35 +145,47 @@ activate_vpp (GstVaapiDecodeBin * vaapidecbin)
vaapidecbin->deinterlace_method, NULL);
gst_bin_add (GST_BIN (vaapidecbin), vaapidecbin->postproc);
- if (!gst_element_link_pads_full (vaapidecbin->queue, "src",
- vaapidecbin->postproc, "sink", GST_PAD_LINK_CHECK_NOTHING))
+
+ if (!gst_element_sync_state_with_parent (vaapidecbin->postproc))
+ goto error_sync_state;
+
+ srcpad = gst_element_get_static_pad (GST_ELEMENT_CAST (vaapidecbin), "src");
+ if (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (srcpad), NULL))
goto error_link_pad;
- GST_DEBUG_OBJECT (vaapidecbin, "Enabling VPP");
- src = vaapidecbin->postproc;
+ queue_srcpad = gst_element_get_static_pad (vaapidecbin->queue, "src");
+ vpp_sinkpad = gst_element_get_static_pad (vaapidecbin->postproc, "sink");
+ res = (gst_pad_link (queue_srcpad, vpp_sinkpad) == GST_PAD_LINK_OK);
+ gst_object_unref (vpp_sinkpad);
+ gst_object_unref (queue_srcpad);
+ if (!res)
+ goto error_link_pad;
+
+ vpp_srcpad = gst_element_get_static_pad (vaapidecbin->postproc, "src");
+ res = gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (srcpad), vpp_srcpad);
+ gst_object_unref (vpp_srcpad);
+ if (!res)
+ goto error_link_pad;
- goto connect_src_ghost_pad;
+ gst_object_unref (srcpad);
+
+ return TRUE;
error_element_missing:
{
post_missing_element_message (vaapidecbin, "vaapipostproc");
return FALSE;
}
-error_link_pad:
+error_sync_state:
{
- GST_ERROR_OBJECT (vaapidecbin, "Failed to link the child elements");
+ GST_ERROR_OBJECT (vaapidecbin, "Failed to sync VPP state");
return FALSE;
}
-connect_src_ghost_pad:
+error_link_pad:
{
- GstPad *srcpad, *ghostpad;
-
- srcpad = gst_element_get_static_pad (src, "src");
- ghostpad = gst_ghost_pad_new ("src", srcpad);
- vaapidecbin->ghost_pad_src = ghostpad;
gst_object_unref (srcpad);
- gst_element_add_pad (GST_ELEMENT (vaapidecbin), ghostpad);
- return TRUE;
+ GST_ERROR_OBJECT (vaapidecbin, "Failed to link the child elements");
+ return FALSE;
}
}
@@ -184,7 +197,7 @@ ensure_vpp (GstVaapiDecodeBin * vaapidecbin)
if (vaapidecbin->has_vpp != HAS_VPP_UNKNOWN)
return TRUE;
- GST_DEBUG_OBJECT (vaapidecbin, "Creating a dummy display to test for vpp");
+ GST_INFO_OBJECT (vaapidecbin, "Creating a dummy display to test for vpp");
display = gst_vaapi_create_test_display ();
if (!display)
return FALSE;
@@ -420,6 +433,8 @@ static gboolean
gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * vaapidecbin)
{
gchar *missing_factory = NULL;
+ GstPad *pad, *ghostpad;
+ GstPadTemplate *tmpl;
/* create the decoder */
vaapidecbin->decoder =
@@ -440,13 +455,29 @@ gst_vaapi_decode_bin_configure (GstVaapiDecodeBin * vaapidecbin)
"max-size-buffers", vaapidecbin->max_size_buffers,
"max-size-time", vaapidecbin->max_size_time, NULL);
- gst_bin_add_many (GST_BIN (vaapidecbin),
- vaapidecbin->decoder, vaapidecbin->queue, NULL);
+ gst_bin_add_many (GST_BIN (vaapidecbin), vaapidecbin->decoder,
+ vaapidecbin->queue, NULL);
- if (!gst_element_link_pads_full (vaapidecbin->decoder, "src",
- vaapidecbin->queue, "sink", GST_PAD_LINK_CHECK_NOTHING))
+ if (!gst_element_link_many (vaapidecbin->decoder, vaapidecbin->queue, NULL))
goto error_link_pad;
+ /* create ghost pad sink */
+ pad = gst_element_get_static_pad (GST_ELEMENT (vaapidecbin->decoder), "sink");
+ ghostpad = gst_ghost_pad_new_from_template ("sink", pad,
+ GST_PAD_PAD_TEMPLATE (pad));
+ gst_object_unref (pad);
+ if (!gst_element_add_pad (GST_ELEMENT (vaapidecbin), ghostpad))
+ goto error_adding_pad;
+
+ /* create ghost pad src */
+ pad = gst_element_get_static_pad (GST_ELEMENT (vaapidecbin->queue), "src");
+ tmpl = gst_static_pad_template_get (&gst_vaapi_decode_bin_src_factory);
+ ghostpad = gst_ghost_pad_new_from_template ("src", pad, tmpl);
+ gst_object_unref (pad);
+ gst_object_unref (tmpl);
+ if (!gst_element_add_pad (GST_ELEMENT (vaapidecbin), ghostpad))
+ goto error_adding_pad;
+
return TRUE;
error_element_missing:
@@ -456,8 +487,14 @@ error_element_missing:
}
error_link_pad:
{
- GST_ELEMENT_ERROR (vaapidecbin, CORE, PAD,
- (NULL), ("Failed to configure the vaapidecodebin."));
+ GST_ELEMENT_ERROR (vaapidecbin, CORE, PAD, (NULL),
+ ("Failed to configure the vaapidecodebin."));
+ return FALSE;
+ }
+error_adding_pad:
+ {
+ GST_ELEMENT_ERROR (vaapidecbin, CORE, PAD, (NULL),
+ ("Failed to adding pads."));
return FALSE;
}
}
@@ -465,20 +502,8 @@ error_link_pad:
static void
gst_vaapi_decode_bin_init (GstVaapiDecodeBin * vaapidecbin)
{
- GstPad *element_pad, *ghost_pad;
-
vaapidecbin->has_vpp = HAS_VPP_UNKNOWN;
vaapidecbin->deinterlace_method = DEFAULT_DEINTERLACE_METHOD;
- if (!gst_vaapi_decode_bin_configure (vaapidecbin))
- return;
-
- /* create ghost pad sink */
- element_pad =
- gst_element_get_static_pad (GST_ELEMENT (vaapidecbin->decoder), "sink");
- ghost_pad =
- gst_ghost_pad_new_from_template ("sink", element_pad,
- GST_PAD_PAD_TEMPLATE (element_pad));
- gst_object_unref (element_pad);
- gst_element_add_pad (GST_ELEMENT (vaapidecbin), ghost_pad);
+ gst_vaapi_decode_bin_configure (vaapidecbin);
}
diff --git a/gst/vaapi/gstvaapidecodebin.h b/gst/vaapi/gstvaapidecodebin.h
index 18685fe7..81804b99 100644
--- a/gst/vaapi/gstvaapidecodebin.h
+++ b/gst/vaapi/gstvaapidecodebin.h
@@ -47,8 +47,6 @@ typedef struct _GstVaapiDecodeBin {
GstElement *queue;
GstElement *postproc;
- GstPad *ghost_pad_src;
-
/* properties */
guint max_size_buffers;
guint max_size_bytes;