From 7a5797d3a62e47cd6cc7426dac843867445fc7d9 Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Mon, 2 May 2016 10:23:09 -0300 Subject: [PATCH] opusdec: improve getcaps to return all possible rates The library is capable of converting to different rates. Includes tests. https://bugzilla.gnome.org/show_bug.cgi?id=765684 --- ext/opus/gstopusdec.c | 34 ++++++++++++++ tests/check/elements/opus.c | 90 +++++++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+) diff --git a/ext/opus/gstopusdec.c b/ext/opus/gstopusdec.c index 90301e00bb..aa53ff3320 100644 --- a/ext/opus/gstopusdec.c +++ b/ext/opus/gstopusdec.c @@ -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; } diff --git a/tests/check/elements/opus.c b/tests/check/elements/opus.c index d99927bbf6..0fe1041c35 100644 --- a/tests/check/elements/opus.c +++ b/tests/check/elements/opus.c @@ -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; }