diff --git a/media/BUILD.gn b/media/BUILD.gn index 8508a7b5c5..c0aba7aac1 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn @@ -293,6 +293,7 @@ rtc_library("codec") { ":media_constants", "../api:field_trials_view", "../api:rtp_parameters", + "../api/audio_codecs:audio_codecs_api", "../api/video_codecs:video_codecs_api", "../rtc_base:checks", "../rtc_base:logging", diff --git a/media/base/codec.cc b/media/base/codec.cc index 7a238cfae4..70a8d90e25 100644 --- a/media/base/codec.cc +++ b/media/base/codec.cc @@ -12,6 +12,7 @@ #include "absl/algorithm/container.h" #include "absl/strings/match.h" +#include "api/audio_codecs/audio_format.h" #include "api/video_codecs/av1_profile.h" #include "api/video_codecs/h264_profile_level_id.h" #include "api/video_codecs/vp9_profile.h" @@ -131,6 +132,11 @@ Codec::Codec(Type type, Codec::Codec(Type type) : Codec(type, 0, "", 0) {} +Codec::Codec(const webrtc::SdpAudioFormat& c) + : Codec(Type::kAudio, 0, c.name, c.clockrate_hz, c.num_channels) { + params = c.parameters; +} + Codec::Codec(const webrtc::SdpVideoFormat& c) : Codec(Type::kVideo, 0, c.name, kVideoCodecClockrate) { params = c.parameters; @@ -442,6 +448,10 @@ Codec CreateAudioCodec(int id, return Codec(Codec::Type::kAudio, id, name, clockrate, channels); } +Codec CreateAudioCodec(const webrtc::SdpAudioFormat& c) { + return Codec(c); +} + Codec CreateVideoCodec(const std::string& name) { return CreateVideoCodec(0, name); } diff --git a/media/base/codec.h b/media/base/codec.h index 1ca0931b66..74c5cc2add 100644 --- a/media/base/codec.h +++ b/media/base/codec.h @@ -19,6 +19,7 @@ #include "absl/container/inlined_vector.h" #include "absl/strings/string_view.h" #include "absl/types/optional.h" +#include "api/audio_codecs/audio_format.h" #include "api/field_trials_view.h" #include "api/rtp_parameters.h" #include "api/video_codecs/sdp_video_format.h" @@ -166,12 +167,14 @@ struct RTC_EXPORT Codec { int clockrate, size_t channels); + explicit Codec(const webrtc::SdpAudioFormat& c); explicit Codec(const webrtc::SdpVideoFormat& c); friend Codec CreateAudioCodec(int id, const std::string& name, int clockrate, size_t channels); + friend Codec CreateAudioCodec(const webrtc::SdpAudioFormat& c); friend Codec CreateAudioRtxCodec(int rtx_payload_type, int associated_payload_type); friend Codec CreateVideoCodec(int id, const std::string& name); @@ -188,6 +191,7 @@ Codec CreateAudioCodec(int id, const std::string& name, int clockrate, size_t channels); +Codec CreateAudioCodec(const webrtc::SdpAudioFormat& c); Codec CreateAudioRtxCodec(int rtx_payload_type, int associated_payload_type); Codec CreateVideoCodec(const std::string& name); Codec CreateVideoCodec(int id, const std::string& name); diff --git a/media/base/fake_media_engine.cc b/media/base/fake_media_engine.cc index 5e4ecd310d..e31ffad3a6 100644 --- a/media/base/fake_media_engine.cc +++ b/media/base/fake_media_engine.cc @@ -74,6 +74,12 @@ const std::vector& FakeVoiceMediaChannel::send_codecs() const { const std::vector& FakeVoiceMediaChannel::codecs() const { return send_codecs(); } +absl::optional FakeVoiceMediaChannel::GetSendCodec() const { + if (!send_codecs_.empty()) { + return send_codecs_.front(); + } + return absl::nullopt; +} const std::vector& FakeVoiceMediaChannel::dtmf_info_queue() const { return dtmf_info_queue_; @@ -317,7 +323,7 @@ bool FakeVideoMediaChannel::AddSendStream(const StreamParams& sp) { bool FakeVideoMediaChannel::RemoveSendStream(uint32_t ssrc) { return RtpHelper::RemoveSendStream(ssrc); } -absl::optional FakeVideoMediaChannel::GetSendCodec() { +absl::optional FakeVideoMediaChannel::GetSendCodec() const { if (send_codecs_.empty()) { return absl::nullopt; } diff --git a/media/base/fake_media_engine.h b/media/base/fake_media_engine.h index 26fe27666c..caa5fab4be 100644 --- a/media/base/fake_media_engine.h +++ b/media/base/fake_media_engine.h @@ -423,6 +423,7 @@ class FakeVoiceMediaChannel : public RtpHelper { bool SendCodecHasNack() const override { return false; } void SetSendCodecChangedCallback( absl::AnyInvocable callback) override {} + absl::optional GetSendCodec() const override; private: class VoiceChannelAudioSink : public AudioSource::Sink { @@ -489,7 +490,7 @@ class FakeVideoMediaChannel : public RtpHelper { bool AddSendStream(const StreamParams& sp) override; bool RemoveSendStream(uint32_t ssrc) override; - absl::optional GetSendCodec() override; + absl::optional GetSendCodec() const override; bool SetSink(uint32_t ssrc, rtc::VideoSinkInterface* sink) override; void SetDefaultSink( diff --git a/media/base/media_channel.h b/media/base/media_channel.h index ea6384ab95..e18e1d312e 100644 --- a/media/base/media_channel.h +++ b/media/base/media_channel.h @@ -193,6 +193,9 @@ class MediaSendChannelInterface { virtual VoiceMediaSendChannelInterface* AsVoiceSendChannel() = 0; virtual cricket::MediaType media_type() const = 0; + // Gets the currently set codecs/payload types to be used for outgoing media. + virtual absl::optional GetSendCodec() const = 0; + // Creates a new outgoing media stream with SSRCs and CNAME as described // by sp. virtual bool AddSendStream(const StreamParams& sp) = 0; @@ -931,8 +934,6 @@ struct VideoRecvParameters : RtpParameters {}; class VideoMediaSendChannelInterface : public MediaSendChannelInterface { public: virtual bool SetSendParameters(const VideoSendParameters& params) = 0; - // Gets the currently set codecs/payload types to be used for outgoing media. - virtual absl::optional GetSendCodec() = 0; // Starts or stops transmission (and potentially capture) of local video. virtual bool SetSend(bool send) = 0; // Configure stream for sending and register a source. diff --git a/media/base/media_channel_shim.h b/media/base/media_channel_shim.h index e4dbee700d..f051d1a11a 100644 --- a/media/base/media_channel_shim.h +++ b/media/base/media_channel_shim.h @@ -87,6 +87,9 @@ class VoiceMediaShimChannel : public VoiceMediaChannel { cricket::MediaType media_type() const override { return MEDIA_TYPE_AUDIO; } // Implementation of MediaSendChannelInterface + absl::optional GetSendCodec() const override { + return send_impl()->GetSendCodec(); + } void OnPacketSent(const rtc::SentPacket& sent_packet) override { send_impl()->OnPacketSent(sent_packet); } @@ -385,7 +388,7 @@ class VideoMediaShimChannel : public VideoMediaChannel { bool SetSendParameters(const VideoSendParameters& params) override { return send_impl()->SetSendParameters(params); } - absl::optional GetSendCodec() override { + absl::optional GetSendCodec() const override { return send_impl()->GetSendCodec(); } bool SetSend(bool send) override { return send_impl()->SetSend(send); } diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc index bbda10dbd6..68df906b54 100644 --- a/media/engine/webrtc_video_engine.cc +++ b/media/engine/webrtc_video_engine.cc @@ -1300,7 +1300,7 @@ webrtc::RTCError WebRtcVideoSendChannel::SetRtpSendParameters( return it->second->SetRtpParameters(parameters, std::move(callback)); } -absl::optional WebRtcVideoSendChannel::GetSendCodec() { +absl::optional WebRtcVideoSendChannel::GetSendCodec() const { RTC_DCHECK_RUN_ON(&thread_checker_); if (!send_codec()) { RTC_LOG(LS_VERBOSE) << "GetSendCodec: No send codec set."; diff --git a/media/engine/webrtc_video_engine.h b/media/engine/webrtc_video_engine.h index e210f040bf..e1413b7bb2 100644 --- a/media/engine/webrtc_video_engine.h +++ b/media/engine/webrtc_video_engine.h @@ -207,7 +207,7 @@ class WebRtcVideoSendChannel : public MediaChannelUtil, const webrtc::RtpParameters& parameters, webrtc::SetParametersCallback callback) override; webrtc::RtpParameters GetRtpSendParameters(uint32_t ssrc) const override; - absl::optional GetSendCodec() override; + absl::optional GetSendCodec() const override; bool SetSend(bool send) override; bool SetVideoSend( uint32_t ssrc, diff --git a/media/engine/webrtc_video_engine_unittest.cc b/media/engine/webrtc_video_engine_unittest.cc index 3f6cd2572c..784d6147d6 100644 --- a/media/engine/webrtc_video_engine_unittest.cc +++ b/media/engine/webrtc_video_engine_unittest.cc @@ -2539,7 +2539,7 @@ TEST_F(WebRtcVideoChannelBaseTest, RequestEncoderFallback) { parameters.codecs.push_back(GetEngineCodec("VP8")); EXPECT_TRUE(channel_->SetSendParameters(parameters)); - absl::optional codec = channel_->GetSendCodec(); + absl::optional codec = send_channel_->GetSendCodec(); ASSERT_TRUE(codec); EXPECT_EQ("VP9", codec->name); @@ -2547,14 +2547,14 @@ TEST_F(WebRtcVideoChannelBaseTest, RequestEncoderFallback) { // the current thread), hence the ProcessMessages call. SendImpl()->RequestEncoderFallback(); time_controller_.AdvanceTime(kFrameDuration); - codec = channel_->GetSendCodec(); + codec = send_channel_->GetSendCodec(); ASSERT_TRUE(codec); EXPECT_EQ("VP8", codec->name); // No other codec to fall back to, keep using VP8. SendImpl()->RequestEncoderFallback(); time_controller_.AdvanceTime(kFrameDuration); - codec = channel_->GetSendCodec(); + codec = send_channel_->GetSendCodec(); ASSERT_TRUE(codec); EXPECT_EQ("VP8", codec->name); } @@ -2565,7 +2565,7 @@ TEST_F(WebRtcVideoChannelBaseTest, RequestEncoderSwitchDefaultFallback) { parameters.codecs.push_back(GetEngineCodec("VP8")); EXPECT_TRUE(channel_->SetSendParameters(parameters)); - absl::optional codec = channel_->GetSendCodec(); + absl::optional codec = send_channel_->GetSendCodec(); ASSERT_TRUE(codec); EXPECT_EQ("VP9", codec->name); @@ -2577,7 +2577,7 @@ TEST_F(WebRtcVideoChannelBaseTest, RequestEncoderSwitchDefaultFallback) { // Requested encoder is not available. Default fallback is allowed. Switch to // the next negotiated codec, VP8. - codec = channel_->GetSendCodec(); + codec = send_channel_->GetSendCodec(); ASSERT_TRUE(codec); EXPECT_EQ("VP8", codec->name); } @@ -2591,7 +2591,7 @@ TEST_F(WebRtcVideoChannelBaseTest, RequestEncoderSwitchStrictPreference) { parameters.codecs.push_back(vp9); EXPECT_TRUE(channel_->SetSendParameters(parameters)); - absl::optional codec = channel_->GetSendCodec(); + absl::optional codec = send_channel_->GetSendCodec(); ASSERT_TRUE(codec); EXPECT_EQ("VP8", codec->name); @@ -2602,7 +2602,7 @@ TEST_F(WebRtcVideoChannelBaseTest, RequestEncoderSwitchStrictPreference) { // VP9 profile_id=1 is not available. Default fallback is not allowed. Switch // is not performed. - codec = channel_->GetSendCodec(); + codec = send_channel_->GetSendCodec(); ASSERT_TRUE(codec); EXPECT_EQ("VP8", codec->name); @@ -2612,7 +2612,7 @@ TEST_F(WebRtcVideoChannelBaseTest, RequestEncoderSwitchStrictPreference) { time_controller_.AdvanceTime(kFrameDuration); // VP9 profile_id=0 is available. Switch encoder. - codec = channel_->GetSendCodec(); + codec = send_channel_->GetSendCodec(); ASSERT_TRUE(codec); EXPECT_EQ("VP9", codec->name); } @@ -4281,7 +4281,7 @@ TEST_F(WebRtcVideoChannelTest, SetDefaultSendCodecs) { AssignDefaultAptRtxTypes(); ASSERT_TRUE(channel_->SetSendParameters(send_parameters_)); - absl::optional codec = channel_->GetSendCodec(); + absl::optional codec = send_channel_->GetSendCodec(); ASSERT_TRUE(codec); EXPECT_TRUE(codec->Matches(engine_.send_codecs()[0], &field_trials_)); @@ -5036,7 +5036,7 @@ TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithMaxQuantization) { EXPECT_EQ(atoi(kMaxQuantization), AddSendStream()->GetVideoStreams().back().max_qp); - absl::optional codec = channel_->GetSendCodec(); + absl::optional codec = send_channel_->GetSendCodec(); ASSERT_TRUE(codec); EXPECT_EQ(kMaxQuantization, codec->params[kCodecParamMaxQuantization]); } @@ -9751,7 +9751,7 @@ TEST_F(WebRtcVideoChannelBaseTest, EncoderSelectorSwitchCodec) { EXPECT_TRUE(channel_->SetSendParameters(parameters)); channel_->SetSend(true); - absl::optional codec = channel_->GetSendCodec(); + absl::optional codec = send_channel_->GetSendCodec(); ASSERT_TRUE(codec); EXPECT_EQ("VP8", codec->name); @@ -9762,7 +9762,7 @@ TEST_F(WebRtcVideoChannelBaseTest, EncoderSelectorSwitchCodec) { channel_->SetEncoderSelector(kSsrc, &encoder_selector); time_controller_.AdvanceTime(kFrameDuration); - codec = channel_->GetSendCodec(); + codec = send_channel_->GetSendCodec(); ASSERT_TRUE(codec); EXPECT_EQ("VP9", codec->name); diff --git a/media/engine/webrtc_voice_engine.cc b/media/engine/webrtc_voice_engine.cc index 1ee0c21993..74d0d53cea 100644 --- a/media/engine/webrtc_voice_engine.cc +++ b/media/engine/webrtc_voice_engine.cc @@ -49,6 +49,7 @@ #include "call/rtp_config.h" #include "call/rtp_transport_controller_send_interface.h" #include "media/base/audio_source.h" +#include "media/base/codec.h" #include "media/base/media_constants.h" #include "media/base/stream_params.h" #include "media/engine/adm_helpers.h" @@ -1330,6 +1331,13 @@ bool WebRtcVoiceSendChannel::SetSendParameters( return SetOptions(params.options); } +absl::optional WebRtcVoiceSendChannel::GetSendCodec() const { + if (send_codec_spec_) { + return CreateAudioCodec(send_codec_spec_->format); + } + return absl::nullopt; +} + // Utility function called from SetSendParameters() to extract current send // codec settings from the given list of codecs (originally from SDP). Both send // and receive streams may be reconfigured based on the new settings. diff --git a/media/engine/webrtc_voice_engine.h b/media/engine/webrtc_voice_engine.h index 0f7313ea10..7c15e8d7f3 100644 --- a/media/engine/webrtc_voice_engine.h +++ b/media/engine/webrtc_voice_engine.h @@ -218,6 +218,8 @@ class WebRtcVoiceSendChannel final : public MediaChannelUtil, } VoiceMediaSendChannelInterface* AsVoiceSendChannel() override { return this; } + absl::optional GetSendCodec() const override; + // Functions imported from MediaChannelUtil void SetInterface(MediaChannelNetworkInterface* iface) override { MediaChannelUtil::SetInterface(iface); diff --git a/pc/test/mock_voice_media_channel.h b/pc/test/mock_voice_media_channel.h index e3eb42d157..2668032037 100644 --- a/pc/test/mock_voice_media_channel.h +++ b/pc/test/mock_voice_media_channel.h @@ -67,6 +67,7 @@ class MockVoiceMediaChannel : public VoiceMediaChannel { ChooseReceiverReportSsrc, (const std::set&), (override)); + MOCK_METHOD(absl::optional, GetSendCodec, (), (const, override)); MOCK_METHOD(bool, SendCodecHasNack, (), (const, override)); MOCK_METHOD(void, SetSsrcListChangedCallback,