mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-09-01 01:33:52 +00:00
audio-converter: audio-converter: make some optimized functions
Make optimized functions for generic and passthrough conversion.
This commit is contained in:
parent
cde091ae81
commit
0f757bc23c
2 changed files with 77 additions and 54 deletions
|
@ -77,6 +77,10 @@ ensure_debug_category (void)
|
||||||
typedef struct _AudioChain AudioChain;
|
typedef struct _AudioChain AudioChain;
|
||||||
|
|
||||||
typedef void (*AudioConvertFunc) (gpointer dst, const gpointer src, gint count);
|
typedef void (*AudioConvertFunc) (gpointer dst, const gpointer src, gint count);
|
||||||
|
typedef gboolean (*AudioConvertSamplesFunc) (GstAudioConverter * convert,
|
||||||
|
GstAudioConverterFlags flags, gpointer in[], gsize in_frames,
|
||||||
|
gpointer out[], gsize out_frames);
|
||||||
|
|
||||||
/* int/int int/float float/int float/float
|
/* int/int int/float float/int float/float
|
||||||
*
|
*
|
||||||
* unpack S32 S32 F64 F64
|
* unpack S32 S32 F64 F64
|
||||||
|
@ -105,9 +109,9 @@ struct _GstAudioConverter
|
||||||
|
|
||||||
gboolean in_writable;
|
gboolean in_writable;
|
||||||
gpointer *in_data;
|
gpointer *in_data;
|
||||||
gsize in_samples;
|
gsize in_frames;
|
||||||
gpointer *out_data;
|
gpointer *out_data;
|
||||||
gsize out_samples;
|
gsize out_frames;
|
||||||
|
|
||||||
/* unpack */
|
/* unpack */
|
||||||
gboolean in_default;
|
gboolean in_default;
|
||||||
|
@ -135,7 +139,7 @@ struct _GstAudioConverter
|
||||||
gboolean out_default;
|
gboolean out_default;
|
||||||
AudioChain *pack_chain;
|
AudioChain *pack_chain;
|
||||||
|
|
||||||
gboolean passthrough;
|
AudioConvertSamplesFunc convert;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef gboolean (*AudioChainFunc) (AudioChain * chain, gpointer user_data);
|
typedef gboolean (*AudioChainFunc) (AudioChain * chain, gpointer user_data);
|
||||||
|
@ -404,7 +408,7 @@ do_unpack (AudioChain * chain, gpointer user_data)
|
||||||
gboolean in_writable;
|
gboolean in_writable;
|
||||||
|
|
||||||
in_writable = convert->in_writable;
|
in_writable = convert->in_writable;
|
||||||
num_samples = convert->in_samples;
|
num_samples = convert->in_frames;
|
||||||
|
|
||||||
if (!chain->allow_ip || !in_writable || !convert->in_default) {
|
if (!chain->allow_ip || !in_writable || !convert->in_default) {
|
||||||
gint i;
|
gint i;
|
||||||
|
@ -733,6 +737,59 @@ setup_allocators (GstAudioConverter * convert)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
converter_passthrough (GstAudioConverter * convert,
|
||||||
|
GstAudioConverterFlags flags, gpointer in[], gsize in_frames,
|
||||||
|
gpointer out[], gsize out_frames)
|
||||||
|
{
|
||||||
|
gint i;
|
||||||
|
gsize bytes;
|
||||||
|
AudioChain *chain;
|
||||||
|
|
||||||
|
chain = convert->pack_chain;
|
||||||
|
|
||||||
|
bytes = in_frames * chain->inc * (convert->in.bpf / convert->in.channels);
|
||||||
|
|
||||||
|
GST_LOG ("passthrough: %" G_GSIZE_FORMAT " / %" G_GSIZE_FORMAT " bytes",
|
||||||
|
in_frames, bytes);
|
||||||
|
|
||||||
|
for (i = 0; i < chain->blocks; i++)
|
||||||
|
memcpy (out[i], in[i], bytes);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
converter_generic (GstAudioConverter * convert,
|
||||||
|
GstAudioConverterFlags flags, gpointer in[], gsize in_frames,
|
||||||
|
gpointer out[], gsize out_frames)
|
||||||
|
{
|
||||||
|
AudioChain *chain;
|
||||||
|
gpointer *tmp;
|
||||||
|
gint i;
|
||||||
|
gsize produced;
|
||||||
|
|
||||||
|
chain = convert->pack_chain;
|
||||||
|
|
||||||
|
convert->in_writable = flags & GST_AUDIO_CONVERTER_FLAG_IN_WRITABLE;
|
||||||
|
convert->in_data = in;
|
||||||
|
convert->in_frames = in_frames;
|
||||||
|
convert->out_data = out;
|
||||||
|
convert->out_frames = out_frames;
|
||||||
|
|
||||||
|
/* get frames to pack */
|
||||||
|
tmp = audio_chain_get_samples (chain, &produced);
|
||||||
|
|
||||||
|
if (!convert->out_default) {
|
||||||
|
GST_LOG ("pack %p, %p %" G_GSIZE_FORMAT, tmp, out, produced);
|
||||||
|
/* and pack if needed */
|
||||||
|
for (i = 0; i < chain->blocks; i++)
|
||||||
|
convert->out.finfo->pack_func (convert->out.finfo, 0, tmp[i], out[i],
|
||||||
|
produced * chain->inc);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_audio_converter_new: (skip)
|
* gst_audio_converter_new: (skip)
|
||||||
* @flags: #GstAudioConverterFlags
|
* @flags: #GstAudioConverterFlags
|
||||||
|
@ -796,7 +853,10 @@ gst_audio_converter_new (GstAudioConverterFlags flags, GstAudioInfo * in_info,
|
||||||
if (out_info->finfo->format == in_info->finfo->format
|
if (out_info->finfo->format == in_info->finfo->format
|
||||||
&& convert->mix_passthrough) {
|
&& convert->mix_passthrough) {
|
||||||
GST_INFO ("same formats and passthrough mixing -> passthrough");
|
GST_INFO ("same formats and passthrough mixing -> passthrough");
|
||||||
convert->passthrough = TRUE;
|
convert->convert = converter_passthrough;
|
||||||
|
} else {
|
||||||
|
GST_INFO ("do full conversion");
|
||||||
|
convert->convert = converter_generic;
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_allocators (convert);
|
setup_allocators (convert);
|
||||||
|
@ -899,12 +959,12 @@ gst_audio_converter_get_max_latency (GstAudioConverter * convert)
|
||||||
* gst_audio_converter_samples:
|
* gst_audio_converter_samples:
|
||||||
* @convert: a #GstAudioConverter
|
* @convert: a #GstAudioConverter
|
||||||
* @flags: extra #GstAudioConverterFlags
|
* @flags: extra #GstAudioConverterFlags
|
||||||
* @in: input samples
|
* @in: input frames
|
||||||
* @in_samples: number of input samples
|
* @in_frames: number of input frames
|
||||||
* @out: output samples
|
* @out: output frames
|
||||||
* @out_samples: number of output samples
|
* @out_frames: number of output frames
|
||||||
*
|
*
|
||||||
* Perform the conversion with @in_samples in @in to @out_samples in @out
|
* Perform the conversion with @in_frames in @in to @out_frames in @out
|
||||||
* using @convert.
|
* using @convert.
|
||||||
*
|
*
|
||||||
* In case the samples are interleaved, @in and @out must point to an
|
* In case the samples are interleaved, @in and @out must point to an
|
||||||
|
@ -922,55 +982,18 @@ gst_audio_converter_get_max_latency (GstAudioConverter * convert)
|
||||||
*/
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
gst_audio_converter_samples (GstAudioConverter * convert,
|
gst_audio_converter_samples (GstAudioConverter * convert,
|
||||||
GstAudioConverterFlags flags, gpointer in[], gsize in_samples,
|
GstAudioConverterFlags flags, gpointer in[], gsize in_frames,
|
||||||
gpointer out[], gsize out_samples)
|
gpointer out[], gsize out_frames)
|
||||||
{
|
{
|
||||||
AudioChain *chain;
|
|
||||||
gpointer *tmp;
|
|
||||||
gint i;
|
|
||||||
gsize produced;
|
|
||||||
|
|
||||||
g_return_val_if_fail (convert != NULL, FALSE);
|
g_return_val_if_fail (convert != NULL, FALSE);
|
||||||
g_return_val_if_fail (in != NULL, FALSE);
|
g_return_val_if_fail (in != NULL, FALSE);
|
||||||
g_return_val_if_fail (out != NULL, FALSE);
|
g_return_val_if_fail (out != NULL, FALSE);
|
||||||
|
|
||||||
in_samples = MIN (in_samples, out_samples);
|
in_frames = MIN (in_frames, out_frames);
|
||||||
|
|
||||||
if (in_samples == 0) {
|
if (in_frames == 0) {
|
||||||
GST_LOG ("skipping empty buffer");
|
GST_LOG ("skipping empty buffer");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
return convert->convert (convert, flags, in, in_frames, out, out_frames);
|
||||||
chain = convert->pack_chain;
|
|
||||||
|
|
||||||
if (convert->passthrough) {
|
|
||||||
gsize bytes = in_samples * chain->inc *
|
|
||||||
(convert->in.bpf / convert->in.channels);
|
|
||||||
|
|
||||||
GST_LOG ("passthrough: %" G_GSIZE_FORMAT " / %" G_GSIZE_FORMAT " bytes",
|
|
||||||
in_samples, bytes);
|
|
||||||
for (i = 0; i < chain->blocks; i++)
|
|
||||||
memcpy (out[i], in[i], bytes);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
convert->in_samples = in_samples;
|
|
||||||
convert->out_data = out;
|
|
||||||
convert->out_samples = out_samples;
|
|
||||||
|
|
||||||
/* get samples to pack */
|
|
||||||
tmp = audio_chain_get_samples (chain, &produced);
|
|
||||||
|
|
||||||
if (!convert->out_default) {
|
|
||||||
GST_LOG ("pack %p, %p %" G_GSIZE_FORMAT, tmp, out, produced);
|
|
||||||
/* and pack if needed */
|
|
||||||
for (i = 0; i < chain->blocks; i++)
|
|
||||||
convert->out.finfo->pack_func (convert->out.finfo, 0, tmp[i], out[i],
|
|
||||||
produced * chain->inc);
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,7 @@ gsize gst_audio_converter_get_max_latency (GstAudioConverter *con
|
||||||
|
|
||||||
gboolean gst_audio_converter_samples (GstAudioConverter * convert,
|
gboolean gst_audio_converter_samples (GstAudioConverter * convert,
|
||||||
GstAudioConverterFlags flags,
|
GstAudioConverterFlags flags,
|
||||||
gpointer in[], gsize in_samples,
|
gpointer in[], gsize in_frames,
|
||||||
gpointer out[], gsize out_samples);
|
gpointer out[], gsize out_frames);
|
||||||
|
|
||||||
#endif /* __GST_AUDIO_CONVERTER_H__ */
|
#endif /* __GST_AUDIO_CONVERTER_H__ */
|
||||||
|
|
Loading…
Reference in a new issue