rtpmux: handle different ssrc's on sinkpads
authorHavard Graff <havard.graff@gmail.com>
Thu, 16 Jul 2015 13:12:17 +0000 (15:12 +0200)
committerOlivier CrĂȘte <olivier.crete@collabora.com>
Thu, 16 Jul 2015 20:46:11 +0000 (16:46 -0400)
Do this by not putting the ssrc from the src pads in the caps used to
probe other sinkpads, and then  intersecting with it later.

https://bugzilla.gnome.org/show_bug.cgi?id=752491

gst/rtpmanager/gstrtpmux.c
tests/check/elements/rtpmux.c

index 575b652..302600c 100644 (file)
@@ -602,7 +602,6 @@ same_clock_rate_fold (const GValue * item, GValue * ret, gpointer user_data)
   GstPad *pad = g_value_get_object (item);
   GstCaps *peercaps;
   GstCaps *accumcaps;
-  GstCaps *intersect;
 
   if (pad == mypad)
     return TRUE;
@@ -616,12 +615,9 @@ same_clock_rate_fold (const GValue * item, GValue * ret, gpointer user_data)
   peercaps = gst_caps_make_writable (peercaps);
   clear_caps (peercaps, TRUE);
 
-  intersect = gst_caps_intersect (accumcaps, peercaps);
+  g_value_take_boxed (ret, peercaps);
 
-  g_value_take_boxed (ret, intersect);
-  gst_caps_unref (peercaps);
-
-  return !gst_caps_is_empty (intersect);
+  return !gst_caps_is_empty (peercaps);
 }
 
 static GstCaps *
@@ -634,6 +630,7 @@ gst_rtp_mux_getcaps (GstPad * pad, GstRTPMux * mux, GstCaps * filter)
   GstCaps *peercaps;
   GstCaps *othercaps;
   GstCaps *tcaps;
+  GstCaps *other_filtered;
 
   peercaps = gst_pad_peer_query_caps (mux->srcpad, filter);
 
@@ -654,24 +651,30 @@ gst_rtp_mux_getcaps (GstPad * pad, GstRTPMux * mux, GstCaps * filter)
 
   clear_caps (othercaps, FALSE);
 
+  other_filtered = gst_caps_copy (othercaps);
+  clear_caps (other_filtered, TRUE);
+
   g_value_init (&v, GST_TYPE_CAPS);
 
   iter = gst_element_iterate_sink_pads (GST_ELEMENT (mux));
   do {
-    gst_value_set_caps (&v, othercaps);
+    gst_value_set_caps (&v, other_filtered);
     res = gst_iterator_fold (iter, same_clock_rate_fold, &v, pad);
     gst_iterator_resync (iter);
   } while (res == GST_ITERATOR_RESYNC);
   gst_iterator_free (iter);
+  gst_caps_unref (other_filtered);
 
-  caps = (GstCaps *) gst_value_get_caps (&v);
+  caps = gst_caps_intersect ((GstCaps *) gst_value_get_caps (&v), othercaps);
+
+  g_value_unset (&v);
+  gst_caps_unref (othercaps);
 
   if (res == GST_ITERATOR_ERROR) {
     gst_caps_unref (caps);
     caps = gst_caps_new_empty ();
   }
 
-  gst_caps_unref (othercaps);
 
   return caps;
 }
index 11ba979..36b58e6 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <gst/check/gstcheck.h>
+#include <gst/check/gstharness.h>
 #include <gst/rtp/gstrtpbuffer.h>
 #include <gst/gst.h>
 
@@ -296,6 +297,58 @@ GST_START_TEST (test_rtpdtmfmux_lock)
 
 GST_END_TEST;
 
+static GstBuffer *
+generate_test_buffer (guint seq_num, guint ssrc)
+{
+  GstBuffer *buf;
+  guint8 *payload;
+  guint i;
+  GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
+  gsize size = 10;
+
+  buf = gst_rtp_buffer_new_allocate (size, 0, 0);
+  GST_BUFFER_DTS (buf) = GST_MSECOND * 20 * seq_num;
+  GST_BUFFER_PTS (buf) = GST_MSECOND * 20 * seq_num;
+
+  gst_rtp_buffer_map (buf, GST_MAP_READWRITE, &rtp);
+  gst_rtp_buffer_set_payload_type (&rtp, 0);
+  gst_rtp_buffer_set_seq (&rtp, seq_num);
+  gst_rtp_buffer_set_timestamp (&rtp, 160 * seq_num);
+  gst_rtp_buffer_set_ssrc (&rtp, ssrc);
+
+  payload = gst_rtp_buffer_get_payload (&rtp);
+  for (i = 0; i < size; i++)
+    payload[i] = 0xff;
+
+  gst_rtp_buffer_unmap (&rtp);
+
+  return buf;
+}
+
+GST_START_TEST (test_rtpmux_ssrc)
+{
+  GstHarness * h = gst_harness_new_with_padnames ("rtpdtmfmux", NULL, "src");
+  GstHarness * h0 = gst_harness_new_with_element (
+      h->element, "sink_0", NULL);
+  GstHarness * h1 = gst_harness_new_with_element (
+      h->element, "sink_1", NULL);
+
+  g_object_set (h->element, "ssrc", 111111, NULL);
+
+  gst_harness_set_src_caps_str (h0, "application/x-rtp, ssrc=(uint)222222");
+  gst_harness_set_src_caps_str (h1, "application/x-rtp, ssrc=(uint)333333");
+
+  fail_unless_equals_int (GST_FLOW_OK,
+      gst_harness_push (h0, generate_test_buffer (0, 222222)));
+  fail_unless_equals_int (GST_FLOW_OK,
+      gst_harness_push (h1, generate_test_buffer (0, 333333)));
+
+  gst_harness_teardown (h0);
+  gst_harness_teardown (h1);
+  gst_harness_teardown (h);
+}
+GST_END_TEST;
+
 static Suite *
 rtpmux_suite (void)
 {
@@ -303,8 +356,9 @@ rtpmux_suite (void)
   TCase *tc_chain;
 
   tc_chain = tcase_create ("rtpmux_basic");
-  tcase_add_test (tc_chain, test_rtpmux_basic);
   suite_add_tcase (s, tc_chain);
+  tcase_add_test (tc_chain, test_rtpmux_basic);
+  tcase_add_test (tc_chain, test_rtpmux_ssrc);
 
   tc_chain = tcase_create ("rtpdtmfmux_basic");
   tcase_add_test (tc_chain, test_rtpdtmfmux_basic);