audio-resampler: Fix segfault when we can't output any frames
authorNirbheek Chauhan <nirbheek@centricular.com>
Fri, 12 Nov 2021 12:56:58 +0000 (18:26 +0530)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Fri, 12 Nov 2021 16:12:27 +0000 (16:12 +0000)
Sometimes the resampler has enough space to store all the incoming
samples without outputting anything. When this happens,
gst_audio_resampler_get_out_frames() returns 0.

In that case, the resampler should consume samples and just return.
Otherwise, we get a segfault when gst_audio_resampler_resample() tries
to resample into a NULL 'out' pointer.

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

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

index 69c14c7..5e65da5 100644 (file)
@@ -1662,12 +1662,16 @@ gst_audio_resampler_get_out_frames (GstAudioResampler * resampler,
   GST_LOG ("need %d = %d + %d + %d, avail %d = %d + %d", (gint) need,
       resampler->n_taps, resampler->samp_index, resampler->skip,
       (gint) avail, (gint) resampler->samples_avail, (gint) in_frames);
-  if (avail < need)
+  if (avail < need) {
+    GST_LOG ("avail %d < need %d", (int) avail, (int) need);
     return 0;
+  }
 
   out = (avail - need) * resampler->out_rate;
-  if (out < resampler->samp_phase)
+  if (out < resampler->samp_phase) {
+    GST_LOG ("out %d < samp_phase %d", (int) out, (int) resampler->samp_phase);
     return 0;
+  }
 
   out = ((out - resampler->samp_phase) / resampler->in_rate) + 1;
   GST_LOG ("out %d = ((%d * %d - %d) / %d) + 1", (gint) out,
@@ -1775,7 +1779,10 @@ gst_audio_resampler_resample (GstAudioResampler * resampler,
   resampler->samples_avail = samples_avail += in_frames;
 
   need = resampler->n_taps + resampler->samp_index;
-  if (G_UNLIKELY (samples_avail < need)) {
+  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,
+        out_frames);
     /* not enough samples to start */
     return;
   }