From ffcb8845510802f70c159bf510797b1a89351241 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tim-Philipp=20M=C3=BCller?= Date: Fri, 13 Jun 2014 09:45:28 +0100 Subject: [PATCH] oss: make sure 16-bit formats are before 8-bit formats in probed caps Probe supported formats in order of desirability rather than in what order they may happen to be in the formats bitmask. Fixes accidentally exposure of 8-bit formats in caps before 16-bit formats (in case where U16 was not supported S8 might be listed before S16). https://bugzilla.gnome.org/show_bug.cgi?id=706884 --- sys/oss/gstosshelper.c | 90 +++++++++++++++++++++++--------------------------- 1 file changed, 42 insertions(+), 48 deletions(-) diff --git a/sys/oss/gstosshelper.c b/sys/oss/gstosshelper.c index 9fc2701..439171e 100644 --- a/sys/oss/gstosshelper.c +++ b/sys/oss/gstosshelper.c @@ -81,75 +81,69 @@ static int gst_oss_helper_rate_int_compare (gconstpointer a, gconstpointer b); GstCaps * gst_oss_helper_probe_caps (gint fd) { +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + const guint probe_formats[] = { AFMT_S16_LE, AFMT_U16_LE, AFMT_U8, AFMT_S8 }; +#else + const guint probe_formats[] = { AFMT_S16_BE, AFMT_U16_BE, AFMT_U8, AFMT_S8 }; +#endif GstOssProbe *probe; - int i; + int i, f; gboolean ret; GstStructure *structure; - unsigned int format_bit; - unsigned int format_mask; GstCaps *caps; /* FIXME test make sure we're not currently playing */ /* FIXME test both mono and stereo */ - format_mask = AFMT_U8 | AFMT_S8; - - if (G_BYTE_ORDER == G_LITTLE_ENDIAN) - format_mask |= AFMT_S16_LE | AFMT_U16_LE; - else - format_mask |= AFMT_S16_BE | AFMT_U16_BE; - caps = gst_caps_new_empty (); /* assume that the most significant bit of format_mask is 0 */ - for (format_bit = 1 << 31; format_bit > 0; format_bit >>= 1) { - if (format_bit & format_mask) { - GValue rate_value = { 0 }; - - probe = g_new0 (GstOssProbe, 1); - probe->fd = fd; - probe->format = format_bit; - /* FIXME: this is not working for all cards, see bug #518474 */ - probe->n_channels = 2; - - ret = gst_oss_helper_rate_probe_check (probe); - if (probe->min == -1 || probe->max == -1) { - g_array_free (probe->rates, TRUE); - g_free (probe); - continue; - } + for (f = 0; f < G_N_ELEMENTS (probe_formats); ++f) { + GValue rate_value = { 0 }; - if (ret) { - GValue value = { 0 }; + probe = g_new0 (GstOssProbe, 1); + probe->fd = fd; + probe->format = probe_formats[f]; + /* FIXME: this is not working for all cards, see bug #518474 */ + probe->n_channels = 2; - g_array_sort (probe->rates, gst_oss_helper_rate_int_compare); + ret = gst_oss_helper_rate_probe_check (probe); + if (probe->min == -1 || probe->max == -1) { + g_array_free (probe->rates, TRUE); + g_free (probe); + continue; + } - g_value_init (&rate_value, GST_TYPE_LIST); - g_value_init (&value, G_TYPE_INT); + if (ret) { + GValue value = { 0 }; - for (i = 0; i < probe->rates->len; i++) { - g_value_set_int (&value, g_array_index (probe->rates, int, i)); + g_array_sort (probe->rates, gst_oss_helper_rate_int_compare); - gst_value_list_append_value (&rate_value, &value); - } + g_value_init (&rate_value, GST_TYPE_LIST); + g_value_init (&value, G_TYPE_INT); - g_value_unset (&value); - } else { - /* one big range */ - g_value_init (&rate_value, GST_TYPE_INT_RANGE); - gst_value_set_int_range (&rate_value, probe->min, probe->max); + for (i = 0; i < probe->rates->len; i++) { + g_value_set_int (&value, g_array_index (probe->rates, int, i)); + + gst_value_list_append_value (&rate_value, &value); } - g_array_free (probe->rates, TRUE); - g_free (probe); + g_value_unset (&value); + } else { + /* one big range */ + g_value_init (&rate_value, GST_TYPE_INT_RANGE); + gst_value_set_int_range (&rate_value, probe->min, probe->max); + } - structure = gst_oss_helper_get_format_structure (format_bit); - gst_structure_set (structure, "channels", GST_TYPE_INT_RANGE, 1, 2, NULL); - gst_structure_set_value (structure, "rate", &rate_value); - g_value_unset (&rate_value); + g_array_free (probe->rates, TRUE); + g_free (probe); - gst_caps_append_structure (caps, structure); - } + structure = gst_oss_helper_get_format_structure (probe_formats[f]); + gst_structure_set (structure, "channels", GST_TYPE_INT_RANGE, 1, 2, NULL); + gst_structure_set_value (structure, "rate", &rate_value); + g_value_unset (&rate_value); + + gst_caps_append_structure (caps, structure); } if (gst_caps_is_empty (caps)) { -- 2.7.4