Split MediaChannel concrete functions to MediaChannelUtil

This allows subclasses of MediaSendChannel and MediaReceiveChannel
to derive from MediaChannelUtil without promising to implement
the interfaces.

Bug: webrtc:13931
Change-Id: I998de7566b343032c83cd6e5419f49349f41035f
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/307140
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40185}
diff --git a/media/base/media_channel_impl.cc b/media/base/media_channel_impl.cc
index 0de04b6..f2a5af5 100644
--- a/media/base/media_channel_impl.cc
+++ b/media/base/media_channel_impl.cc
@@ -57,54 +57,57 @@
     : content_hint(VideoTrackInterface::ContentHint::kNone) {}
 VideoOptions::~VideoOptions() = default;
 
-MediaChannel::MediaChannel(Role role,
-                           TaskQueueBase* network_thread,
-                           bool enable_dscp)
-    : role_(role),
-      enable_dscp_(enable_dscp),
+MediaChannelUtil::MediaChannelUtil(TaskQueueBase* network_thread,
+                                   bool enable_dscp)
+    : enable_dscp_(enable_dscp),
       network_safety_(PendingTaskSafetyFlag::CreateDetachedInactive()),
       network_thread_(network_thread) {}
 
-MediaChannel::~MediaChannel() {
+MediaChannel::MediaChannel(Role role,
+                           TaskQueueBase* network_thread,
+                           bool enable_dscp)
+    : MediaChannelUtil(network_thread, enable_dscp), role_(role) {}
+
+MediaChannelUtil::~MediaChannelUtil() {
   RTC_DCHECK(!network_interface_);
 }
 
-void MediaChannel::SetInterface(MediaChannelNetworkInterface* iface) {
+void MediaChannelUtil::SetInterface(MediaChannelNetworkInterface* iface) {
   RTC_DCHECK_RUN_ON(network_thread_);
   iface ? network_safety_->SetAlive() : network_safety_->SetNotAlive();
   network_interface_ = iface;
   UpdateDscp();
 }
 
-int MediaChannel::GetRtpSendTimeExtnId() const {
+int MediaChannelUtil::GetRtpSendTimeExtnId() const {
   return -1;
 }
 
-void MediaChannel::SetFrameEncryptor(
+void MediaChannelUtil::SetFrameEncryptor(
     uint32_t ssrc,
     rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor) {
   // Placeholder should be pure virtual once internal supports it.
 }
 
-void MediaChannel::SetFrameDecryptor(
+void MediaChannelUtil::SetFrameDecryptor(
     uint32_t ssrc,
     rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor) {
   // Placeholder should be pure virtual once internal supports it.
 }
 
-bool MediaChannel::SendPacket(rtc::CopyOnWriteBuffer* packet,
-                              const rtc::PacketOptions& options) {
+bool MediaChannelUtil::SendPacket(rtc::CopyOnWriteBuffer* packet,
+                                  const rtc::PacketOptions& options) {
   return DoSendPacket(packet, false, options);
 }
 
-bool MediaChannel::SendRtcp(rtc::CopyOnWriteBuffer* packet,
-                            const rtc::PacketOptions& options) {
+bool MediaChannelUtil::SendRtcp(rtc::CopyOnWriteBuffer* packet,
+                                const rtc::PacketOptions& options) {
   return DoSendPacket(packet, true, options);
 }
 
-int MediaChannel::SetOption(MediaChannelNetworkInterface::SocketType type,
-                            rtc::Socket::Option opt,
-                            int option) {
+int MediaChannelUtil::SetOption(MediaChannelNetworkInterface::SocketType type,
+                                rtc::Socket::Option opt,
+                                int option) {
   RTC_DCHECK_RUN_ON(network_thread_);
   return SetOptionLocked(type, opt, option);
 }
@@ -113,47 +116,48 @@
 // Set to true if it's allowed to mix one- and two-byte RTP header extensions
 // in the same stream. The setter and getter must only be called from
 // worker_thread.
-void MediaChannel::SetExtmapAllowMixed(bool extmap_allow_mixed) {
+void MediaChannelUtil::SetExtmapAllowMixed(bool extmap_allow_mixed) {
   extmap_allow_mixed_ = extmap_allow_mixed;
 }
 
-bool MediaChannel::ExtmapAllowMixed() const {
+bool MediaChannelUtil::ExtmapAllowMixed() const {
   return extmap_allow_mixed_;
 }
 
-bool MediaChannel::HasNetworkInterface() const {
+bool MediaChannelUtil::HasNetworkInterface() const {
   RTC_DCHECK_RUN_ON(network_thread_);
   return network_interface_ != nullptr;
 }
 
-void MediaChannel::SetEncoderToPacketizerFrameTransformer(
+void MediaChannelUtil::SetEncoderToPacketizerFrameTransformer(
     uint32_t ssrc,
     rtc::scoped_refptr<FrameTransformerInterface> frame_transformer) {}
 
-void MediaChannel::SetDepacketizerToDecoderFrameTransformer(
+void MediaChannelUtil::SetDepacketizerToDecoderFrameTransformer(
     uint32_t ssrc,
     rtc::scoped_refptr<FrameTransformerInterface> frame_transformer) {}
 
-int MediaChannel::SetOptionLocked(MediaChannelNetworkInterface::SocketType type,
-                                  rtc::Socket::Option opt,
-                                  int option) {
+int MediaChannelUtil::SetOptionLocked(
+    MediaChannelNetworkInterface::SocketType type,
+    rtc::Socket::Option opt,
+    int option) {
   if (!network_interface_)
     return -1;
   return network_interface_->SetOption(type, opt, option);
 }
 
-bool MediaChannel::DscpEnabled() const {
+bool MediaChannelUtil::DscpEnabled() const {
   return enable_dscp_;
 }
 
 // This is the DSCP value used for both RTP and RTCP channels if DSCP is
 // enabled. It can be changed at any time via `SetPreferredDscp`.
-rtc::DiffServCodePoint MediaChannel::PreferredDscp() const {
+rtc::DiffServCodePoint MediaChannelUtil::PreferredDscp() const {
   RTC_DCHECK_RUN_ON(network_thread_);
   return preferred_dscp_;
 }
 
-void MediaChannel::SetPreferredDscp(rtc::DiffServCodePoint new_dscp) {
+void MediaChannelUtil::SetPreferredDscp(rtc::DiffServCodePoint new_dscp) {
   if (!network_thread_->IsCurrent()) {
     // This is currently the common path as the derived channel classes
     // get called on the worker thread. There are still some tests though
@@ -171,11 +175,11 @@
   UpdateDscp();
 }
 
-rtc::scoped_refptr<PendingTaskSafetyFlag> MediaChannel::network_safety() {
+rtc::scoped_refptr<PendingTaskSafetyFlag> MediaChannelUtil::network_safety() {
   return network_safety_;
 }
 
-void MediaChannel::UpdateDscp() {
+void MediaChannelUtil::UpdateDscp() {
   rtc::DiffServCodePoint value =
       enable_dscp_ ? preferred_dscp_ : rtc::DSCP_DEFAULT;
   int ret = SetOptionLocked(MediaChannelNetworkInterface::ST_RTP,
@@ -185,9 +189,9 @@
                     rtc::Socket::OPT_DSCP, value);
 }
 
-bool MediaChannel::DoSendPacket(rtc::CopyOnWriteBuffer* packet,
-                                bool rtcp,
-                                const rtc::PacketOptions& options) {
+bool MediaChannelUtil::DoSendPacket(rtc::CopyOnWriteBuffer* packet,
+                                    bool rtcp,
+                                    const rtc::PacketOptions& options) {
   RTC_DCHECK_RUN_ON(network_thread_);
   if (!network_interface_)
     return false;
@@ -196,9 +200,9 @@
                  : network_interface_->SendRtcp(packet, options);
 }
 
-void MediaChannel::SendRtp(const uint8_t* data,
-                           size_t len,
-                           const webrtc::PacketOptions& options) {
+void MediaChannelUtil::SendRtp(const uint8_t* data,
+                               size_t len,
+                               const webrtc::PacketOptions& options) {
   auto send =
       [this, packet_id = options.packet_id,
        included_in_feedback = options.included_in_feedback,
@@ -231,7 +235,7 @@
   }
 }
 
-void MediaChannel::SendRtcp(const uint8_t* data, size_t len) {
+void MediaChannelUtil::SendRtcp(const uint8_t* data, size_t len) {
   auto send = [this, packet = rtc::CopyOnWriteBuffer(
                          data, len, kMaxRtpPacketLen)]() mutable {
     rtc::PacketOptions rtc_options;
diff --git a/media/base/media_channel_impl.h b/media/base/media_channel_impl.h
index e3c8cc1..dfd9fb3 100644
--- a/media/base/media_channel_impl.h
+++ b/media/base/media_channel_impl.h
@@ -62,56 +62,21 @@
 // the MediaChannel interfaces.
 // These implementation classes used to be the exposed interface names,
 // but this is in the process of being changed.
-// TODO(bugs.webrtc.org/13931): Consider removing these classes.
-
-// The target
+// TODO(bugs.webrtc.org/13931): Remove the MediaChannel class.
 
 namespace cricket {
 
 class VoiceMediaChannel;
 class VideoMediaChannel;
 
-class MediaChannel : public MediaSendChannelInterface,
-                     public MediaReceiveChannelInterface {
+// The `MediaChannelUtil` class provides functionality that is used by
+// multiple MediaChannel-like objects, of both sending and receiving
+// types.
+class MediaChannelUtil {
  public:
-  // Role of the channel. Used to describe which interface it supports.
-  // This is temporary until we stop using the same implementation for both
-  // interfaces.
-  enum class Role {
-    kSend,
-    kReceive,
-    kBoth  // Temporary value for non-converted test and downstream code
-    // TODO(bugs.webrtc.org/13931): Remove kBoth when usage is removed.
-  };
-
-  explicit MediaChannel(Role role,
-                        webrtc::TaskQueueBase* network_thread,
-                        bool enable_dscp = false);
-  virtual ~MediaChannel();
-
-  Role role() const { return role_; }
-
-  // Downcasting to the subclasses.
-  virtual VideoMediaChannel* AsVideoChannel() {
-    RTC_CHECK_NOTREACHED();
-    return nullptr;
-  }
-
-  virtual VoiceMediaChannel* AsVoiceChannel() {
-    RTC_CHECK_NOTREACHED();
-    return nullptr;
-  }
-  // Must declare the methods inherited from the base interface template,
-  // even when abstract, to tell the compiler that all instances of the name
-  // referred to by subclasses of this share the same implementation.
-  cricket::MediaType media_type() const override = 0;
-  void OnPacketReceived(const webrtc::RtpPacketReceived& packet) override = 0;
-  void OnPacketSent(const rtc::SentPacket& sent_packet) override = 0;
-  void OnReadyToSend(bool ready) override = 0;
-  void OnNetworkRouteChanged(absl::string_view transport_name,
-                             const rtc::NetworkRoute& network_route) override =
-      0;
-
+  MediaChannelUtil(webrtc::TaskQueueBase* network_thread,
+                   bool enable_dscp = false);
+  virtual ~MediaChannelUtil();
   // Returns the absolute sendtime extension id value from media channel.
   virtual int GetRtpSendTimeExtnId() const;
   // Base method to send packet using MediaChannelNetworkInterface.
@@ -125,33 +90,35 @@
                 rtc::Socket::Option opt,
                 int option);
 
+  // Functions that form part of one or more interface classes.
+  // Not marked override, since this class does not inherit from the
+  // interfaces.
+
   // Corresponds to the SDP attribute extmap-allow-mixed, see RFC8285.
   // Set to true if it's allowed to mix one- and two-byte RTP header extensions
   // in the same stream. The setter and getter must only be called from
   // worker_thread.
-  void SetExtmapAllowMixed(bool extmap_allow_mixed) override;
-  bool ExtmapAllowMixed() const override;
+  void SetExtmapAllowMixed(bool extmap_allow_mixed);
+  bool ExtmapAllowMixed() const;
 
-  void SetInterface(MediaChannelNetworkInterface* iface) override;
+  void SetInterface(MediaChannelNetworkInterface* iface);
   // Returns `true` if a non-null MediaChannelNetworkInterface pointer is held.
   // Must be called on the network thread.
-  bool HasNetworkInterface() const override;
+  bool HasNetworkInterface() const;
 
-  void SetFrameEncryptor(uint32_t ssrc,
-                         rtc::scoped_refptr<webrtc::FrameEncryptorInterface>
-                             frame_encryptor) override;
-  void SetFrameDecryptor(uint32_t ssrc,
-                         rtc::scoped_refptr<webrtc::FrameDecryptorInterface>
-                             frame_decryptor) override;
+  void SetFrameEncryptor(
+      uint32_t ssrc,
+      rtc::scoped_refptr<webrtc::FrameEncryptorInterface> frame_encryptor);
+  void SetFrameDecryptor(
+      uint32_t ssrc,
+      rtc::scoped_refptr<webrtc::FrameDecryptorInterface> frame_decryptor);
 
   void SetEncoderToPacketizerFrameTransformer(
       uint32_t ssrc,
-      rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer)
-      override;
+      rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer);
   void SetDepacketizerToDecoderFrameTransformer(
       uint32_t ssrc,
-      rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer)
-      override;
+      rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer);
 
  protected:
   int SetOptionLocked(MediaChannelNetworkInterface::SocketType type,
@@ -184,7 +151,6 @@
                     bool rtcp,
                     const rtc::PacketOptions& options);
 
-  const Role role_;
   const bool enable_dscp_;
   const rtc::scoped_refptr<webrtc::PendingTaskSafetyFlag> network_safety_
       RTC_PT_GUARDED_BY(network_thread_);
@@ -196,6 +162,61 @@
   bool extmap_allow_mixed_ = false;
 };
 
+// The `MediaChannel` class implements both the SendChannel and
+// ReceiveChannel interface. It is used in legacy code that does not
+// use the split interfaces.
+class MediaChannel : public MediaChannelUtil,
+                     public MediaSendChannelInterface,
+                     public MediaReceiveChannelInterface {
+ public:
+  // Role of the channel. Used to describe which interface it supports.
+  // This is temporary until we stop using the same implementation for both
+  // interfaces.
+  enum class Role {
+    kSend,
+    kReceive,
+    kBoth  // Temporary value for non-converted test and downstream code
+    // TODO(bugs.webrtc.org/13931): Remove kBoth when usage is removed.
+  };
+
+  explicit MediaChannel(Role role,
+                        webrtc::TaskQueueBase* network_thread,
+                        bool enable_dscp = false);
+  virtual ~MediaChannel() = default;
+
+  Role role() const { return role_; }
+
+  // Downcasting to the subclasses.
+  virtual VideoMediaChannel* AsVideoChannel() {
+    RTC_CHECK_NOTREACHED();
+    return nullptr;
+  }
+
+  virtual VoiceMediaChannel* AsVoiceChannel() {
+    RTC_CHECK_NOTREACHED();
+    return nullptr;
+  }
+  // Must declare the methods inherited from the base interface template,
+  // even when abstract, to tell the compiler that all instances of the name
+  // referred to by subclasses of this share the same implementation.
+  cricket::MediaType media_type() const override = 0;
+  void OnPacketReceived(const webrtc::RtpPacketReceived& packet) override = 0;
+  void OnPacketSent(const rtc::SentPacket& sent_packet) override = 0;
+  void OnReadyToSend(bool ready) override = 0;
+  void OnNetworkRouteChanged(absl::string_view transport_name,
+                             const rtc::NetworkRoute& network_route) override =
+      0;
+
+  // Methods from the APIs that are implemented in MediaChannelUtil
+  using MediaChannelUtil::ExtmapAllowMixed;
+  using MediaChannelUtil::HasNetworkInterface;
+  using MediaChannelUtil::SetExtmapAllowMixed;
+  using MediaChannelUtil::SetInterface;
+
+ private:
+  const Role role_;
+};
+
 // Base class for implementation classes
 
 class VideoMediaChannel : public MediaChannel,