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);
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;
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);
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);
}
--- /dev/null
+/* 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)