mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
In a source ghostpad, when caps are changed in the target pad, the change needs to be reflected in the ghostpad.
Original commit message from CVS: * gst/gstghostpad.c: * tests/check/gst/gstghostpad.c: In a source ghostpad, when caps are changed in the target pad, the change needs to be reflected in the ghostpad. Fixes #564863.
This commit is contained in:
parent
33239dded7
commit
c0a2c5839e
4 changed files with 117 additions and 16 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
2008-12-17 Alessandro Decina <alessandro.decina@collabora.co.uk>
|
||||||
|
|
||||||
|
* gst/gstghostpad.c:
|
||||||
|
* tests/check/gst/gstghostpad.c:
|
||||||
|
In a source ghostpad, when caps are changed in the target pad, the
|
||||||
|
change needs to be reflected in the ghostpad.
|
||||||
|
Fixes #564863.
|
||||||
|
|
||||||
2008-12-17 Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
2008-12-17 Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
||||||
|
|
||||||
* gst/gstutils.c: (gst_element_found_tags_for_pad):
|
* gst/gstutils.c: (gst_element_found_tags_for_pad):
|
||||||
|
|
2
common
2
common
|
@ -1 +1 @@
|
||||||
Subproject commit 2c4d28a75c26e572b94a967901254caff83d85c4
|
Subproject commit 5dc8ae302733ce1aae5b1aaa613ce77a8ae4b3d9
|
|
@ -80,6 +80,9 @@ static xmlNodePtr gst_proxy_pad_save_thyself (GstObject * object,
|
||||||
xmlNodePtr parent);
|
xmlNodePtr parent);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void on_src_target_notify (GstPad * target,
|
||||||
|
GParamSpec * unused, GstGhostPad * pad);
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_proxy_pad_class_init (GstProxyPadClass * klass)
|
gst_proxy_pad_class_init (GstProxyPadClass * klass)
|
||||||
|
@ -322,9 +325,9 @@ gst_proxy_pad_set_target_unlocked (GstPad * pad, GstPad * target)
|
||||||
GST_LOG_OBJECT (pad, "clearing target");
|
GST_LOG_OBJECT (pad, "clearing target");
|
||||||
|
|
||||||
/* clear old target */
|
/* clear old target */
|
||||||
if ((oldtarget = GST_PROXY_PAD_TARGET (pad))) {
|
if ((oldtarget = GST_PROXY_PAD_TARGET (pad)))
|
||||||
gst_object_unref (oldtarget);
|
gst_object_unref (oldtarget);
|
||||||
}
|
|
||||||
/* set and ref new target if any */
|
/* set and ref new target if any */
|
||||||
if (target)
|
if (target)
|
||||||
GST_PROXY_PAD_TARGET (pad) = gst_object_ref (target);
|
GST_PROXY_PAD_TARGET (pad) = gst_object_ref (target);
|
||||||
|
@ -684,6 +687,23 @@ on_int_notify (GstPad * internal, GParamSpec * unused, GstGhostPad * pad)
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_src_target_notify (GstPad * target, GParamSpec * unused, GstGhostPad * pad)
|
||||||
|
{
|
||||||
|
GstCaps *caps;
|
||||||
|
|
||||||
|
g_object_get (target, "caps", &caps, NULL);
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (pad);
|
||||||
|
gst_caps_replace (&(GST_PAD_CAPS (pad)), caps);
|
||||||
|
GST_OBJECT_UNLOCK (pad);
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (pad), "caps");
|
||||||
|
if (caps)
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_ghost_pad_init (GstGhostPad * pad)
|
gst_ghost_pad_init (GstGhostPad * pad)
|
||||||
{
|
{
|
||||||
|
@ -701,12 +721,26 @@ gst_ghost_pad_dispose (GObject * object)
|
||||||
{
|
{
|
||||||
GstPad *pad;
|
GstPad *pad;
|
||||||
GstPad *internal;
|
GstPad *internal;
|
||||||
GstPad *intpeer;
|
GstPad *peer;
|
||||||
|
|
||||||
pad = GST_PAD (object);
|
pad = GST_PAD (object);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (pad, "dispose");
|
GST_DEBUG_OBJECT (pad, "dispose");
|
||||||
|
|
||||||
|
gst_ghost_pad_set_target (GST_GHOST_PAD (pad), NULL);
|
||||||
|
|
||||||
|
/* Unlink here so that gst_pad_dispose doesn't. That would lead to a call to
|
||||||
|
* gst_ghost_pad_do_unlink when the ghost pad is in an inconsistent state */
|
||||||
|
peer = gst_pad_get_peer (pad);
|
||||||
|
if (peer) {
|
||||||
|
if (GST_PAD_IS_SRC (pad))
|
||||||
|
gst_pad_unlink (pad, peer);
|
||||||
|
else
|
||||||
|
gst_pad_unlink (peer, pad);
|
||||||
|
|
||||||
|
gst_object_unref (peer);
|
||||||
|
}
|
||||||
|
|
||||||
GST_PROXY_LOCK (pad);
|
GST_PROXY_LOCK (pad);
|
||||||
internal = GST_PROXY_PAD_INTERNAL (pad);
|
internal = GST_PROXY_PAD_INTERNAL (pad);
|
||||||
|
|
||||||
|
@ -716,21 +750,10 @@ gst_ghost_pad_dispose (GObject * object)
|
||||||
g_signal_handler_disconnect (internal,
|
g_signal_handler_disconnect (internal,
|
||||||
GST_GHOST_PAD_PRIVATE (pad)->notify_id);
|
GST_GHOST_PAD_PRIVATE (pad)->notify_id);
|
||||||
|
|
||||||
intpeer = gst_pad_get_peer (internal);
|
|
||||||
if (intpeer) {
|
|
||||||
if (GST_PAD_IS_SRC (internal))
|
|
||||||
gst_pad_unlink (internal, intpeer);
|
|
||||||
else
|
|
||||||
gst_pad_unlink (intpeer, internal);
|
|
||||||
|
|
||||||
gst_object_unref (intpeer);
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_PROXY_PAD_INTERNAL (internal) = NULL;
|
|
||||||
|
|
||||||
/* disposes of the internal pad, since the ghostpad is the only possible object
|
/* disposes of the internal pad, since the ghostpad is the only possible object
|
||||||
* that has a refcount on the internal pad. */
|
* that has a refcount on the internal pad. */
|
||||||
gst_object_unparent (GST_OBJECT_CAST (internal));
|
gst_object_unparent (GST_OBJECT_CAST (internal));
|
||||||
|
GST_PROXY_PAD_INTERNAL (pad) = NULL;
|
||||||
|
|
||||||
GST_PROXY_UNLOCK (pad);
|
GST_PROXY_UNLOCK (pad);
|
||||||
|
|
||||||
|
@ -1089,6 +1112,11 @@ gst_ghost_pad_set_target (GstGhostPad * gpad, GstPad * newtarget)
|
||||||
|
|
||||||
/* clear old target */
|
/* clear old target */
|
||||||
if ((oldtarget = GST_PROXY_PAD_TARGET (gpad))) {
|
if ((oldtarget = GST_PROXY_PAD_TARGET (gpad))) {
|
||||||
|
if (GST_PAD_IS_SRC (oldtarget)) {
|
||||||
|
g_signal_handlers_disconnect_by_func (oldtarget,
|
||||||
|
on_src_target_notify, gpad);
|
||||||
|
}
|
||||||
|
|
||||||
/* if we have an internal pad, unlink */
|
/* if we have an internal pad, unlink */
|
||||||
if (internal) {
|
if (internal) {
|
||||||
if (GST_PAD_IS_SRC (internal))
|
if (GST_PAD_IS_SRC (internal))
|
||||||
|
@ -1101,6 +1129,11 @@ gst_ghost_pad_set_target (GstGhostPad * gpad, GstPad * newtarget)
|
||||||
result = gst_proxy_pad_set_target_unlocked (GST_PAD_CAST (gpad), newtarget);
|
result = gst_proxy_pad_set_target_unlocked (GST_PAD_CAST (gpad), newtarget);
|
||||||
|
|
||||||
if (result && newtarget) {
|
if (result && newtarget) {
|
||||||
|
if (GST_PAD_IS_SRC (newtarget)) {
|
||||||
|
g_signal_connect (newtarget, "notify::caps",
|
||||||
|
G_CALLBACK (on_src_target_notify), gpad);
|
||||||
|
}
|
||||||
|
|
||||||
/* and link to internal pad */
|
/* and link to internal pad */
|
||||||
GST_DEBUG_OBJECT (gpad, "connecting internal pad to target");
|
GST_DEBUG_OBJECT (gpad, "connecting internal pad to target");
|
||||||
|
|
||||||
|
|
|
@ -668,6 +668,65 @@ GST_START_TEST (test_ghost_pads_new_no_target_from_template)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
static void
|
||||||
|
ghost_notify_caps (GObject * object, GParamSpec * pspec, gpointer * user_data)
|
||||||
|
{
|
||||||
|
(*(gint *) user_data)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_START_TEST (test_ghost_pads_forward_setcaps)
|
||||||
|
{
|
||||||
|
GstCaps *templ_caps, *caps1, *caps2;
|
||||||
|
GstPadTemplate *src_template, *sink_template;
|
||||||
|
GstPad *src, *ghost, *sink;
|
||||||
|
gint notify_counter = 0;
|
||||||
|
|
||||||
|
templ_caps = gst_caps_from_string ("meh; muh");
|
||||||
|
src_template = gst_pad_template_new ("src", GST_PAD_SRC,
|
||||||
|
GST_PAD_ALWAYS, templ_caps);
|
||||||
|
sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
|
||||||
|
GST_PAD_ALWAYS, templ_caps);
|
||||||
|
gst_caps_unref (templ_caps);
|
||||||
|
|
||||||
|
src = gst_pad_new_from_template (src_template, "src");
|
||||||
|
sink = gst_pad_new_from_template (sink_template, "sink");
|
||||||
|
|
||||||
|
/* ghost source pad */
|
||||||
|
ghost = gst_ghost_pad_new ("ghostsrc", src);
|
||||||
|
g_signal_connect (ghost, "notify::caps",
|
||||||
|
G_CALLBACK (ghost_notify_caps), ¬ify_counter);
|
||||||
|
fail_unless (gst_pad_link (ghost, sink) == GST_PAD_LINK_OK);
|
||||||
|
|
||||||
|
caps1 = gst_caps_from_string ("meh");
|
||||||
|
fail_unless (gst_pad_set_caps (src, caps1));
|
||||||
|
caps2 = GST_PAD_CAPS (ghost);
|
||||||
|
fail_unless (gst_caps_is_equal (caps1, caps2));
|
||||||
|
fail_unless_equals_int (notify_counter, 1);
|
||||||
|
|
||||||
|
gst_object_unref (ghost);
|
||||||
|
gst_caps_unref (caps1);
|
||||||
|
|
||||||
|
/* ghost sink pad */
|
||||||
|
notify_counter = 0;
|
||||||
|
ghost = gst_ghost_pad_new ("ghostsink", sink);
|
||||||
|
g_signal_connect (ghost, "notify::caps",
|
||||||
|
G_CALLBACK (ghost_notify_caps), ¬ify_counter);
|
||||||
|
fail_unless (gst_pad_link (src, ghost) == GST_PAD_LINK_OK);
|
||||||
|
|
||||||
|
caps1 = gst_caps_from_string ("muh");
|
||||||
|
fail_unless (gst_pad_set_caps (ghost, caps1));
|
||||||
|
caps2 = GST_PAD_CAPS (sink);
|
||||||
|
fail_unless (gst_caps_is_equal (caps1, caps2));
|
||||||
|
fail_unless_equals_int (notify_counter, 1);
|
||||||
|
|
||||||
|
gst_object_unref (src);
|
||||||
|
gst_object_unref (sink);
|
||||||
|
gst_object_unref (src_template);
|
||||||
|
gst_object_unref (sink_template);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
static Suite *
|
static Suite *
|
||||||
gst_ghost_pad_suite (void)
|
gst_ghost_pad_suite (void)
|
||||||
{
|
{
|
||||||
|
@ -686,6 +745,7 @@ gst_ghost_pad_suite (void)
|
||||||
tcase_add_test (tc_chain, test_ghost_pads_probes);
|
tcase_add_test (tc_chain, test_ghost_pads_probes);
|
||||||
tcase_add_test (tc_chain, test_ghost_pads_new_from_template);
|
tcase_add_test (tc_chain, test_ghost_pads_new_from_template);
|
||||||
tcase_add_test (tc_chain, test_ghost_pads_new_no_target_from_template);
|
tcase_add_test (tc_chain, test_ghost_pads_new_no_target_from_template);
|
||||||
|
tcase_add_test (tc_chain, test_ghost_pads_forward_setcaps);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue