mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
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:
parent
4d47d43a13
commit
ef3844cf6f
1 changed files with 34 additions and 15 deletions
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue