diff --git a/audio/audio_send_stream.cc b/audio/audio_send_stream.cc index e12e24569d..280c915f96 100644 --- a/audio/audio_send_stream.cc +++ b/audio/audio_send_stream.cc @@ -179,6 +179,11 @@ AudioSendStream::~AudioSendStream() { rtp_transport_->DeRegisterPacketFeedbackObserver(this); channel_send_->ResetSenderCongestionControlObjects(); } + // Blocking call to synchronize state with worker queue to ensure that there + // are no pending tasks left that keeps references to audio. + rtc::Event thread_sync_event; + worker_queue_->PostTask([&] { thread_sync_event.Set(); }); + thread_sync_event.Wait(rtc::Event::kForever); } const webrtc::AudioSendStream::Config& AudioSendStream::GetConfig() const { @@ -310,7 +315,7 @@ void AudioSendStream::ConfigureStream( } void AudioSendStream::Start() { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + RTC_DCHECK_RUN_ON(&worker_thread_checker_); if (sending_) { return; } @@ -320,8 +325,13 @@ void AudioSendStream::Start() { TransportSeqNumId(config_))) { rtp_transport_->packet_sender()->SetAccountForAudioPackets(true); rtp_rtcp_module_->SetAsPartOfAllocation(true); - ConfigureBitrateObserver(config_.min_bitrate_bps, config_.max_bitrate_bps, - config_.bitrate_priority); + rtc::Event thread_sync_event; + worker_queue_->PostTask([&] { + RTC_DCHECK_RUN_ON(worker_queue_); + ConfigureBitrateObserver(); + thread_sync_event.Set(); + }); + thread_sync_event.Wait(rtc::Event::kForever); } else { rtp_rtcp_module_->SetAsPartOfAllocation(false); } @@ -505,6 +515,15 @@ void AudioSendStream::UpdateOverheadForEncoder() { channel_send_->CallEncoder([&](AudioEncoder* encoder) { encoder->OnReceivedOverhead(overhead_per_packet_bytes); }); + worker_queue_->PostTask([this, overhead_per_packet_bytes] { + RTC_DCHECK_RUN_ON(worker_queue_); + if (total_packet_overhead_bytes_ != overhead_per_packet_bytes) { + total_packet_overhead_bytes_ = overhead_per_packet_bytes; + if (registered_with_allocator_) { + ConfigureBitrateObserver(); + } + } + }); } size_t AudioSendStream::TestOnlyGetPerPacketOverheadBytes() const { @@ -733,6 +752,7 @@ void AudioSendStream::ReconfigureCNG(AudioSendStream* stream, void AudioSendStream::ReconfigureBitrateObserver( AudioSendStream* stream, const webrtc::AudioSendStream::Config& new_config) { + RTC_DCHECK_RUN_ON(&stream->worker_thread_checker_); // Since the Config's default is for both of these to be -1, this test will // allow us to configure the bitrate observer if the new config has bitrate // limits set, but would only have us call RemoveBitrateObserver if we were @@ -749,9 +769,20 @@ void AudioSendStream::ReconfigureBitrateObserver( new_config.min_bitrate_bps, new_config.max_bitrate_bps, new_config.has_dscp, TransportSeqNumId(new_config))) { stream->rtp_transport_->packet_sender()->SetAccountForAudioPackets(true); - stream->ConfigureBitrateObserver(new_config.min_bitrate_bps, - new_config.max_bitrate_bps, - new_config.bitrate_priority); + rtc::Event thread_sync_event; + stream->worker_queue_->PostTask([&] { + RTC_DCHECK_RUN_ON(stream->worker_queue_); + stream->registered_with_allocator_ = true; + // We may get a callback immediately as the observer is registered, so + // make + // sure the bitrate limits in config_ are up-to-date. + stream->config_.min_bitrate_bps = new_config.min_bitrate_bps; + stream->config_.max_bitrate_bps = new_config.max_bitrate_bps; + stream->config_.bitrate_priority = new_config.bitrate_priority; + stream->ConfigureBitrateObserver(); + thread_sync_event.Set(); + }); + thread_sync_event.Wait(rtc::Event::kForever); stream->rtp_rtcp_module_->SetAsPartOfAllocation(true); } else { stream->rtp_transport_->packet_sender()->SetAccountForAudioPackets(false); @@ -760,34 +791,23 @@ void AudioSendStream::ReconfigureBitrateObserver( } } -void AudioSendStream::ConfigureBitrateObserver(int min_bitrate_bps, - int max_bitrate_bps, - double bitrate_priority) { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - RTC_DCHECK_GE(max_bitrate_bps, min_bitrate_bps); - rtc::Event thread_sync_event; - worker_queue_->PostTask([&] { - // We may get a callback immediately as the observer is registered, so make - // sure the bitrate limits in config_ are up-to-date. - config_.min_bitrate_bps = min_bitrate_bps; - config_.max_bitrate_bps = max_bitrate_bps; - config_.bitrate_priority = bitrate_priority; - // This either updates the current observer or adds a new observer. - bitrate_allocator_->AddObserver( - this, MediaStreamAllocationConfig{ - static_cast(min_bitrate_bps), - static_cast(max_bitrate_bps), 0, - allocation_settings_.DefaultPriorityBitrate().bps(), true, - config_.track_id, bitrate_priority}); - thread_sync_event.Set(); - }); - thread_sync_event.Wait(rtc::Event::kForever); +void AudioSendStream::ConfigureBitrateObserver() { + // This either updates the current observer or adds a new observer. + // TODO(srte): Add overhead compensation here. + bitrate_allocator_->AddObserver( + this, MediaStreamAllocationConfig{ + static_cast(config_.min_bitrate_bps), + static_cast(config_.max_bitrate_bps), 0, + allocation_settings_.DefaultPriorityBitrate().bps(), true, + config_.track_id, config_.bitrate_priority}); } void AudioSendStream::RemoveBitrateObserver() { RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); rtc::Event thread_sync_event; worker_queue_->PostTask([this, &thread_sync_event] { + RTC_DCHECK_RUN_ON(worker_queue_); + registered_with_allocator_ = false; bitrate_allocator_->RemoveObserver(this); thread_sync_event.Set(); }); diff --git a/audio/audio_send_stream.h b/audio/audio_send_stream.h index 54a26c2a6f..afe932127b 100644 --- a/audio/audio_send_stream.h +++ b/audio/audio_send_stream.h @@ -122,9 +122,7 @@ class AudioSendStream final : public webrtc::AudioSendStream, static void ReconfigureBitrateObserver(AudioSendStream* stream, const Config& new_config); - void ConfigureBitrateObserver(int min_bitrate_bps, - int max_bitrate_bps, - double bitrate_priority); + void ConfigureBitrateObserver() RTC_RUN_ON(worker_queue_); void RemoveBitrateObserver(); // Sets per-packet overhead on encoded (for ANA) based on current known values @@ -153,7 +151,8 @@ class AudioSendStream final : public webrtc::AudioSendStream, size_t encoder_num_channels_ = 0; bool sending_ = false; - BitrateAllocatorInterface* const bitrate_allocator_; + BitrateAllocatorInterface* const bitrate_allocator_ + RTC_GUARDED_BY(worker_queue_); RtpTransportControllerSendInterface* const rtp_transport_; rtc::CriticalSection packet_loss_tracker_cs_; @@ -187,6 +186,9 @@ class AudioSendStream final : public webrtc::AudioSendStream, size_t audio_overhead_per_packet_bytes_ RTC_GUARDED_BY(overhead_per_packet_lock_) = 0; + bool registered_with_allocator_ RTC_GUARDED_BY(worker_queue_) = false; + size_t total_packet_overhead_bytes_ RTC_GUARDED_BY(worker_queue_) = 0; + RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AudioSendStream); }; } // namespace internal