mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
audioconvert: Prefer output formats with the same depth or at least a higher depth
Enhance current code to prefer an exact match on sample depth if possible. Also ignore GST_AUDIO_FORMAT_FLAG_UNPACK when checking equality on the flags.
This commit is contained in:
parent
5f44303925
commit
c286f8ffa2
2 changed files with 84 additions and 8 deletions
|
@ -442,6 +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;
|
||||||
|
|
||||||
in_format = gst_structure_get_string (ins, "format");
|
in_format = gst_structure_get_string (ins, "format");
|
||||||
if (!in_format)
|
if (!in_format)
|
||||||
|
@ -457,6 +458,9 @@ gst_audio_convert_fixate_format (GstBaseTransform * base, GstStructure * ins,
|
||||||
if (!in_info)
|
if (!in_info)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
in_flags = GST_AUDIO_FORMAT_INFO_FLAGS (in_info);
|
||||||
|
in_flags &= ~(GST_AUDIO_FORMAT_FLAG_UNPACK);
|
||||||
|
|
||||||
if (GST_VALUE_HOLDS_LIST (format)) {
|
if (GST_VALUE_HOLDS_LIST (format)) {
|
||||||
gint i, len;
|
gint i, len;
|
||||||
|
|
||||||
|
@ -467,22 +471,32 @@ 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;
|
||||||
fname = g_value_get_string (val);
|
fname = g_value_get_string (val);
|
||||||
out_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));
|
||||||
if (!out_info)
|
if (!t_info)
|
||||||
continue;
|
continue;
|
||||||
/* accept input format */
|
/* accept input format */
|
||||||
if (strcmp (fname, in_format) == 0)
|
if (strcmp (fname, in_format) == 0)
|
||||||
break;
|
break;
|
||||||
|
out_flags = GST_AUDIO_FORMAT_INFO_FLAGS (t_info);
|
||||||
|
out_flags &= ~(GST_AUDIO_FORMAT_FLAG_UNPACK);
|
||||||
/* or another format without losing precision */
|
/* or another format without losing precision */
|
||||||
if ((GST_AUDIO_FORMAT_INFO_FLAGS (out_info) ==
|
if (in_flags == out_flags) {
|
||||||
GST_AUDIO_FORMAT_INFO_FLAGS (in_info)) &&
|
if (GST_AUDIO_FORMAT_INFO_DEPTH (t_info) ==
|
||||||
(GST_AUDIO_FORMAT_INFO_DEPTH (out_info) >=
|
GST_AUDIO_FORMAT_INFO_DEPTH (in_info)) {
|
||||||
GST_AUDIO_FORMAT_INFO_DEPTH (in_info)))
|
/* exact match. We are done */
|
||||||
break;
|
out_info = t_info;
|
||||||
|
break;
|
||||||
|
} else if ((GST_AUDIO_FORMAT_INFO_DEPTH (t_info) >=
|
||||||
|
GST_AUDIO_FORMAT_INFO_DEPTH (in_info))) {
|
||||||
|
/* match where we do not lose precision. This could
|
||||||
|
be ok, but keep searching for an exact match */
|
||||||
|
out_info = t_info;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
out_info = NULL;
|
|
||||||
}
|
}
|
||||||
if (out_info)
|
if (out_info)
|
||||||
gst_structure_set (outs, "format", G_TYPE_STRING,
|
gst_structure_set (outs, "format", G_TYPE_STRING,
|
||||||
|
|
|
@ -1441,6 +1441,67 @@ GST_START_TEST (test_convert_undefined_multichannel)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
#define SIMPLE_CAPS_TEMPLATE_STRING \
|
||||||
|
"audio/x-raw, " \
|
||||||
|
"format = (string) {S8, S16LE, S24LE, S32LE}, " \
|
||||||
|
"rate = (int) [ 1, MAX ], " \
|
||||||
|
"channels = (int) [ 1, MAX ]"
|
||||||
|
|
||||||
|
static GstStaticPadTemplate simple_sinktemplate =
|
||||||
|
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
|
GST_PAD_SINK,
|
||||||
|
GST_PAD_ALWAYS,
|
||||||
|
GST_STATIC_CAPS (SIMPLE_CAPS_TEMPLATE_STRING)
|
||||||
|
);
|
||||||
|
|
||||||
|
GST_START_TEST (test_preserve_width)
|
||||||
|
{
|
||||||
|
static const struct _test_formats
|
||||||
|
{
|
||||||
|
int width;
|
||||||
|
const gchar *outf;
|
||||||
|
} test_formats[] = { {
|
||||||
|
8, "S8"}, {
|
||||||
|
16, "S16LE"}, {
|
||||||
|
24, "S24LE"}, {
|
||||||
|
32, "S32LE"}, {
|
||||||
|
0, NULL}};
|
||||||
|
|
||||||
|
gint i;
|
||||||
|
GstStructure *structure;
|
||||||
|
GstElement *audioconvert;
|
||||||
|
GstCaps *incaps, *convert_outcaps;
|
||||||
|
|
||||||
|
audioconvert = gst_check_setup_element ("audioconvert");
|
||||||
|
mysrcpad = gst_check_setup_src_pad (audioconvert, &srctemplate);
|
||||||
|
mysinkpad = gst_check_setup_sink_pad (audioconvert, &simple_sinktemplate);
|
||||||
|
|
||||||
|
gst_pad_set_active (mysrcpad, TRUE);
|
||||||
|
gst_pad_set_active (mysinkpad, TRUE);
|
||||||
|
|
||||||
|
fail_unless (gst_element_set_state (audioconvert,
|
||||||
|
GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
|
||||||
|
"could not set to playing");
|
||||||
|
|
||||||
|
for (i = 0; test_formats[i].width; i++) {
|
||||||
|
gint width = test_formats[i].width;
|
||||||
|
incaps = get_int_caps (1, G_BIG_ENDIAN, width, width, TRUE);
|
||||||
|
gst_pad_set_caps (mysrcpad, incaps);
|
||||||
|
|
||||||
|
convert_outcaps = gst_pad_get_current_caps (mysinkpad);
|
||||||
|
structure = gst_caps_get_structure (convert_outcaps, 0);
|
||||||
|
fail_unless_equals_string (gst_structure_get_string (structure, "format"),
|
||||||
|
test_formats[i].outf);
|
||||||
|
|
||||||
|
gst_caps_unref (convert_outcaps);
|
||||||
|
gst_caps_unref (incaps);
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup_audioconvert (audioconvert);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
static Suite *
|
static Suite *
|
||||||
audioconvert_suite (void)
|
audioconvert_suite (void)
|
||||||
{
|
{
|
||||||
|
@ -1455,6 +1516,7 @@ audioconvert_suite (void)
|
||||||
tcase_add_test (tc_chain, test_multichannel_conversion);
|
tcase_add_test (tc_chain, test_multichannel_conversion);
|
||||||
tcase_add_test (tc_chain, test_caps_negotiation);
|
tcase_add_test (tc_chain, test_caps_negotiation);
|
||||||
tcase_add_test (tc_chain, test_convert_undefined_multichannel);
|
tcase_add_test (tc_chain, test_convert_undefined_multichannel);
|
||||||
|
tcase_add_test (tc_chain, test_preserve_width);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue