From dedfd28a52224edba5d5d4d15c020f9a267c18ae Mon Sep 17 00:00:00 2001 From: ossu Date: Tue, 14 Jun 2016 07:12:39 -0700 Subject: [PATCH] Support for two audio codec lists down into WebRtcVoiceEngine. Added the plumbing necessary to get two different lists of codecs from WebRtcVoiceEngine up to MediaSessionDescriptionFactory. This should be the last step in this set of CLs. Once https://codereview.webrtc.org/1991233004/ has landed, it's possible to implement the ReceiveCodecs getter with the info from the AudioDecoderFactory. The factory needs to be updated to actually produce the correct list, as well. BUG=webrtc:5805 Review-Url: https://codereview.webrtc.org/2013053002 Cr-Commit-Position: refs/heads/master@{#13131} --- webrtc/api/webrtcsession_unittest.cc | 3 ++- webrtc/media/base/fakemediaengine.h | 7 +++++-- webrtc/media/base/mediaengine.h | 10 +++++++--- webrtc/media/engine/webrtcvoiceengine.cc | 7 ++++++- webrtc/media/engine/webrtcvoiceengine.h | 3 ++- .../media/engine/webrtcvoiceengine_unittest.cc | 16 ++++++++++------ webrtc/pc/channelmanager.cc | 13 ++++++------- webrtc/pc/channelmanager.h | 3 ++- webrtc/pc/mediasession.cc | 11 +++++++---- webrtc/pc/mediasession.h | 2 +- webrtc/pc/mediasession_unittest.cc | 18 +++++++++--------- 11 files changed, 57 insertions(+), 36 deletions(-) diff --git a/webrtc/api/webrtcsession_unittest.cc b/webrtc/api/webrtcsession_unittest.cc index db5495b5ee..674d54fa53 100644 --- a/webrtc/api/webrtcsession_unittest.cc +++ b/webrtc/api/webrtcsession_unittest.cc @@ -1336,7 +1336,8 @@ class WebRtcSessionTest const cricket::AudioCodec kCNCodec2(103, "CN", 16000, 0, 1); // Add kCNCodec for dtmf test. - std::vector codecs = media_engine_->audio_codecs();; + std::vector codecs = + media_engine_->audio_send_codecs(); codecs.push_back(kCNCodec1); codecs.push_back(kCNCodec2); media_engine_->SetAudioCodecs(codecs); diff --git a/webrtc/media/base/fakemediaengine.h b/webrtc/media/base/fakemediaengine.h index 784967ac4f..b2ec1243c9 100644 --- a/webrtc/media/base/fakemediaengine.h +++ b/webrtc/media/base/fakemediaengine.h @@ -767,8 +767,11 @@ class FakeVoiceEngine : public FakeBaseEngine { channels_.erase(std::find(channels_.begin(), channels_.end(), channel)); } - const std::vector& codecs() { return codecs_; } - void SetCodecs(const std::vector codecs) { codecs_ = codecs; } + // TODO(ossu): For proper testing, These should either individually settable + // or the voice engine should reference mockable factories. + const std::vector& send_codecs() { return codecs_; } + const std::vector& recv_codecs() { return codecs_; } + void SetCodecs(const std::vector& codecs) { codecs_ = codecs; } bool GetOutputVolume(int* level) { *level = output_volume_; diff --git a/webrtc/media/base/mediaengine.h b/webrtc/media/base/mediaengine.h index bd1ce431ec..9204fc129c 100644 --- a/webrtc/media/base/mediaengine.h +++ b/webrtc/media/base/mediaengine.h @@ -81,7 +81,8 @@ class MediaEngineInterface { // Gets the current microphone level, as a value between 0 and 10. virtual int GetInputLevel() = 0; - virtual const std::vector& audio_codecs() = 0; + virtual const std::vector& audio_send_codecs() = 0; + virtual const std::vector& audio_recv_codecs() = 0; virtual RtpCapabilities GetAudioCapabilities() = 0; virtual const std::vector& video_codecs() = 0; virtual RtpCapabilities GetVideoCapabilities() = 0; @@ -163,8 +164,11 @@ class CompositeMediaEngine : public MediaEngineInterface { virtual int GetInputLevel() { return voice_.GetInputLevel(); } - virtual const std::vector& audio_codecs() { - return voice_.codecs(); + virtual const std::vector& audio_send_codecs() { + return voice_.send_codecs(); + } + virtual const std::vector& audio_recv_codecs() { + return voice_.recv_codecs(); } virtual RtpCapabilities GetAudioCapabilities() { return voice_.GetCapabilities(); diff --git a/webrtc/media/engine/webrtcvoiceengine.cc b/webrtc/media/engine/webrtcvoiceengine.cc index b78d73ad0b..fa6e257ca9 100644 --- a/webrtc/media/engine/webrtcvoiceengine.cc +++ b/webrtc/media/engine/webrtcvoiceengine.cc @@ -948,7 +948,12 @@ int WebRtcVoiceEngine::GetInputLevel() { static_cast(ulevel) : -1; } -const std::vector& WebRtcVoiceEngine::codecs() { +const std::vector& WebRtcVoiceEngine::send_codecs() const { + RTC_DCHECK(signal_thread_checker_.CalledOnValidThread()); + return codecs_; +} + +const std::vector& WebRtcVoiceEngine::recv_codecs() const { RTC_DCHECK(signal_thread_checker_.CalledOnValidThread()); return codecs_; } diff --git a/webrtc/media/engine/webrtcvoiceengine.h b/webrtc/media/engine/webrtcvoiceengine.h index 63ef3f305d..b7da44f8c0 100644 --- a/webrtc/media/engine/webrtcvoiceengine.h +++ b/webrtc/media/engine/webrtcvoiceengine.h @@ -65,7 +65,8 @@ class WebRtcVoiceEngine final : public webrtc::TraceCallback { bool SetOutputVolume(int level); int GetInputLevel(); - const std::vector& codecs(); + const std::vector& send_codecs() const; + const std::vector& recv_codecs() const; RtpCapabilities GetCapabilities() const; // For tracking WebRtc channels. Needed because we have to pause them diff --git a/webrtc/media/engine/webrtcvoiceengine_unittest.cc b/webrtc/media/engine/webrtcvoiceengine_unittest.cc index 331e6250ce..c6cac1bd8d 100644 --- a/webrtc/media/engine/webrtcvoiceengine_unittest.cc +++ b/webrtc/media/engine/webrtcvoiceengine_unittest.cc @@ -525,8 +525,10 @@ TEST_F(WebRtcVoiceEngineTestFake, CreateRecvStream) { // Tests that the list of supported codecs is created properly and ordered // correctly (such that opus appears first). +// TODO(ossu): This test should move into a separate builtin audio codecs +// module. TEST_F(WebRtcVoiceEngineTestFake, CodecOrder) { - const std::vector& codecs = engine_->codecs(); + const std::vector& codecs = engine_->send_codecs(); ASSERT_FALSE(codecs.empty()); EXPECT_STRCASEEQ("opus", codecs[0].name.c_str()); EXPECT_EQ(48000, codecs[0].clockrate); @@ -535,7 +537,7 @@ TEST_F(WebRtcVoiceEngineTestFake, CodecOrder) { } TEST_F(WebRtcVoiceEngineTestFake, OpusSupportsTransportCc) { - const std::vector& codecs = engine_->codecs(); + const std::vector& codecs = engine_->send_codecs(); bool opus_found = false; for (cricket::AudioCodec codec : codecs) { if (codec.name == "opus") { @@ -831,7 +833,7 @@ TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) { EXPECT_TRUE(SetupChannel()); const int kDesiredBitrate = 128000; cricket::AudioSendParameters parameters; - parameters.codecs = engine_->codecs(); + parameters.codecs = engine_->send_codecs(); parameters.max_bandwidth_bps = kDesiredBitrate; EXPECT_TRUE(channel_->SetSendParameters(parameters)); @@ -1579,7 +1581,7 @@ TEST_F(WebRtcVoiceEngineTestFake, TransportCcCanBeEnabledAndDisabled) { EXPECT_FALSE( call_.GetAudioReceiveStream(kSsrc1)->GetConfig().rtp.transport_cc); - send_parameters.codecs = engine_->codecs(); + send_parameters.codecs = engine_->send_codecs(); EXPECT_TRUE(channel_->SetSendParameters(send_parameters)); ASSERT_TRUE(call_.GetAudioReceiveStream(kSsrc1) != nullptr); EXPECT_TRUE( @@ -3576,6 +3578,8 @@ TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) { } // Tests that the library is configured with the codecs we want. +// TODO(ossu): This test should move into the builtin audio codecs module +// eventually. TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) { // TODO(ossu): These tests should move into a future "builtin audio codecs" // module. @@ -3636,7 +3640,7 @@ TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) { cricket::WebRtcVoiceEngine engine(nullptr, webrtc::CreateBuiltinAudioDecoderFactory()); for (std::vector::const_iterator it = - engine.codecs().begin(); it != engine.codecs().end(); ++it) { + engine.send_codecs().begin(); it != engine.send_codecs().end(); ++it) { if (it->name == "CN" && it->clockrate == 16000) { EXPECT_EQ(105, it->id); } else if (it->name == "CN" && it->clockrate == 32000) { @@ -3701,6 +3705,6 @@ TEST(WebRtcVoiceEngineTest, SetRecvCodecs) { cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(), cricket::AudioOptions(), call.get()); cricket::AudioRecvParameters parameters; - parameters.codecs = engine.codecs(); + parameters.codecs = engine.recv_codecs(); EXPECT_TRUE(channel.SetRecvParameters(parameters)); } diff --git a/webrtc/pc/channelmanager.cc b/webrtc/pc/channelmanager.cc index 334a712e68..afac930cd0 100644 --- a/webrtc/pc/channelmanager.cc +++ b/webrtc/pc/channelmanager.cc @@ -100,15 +100,14 @@ bool ChannelManager::SetVideoRtxEnabled(bool enable) { } } -void ChannelManager::GetSupportedAudioCodecs( +void ChannelManager::GetSupportedAudioSendCodecs( std::vector* codecs) const { - codecs->clear(); + *codecs = media_engine_->audio_send_codecs(); +} - for (std::vector::const_iterator it = - media_engine_->audio_codecs().begin(); - it != media_engine_->audio_codecs().end(); ++it) { - codecs->push_back(*it); - } +void ChannelManager::GetSupportedAudioReceiveCodecs( + std::vector* codecs) const { + *codecs = media_engine_->audio_recv_codecs(); } void ChannelManager::GetSupportedAudioRtpHeaderExtensions( diff --git a/webrtc/pc/channelmanager.h b/webrtc/pc/channelmanager.h index 3b0c0e967e..16adf875d3 100644 --- a/webrtc/pc/channelmanager.h +++ b/webrtc/pc/channelmanager.h @@ -72,7 +72,8 @@ class ChannelManager { // Retrieves the list of supported audio & video codec types. // Can be called before starting the media engine. - void GetSupportedAudioCodecs(std::vector* codecs) const; + void GetSupportedAudioSendCodecs(std::vector* codecs) const; + void GetSupportedAudioReceiveCodecs(std::vector* codecs) const; void GetSupportedAudioRtpHeaderExtensions(RtpHeaderExtensions* ext) const; void GetSupportedVideoCodecs(std::vector* codecs) const; void GetSupportedVideoRtpHeaderExtensions(RtpHeaderExtensions* ext) const; diff --git a/webrtc/pc/mediasession.cc b/webrtc/pc/mediasession.cc index 5d9af981a7..937a2c11f2 100644 --- a/webrtc/pc/mediasession.cc +++ b/webrtc/pc/mediasession.cc @@ -1273,16 +1273,19 @@ MediaSessionDescriptionFactory::MediaSessionDescriptionFactory( : secure_(SEC_DISABLED), add_legacy_(true), transport_desc_factory_(transport_desc_factory) { - channel_manager->GetSupportedAudioCodecs(&audio_sendrecv_codecs_); + channel_manager->GetSupportedAudioSendCodecs(&audio_send_codecs_); + channel_manager->GetSupportedAudioReceiveCodecs(&audio_recv_codecs_); + channel_manager->GetSupportedAudioSendCodecs(&audio_send_codecs_); channel_manager->GetSupportedAudioRtpHeaderExtensions(&audio_rtp_extensions_); channel_manager->GetSupportedVideoCodecs(&video_codecs_); channel_manager->GetSupportedVideoRtpHeaderExtensions(&video_rtp_extensions_); channel_manager->GetSupportedDataCodecs(&data_codecs_); - audio_send_codecs_ = audio_sendrecv_codecs_; - audio_recv_codecs_ = audio_sendrecv_codecs_; + NegotiateCodecs(audio_recv_codecs_, audio_send_codecs_, + &audio_sendrecv_codecs_); } -const AudioCodecs& MediaSessionDescriptionFactory::audio_codecs() const { +const AudioCodecs& MediaSessionDescriptionFactory::audio_sendrecv_codecs() + const { return audio_sendrecv_codecs_; } diff --git a/webrtc/pc/mediasession.h b/webrtc/pc/mediasession.h index 7a43b005fe..34354dcd49 100644 --- a/webrtc/pc/mediasession.h +++ b/webrtc/pc/mediasession.h @@ -428,7 +428,7 @@ class MediaSessionDescriptionFactory { MediaSessionDescriptionFactory(ChannelManager* cmanager, const TransportDescriptionFactory* factory); - const AudioCodecs& audio_codecs() const; + const AudioCodecs& audio_sendrecv_codecs() const; const AudioCodecs& audio_send_codecs() const; const AudioCodecs& audio_recv_codecs() const; void set_audio_codecs(const AudioCodecs& send_codecs, diff --git a/webrtc/pc/mediasession_unittest.cc b/webrtc/pc/mediasession_unittest.cc index c898315b1a..8ad652643e 100644 --- a/webrtc/pc/mediasession_unittest.cc +++ b/webrtc/pc/mediasession_unittest.cc @@ -474,7 +474,7 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioOffer) { const AudioContentDescription* acd = static_cast(ac->description); EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type()); - EXPECT_EQ(f1_.audio_codecs(), acd->codecs()); + EXPECT_EQ(f1_.audio_sendrecv_codecs(), acd->codecs()); EXPECT_NE(0U, acd->first_ssrc()); // a random nonzero ssrc EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // default bandwidth (auto) EXPECT_TRUE(acd->rtcp_mux()); // rtcp-mux defaults on @@ -500,7 +500,7 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoOffer) { const VideoContentDescription* vcd = static_cast(vc->description); EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type()); - EXPECT_EQ(f1_.audio_codecs(), acd->codecs()); + EXPECT_EQ(f1_.audio_sendrecv_codecs(), acd->codecs()); EXPECT_NE(0U, acd->first_ssrc()); // a random nonzero ssrc EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // default bandwidth (auto) EXPECT_TRUE(acd->rtcp_mux()); // rtcp-mux defaults on @@ -520,7 +520,7 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoOffer) { // duplicate RTP payload types. TEST_F(MediaSessionDescriptionFactoryTest, TestBundleOfferWithSameCodecPlType) { const VideoCodec& offered_video_codec = f2_.video_codecs()[0]; - const AudioCodec& offered_audio_codec = f2_.audio_codecs()[0]; + const AudioCodec& offered_audio_codec = f2_.audio_sendrecv_codecs()[0]; const DataCodec& offered_data_codec = f2_.data_codecs()[0]; ASSERT_EQ(offered_video_codec.id, offered_audio_codec.id); ASSERT_EQ(offered_video_codec.id, offered_data_codec.id); @@ -607,7 +607,7 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateRtpDataOffer) { const DataContentDescription* dcd = static_cast(dc->description); EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type()); - EXPECT_EQ(f1_.audio_codecs(), acd->codecs()); + EXPECT_EQ(f1_.audio_sendrecv_codecs(), acd->codecs()); EXPECT_NE(0U, acd->first_ssrc()); // a random nonzero ssrc EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // default bandwidth (auto) EXPECT_TRUE(acd->rtcp_mux()); // rtcp-mux defaults on @@ -1222,7 +1222,7 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateMultiStreamVideoOffer) { const DataContentDescription* dcd = static_cast(dc->description); EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type()); - EXPECT_EQ(f1_.audio_codecs(), acd->codecs()); + EXPECT_EQ(f1_.audio_sendrecv_codecs(), acd->codecs()); const StreamParamsVec& audio_streams = acd->streams(); ASSERT_EQ(2U, audio_streams.size()); @@ -2486,25 +2486,25 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestSetAudioCodecs) { sf.set_audio_codecs(send_codecs, recv_codecs); EXPECT_TRUE(sf.audio_send_codecs() == send_codecs); EXPECT_TRUE(sf.audio_recv_codecs() == recv_codecs); - EXPECT_TRUE(sf.audio_codecs() == sendrecv_codecs); + EXPECT_TRUE(sf.audio_sendrecv_codecs() == sendrecv_codecs); // Test empty send codecs list sf.set_audio_codecs(no_codecs, recv_codecs); EXPECT_TRUE(sf.audio_send_codecs() == no_codecs); EXPECT_TRUE(sf.audio_recv_codecs() == recv_codecs); - EXPECT_TRUE(sf.audio_codecs() == no_codecs); + EXPECT_TRUE(sf.audio_sendrecv_codecs() == no_codecs); // Test empty recv codecs list sf.set_audio_codecs(send_codecs, no_codecs); EXPECT_TRUE(sf.audio_send_codecs() == send_codecs); EXPECT_TRUE(sf.audio_recv_codecs() == no_codecs); - EXPECT_TRUE(sf.audio_codecs() == no_codecs); + EXPECT_TRUE(sf.audio_sendrecv_codecs() == no_codecs); // Test all empty codec lists sf.set_audio_codecs(no_codecs, no_codecs); EXPECT_TRUE(sf.audio_send_codecs() == no_codecs); EXPECT_TRUE(sf.audio_recv_codecs() == no_codecs); - EXPECT_TRUE(sf.audio_codecs() == no_codecs); + EXPECT_TRUE(sf.audio_sendrecv_codecs() == no_codecs); } namespace {