audio-converter: Fix resampling when there's nothing to output
authorNirbheek Chauhan <nirbheek@centricular.com>
Mon, 20 Dec 2021 16:07:18 +0000 (21:37 +0530)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Sat, 8 Jan 2022 05:15:30 +0000 (05:15 +0000)
Sometimes we can't output anything because we don't have enough
incoming frames. In that case, the resampler was trying to call
do_quantize() and do_resample() in a loop forever because there would
never be samples to output (so chain->samples would always be NULL).

Fix this by not calling chain->make_func() in a loop -- seems
completely unnecessary since calling it over and over won't change
anything if the make_func() can't output samples.

Also add some checks for the input and / or output being NULL when
doing conversion or quantization. This will happen when we have
nothing to output.

We can't bail early, because we need resampler->samples_avail to be
updated in gst_audio_resampler_resample(), so we must call that and
no-op everything along the way.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1461>

subprojects/gst-plugins-base/gst-libs/gst/audio/audio-converter.c
subprojects/gst-plugins-base/gst-libs/gst/audio/audio-resampler.c

index ed93e31..65396aa 100644 (file)
@@ -253,7 +253,7 @@ audio_chain_get_samples (AudioChain * chain, gsize * avail)
 {
   gpointer *res;
 
-  while (!chain->samples)
+  if (!chain->samples)
     chain->make_func (chain, chain->make_func_data);
 
   res = chain->samples;
@@ -582,7 +582,8 @@ do_quantize (AudioChain * chain, gpointer user_data)
   out = (chain->allow_ip ? in : audio_chain_alloc_samples (chain, num_samples));
   GST_LOG ("quantize %p, %p %" G_GSIZE_FORMAT, in, out, num_samples);
 
-  gst_audio_quantize_samples (convert->quant, in, out, num_samples);
+  if (in && out)
+    gst_audio_quantize_samples (convert->quant, in, out, num_samples);
 
   audio_chain_set_samples (chain, out, num_samples);
 
@@ -1274,7 +1275,7 @@ converter_generic (GstAudioConverter * convert,
   /* get frames to pack */
   tmp = audio_chain_get_samples (chain, &produced);
 
-  if (!convert->out_default) {
+  if (!convert->out_default && tmp && out) {
     GST_LOG ("pack %p, %p %" G_GSIZE_FORMAT, tmp, out, produced);
     /* and pack if needed */
     for (i = 0; i < chain->blocks; i++)
index 5e65da5..c67f860 100644 (file)
@@ -1781,7 +1781,7 @@ gst_audio_resampler_resample (GstAudioResampler * resampler,
   need = resampler->n_taps + resampler->samp_index;
   if (G_UNLIKELY (samples_avail < need || out_frames == 0)) {
     GST_LOG ("not enough samples to start: need %" G_GSIZE_FORMAT ", avail %"
-        G_GSIZE_FORMAT ", out %" G_GSIZE_FORMAT, samples_avail, need,
+        G_GSIZE_FORMAT ", out %" G_GSIZE_FORMAT, need, samples_avail,
         out_frames);
     /* not enough samples to start */
     return;