audio-converter: handle NULL input

Allow NULL as input to mean silence samples.
This commit is contained in:
Wim Taymans 2016-01-26 16:36:41 +01:00
parent 6050509b65
commit 2d971df593

View file

@ -154,6 +154,7 @@ struct _AudioChain
gpointer make_func_data; gpointer make_func_data;
GDestroyNotify make_func_notify; GDestroyNotify make_func_notify;
const GstAudioFormatInfo *finfo;
gint stride; gint stride;
gint inc; gint inc;
gint blocks; gint blocks;
@ -175,7 +176,6 @@ static AudioChain *
audio_chain_new (AudioChain * prev, GstAudioConverter * convert) audio_chain_new (AudioChain * prev, GstAudioConverter * convert)
{ {
AudioChain *chain; AudioChain *chain;
const GstAudioFormatInfo *finfo;
chain = g_slice_new0 (AudioChain); chain = g_slice_new0 (AudioChain);
chain->prev = prev; chain->prev = prev;
@ -187,8 +187,8 @@ audio_chain_new (AudioChain * prev, GstAudioConverter * convert)
chain->inc = convert->current_channels; chain->inc = convert->current_channels;
chain->blocks = 1; chain->blocks = 1;
} }
finfo = gst_audio_format_get_info (convert->current_format); chain->finfo = gst_audio_format_get_info (convert->current_format);
chain->stride = (finfo->width * chain->inc) / 8; chain->stride = (chain->finfo->width * chain->inc) / 8;
return chain; return chain;
} }
@ -425,6 +425,7 @@ do_unpack (AudioChain * chain, gpointer user_data)
GST_LOG ("unpack to tmp %p, %" G_GSIZE_FORMAT, tmp, num_samples); GST_LOG ("unpack to tmp %p, %" G_GSIZE_FORMAT, tmp, num_samples);
} }
if (convert->in_data) {
for (i = 0; i < chain->blocks; i++) { for (i = 0; i < chain->blocks; i++) {
GST_LOG ("unpack %p, %p, %" G_GSIZE_FORMAT, tmp[i], convert->in_data[i], GST_LOG ("unpack %p, %p, %" G_GSIZE_FORMAT, tmp[i], convert->in_data[i],
num_samples); num_samples);
@ -432,6 +433,12 @@ do_unpack (AudioChain * chain, gpointer user_data)
GST_AUDIO_PACK_FLAG_TRUNCATE_RANGE, tmp[i], convert->in_data[i], GST_AUDIO_PACK_FLAG_TRUNCATE_RANGE, tmp[i], convert->in_data[i],
num_samples * chain->inc); num_samples * chain->inc);
} }
} else {
for (i = 0; i < chain->blocks; i++) {
gst_audio_format_fill_silence (chain->finfo, tmp[i],
num_samples * chain->inc);
}
}
} else { } else {
tmp = convert->in_data; tmp = convert->in_data;
GST_LOG ("get in samples %p", tmp); GST_LOG ("get in samples %p", tmp);
@ -531,7 +538,6 @@ chain_unpack (GstAudioConverter * convert)
AudioChain *prev; AudioChain *prev;
GstAudioInfo *in = &convert->in; GstAudioInfo *in = &convert->in;
GstAudioInfo *out = &convert->out; GstAudioInfo *out = &convert->out;
const GstAudioFormatInfo *fup;
gboolean same_format; gboolean same_format;
same_format = in->finfo->format == out->finfo->format; same_format = in->finfo->format == out->finfo->format;
@ -552,10 +558,8 @@ chain_unpack (GstAudioConverter * convert)
gst_audio_format_to_string (in->finfo->format), gst_audio_format_to_string (in->finfo->format),
gst_audio_format_to_string (convert->current_format)); gst_audio_format_to_string (convert->current_format));
fup = gst_audio_format_get_info (convert->current_format);
prev = convert->unpack_chain = audio_chain_new (NULL, convert); prev = convert->unpack_chain = audio_chain_new (NULL, convert);
prev->allow_ip = fup->width <= in->finfo->width; prev->allow_ip = prev->finfo->width <= in->finfo->width;
prev->pass_alloc = FALSE; prev->pass_alloc = FALSE;
audio_chain_set_make_func (prev, do_unpack, convert, NULL); audio_chain_set_make_func (prev, do_unpack, convert, NULL);
@ -747,18 +751,27 @@ converter_passthrough (GstAudioConverter * convert,
gpointer out[], gsize out_frames) gpointer out[], gsize out_frames)
{ {
gint i; gint i;
gsize bytes;
AudioChain *chain; AudioChain *chain;
gsize samples;
chain = convert->pack_chain; chain = convert->pack_chain;
bytes = in_frames * chain->inc * (convert->in.bpf / convert->in.channels); samples = in_frames * chain->inc;
GST_LOG ("passthrough: %" G_GSIZE_FORMAT " / %" G_GSIZE_FORMAT " bytes", GST_LOG ("passthrough: %" G_GSIZE_FORMAT " / %" G_GSIZE_FORMAT " samples",
in_frames, bytes); in_frames, samples);
if (in) {
gsize bytes;
bytes = samples * (convert->in.bpf / convert->in.channels);
for (i = 0; i < chain->blocks; i++) for (i = 0; i < chain->blocks; i++)
memcpy (out[i], in[i], bytes); memcpy (out[i], in[i], bytes);
} else {
for (i = 0; i < chain->blocks; i++)
gst_audio_format_fill_silence (convert->in.finfo, out[i], samples);
}
return TRUE; return TRUE;
} }
@ -977,6 +990,9 @@ gst_audio_converter_get_max_latency (GstAudioConverter * convert)
* If non-interleaved samples are used, @in and @out must point to an * If non-interleaved samples are used, @in and @out must point to an
* array with pointers to memory blocks, one for each channel. * array with pointers to memory blocks, one for each channel.
* *
* @in may be %NULL, in which case @in_frames of silence samples are processed
* by the converter.
*
* This function always produces @out_frames of output and consumes @in_frames of * This function always produces @out_frames of output and consumes @in_frames of
* input. Use gst_audio_converter_get_out_frames() and * input. Use gst_audio_converter_get_out_frames() and
* gst_audio_converter_get_in_frames() to make sure @in_frames and @out_frames * gst_audio_converter_get_in_frames() to make sure @in_frames and @out_frames
@ -990,7 +1006,6 @@ gst_audio_converter_samples (GstAudioConverter * convert,
gpointer out[], gsize out_frames) gpointer out[], gsize out_frames)
{ {
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 (out != NULL, FALSE); g_return_val_if_fail (out != NULL, FALSE);
in_frames = MIN (in_frames, out_frames); in_frames = MIN (in_frames, out_frames);