rtpptdemux: set payload to caps inside gst_rtp_pt_demux_get_caps
authorMikhail Fludkov <misha@pexip.com>
Thu, 13 Jul 2017 11:49:07 +0000 (13:49 +0200)
committerTim-Philipp Müller <tim@centricular.com>
Tue, 11 Feb 2020 18:39:22 +0000 (18:39 +0000)
Refactoring to remove duplicate code and add test

gst/rtpmanager/gstrtpptdemux.c
tests/check/elements/rtpptdemux.c [new file with mode: 0644]
tests/check/meson.build

index a8424ec..d8d54ba 100644 (file)
@@ -313,10 +313,11 @@ gst_rtp_pt_demux_finalize (GObject * object)
 static GstCaps *
 gst_rtp_pt_demux_get_caps (GstRtpPtDemux * rtpdemux, guint pt)
 {
-  GstCaps *caps;
+  guint32 ssrc = 0;
+  gboolean have_ssrc = FALSE;
+  GstCaps *caps, *sink_caps;
   GValue ret = { 0 };
   GValue args[2] = { {0}, {0} };
-  GstCaps *sink_caps;
 
   /* figure out the caps */
   g_value_init (&args[0], GST_TYPE_ELEMENT);
@@ -333,29 +334,25 @@ gst_rtp_pt_demux_get_caps (GstRtpPtDemux * rtpdemux, guint pt)
   g_value_unset (&args[0]);
   g_value_unset (&args[1]);
   caps = g_value_dup_boxed (&ret);
-  g_value_unset (&ret);
-
   sink_caps = gst_pad_get_current_caps (rtpdemux->sink);
+  g_value_unset (&ret);
 
-  if (sink_caps) {
-    if (caps == NULL) {
-      caps = gst_caps_ref (sink_caps);
-    } else {
-      GstStructure *s1;
-      GstStructure *s2;
-      guint ssrc;
-
-      caps = gst_caps_make_writable (caps);
-      s1 = gst_caps_get_structure (sink_caps, 0);
-      s2 = gst_caps_get_structure (caps, 0);
-
-      gst_structure_get_uint (s1, "ssrc", &ssrc);
-      gst_structure_set (s2, "ssrc", G_TYPE_UINT, ssrc, NULL);
-    }
-
+  if (caps == NULL) {
+    caps = sink_caps;
+  } else if (sink_caps) {
+    have_ssrc =
+        gst_structure_get_uint (gst_caps_get_structure (sink_caps, 0), "ssrc",
+        &ssrc);
     gst_caps_unref (sink_caps);
   }
 
+  if (caps != NULL) {
+    caps = gst_caps_make_writable (caps);
+    gst_caps_set_simple (caps, "payload", G_TYPE_INT, pt, NULL);
+    if (have_ssrc)
+      gst_caps_set_simple (caps, "ssrc", G_TYPE_UINT, ssrc, NULL);
+  }
+
   GST_DEBUG_OBJECT (rtpdemux, "pt %d, got caps %" GST_PTR_FORMAT, pt, caps);
 
   return caps;
@@ -501,14 +498,11 @@ gst_rtp_pt_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
 
     gst_pad_set_active (srcpad, TRUE);
 
-
     /* First push the stream-start event, it must always come first */
     gst_pad_push_event (srcpad,
         gst_pad_get_sticky_event (rtpdemux->sink, GST_EVENT_STREAM_START, 0));
 
     /* Then caps event is sent */
-    caps = gst_caps_make_writable (caps);
-    gst_caps_set_simple (caps, "payload", G_TYPE_INT, pt, NULL);
     gst_pad_set_caps (srcpad, caps);
     gst_caps_unref (caps);
 
@@ -542,8 +536,6 @@ gst_rtp_pt_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
 
     clear_newcaps_for_pt (rtpdemux, pt);
 
-    caps = gst_caps_make_writable (caps);
-    gst_caps_set_simple (caps, "payload", G_TYPE_INT, pt, NULL);
     gst_pad_set_caps (srcpad, caps);
     gst_caps_unref (caps);
   }
diff --git a/tests/check/elements/rtpptdemux.c b/tests/check/elements/rtpptdemux.c
new file mode 100644 (file)
index 0000000..b181baa
--- /dev/null
@@ -0,0 +1,147 @@
+/* GStreamer
+ *
+ * unit test for rtpptdemux element
+ *
+ * Copyright 2017 Pexip
+ *  @author: Mikhail Fludkov <misha@pexip.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gst/check/gstcheck.h>
+#include <gst/check/gstharness.h>
+#include <gst/rtp/gstrtpbuffer.h>
+#include <gst/gst.h>
+
+static void
+new_payload_type (G_GNUC_UNUSED GstElement * element, G_GNUC_UNUSED guint pt,
+    GstPad * pad, GstHarness ** h)
+{
+  gst_harness_add_element_src_pad (*h, pad);
+}
+
+static void
+test_rtpptdemux_srccaps_from_sinkcaps_base (const gchar * srccaps,
+    const gchar * sinkcaps)
+{
+  GstCaps *caps;
+  gchar *caps_str;
+  GstHarness *h = gst_harness_new_with_padnames ("rtpptdemux", "sink", NULL);
+
+  gst_harness_set_src_caps_str (h, srccaps);
+  g_signal_connect (h->element,
+      "new-payload-type", (GCallback) new_payload_type, &h);
+  gst_harness_play (h);
+
+  gst_buffer_unref (gst_harness_push_and_pull (h,
+          gst_rtp_buffer_new_allocate (0, 0, 0)));
+
+  caps = gst_pad_get_current_caps (h->sinkpad);
+  caps_str = gst_caps_to_string (caps);
+  fail_unless_equals_string (caps_str, sinkcaps);
+
+  g_free (caps_str);
+  gst_caps_unref (caps);
+  gst_harness_teardown (h);
+}
+
+GST_START_TEST (test_rtpptdemux_srccaps_from_sinkcaps)
+{
+  test_rtpptdemux_srccaps_from_sinkcaps_base
+      ("application/x-rtp, ssrc=(uint)1111",
+      "application/x-rtp, ssrc=(uint)1111, payload=(int)0");
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_rtpptdemux_srccaps_from_sinkcaps_nossrc)
+{
+  test_rtpptdemux_srccaps_from_sinkcaps_base ("application/x-rtp",
+      "application/x-rtp, payload=(int)0");
+}
+
+GST_END_TEST;
+
+static GstCaps *
+request_pt_map (G_GNUC_UNUSED GstElement * demux,
+    G_GNUC_UNUSED guint pt, const gchar * caps)
+{
+  return gst_caps_from_string (caps);
+}
+
+static void
+test_rtpptdemux_srccaps_from_signal_base (const gchar * srccaps,
+    const gchar * sigcaps, const gchar * sinkcaps)
+{
+  GstCaps *caps;
+  gchar *caps_str;
+  GstHarness *h = gst_harness_new_with_padnames ("rtpptdemux", "sink", NULL);
+
+  gst_harness_set_src_caps_str (h, srccaps);
+  g_signal_connect (h->element,
+      "new-payload-type", (GCallback) new_payload_type, &h);
+  g_signal_connect (h->element,
+      "request-pt-map", (GCallback) request_pt_map, (gpointer) sigcaps);
+  gst_harness_play (h);
+
+  gst_buffer_unref (gst_harness_push_and_pull (h,
+          gst_rtp_buffer_new_allocate (0, 0, 0)));
+
+  caps = gst_pad_get_current_caps (h->sinkpad);
+  caps_str = gst_caps_to_string (caps);
+  fail_unless_equals_string (caps_str, sinkcaps);
+
+  g_free (caps_str);
+  gst_caps_unref (caps);
+  gst_harness_teardown (h);
+}
+
+GST_START_TEST (test_rtpptdemux_srccaps_from_signal)
+{
+  test_rtpptdemux_srccaps_from_signal_base
+      ("application/x-rtp, ssrc=(uint)1111",
+      "application/x-rtp, encoding-name=(string)H264, media=(string)video, clock-rate=(int)90000",
+      "application/x-rtp, encoding-name=(string)H264, media=(string)video, clock-rate=(int)90000, payload=(int)0, ssrc=(uint)1111");
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_rtpptdemux_srccaps_from_signal_nossrc)
+{
+  test_rtpptdemux_srccaps_from_signal_base ("application/x-rtp",
+      "application/x-rtp, encoding-name=(string)H264, media=(string)video, clock-rate=(int)90000",
+      "application/x-rtp, encoding-name=(string)H264, media=(string)video, clock-rate=(int)90000, payload=(int)0");
+}
+
+GST_END_TEST;
+
+static Suite *
+rtpptdemux_suite (void)
+{
+  Suite *s = suite_create ("rtpptdemux");
+  TCase *tc_chain;
+
+  tc_chain = tcase_create ("general");
+  tcase_add_test (tc_chain, test_rtpptdemux_srccaps_from_sinkcaps);
+  tcase_add_test (tc_chain, test_rtpptdemux_srccaps_from_sinkcaps_nossrc);
+  tcase_add_test (tc_chain, test_rtpptdemux_srccaps_from_signal);
+  tcase_add_test (tc_chain, test_rtpptdemux_srccaps_from_signal_nossrc);
+  suite_add_tcase (s, tc_chain);
+
+  return s;
+}
+
+GST_CHECK_MAIN (rtpptdemux)
index 78cf84d..e51d98a 100644 (file)
@@ -74,6 +74,7 @@ good_tests = [
       '../../gst/rtpmanager/rtpstats.c',
       '../../gst/rtpmanager/rtptimerqueue.c']],
   [ 'elements/rtpmux' ],
+  [ 'elements/rtpptdemux' ],
   [ 'elements/rtprtx' ],
   [ 'elements/rtpsession' ],
   [ 'elements/rtpstorage', false, [],  ['../../gst/rtp/gstrtpstorage.c',