No silence frame is fed to the resampler when the duplex stream runs on a
Bluetooth device when the device is switching from A2DP to HFP/HSP profile,
which leads to hitting an assertion [1] within cubeb resampler.
When the duplex cubeb stream runs on a Bluetooth device and the device
is switching from A2DP to HFP/HSP profile, the input_buffer_manager
has no input data to be appended [2] in audiounit_input_callback. And
then when audiounit_output_callback runs, the buffered_input_frames
is 0 but input_frames_needed is a positive integer greater than 0.
However, the input_frames in this case is equal to
buffered_input_frames in current implementation since neither
switching_device nor frames_read > 0 is true. This is wrong. The
input_frames should be input_frames_needed rather than 0.
When the above case happens in the first audiounit_output_callback
call, it makes the cubeb resampler hit the assertion in [1]. The data_
[3] in the internal_input_buffer [4] is nullptr when the resampler
is created (passthrough_resampler in my case). If the length in the
first push* [5] is 0, then the reserve [6] won't be called so data_
remains nullptr, which makes the resampler hit the assertion in [1]
We should append the silence frames to the resampler in this case not
only to avoid hitting the assertion but also to append the silence
frames correctly when we need.
This fixes BMO 1721496
No silence frame is fed to the resampler when the duplex stream runs on a Bluetooth device when the device is switching from A2DP to HFP/HSP profile, which leads to hitting an assertion [1] within cubeb resampler.
When the duplex cubeb stream runs on a Bluetooth device and the device is switching from A2DP to HFP/HSP profile, the
input_buffer_manager
has no input data to be appended [2] inaudiounit_input_callback
. And then whenaudiounit_output_callback
runs, thebuffered_input_frames
is0
butinput_frames_needed
is a positive integer greater than0
. However, theinput_frames
in this case is equal tobuffered_input_frames
in current implementation since neitherswitching_device
norframes_read > 0
istrue
. This is wrong. Theinput_frames
should beinput_frames_needed
rather than0
.When the above case happens in the first
audiounit_output_callback
call, it makes the cubeb resampler hit the assertion in [1]. Thedata_
[3] in theinternal_input_buffer
[4] isnullptr
when the resampler is created (passthrough_resampler
in my case). If thelength
in the firstpush*
[5] is0
, then thereserve
[6] won't be called sodata_
remainsnullptr
, which makes the resampler hit the assertion in [1]We should append the silence frames to the resampler in this case not only to avoid hitting the assertion but also to append the silence frames correctly when we need.
[1] https://github.com/mozilla/cubeb/blob/b608f590249d5821c91b3ea83e394f0fd839f5b9/src/cubeb_utils.h#L31 [2] https://github.com/mozilla/cubeb-coreaudio-rs/blob/8c9bb1e74507b1fcac849c91fc6eb6f86d44692d/src/backend/mod.rs#L409 [3] https://github.com/mozilla/cubeb/blob/b608f590249d5821c91b3ea83e394f0fd839f5b9/src/cubeb_utils.h#L115 [4] https://github.com/mozilla/cubeb/blob/b608f590249d5821c91b3ea83e394f0fd839f5b9/src/cubeb_resampler_internal.h#L112 [5] https://github.com/mozilla/cubeb/blob/b608f590249d5821c91b3ea83e394f0fd839f5b9/src/cubeb_utils.h#L196 [6] https://github.com/mozilla/cubeb/blob/b608f590249d5821c91b3ea83e394f0fd839f5b9/src/cubeb_utils.h#L172