rtopuspay: Ignore the stereo parameter in multiopus caps
authorOlivier Crête <olivier.crete@ocrete.ca>
Thu, 12 Jan 2023 19:25:52 +0000 (14:25 -0500)
committerOlivier Crête <olivier.crete@ocrete.ca>
Thu, 12 Jan 2023 23:48:35 +0000 (18:48 -0500)
Also add unit tests for the various variants

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3674>

subprojects/gst-plugins-good/gst/rtp/gstrtpopuspay.c
subprojects/gst-plugins-good/tests/check/elements/rtpopus.c

index 8f9a43a5284b34aacf9fb93785ac57a1de97abe9..e2e15789e75ec7b2c92284df8e6a03b94dbd2af8 100644 (file)
@@ -372,7 +372,7 @@ gst_rtp_opus_pay_getcaps (GstRTPBasePayload * payload,
     GstPad * pad, GstCaps * filter)
 {
   GstStructure *s;
-  const gchar *stereo;
+  int channel_mapping_family = 0;
   GstCaps *caps, *peercaps, *tcaps, *tempcaps;
 
   if (pad == GST_RTP_BASE_PAYLOAD_SRCPAD (payload))
@@ -428,21 +428,27 @@ gst_rtp_opus_pay_getcaps (GstRTPBasePayload * payload,
   }
   gst_caps_unref (tempcaps);
 
-  s = gst_caps_get_structure (peercaps, 0);
-  stereo = gst_structure_get_string (s, "stereo");
-  if (stereo != NULL) {
-    caps = gst_caps_make_writable (caps);
+  s = gst_caps_get_structure (caps, 0);
+  gst_structure_get_int (s, "channel-mapping-family", &channel_mapping_family);
+  if (channel_mapping_family == 0) {
+    GstStructure *sp = gst_caps_get_structure (peercaps, 0);
+    const gchar *stereo = gst_structure_get_string (sp, "stereo");
+
+    if (stereo != NULL) {
+      guint channels = 0;
 
-    if (!strcmp (stereo, "1")) {
-      GstCaps *caps2 = gst_caps_copy (caps);
+      if (!strcmp (stereo, "1"))
+        channels = 2;
+      else if (!strcmp (stereo, "0"))
+        channels = 1;
 
-      gst_caps_set_simple (caps, "channels", G_TYPE_INT, 2, NULL);
-      caps = gst_caps_merge (caps, caps2);
-    } else if (!strcmp (stereo, "0")) {
-      GstCaps *caps2 = gst_caps_copy (caps);
+      if (channels) {
+        GstCaps *caps2 = gst_caps_copy_nth (caps, 0);
 
-      gst_caps_set_simple (caps, "channels", G_TYPE_INT, 1, NULL);
-      caps = gst_caps_merge (caps, caps2);
+        gst_caps_set_simple (caps2, "channels", G_TYPE_INT, channels, NULL);
+        caps = gst_caps_make_writable (caps);
+        caps = gst_caps_merge (caps2, caps);
+      }
     }
   }
   gst_caps_unref (peercaps);
index d8c2cb43af7dd8791268518065b972e9957c6781..9363b7d9dbd0528c7fcc02dab34d2d391513851b 100644 (file)
@@ -126,6 +126,7 @@ GST_START_TEST (test_pay_to_depay_multichannel)
 }
 
 GST_END_TEST;
+
 GST_START_TEST (test_depay_to_pay_multichannel)
 {
   GstHarness *h = gst_harness_new_parse ("rtpopusdepay ! rtpopuspay");
@@ -165,6 +166,95 @@ GST_START_TEST (test_depay_to_pay_multichannel)
 
 GST_END_TEST;
 
+GST_START_TEST (test_pay_getcaps)
+{
+  GstHarness *h = gst_harness_new ("rtpopuspay");
+  GstCaps *ref, *qcaps;
+
+  gst_harness_set_sink_caps_str (h, "application/x-rtp, "
+      "encoding-name=(string)OPUS, stereo=(string)0");
+  qcaps = gst_pad_peer_query_caps (h->srcpad, NULL);
+  /* Check that is also contains stereo */
+  ref = gst_caps_from_string ("audio/x-opus, channels=(int)2, "
+      "channel-mapping-family=(int)0");
+  fail_unless (gst_caps_can_intersect (ref, qcaps));
+  gst_caps_unref (ref);
+  fail_unless_equals_int (gst_caps_get_size (qcaps), 2);
+  qcaps = gst_caps_truncate (qcaps);
+  /* Check that the first structure is mono */
+  ref = gst_caps_from_string ("audio/x-opus, channels=(int)1, "
+      "channel-mapping-family=(int)0");
+  fail_unless (gst_caps_is_equal (ref, qcaps));
+  gst_caps_unref (ref);
+  gst_caps_unref (qcaps);
+
+  gst_harness_set_sink_caps_str (h, "application/x-rtp, "
+      "encoding-name=(string)OPUS, stereo=(string)1");
+  qcaps = gst_pad_peer_query_caps (h->srcpad, NULL);
+  /* Check that is also contains stereo */
+  ref = gst_caps_from_string ("audio/x-opus, channels=(int)2, "
+      "channel-mapping-family=(int)0");
+  fail_unless (gst_caps_can_intersect (ref, qcaps));
+  gst_caps_unref (ref);
+  fail_unless_equals_int (gst_caps_get_size (qcaps), 2);
+  qcaps = gst_caps_truncate (qcaps);
+  /* Check that the first structure is mono */
+  ref = gst_caps_from_string ("audio/x-opus, channels=(int)2, "
+      "channel-mapping-family=(int)0");
+  fail_unless (gst_caps_is_equal (ref, qcaps));
+  gst_caps_unref (ref);
+  gst_caps_unref (qcaps);
+
+  gst_harness_set_sink_caps_str (h, "application/x-rtp, "
+      "encoding-name=(string)MULTIOPUS");
+  qcaps = gst_pad_peer_query_caps (h->srcpad, NULL);
+  /* Check that is also contains stereo */
+  ref = gst_caps_from_string ("audio/x-opus, channels=(int)[3, 255], "
+      "channel-mapping-family=(int)1");
+  fail_unless (gst_caps_is_equal (ref, qcaps));
+  gst_caps_unref (ref);
+  fail_unless_equals_int (gst_caps_get_size (qcaps), 1);
+  gst_caps_unref (qcaps);
+
+  gst_harness_set_sink_caps_str (h, "application/x-rtp, "
+      "encoding-name=(string)MULTIOPUS, stereo=(string)1");
+  qcaps = gst_pad_peer_query_caps (h->srcpad, NULL);
+  /* Check that is also contains stereo */
+  ref = gst_caps_from_string ("audio/x-opus, channels=(int)[3, 255], "
+      "channel-mapping-family=(int)1");
+  fail_unless (gst_caps_is_equal (ref, qcaps));
+  gst_caps_unref (ref);
+  fail_unless_equals_int (gst_caps_get_size (qcaps), 1);
+  gst_caps_unref (qcaps);
+
+  gst_harness_set_sink_caps_str (h, "application/x-rtp, "
+      "encoding-name=(string)OPUS, stereo=(string)0;"
+      "application/x-rtp, encoding-name=(string)MULTIOPUS");
+  qcaps = gst_pad_peer_query_caps (h->srcpad, NULL);
+  /* Check that is also contains stereo */
+  ref = gst_caps_from_string ("audio/x-opus, channels=(int)2, "
+      "channel-mapping-family=(int)0");
+  fail_unless (gst_caps_can_intersect (ref, qcaps));
+  gst_caps_unref (ref);
+  /* Check that is also contains 3 channels */
+  ref = gst_caps_from_string ("audio/x-opus, channels=(int)3, "
+      "channel-mapping-family=(int)1");
+  fail_unless (gst_caps_can_intersect (ref, qcaps));
+  gst_caps_unref (ref);
+  fail_unless_equals_int (gst_caps_get_size (qcaps), 3);
+  qcaps = gst_caps_truncate (qcaps);
+  /* Check that the first structure is mono */
+  ref = gst_caps_from_string ("audio/x-opus, channels=(int)1, "
+      "channel-mapping-family=(int)0");
+  fail_unless (gst_caps_can_intersect (ref, qcaps));
+  gst_caps_unref (ref);
+  gst_caps_unref (qcaps);
+
+  gst_harness_teardown (h);
+}
+
+GST_END_TEST;
+
 static Suite *
 rtpopus_suite (void)
 {
@@ -176,6 +266,7 @@ rtpopus_suite (void)
   tcase_add_test (tc_chain, test_depay_to_pay);
   tcase_add_test (tc_chain, test_pay_to_depay_multichannel);
   tcase_add_test (tc_chain, test_depay_to_pay_multichannel);
+  tcase_add_test (tc_chain, test_pay_getcaps);
 
   return s;
 }