From e0d4637bea1c5914de73036006c2e4a34e297791 Mon Sep 17 00:00:00 2001 From: skvlad Date: Thu, 7 Apr 2016 22:59:22 -0700 Subject: [PATCH] Allow applications to control audio send bitrate through RtpParameters. This change builds on top of the refactoring in https://codereview.webrtc.org/1841083008/, and enables WebRTC client applications to control the max send bitrate for every audio stream through RtpParameters. The AudioSendStream now stores the last codec spec, and whenever a global or per-stream bitrate limit changes, the effective limit (smaller of the two) is recomputed and the codec is reconfigured with that bitrate. TBR=pthatcher BUG= Review URL: https://codereview.webrtc.org/1847353004 Cr-Commit-Position: refs/heads/master@{#12290} --- webrtc/api/webrtcsession_unittest.cc | 27 ++-- webrtc/media/base/mediachannel.h | 3 + webrtc/media/engine/webrtcvoiceengine.cc | 136 +++++++++++++----- webrtc/media/engine/webrtcvoiceengine.h | 14 +- .../engine/webrtcvoiceengine_unittest.cc | 132 +++++++++++++++++ webrtc/pc/channel.cc | 8 +- webrtc/pc/channel_unittest.cc | 20 +-- 7 files changed, 271 insertions(+), 69 deletions(-) diff --git a/webrtc/api/webrtcsession_unittest.cc b/webrtc/api/webrtcsession_unittest.cc index 18c1a95116..f4b41d355a 100644 --- a/webrtc/api/webrtcsession_unittest.cc +++ b/webrtc/api/webrtcsession_unittest.cc @@ -3385,23 +3385,32 @@ TEST_F(WebRtcSessionTest, SetAudioPlayout) { EXPECT_EQ(1, volume); } -TEST_F(WebRtcSessionTest, AudioMaxSendBitrateNotImplemented) { - // This test verifies that RtpParameters for audio RtpSenders cannot be - // changed. - // TODO(skvlad): Update the test after adding support for bitrate limiting in - // WebRtcAudioSendStream. - +TEST_F(WebRtcSessionTest, SetAudioMaxSendBitrate) { Init(); SendAudioVideoStream1(); CreateAndSetRemoteOfferAndLocalAnswer(); cricket::FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0); ASSERT_TRUE(channel != NULL); uint32_t send_ssrc = channel->send_streams()[0].first_ssrc(); + EXPECT_EQ(-1, channel->max_bps()); webrtc::RtpParameters params = session_->GetAudioRtpParameters(send_ssrc); + EXPECT_EQ(1, params.encodings.size()); + EXPECT_EQ(-1, params.encodings[0].max_bitrate_bps); + params.encodings[0].max_bitrate_bps = 1000; + EXPECT_TRUE(session_->SetAudioRtpParameters(send_ssrc, params)); - EXPECT_EQ(0, params.encodings.size()); - params.encodings.push_back(webrtc::RtpEncodingParameters()); - EXPECT_FALSE(session_->SetAudioRtpParameters(send_ssrc, params)); + // Read back the parameters and verify they have been changed. + params = session_->GetAudioRtpParameters(send_ssrc); + EXPECT_EQ(1, params.encodings.size()); + EXPECT_EQ(1000, params.encodings[0].max_bitrate_bps); + + // Verify that the audio channel received the new parameters. + params = channel->GetRtpParameters(send_ssrc); + EXPECT_EQ(1, params.encodings.size()); + EXPECT_EQ(1000, params.encodings[0].max_bitrate_bps); + + // Verify that the global bitrate limit has not been changed. + EXPECT_EQ(-1, channel->max_bps()); } TEST_F(WebRtcSessionTest, SetAudioSend) { diff --git a/webrtc/media/base/mediachannel.h b/webrtc/media/base/mediachannel.h index 424572de2f..4166a60dd3 100644 --- a/webrtc/media/base/mediachannel.h +++ b/webrtc/media/base/mediachannel.h @@ -904,6 +904,9 @@ class VoiceMediaChannel : public MediaChannel { virtual ~VoiceMediaChannel() {} virtual bool SetSendParameters(const AudioSendParameters& params) = 0; virtual bool SetRecvParameters(const AudioRecvParameters& params) = 0; + virtual webrtc::RtpParameters GetRtpParameters(uint32_t ssrc) const = 0; + virtual bool SetRtpParameters(uint32_t ssrc, + const webrtc::RtpParameters& parameters) = 0; // Starts or stops playout of received audio. virtual bool SetPlayout(bool playout) = 0; // Starts or stops sending (and potentially capture) of local audio. diff --git a/webrtc/media/engine/webrtcvoiceengine.cc b/webrtc/media/engine/webrtcvoiceengine.cc index 21094fde4d..97e955f51e 100644 --- a/webrtc/media/engine/webrtcvoiceengine.cc +++ b/webrtc/media/engine/webrtcvoiceengine.cc @@ -1081,13 +1081,16 @@ int WebRtcVoiceEngine::CreateVoEChannel() { class WebRtcVoiceMediaChannel::WebRtcAudioSendStream : public AudioSource::Sink { public: - WebRtcAudioSendStream(int ch, webrtc::AudioTransport* voe_audio_transport, - uint32_t ssrc, const std::string& c_name, + WebRtcAudioSendStream(int ch, + webrtc::AudioTransport* voe_audio_transport, + uint32_t ssrc, + const std::string& c_name, const std::vector& extensions, webrtc::Call* call) : voe_audio_transport_(voe_audio_transport), call_(call), - config_(nullptr) { + config_(nullptr), + rtp_parameters_(CreateRtpParametersWithOneEncoding()) { RTC_DCHECK_GE(ch, 0); // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore: // RTC_DCHECK(voe_audio_transport); @@ -1198,6 +1201,15 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream return config_.voe_channel_id; } + const webrtc::RtpParameters& rtp_parameters() const { + return rtp_parameters_; + } + + void set_rtp_parameters(const webrtc::RtpParameters& parameters) { + RTC_CHECK_EQ(1UL, parameters.encodings.size()); + rtp_parameters_ = parameters; + } + private: void UpdateSendState() { RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); @@ -1223,6 +1235,7 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream // goes away. AudioSource* source_ = nullptr; bool send_ = false; + webrtc::RtpParameters rtp_parameters_; RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream); }; @@ -1359,7 +1372,7 @@ bool WebRtcVoiceMediaChannel::SetSendParameters( } } - if (!SetMaxSendBandwidth(params.max_bandwidth_bps)) { + if (!SetSendBitrate(params.max_bandwidth_bps)) { return false; } return SetOptions(params.options); @@ -1393,6 +1406,51 @@ bool WebRtcVoiceMediaChannel::SetRecvParameters( return true; } +webrtc::RtpParameters WebRtcVoiceMediaChannel::GetRtpParameters( + uint32_t ssrc) const { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + auto it = send_streams_.find(ssrc); + if (it == send_streams_.end()) { + LOG(LS_WARNING) << "Attempting to get RTP parameters for stream with ssrc " + << ssrc << " which doesn't exist."; + return webrtc::RtpParameters(); + } + + return it->second->rtp_parameters(); +} + +bool WebRtcVoiceMediaChannel::SetRtpParameters( + uint32_t ssrc, + const webrtc::RtpParameters& parameters) { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + if (!ValidateRtpParameters(parameters)) { + return false; + } + auto it = send_streams_.find(ssrc); + if (it == send_streams_.end()) { + LOG(LS_WARNING) << "Attempting to set RTP parameters for stream with ssrc " + << ssrc << " which doesn't exist."; + return false; + } + + if (!SetChannelParameters(it->second->channel(), parameters)) { + LOG(LS_WARNING) << "Failed to set RtpParameters."; + return false; + } + it->second->set_rtp_parameters(parameters); + return true; +} + +bool WebRtcVoiceMediaChannel::ValidateRtpParameters( + const webrtc::RtpParameters& rtp_parameters) { + if (rtp_parameters.encodings.size() != 1) { + LOG(LS_ERROR) + << "Attempted to set RtpParameters without exactly one encoding"; + return false; + } + return true; +} + bool WebRtcVoiceMediaChannel::SetOptions(const AudioOptions& options) { RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); LOG(LS_INFO) << "Setting voice channel options: " @@ -1587,7 +1645,7 @@ bool WebRtcVoiceMediaChannel::SetSendCodecs( // Cache the codecs in order to configure the channel created later. for (const auto& ch : send_streams_) { - if (!SetSendCodecs(ch.second->channel())) { + if (!SetSendCodecs(ch.second->channel(), ch.second->rtp_parameters())) { return false; } } @@ -1614,7 +1672,9 @@ bool WebRtcVoiceMediaChannel::SetSendCodecs( } // Apply current codec settings to a single voe::Channel used for sending. -bool WebRtcVoiceMediaChannel::SetSendCodecs(int channel) { +bool WebRtcVoiceMediaChannel::SetSendCodecs( + int channel, + const webrtc::RtpParameters& rtp_parameters) { // Disable VAD, FEC, and RED unless we know the other side wants them. engine()->voe()->codec()->SetVADStatus(channel, false); engine()->voe()->rtp()->SetNACKStatus(channel, false, 0); @@ -1682,10 +1742,9 @@ bool WebRtcVoiceMediaChannel::SetSendCodecs(int channel) { } } } - - if (send_bitrate_setting_) { - SetSendBitrateInternal(send_bitrate_bps_); - } + // TODO(solenberg): SetSendBitrate() yields another call to SetSendCodec(). + // Check if it is possible to fuse with the previous call in this function. + SetChannelParameters(channel, rtp_parameters); // Set the CN payloadtype and the VAD status. if (send_codec_spec_.cng_payload_type != -1) { @@ -1880,13 +1939,14 @@ bool WebRtcVoiceMediaChannel::AddSendStream(const StreamParams& sp) { // delete the channel in case failure happens below. webrtc::AudioTransport* audio_transport = engine()->voe()->base()->audio_transport(); - send_streams_.insert(std::make_pair(ssrc, new WebRtcAudioSendStream( - channel, audio_transport, ssrc, sp.cname, send_rtp_extensions_, call_))); + WebRtcAudioSendStream* stream = new WebRtcAudioSendStream( + channel, audio_transport, ssrc, sp.cname, send_rtp_extensions_, call_); + send_streams_.insert(std::make_pair(ssrc, stream)); // Set the current codecs to be used for the new channel. We need to do this // after adding the channel to send_channels_, because of how max bitrate is // currently being configured by SetSendCodec(). - if (HasSendCodec() && !SetSendCodecs(channel)) { + if (HasSendCodec() && !SetSendCodecs(channel, stream->rtp_parameters())) { RemoveSendStream(ssrc); return false; } @@ -2310,18 +2370,34 @@ bool WebRtcVoiceMediaChannel::MuteStream(uint32_t ssrc, bool muted) { return true; } -// TODO(minyue): SetMaxSendBandwidth() is subject to be renamed to -// SetMaxSendBitrate() in future. -bool WebRtcVoiceMediaChannel::SetMaxSendBandwidth(int bps) { - LOG(LS_INFO) << "WebRtcVoiceMediaChannel::SetMaxSendBandwidth."; - return SetSendBitrateInternal(bps); +bool WebRtcVoiceMediaChannel::SetSendBitrate(int bps) { + LOG(LS_INFO) << "WebRtcVoiceMediaChannel::SetSendBitrate."; + send_bitrate_bps_ = bps; + + for (const auto& kv : send_streams_) { + if (!SetChannelParameters(kv.second->channel(), + kv.second->rtp_parameters())) { + return false; + } + } + return true; } -bool WebRtcVoiceMediaChannel::SetSendBitrateInternal(int bps) { - LOG(LS_INFO) << "WebRtcVoiceMediaChannel::SetSendBitrateInternal."; +bool WebRtcVoiceMediaChannel::SetChannelParameters( + int channel, + const webrtc::RtpParameters& parameters) { + RTC_CHECK_EQ(1UL, parameters.encodings.size()); + return SetSendBitrate( + channel, + MinPositive(send_bitrate_bps_, parameters.encodings[0].max_bitrate_bps)); +} - send_bitrate_setting_ = true; - send_bitrate_bps_ = bps; +bool WebRtcVoiceMediaChannel::SetSendBitrate(int channel, int bps) { + // Bitrate is auto by default. + // TODO(bemasc): Fix this so that if SetMaxSendBandwidth(50) is followed by + // SetMaxSendBandwith(0), the second call removes the previous limit. + if (bps <= 0) + return true; if (!HasSendCodec()) { LOG(LS_INFO) << "The send codec has not been set up yet. " @@ -2329,24 +2405,16 @@ bool WebRtcVoiceMediaChannel::SetSendBitrateInternal(int bps) { return true; } - // Bitrate is auto by default. - // TODO(bemasc): Fix this so that if SetMaxSendBandwidth(50) is followed by - // SetMaxSendBandwith(0), the second call removes the previous limit. - if (bps <= 0) - return true; - webrtc::CodecInst codec = send_codec_spec_.codec_inst; bool is_multi_rate = WebRtcVoiceCodecs::IsCodecMultiRate(codec); if (is_multi_rate) { // If codec is multi-rate then just set the bitrate. codec.rate = bps; - for (const auto& ch : send_streams_) { - if (!SetSendCodec(ch.second->channel(), codec)) { - LOG(LS_INFO) << "Failed to set codec " << codec.plname - << " to bitrate " << bps << " bps."; - return false; - } + if (!SetSendCodec(channel, codec)) { + LOG(LS_INFO) << "Failed to set codec " << codec.plname << " to bitrate " + << bps << " bps."; + return false; } return true; } else { diff --git a/webrtc/media/engine/webrtcvoiceengine.h b/webrtc/media/engine/webrtcvoiceengine.h index 396e3bbb8c..dd565038b7 100644 --- a/webrtc/media/engine/webrtcvoiceengine.h +++ b/webrtc/media/engine/webrtcvoiceengine.h @@ -146,6 +146,10 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel, bool SetSendParameters(const AudioSendParameters& params) override; bool SetRecvParameters(const AudioRecvParameters& params) override; + webrtc::RtpParameters GetRtpParameters(uint32_t ssrc) const override; + bool SetRtpParameters(uint32_t ssrc, + const webrtc::RtpParameters& parameters) override; + bool SetPlayout(bool playout) override; bool PausePlayout(); bool ResumePlayout(); @@ -206,10 +210,9 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel, bool SetOptions(const AudioOptions& options); bool SetRecvCodecs(const std::vector& codecs); bool SetSendCodecs(const std::vector& codecs); - bool SetSendCodecs(int channel); + bool SetSendCodecs(int channel, const webrtc::RtpParameters& rtp_parameters); void SetNack(int channel, bool nack_enabled); bool SetSendCodec(int channel, const webrtc::CodecInst& send_codec); - bool SetMaxSendBandwidth(int bps); bool SetLocalSource(uint32_t ssrc, AudioSource* source); bool MuteStream(uint32_t ssrc, bool mute); @@ -223,16 +226,19 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel, bool IsDefaultRecvStream(uint32_t ssrc) { return default_recv_ssrc_ == static_cast(ssrc); } - bool SetSendBitrateInternal(int bps); + bool SetSendBitrate(int bps); + bool SetChannelParameters(int channel, + const webrtc::RtpParameters& parameters); + bool SetSendBitrate(int channel, int bps); bool HasSendCodec() const { return send_codec_spec_.codec_inst.pltype != -1; } + bool ValidateRtpParameters(const webrtc::RtpParameters& parameters); rtc::ThreadChecker worker_thread_checker_; WebRtcVoiceEngine* const engine_ = nullptr; std::vector recv_codecs_; - bool send_bitrate_setting_ = false; int send_bitrate_bps_ = 0; AudioOptions options_; rtc::Optional dtmf_payload_type_; diff --git a/webrtc/media/engine/webrtcvoiceengine_unittest.cc b/webrtc/media/engine/webrtcvoiceengine_unittest.cc index 78b6a20790..7645e9272c 100644 --- a/webrtc/media/engine/webrtcvoiceengine_unittest.cc +++ b/webrtc/media/engine/webrtcvoiceengine_unittest.cc @@ -214,6 +214,56 @@ class WebRtcVoiceEngineTestFake : public testing::Test { EXPECT_EQ(expected_bitrate, temp_codec.rate); } + // Sets the per-stream maximum bitrate limit for the specified SSRC. + bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) { + webrtc::RtpParameters parameters = channel_->GetRtpParameters(ssrc); + EXPECT_EQ(1UL, parameters.encodings.size()); + + parameters.encodings[0].max_bitrate_bps = bitrate; + return channel_->SetRtpParameters(ssrc, parameters); + } + + bool SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) { + cricket::AudioSendParameters send_parameters; + send_parameters.codecs.push_back(codec); + send_parameters.max_bandwidth_bps = bitrate; + return channel_->SetSendParameters(send_parameters); + } + + int GetCodecBitrate(int32_t ssrc) { + cricket::WebRtcVoiceMediaChannel* media_channel = + static_cast(channel_); + int channel = media_channel->GetSendChannelId(ssrc); + EXPECT_NE(-1, channel); + webrtc::CodecInst codec; + EXPECT_FALSE(voe_.GetSendCodec(channel, codec)); + return codec.rate; + } + + void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec, + int global_max, + int stream_max, + bool expected_result, + int expected_codec_bitrate) { + // Clear the bitrate limit from the previous test case. + EXPECT_TRUE(SetMaxBitrateForStream(kSsrc1, -1)); + + // Attempt to set the requested bitrate limits. + EXPECT_TRUE(SetGlobalMaxBitrate(codec, global_max)); + EXPECT_EQ(expected_result, SetMaxBitrateForStream(kSsrc1, stream_max)); + + // Verify that reading back the parameters gives results + // consistent with the Set() result. + webrtc::RtpParameters resulting_parameters = + channel_->GetRtpParameters(kSsrc1); + EXPECT_EQ(1UL, resulting_parameters.encodings.size()); + EXPECT_EQ(expected_result ? stream_max : -1, + resulting_parameters.encodings[0].max_bitrate_bps); + + // Verify that the codec settings have the expected bitrate. + EXPECT_EQ(expected_codec_bitrate, GetCodecBitrate(kSsrc1)); + } + void TestSetSendRtpHeaderExtensions(const std::string& ext) { EXPECT_TRUE(SetupSendStream()); @@ -772,6 +822,88 @@ TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) { EXPECT_EQ(64000, codec.rate); } +// Test that the per-stream bitrate limit and the global +// bitrate limit both apply. +TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) { + EXPECT_TRUE(SetupSendStream()); + + // opus, default bitrate == 64000. + SetAndExpectMaxBitrate(kOpusCodec, 0, 0, true, 64000); + SetAndExpectMaxBitrate(kOpusCodec, 48000, 0, true, 48000); + SetAndExpectMaxBitrate(kOpusCodec, 48000, 64000, true, 48000); + SetAndExpectMaxBitrate(kOpusCodec, 64000, 48000, true, 48000); + + // CBR codecs allow both maximums to exceed the bitrate. + SetAndExpectMaxBitrate(kPcmuCodec, 0, 0, true, 64000); + SetAndExpectMaxBitrate(kPcmuCodec, 64001, 0, true, 64000); + SetAndExpectMaxBitrate(kPcmuCodec, 0, 64001, true, 64000); + SetAndExpectMaxBitrate(kPcmuCodec, 64001, 64001, true, 64000); + + // CBR codecs don't allow per stream maximums to be too low. + SetAndExpectMaxBitrate(kPcmuCodec, 0, 63999, false, 64000); + SetAndExpectMaxBitrate(kPcmuCodec, 64001, 63999, false, 64000); +} + +// Test that an attempt to set RtpParameters for a stream that does not exist +// fails. +TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) { + EXPECT_TRUE(SetupChannel()); + webrtc::RtpParameters nonexistent_parameters = + channel_->GetRtpParameters(kSsrc1); + EXPECT_EQ(0, nonexistent_parameters.encodings.size()); + + nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters()); + EXPECT_FALSE(channel_->SetRtpParameters(kSsrc1, nonexistent_parameters)); +} + +TEST_F(WebRtcVoiceEngineTestFake, + CannotSetRtpParametersWithIncorrectNumberOfEncodings) { + // This test verifies that setting RtpParameters succeeds only if + // the structure contains exactly one encoding. + // TODO(skvlad): Update this test when we start supporting setting parameters + // for each encoding individually. + + EXPECT_TRUE(SetupSendStream()); + // Setting RtpParameters with no encoding is expected to fail. + webrtc::RtpParameters parameters; + EXPECT_FALSE(channel_->SetRtpParameters(kSsrc1, parameters)); + // Setting RtpParameters with exactly one encoding should succeed. + parameters.encodings.push_back(webrtc::RtpEncodingParameters()); + EXPECT_TRUE(channel_->SetRtpParameters(kSsrc1, parameters)); + // Two or more encodings should result in failure. + parameters.encodings.push_back(webrtc::RtpEncodingParameters()); + EXPECT_FALSE(channel_->SetRtpParameters(kSsrc1, parameters)); +} + +// Test that SetRtpParameters configures the correct encoding channel for each +// SSRC. +TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) { + SetupForMultiSendStream(); + // Create send streams. + for (uint32_t ssrc : kSsrcs4) { + EXPECT_TRUE( + channel_->AddSendStream(cricket::StreamParams::CreateLegacy(ssrc))); + } + // Configure one stream to be limited by the stream config, another to be + // limited by the global max, and the third one with no per-stream limit + // (still subject to the global limit). + EXPECT_TRUE(SetGlobalMaxBitrate(kOpusCodec, 64000)); + EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[0], 48000)); + EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[1], 96000)); + EXPECT_TRUE(SetMaxBitrateForStream(kSsrcs4[2], -1)); + + EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[0])); + EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[1])); + EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[2])); + + // Remove the global cap; the streams should switch to their respective + // maximums (or remain unchanged if there was no other limit on them.) + EXPECT_TRUE(SetGlobalMaxBitrate(kOpusCodec, -1)); + EXPECT_EQ(48000, GetCodecBitrate(kSsrcs4[0])); + EXPECT_EQ(96000, GetCodecBitrate(kSsrcs4[1])); + EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[2])); +} + // Test that we apply codecs properly. TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) { EXPECT_TRUE(SetupSendStream()); diff --git a/webrtc/pc/channel.cc b/webrtc/pc/channel.cc index b76d7bdb1d..9556beb6fe 100644 --- a/webrtc/pc/channel.cc +++ b/webrtc/pc/channel.cc @@ -1409,9 +1409,7 @@ webrtc::RtpParameters VoiceChannel::GetRtpParameters(uint32_t ssrc) const { } webrtc::RtpParameters VoiceChannel::GetRtpParameters_w(uint32_t ssrc) const { - // Not yet implemented. - // TODO(skvlad): Add support for limiting send bitrate for audio channels. - return webrtc::RtpParameters(); + return media_channel()->GetRtpParameters(ssrc); } bool VoiceChannel::SetRtpParameters(uint32_t ssrc, @@ -1422,9 +1420,7 @@ bool VoiceChannel::SetRtpParameters(uint32_t ssrc, bool VoiceChannel::SetRtpParameters_w(uint32_t ssrc, webrtc::RtpParameters parameters) { - // Not yet implemented. - // TODO(skvlad): Add support for limiting send bitrate for audio channels. - return false; + return media_channel()->SetRtpParameters(ssrc, parameters); } bool VoiceChannel::GetStats(VoiceMediaInfo* stats) { diff --git a/webrtc/pc/channel_unittest.cc b/webrtc/pc/channel_unittest.cc index a423842e00..d84076ec2d 100644 --- a/webrtc/pc/channel_unittest.cc +++ b/webrtc/pc/channel_unittest.cc @@ -2357,24 +2357,12 @@ TEST_F(VoiceChannelTest, SendBundleToBundleWithRtcpMuxSecure) { Base::SendBundleToBundle(kAudioPts, arraysize(kAudioPts), true, true); } -TEST_F(VoiceChannelTest, GetRtpParametersIsNotImplemented) { - // These tests verify that the Get/SetRtpParameters methods for VoiceChannel - // always fail as they are not implemented. - // TODO(skvlad): Replace with full tests when support for bitrate limiting - // for audio RtpSenders is added. - CreateChannels(0, 0); - EXPECT_TRUE( - channel1_->SetLocalContent(&local_media_content1_, CA_OFFER, NULL)); - webrtc::RtpParameters voice_parameters = channel1_->GetRtpParameters(kSsrc1); - EXPECT_EQ(0UL, voice_parameters.encodings.size()); +TEST_F(VoiceChannelTest, DefaultMaxBitrateIsUnlimited) { + Base::DefaultMaxBitrateIsUnlimited(); } -TEST_F(VoiceChannelTest, SetRtpParametersIsNotImplemented) { - CreateChannels(0, 0); - EXPECT_TRUE( - channel1_->SetLocalContent(&local_media_content1_, CA_OFFER, NULL)); - EXPECT_FALSE( - channel1_->SetRtpParameters(kSsrc1, BitrateLimitedParameters(1000))); +TEST_F(VoiceChannelTest, CanChangeMaxBitrate) { + Base::CanChangeMaxBitrate(); } // VideoChannelTest