diff options
author | John Thacker <johnthacker@gmail.com> | 2023-06-26 08:39:56 -0400 |
---|---|---|
committer | John Thacker <johnthacker@gmail.com> | 2023-06-27 11:32:14 +0000 |
commit | d2d246d3d55041a6151e254dca172a758f72be37 (patch) | |
tree | c625885c0dceead367ec081d195610ab75722cf9 /ui/qt/rtp_audio_stream.cpp | |
parent | 7335260e741406ca37b855a9bc30f8ed76391925 (diff) |
RTP Player: Init resampler if it doesn't exist yet
Check if the resampler has been initialized before trying to resample.
If input rate of RTP stream changes more than once, second and later
changes was using transcoder with incorrect input rate.
The issue was found during solving of #19170.
Changes:
- input rate is remembered when resampler is initiated
- resampler is reinitiated every time input rate changes
- as consequence it makes no sense to keep resampler as instance
property so it was moved as local variable of decodeAudio()
Fix #19170
Diffstat (limited to 'ui/qt/rtp_audio_stream.cpp')
-rw-r--r-- | ui/qt/rtp_audio_stream.cpp | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/ui/qt/rtp_audio_stream.cpp b/ui/qt/rtp_audio_stream.cpp index 6f93c12403..a63815b9ae 100644 --- a/ui/qt/rtp_audio_stream.cpp +++ b/ui/qt/rtp_audio_stream.cpp @@ -53,7 +53,6 @@ RtpAudioStream::RtpAudioStream(QObject *parent, rtpstream_id_t *id, bool stereo_ , first_sample_rate_(0) , audio_out_rate_(0) , audio_requested_out_rate_(0) - , audio_resampler_(0) , max_sample_val_(1) , max_sample_val_used_(1) , color_(0) @@ -92,7 +91,6 @@ RtpAudioStream::~RtpAudioStream() g_free(rtp_packet); } g_hash_table_destroy(decoders_hash_); - if (audio_resampler_) speex_resampler_destroy(audio_resampler_); speex_resampler_destroy(visual_resampler_); rtpstream_info_free_data(&rtpstream_); rtpstream_id_free(&id_); @@ -189,9 +187,6 @@ void RtpAudioStream::decode(QAudioDeviceInfo out_device) { if (rtp_packets_.size() < 1) return; - if (audio_resampler_) { - speex_resampler_reset_mem(audio_resampler_); - } audio_file_->setFrameWriteStage(); decodeAudio(out_device); @@ -203,7 +198,6 @@ void RtpAudioStream::decode(QAudioDeviceInfo out_device) audio_file_->setDataReadStage(); } -// Side effect: it creates and initiates resampler if needed #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) quint32 RtpAudioStream::calculateAudioOutRate(QAudioDevice out_device, unsigned int sample_rate, unsigned int requested_out_rate) #else @@ -241,15 +235,11 @@ quint32 RtpAudioStream::calculateAudioOutRate(QAudioDeviceInfo out_device, unsig #else out_rate = out_device.nearestFormat(format).sampleRate(); #endif - audio_resampler_ = speex_resampler_init(1, sample_rate, out_rate, 10, NULL); - RTP_STREAM_DEBUG("Started resampling from %u to (out) %u Hz.", sample_rate, out_rate); } else { if ((requested_out_rate != 0) && (requested_out_rate != sample_rate) ) { out_rate = requested_out_rate; - audio_resampler_ = speex_resampler_init(1, sample_rate, out_rate, 10, NULL); - RTP_STREAM_DEBUG("Started resampling from %u to (out) %u Hz.", sample_rate, out_rate); } else { out_rate = sample_rate; } @@ -285,6 +275,8 @@ void RtpAudioStream::decodeAudio(QAudioDeviceInfo out_device) guint64 start_timestamp = 0; size_t decoded_bytes_prev = 0; + unsigned int audio_resampler_input_rate = 0; + struct SpeexResamplerState_ *audio_resampler = NULL; for (int cur_packet = 0; cur_packet < rtp_packets_.size(); cur_packet++) { SAMPLE *decode_buff = NULL; @@ -439,7 +431,20 @@ void RtpAudioStream::decodeAudio(QAudioDeviceInfo out_device) spx_uint32_t out_len = (spx_uint32_t) ((guint64)in_len * audio_out_rate_ / sample_rate); resample_buff = resizeBufferIfNeeded(resample_buff, &resample_buff_bytes, out_len * SAMPLE_BYTES); - speex_resampler_process_int(audio_resampler_, 0, decode_buff, &in_len, resample_buff, &out_len); + if (audio_resampler && + sample_rate != audio_resampler_input_rate + ) { + // Clear old resampler because input rate changed + speex_resampler_destroy(audio_resampler); + audio_resampler_input_rate = 0; + audio_resampler = NULL; + } + if (!audio_resampler) { + audio_resampler_input_rate = sample_rate; + audio_resampler = speex_resampler_init(1, sample_rate, audio_out_rate_, 10, NULL); + RTP_STREAM_DEBUG("Started resampling from %u to (out) %u Hz.", sample_rate, audio_out_rate_); + } + speex_resampler_process_int(audio_resampler, 0, decode_buff, &in_len, resample_buff, &out_len); write_buff = (char *) resample_buff; write_bytes = out_len * SAMPLE_BYTES; @@ -455,6 +460,8 @@ void RtpAudioStream::decodeAudio(QAudioDeviceInfo out_device) g_free(decode_buff); } g_free(resample_buff); + + if (audio_resampler) speex_resampler_destroy(audio_resampler); } // We preallocate buffer, 320 samples is enough for most scenarios |