Reland "Remove AudioReceiveStream::Reconfigure() method."

This reverts commit 8a18e5b3c9.

Reason for revert: Removing the problematic DCHECK.

Original change's description:
> Revert "Remove AudioReceiveStream::Reconfigure() method."
>
> This reverts commit e2561e17e2.
>
> Reason for revert: Speculative revert: breaks an downstream project
>
> Original change's description:
> > Remove AudioReceiveStream::Reconfigure() method.
> >
> > Instead, adding specific setters that are needed at runtime:
> > * SetDepacketizerToDecoderFrameTransformer
> > * SetDecoderMap
> > * SetUseTransportCcAndNackHistory
> >
> > The whole config struct is big and much of the state it holds, needs to
> > be considered const. For that reason the Reconfigure() method is too
> > broad of an interface since it overwrites the whole config struct
> > and doesn't actually handle all the potential config changes that might
> > occur when the config changes.
> >
> > Bug: webrtc:11993
> > Change-Id: Ia5311978f56b2e136781467e44f0d18039f0bb2d
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/221363
> > Reviewed-by: Niels Moller <nisse@webrtc.org>
> > Commit-Queue: Tommi <tommi@webrtc.org>
> > Cr-Commit-Position: refs/heads/master@{#34252}
>
> TBR=saza@webrtc.org,nisse@webrtc.org,tommi@webrtc.org,webrtc-scoped@luci-project-accounts.iam.gserviceaccount.com
>
> Change-Id: I15ca2d8ee5fd612e13dc1f4b3bfb9c885c21dc66
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: webrtc:11993
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/221746
> Commit-Queue: Artem Titov <titovartem@webrtc.org>
> Reviewed-by: Andrey Logvin <landrey@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#34253}

# Not skipping CQ checks because this is a reland.

Bug: webrtc:11993
Change-Id: I0d3bf9abdcdc8d3f9259d014e6074a5e6b6cc73c
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/221747
Reviewed-by: Tommi <tommi@webrtc.org>
Reviewed-by: Artem Titov <titovartem@webrtc.org>
Reviewed-by: Andrey Logvin <landrey@webrtc.org>
Commit-Queue: Tommi <tommi@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34255}
This commit is contained in:
Tommi 2021-06-09 13:46:28 +02:00 committed by WebRTC LUCI CQ
parent c0a95863bd
commit 6eda26c550
9 changed files with 153 additions and 78 deletions

View file

@ -84,8 +84,8 @@ std::unique_ptr<voe::ChannelReceiveInterface> CreateChannelReceive(
config.jitter_buffer_max_packets, config.jitter_buffer_fast_accelerate, config.jitter_buffer_max_packets, config.jitter_buffer_fast_accelerate,
config.jitter_buffer_min_delay_ms, config.jitter_buffer_min_delay_ms,
config.jitter_buffer_enable_rtx_handling, config.decoder_factory, config.jitter_buffer_enable_rtx_handling, config.decoder_factory,
config.codec_pair_id, config.frame_decryptor, config.crypto_options, config.codec_pair_id, std::move(config.frame_decryptor),
std::move(config.frame_transformer)); config.crypto_options, std::move(config.frame_transformer));
} }
} // namespace } // namespace
@ -143,8 +143,8 @@ AudioReceiveStream::AudioReceiveStream(
channel_receive_->SetNACKStatus(config.rtp.nack.rtp_history_ms != 0, channel_receive_->SetNACKStatus(config.rtp.nack.rtp_history_ms != 0,
config.rtp.nack.rtp_history_ms / 20); config.rtp.nack.rtp_history_ms / 20);
channel_receive_->SetReceiveCodecs(config.decoder_map); channel_receive_->SetReceiveCodecs(config.decoder_map);
channel_receive_->SetDepacketizerToDecoderFrameTransformer( // `frame_transformer` and `frame_decryptor` have been given to
config.frame_transformer); // `channel_receive_` already.
} }
AudioReceiveStream::~AudioReceiveStream() { AudioReceiveStream::~AudioReceiveStream() {
@ -168,35 +168,28 @@ void AudioReceiveStream::UnregisterFromTransport() {
rtp_stream_receiver_.reset(); rtp_stream_receiver_.reset();
} }
void AudioReceiveStream::Reconfigure( void AudioReceiveStream::ReconfigureForTesting(
const webrtc::AudioReceiveStream::Config& config) { const webrtc::AudioReceiveStream::Config& config) {
RTC_DCHECK(worker_thread_checker_.IsCurrent()); RTC_DCHECK_RUN_ON(&worker_thread_checker_);
// Configuration parameters which cannot be changed.
RTC_DCHECK(config_.rtp.remote_ssrc == config.rtp.remote_ssrc);
RTC_DCHECK(config_.rtcp_send_transport == config.rtcp_send_transport);
// Decoder factory cannot be changed because it is configured at
// voe::Channel construction time.
RTC_DCHECK(config_.decoder_factory == config.decoder_factory);
// SSRC can't be changed mid-stream. // SSRC can't be changed mid-stream.
RTC_DCHECK_EQ(config_.rtp.local_ssrc, config.rtp.local_ssrc);
RTC_DCHECK_EQ(config_.rtp.remote_ssrc, config.rtp.remote_ssrc); RTC_DCHECK_EQ(config_.rtp.remote_ssrc, config.rtp.remote_ssrc);
RTC_DCHECK_EQ(config_.rtp.local_ssrc, config.rtp.local_ssrc);
// Configuration parameters which cannot be changed.
RTC_DCHECK_EQ(config_.rtcp_send_transport, config.rtcp_send_transport);
// Decoder factory cannot be changed because it is configured at
// voe::Channel construction time.
RTC_DCHECK_EQ(config_.decoder_factory, config.decoder_factory);
// TODO(solenberg): Config NACK history window (which is a packet count), // TODO(solenberg): Config NACK history window (which is a packet count),
// using the actual packet size for the configured codec. // using the actual packet size for the configured codec.
if (config_.rtp.nack.rtp_history_ms != config.rtp.nack.rtp_history_ms) { RTC_DCHECK_EQ(config_.rtp.nack.rtp_history_ms, config.rtp.nack.rtp_history_ms)
channel_receive_->SetNACKStatus(config.rtp.nack.rtp_history_ms != 0, << "Use SetUseTransportCcAndNackHistory";
config.rtp.nack.rtp_history_ms / 20);
}
if (config_.decoder_map != config.decoder_map) {
channel_receive_->SetReceiveCodecs(config.decoder_map);
}
if (config_.frame_transformer != config.frame_transformer) { RTC_DCHECK(config_.decoder_map == config.decoder_map) << "Use SetDecoderMap";
channel_receive_->SetDepacketizerToDecoderFrameTransformer( RTC_DCHECK_EQ(config_.frame_transformer, config.frame_transformer)
config.frame_transformer); << "Use SetDepacketizerToDecoderFrameTransformer";
}
config_ = config; config_ = config;
} }
@ -226,6 +219,33 @@ bool AudioReceiveStream::IsRunning() const {
return playing_; return playing_;
} }
void AudioReceiveStream::SetDepacketizerToDecoderFrameTransformer(
rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer) {
RTC_DCHECK_RUN_ON(&worker_thread_checker_);
channel_receive_->SetDepacketizerToDecoderFrameTransformer(
std::move(frame_transformer));
}
void AudioReceiveStream::SetDecoderMap(
std::map<int, SdpAudioFormat> decoder_map) {
RTC_DCHECK_RUN_ON(&worker_thread_checker_);
config_.decoder_map = std::move(decoder_map);
channel_receive_->SetReceiveCodecs(config_.decoder_map);
}
void AudioReceiveStream::SetUseTransportCcAndNackHistory(bool use_transport_cc,
int history_ms) {
RTC_DCHECK_RUN_ON(&worker_thread_checker_);
RTC_DCHECK_GE(history_ms, 0);
config_.rtp.transport_cc = use_transport_cc;
if (config_.rtp.nack.rtp_history_ms != history_ms) {
config_.rtp.nack.rtp_history_ms = history_ms;
// TODO(solenberg): Config NACK history window (which is a packet count),
// using the actual packet size for the configured codec.
channel_receive_->SetNACKStatus(history_ms != 0, history_ms / 20);
}
}
webrtc::AudioReceiveStream::Stats AudioReceiveStream::GetStats( webrtc::AudioReceiveStream::Stats AudioReceiveStream::GetStats(
bool get_and_clear_legacy_stats) const { bool get_and_clear_legacy_stats) const {
RTC_DCHECK_RUN_ON(&worker_thread_checker_); RTC_DCHECK_RUN_ON(&worker_thread_checker_);

View file

@ -11,6 +11,7 @@
#ifndef AUDIO_AUDIO_RECEIVE_STREAM_H_ #ifndef AUDIO_AUDIO_RECEIVE_STREAM_H_
#define AUDIO_AUDIO_RECEIVE_STREAM_H_ #define AUDIO_AUDIO_RECEIVE_STREAM_H_
#include <map>
#include <memory> #include <memory>
#include <vector> #include <vector>
@ -81,10 +82,15 @@ class AudioReceiveStream final : public webrtc::AudioReceiveStream,
void UnregisterFromTransport(); void UnregisterFromTransport();
// webrtc::AudioReceiveStream implementation. // webrtc::AudioReceiveStream implementation.
void Reconfigure(const webrtc::AudioReceiveStream::Config& config) override;
void Start() override; void Start() override;
void Stop() override; void Stop() override;
bool IsRunning() const override; bool IsRunning() const override;
void SetDepacketizerToDecoderFrameTransformer(
rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer)
override;
void SetDecoderMap(std::map<int, SdpAudioFormat> decoder_map) override;
void SetUseTransportCcAndNackHistory(bool use_transport_cc,
int history_ms) override;
webrtc::AudioReceiveStream::Stats GetStats( webrtc::AudioReceiveStream::Stats GetStats(
bool get_and_clear_legacy_stats) const override; bool get_and_clear_legacy_stats) const override;
@ -111,9 +117,25 @@ class AudioReceiveStream final : public webrtc::AudioReceiveStream,
void AssociateSendStream(AudioSendStream* send_stream); void AssociateSendStream(AudioSendStream* send_stream);
void DeliverRtcp(const uint8_t* packet, size_t length); void DeliverRtcp(const uint8_t* packet, size_t length);
uint32_t local_ssrc() const {
// The local_ssrc member variable of config_ will never change and can be
// considered const.
return config_.rtp.local_ssrc;
}
uint32_t remote_ssrc() const {
// The remote_ssrc member variable of config_ will never change and can be
// considered const.
return config_.rtp.remote_ssrc;
}
const webrtc::AudioReceiveStream::Config& config() const; const webrtc::AudioReceiveStream::Config& config() const;
const AudioSendStream* GetAssociatedSendStreamForTesting() const; const AudioSendStream* GetAssociatedSendStreamForTesting() const;
// TODO(tommi): Remove this method.
void ReconfigureForTesting(const webrtc::AudioReceiveStream::Config& config);
private: private:
AudioState* audio_state() const; AudioState* audio_state() const;

View file

@ -104,8 +104,6 @@ struct ConfigHelper {
.WillRepeatedly(Invoke([](const std::map<int, SdpAudioFormat>& codecs) { .WillRepeatedly(Invoke([](const std::map<int, SdpAudioFormat>& codecs) {
EXPECT_THAT(codecs, ::testing::IsEmpty()); EXPECT_THAT(codecs, ::testing::IsEmpty());
})); }));
EXPECT_CALL(*channel_receive_, SetDepacketizerToDecoderFrameTransformer(_))
.Times(1);
EXPECT_CALL(*channel_receive_, SetSourceTracker(_)); EXPECT_CALL(*channel_receive_, SetSourceTracker(_));
stream_config_.rtp.local_ssrc = kLocalSsrc; stream_config_.rtp.local_ssrc = kLocalSsrc;
@ -328,35 +326,37 @@ TEST(AudioReceiveStreamTest, StreamsShouldBeAddedToMixerOnceOnStart) {
} }
} }
TEST(AudioReceiveStreamTest, ReconfigureWithSameConfig) {
for (bool use_null_audio_processing : {false, true}) {
ConfigHelper helper(use_null_audio_processing);
auto recv_stream = helper.CreateAudioReceiveStream();
recv_stream->Reconfigure(helper.config());
recv_stream->UnregisterFromTransport();
}
}
TEST(AudioReceiveStreamTest, ReconfigureWithUpdatedConfig) { TEST(AudioReceiveStreamTest, ReconfigureWithUpdatedConfig) {
for (bool use_null_audio_processing : {false, true}) { for (bool use_null_audio_processing : {false, true}) {
ConfigHelper helper(use_null_audio_processing); ConfigHelper helper(use_null_audio_processing);
auto recv_stream = helper.CreateAudioReceiveStream(); auto recv_stream = helper.CreateAudioReceiveStream();
auto new_config = helper.config(); auto new_config = helper.config();
new_config.rtp.nack.rtp_history_ms = 300 + 20;
new_config.rtp.extensions.clear(); new_config.rtp.extensions.clear();
new_config.rtp.extensions.push_back( new_config.rtp.extensions.push_back(
RtpExtension(RtpExtension::kAudioLevelUri, kAudioLevelId + 1)); RtpExtension(RtpExtension::kAudioLevelUri, kAudioLevelId + 1));
new_config.rtp.extensions.push_back( new_config.rtp.extensions.push_back(
RtpExtension(RtpExtension::kTransportSequenceNumberUri, RtpExtension(RtpExtension::kTransportSequenceNumberUri,
kTransportSequenceNumberId + 1)); kTransportSequenceNumberId + 1));
new_config.decoder_map.emplace(1, SdpAudioFormat("foo", 8000, 1));
MockChannelReceive& channel_receive = *helper.channel_receive(); MockChannelReceive& channel_receive = *helper.channel_receive();
EXPECT_CALL(channel_receive, SetNACKStatus(true, 15 + 1)).Times(1);
EXPECT_CALL(channel_receive, SetReceiveCodecs(new_config.decoder_map));
recv_stream->Reconfigure(new_config); // TODO(tommi, nisse): This applies new extensions to the internal config,
// but there's nothing that actually verifies that the changes take effect.
// In fact Call manages the extensions separately in Call::ReceiveRtpConfig
// and changing this config value (there seem to be a few copies), doesn't
// affect that logic.
recv_stream->ReconfigureForTesting(new_config);
new_config.decoder_map.emplace(1, SdpAudioFormat("foo", 8000, 1));
EXPECT_CALL(channel_receive, SetReceiveCodecs(new_config.decoder_map));
recv_stream->SetDecoderMap(new_config.decoder_map);
EXPECT_CALL(channel_receive, SetNACKStatus(true, 15 + 1)).Times(1);
recv_stream->SetUseTransportCcAndNackHistory(new_config.rtp.transport_cc,
300 + 20);
recv_stream->UnregisterFromTransport(); recv_stream->UnregisterFromTransport();
} }
} }
@ -371,14 +371,19 @@ TEST(AudioReceiveStreamTest, ReconfigureWithFrameDecryptor) {
rtc::make_ref_counted<MockFrameDecryptor>()); rtc::make_ref_counted<MockFrameDecryptor>());
new_config_0.frame_decryptor = mock_frame_decryptor_0; new_config_0.frame_decryptor = mock_frame_decryptor_0;
recv_stream->Reconfigure(new_config_0); // TODO(tommi): While this changes the internal config value, it doesn't
// actually change what frame_decryptor is used. WebRtcAudioReceiveStream
// recreates the whole instance in order to change this value.
// So, it's not clear if changing this post initialization needs to be
// supported.
recv_stream->ReconfigureForTesting(new_config_0);
auto new_config_1 = helper.config(); auto new_config_1 = helper.config();
rtc::scoped_refptr<FrameDecryptorInterface> mock_frame_decryptor_1( rtc::scoped_refptr<FrameDecryptorInterface> mock_frame_decryptor_1(
rtc::make_ref_counted<MockFrameDecryptor>()); rtc::make_ref_counted<MockFrameDecryptor>());
new_config_1.frame_decryptor = mock_frame_decryptor_1; new_config_1.frame_decryptor = mock_frame_decryptor_1;
new_config_1.crypto_options.sframe.require_frame_encryption = true; new_config_1.crypto_options.sframe.require_frame_encryption = true;
recv_stream->Reconfigure(new_config_1); recv_stream->ReconfigureForTesting(new_config_1);
recv_stream->UnregisterFromTransport(); recv_stream->UnregisterFromTransport();
} }
} }

View file

@ -10,8 +10,6 @@
#include "audio/channel_receive.h" #include "audio/channel_receive.h"
#include <assert.h>
#include <algorithm> #include <algorithm>
#include <map> #include <map>
#include <memory> #include <memory>
@ -563,7 +561,7 @@ ChannelReceive::ChannelReceive(
} }
ChannelReceive::~ChannelReceive() { ChannelReceive::~ChannelReceive() {
RTC_DCHECK(construction_thread_.IsCurrent()); RTC_DCHECK_RUN_ON(&construction_thread_);
// Unregister the module before stopping playout etc, to match the order // Unregister the module before stopping playout etc, to match the order
// things were set up in the ctor. // things were set up in the ctor.
@ -655,7 +653,7 @@ void ChannelReceive::ReceivePacket(const uint8_t* packet,
size_t packet_length, size_t packet_length,
const RTPHeader& header) { const RTPHeader& header) {
const uint8_t* payload = packet + header.headerLength; const uint8_t* payload = packet + header.headerLength;
assert(packet_length >= header.headerLength); RTC_DCHECK_GE(packet_length, header.headerLength);
size_t payload_length = packet_length - header.headerLength; size_t payload_length = packet_length - header.headerLength;
size_t payload_data_length = payload_length - header.paddingLength; size_t payload_data_length = payload_length - header.paddingLength;
@ -870,8 +868,11 @@ void ChannelReceive::SetDepacketizerToDecoderFrameTransformer(
RTC_DCHECK_RUN_ON(&worker_thread_checker_); RTC_DCHECK_RUN_ON(&worker_thread_checker_);
// Depending on when the channel is created, the transformer might be set // Depending on when the channel is created, the transformer might be set
// twice. Don't replace the delegate if it was already initialized. // twice. Don't replace the delegate if it was already initialized.
if (!frame_transformer || frame_transformer_delegate_) if (!frame_transformer || frame_transformer_delegate_) {
RTC_NOTREACHED() << "Not setting the transformer?";
return; return;
}
InitFrameTransformerDelegate(std::move(frame_transformer)); InitFrameTransformerDelegate(std::move(frame_transformer));
} }
@ -1089,8 +1090,8 @@ std::unique_ptr<ChannelReceiveInterface> CreateChannelReceive(
rtcp_send_transport, rtc_event_log, local_ssrc, remote_ssrc, rtcp_send_transport, rtc_event_log, local_ssrc, remote_ssrc,
jitter_buffer_max_packets, jitter_buffer_fast_playout, jitter_buffer_max_packets, jitter_buffer_fast_playout,
jitter_buffer_min_delay_ms, jitter_buffer_enable_rtx_handling, jitter_buffer_min_delay_ms, jitter_buffer_enable_rtx_handling,
decoder_factory, codec_pair_id, frame_decryptor, crypto_options, decoder_factory, codec_pair_id, std::move(frame_decryptor),
std::move(frame_transformer)); crypto_options, std::move(frame_transformer));
} }
} // namespace voe } // namespace voe

View file

@ -157,15 +157,26 @@ class AudioReceiveStream {
// An optional custom frame decryptor that allows the entire frame to be // An optional custom frame decryptor that allows the entire frame to be
// decrypted in whatever way the caller choses. This is not required by // decrypted in whatever way the caller choses. This is not required by
// default. // default.
// TODO(tommi): Remove this member variable from the struct. It's not
// a part of the AudioReceiveStream state but rather a pass through
// variable.
rtc::scoped_refptr<webrtc::FrameDecryptorInterface> frame_decryptor; rtc::scoped_refptr<webrtc::FrameDecryptorInterface> frame_decryptor;
// An optional frame transformer used by insertable streams to transform // An optional frame transformer used by insertable streams to transform
// encoded frames. // encoded frames.
// TODO(tommi): Remove this member variable from the struct. It's not
// a part of the AudioReceiveStream state but rather a pass through
// variable.
rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer; rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer;
}; };
// Reconfigure the stream according to the Configuration. // Methods that support reconfiguring the stream post initialization.
virtual void Reconfigure(const Config& config) = 0; virtual void SetDepacketizerToDecoderFrameTransformer(
rtc::scoped_refptr<webrtc::FrameTransformerInterface>
frame_transformer) = 0;
virtual void SetDecoderMap(std::map<int, SdpAudioFormat> decoder_map) = 0;
virtual void SetUseTransportCcAndNackHistory(bool use_transport_cc,
int history_ms) = 0;
// Starts stream activity. // Starts stream activity.
// When a stream is active, it can receive, process and deliver packets. // When a stream is active, it can receive, process and deliver packets.

View file

@ -935,7 +935,7 @@ webrtc::AudioSendStream* Call::CreateAudioSendStream(
// TODO(bugs.webrtc.org/11993): call AssociateSendStream and // TODO(bugs.webrtc.org/11993): call AssociateSendStream and
// UpdateAggregateNetworkState asynchronously on the network thread. // UpdateAggregateNetworkState asynchronously on the network thread.
for (AudioReceiveStream* stream : audio_receive_streams_) { for (AudioReceiveStream* stream : audio_receive_streams_) {
if (stream->config().rtp.local_ssrc == config.rtp.ssrc) { if (stream->local_ssrc() == config.rtp.ssrc) {
stream->AssociateSendStream(send_stream); stream->AssociateSendStream(send_stream);
} }
} }
@ -963,7 +963,7 @@ void Call::DestroyAudioSendStream(webrtc::AudioSendStream* send_stream) {
// TODO(bugs.webrtc.org/11993): call AssociateSendStream and // TODO(bugs.webrtc.org/11993): call AssociateSendStream and
// UpdateAggregateNetworkState asynchronously on the network thread. // UpdateAggregateNetworkState asynchronously on the network thread.
for (AudioReceiveStream* stream : audio_receive_streams_) { for (AudioReceiveStream* stream : audio_receive_streams_) {
if (stream->config().rtp.local_ssrc == ssrc) { if (stream->local_ssrc() == ssrc) {
stream->AssociateSendStream(nullptr); stream->AssociateSendStream(nullptr);
} }
} }
@ -985,6 +985,7 @@ webrtc::AudioReceiveStream* Call::CreateAudioReceiveStream(
clock_, transport_send_->packet_router(), clock_, transport_send_->packet_router(),
module_process_thread_->process_thread(), config_.neteq_factory, config, module_process_thread_->process_thread(), config_.neteq_factory, config,
config_.audio_state, event_log_); config_.audio_state, event_log_);
audio_receive_streams_.insert(receive_stream);
// TODO(bugs.webrtc.org/11993): Make the registration on the network thread // TODO(bugs.webrtc.org/11993): Make the registration on the network thread
// (asynchronously). The registration and `audio_receiver_controller_` need // (asynchronously). The registration and `audio_receiver_controller_` need
@ -995,7 +996,6 @@ webrtc::AudioReceiveStream* Call::CreateAudioReceiveStream(
// We could possibly set up the audio_receiver_controller_ association up // We could possibly set up the audio_receiver_controller_ association up
// as part of the async setup. // as part of the async setup.
receive_rtp_config_.emplace(config.rtp.remote_ssrc, ReceiveRtpConfig(config)); receive_rtp_config_.emplace(config.rtp.remote_ssrc, ReceiveRtpConfig(config));
audio_receive_streams_.insert(receive_stream);
ConfigureSync(config.sync_group); ConfigureSync(config.sync_group);
@ -1016,22 +1016,24 @@ void Call::DestroyAudioReceiveStream(
webrtc::internal::AudioReceiveStream* audio_receive_stream = webrtc::internal::AudioReceiveStream* audio_receive_stream =
static_cast<webrtc::internal::AudioReceiveStream*>(receive_stream); static_cast<webrtc::internal::AudioReceiveStream*>(receive_stream);
const AudioReceiveStream::Config& config = audio_receive_stream->config();
uint32_t ssrc = config.rtp.remote_ssrc;
receive_side_cc_.GetRemoteBitrateEstimator(UseSendSideBwe(config))
->RemoveStream(ssrc);
// TODO(bugs.webrtc.org/11993): Access the map, rtp config, call ConfigureSync // TODO(bugs.webrtc.org/11993): Access the map, rtp config, call ConfigureSync
// and UpdateAggregateNetworkState on the network thread. The call to // and UpdateAggregateNetworkState on the network thread. The call to
// `UnregisterFromTransport` should also happen on the network thread. // `UnregisterFromTransport` should also happen on the network thread.
audio_receive_stream->UnregisterFromTransport(); audio_receive_stream->UnregisterFromTransport();
audio_receive_streams_.erase(audio_receive_stream);
const std::string& sync_group = audio_receive_stream->config().sync_group;
const auto it = sync_stream_mapping_.find(sync_group); uint32_t ssrc = audio_receive_stream->remote_ssrc();
const AudioReceiveStream::Config& config = audio_receive_stream->config();
receive_side_cc_
.GetRemoteBitrateEstimator(
UseSendSideBwe(config.rtp.extensions, config.rtp.transport_cc))
->RemoveStream(ssrc);
audio_receive_streams_.erase(audio_receive_stream);
const auto it = sync_stream_mapping_.find(config.sync_group);
if (it != sync_stream_mapping_.end() && it->second == audio_receive_stream) { if (it != sync_stream_mapping_.end() && it->second == audio_receive_stream) {
sync_stream_mapping_.erase(it); sync_stream_mapping_.erase(it);
ConfigureSync(sync_group); ConfigureSync(config.sync_group);
} }
receive_rtp_config_.erase(ssrc); receive_rtp_config_.erase(ssrc);
@ -1444,6 +1446,7 @@ void Call::OnAllocationLimitsChanged(BitrateAllocationLimits limits) {
std::memory_order_relaxed); std::memory_order_relaxed);
} }
// RTC_RUN_ON(worker_thread_)
void Call::ConfigureSync(const std::string& sync_group) { void Call::ConfigureSync(const std::string& sync_group) {
// TODO(bugs.webrtc.org/11993): Expect to be called on the network thread. // TODO(bugs.webrtc.org/11993): Expect to be called on the network thread.
// Set sync only if there was no previous one. // Set sync only if there was no previous one.

View file

@ -96,9 +96,21 @@ bool FakeAudioReceiveStream::DeliverRtp(const uint8_t* packet,
return true; return true;
} }
void FakeAudioReceiveStream::Reconfigure( void FakeAudioReceiveStream::SetDepacketizerToDecoderFrameTransformer(
const webrtc::AudioReceiveStream::Config& config) { rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer) {
config_ = config; config_.frame_transformer = std::move(frame_transformer);
}
void FakeAudioReceiveStream::SetDecoderMap(
std::map<int, webrtc::SdpAudioFormat> decoder_map) {
config_.decoder_map = std::move(decoder_map);
}
void FakeAudioReceiveStream::SetUseTransportCcAndNackHistory(
bool use_transport_cc,
int history_ms) {
config_.rtp.transport_cc = use_transport_cc;
config_.rtp.nack.rtp_history_ms = history_ms;
} }
webrtc::AudioReceiveStream::Stats FakeAudioReceiveStream::GetStats( webrtc::AudioReceiveStream::Stats FakeAudioReceiveStream::GetStats(

View file

@ -102,10 +102,16 @@ class FakeAudioReceiveStream final : public webrtc::AudioReceiveStream {
private: private:
// webrtc::AudioReceiveStream implementation. // webrtc::AudioReceiveStream implementation.
void Reconfigure(const webrtc::AudioReceiveStream::Config& config) override;
void Start() override { started_ = true; } void Start() override { started_ = true; }
void Stop() override { started_ = false; } void Stop() override { started_ = false; }
bool IsRunning() const override { return started_; } bool IsRunning() const override { return started_; }
void SetDepacketizerToDecoderFrameTransformer(
rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer)
override;
void SetDecoderMap(
std::map<int, webrtc::SdpAudioFormat> decoder_map) override;
void SetUseTransportCcAndNackHistory(bool use_transport_cc,
int history_ms) override;
webrtc::AudioReceiveStream::Stats GetStats( webrtc::AudioReceiveStream::Stats GetStats(
bool get_and_clear_legacy_stats) const override; bool get_and_clear_legacy_stats) const override;

View file

@ -1234,7 +1234,8 @@ class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream {
RTC_DCHECK_RUN_ON(&worker_thread_checker_); RTC_DCHECK_RUN_ON(&worker_thread_checker_);
config_.rtp.transport_cc = use_transport_cc; config_.rtp.transport_cc = use_transport_cc;
config_.rtp.nack.rtp_history_ms = use_nack ? kNackRtpHistoryMs : 0; config_.rtp.nack.rtp_history_ms = use_nack ? kNackRtpHistoryMs : 0;
ReconfigureAudioReceiveStream(); stream_->SetUseTransportCcAndNackHistory(use_transport_cc,
config_.rtp.nack.rtp_history_ms);
} }
void SetRtpExtensionsAndRecreateStream( void SetRtpExtensionsAndRecreateStream(
@ -1248,7 +1249,7 @@ class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream {
void SetDecoderMap(const std::map<int, webrtc::SdpAudioFormat>& decoder_map) { void SetDecoderMap(const std::map<int, webrtc::SdpAudioFormat>& decoder_map) {
RTC_DCHECK_RUN_ON(&worker_thread_checker_); RTC_DCHECK_RUN_ON(&worker_thread_checker_);
config_.decoder_map = decoder_map; config_.decoder_map = decoder_map;
ReconfigureAudioReceiveStream(); stream_->SetDecoderMap(decoder_map);
} }
void MaybeRecreateAudioReceiveStream( void MaybeRecreateAudioReceiveStream(
@ -1339,8 +1340,8 @@ class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream {
void SetDepacketizerToDecoderFrameTransformer( void SetDepacketizerToDecoderFrameTransformer(
rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer) { rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer) {
RTC_DCHECK_RUN_ON(&worker_thread_checker_); RTC_DCHECK_RUN_ON(&worker_thread_checker_);
stream_->SetDepacketizerToDecoderFrameTransformer(frame_transformer);
config_.frame_transformer = std::move(frame_transformer); config_.frame_transformer = std::move(frame_transformer);
ReconfigureAudioReceiveStream();
} }
private: private:
@ -1359,12 +1360,6 @@ class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream {
stream_->SetSink(raw_audio_sink_.get()); stream_->SetSink(raw_audio_sink_.get());
} }
void ReconfigureAudioReceiveStream() {
RTC_DCHECK_RUN_ON(&worker_thread_checker_);
RTC_DCHECK(stream_);
stream_->Reconfigure(config_);
}
webrtc::SequenceChecker worker_thread_checker_; webrtc::SequenceChecker worker_thread_checker_;
webrtc::Call* call_ = nullptr; webrtc::Call* call_ = nullptr;
webrtc::AudioReceiveStream::Config config_; webrtc::AudioReceiveStream::Config config_;