Remove WebRtcVideoSendStream2::VideoSink inheritance. Remove sending black frame on source removal.

BUG=webrtc:6371,webrtc:6983

Review-Url: https://codereview.webrtc.org/2469993003
Cr-Commit-Position: refs/heads/master@{#16048}
diff --git a/webrtc/media/base/videoengine_unittest.h b/webrtc/media/base/videoengine_unittest.h
index a673d35..a571bbc 100644
--- a/webrtc/media/base/videoengine_unittest.h
+++ b/webrtc/media/base/videoengine_unittest.h
@@ -830,14 +830,12 @@
     rtc::Thread::Current()->ProcessMessages(30);
     // Remove the capturer.
     EXPECT_TRUE(channel_->SetVideoSend(kSsrc, true, nullptr, nullptr));
-    // Wait for one black frame for removing the capturer.
-    EXPECT_FRAME_WAIT(2, kVideoWidth, kVideoHeight, kTimeout);
 
     // No capturer was added, so this SetVideoSend shouldn't do anything.
     EXPECT_TRUE(channel_->SetVideoSend(kSsrc, true, nullptr, nullptr));
     rtc::Thread::Current()->ProcessMessages(300);
     // Verify no more frames were sent.
-    EXPECT_EQ(2, renderer_.num_rendered_frames());
+    EXPECT_EQ(1, renderer_.num_rendered_frames());
   }
 
   // Tests that we can add and remove capturer as unique sources.
diff --git a/webrtc/media/engine/webrtcvideoengine2.cc b/webrtc/media/engine/webrtcvideoengine2.cc
index f09b254..ca65e65 100644
--- a/webrtc/media/engine/webrtcvideoengine2.cc
+++ b/webrtc/media/engine/webrtcvideoengine2.cc
@@ -1553,8 +1553,7 @@
       parameters_(std::move(config), options, max_bitrate_bps, codec_settings),
       rtp_parameters_(CreateRtpParametersWithOneEncoding()),
       allocated_encoder_(nullptr, cricket::VideoCodec(), false),
-      sending_(false),
-      last_frame_timestamp_us_(0) {
+      sending_(false) {
   parameters_.config.rtp.max_packet_size = kVideoMtu;
   parameters_.conference_mode = send_params.conference_mode;
 
@@ -1612,43 +1611,6 @@
   DestroyVideoEncoder(&allocated_encoder_);
 }
 
-void WebRtcVideoChannel2::WebRtcVideoSendStream::OnFrame(
-    const webrtc::VideoFrame& frame) {
-  TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::OnFrame");
-  webrtc::VideoFrame video_frame(frame.video_frame_buffer(),
-                                 frame.rotation(),
-                                 frame.timestamp_us());
-
-  rtc::CritScope cs(&lock_);
-
-  if (video_frame.width() != last_frame_info_.width ||
-      video_frame.height() != last_frame_info_.height ||
-      video_frame.rotation() != last_frame_info_.rotation ||
-      video_frame.is_texture() != last_frame_info_.is_texture) {
-    last_frame_info_.width = video_frame.width();
-    last_frame_info_.height = video_frame.height();
-    last_frame_info_.rotation = video_frame.rotation();
-    last_frame_info_.is_texture = video_frame.is_texture();
-
-    LOG(LS_INFO) << "Video frame parameters changed: dimensions="
-                 << last_frame_info_.width << "x" << last_frame_info_.height
-                 << ", rotation=" << last_frame_info_.rotation
-                 << ", texture=" << last_frame_info_.is_texture;
-  }
-
-  if (encoder_sink_ == NULL) {
-    // Frame input before send codecs are configured, dropping frame.
-    return;
-  }
-
-  last_frame_timestamp_us_ = video_frame.timestamp_us();
-
-  // Forward frame to the encoder regardless if we are sending or not. This is
-  // to ensure that the encoder can be reconfigured with the correct frame size
-  // as quickly as possible.
-  encoder_sink_->OnFrame(video_frame);
-}
-
 bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoSend(
     bool enable,
     const VideoOptions* options,
@@ -1658,7 +1620,6 @@
 
   // Ignore |options| pointer if |enable| is false.
   bool options_present = enable && options;
-  bool source_changing = source_ != source;
 
   if (options_present) {
     VideoOptions old_options = parameters_.options;
@@ -1668,29 +1629,6 @@
     }
   }
 
-  if (source_changing) {
-    rtc::CritScope cs(&lock_);
-    if (source == nullptr && last_frame_info_.width > 0 && encoder_sink_) {
-      LOG(LS_VERBOSE) << "Disabling capturer, sending black frame.";
-      // Force this black frame not to be dropped due to timestamp order
-      // check. As IncomingCapturedFrame will drop the frame if this frame's
-      // timestamp is less than or equal to last frame's timestamp, it is
-      // necessary to give this black frame a larger timestamp than the
-      // previous one.
-      last_frame_timestamp_us_ += rtc::kNumMicrosecsPerMillisec;
-      rtc::scoped_refptr<webrtc::I420Buffer> black_buffer(
-          webrtc::I420Buffer::Create(last_frame_info_.width,
-                                     last_frame_info_.height));
-      webrtc::I420Buffer::SetBlack(black_buffer);
-
-      encoder_sink_->OnFrame(webrtc::VideoFrame(
-          black_buffer, last_frame_info_.rotation, last_frame_timestamp_us_));
-    }
-  }
-
-  // TODO(perkj, nisse): Remove |source_| and directly call
-  // |stream_|->SetSource(source) once the video frame types have been
-  // merged.
   if (source_ && stream_) {
     stream_->SetSource(
         nullptr, webrtc::VideoSendStream::DegradationPreference::kBalanced);
@@ -1700,6 +1638,8 @@
   if (source && stream_) {
     // Do not adapt resolution for screen content as this will likely
     // result in blurry and unreadable text.
+    // |this| acts like a VideoSource to make sure SinkWants are handled on the
+    // correct thread.
     stream_->SetSource(
         this, enable_cpu_overuse_detection_ &&
                       !parameters_.options.is_screencast.value_or(false)
@@ -1973,45 +1913,35 @@
 }
 
 void WebRtcVideoChannel2::WebRtcVideoSendStream::RemoveSink(
-    VideoSinkInterface<webrtc::VideoFrame>* sink) {
+    rtc::VideoSinkInterface<webrtc::VideoFrame>* sink) {
   RTC_DCHECK_RUN_ON(&thread_checker_);
-  {
-    rtc::CritScope cs(&lock_);
-    RTC_DCHECK(encoder_sink_ == sink);
-    encoder_sink_ = nullptr;
-  }
-  source_->RemoveSink(this);
+  RTC_DCHECK(encoder_sink_ == sink);
+  encoder_sink_ = nullptr;
+  source_->RemoveSink(sink);
 }
 
 void WebRtcVideoChannel2::WebRtcVideoSendStream::AddOrUpdateSink(
-    VideoSinkInterface<webrtc::VideoFrame>* sink,
+    rtc::VideoSinkInterface<webrtc::VideoFrame>* sink,
     const rtc::VideoSinkWants& wants) {
   if (worker_thread_ == rtc::Thread::Current()) {
     // AddOrUpdateSink is called on |worker_thread_| if this is the first
     // registration of |sink|.
     RTC_DCHECK_RUN_ON(&thread_checker_);
-    {
-      rtc::CritScope cs(&lock_);
-      encoder_sink_ = sink;
-    }
-    source_->AddOrUpdateSink(this, wants);
+    encoder_sink_ = sink;
+    source_->AddOrUpdateSink(encoder_sink_, wants);
   } else {
     // Subsequent calls to AddOrUpdateSink will happen on the encoder task
     // queue.
-    invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_, [this, wants] {
-      RTC_DCHECK_RUN_ON(&thread_checker_);
-      bool encoder_sink_valid = true;
-      {
-        rtc::CritScope cs(&lock_);
-        encoder_sink_valid = encoder_sink_ != nullptr;
-      }
-      // Since |source_| is still valid after a call to RemoveSink, check if
-      // |encoder_sink_| is still valid to check if this call should be
-      // cancelled.
-      if (source_ && encoder_sink_valid) {
-        source_->AddOrUpdateSink(this, wants);
-      }
-    });
+    invoker_.AsyncInvoke<void>(
+        RTC_FROM_HERE, worker_thread_, [this, sink, wants] {
+          RTC_DCHECK_RUN_ON(&thread_checker_);
+          // |sink| may be invalidated after this task was posted since
+          // RemoveSink is called on the worker thread.
+          bool encoder_sink_valid = (sink == encoder_sink_);
+          if (source_ && encoder_sink_valid) {
+            source_->AddOrUpdateSink(encoder_sink_, wants);
+          }
+        });
   }
 }
 
@@ -2135,12 +2065,10 @@
   parameters_.encoder_config.encoder_specific_settings = NULL;
 
   if (source_) {
-    // TODO(perkj, nisse): Remove |source_| and directly call
-    // |stream_|->SetSource(source) once the video frame types have been
-    // merged and |stream_| internally reconfigure the encoder on frame
-    // resolution change.
     // Do not adapt resolution for screen content as this will likely result in
     // blurry and unreadable text.
+    // |this| acts like a VideoSource to make sure SinkWants are handled on the
+    // correct thread.
     stream_->SetSource(
         this, enable_cpu_overuse_detection_ &&
                       !parameters_.options.is_screencast.value_or(false)
diff --git a/webrtc/media/engine/webrtcvideoengine2.h b/webrtc/media/engine/webrtcvideoengine2.h
index 1fb794e..b50c5a1 100644
--- a/webrtc/media/engine/webrtcvideoengine2.h
+++ b/webrtc/media/engine/webrtcvideoengine2.h
@@ -231,11 +231,9 @@
   static std::string CodecSettingsVectorToString(
       const std::vector<VideoCodecSettings>& codecs);
 
-  // Wrapper for the sender part, this is where the source is connected and
-  // frames are then converted from cricket frames to webrtc frames.
+  // Wrapper for the sender part.
   class WebRtcVideoSendStream
-      : public rtc::VideoSinkInterface<webrtc::VideoFrame>,
-        public rtc::VideoSourceInterface<webrtc::VideoFrame> {
+      : public rtc::VideoSourceInterface<webrtc::VideoFrame> {
    public:
     WebRtcVideoSendStream(
         webrtc::Call* call,
@@ -256,14 +254,12 @@
 
     // Implements rtc::VideoSourceInterface<webrtc::VideoFrame>.
     // WebRtcVideoSendStream acts as a source to the webrtc::VideoSendStream
-    // in |stream_|.
-    // TODO(perkj, nisse): Refactor WebRtcVideoSendStream to directly connect
-    // the camera input |source_|
-    void AddOrUpdateSink(VideoSinkInterface<webrtc::VideoFrame>* sink,
+    // in |stream_|. This is done to proxy VideoSinkWants from the encoder to
+    // the worker thread.
+    void AddOrUpdateSink(rtc::VideoSinkInterface<webrtc::VideoFrame>* sink,
                          const rtc::VideoSinkWants& wants) override;
-    void RemoveSink(VideoSinkInterface<webrtc::VideoFrame>* sink) override;
+    void RemoveSink(rtc::VideoSinkInterface<webrtc::VideoFrame>* sink) override;
 
-    void OnFrame(const webrtc::VideoFrame& frame) override;
     bool SetVideoSend(bool mute,
                       const VideoOptions* options,
                       rtc::VideoSourceInterface<webrtc::VideoFrame>* source);
@@ -306,21 +302,6 @@
       bool external;
     };
 
-    // TODO(perkj): VideoFrameInfo is currently used for sending a black frame
-    // when the video source is removed. Consider moving that logic to
-    // VieEncoder or remove it.
-    struct VideoFrameInfo {
-      VideoFrameInfo()
-          : width(0),
-            height(0),
-            rotation(webrtc::kVideoRotation_0),
-            is_texture(false) {}
-      int width;
-      int height;
-      webrtc::VideoRotation rotation;
-      bool is_texture;
-    };
-
     rtc::scoped_refptr<webrtc::VideoEncoderConfig::EncoderSpecificSettings>
     ConfigureVideoEncoderSettings(const VideoCodec& codec);
     AllocatedEncoder CreateVideoEncoder(const VideoCodec& codec);
@@ -348,10 +329,9 @@
     WebRtcVideoEncoderFactory* const external_encoder_factory_
         ACCESS_ON(&thread_checker_);
 
-    rtc::CriticalSection lock_;
     webrtc::VideoSendStream* stream_ ACCESS_ON(&thread_checker_);
     rtc::VideoSinkInterface<webrtc::VideoFrame>* encoder_sink_
-        GUARDED_BY(lock_);
+        ACCESS_ON(&thread_checker_);
     // Contains settings that are the same for all streams in the MediaChannel,
     // such as codecs, header extensions, and the global bitrate limit for the
     // entire channel.
@@ -363,13 +343,8 @@
     // one stream per MediaChannel.
     webrtc::RtpParameters rtp_parameters_ ACCESS_ON(&thread_checker_);
     AllocatedEncoder allocated_encoder_ ACCESS_ON(&thread_checker_);
-    VideoFrameInfo last_frame_info_ GUARDED_BY(lock_);
 
     bool sending_ ACCESS_ON(&thread_checker_);
-
-    // The timestamp of the last frame received
-    // Used to generate timestamp for the black frame when source is removed
-    int64_t last_frame_timestamp_us_ GUARDED_BY(lock_);
   };
 
   // Wrapper for the receiver part, contains configs etc. that are needed to
diff --git a/webrtc/media/engine/webrtcvideoengine2_unittest.cc b/webrtc/media/engine/webrtcvideoengine2_unittest.cc
index 8349469..852eedd 100644
--- a/webrtc/media/engine/webrtcvideoengine2_unittest.cc
+++ b/webrtc/media/engine/webrtcvideoengine2_unittest.cc
@@ -1654,8 +1654,7 @@
       << "Non-screenshare shouldn't use min-transmit bitrate.";
 
   EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
-  // Removing a capturer triggers a black frame to be sent.
-  EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
+  EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
   VideoOptions screencast_options;
   screencast_options.is_screencast = rtc::Optional<bool>(true);
   EXPECT_TRUE(
@@ -1663,7 +1662,7 @@
   EXPECT_TRUE(capturer.CaptureFrame());
   // Send stream not recreated after option change.
   ASSERT_EQ(send_stream, fake_call_->GetVideoSendStreams().front());
-  EXPECT_EQ(3, send_stream->GetNumberOfSwappedFrames());
+  EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
 
   // Verify screencast settings.
   encoder_config = send_stream->GetEncoderConfig().Copy();