Reland of Add experimental simulcast screen content mode

The original CL was reverted because of a bug discovered by the
chromium bots. Description of that CL:

> Review-Url: https://codereview.webrtc.org/2636443002
> Cr-Commit-Position: refs/heads/master@{#16135}
> Committed: https://chromium.googlesource.com/external/webrtc/+/a28e971e3bc8a06f366f0ef82cc7168b05a83b59

The first patch set of this CL is the same as r16135.
Subsequence patch sets are the fixes applied.
Some new test cases have been added, which reveal a few more bugs that
have also been fixed.

BUG=webrtc:4172

Review-Url: https://codereview.webrtc.org/2641133002
Cr-Original-Commit-Position: refs/heads/master@{#16299}
Cr-Mirrored-From: https://chromium.googlesource.com/external/webrtc
Cr-Mirrored-Commit: 429600d7d00b526b3b35b6387b7d72a053709860
diff --git a/media/engine/webrtcvideoengine2.cc b/media/engine/webrtcvideoengine2.cc
index 9e7f5c4..0cd3193 100644
--- a/media/engine/webrtcvideoengine2.cc
+++ b/media/engine/webrtcvideoengine2.cc
@@ -301,11 +301,16 @@
       int width,
       int height,
       const webrtc::VideoEncoderConfig& encoder_config) override {
-    RTC_DCHECK(encoder_config.number_of_streams > 1 ? !is_screencast_ : true);
-    if (encoder_config.number_of_streams > 1) {
+    if (is_screencast_ &&
+        (!conference_mode_ || !cricket::UseSimulcastScreenshare())) {
+      RTC_DCHECK_EQ(1, encoder_config.number_of_streams);
+    }
+    if (encoder_config.number_of_streams > 1 ||
+        (CodecNamesEq(codec_name_, kVp8CodecName) && is_screencast_ &&
+         conference_mode_)) {
       return GetSimulcastConfig(encoder_config.number_of_streams, width, height,
                                 encoder_config.max_bitrate_bps, max_qp_,
-                                max_framerate_);
+                                max_framerate_, is_screencast_);
     }
 
     // For unset max bitrates set default bitrate for non-simulcast.
@@ -322,20 +327,6 @@
     stream.target_bitrate_bps = stream.max_bitrate_bps = max_bitrate_bps;
     stream.max_qp = max_qp_;
 
-    // Conference mode screencast uses 2 temporal layers split at 100kbit.
-    if (conference_mode_ && is_screencast_) {
-      ScreenshareLayerConfig config = ScreenshareLayerConfig::GetDefault();
-      // For screenshare in conference mode, tl0 and tl1 bitrates are
-      // piggybacked
-      // on the VideoCodec struct as target and max bitrates, respectively.
-      // See eg. webrtc::VP8EncoderImpl::SetRates().
-      stream.target_bitrate_bps = config.tl0_bitrate_kbps * 1000;
-      stream.max_bitrate_bps = config.tl1_bitrate_kbps * 1000;
-      stream.temporal_layer_thresholds_bps.clear();
-      stream.temporal_layer_thresholds_bps.push_back(config.tl0_bitrate_kbps *
-                                                     1000);
-    }
-
     if (CodecNamesEq(codec_name_, kVp9CodecName) && !is_screencast_) {
       stream.temporal_layer_thresholds_bps.resize(
           GetDefaultVp9TemporalLayers() - 1);
@@ -1551,6 +1542,7 @@
       enable_cpu_overuse_detection_(enable_cpu_overuse_detection),
       source_(nullptr),
       external_encoder_factory_(external_encoder_factory),
+      internal_encoder_factory_(new InternalEncoderFactory()),
       stream_(nullptr),
       encoder_sink_(nullptr),
       parameters_(std::move(config), options, max_bitrate_bps, codec_settings),
@@ -1678,10 +1670,20 @@
   }
 
   // Try creating internal encoder.
-  InternalEncoderFactory internal_encoder_factory;
-  if (FindMatchingCodec(internal_encoder_factory.supported_codecs(), codec)) {
-    return AllocatedEncoder(internal_encoder_factory.CreateVideoEncoder(codec),
-                            codec, false /* is_external */);
+  if (FindMatchingCodec(internal_encoder_factory_->supported_codecs(), codec)) {
+    if (parameters_.encoder_config.content_type ==
+            webrtc::VideoEncoderConfig::ContentType::kScreen &&
+        parameters_.conference_mode && UseSimulcastScreenshare()) {
+      // TODO(sprang): Remove this adapter once libvpx supports simulcast with
+      // same-resolution substreams.
+      WebRtcSimulcastEncoderFactory adapter_factory(
+          internal_encoder_factory_.get());
+      return AllocatedEncoder(adapter_factory.CreateVideoEncoder(codec), codec,
+                              false /* is_external */);
+    }
+    return AllocatedEncoder(
+        internal_encoder_factory_->CreateVideoEncoder(codec), codec,
+        false /* is_external */);
   }
 
   // This shouldn't happen, we should not be trying to create something we don't
@@ -1858,9 +1860,11 @@
 
   // By default, the stream count for the codec configuration should match the
   // number of negotiated ssrcs. But if the codec is blacklisted for simulcast
-  // or a screencast, only configure a single stream.
+  // or a screencast (and not in simulcast screenshare experiment), only
+  // configure a single stream.
   encoder_config.number_of_streams = parameters_.config.rtp.ssrcs.size();
-  if (IsCodecBlacklistedForSimulcast(codec.name) || is_screencast) {
+  if (IsCodecBlacklistedForSimulcast(codec.name) ||
+      (is_screencast && !UseSimulcastScreenshare())) {
     encoder_config.number_of_streams = 1;
   }