Remove default video encoders for new video API.

Reduces stream creation time significantly. As a side effect also
removes default encoders for receive-only channels.

BUG=1788,1667
R=stefan@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/37049004

Cr-Commit-Position: refs/heads/master@{#8356}
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8356 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/talk/media/webrtc/fakewebrtcvideoengine.h b/talk/media/webrtc/fakewebrtcvideoengine.h
index cc217bb..470a887 100644
--- a/talk/media/webrtc/fakewebrtcvideoengine.h
+++ b/talk/media/webrtc/fakewebrtcvideoengine.h
@@ -680,6 +680,7 @@
     channels_[channel]->original_channel_id_ = original_channel;
     return 0;
   }
+  WEBRTC_STUB(CreateChannelWithoutDefaultEncoder, (int&, int original_channel));
   WEBRTC_FUNC(CreateReceiveChannel, (int& channel, int original_channel)) {
     return CreateChannel(channel, original_channel);
   }
diff --git a/webrtc/video/video_send_stream.cc b/webrtc/video/video_send_stream.cc
index 4c31f0c..ab7f0c1 100644
--- a/webrtc/video/video_send_stream.cc
+++ b/webrtc/video/video_send_stream.cc
@@ -126,7 +126,8 @@
     assert(bitrate_config.max_bitrate_bps >= bitrate_config.start_bitrate_bps);
 
   video_engine_base_ = ViEBase::GetInterface(video_engine);
-  video_engine_base_->CreateChannel(channel_, base_channel);
+  video_engine_base_->CreateChannelWithoutDefaultEncoder(channel_,
+                                                         base_channel);
   assert(channel_ != -1);
 
   rtp_rtcp_ = ViERTP_RTCP::GetInterface(video_engine);
diff --git a/webrtc/video_engine/encoder_state_feedback_unittest.cc b/webrtc/video_engine/encoder_state_feedback_unittest.cc
index 4e15752..0cb0fc7 100644
--- a/webrtc/video_engine/encoder_state_feedback_unittest.cc
+++ b/webrtc/video_engine/encoder_state_feedback_unittest.cc
@@ -28,7 +28,7 @@
 class MockVieEncoder : public ViEEncoder {
  public:
   explicit MockVieEncoder(ProcessThread* process_thread)
-      : ViEEncoder(1, 1, 1, config_, *process_thread, NULL) {}
+      : ViEEncoder(1, 1, 1, config_, *process_thread, NULL, false) {}
   ~MockVieEncoder() {}
 
   MOCK_METHOD1(OnReceivedIntraFrameRequest,
diff --git a/webrtc/video_engine/include/vie_base.h b/webrtc/video_engine/include/vie_base.h
index f42992f..3f4840a 100644
--- a/webrtc/video_engine/include/vie_base.h
+++ b/webrtc/video_engine/include/vie_base.h
@@ -184,6 +184,9 @@
   virtual int CreateChannel(int& video_channel,
                             int original_channel) = 0;
 
+  virtual int CreateChannelWithoutDefaultEncoder(int& video_channel,
+                                                 int original_channel) = 0;
+
   // Creates a new channel grouped together with |original_channel|. The channel
   // can only receive video and it is assumed the remote end-point is the same
   // as for |original_channel|.
diff --git a/webrtc/video_engine/vie_base_impl.cc b/webrtc/video_engine/vie_base_impl.cc
index 825bcdb..9c7ec16 100644
--- a/webrtc/video_engine/vie_base_impl.cc
+++ b/webrtc/video_engine/vie_base_impl.cc
@@ -169,12 +169,18 @@
 
 int ViEBaseImpl::CreateChannel(int& video_channel,  // NOLINT
                                int original_channel) {
-  return CreateChannel(video_channel, original_channel, true);
+  return CreateChannel(video_channel, original_channel, true, false);
+}
+
+int ViEBaseImpl::CreateChannelWithoutDefaultEncoder(
+    int& video_channel,  // NOLINT
+    int original_channel) {
+  return CreateChannel(video_channel, original_channel, true, true);
 }
 
 int ViEBaseImpl::CreateReceiveChannel(int& video_channel,  // NOLINT
                                       int original_channel) {
-  return CreateChannel(video_channel, original_channel, false);
+  return CreateChannel(video_channel, original_channel, false, true);
 }
 
 int ViEBaseImpl::DeleteChannel(const int video_channel) {
@@ -338,16 +344,18 @@
 }
 
 int ViEBaseImpl::CreateChannel(int& video_channel,  // NOLINT
-                               int original_channel, bool sender) {
+                               int original_channel,
+                               bool sender,
+                               bool disable_default_encoder) {
   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
   if (!cs.Channel(original_channel)) {
     shared_data_.SetLastError(kViEBaseInvalidChannelId);
     return -1;
   }
 
-  if (shared_data_.channel_manager()->CreateChannel(&video_channel,
-                                                    original_channel,
-                                                    sender) == -1) {
+  if (shared_data_.channel_manager()->CreateChannel(
+          &video_channel, original_channel, sender, disable_default_encoder) ==
+      -1) {
     video_channel = -1;
     shared_data_.SetLastError(kViEBaseChannelCreationFailed);
     return -1;
diff --git a/webrtc/video_engine/vie_base_impl.h b/webrtc/video_engine/vie_base_impl.h
index c949acd..dd21a04 100644
--- a/webrtc/video_engine/vie_base_impl.h
+++ b/webrtc/video_engine/vie_base_impl.h
@@ -44,6 +44,9 @@
                             const Config* config);
   virtual int CreateChannel(int& video_channel,  // NOLINT
                             int original_channel);
+  virtual int CreateChannelWithoutDefaultEncoder(int& video_channel,  // NOLINT
+                                                 int original_channel);
+
   virtual int CreateReceiveChannel(int& video_channel,  // NOLINT
                                    int original_channel);
   virtual int DeleteChannel(const int video_channel);
@@ -65,7 +68,7 @@
 
  private:
   int CreateChannel(int& video_channel, int original_channel,  // NOLINT
-                    bool sender);
+                    bool sender, bool disable_default_encoder);
 
   virtual void RegisterSendStatisticsProxy(
       int channel,
diff --git a/webrtc/video_engine/vie_channel.cc b/webrtc/video_engine/vie_channel.cc
index 8057ca0..0278fe3 100644
--- a/webrtc/video_engine/vie_channel.cc
+++ b/webrtc/video_engine/vie_channel.cc
@@ -71,7 +71,8 @@
                        RtcpRttStats* rtt_stats,
                        PacedSender* paced_sender,
                        RtpRtcp* default_rtp_rtcp,
-                       bool sender)
+                       bool sender,
+                       bool disable_default_encoder)
     : ViEFrameProviderBase(channel_id, engine_id),
       channel_id_(channel_id),
       engine_id_(engine_id),
@@ -105,6 +106,7 @@
       color_enhancement_(false),
       mtu_(0),
       sender_(sender),
+      disable_default_encoder_(disable_default_encoder),
       nack_history_size_sender_(kSendSidePacketHistorySize),
       max_nack_reordering_threshold_(kMaxPacketAgeToNack),
       pre_render_callback_(NULL),
@@ -155,18 +157,20 @@
     return -1;
   }
 #ifdef VIDEOCODEC_VP8
-  VideoCodec video_codec;
-  if (vcm_->Codec(kVideoCodecVP8, &video_codec) == VCM_OK) {
-    rtp_rtcp_->RegisterSendPayload(video_codec);
-    // TODO(holmer): Can we call SetReceiveCodec() here instead?
-    if (!vie_receiver_.RegisterPayload(video_codec)) {
-      return -1;
+  if (!disable_default_encoder_) {
+    VideoCodec video_codec;
+    if (vcm_->Codec(kVideoCodecVP8, &video_codec) == VCM_OK) {
+      rtp_rtcp_->RegisterSendPayload(video_codec);
+      // TODO(holmer): Can we call SetReceiveCodec() here instead?
+      if (!vie_receiver_.RegisterPayload(video_codec)) {
+        return -1;
+      }
+      vcm_->RegisterReceiveCodec(&video_codec, number_of_cores_);
+      vcm_->RegisterSendCodec(&video_codec, number_of_cores_,
+                              rtp_rtcp_->MaxDataPayloadLength());
+    } else {
+      assert(false);
     }
-    vcm_->RegisterReceiveCodec(&video_codec, number_of_cores_);
-    vcm_->RegisterSendCodec(&video_codec, number_of_cores_,
-                           rtp_rtcp_->MaxDataPayloadLength());
-  } else {
-    assert(false);
   }
 #endif
 
diff --git a/webrtc/video_engine/vie_channel.h b/webrtc/video_engine/vie_channel.h
index 5640f23..d79065d 100644
--- a/webrtc/video_engine/vie_channel.h
+++ b/webrtc/video_engine/vie_channel.h
@@ -74,7 +74,8 @@
              RtcpRttStats* rtt_stats,
              PacedSender* paced_sender,
              RtpRtcp* default_rtp_rtcp,
-             bool sender);
+             bool sender,
+             bool disable_default_encoder);
   ~ViEChannel();
 
   int32_t Init();
@@ -509,6 +510,8 @@
   // User set MTU, -1 if not set.
   uint16_t mtu_;
   const bool sender_;
+  // Used to skip default encoder in the new API.
+  const bool disable_default_encoder_;
 
   int nack_history_size_sender_;
   int max_nack_reordering_threshold_;
diff --git a/webrtc/video_engine/vie_channel_manager.cc b/webrtc/video_engine/vie_channel_manager.cc
index 0ea23ad..f2788cf 100644
--- a/webrtc/video_engine/vie_channel_manager.cc
+++ b/webrtc/video_engine/vie_channel_manager.cc
@@ -93,7 +93,8 @@
                                            number_of_cores_,
                                            engine_config_,
                                            *module_process_thread_,
-                                           bitrate_controller);
+                                           bitrate_controller,
+                                           false);
 
   RtcpBandwidthObserver* bandwidth_observer =
       bitrate_controller->CreateRtcpBandwidthObserver();
@@ -108,7 +109,7 @@
         CreateChannelObject(new_channel_id, vie_encoder, bandwidth_observer,
                             remote_bitrate_estimator, rtcp_rtt_stats,
                             encoder_state_feedback->GetRtcpIntraFrameObserver(),
-                            true))) {
+                            true, false))) {
     delete vie_encoder;
     vie_encoder = NULL;
     ReturnChannelId(new_channel_id);
@@ -138,7 +139,8 @@
 
 int ViEChannelManager::CreateChannel(int* channel_id,
                                      int original_channel,
-                                     bool sender) {
+                                     bool sender,
+                                     bool disable_default_encoder) {
   CriticalSectionScoped cs(channel_id_critsect_);
 
   ChannelGroup* channel_group = FindGroup(original_channel);
@@ -165,7 +167,8 @@
     vie_encoder = new ViEEncoder(engine_id_, new_channel_id, number_of_cores_,
                                  engine_config_,
                                  *module_process_thread_,
-                                 bitrate_controller);
+                                 bitrate_controller,
+                                 disable_default_encoder);
     if (!(vie_encoder->Init() &&
         CreateChannelObject(
             new_channel_id,
@@ -174,7 +177,8 @@
             remote_bitrate_estimator,
             rtcp_rtt_stats,
             encoder_state_feedback->GetRtcpIntraFrameObserver(),
-            sender))) {
+            sender,
+            disable_default_encoder))) {
       delete vie_encoder;
       vie_encoder = NULL;
     }
@@ -197,7 +201,8 @@
         remote_bitrate_estimator,
         rtcp_rtt_stats,
         encoder_state_feedback->GetRtcpIntraFrameObserver(),
-        sender)) {
+        sender,
+        disable_default_encoder)) {
       vie_encoder = NULL;
     }
   }
@@ -421,7 +426,8 @@
     RemoteBitrateEstimator* remote_bitrate_estimator,
     RtcpRttStats* rtcp_rtt_stats,
     RtcpIntraFrameObserver* intra_frame_observer,
-    bool sender) {
+    bool sender,
+    bool disable_default_encoder) {
   PacedSender* paced_sender = vie_encoder->GetPacedSender();
 
   // Register the channel at the encoder.
@@ -437,19 +443,22 @@
                                            rtcp_rtt_stats,
                                            paced_sender,
                                            send_rtp_rtcp_module,
-                                           sender);
+                                           sender,
+                                           disable_default_encoder);
   if (vie_channel->Init() != 0) {
     delete vie_channel;
     return false;
   }
-  VideoCodec encoder;
-  if (vie_encoder->GetEncoder(&encoder) != 0) {
-    delete vie_channel;
-    return false;
-  }
-  if (sender && vie_channel->SetSendCodec(encoder) != 0) {
-    delete vie_channel;
-    return false;
+  if (!disable_default_encoder) {
+    VideoCodec encoder;
+    if (vie_encoder->GetEncoder(&encoder) != 0) {
+      delete vie_channel;
+      return false;
+    }
+    if (sender && vie_channel->SetSendCodec(encoder) != 0) {
+      delete vie_channel;
+      return false;
+    }
   }
   // Store the channel, add it to the channel group and save the vie_encoder.
   channel_map_[channel_id] = vie_channel;
diff --git a/webrtc/video_engine/vie_channel_manager.h b/webrtc/video_engine/vie_channel_manager.h
index e0e3588..a02cfa2 100644
--- a/webrtc/video_engine/vie_channel_manager.h
+++ b/webrtc/video_engine/vie_channel_manager.h
@@ -56,7 +56,11 @@
   // Creates a new channel grouped with |original_channel|. The new channel
   // will get its own |ViEEncoder| if |sender| is set to true. It will be a
   // receive only channel, without an own |ViEEncoder| if |sender| is false.
-  int CreateChannel(int* channel_id, int original_channel, bool sender);
+  // Doesn't internally allocate an encoder if |disable_default_encoder|.
+  int CreateChannel(int* channel_id,
+                    int original_channel,
+                    bool sender,
+                    bool disable_default_encoder);
 
   // Deletes a channel.
   int DeleteChannel(int channel_id);
@@ -94,7 +98,8 @@
                            RemoteBitrateEstimator* remote_bitrate_estimator,
                            RtcpRttStats* rtcp_rtt_stats,
                            RtcpIntraFrameObserver* intra_frame_observer,
-                           bool sender);
+                           bool sender,
+                           bool disable_default_encoder);
 
   // Used by ViEChannelScoped, forcing a manager user to use scoped.
   // Returns a pointer to the channel with id 'channel_id'.
diff --git a/webrtc/video_engine/vie_codec_impl.cc b/webrtc/video_engine/vie_codec_impl.cc
index d90117a..aa0a21a 100644
--- a/webrtc/video_engine/vie_codec_impl.cc
+++ b/webrtc/video_engine/vie_codec_impl.cc
@@ -188,15 +188,12 @@
     video_codec_internal.startBitrate = video_codec_internal.maxBitrate;
   }
 
-  VideoCodec encoder;
-  vie_encoder->GetEncoder(&encoder);
-
   // Make sure to generate a new SSRC if the codec type and/or resolution has
   // changed. This won't have any effect if the user has set an SSRC.
-  bool new_rtp_stream = false;
-  if (encoder.codecType != video_codec_internal.codecType) {
-    new_rtp_stream = true;
-  }
+  bool new_rtp_stream = true;
+  VideoCodec encoder;
+  if (vie_encoder->GetEncoder(&encoder) == 0)
+    new_rtp_stream = encoder.codecType != video_codec_internal.codecType;
 
   ViEInputManagerScoped is(*(shared_data_->input_manager()));
 
diff --git a/webrtc/video_engine/vie_encoder.cc b/webrtc/video_engine/vie_encoder.cc
index 0dd7e91..fb7ea61 100644
--- a/webrtc/video_engine/vie_encoder.cc
+++ b/webrtc/video_engine/vie_encoder.cc
@@ -132,10 +132,12 @@
                        uint32_t number_of_cores,
                        const Config& config,
                        ProcessThread& module_process_thread,
-                       BitrateController* bitrate_controller)
+                       BitrateController* bitrate_controller,
+                       bool disable_default_encoder)
   : engine_id_(engine_id),
     channel_id_(channel_id),
     number_of_cores_(number_of_cores),
+    disable_default_encoder_(disable_default_encoder),
     vcm_(*webrtc::VideoCodingModule::Create()),
     vpm_(*webrtc::VideoProcessingModule::Create(ViEModuleId(engine_id,
                                                             channel_id))),
@@ -202,26 +204,28 @@
   }
   qm_callback_ = new QMVideoSettingsCallback(&vpm_);
 
+  if (!disable_default_encoder_) {
 #ifdef VIDEOCODEC_VP8
-  VideoCodecType codec_type = webrtc::kVideoCodecVP8;
+    VideoCodecType codec_type = webrtc::kVideoCodecVP8;
 #else
-  VideoCodecType codec_type = webrtc::kVideoCodecI420;
+    VideoCodecType codec_type = webrtc::kVideoCodecI420;
 #endif
-
-  VideoCodec video_codec;
-  if (vcm_.Codec(codec_type, &video_codec) != VCM_OK) {
-    return false;
-  }
-  {
-    CriticalSectionScoped cs(data_cs_.get());
-    send_padding_ = video_codec.numberOfSimulcastStreams > 1;
-  }
-  if (vcm_.RegisterSendCodec(&video_codec, number_of_cores_,
-                             PayloadRouter::DefaultMaxPayloadLength()) != 0) {
-    return false;
-  }
-  if (default_rtp_rtcp_->RegisterSendPayload(video_codec) != 0) {
-    return false;
+    VideoCodec video_codec;
+    if (vcm_.Codec(codec_type, &video_codec) != VCM_OK) {
+      return false;
+    }
+    {
+      CriticalSectionScoped cs(data_cs_.get());
+      send_padding_ = video_codec.numberOfSimulcastStreams > 1;
+    }
+    if (vcm_.RegisterSendCodec(&video_codec, number_of_cores_,
+                               PayloadRouter::DefaultMaxPayloadLength()) !=
+        0) {
+      return false;
+    }
+    if (default_rtp_rtcp_->RegisterSendPayload(video_codec) != 0) {
+      return false;
+    }
   }
   if (vcm_.RegisterTransportCallback(this) != 0) {
     return false;
@@ -338,6 +342,9 @@
     return -1;
   }
 
+  if (disable_default_encoder_)
+    return 0;
+
   // If the external encoder is the current send codec, use vcm internal
   // encoder.
   if (current_send_codec.plType == pl_type) {
diff --git a/webrtc/video_engine/vie_encoder.h b/webrtc/video_engine/vie_encoder.h
index 3ed661a..3777adb 100644
--- a/webrtc/video_engine/vie_encoder.h
+++ b/webrtc/video_engine/vie_encoder.h
@@ -59,7 +59,8 @@
              uint32_t number_of_cores,
              const Config& config,
              ProcessThread& module_process_thread,
-             BitrateController* bitrate_controller);
+             BitrateController* bitrate_controller,
+             bool disable_default_encoder);
   ~ViEEncoder();
 
   bool Init();
@@ -202,6 +203,7 @@
   int32_t engine_id_;
   const int channel_id_;
   const uint32_t number_of_cores_;
+  const bool disable_default_encoder_;
 
   VideoCodingModule& vcm_;
   VideoProcessingModule& vpm_;