- Rename VoiceChannel::MuteStream() -> SetAudioSend() (incl. media channel)
- Rename VideoChannel::MuteStream() -> SetVideoSend() (incl. media channel)
- Collapse NnChannel::SetChannelOptions() into the above.
- Collapse VoiceChannel::SetLocalRenderer into SetAudioSend().

BUG=webrtc:4690

Review URL: https://codereview.webrtc.org/1311533009

Cr-Commit-Position: refs/heads/master@{#9915}
diff --git a/talk/app/webrtc/webrtcsession.cc b/talk/app/webrtc/webrtcsession.cc
index 082e214..179d793 100644
--- a/talk/app/webrtc/webrtcsession.cc
+++ b/talk/app/webrtc/webrtcsession.cc
@@ -1182,20 +1182,9 @@
     LOG(LS_ERROR) << "SetAudioSend: No audio channel exists.";
     return;
   }
-  if (!voice_channel_->SetLocalRenderer(ssrc, renderer)) {
-    // SetRenderer() can fail if the ssrc does not match any send channel.
+  if (!voice_channel_->SetAudioSend(ssrc, !enable, &options, renderer)) {
     LOG(LS_ERROR) << "SetAudioSend: ssrc is incorrect: " << ssrc;
-    return;
   }
-  if (!voice_channel_->MuteStream(ssrc, !enable)) {
-    // Allow that MuteStream fail if |enable| is false but assert otherwise.
-    // This in the normal case when the underlying media channel has already
-    // been deleted.
-    ASSERT(enable == false);
-    return;
-  }
-  if (enable)
-    voice_channel_->SetChannelOptions(options);
 }
 
 void WebRtcSession::SetAudioPlayoutVolume(uint32 ssrc, double volume) {
@@ -1254,15 +1243,12 @@
     LOG(LS_WARNING) << "SetVideoSend: No video channel exists.";
     return;
   }
-  if (!video_channel_->MuteStream(ssrc, !enable)) {
+  if (!video_channel_->SetVideoSend(ssrc, !enable, options)) {
     // Allow that MuteStream fail if |enable| is false but assert otherwise.
     // This in the normal case when the underlying media channel has already
     // been deleted.
     ASSERT(enable == false);
-    return;
   }
-  if (enable && options)
-    video_channel_->SetChannelOptions(*options);
 }
 
 bool WebRtcSession::CanInsertDtmf(const std::string& track_id) {
diff --git a/talk/media/base/fakemediaengine.h b/talk/media/base/fakemediaengine.h
index 47ec402..56986c5 100644
--- a/talk/media/base/fakemediaengine.h
+++ b/talk/media/base/fakemediaengine.h
@@ -137,15 +137,6 @@
   virtual bool RemoveRecvStream(uint32 ssrc) {
     return RemoveStreamBySsrc(&receive_streams_, ssrc);
   }
-  virtual bool MuteStream(uint32 ssrc, bool on) {
-    if (!HasSendStream(ssrc) && ssrc != 0)
-      return false;
-    if (on)
-      muted_streams_.insert(ssrc);
-    else
-      muted_streams_.erase(ssrc);
-    return true;
-  }
   bool IsStreamMuted(uint32 ssrc) const {
     bool ret = muted_streams_.find(ssrc) != muted_streams_.end();
     // If |ssrc = 0| check if the first send stream is muted.
@@ -188,6 +179,15 @@
   }
 
  protected:
+  bool MuteStream(uint32 ssrc, bool mute) {
+    if (!HasSendStream(ssrc) && ssrc != 0)
+      return false;
+    if (mute)
+      muted_streams_.insert(ssrc);
+    else
+      muted_streams_.erase(ssrc);
+    return true;
+  }
   bool set_sending(bool send) {
     sending_ = send;
     return true;
@@ -283,6 +283,20 @@
     }
     return set_sending(flag != SEND_NOTHING);
   }
+  virtual bool SetAudioSend(uint32 ssrc, bool mute,
+                            const AudioOptions* options,
+                            AudioRenderer* renderer) {
+    if (!SetLocalRenderer(ssrc, renderer)) {
+      return false;
+    }
+    if (!RtpHelper<VoiceMediaChannel>::MuteStream(ssrc, mute)) {
+      return false;
+    }
+    if (!mute && options) {
+      return SetOptions(*options);
+    }
+    return true;
+  }
   virtual bool SetMaxSendBandwidth(int bps) { return true; }
   virtual bool AddRecvStream(const StreamParams& sp) {
     if (!RtpHelper<VoiceMediaChannel>::AddRecvStream(sp))
@@ -316,26 +330,6 @@
     }
     return true;
   }
-  virtual bool SetLocalRenderer(uint32 ssrc, AudioRenderer* renderer) {
-    std::map<uint32, VoiceChannelAudioSink*>::iterator it =
-        local_renderers_.find(ssrc);
-    if (renderer) {
-      if (it != local_renderers_.end()) {
-        ASSERT(it->second->renderer() == renderer);
-      } else {
-        local_renderers_.insert(std::make_pair(
-            ssrc, new VoiceChannelAudioSink(renderer)));
-      }
-    } else {
-      if (it != local_renderers_.end()) {
-        delete it->second;
-        local_renderers_.erase(it);
-      } else {
-        return false;
-      }
-    }
-    return true;
-  }
 
   virtual bool GetActiveStreams(AudioInfo::StreamList* streams) { return true; }
   virtual int GetOutputLevel() { return 0; }
@@ -442,6 +436,23 @@
     AudioRenderer* renderer_;
   };
 
+  bool SetLocalRenderer(uint32 ssrc, AudioRenderer* renderer) {
+    auto it = local_renderers_.find(ssrc);
+    if (renderer) {
+      if (it != local_renderers_.end()) {
+        ASSERT(it->second->renderer() == renderer);
+      } else {
+        local_renderers_.insert(std::make_pair(
+            ssrc, new VoiceChannelAudioSink(renderer)));
+      }
+    } else {
+      if (it != local_renderers_.end()) {
+        delete it->second;
+        local_renderers_.erase(it);
+      }
+    }
+    return true;
+  }
 
   FakeVoiceEngine* engine_;
   std::vector<AudioCodec> recv_codecs_;
@@ -556,6 +567,17 @@
   }
 
   virtual bool SetSend(bool send) { return set_sending(send); }
+  virtual bool SetVideoSend(uint32 ssrc, bool mute,
+                            const VideoOptions* options) {
+    if (!RtpHelper<VideoMediaChannel>::MuteStream(ssrc, mute)) {
+      return false;
+    }
+    if (!mute && options) {
+      return SetOptions(*options);
+    } else {
+      return true;
+    }
+  }
   virtual bool SetCapturer(uint32 ssrc, VideoCapturer* capturer) {
     capturers_[ssrc] = capturer;
     return true;
diff --git a/talk/media/base/mediachannel.h b/talk/media/base/mediachannel.h
index 7c76d2b..cfeb2d8 100644
--- a/talk/media/base/mediachannel.h
+++ b/talk/media/base/mediachannel.h
@@ -566,9 +566,6 @@
   // multiple SSRCs.
   virtual bool RemoveRecvStream(uint32 ssrc) = 0;
 
-  // Mutes the channel.
-  virtual bool MuteStream(uint32 ssrc, bool on) = 0;
-
   // Sets the RTP extension headers and IDs to use when sending RTP.
   virtual bool SetRecvRtpHeaderExtensions(
       const std::vector<RtpHeaderExtension>& extensions) = 0;
@@ -1097,10 +1094,11 @@
   virtual bool SetPlayout(bool playout) = 0;
   // Starts or stops sending (and potentially capture) of local audio.
   virtual bool SetSend(SendFlags flag) = 0;
+  // Configure stream for sending.
+  virtual bool SetAudioSend(uint32 ssrc, bool mute, const AudioOptions* options,
+                            AudioRenderer* renderer) = 0;
   // Sets the renderer object to be used for the specified remote audio stream.
   virtual bool SetRemoteRenderer(uint32 ssrc, AudioRenderer* renderer) = 0;
-  // Sets the renderer object to be used for the specified local audio stream.
-  virtual bool SetLocalRenderer(uint32 ssrc, AudioRenderer* renderer) = 0;
   // Gets current energy levels for all incoming streams.
   virtual bool GetActiveStreams(AudioInfo::StreamList* actives) = 0;
   // Get the current energy level of the stream sent to the speaker.
@@ -1196,6 +1194,9 @@
   virtual bool SetRender(bool render) = 0;
   // Starts or stops transmission (and potentially capture) of local video.
   virtual bool SetSend(bool send) = 0;
+  // Configure stream for sending.
+  virtual bool SetVideoSend(uint32 ssrc, bool mute,
+                            const VideoOptions* options) = 0;
   // Sets the renderer object to be used for the specified stream.
   // If SSRC is 0, the renderer is used for the 'default' stream.
   virtual bool SetRenderer(uint32 ssrc, VideoRenderer* renderer) = 0;
@@ -1337,7 +1338,6 @@
   virtual bool SetSendCodecs(const std::vector<DataCodec>& codecs) = 0;
   virtual bool SetRecvCodecs(const std::vector<DataCodec>& codecs) = 0;
 
-  virtual bool MuteStream(uint32 ssrc, bool on) { return false; }
   // TODO(pthatcher): Implement this.
   virtual bool GetStats(DataMediaInfo* info) { return true; }
 
diff --git a/talk/media/base/videoengine_unittest.h b/talk/media/base/videoengine_unittest.h
index 5f00a0e..c74479c 100644
--- a/talk/media/base/videoengine_unittest.h
+++ b/talk/media/base/videoengine_unittest.h
@@ -1647,48 +1647,41 @@
     EXPECT_TRUE(channel_->SetRender(true));
     EXPECT_TRUE(channel_->SetRenderer(kDefaultReceiveSsrc, &renderer_));
     EXPECT_EQ(0, renderer_.num_rendered_frames());
-
     // Mute the channel and expect black output frame.
     int frame_count = 0;
-    EXPECT_TRUE(channel_->MuteStream(kSsrc, true));
+    EXPECT_TRUE(channel_->SetVideoSend(kSsrc, true, nullptr));
     EXPECT_TRUE(video_capturer.CaptureFrame());
     ++frame_count;
     EXPECT_EQ_WAIT(frame_count, renderer_.num_rendered_frames(), kTimeout);
     EXPECT_TRUE(renderer_.black_frame());
-
     // Unmute the channel and expect non-black output frame.
-    EXPECT_TRUE(channel_->MuteStream(kSsrc, false));
+    EXPECT_TRUE(channel_->SetVideoSend(kSsrc, false, nullptr));
     EXPECT_TRUE(rtc::Thread::Current()->ProcessMessages(30));
     EXPECT_TRUE(video_capturer.CaptureFrame());
     ++frame_count;
     EXPECT_EQ_WAIT(frame_count, renderer_.num_rendered_frames(), kTimeout);
     EXPECT_FALSE(renderer_.black_frame());
-
     // Test that we can also Mute using the correct send stream SSRC.
-    EXPECT_TRUE(channel_->MuteStream(kSsrc, true));
+    EXPECT_TRUE(channel_->SetVideoSend(kSsrc, true, nullptr));
     EXPECT_TRUE(rtc::Thread::Current()->ProcessMessages(30));
     EXPECT_TRUE(video_capturer.CaptureFrame());
     ++frame_count;
     EXPECT_EQ_WAIT(frame_count, renderer_.num_rendered_frames(), kTimeout);
     EXPECT_TRUE(renderer_.black_frame());
-
-    EXPECT_TRUE(channel_->MuteStream(kSsrc, false));
+    EXPECT_TRUE(channel_->SetVideoSend(kSsrc, false, nullptr));
     EXPECT_TRUE(rtc::Thread::Current()->ProcessMessages(30));
     EXPECT_TRUE(video_capturer.CaptureFrame());
     ++frame_count;
     EXPECT_EQ_WAIT(frame_count, renderer_.num_rendered_frames(), kTimeout);
     EXPECT_FALSE(renderer_.black_frame());
-
     // Test that muting an existing stream succeeds even if it's muted.
-    EXPECT_TRUE(channel_->MuteStream(kSsrc, true));
-    EXPECT_TRUE(channel_->MuteStream(kSsrc, true));
-
+    EXPECT_TRUE(channel_->SetVideoSend(kSsrc, true, nullptr));
+    EXPECT_TRUE(channel_->SetVideoSend(kSsrc, true, nullptr));
     // Test that unmuting an existing stream succeeds even if it's not muted.
-    EXPECT_TRUE(channel_->MuteStream(kSsrc, false));
-    EXPECT_TRUE(channel_->MuteStream(kSsrc, false));
-
+    EXPECT_TRUE(channel_->SetVideoSend(kSsrc, false, nullptr));
+    EXPECT_TRUE(channel_->SetVideoSend(kSsrc, false, nullptr));
     // Test that muting an invalid stream fails.
-    EXPECT_FALSE(channel_->MuteStream(kSsrc+1, true));
+    EXPECT_FALSE(channel_->SetVideoSend(kSsrc+1, true, nullptr));
     EXPECT_TRUE(channel_->SetCapturer(kSsrc, NULL));
   }
 
diff --git a/talk/media/webrtc/webrtcvideoengine2.cc b/talk/media/webrtc/webrtcvideoengine2.cc
index 60a7022..e94c0b1 100644
--- a/talk/media/webrtc/webrtcvideoengine2.cc
+++ b/talk/media/webrtc/webrtcvideoengine2.cc
@@ -1095,6 +1095,20 @@
   return true;
 }
 
+bool WebRtcVideoChannel2::SetVideoSend(uint32 ssrc, bool mute,
+                                       const VideoOptions* options) {
+  // TODO(solenberg): The state change should be fully rolled back if any one of
+  //                  these calls fail.
+  if (!MuteStream(ssrc, mute)) {
+    return false;
+  }
+  if (!mute && options) {
+    return SetOptions(*options);
+  } else {
+    return true;
+  }
+}
+
 bool WebRtcVideoChannel2::ValidateSendSsrcAvailability(
     const StreamParams& sp) const {
   for (uint32_t ssrc: sp.ssrcs) {
diff --git a/talk/media/webrtc/webrtcvideoengine2.h b/talk/media/webrtc/webrtcvideoengine2.h
index eabea76..f27099b 100644
--- a/talk/media/webrtc/webrtcvideoengine2.h
+++ b/talk/media/webrtc/webrtcvideoengine2.h
@@ -193,7 +193,8 @@
   bool SetSendStreamFormat(uint32 ssrc, const VideoFormat& format) override;
   bool SetRender(bool render) override;
   bool SetSend(bool send) override;
-
+  bool SetVideoSend(uint32 ssrc, bool mute,
+                    const VideoOptions* options) override;
   bool AddSendStream(const StreamParams& sp) override;
   bool RemoveSendStream(uint32 ssrc) override;
   bool AddRecvStream(const StreamParams& sp) override;
@@ -210,7 +211,6 @@
   void OnRtcpReceived(rtc::Buffer* packet,
                       const rtc::PacketTime& packet_time) override;
   void OnReadyToSend(bool ready) override;
-  bool MuteStream(uint32 ssrc, bool mute) override;
 
   // Set send/receive RTP header extensions. This must be done before creating
   // streams as it only has effect on future streams.
@@ -233,6 +233,7 @@
   bool GetRenderer(uint32 ssrc, VideoRenderer** renderer);
 
  private:
+  bool MuteStream(uint32 ssrc, bool mute);
   class WebRtcVideoReceiveStream;
   void ConfigureReceiverRtp(webrtc::VideoReceiveStream::Config* config,
                             const StreamParams& sp) const;
diff --git a/talk/media/webrtc/webrtcvoiceengine.cc b/talk/media/webrtc/webrtcvoiceengine.cc
index bcf1738..43cbc2e 100644
--- a/talk/media/webrtc/webrtcvoiceengine.cc
+++ b/talk/media/webrtc/webrtcvoiceengine.cc
@@ -2374,6 +2374,23 @@
   return true;
 }
 
+bool WebRtcVoiceMediaChannel::SetAudioSend(uint32 ssrc, bool mute,
+                                           const AudioOptions* options,
+                                           AudioRenderer* renderer) {
+  // TODO(solenberg): The state change should be fully rolled back if any one of
+  //                  these calls fail.
+  if (!SetLocalRenderer(ssrc, renderer)) {
+    return false;
+  }
+  if (!MuteStream(ssrc, mute)) {
+    return false;
+  }
+  if (!mute && options) {
+    return SetOptions(*options);
+  }
+  return true;
+}
+
 // TODO(ronghuawu): Change this method to return bool.
 void WebRtcVoiceMediaChannel::ConfigureSendChannel(int channel) {
   if (engine()->voe()->network()->RegisterExternalTransport(
diff --git a/talk/media/webrtc/webrtcvoiceengine.h b/talk/media/webrtc/webrtcvoiceengine.h
index 4b35ba7..951c878 100644
--- a/talk/media/webrtc/webrtcvoiceengine.h
+++ b/talk/media/webrtc/webrtcvoiceengine.h
@@ -302,12 +302,13 @@
   bool SetSend(SendFlags send) override;
   bool PauseSend();
   bool ResumeSend();
+  bool SetAudioSend(uint32 ssrc, bool mute, const AudioOptions* options,
+                    AudioRenderer* renderer) override;
   bool AddSendStream(const StreamParams& sp) override;
   bool RemoveSendStream(uint32 ssrc) override;
   bool AddRecvStream(const StreamParams& sp) override;
   bool RemoveRecvStream(uint32 ssrc) override;
   bool SetRemoteRenderer(uint32 ssrc, AudioRenderer* renderer) override;
-  bool SetLocalRenderer(uint32 ssrc, AudioRenderer* renderer) override;
   bool GetActiveStreams(AudioInfo::StreamList* actives) override;
   int GetOutputLevel() override;
   int GetTimeSinceLastTyping() override;
@@ -328,7 +329,6 @@
   void OnRtcpReceived(rtc::Buffer* packet,
                       const rtc::PacketTime& packet_time) override;
   void OnReadyToSend(bool ready) override {}
-  bool MuteStream(uint32 ssrc, bool on) override;
   bool SetMaxSendBandwidth(int bps) override;
   bool GetStats(VoiceMediaInfo* info) override;
   // Gets last reported error from WebRtc voice engine.  This should be only
@@ -359,6 +359,8 @@
   void SetCall(webrtc::Call* call);
 
  private:
+  bool SetLocalRenderer(uint32 ssrc, AudioRenderer* renderer);
+  bool MuteStream(uint32 ssrc, bool mute);
   WebRtcVoiceEngine* engine() { return engine_; }
   int GetLastEngineError() { return engine()->GetLastEngineError(); }
   int GetOutputLevel(int channel);
diff --git a/talk/session/media/channel.cc b/talk/session/media/channel.cc
index 4288291..294681e 100644
--- a/talk/session/media/channel.cc
+++ b/talk/session/media/channel.cc
@@ -322,14 +322,6 @@
   return true;
 }
 
-bool BaseChannel::MuteStream(uint32 ssrc, bool mute) {
-  return InvokeOnWorker(Bind(&BaseChannel::MuteStream_w, this, ssrc, mute));
-}
-
-bool BaseChannel::IsStreamMuted(uint32 ssrc) {
-  return InvokeOnWorker(Bind(&BaseChannel::IsStreamMuted_w, this, ssrc));
-}
-
 bool BaseChannel::AddRecvStream(const StreamParams& sp) {
   return InvokeOnWorker(Bind(&BaseChannel::AddRecvStream_w, this, sp));
 }
@@ -723,23 +715,6 @@
   ChangeState();
 }
 
-bool BaseChannel::MuteStream_w(uint32 ssrc, bool mute) {
-  ASSERT(worker_thread_ == rtc::Thread::Current());
-  bool ret = media_channel()->MuteStream(ssrc, mute);
-  if (ret) {
-    if (mute)
-      muted_streams_.insert(ssrc);
-    else
-      muted_streams_.erase(ssrc);
-  }
-  return ret;
-}
-
-bool BaseChannel::IsStreamMuted_w(uint32 ssrc) {
-  ASSERT(worker_thread_ == rtc::Thread::Current());
-  return muted_streams_.find(ssrc) != muted_streams_.end();
-}
-
 void BaseChannel::ChannelWritable_w() {
   ASSERT(worker_thread_ == rtc::Thread::Current());
   if (writable_)
@@ -1289,9 +1264,11 @@
                              media_channel(), ssrc, renderer));
 }
 
-bool VoiceChannel::SetLocalRenderer(uint32 ssrc, AudioRenderer* renderer) {
-  return InvokeOnWorker(Bind(&VoiceMediaChannel::SetLocalRenderer,
-                             media_channel(), ssrc, renderer));
+bool VoiceChannel::SetAudioSend(uint32 ssrc, bool mute,
+                                const AudioOptions* options,
+                                AudioRenderer* renderer) {
+  return InvokeOnWorker(Bind(&VoiceMediaChannel::SetAudioSend,
+                             media_channel(), ssrc, mute, options, renderer));
 }
 
 bool VoiceChannel::SetRingbackTone(const void* buf, int len) {
@@ -1560,11 +1537,6 @@
   return media_channel()->InsertDtmf(ssrc, event, duration, flags);
 }
 
-bool VoiceChannel::SetChannelOptions(const AudioOptions& options) {
-  return InvokeOnWorker(Bind(&VoiceMediaChannel::SetOptions,
-                             media_channel(), options));
-}
-
 void VoiceChannel::OnMessage(rtc::Message *pmsg) {
   switch (pmsg->message_id) {
     case MSG_EARLYMEDIATIMEOUT:
@@ -1735,6 +1707,12 @@
   return true;
 }
 
+bool VideoChannel::SetVideoSend(uint32 ssrc, bool mute,
+                                const VideoOptions* options) {
+  return InvokeOnWorker(Bind(&VideoMediaChannel::SetVideoSend,
+                             media_channel(), ssrc, mute, options));
+}
+
 void VideoChannel::ChangeState() {
   // Render incoming data if we're the active call, and we have the local
   // content. We receive data on the default channel and multiplexed streams.
@@ -1952,11 +1930,6 @@
   SignalScreencastWindowEvent(ssrc, we);
 }
 
-bool VideoChannel::SetChannelOptions(const VideoOptions &options) {
-  return InvokeOnWorker(Bind(&VideoMediaChannel::SetOptions,
-                             media_channel(), options));
-}
-
 void VideoChannel::OnMessage(rtc::Message *pmsg) {
   switch (pmsg->message_id) {
     case MSG_SCREENCASTWINDOWEVENT: {
@@ -2066,7 +2039,6 @@
   }
 }
 
-
 void VideoChannel::GetSrtpCiphers(std::vector<std::string>* ciphers) const {
   GetSupportedVideoCryptoSuites(ciphers);
 }
diff --git a/talk/session/media/channel.h b/talk/session/media/channel.h
index c09d51c..bb430bf 100644
--- a/talk/session/media/channel.h
+++ b/talk/session/media/channel.h
@@ -61,7 +61,7 @@
 };
 
 // BaseChannel contains logic common to voice and video, including
-// enable/mute, marshaling calls to a worker thread, and
+// enable, marshaling calls to a worker thread, and
 // connection and media monitors.
 //
 // WARNING! SUBCLASSES MUST CALL Deinit() IN THEIR DESTRUCTORS!
@@ -103,7 +103,6 @@
   bool secure_required() const { return secure_required_; }
 
   bool writable() const { return writable_; }
-  bool IsStreamMuted(uint32 ssrc);
 
   // Activate RTCP mux, regardless of the state so far.  Once
   // activated, it can not be deactivated, and if the remote
@@ -125,9 +124,6 @@
                         std::string* error_desc);
 
   bool Enable(bool enable);
-  // Mute sending media on the stream with SSRC |ssrc|
-  // If there is only one sending stream SSRC 0 can be used.
-  bool MuteStream(uint32 ssrc, bool mute);
 
   // Multiplexing
   bool AddRecvStream(const StreamParams& sp);
@@ -227,8 +223,6 @@
 
   void EnableMedia_w();
   void DisableMedia_w();
-  bool MuteStream_w(uint32 ssrc, bool mute);
-  bool IsStreamMuted_w(uint32 ssrc);
   void ChannelWritable_w();
   void ChannelNotWritable_w();
   bool AddRecvStream_w(const StreamParams& sp);
@@ -319,7 +313,6 @@
   bool was_ever_writable_;
   MediaContentDirection local_content_direction_;
   MediaContentDirection remote_content_direction_;
-  std::set<uint32> muted_streams_;
   bool has_received_packet_;
   bool dtls_keyed_;
   bool secure_required_;
@@ -336,7 +329,11 @@
   ~VoiceChannel();
   bool Init();
   bool SetRemoteRenderer(uint32 ssrc, AudioRenderer* renderer);
-  bool SetLocalRenderer(uint32 ssrc, AudioRenderer* renderer);
+
+  // Configure sending media on the stream with SSRC |ssrc|
+  // If there is only one sending stream SSRC 0 can be used.
+  bool SetAudioSend(uint32 ssrc, bool mute, const AudioOptions* options,
+                    AudioRenderer* renderer);
 
   // downcasts a MediaChannel
   virtual VoiceMediaChannel* media_channel() const {
@@ -387,9 +384,6 @@
   sigslot::signal3<VoiceChannel*, uint32, VoiceMediaChannel::Error>
       SignalMediaError;
 
-  // Configuration and setting.
-  bool SetChannelOptions(const AudioOptions& options);
-
  private:
   // overrides from BaseChannel
   virtual void OnChannelRead(TransportChannel* channel,
@@ -480,8 +474,9 @@
   sigslot::signal3<VideoChannel*, uint32, VideoMediaChannel::Error>
       SignalMediaError;
 
-  // Configuration and setting.
-  bool SetChannelOptions(const VideoOptions& options);
+  // Configure sending media on the stream with SSRC |ssrc|
+  // If there is only one sending stream SSRC 0 can be used.
+  bool SetVideoSend(uint32 ssrc, bool mute, const VideoOptions* options);
 
  private:
   typedef std::map<uint32, VideoCapturer*> ScreencastMap;
diff --git a/talk/session/media/channel_unittest.cc b/talk/session/media/channel_unittest.cc
index fa182c3..a7d5c15 100644
--- a/talk/session/media/channel_unittest.cc
+++ b/talk/session/media/channel_unittest.cc
@@ -894,28 +894,6 @@
     EXPECT_TRUE(media_channel1_->sending());
   }
 
-  void TestMuteStream() {
-    CreateChannels(0, 0);
-    // Test that we can Mute the default channel even though the sending SSRC is
-    // unknown.
-    EXPECT_FALSE(media_channel1_->IsStreamMuted(0));
-    EXPECT_TRUE(channel1_->MuteStream(0, true));
-    EXPECT_TRUE(media_channel1_->IsStreamMuted(0));
-    EXPECT_TRUE(channel1_->MuteStream(0, false));
-    EXPECT_FALSE(media_channel1_->IsStreamMuted(0));
-
-    // Test that we can not mute an unknown SSRC.
-    EXPECT_FALSE(channel1_->MuteStream(kSsrc1, true));
-
-    SendInitiate();
-    // After the local session description has been set, we can mute a stream
-    // with its SSRC.
-    EXPECT_TRUE(channel1_->MuteStream(kSsrc1, true));
-    EXPECT_TRUE(media_channel1_->IsStreamMuted(kSsrc1));
-    EXPECT_TRUE(channel1_->MuteStream(kSsrc1, false));
-    EXPECT_FALSE(media_channel1_->IsStreamMuted(kSsrc1));
-  }
-
   // Test that changing the MediaContentDirection in the local and remote
   // session description start playout and sending at the right time.
   void TestMediaContentDirection() {
@@ -1832,30 +1810,9 @@
 class VoiceChannelTest
     : public ChannelTest<VoiceTraits> {
  public:
-  typedef ChannelTest<VoiceTraits>
-  Base;
+  typedef ChannelTest<VoiceTraits> Base;
   VoiceChannelTest() : Base(kPcmuFrame, sizeof(kPcmuFrame),
-                            kRtcpReport, sizeof(kRtcpReport)) {
-  }
-
-  void TestSetChannelOptions() {
-    CreateChannels(0, 0);
-
-    cricket::AudioOptions options1;
-    options1.echo_cancellation.Set(false);
-    cricket::AudioOptions options2;
-    options2.echo_cancellation.Set(true);
-
-    channel1_->SetChannelOptions(options1);
-    channel2_->SetChannelOptions(options1);
-    EXPECT_EQ(options1, media_channel1_->options());
-    EXPECT_EQ(options1, media_channel2_->options());
-
-    channel1_->SetChannelOptions(options2);
-    channel2_->SetChannelOptions(options2);
-    EXPECT_EQ(options2, media_channel1_->options());
-    EXPECT_EQ(options2, media_channel2_->options());
-  }
+                            kRtcpReport, sizeof(kRtcpReport)) {}
 };
 
 // override to add NULL parameter
@@ -1917,29 +1874,9 @@
 class VideoChannelTest
     : public ChannelTest<VideoTraits> {
  public:
-  typedef ChannelTest<VideoTraits>
-  Base;
+  typedef ChannelTest<VideoTraits> Base;
   VideoChannelTest() : Base(kH264Packet, sizeof(kH264Packet),
-                            kRtcpReport, sizeof(kRtcpReport)) {
-  }
-
-  void TestSetChannelOptions() {
-    CreateChannels(0, 0);
-
-    cricket::VideoOptions o1;
-    o1.video_noise_reduction.Set(true);
-
-    channel1_->SetChannelOptions(o1);
-    channel2_->SetChannelOptions(o1);
-    EXPECT_EQ(o1, media_channel1_->options());
-    EXPECT_EQ(o1, media_channel2_->options());
-
-    o1.video_start_bitrate.Set(123);
-    channel1_->SetChannelOptions(o1);
-    channel2_->SetChannelOptions(o1);
-    EXPECT_EQ(o1, media_channel1_->options());
-    EXPECT_EQ(o1, media_channel2_->options());
-  }
+                            kRtcpReport, sizeof(kRtcpReport)) {}
 };
 
 
@@ -1992,7 +1929,25 @@
 }
 
 TEST_F(VoiceChannelTest, TestMuteStream) {
-  Base::TestMuteStream();
+  CreateChannels(0, 0);
+  // Test that we can Mute the default channel even though the sending SSRC
+  // is unknown.
+  EXPECT_FALSE(media_channel1_->IsStreamMuted(0));
+  EXPECT_TRUE(channel1_->SetAudioSend(0, true, nullptr, nullptr));
+  EXPECT_TRUE(media_channel1_->IsStreamMuted(0));
+  EXPECT_TRUE(channel1_->SetAudioSend(0, false, nullptr, nullptr));
+  EXPECT_FALSE(media_channel1_->IsStreamMuted(0));
+
+  // Test that we can not mute an unknown SSRC.
+  EXPECT_FALSE(channel1_->SetAudioSend(kSsrc1, true, nullptr, nullptr));
+
+  SendInitiate();
+  // After the local session description has been set, we can mute a stream
+  // with its SSRC.
+  EXPECT_TRUE(channel1_->SetAudioSend(kSsrc1, true, nullptr, nullptr));
+  EXPECT_TRUE(media_channel1_->IsStreamMuted(kSsrc1));
+  EXPECT_TRUE(channel1_->SetAudioSend(kSsrc1, false, nullptr, nullptr));
+  EXPECT_FALSE(media_channel1_->IsStreamMuted(kSsrc1));
 }
 
 TEST_F(VoiceChannelTest, TestMediaContentDirection) {
@@ -2106,17 +2061,6 @@
   Base::TestMediaMonitor();
 }
 
-// Test that MuteStream properly forwards to the media channel and does
-// not signal.
-TEST_F(VoiceChannelTest, TestVoiceSpecificMuteStream) {
-  CreateChannels(0, 0);
-  EXPECT_FALSE(media_channel1_->IsStreamMuted(0));
-  EXPECT_TRUE(channel1_->MuteStream(0, true));
-  EXPECT_TRUE(media_channel1_->IsStreamMuted(0));
-  EXPECT_TRUE(channel1_->MuteStream(0, false));
-  EXPECT_FALSE(media_channel1_->IsStreamMuted(0));
-}
-
 // Test that PressDTMF properly forwards to the media channel.
 TEST_F(VoiceChannelTest, TestDtmf) {
   CreateChannels(0, 0);
@@ -2314,10 +2258,6 @@
       kAudioPts, ARRAY_SIZE(kAudioPts), true, true);
 }
 
-TEST_F(VoiceChannelTest, TestSetChannelOptions) {
-  TestSetChannelOptions();
-}
-
 // VideoChannelTest
 TEST_F(VideoChannelTest, TestInit) {
   Base::TestInit();
@@ -2394,7 +2334,23 @@
 }
 
 TEST_F(VideoChannelTest, TestMuteStream) {
-  Base::TestMuteStream();
+  CreateChannels(0, 0);
+  // Test that we can Mute the default channel even though the sending SSRC
+  // is unknown.
+  EXPECT_FALSE(media_channel1_->IsStreamMuted(0));
+  EXPECT_TRUE(channel1_->SetVideoSend(0, true, nullptr));
+  EXPECT_TRUE(media_channel1_->IsStreamMuted(0));
+  EXPECT_TRUE(channel1_->SetVideoSend(0, false, nullptr));
+  EXPECT_FALSE(media_channel1_->IsStreamMuted(0));
+  // Test that we can not mute an unknown SSRC.
+  EXPECT_FALSE(channel1_->SetVideoSend(kSsrc1, true, nullptr));
+  SendInitiate();
+  // After the local session description has been set, we can mute a stream
+  // with its SSRC.
+  EXPECT_TRUE(channel1_->SetVideoSend(kSsrc1, true, nullptr));
+  EXPECT_TRUE(media_channel1_->IsStreamMuted(kSsrc1));
+  EXPECT_TRUE(channel1_->SetVideoSend(kSsrc1, false, nullptr));
+  EXPECT_FALSE(media_channel1_->IsStreamMuted(kSsrc1));
 }
 
 TEST_F(VideoChannelTest, TestMediaContentDirection) {
@@ -2624,10 +2580,6 @@
   EXPECT_EQ(0, send_format.height);
 }
 
-TEST_F(VideoChannelTest, TestSetChannelOptions) {
-  TestSetChannelOptions();
-}
-
 
 // DataChannelTest