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 GValue *format;
|
||||
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");
|
||||
if (!in_format)
|
||||
|
@ -473,6 +473,8 @@ gst_audio_convert_fixate_format (GstBaseTransform * base, GstStructure * ins,
|
|||
val = gst_value_list_get_value (format, i);
|
||||
if (G_VALUE_HOLDS_STRING (val)) {
|
||||
const GstAudioFormatInfo *t_info;
|
||||
GstAudioFormatFlags t_flags;
|
||||
|
||||
fname = g_value_get_string (val);
|
||||
t_info =
|
||||
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;
|
||||
}
|
||||
|
||||
out_flags = GST_AUDIO_FORMAT_INFO_FLAGS (t_info);
|
||||
out_flags &= ~(GST_AUDIO_FORMAT_FLAG_UNPACK);
|
||||
out_flags &= ~(GST_AUDIO_FORMAT_FLAG_SIGNED);
|
||||
/* or another format without losing precision */
|
||||
if (in_flags == out_flags) {
|
||||
t_flags = GST_AUDIO_FORMAT_INFO_FLAGS (t_info);
|
||||
t_flags &= ~(GST_AUDIO_FORMAT_FLAG_UNPACK);
|
||||
t_flags &= ~(GST_AUDIO_FORMAT_FLAG_SIGNED);
|
||||
|
||||
if (GST_AUDIO_FORMAT_INFO_DEPTH (t_info) ==
|
||||
GST_AUDIO_FORMAT_INFO_DEPTH (in_info) &&
|
||||
(!out_info
|
||||
|| GST_AUDIO_FORMAT_INFO_DEPTH (out_info) >=
|
||||
GST_AUDIO_FORMAT_INFO_DEPTH (in_info))) {
|
||||
/* exact match of depth, we still continue
|
||||
* to iterate to see if we can get exactly
|
||||
* the same format.
|
||||
* Only go here if we don't have another
|
||||
* format with the same depth already. We
|
||||
* always take the first to prefer caps
|
||||
* order. */
|
||||
GST_AUDIO_FORMAT_INFO_DEPTH (in_info) && (!out_info
|
||||
|| GST_AUDIO_FORMAT_INFO_DEPTH (out_info) !=
|
||||
GST_AUDIO_FORMAT_INFO_DEPTH (in_info)
|
||||
|| (t_flags == in_flags && out_flags != in_flags))) {
|
||||
/* Prefer to use the first format that has the same depth with the same
|
||||
* flags, and if none with the same flags exist use the first other one
|
||||
* that has the same depth */
|
||||
out_info = t_info;
|
||||
} else if ((GST_AUDIO_FORMAT_INFO_DEPTH (t_info) >=
|
||||
GST_AUDIO_FORMAT_INFO_DEPTH (in_info)) && !out_info) {
|
||||
/* match where we do not lose precision. This could
|
||||
* be ok, but keep searching for an exact match.
|
||||
* Only go here if we don't have another format with
|
||||
* a bigger/equal depth already. We always take the
|
||||
* first to prefer caps order. */
|
||||
out_flags = t_flags;
|
||||
} else 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)
|
||||
|| (GST_AUDIO_FORMAT_INFO_DEPTH (out_info) >=
|
||||
GST_AUDIO_FORMAT_INFO_DEPTH (in_info) && t_flags == in_flags
|
||||
&& out_flags != in_flags))) {
|
||||
/* Otherwise use the first format that has a higher depth with the same flags,
|
||||
* if none with the same flags exist use the first other one that has a higher
|
||||
* depth */
|
||||
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