Skip to content

audio-converter: Fix resampling when there's nothing to output

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.

This is the traceback in which there was an infinite loop:

lldb backtrace
* thread #48, name = 'rtpjitterbuffer0:src'
  * frame #0: 0x00007fff20564029 libsystem_platform.dylib`_platform_memmove$VARIANT$Haswell + 41
    frame #1: 0x0000000100ad8cb8 libgstaudio-1.0.0.dylib`get_sample_bufs(resampler=<unavailable>, need=543779) at audio-resampler.c:1452:7 [opt]
    frame #2: 0x0000000100ad914d libgstaudio-1.0.0.dylib`gst_audio_resampler_resample(resampler=0x00000001021afd80, in=0x0000000101e7b790, in_frames=32, out=0x0000000000000000, out_frames=0) at audio-resampler.c:1773:10 [opt]
    frame #3: 0x0000000100ad0619 libgstaudio-1.0.0.dylib`do_resample(chain=0x00000001030b5990, user_data=0x00000001020d9960) at audio-converter.c:546:3 [opt]
    frame #4: 0x0000000100ad09b3 libgstaudio-1.0.0.dylib`do_quantize [inlined] audio_chain_get_samples(chain=0x00000001030b5990, avail=<unavailable>) at audio-converter.c:257:5 [opt]
    frame #5: 0x0000000100ad0998 libgstaudio-1.0.0.dylib`do_quantize(chain=0x00000001030b5a70, user_data=0x00000001020d9960) at audio-converter.c:581 [opt]
    frame #6: 0x0000000100acf1c3 libgstaudio-1.0.0.dylib`converter_generic [inlined] audio_chain_get_samples(chain=0x00000001030b5a70, avail=<unavailable>) at audio-converter.c:257:5 [opt]
    frame #7: 0x0000000100acf1b0 libgstaudio-1.0.0.dylib`converter_generic(convert=0x00000001020d9960, flags=<unavailable>, in=<unavailable>, in_frames=<unavailable>, out=0x000070001107a620, out_frames=<unavailable>) at audio-converter.c:1275 [opt]
    frame #8: 0x00000001019f5488 libgstaudioresample.dylib`gst_audio_resample_transform at gstaudioresample.c:830:7 [opt]
    frame #9: 0x00000001019f528a libgstaudioresample.dylib`gst_audio_resample_transform(base=<unavailable>, inbuf=<unavailable>, outbuf=<unavailable>) at gstaudioresample.c:937 [opt]
    frame #10: 0x000000010069e91c libgstbase-1.0.0.dylib`default_generate_output(trans=0x00000001011844d0, outbuf=<unavailable>) at gstbasetransform.c:2188:15 [opt]
    frame #11: 0x00000001006a4017 libgstbase-1.0.0.dylib`gst_base_transform_chain(pad=<unavailable>, parent=0x00000001011844d0, buffer=<unavailable>) at gstbasetransform.c:2341:11 [opt]
    frame #12: 0x00000001001946da libgstreamer-1.0.0.dylib`gst_pad_chain_data_unchecked(pad=0x00000001021b3690, type=<unavailable>, data=0x00000001021afc60) at gstpad.c:4447:11 [opt]
    frame #13: 0x0000000100195527 libgstreamer-1.0.0.dylib`gst_pad_push_data(pad=0x00000001021b3440, type=GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_PUSH, data=0x00000001021afc60) at gstpad.c:4711:9 [opt]
    frame #14: 0x000000010019534b libgstreamer-1.0.0.dylib`gst_pad_push(pad=0x00000001021b3440, buffer=0x00000001021afc60) at gstpad.c:4830:9 [opt]
    frame #15: 0x00000001006a3f5a libgstbase-1.0.0.dylib`gst_base_transform_chain(pad=<unavailable>, parent=0x000000010308f0d0, buffer=<unavailable>) at gstbasetransform.c:2377:15 [opt]
    frame #16: 0x00000001001946da libgstreamer-1.0.0.dylib`gst_pad_chain_data_unchecked(pad=0x00000001021b31f0, type=<unavailable>, data=0x00000001021afc60) at gstpad.c:4447:11 [opt]
    frame #17: 0x0000000100195527 libgstreamer-1.0.0.dylib`gst_pad_push_data(pad=0x00000001021bc2f0, type=GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_PUSH, data=0x00000001021afc60) at gstpad.c:4711:9 [opt]
    frame #18: 0x000000010019534b libgstreamer-1.0.0.dylib`gst_pad_push(pad=0x00000001021bc2f0, buffer=0x00000001021afc60) at gstpad.c:4830:9 [opt]
    frame #19: 0x000000010017afc5 libgstreamer-1.0.0.dylib`gst_proxy_pad_chain_default(pad=<unavailable>, parent=<unavailable>, buffer=0x00000001021afc60) at gstghostpad.c:127:9 [opt]
    frame #20: 0x00000001001946da libgstreamer-1.0.0.dylib`gst_pad_chain_data_unchecked(pad=0x00000001011cc550, type=<unavailable>, data=0x00000001021afc60) at gstpad.c:4447:11 [opt]
    frame #21: 0x0000000100195527 libgstreamer-1.0.0.dylib`gst_pad_push_data(pad=0x00000001021b2fa0, type=GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_PUSH, data=0x00000001021afc60) at gstpad.c:4711:9 [opt]
    frame #22: 0x000000010019534b libgstreamer-1.0.0.dylib`gst_pad_push(pad=0x00000001021b2fa0, buffer=0x00000001021afc60) at gstpad.c:4830:9 [opt]
    frame #23: 0x00000001004bec7d libgstrtp-1.0.0.dylib`gst_rtp_base_depayload_do_push at gstrtpbasedepayload.c:1319:12 [opt] [artificial]
    frame #24: 0x00000001004c0ad0 libgstrtp-1.0.0.dylib`gst_rtp_base_depayload_handle_buffer [inlined] gst_rtp_base_depayload_push(filter=0x00000001021c4170, out_buf=0x00000001021afc60) at gstrtpbasedepayload.c:1447:9 [opt]
    frame #25: 0x00000001004c0ac3 libgstrtp-1.0.0.dylib`gst_rtp_base_depayload_handle_buffer(filter=0x00000001021c4170, bclass=<unavailable>, in=0x00000001021af900) at gstrtpbasedepayload.c:801 [opt]
    frame #26: 0x00000001004c04fb libgstrtp-1.0.0.dylib`gst_rtp_base_depayload_chain(pad=<unavailable>, parent=<unavailable>, in=<unavailable>) at gstrtpbasedepayload.c:862:14 [opt] [artificial]
    frame #27: 0x00000001001946da libgstreamer-1.0.0.dylib`gst_pad_chain_data_unchecked(pad=0x00000001021b2410, type=<unavailable>, data=0x00000001021af900) at gstpad.c:4447:11 [opt]
    frame #28: 0x0000000100195527 libgstreamer-1.0.0.dylib`gst_pad_push_data(pad=0x00000001021b21c0, type=GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_PUSH, data=0x00000001021af900) at gstpad.c:4711:9 [opt]
    frame #29: 0x000000010019534b libgstreamer-1.0.0.dylib`gst_pad_push(pad=0x00000001021b21c0, buffer=0x00000001021af900) at gstpad.c:4830:9 [opt]
    frame #30: 0x0000000101966dc2 libgstcoreelements.dylib`gst_type_find_element_chain(pad=<unavailable>, parent=<unavailable>, buffer=<unavailable>) at gsttypefindelement.c:913:14 [opt] [artificial]
    frame #31: 0x00000001001946da libgstreamer-1.0.0.dylib`gst_pad_chain_data_unchecked(pad=0x00000001028c9da0, type=<unavailable>, data=0x00000001021af900) at gstpad.c:4447:11 [opt]
    frame #32: 0x0000000100195527 libgstreamer-1.0.0.dylib`gst_pad_push_data(pad=0x00000001011cc2f0, type=GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_PUSH, data=0x00000001021af900) at gstpad.c:4711:9 [opt]
    frame #33: 0x000000010019534b libgstreamer-1.0.0.dylib`gst_pad_push(pad=0x00000001011cc2f0, buffer=0x00000001021af900) at gstpad.c:4830:9 [opt]
    frame #34: 0x000000010017afc5 libgstreamer-1.0.0.dylib`gst_proxy_pad_chain_default(pad=<unavailable>, parent=<unavailable>, buffer=0x00000001021af900) at gstghostpad.c:127:9 [opt]
    frame #35: 0x00000001001946da libgstreamer-1.0.0.dylib`gst_pad_chain_data_unchecked(pad=0x00000001021438c0, type=<unavailable>, data=0x00000001021af900) at gstpad.c:4447:11 [opt]
    frame #36: 0x0000000100195527 libgstreamer-1.0.0.dylib`gst_pad_push_data(pad=0x00000001011940b0, type=GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_PUSH, data=0x00000001021af900) at gstpad.c:4711:9 [opt]
    frame #37: 0x000000010019534b libgstreamer-1.0.0.dylib`gst_pad_push(pad=0x00000001011940b0, buffer=0x00000001021af900) at gstpad.c:4830:9 [opt]
    frame #38: 0x000000010017afc5 libgstreamer-1.0.0.dylib`gst_proxy_pad_chain_default(pad=<unavailable>, parent=<unavailable>, buffer=0x00000001021af900) at gstghostpad.c:127:9 [opt]
    frame #39: 0x00000001001946da libgstreamer-1.0.0.dylib`gst_pad_chain_data_unchecked(pad=0x000000010213b640, type=<unavailable>, data=0x00000001021af900) at gstpad.c:4447:11 [opt]
    frame #40: 0x0000000100195527 libgstreamer-1.0.0.dylib`gst_pad_push_data(pad=0x0000000102143650, type=GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_PUSH, data=0x00000001021af900) at gstpad.c:4711:9 [opt]
    frame #41: 0x000000010019534b libgstreamer-1.0.0.dylib`gst_pad_push(pad=0x0000000102143650, buffer=0x00000001021af900) at gstpad.c:4830:9 [opt]
    frame #42: 0x000000010017afc5 libgstreamer-1.0.0.dylib`gst_proxy_pad_chain_default(pad=<unavailable>, parent=<unavailable>, buffer=0x00000001021af900) at gstghostpad.c:127:9 [opt]
    frame #43: 0x00000001001946da libgstreamer-1.0.0.dylib`gst_pad_chain_data_unchecked(pad=0x00000001011cc090, type=<unavailable>, data=0x00000001021af900) at gstpad.c:4447:11 [opt]
    frame #44: 0x0000000100195527 libgstreamer-1.0.0.dylib`gst_pad_push_data(pad=0x00000001028c9b50, type=GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_PUSH, data=0x00000001021af900) at gstpad.c:4711:9 [opt]
    frame #45: 0x000000010019534b libgstreamer-1.0.0.dylib`gst_pad_push(pad=0x00000001028c9b50, buffer=0x00000001021af900) at gstpad.c:4830:9 [opt]
    frame #46: 0x0000000107a27f91 libgstrtpmanager.dylib`gst_rtp_pt_demux_chain(pad=0x00000001028c88d0, parent=<unavailable>, buf=<unavailable>) at gstrtpptdemux.c:546:9 [opt]
    frame #47: 0x00000001001946da libgstreamer-1.0.0.dylib`gst_pad_chain_data_unchecked(pad=0x00000001028c88d0, type=<unavailable>, data=0x00000001021af900) at gstpad.c:4447:11 [opt]
    frame #48: 0x0000000100195527 libgstreamer-1.0.0.dylib`gst_pad_push_data(pad=0x0000000102147890, type=GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_PUSH, data=0x00000001021af900) at gstpad.c:4711:9 [opt]
    frame #49: 0x000000010019534b libgstreamer-1.0.0.dylib`gst_pad_push(pad=0x0000000102147890, buffer=0x00000001021af900) at gstpad.c:4830:9 [opt]
    frame #50: 0x0000000107a225c9 libgstrtpmanager.dylib`pop_and_push_next(jitterbuffer=0x00000001028a7d30, seqnum=<unavailable>) at gstrtpjitterbuffer.c:3604:16 [opt]
    frame #51: 0x0000000107a21a4a libgstrtpmanager.dylib`gst_rtp_jitter_buffer_loop [inlined] handle_next_buffer(jitterbuffer=0x00000001028a7d30) at gstrtpjitterbuffer.c:0:9 [opt]
    frame #52: 0x0000000107a21965 libgstrtpmanager.dylib`gst_rtp_jitter_buffer_loop(jitterbuffer=0x00000001028a7d30) at gstrtpjitterbuffer.c:4222 [opt]
    frame #53: 0x00000001001c9d67 libgstreamer-1.0.0.dylib`gst_task_func(task=0x00000001028be710) at gsttask.c:384:5 [opt]
    frame #54: 0x00000001003832e0 libglib-2.0.0.dylib`g_thread_pool_thread_proxy(data=<unavailable>) at gthreadpool.c:354:15 [opt]
    frame #55: 0x00000001003820e2 libglib-2.0.0.dylib`g_thread_proxy(data=0x000000010284c460) at gthread.c:826:20 [opt]
    frame #56: 0x00007fff205218fc libsystem_pthread.dylib`_pthread_start + 224
    frame #57: 0x00007fff2051d443 libsystem_pthread.dylib`thread_start + 15

Edited by Nirbheek Chauhan

Merge request reports