Move GetSendCodec() to MediaSendChannelInterface

This allows the voice send channels to share the method definition.

Bug: webrtc:15214
Change-Id: Ie0cc23f3694eeb8322a9ea7328a8d56fa7571c95
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/309600
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40322}
diff --git a/media/BUILD.gn b/media/BUILD.gn
index 8508a7b..c0aba7a 100644
--- a/media/BUILD.gn
+++ b/media/BUILD.gn
@@ -293,6 +293,7 @@
     ":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 7a238cf..70a8d90 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(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 @@
   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 1ca0931..74c5cc2 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 @@
         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 @@
                        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 5e4ecd3..e31ffad 100644
--- a/media/base/fake_media_engine.cc
+++ b/media/base/fake_media_engine.cc
@@ -74,6 +74,12 @@
 const std::vector<AudioCodec>& FakeVoiceMediaChannel::codecs() const {
   return send_codecs();
 }
+absl::optional<Codec> FakeVoiceMediaChannel::GetSendCodec() const {
+  if (!send_codecs_.empty()) {
+    return send_codecs_.front();
+  }
+  return absl::nullopt;
+}
 const std::vector<FakeVoiceMediaChannel::DtmfInfo>&
 FakeVoiceMediaChannel::dtmf_info_queue() const {
   return dtmf_info_queue_;
@@ -317,7 +323,7 @@
 bool FakeVideoMediaChannel::RemoveSendStream(uint32_t ssrc) {
   return RtpHelper<VideoMediaChannel>::RemoveSendStream(ssrc);
 }
-absl::optional<VideoCodec> FakeVideoMediaChannel::GetSendCodec() {
+absl::optional<Codec> 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 26fe276..caa5fab 100644
--- a/media/base/fake_media_engine.h
+++ b/media/base/fake_media_engine.h
@@ -423,6 +423,7 @@
   bool SendCodecHasNack() const override { return false; }
   void SetSendCodecChangedCallback(
       absl::AnyInvocable<void()> callback) override {}
+  absl::optional<Codec> GetSendCodec() const override;
 
  private:
   class VoiceChannelAudioSink : public AudioSource::Sink {
@@ -489,7 +490,7 @@
   bool AddSendStream(const StreamParams& sp) override;
   bool RemoveSendStream(uint32_t ssrc) override;
 
-  absl::optional<VideoCodec> GetSendCodec() override;
+  absl::optional<Codec> GetSendCodec() const override;
   bool SetSink(uint32_t ssrc,
                rtc::VideoSinkInterface<webrtc::VideoFrame>* sink) override;
   void SetDefaultSink(
diff --git a/media/base/media_channel.h b/media/base/media_channel.h
index ea6384a..e18e1d3 100644
--- a/media/base/media_channel.h
+++ b/media/base/media_channel.h
@@ -193,6 +193,9 @@
   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<Codec> 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 @@
 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<VideoCodec> 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 e4dbee7..f051d1a 100644
--- a/media/base/media_channel_shim.h
+++ b/media/base/media_channel_shim.h
@@ -87,6 +87,9 @@
   cricket::MediaType media_type() const override { return MEDIA_TYPE_AUDIO; }
 
   // Implementation of MediaSendChannelInterface
+  absl::optional<Codec> GetSendCodec() const override {
+    return send_impl()->GetSendCodec();
+  }
   void OnPacketSent(const rtc::SentPacket& sent_packet) override {
     send_impl()->OnPacketSent(sent_packet);
   }
@@ -385,7 +388,7 @@
   bool SetSendParameters(const VideoSendParameters& params) override {
     return send_impl()->SetSendParameters(params);
   }
-  absl::optional<VideoCodec> GetSendCodec() override {
+  absl::optional<Codec> 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 bbda10d..68df906 100644
--- a/media/engine/webrtc_video_engine.cc
+++ b/media/engine/webrtc_video_engine.cc
@@ -1300,7 +1300,7 @@
 
   return it->second->SetRtpParameters(parameters, std::move(callback));
 }
-absl::optional<VideoCodec> WebRtcVideoSendChannel::GetSendCodec() {
+absl::optional<Codec> 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 e210f04..e1413b7 100644
--- a/media/engine/webrtc_video_engine.h
+++ b/media/engine/webrtc_video_engine.h
@@ -207,7 +207,7 @@
       const webrtc::RtpParameters& parameters,
       webrtc::SetParametersCallback callback) override;
   webrtc::RtpParameters GetRtpSendParameters(uint32_t ssrc) const override;
-  absl::optional<VideoCodec> GetSendCodec() override;
+  absl::optional<Codec> 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 3f6cd25..784d614 100644
--- a/media/engine/webrtc_video_engine_unittest.cc
+++ b/media/engine/webrtc_video_engine_unittest.cc
@@ -2539,7 +2539,7 @@
   parameters.codecs.push_back(GetEngineCodec("VP8"));
   EXPECT_TRUE(channel_->SetSendParameters(parameters));
 
-  absl::optional<VideoCodec> codec = channel_->GetSendCodec();
+  absl::optional<VideoCodec> codec = send_channel_->GetSendCodec();
   ASSERT_TRUE(codec);
   EXPECT_EQ("VP9", codec->name);
 
@@ -2547,14 +2547,14 @@
   // 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 @@
   parameters.codecs.push_back(GetEngineCodec("VP8"));
   EXPECT_TRUE(channel_->SetSendParameters(parameters));
 
-  absl::optional<VideoCodec> codec = channel_->GetSendCodec();
+  absl::optional<VideoCodec> codec = send_channel_->GetSendCodec();
   ASSERT_TRUE(codec);
   EXPECT_EQ("VP9", codec->name);
 
@@ -2577,7 +2577,7 @@
 
   // 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 @@
   parameters.codecs.push_back(vp9);
   EXPECT_TRUE(channel_->SetSendParameters(parameters));
 
-  absl::optional<VideoCodec> codec = channel_->GetSendCodec();
+  absl::optional<VideoCodec> codec = send_channel_->GetSendCodec();
   ASSERT_TRUE(codec);
   EXPECT_EQ("VP8", codec->name);
 
@@ -2602,7 +2602,7 @@
 
   // 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 @@
   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 @@
   AssignDefaultAptRtxTypes();
   ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
 
-  absl::optional<VideoCodec> codec = channel_->GetSendCodec();
+  absl::optional<VideoCodec> codec = send_channel_->GetSendCodec();
   ASSERT_TRUE(codec);
   EXPECT_TRUE(codec->Matches(engine_.send_codecs()[0], &field_trials_));
 
@@ -5036,7 +5036,7 @@
   EXPECT_EQ(atoi(kMaxQuantization),
             AddSendStream()->GetVideoStreams().back().max_qp);
 
-  absl::optional<VideoCodec> codec = channel_->GetSendCodec();
+  absl::optional<VideoCodec> codec = send_channel_->GetSendCodec();
   ASSERT_TRUE(codec);
   EXPECT_EQ(kMaxQuantization, codec->params[kCodecParamMaxQuantization]);
 }
@@ -9751,7 +9751,7 @@
   EXPECT_TRUE(channel_->SetSendParameters(parameters));
   channel_->SetSend(true);
 
-  absl::optional<VideoCodec> codec = channel_->GetSendCodec();
+  absl::optional<VideoCodec> codec = send_channel_->GetSendCodec();
   ASSERT_TRUE(codec);
   EXPECT_EQ("VP8", codec->name);
 
@@ -9762,7 +9762,7 @@
   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 1ee0c21..74d0d53 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 @@
   return SetOptions(params.options);
 }
 
+absl::optional<Codec> 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 0f7313e..7c15e8d 100644
--- a/media/engine/webrtc_voice_engine.h
+++ b/media/engine/webrtc_voice_engine.h
@@ -218,6 +218,8 @@
   }
   VoiceMediaSendChannelInterface* AsVoiceSendChannel() override { return this; }
 
+  absl::optional<Codec> 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 e3eb42d..2668032 100644
--- a/pc/test/mock_voice_media_channel.h
+++ b/pc/test/mock_voice_media_channel.h
@@ -67,6 +67,7 @@
               ChooseReceiverReportSsrc,
               (const std::set<uint32_t>&),
               (override));
+  MOCK_METHOD(absl::optional<Codec>, GetSendCodec, (), (const, override));
   MOCK_METHOD(bool, SendCodecHasNack, (), (const, override));
   MOCK_METHOD(void,
               SetSsrcListChangedCallback,