summaryrefslogtreecommitdiff
path: root/gst/audioconvert
diff options
context:
space:
mode:
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2012-10-18 22:13:09 +0200
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2012-10-19 16:02:44 +0200
commita66ff00908432bb984269433aadd27ba5ec86841 (patch)
tree2c382fa9e6bc1364157781cbe56eef641988dfdb /gst/audioconvert
parentb57d3252ecbe4f37d8b35977847c8de75e0aff50 (diff)
audioconvert: enhance transforming caps
... so as to preserve input format precision, and preferably not convert at all.
Diffstat (limited to 'gst/audioconvert')
-rw-r--r--gst/audioconvert/gstaudioconvert.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/gst/audioconvert/gstaudioconvert.c b/gst/audioconvert/gstaudioconvert.c
index 9a5f5ada8c..e7a1f1da15 100644
--- a/gst/audioconvert/gstaudioconvert.c
+++ b/gst/audioconvert/gstaudioconvert.c
@@ -436,6 +436,64 @@ find_suitable_mask (guint64 mask, gint n_chans)
}
static void
+gst_audio_convert_fixate_format (GstBaseTransform * base, GstStructure * ins,
+ GstStructure * outs)
+{
+ const gchar *in_format;
+ const GValue *format;
+ const GstAudioFormatInfo *in_info, *out_info = NULL;
+
+ in_format = gst_structure_get_string (ins, "format");
+ if (!in_format)
+ return;
+
+ format = gst_structure_get_value (outs, "format");
+ /* should not happen */
+ if (format == NULL)
+ return;
+
+ in_info =
+ gst_audio_format_get_info (gst_audio_format_from_string (in_format));
+ if (!in_info)
+ return;
+
+ if (GST_VALUE_HOLDS_LIST (format)) {
+ gint i, len;
+
+ len = gst_value_list_get_size (format);
+ for (i = 0; i < len; i++) {
+ const GValue *val;
+ const gchar *fname;
+
+ val = gst_value_list_get_value (format, i);
+ if (G_VALUE_HOLDS_STRING (val)) {
+ fname = g_value_get_string (val);
+ out_info =
+ gst_audio_format_get_info (gst_audio_format_from_string (fname));
+ if (!out_info)
+ continue;
+ /* accept input format */
+ if (strcmp (fname, in_format) == 0)
+ break;
+ /* or another format without losing precision */
+ if ((GST_AUDIO_FORMAT_INFO_FLAGS (out_info) ==
+ GST_AUDIO_FORMAT_INFO_FLAGS (in_info)) &&
+ (GST_AUDIO_FORMAT_INFO_DEPTH (out_info) >=
+ GST_AUDIO_FORMAT_INFO_DEPTH (in_info)))
+ break;
+ }
+ out_info = NULL;
+ }
+ if (out_info)
+ gst_structure_set (outs, "format", G_TYPE_STRING,
+ GST_AUDIO_FORMAT_INFO_NAME (out_info), NULL);
+ } else {
+ /* nothing to fixate */
+ return;
+ }
+}
+
+static void
gst_audio_convert_fixate_channels (GstBaseTransform * base, GstStructure * ins,
GstStructure * outs)
{
@@ -626,6 +684,9 @@ gst_audio_convert_fixate_caps (GstBaseTransform * base,
outs = gst_caps_get_structure (result, 0);
gst_audio_convert_fixate_channels (base, ins, outs);
+ gst_audio_convert_fixate_format (base, ins, outs);
+
+ /* fixate remaining */
result = gst_caps_fixate (result);
GST_DEBUG_OBJECT (base, "fixated othercaps to %" GST_PTR_FORMAT, result);