alessandro gstreamer: gstreamer/ gstreamer/gst/ gstreamer/tests/check/gst/

[email protected] Wed, 17 Dec 2008 08:16:59 -0800 (PST)
Newsgroups gmane.comp.video.gstreamer.cvs
Message-ID <[email protected]>
CVS Root:       /cvs/gstreamer
Module:         gstreamer
Changes by:     alessandro
Date:           Wed Dec 17 2008  16:16:59 UTC

Log message:
	* 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.

Modified files:
    .               : ChangeLog
    gst             : gstghostpad.c
    tests/check/gst : gstghostpad.c

Links:
http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.4200&r2=1.4201
http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstghostpad.c.diff?r1=1.60&r2=1.61
http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/tests/check/gst/gstghostpad.c.diff?r1=1.30&r2=1.31

====Begin Diffs====
Index: ChangeLog
===================================================================
RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v
retrieving revision 1.4200
retrieving revision 1.4201
diff -u -d -r1.4200 -r1.4201
--- ChangeLog	17 Dec 2008 09:37:45 -0000	1.4200
+++ ChangeLog	17 Dec 2008 16:16:42 -0000	1.4201
@@ -1,3 +1,11 @@
+2008-12-17  Alessandro Decina  <[email protected]>
+
+	* 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  <[email protected]>
 
 	* gst/gstutils.c: (gst_element_found_tags_for_pad):
Index: gstghostpad.c
RCS file: /cvs/gstreamer/gstreamer/gst/gstghostpad.c,v
retrieving revision 1.60
retrieving revision 1.61
diff -u -d -r1.60 -r1.61
--- gstghostpad.c	8 Oct 2008 10:39:24 -0000	1.60
+++ gstghostpad.c	17 Dec 2008 16:16:45 -0000	1.61
@@ -80,6 +80,9 @@
     xmlNodePtr parent);
 #endif
+static void on_src_target_notify (GstPad * target,
+    GParamSpec * unused, GstGhostPad * pad);
 static void
 gst_proxy_pad_class_init (GstProxyPadClass * klass)
@@ -322,9 +325,9 @@
     GST_LOG_OBJECT (pad, "clearing target");
   /* clear old target */
-  if ((oldtarget = GST_PROXY_PAD_TARGET (pad))) {
+  if ((oldtarget = GST_PROXY_PAD_TARGET (pad)))
     gst_object_unref (oldtarget);
-  }
   /* set and ref new target if any */
   if (target)
     GST_PROXY_PAD_TARGET (pad) = gst_object_ref (target);
@@ -685,6 +688,23 @@
 }
+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
 gst_ghost_pad_init (GstGhostPad * pad)
 {
   GST_GHOST_PAD_PRIVATE (pad) = G_TYPE_INSTANCE_GET_PRIVATE (pad,
@@ -701,12 +721,26 @@
   GstPad *pad;
   GstPad *internal;
-  GstPad *intpeer;
+  GstPad *peer;
   pad = GST_PAD (object);
   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);
   internal = GST_PROXY_PAD_INTERNAL (pad);
@@ -716,21 +750,10 @@
   g_signal_handler_disconnect (internal,
       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
    * that has a refcount on the internal pad. */
   gst_object_unparent (GST_OBJECT_CAST (internal));
+  GST_PROXY_PAD_INTERNAL (pad) = NULL;
   GST_PROXY_UNLOCK (pad);
@@ -1089,6 +1112,11 @@
   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 (internal) {
       if (GST_PAD_IS_SRC (internal))
@@ -1101,6 +1129,11 @@
   result = gst_proxy_pad_set_target_unlocked (GST_PAD_CAST (gpad), 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 */
     GST_DEBUG_OBJECT (gpad, "connecting internal pad to target");
RCS file: /cvs/gstreamer/gstreamer/tests/check/gst/gstghostpad.c,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -d -r1.30 -r1.31
--- gstghostpad.c	30 Aug 2008 11:55:58 -0000	1.30
+++ gstghostpad.c	17 Dec 2008 16:16:45 -0000	1.31
@@ -668,6 +668,65 @@
 GST_END_TEST;
+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_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), &notify_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);
+  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);
+  gst_object_unref (src);
+  gst_object_unref (sink);
+  gst_object_unref (src_template);
+  gst_object_unref (sink_template);
+GST_END_TEST;
 static Suite *
 gst_ghost_pad_suite (void)
@@ -686,6 +745,7 @@
   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_no_target_from_template);
+  tcase_add_test (tc_chain, test_ghost_pads_forward_setcaps);
   return s;

------------------------------------------------------------------------------
SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada.
The future of the web can't happen without you.  Join us at MIX09 to help
pave the way to the Next Web now. Learn more and register at
http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/

_______________________________________________
gstreamer-cvs-verbose mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/gstreamer-cvs-verbose