mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 22:36:33 +00:00
audioconvert: If we have to lose precision, try to lose as less precision as possible
https://bugzilla.gnome.org/show_bug.cgi?id=706624
This commit is contained in:
parent
f9ebfd57f8
commit
cebae4514a
1 changed files with 40 additions and 28 deletions
|
@ -442,7 +442,7 @@ gst_audio_convert_fixate_format (GstBaseTransform * base, GstStructure * ins,
|
||||||
const gchar *in_format;
|
const gchar *in_format;
|
||||||
const GValue *format;
|
const GValue *format;
|
||||||
const GstAudioFormatInfo *in_info, *out_info = NULL;
|
const GstAudioFormatInfo *in_info, *out_info = NULL;
|
||||||
GstAudioFormatFlags in_flags, out_flags;
|
GstAudioFormatFlags in_flags, out_flags = 0;
|
||||||
|
|
||||||
in_format = gst_structure_get_string (ins, "format");
|
in_format = gst_structure_get_string (ins, "format");
|
||||||
if (!in_format)
|
if (!in_format)
|
||||||
|
@ -473,6 +473,8 @@ gst_audio_convert_fixate_format (GstBaseTransform * base, GstStructure * ins,
|
||||||
val = gst_value_list_get_value (format, i);
|
val = gst_value_list_get_value (format, i);
|
||||||
if (G_VALUE_HOLDS_STRING (val)) {
|
if (G_VALUE_HOLDS_STRING (val)) {
|
||||||
const GstAudioFormatInfo *t_info;
|
const GstAudioFormatInfo *t_info;
|
||||||
|
GstAudioFormatFlags t_flags;
|
||||||
|
|
||||||
fname = g_value_get_string (val);
|
fname = g_value_get_string (val);
|
||||||
t_info =
|
t_info =
|
||||||
gst_audio_format_get_info (gst_audio_format_from_string (fname));
|
gst_audio_format_get_info (gst_audio_format_from_string (fname));
|
||||||
|
@ -484,33 +486,43 @@ gst_audio_convert_fixate_format (GstBaseTransform * base, GstStructure * ins,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
out_flags = GST_AUDIO_FORMAT_INFO_FLAGS (t_info);
|
t_flags = GST_AUDIO_FORMAT_INFO_FLAGS (t_info);
|
||||||
out_flags &= ~(GST_AUDIO_FORMAT_FLAG_UNPACK);
|
t_flags &= ~(GST_AUDIO_FORMAT_FLAG_UNPACK);
|
||||||
out_flags &= ~(GST_AUDIO_FORMAT_FLAG_SIGNED);
|
t_flags &= ~(GST_AUDIO_FORMAT_FLAG_SIGNED);
|
||||||
/* or another format without losing precision */
|
|
||||||
if (in_flags == out_flags) {
|
if (GST_AUDIO_FORMAT_INFO_DEPTH (t_info) ==
|
||||||
if (GST_AUDIO_FORMAT_INFO_DEPTH (t_info) ==
|
GST_AUDIO_FORMAT_INFO_DEPTH (in_info) && (!out_info
|
||||||
GST_AUDIO_FORMAT_INFO_DEPTH (in_info) &&
|
|| GST_AUDIO_FORMAT_INFO_DEPTH (out_info) !=
|
||||||
(!out_info
|
GST_AUDIO_FORMAT_INFO_DEPTH (in_info)
|
||||||
|| GST_AUDIO_FORMAT_INFO_DEPTH (out_info) >=
|
|| (t_flags == in_flags && out_flags != in_flags))) {
|
||||||
GST_AUDIO_FORMAT_INFO_DEPTH (in_info))) {
|
/* Prefer to use the first format that has the same depth with the same
|
||||||
/* exact match of depth, we still continue
|
* flags, and if none with the same flags exist use the first other one
|
||||||
* to iterate to see if we can get exactly
|
* that has the same depth */
|
||||||
* the same format.
|
out_info = t_info;
|
||||||
* Only go here if we don't have another
|
out_flags = t_flags;
|
||||||
* format with the same depth already. We
|
} else if (GST_AUDIO_FORMAT_INFO_DEPTH (t_info) >=
|
||||||
* always take the first to prefer caps
|
GST_AUDIO_FORMAT_INFO_DEPTH (in_info) && (!out_info
|
||||||
* order. */
|
|| GST_AUDIO_FORMAT_INFO_DEPTH (in_info) >
|
||||||
out_info = t_info;
|
GST_AUDIO_FORMAT_INFO_DEPTH (out_info)
|
||||||
} else if ((GST_AUDIO_FORMAT_INFO_DEPTH (t_info) >=
|
|| (GST_AUDIO_FORMAT_INFO_DEPTH (out_info) >=
|
||||||
GST_AUDIO_FORMAT_INFO_DEPTH (in_info)) && !out_info) {
|
GST_AUDIO_FORMAT_INFO_DEPTH (in_info) && t_flags == in_flags
|
||||||
/* match where we do not lose precision. This could
|
&& out_flags != in_flags))) {
|
||||||
* be ok, but keep searching for an exact match.
|
/* Otherwise use the first format that has a higher depth with the same flags,
|
||||||
* Only go here if we don't have another format with
|
* if none with the same flags exist use the first other one that has a higher
|
||||||
* a bigger/equal depth already. We always take the
|
* depth */
|
||||||
* first to prefer caps order. */
|
out_info = t_info;
|
||||||
out_info = t_info;
|
out_flags = t_flags;
|
||||||
}
|
} else if (!out_info
|
||||||
|
|| (GST_AUDIO_FORMAT_INFO_DEPTH (t_info) >
|
||||||
|
GST_AUDIO_FORMAT_INFO_DEPTH (out_info)
|
||||||
|
&& GST_AUDIO_FORMAT_INFO_DEPTH (out_info) <
|
||||||
|
GST_AUDIO_FORMAT_INFO_DEPTH (in_info)) || (t_flags == in_flags
|
||||||
|
&& out_flags != in_flags
|
||||||
|
&& GST_AUDIO_FORMAT_INFO_DEPTH (out_info) ==
|
||||||
|
GST_AUDIO_FORMAT_INFO_DEPTH (t_info))) {
|
||||||
|
/* Else get at least the one with the highest depth, ideally with the same flags */
|
||||||
|
out_info = t_info;
|
||||||
|
out_flags = t_flags;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue