opusdec: improve getcaps to return all possible rates
authorThiago Santos <thiagoss@osg.samsung.com>
Mon, 2 May 2016 13:23:09 +0000 (10:23 -0300)
committerThiago Santos <thiagoss@osg.samsung.com>
Mon, 2 May 2016 17:29:25 +0000 (14:29 -0300)
The library is capable of converting to different rates.

Includes tests.

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

ext/opus/gstopusdec.c
tests/check/elements/opus.c

index 90301e0..aa53ff3 100644 (file)
@@ -868,6 +868,38 @@ gst_opus_dec_caps_extend_channels_options (GstCaps * caps)
   }
 }
 
+static void
+gst_opus_dec_value_list_append_int (GValue * list, gint i)
+{
+  GValue v = { 0 };
+
+  g_value_init (&v, G_TYPE_INT);
+  g_value_set_int (&v, i);
+  gst_value_list_append_value (list, &v);
+  g_value_unset (&v);
+}
+
+static void
+gst_opus_dec_caps_extend_rate_options (GstCaps * caps)
+{
+  unsigned n;
+  GValue v = { 0 };
+
+  g_value_init (&v, GST_TYPE_LIST);
+  gst_opus_dec_value_list_append_int (&v, 48000);
+  gst_opus_dec_value_list_append_int (&v, 24000);
+  gst_opus_dec_value_list_append_int (&v, 16000);
+  gst_opus_dec_value_list_append_int (&v, 12000);
+  gst_opus_dec_value_list_append_int (&v, 8000);
+
+  for (n = 0; n < gst_caps_get_size (caps); ++n) {
+    GstStructure *s = gst_caps_get_structure (caps, n);
+
+    gst_structure_set_value (s, "rate", &v);
+  }
+  g_value_unset (&v);
+}
+
 GstCaps *
 gst_opus_dec_getcaps (GstAudioDecoder * dec, GstCaps * filter)
 {
@@ -876,6 +908,7 @@ gst_opus_dec_getcaps (GstAudioDecoder * dec, GstCaps * filter)
   if (filter) {
     filter = gst_caps_copy (filter);
     gst_opus_dec_caps_extend_channels_options (filter);
+    gst_opus_dec_caps_extend_rate_options (filter);
   }
   caps = gst_audio_decoder_proxy_getcaps (dec, NULL, filter);
   if (filter)
@@ -883,6 +916,7 @@ gst_opus_dec_getcaps (GstAudioDecoder * dec, GstCaps * filter)
   if (caps) {
     caps = gst_caps_make_writable (caps);
     gst_opus_dec_caps_extend_channels_options (caps);
+    gst_opus_dec_caps_extend_rate_options (caps);
   }
   return caps;
 }
index d99927b..0fe1041 100644 (file)
@@ -317,6 +317,95 @@ GST_START_TEST (test_opus_encode_properties)
 
 GST_END_TEST;
 
+/* removes fields that do not interest our tests to
+ * allow using gst_caps_is_equal for comparison */
+static GstCaps *
+remove_extra_caps_fields (GstCaps * caps)
+{
+  gint i;
+  for (i = 0; i < gst_caps_get_size (caps); i++) {
+    GstStructure *s = gst_caps_get_structure (caps, i);
+
+    gst_structure_remove_field (s, "channel-mapping-family");
+    gst_structure_remove_field (s, "coupled-count");
+    gst_structure_remove_field (s, "stream-count");
+  }
+  return gst_caps_simplify (caps);
+}
+
+static void
+run_getcaps_check (GstCaps * filter, GstCaps * downstream_caps,
+    GstCaps * expected_result)
+{
+  GstElement *opusdec;
+  GstElement *capsfilter;
+  GstPad *sinkpad;
+  GstCaps *result;
+
+  opusdec = gst_element_factory_make ("opusdec", NULL);
+  capsfilter = gst_element_factory_make ("capsfilter", NULL);
+  sinkpad = gst_element_get_static_pad (opusdec, "sink");
+  fail_unless (gst_element_link (opusdec, capsfilter));
+
+  if (downstream_caps)
+    g_object_set (capsfilter, "caps", downstream_caps, NULL);
+  result = gst_pad_query_caps (sinkpad, filter);
+  result = remove_extra_caps_fields (result);
+  fail_unless (gst_caps_is_equal (expected_result, result),
+      "Unexpected output caps: %s", gst_caps_to_string (result));
+
+  if (filter)
+    gst_caps_unref (filter);
+  gst_caps_unref (result);
+  gst_caps_unref (expected_result);
+  if (downstream_caps)
+    gst_caps_unref (downstream_caps);
+  gst_object_unref (sinkpad);
+  gst_object_unref (opusdec);
+  gst_object_unref (capsfilter);
+}
+
+static void
+run_getcaps_check_from_strings (const gchar * filter,
+    const gchar * downstream_caps, const gchar * expected_result)
+{
+  run_getcaps_check (filter ? gst_caps_from_string (filter) : NULL,
+      downstream_caps ? gst_caps_from_string (downstream_caps) : NULL,
+      gst_caps_from_string (expected_result));
+}
+
+GST_START_TEST (test_opusdec_getcaps)
+{
+  /* default result */
+  run_getcaps_check_from_strings (NULL, NULL,
+      "audio/x-opus, rate=(int){48000, 24000, 16000, 12000, 8000}, channels=(int)[1,8]");
+
+  /* A single supported rate downstream - should accept any upstream anyway */
+  run_getcaps_check_from_strings (NULL, "audio/x-raw, rate=(int)8000",
+      "audio/x-opus, rate=(int){48000, 24000, 16000, 12000, 8000}, channels=(int)[1,8]");
+
+  /* Two supported rates (fields as a array, not as a single int) */
+  run_getcaps_check_from_strings (NULL, "audio/x-raw, rate=(int){24000, 8000}",
+      "audio/x-opus, rate=(int){48000, 24000, 16000, 12000, 8000}, channels=(int)[1,8]");
+
+  /* One supported and one unsupported rate */
+  run_getcaps_check_from_strings (NULL, "audio/x-raw, rate=(int){24000, 1000}",
+      "audio/x-opus, rate=(int){48000, 24000, 16000, 12000, 8000}, channels=(int)[1,8]");
+
+  /* Unsupported rate */
+  run_getcaps_check_from_strings (NULL, "audio/x-raw, rate=(int)1000", "EMPTY");
+
+  /* same tests for channels */
+  run_getcaps_check_from_strings (NULL, "audio/x-raw, channels=(int)2",
+      "audio/x-opus, rate=(int){48000, 24000, 16000, 12000, 8000}, channels=(int)[1,2]");
+  run_getcaps_check_from_strings (NULL, "audio/x-raw, channels=(int)[1, 2]",
+      "audio/x-opus, rate=(int){48000, 24000, 16000, 12000, 8000}, channels=(int)[1,2]");
+  run_getcaps_check_from_strings (NULL, "audio/x-raw, channels=(int)5000",
+      "EMPTY");
+}
+
+GST_END_TEST;
+
 static Suite *
 opus_suite (void)
 {
@@ -329,6 +418,7 @@ opus_suite (void)
   tcase_add_test (tc_chain, test_opus_decode_nothing);
   tcase_add_test (tc_chain, test_opus_encode_samples);
   tcase_add_test (tc_chain, test_opus_encode_properties);
+  tcase_add_test (tc_chain, test_opusdec_getcaps);
 
   return s;
 }