audio-converter: Avoid conversion when possible

When the input and output formats are the same and in a possible
intermediate format, avoid unpack and pack.
Never do passthrough channel mixing.
Only do dithering and noise shaping in S32 format
This commit is contained in:
Wim Taymans 2016-01-12 15:27:16 +01:00
parent 4d47d43a13
commit ef3844cf6f

View file

@ -407,15 +407,17 @@ do_unpack (AudioChain * chain, gpointer user_data)
if (!chain->allow_ip || !in_writable || !convert->in_default) {
gint i;
if (in_writable && chain->allow_ip)
if (in_writable && chain->allow_ip) {
tmp = convert->in_data;
else
GST_LOG ("unpack in-place %p, %" G_GSIZE_FORMAT, tmp, num_samples);
} else {
tmp = audio_chain_alloc_samples (chain, num_samples);
GST_LOG ("unpack %p, %p, %" G_GSIZE_FORMAT, tmp, convert->in_data,
num_samples);
GST_LOG ("unpack to tmp %p, %" G_GSIZE_FORMAT, tmp, num_samples);
}
for (i = 0; i < chain->blocks; i++) {
GST_LOG ("unpack %p, %p, %" G_GSIZE_FORMAT, tmp[i], convert->in_data[i],
num_samples);
convert->in.finfo->unpack_func (convert->in.finfo,
GST_AUDIO_PACK_FLAG_TRUNCATE_RANGE, tmp[i], convert->in_data[i],
num_samples * chain->inc);
@ -505,23 +507,42 @@ do_quantize (AudioChain * chain, gpointer user_data)
return TRUE;
}
static gboolean
is_intermediate_format (GstAudioFormat format)
{
return (format == GST_AUDIO_FORMAT_S16 ||
format == GST_AUDIO_FORMAT_S32 ||
format == GST_AUDIO_FORMAT_F32 || format == GST_AUDIO_FORMAT_F64);
}
static AudioChain *
chain_unpack (GstAudioConverter * convert)
{
AudioChain *prev;
GstAudioInfo *in = &convert->in;
GstAudioInfo *out = &convert->out;
const GstAudioFormatInfo *fup;
gboolean same_format;
convert->current_format = in->finfo->unpack_format;
same_format = in->finfo->format == out->finfo->format;
/* do not unpack if we have the same input format as the output format
* and it is a possible intermediate format */
if (same_format && is_intermediate_format (in->finfo->format)) {
convert->current_format = in->finfo->format;
} else {
convert->current_format = in->finfo->unpack_format;
}
convert->current_layout = in->layout;
convert->current_channels = in->channels;
convert->in_default = in->finfo->unpack_format == in->finfo->format;
convert->in_default = convert->current_format == in->finfo->format;
GST_INFO ("unpack format %s to %s",
gst_audio_format_to_string (in->finfo->format),
gst_audio_format_to_string (convert->current_format));
fup = gst_audio_format_get_info (in->finfo->unpack_format);
fup = gst_audio_format_get_info (convert->current_format);
prev = convert->unpack_chain = audio_chain_new (NULL, convert);
prev->allow_ip = fup->width <= in->finfo->width;
@ -582,10 +603,8 @@ chain_mix (GstAudioConverter * convert, AudioChain * prev)
if (!convert->mix_passthrough) {
prev = convert->mix_chain = audio_chain_new (prev, convert);
/* we can only do in-place when in >= out, else we don't have enough
* memory. */
prev->allow_ip = in->channels >= out->channels;
prev->pass_alloc = in->channels <= out->channels;
prev->allow_ip = FALSE;
prev->pass_alloc = FALSE;
audio_chain_set_make_func (prev, do_mix, convert, NULL);
}
return prev;
@ -651,7 +670,8 @@ chain_quantize (GstAudioConverter * convert, AudioChain * prev)
}
/* we still want to run the quantization step when reducing bits to get
* the rounding correct */
if (out_int && out_depth < 32) {
if (out_int && out_depth < 32
&& convert->current_format == GST_AUDIO_FORMAT_S32) {
GST_INFO ("quantize to %d bits, dither %d, ns %d", out_depth, dither, ns);
convert->quant =
gst_audio_quantize_new (dither, ns, 0, convert->current_format,
@ -673,7 +693,6 @@ chain_pack (GstAudioConverter * convert, AudioChain * prev)
convert->current_format = out->finfo->format;
g_assert (out->finfo->unpack_format == format);
convert->out_default = format == out->finfo->format;
GST_INFO ("pack format %s to %s", gst_audio_format_to_string (format),
gst_audio_format_to_string (out->finfo->format));
@ -933,7 +952,7 @@ gst_audio_converter_samples (GstAudioConverter * convert,
return TRUE;
}
GST_LOG ("converting %" G_GSIZE_FORMAT, in_samples);
GST_LOG ("converting %p %p %" G_GSIZE_FORMAT, in, out, in_samples);
convert->in_writable = flags & GST_AUDIO_CONVERTER_FLAG_IN_WRITABLE;
convert->in_data = in;