Make VideoSendStream/VideoReceiveStream configs const.

Benefits of this is that the send config previously had unclear locking
requirements, a lock was used to lock parts parts of it while
reconfiguring the VideoEncoder. Primary work was splitting out video
streams from config as well as encoder_settings as these change on
ReconfigureVideoEncoder. Now threading requirements for both member
configs are clear (as they are read-only), and encoder_settings doesn't
stay in the config as a stale pointer.

CreateVideoSendStream now takes video streams separately as well as the
encoder_settings pointer, analogous to ReconfigureVideoEncoder.

This change required changing so that pacing is silently enabled when
using suspend_below_min_bitrate rather than silently setting it.

R=henrik.lundin@webrtc.org, mflodman@webrtc.org, pthatcher@webrtc.org, stefan@webrtc.org
BUG=3260

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@6349 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/talk/media/webrtc/webrtcvideoengine2.cc b/talk/media/webrtc/webrtcvideoengine2.cc
index 723ef1d..6593b2a 100644
--- a/talk/media/webrtc/webrtcvideoengine2.cc
+++ b/talk/media/webrtc/webrtcvideoengine2.cc
@@ -197,22 +197,15 @@
 
 class DefaultVideoEncoderFactory : public WebRtcVideoEncoderFactory2 {
  public:
-  virtual bool CreateEncoderSettings(
-      webrtc::VideoSendStream::Config::EncoderSettings* encoder_settings,
-      const VideoOptions& options,
+  virtual std::vector<webrtc::VideoStream> CreateVideoStreams(
       const VideoCodec& codec,
+      const VideoOptions& options,
       size_t num_streams) OVERRIDE {
+    assert(SupportsCodec(codec));
     if (num_streams != 1) {
       LOG(LS_ERROR) << "Unsupported number of streams: " << num_streams;
-      return false;
+      return std::vector<webrtc::VideoStream>();
     }
-    if (!SupportsCodec(codec)) {
-      LOG(LS_ERROR) << "Can't create encoder settings for unsupported codec: '"
-                    << codec.name << "'";
-      return false;
-    }
-
-    *encoder_settings = webrtc::VideoSendStream::Config::EncoderSettings();
 
     webrtc::VideoStream stream;
     stream.width = codec.width;
@@ -230,13 +223,16 @@
     int max_qp = 56;
     codec.GetParam(kCodecParamMaxQuantization, &max_qp);
     stream.max_qp = max_qp;
-    encoder_settings->streams.push_back(stream);
+    std::vector<webrtc::VideoStream> streams;
+    streams.push_back(stream);
+    return streams;
+  }
 
-    encoder_settings->encoder = webrtc::VP8Encoder::Create();
-    encoder_settings->payload_type = kDefaultVideoCodecPref.payload_type;
-    encoder_settings->payload_name = kDefaultVideoCodecPref.name;
-
-    return true;
+  virtual webrtc::VideoEncoder* CreateVideoEncoder(
+      const VideoCodec& codec,
+      const VideoOptions& options) OVERRIDE {
+    assert(SupportsCodec(codec));
+    return webrtc::VP8Encoder::Create();
   }
 
   virtual bool SupportsCodec(const VideoCodec& codec) OVERRIDE {
@@ -471,11 +467,11 @@
   return default_video_encoder_factory_.get();
 }
 
-// Thin map between cricket::VideoFrame and an existing webrtc::I420VideoFrame
+// Thin map between VideoFrame and an existing webrtc::I420VideoFrame
 // to avoid having to copy the rendered VideoFrame prematurely.
 // This implementation is only safe to use in a const context and should never
 // be written to.
-class WebRtcVideoRenderFrame : public cricket::VideoFrame {
+class WebRtcVideoRenderFrame : public VideoFrame {
  public:
   explicit WebRtcVideoRenderFrame(const webrtc::I420VideoFrame* frame)
       : frame_(frame) {}
@@ -924,14 +920,17 @@
 
   // CreateEncoderSettings will allocate a suitable VideoEncoder instance
   // matching current settings.
-  if (!encoder_factory_->CreateEncoderSettings(&config.encoder_settings,
-                                               options_,
-                                               codec_settings.codec,
-                                               config.rtp.ssrcs.size())) {
-    LOG(LS_ERROR) << "Failed to create suitable encoder settings.";
+  std::vector<webrtc::VideoStream> video_streams =
+      encoder_factory_->CreateVideoStreams(
+          codec_settings.codec, options_, config.rtp.ssrcs.size());
+  if (video_streams.empty()) {
     return false;
   }
 
+  config.encoder_settings.encoder =
+      encoder_factory_->CreateVideoEncoder(codec_settings.codec, options_);
+  config.encoder_settings.payload_name = codec_settings.codec.name;
+  config.encoder_settings.payload_type = codec_settings.codec.id;
   config.rtp.c_name = sp.cname;
   config.rtp.fec = codec_settings.fec;
   if (!config.rtp.rtx.ssrcs.empty()) {
@@ -942,7 +941,12 @@
   config.rtp.max_packet_size = kVideoMtu;
 
   WebRtcVideoSendStream* stream =
-      new WebRtcVideoSendStream(call_.get(), config, encoder_factory_);
+      new WebRtcVideoSendStream(call_.get(),
+                                config,
+                                options_,
+                                codec_settings.codec,
+                                video_streams,
+                                encoder_factory_);
   send_streams_[ssrc] = stream;
 
   if (rtcp_receiver_report_ssrc_ == kDefaultRtcpReceiverReportSsrc) {
@@ -1339,21 +1343,35 @@
   }
 }
 
+WebRtcVideoChannel2::WebRtcVideoSendStream::VideoSendStreamParameters::
+    VideoSendStreamParameters(
+        const webrtc::VideoSendStream::Config& config,
+        const VideoOptions& options,
+        const VideoCodec& codec,
+        const std::vector<webrtc::VideoStream>& video_streams)
+    : config(config),
+      options(options),
+      codec(codec),
+      video_streams(video_streams) {
+}
+
 WebRtcVideoChannel2::WebRtcVideoSendStream::WebRtcVideoSendStream(
     webrtc::Call* call,
     const webrtc::VideoSendStream::Config& config,
+    const VideoOptions& options,
+    const VideoCodec& codec,
+    const std::vector<webrtc::VideoStream>& video_streams,
     WebRtcVideoEncoderFactory2* encoder_factory)
     : call_(call),
-      config_(config),
+      parameters_(config, options, codec, video_streams),
       encoder_factory_(encoder_factory),
       capturer_(NULL),
       stream_(NULL),
       sending_(false),
       muted_(false),
-      format_(static_cast<int>(config.encoder_settings.streams.back().height),
-              static_cast<int>(config.encoder_settings.streams.back().width),
-              VideoFormat::FpsToInterval(
-                  config.encoder_settings.streams.back().max_framerate),
+      format_(static_cast<int>(video_streams.back().height),
+              static_cast<int>(video_streams.back().width),
+              VideoFormat::FpsToInterval(video_streams.back().max_framerate),
               FOURCC_I420) {
   RecreateWebRtcStream();
 }
@@ -1361,7 +1379,7 @@
 WebRtcVideoChannel2::WebRtcVideoSendStream::~WebRtcVideoSendStream() {
   DisconnectCapturer();
   call_->DestroyVideoSendStream(stream_);
-  delete config_.encoder_settings.encoder;
+  delete parameters_.config.encoder_settings.encoder;
 }
 
 static void SetWebRtcFrameToBlack(webrtc::I420VideoFrame* video_frame) {
@@ -1428,8 +1446,8 @@
   }
   LOG(LS_VERBOSE) << "SwapFrame: " << video_frame_.width() << "x"
                   << video_frame_.height() << " -> (codec) "
-                  << config_.encoder_settings.streams.back().width << "x"
-                  << config_.encoder_settings.streams.back().height;
+                  << parameters_.video_streams.back().width << "x"
+                  << parameters_.video_streams.back().height;
   stream_->Input()->SwapFrame(&video_frame_);
 }
 
@@ -1480,10 +1498,10 @@
   if (format.width == 0 && format.height == 0) {
     LOG(LS_INFO)
         << "0x0 resolution selected. Captured frames will be dropped for ssrc: "
-        << config_.rtp.ssrcs[0] << ".";
+        << parameters_.config.rtp.ssrcs[0] << ".";
   } else {
     // TODO(pbos): Fix me, this only affects the last stream!
-    config_.encoder_settings.streams.back().max_framerate =
+    parameters_.video_streams.back().max_framerate =
         VideoFormat::IntervalToFps(format.interval);
     SetDimensions(format.width, format.height);
   }
@@ -1513,44 +1531,46 @@
     const VideoOptions& options,
     const VideoCodecSettings& codec) {
   talk_base::CritScope cs(&lock_);
-  webrtc::VideoEncoder* old_encoder = config_.encoder_settings.encoder;
-  if (!encoder_factory_->CreateEncoderSettings(
-          &config_.encoder_settings,
-          options,
-          codec.codec,
-          config_.encoder_settings.streams.size())) {
-    LOG(LS_ERROR) << "Could not create encoder settings for: '"
-                  << codec.codec.name
-                  << "'. This is most definitely a bug as SetCodec should only "
-                     "receive codecs which the encoder factory claims to "
-                     "support.";
+
+  std::vector<webrtc::VideoStream> video_streams =
+      encoder_factory_->CreateVideoStreams(
+          codec.codec, options, parameters_.video_streams.size());
+  if (video_streams.empty()) {
     return;
   }
+  parameters_.video_streams = video_streams;
   format_ = VideoFormat(codec.codec.width,
                         codec.codec.height,
                         VideoFormat::FpsToInterval(30),
                         FOURCC_I420);
-  config_.rtp.fec = codec.fec;
+
+  webrtc::VideoEncoder* old_encoder =
+      parameters_.config.encoder_settings.encoder;
+  parameters_.config.encoder_settings.encoder =
+      encoder_factory_->CreateVideoEncoder(codec.codec, options);
+  parameters_.config.rtp.fec = codec.fec;
   // TODO(pbos): Should changing RTX payload type be allowed?
+  parameters_.codec = codec.codec;
+  parameters_.options = options;
   RecreateWebRtcStream();
   delete old_encoder;
 }
 
 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetDimensions(int width,
-                                                              int height) {
-  assert(!config_.encoder_settings.streams.empty());
+                                                               int height) {
+  assert(!parameters_.video_streams.empty());
   LOG(LS_VERBOSE) << "SetDimensions: " << width << "x" << height;
-  if (config_.encoder_settings.streams.back().width == width &&
-      config_.encoder_settings.streams.back().height == height) {
+  if (parameters_.video_streams.back().width == width &&
+      parameters_.video_streams.back().height == height) {
     return;
   }
 
   // TODO(pbos): Fix me, this only affects the last stream!
-  config_.encoder_settings.streams.back().width = width;
-  config_.encoder_settings.streams.back().height = height;
-  // TODO(pbos): Last parameter shouldn't always be NULL?
-  if (!stream_->ReconfigureVideoEncoder(config_.encoder_settings.streams,
-                                        NULL)) {
+  parameters_.video_streams.back().width = width;
+  parameters_.video_streams.back().height = height;
+
+  // TODO(pbos): Wire up encoder_parameters, webrtc:3424.
+  if (!stream_->ReconfigureVideoEncoder(parameters_.video_streams, NULL)) {
     LOG(LS_WARNING) << "Failed to reconfigure video encoder for dimensions: "
                     << width << "x" << height;
     return;
@@ -1573,7 +1593,10 @@
   if (stream_ != NULL) {
     call_->DestroyVideoSendStream(stream_);
   }
-  stream_ = call_->CreateVideoSendStream(config_);
+
+  // TODO(pbos): Wire up encoder_parameters, webrtc:3424.
+  stream_ = call_->CreateVideoSendStream(
+      parameters_.config, parameters_.video_streams, NULL);
   if (sending_) {
     stream_->Start();
   }
diff --git a/talk/media/webrtc/webrtcvideoengine2.h b/talk/media/webrtc/webrtcvideoengine2.h
index 10a1608..4287d28 100644
--- a/talk/media/webrtc/webrtcvideoengine2.h
+++ b/talk/media/webrtc/webrtcvideoengine2.h
@@ -83,11 +83,15 @@
 class WebRtcVideoEncoderFactory2 {
  public:
   virtual ~WebRtcVideoEncoderFactory2();
-  virtual bool CreateEncoderSettings(
-      webrtc::VideoSendStream::Config::EncoderSettings* encoder_settings,
+  virtual std::vector<webrtc::VideoStream> CreateVideoStreams(
+      const VideoCodec& codec,
       const VideoOptions& options,
-      const cricket::VideoCodec& codec,
       size_t num_streams) = 0;
+
+  virtual webrtc::VideoEncoder* CreateVideoEncoder(
+      const VideoCodec& codec,
+      const VideoOptions& options) = 0;
+
   virtual bool SupportsCodec(const cricket::VideoCodec& codec) = 0;
 };
 
@@ -258,7 +262,7 @@
   struct VideoCodecSettings {
     VideoCodecSettings();
 
-    cricket::VideoCodec codec;
+    VideoCodec codec;
     webrtc::FecConfig fec;
     int rtx_payload_type;
   };
@@ -266,8 +270,11 @@
   class WebRtcVideoSendStream : public sigslot::has_slots<> {
    public:
     WebRtcVideoSendStream(webrtc::Call* call,
-                           const webrtc::VideoSendStream::Config& config,
-                           WebRtcVideoEncoderFactory2* encoder_factory);
+                          const webrtc::VideoSendStream::Config& config,
+                          const VideoOptions& options,
+                          const VideoCodec& codec,
+                          const std::vector<webrtc::VideoStream>& video_streams,
+                          WebRtcVideoEncoderFactory2* encoder_factory);
     ~WebRtcVideoSendStream();
     void SetCodec(const VideoOptions& options, const VideoCodecSettings& codec);
 
@@ -281,6 +288,25 @@
     void Stop();
 
    private:
+    // Parameters needed to reconstruct the underlying stream.
+    // webrtc::VideoSendStream doesn't support setting a lot of options on the
+    // fly, so when those need to be changed we tear down and reconstruct with
+    // similar parameters depending on which options changed etc.
+    struct VideoSendStreamParameters {
+      VideoSendStreamParameters(
+          const webrtc::VideoSendStream::Config& config,
+          const VideoOptions& options,
+          const VideoCodec& codec,
+          const std::vector<webrtc::VideoStream>& video_streams);
+      webrtc::VideoSendStream::Config config;
+      VideoOptions options;
+      VideoCodec codec;
+      // Sent resolutions + bitrates etc. by the underlying VideoSendStream,
+      // typically changes when setting a new resolution or reconfiguring
+      // bitrates.
+      std::vector<webrtc::VideoStream> video_streams;
+    };
+
     void RecreateWebRtcStream();
     void SetDimensions(int width, int height);
 
@@ -289,7 +315,8 @@
 
     talk_base::CriticalSection lock_;
     webrtc::VideoSendStream* stream_ GUARDED_BY(lock_);
-    webrtc::VideoSendStream::Config config_ GUARDED_BY(lock_);
+    VideoSendStreamParameters parameters_ GUARDED_BY(lock_);
+
     VideoCapturer* capturer_ GUARDED_BY(lock_);
     bool sending_ GUARDED_BY(lock_);
     bool muted_ GUARDED_BY(lock_);
diff --git a/talk/media/webrtc/webrtcvideoengine2_unittest.cc b/talk/media/webrtc/webrtcvideoengine2_unittest.cc
index bba1455..c478b42 100644
--- a/talk/media/webrtc/webrtcvideoengine2_unittest.cc
+++ b/talk/media/webrtc/webrtcvideoengine2_unittest.cc
@@ -52,12 +52,12 @@
 namespace cricket {
 class FakeVideoSendStream : public webrtc::VideoSendStream {
  public:
-  explicit FakeVideoSendStream(const webrtc::VideoSendStream::Config& config)
-      : sending_(false) {
-    config_ = config;
-  }
+  FakeVideoSendStream(const webrtc::VideoSendStream::Config& config,
+                      const std::vector<webrtc::VideoStream>& video_streams)
+      : sending_(false), config_(config), video_streams_(video_streams) {}
 
   webrtc::VideoSendStream::Config GetConfig() { return config_; }
+  std::vector<webrtc::VideoStream> GetVideoStreams() { return video_streams_; }
 
   bool IsSending() { return sending_; }
 
@@ -68,9 +68,8 @@
 
   virtual bool ReconfigureVideoEncoder(
       const std::vector<webrtc::VideoStream>& streams,
-      void* encoder_specific) OVERRIDE {
-    // TODO(pbos): Store encoder_specific ptr?
-    config_.encoder_settings.streams = streams;
+      const void* encoder_specific) OVERRIDE {
+    video_streams_ = streams;
     return true;
   }
 
@@ -85,6 +84,7 @@
 
   bool sending_;
   webrtc::VideoSendStream::Config config_;
+  std::vector<webrtc::VideoStream> video_streams_;
 };
 
 class FakeVideoReceiveStream : public webrtc::VideoReceiveStream {
@@ -178,8 +178,11 @@
   }
 
   virtual webrtc::VideoSendStream* CreateVideoSendStream(
-      const webrtc::VideoSendStream::Config& config) OVERRIDE {
-    FakeVideoSendStream* fake_stream = new FakeVideoSendStream(config);
+      const webrtc::VideoSendStream::Config& config,
+      const std::vector<webrtc::VideoStream>& video_streams,
+      const void* encoder_settings) OVERRIDE {
+    FakeVideoSendStream* fake_stream =
+        new FakeVideoSendStream(config, video_streams);
     video_send_streams_.push_back(fake_stream);
     return fake_stream;
   }
@@ -515,13 +518,10 @@
 
     FakeVideoSendStream* stream = AddSendStream();
 
-    webrtc::VideoSendStream::Config::EncoderSettings encoder_settings =
-        stream->GetConfig().encoder_settings;
-    ASSERT_EQ(1u, encoder_settings.streams.size());
-    EXPECT_EQ(atoi(min_bitrate),
-              encoder_settings.streams.back().min_bitrate_bps / 1000);
-    EXPECT_EQ(atoi(max_bitrate),
-              encoder_settings.streams.back().max_bitrate_bps / 1000);
+    std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
+    ASSERT_EQ(1u, video_streams.size());
+    EXPECT_EQ(atoi(min_bitrate), video_streams.back().min_bitrate_bps / 1000);
+    EXPECT_EQ(atoi(max_bitrate), video_streams.back().max_bitrate_bps / 1000);
 
     VideoCodec codec;
     EXPECT_TRUE(channel_->GetSendCodec(&codec));
@@ -556,15 +556,14 @@
   const unsigned int kVideoTargetSendBitrateKbps = 300;
   const unsigned int kVideoMaxSendBitrateKbps = 2000;
   FakeVideoSendStream* stream = AddSendStream();
-  webrtc::VideoSendStream::Config::EncoderSettings encoder_settings =
-      stream->GetConfig().encoder_settings;
-  ASSERT_EQ(1u, encoder_settings.streams.size());
+  std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
+  ASSERT_EQ(1u, video_streams.size());
   EXPECT_EQ(kVideoMinSendBitrateKbps,
-            encoder_settings.streams.back().min_bitrate_bps / 1000);
+            video_streams.back().min_bitrate_bps / 1000);
   EXPECT_EQ(kVideoTargetSendBitrateKbps,
-            encoder_settings.streams.back().target_bitrate_bps / 1000);
+            video_streams.back().target_bitrate_bps / 1000);
   EXPECT_EQ(kVideoMaxSendBitrateKbps,
-            encoder_settings.streams.back().max_bitrate_bps / 1000);
+            video_streams.back().max_bitrate_bps / 1000);
 #if 0
   // TODO(pbos): un-#if
   VerifyVP8SendCodec(send_channel, kVP8Codec.width, kVP8Codec.height, 0,
@@ -925,9 +924,8 @@
   codecs.push_back(kVp8Codec);
   codecs[0].params[kCodecParamMaxQuantization] = kMaxQuantization;
   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-  EXPECT_EQ(
-      static_cast<unsigned int>(atoi(kMaxQuantization)),
-      AddSendStream()->GetConfig().encoder_settings.streams.back().max_qp);
+  EXPECT_EQ(static_cast<unsigned int>(atoi(kMaxQuantization)),
+            AddSendStream()->GetVideoStreams().back().max_qp);
 
   VideoCodec codec;
   EXPECT_TRUE(channel_->GetSendCodec(&codec));
diff --git a/webrtc/call.h b/webrtc/call.h
index 53b17ed..1771ad8 100644
--- a/webrtc/call.h
+++ b/webrtc/call.h
@@ -83,7 +83,9 @@
   virtual VideoSendStream::Config GetDefaultSendConfig() = 0;
 
   virtual VideoSendStream* CreateVideoSendStream(
-      const VideoSendStream::Config& config) = 0;
+      const VideoSendStream::Config& config,
+      const std::vector<VideoStream>& video_streams,
+      const void* encoder_settings) = 0;
 
   virtual void DestroyVideoSendStream(VideoSendStream* send_stream) = 0;
 
diff --git a/webrtc/test/encoder_settings.cc b/webrtc/test/encoder_settings.cc
index d02c29f..5193be6 100644
--- a/webrtc/test/encoder_settings.cc
+++ b/webrtc/test/encoder_settings.cc
@@ -16,18 +16,14 @@
 
 namespace webrtc {
 namespace test {
-VideoSendStream::Config::EncoderSettings CreateEncoderSettings(
-    VideoEncoder* encoder,
-    const char* payload_name,
-    int payload_type,
-    size_t num_streams) {
+std::vector<VideoStream> CreateVideoStreams(size_t num_streams) {
   assert(num_streams > 0);
 
   // Add more streams to the settings above with reasonable values if required.
   static const size_t kNumSettings = 3;
   assert(num_streams <= kNumSettings);
 
-  VideoStream stream_settings[kNumSettings];
+  std::vector<VideoStream> stream_settings(kNumSettings);
 
   stream_settings[0].width = 320;
   stream_settings[0].height = 180;
@@ -52,28 +48,20 @@
   stream_settings[2].target_bitrate_bps = stream_settings[2].max_bitrate_bps =
       1500000;
   stream_settings[2].max_qp = 56;
-
-  VideoSendStream::Config::EncoderSettings settings;
-
-  for (size_t i = 0; i < num_streams; ++i)
-    settings.streams.push_back(stream_settings[i]);
-
-  settings.encoder = encoder;
-  settings.payload_name = payload_name;
-  settings.payload_type = payload_type;
-  return settings;
+  stream_settings.resize(num_streams);
+  return stream_settings;
 }
 
 VideoCodec CreateDecoderVideoCodec(
-    const VideoSendStream::Config::EncoderSettings& settings) {
-  assert(settings.streams.size() > 0);
+    const VideoSendStream::Config::EncoderSettings& encoder_settings) {
   VideoCodec codec;
   memset(&codec, 0, sizeof(codec));
 
-  codec.plType = settings.payload_type;
-  strcpy(codec.plName, settings.payload_name.c_str());
+  codec.plType = encoder_settings.payload_type;
+  strcpy(codec.plName, encoder_settings.payload_name.c_str());
   codec.codecType =
-      (settings.payload_name == "VP8" ? kVideoCodecVP8 : kVideoCodecGeneric);
+      (encoder_settings.payload_name == "VP8" ? kVideoCodecVP8
+                                              : kVideoCodecGeneric);
 
   if (codec.codecType == kVideoCodecVP8) {
     codec.codecSpecific.VP8.resilience = kResilientStream;
@@ -85,33 +73,9 @@
     codec.codecSpecific.VP8.keyFrameInterval = 3000;
   }
 
-  codec.minBitrate = settings.streams[0].min_bitrate_bps / 1000;
-  for (size_t i = 0; i < settings.streams.size(); ++i) {
-    const VideoStream& stream = settings.streams[i];
-    if (stream.width > codec.width)
-      codec.width = static_cast<unsigned short>(stream.width);
-    if (stream.height > codec.height)
-      codec.height = static_cast<unsigned short>(stream.height);
-    if (static_cast<unsigned int>(stream.min_bitrate_bps / 1000) <
-        codec.minBitrate)
-      codec.minBitrate =
-          static_cast<unsigned int>(stream.min_bitrate_bps / 1000);
-    codec.maxBitrate += stream.max_bitrate_bps / 1000;
-    if (static_cast<unsigned int>(stream.max_qp) > codec.qpMax)
-      codec.qpMax = static_cast<unsigned int>(stream.max_qp);
-  }
-
-  if (codec.minBitrate < kViEMinCodecBitrate)
-    codec.minBitrate = kViEMinCodecBitrate;
-  if (codec.maxBitrate < kViEMinCodecBitrate)
-    codec.maxBitrate = kViEMinCodecBitrate;
-
-  codec.startBitrate = 300;
-
-  if (codec.startBitrate < codec.minBitrate)
-    codec.startBitrate = codec.minBitrate;
-  if (codec.startBitrate > codec.maxBitrate)
-    codec.startBitrate = codec.maxBitrate;
+  codec.width = 320;
+  codec.height = 180;
+  codec.startBitrate = codec.minBitrate = codec.maxBitrate = 300;
 
   return codec;
 }
diff --git a/webrtc/test/encoder_settings.h b/webrtc/test/encoder_settings.h
index 1d8e355..ea2be97 100644
--- a/webrtc/test/encoder_settings.h
+++ b/webrtc/test/encoder_settings.h
@@ -14,14 +14,10 @@
 
 namespace webrtc {
 namespace test {
-VideoSendStream::Config::EncoderSettings CreateEncoderSettings(
-    VideoEncoder* encoder,
-    const char* payload_name,
-    int payload_type,
-    size_t num_streams);
+std::vector<VideoStream> CreateVideoStreams(size_t num_streams);
 
 VideoCodec CreateDecoderVideoCodec(
-    const VideoSendStream::Config::EncoderSettings& settings);
+    const VideoSendStream::Config::EncoderSettings& encoder_settings);
 }  // namespace test
 }  // namespace webrtc
 
diff --git a/webrtc/video/bitrate_estimator_tests.cc b/webrtc/video/bitrate_estimator_tests.cc
index 7b74818..f8b9060 100644
--- a/webrtc/video/bitrate_estimator_tests.cc
+++ b/webrtc/video/bitrate_estimator_tests.cc
@@ -70,8 +70,10 @@
     send_config_ = sender_call_->GetDefaultSendConfig();
     send_config_.rtp.ssrcs.push_back(kSendSsrc);
     // Encoders will be set separately per stream.
-    send_config_.encoder_settings =
-        test::CreateEncoderSettings(NULL, "FAKE", kSendPayloadType, 1);
+    send_config_.encoder_settings.encoder = NULL;
+    send_config_.encoder_settings.payload_name = "FAKE";
+    send_config_.encoder_settings.payload_type = kSendPayloadType;
+    video_streams_ = test::CreateVideoStreams(1);
 
     receive_config_ = receiver_call_->GetDefaultReceiveConfig();
     assert(receive_config_.codecs.empty());
@@ -169,15 +171,15 @@
           fake_decoder_() {
       test_->send_config_.rtp.ssrcs[0]++;
       test_->send_config_.encoder_settings.encoder = &fake_encoder_;
-      send_stream_ =
-          test_->sender_call_->CreateVideoSendStream(test_->send_config_);
-      assert(test_->send_config_.encoder_settings.streams.size() == 1);
-      frame_generator_capturer_.reset(test::FrameGeneratorCapturer::Create(
-          send_stream_->Input(),
-          test_->send_config_.encoder_settings.streams[0].width,
-          test_->send_config_.encoder_settings.streams[0].height,
-          30,
-          Clock::GetRealTimeClock()));
+      send_stream_ = test_->sender_call_->CreateVideoSendStream(
+          test_->send_config_, test_->video_streams_, NULL);
+      assert(test_->video_streams_.size() == 1);
+      frame_generator_capturer_.reset(
+          test::FrameGeneratorCapturer::Create(send_stream_->Input(),
+                                               test_->video_streams_[0].width,
+                                               test_->video_streams_[0].height,
+                                               30,
+                                               Clock::GetRealTimeClock()));
       send_stream_->Start();
       frame_generator_capturer_->Start();
 
@@ -227,6 +229,7 @@
   scoped_ptr<Call> sender_call_;
   scoped_ptr<Call> receiver_call_;
   VideoSendStream::Config send_config_;
+  std::vector<VideoStream> video_streams_;
   VideoReceiveStream::Config receive_config_;
   std::vector<Stream*> streams_;
 };
diff --git a/webrtc/video/call.cc b/webrtc/video/call.cc
index 6adb0fc..6103074 100644
--- a/webrtc/video/call.cc
+++ b/webrtc/video/call.cc
@@ -70,7 +70,9 @@
   virtual VideoSendStream::Config GetDefaultSendConfig() OVERRIDE;
 
   virtual VideoSendStream* CreateVideoSendStream(
-      const VideoSendStream::Config& config) OVERRIDE;
+      const VideoSendStream::Config& config,
+      const std::vector<VideoStream>& video_streams,
+      const void* encoder_settings) OVERRIDE;
 
   virtual void DestroyVideoSendStream(webrtc::VideoSendStream* send_stream)
       OVERRIDE;
@@ -175,15 +177,19 @@
 }
 
 VideoSendStream* Call::CreateVideoSendStream(
-    const VideoSendStream::Config& config) {
+    const VideoSendStream::Config& config,
+    const std::vector<VideoStream>& video_streams,
+    const void* encoder_settings) {
   assert(config.rtp.ssrcs.size() > 0);
 
-  VideoSendStream* send_stream = new VideoSendStream(
-      config_.send_transport,
-      overuse_observer_proxy_.get(),
-      video_engine_,
-      config,
-      base_channel_id_);
+  VideoSendStream* send_stream =
+      new VideoSendStream(config_.send_transport,
+                          overuse_observer_proxy_.get(),
+                          video_engine_,
+                          config,
+                          video_streams,
+                          encoder_settings,
+                          base_channel_id_);
 
   WriteLockScoped write_lock(*send_lock_);
   for (size_t i = 0; i < config.rtp.ssrcs.size(); ++i) {
diff --git a/webrtc/video/call_perf_tests.cc b/webrtc/video/call_perf_tests.cc
index bc0a1e0..f9e44ae 100644
--- a/webrtc/video/call_perf_tests.cc
+++ b/webrtc/video/call_perf_tests.cc
@@ -53,18 +53,19 @@
       : send_stream_(NULL), fake_encoder_(Clock::GetRealTimeClock()) {}
 
  protected:
-  VideoSendStream::Config GetSendTestConfig(Call* call) {
-    VideoSendStream::Config config = call->GetDefaultSendConfig();
-    config.rtp.ssrcs.push_back(kSendSsrc);
-    config.encoder_settings = test::CreateEncoderSettings(
-        &fake_encoder_, "FAKE", kSendPayloadType, 1);
-    return config;
+  void CreateTestConfig(Call* call) {
+    send_config_ = call->GetDefaultSendConfig();
+    send_config_.rtp.ssrcs.push_back(kSendSsrc);
+    send_config_.encoder_settings.encoder = &fake_encoder_;
+    send_config_.encoder_settings.payload_type = kSendPayloadType;
+    send_config_.encoder_settings.payload_name = "FAKE";
+    video_streams_ = test::CreateVideoStreams(1);
   }
 
   void RunVideoSendTest(Call* call,
                         const VideoSendStream::Config& config,
                         test::RtpRtcpObserver* observer) {
-    send_stream_ = call->CreateVideoSendStream(config);
+    send_stream_ = call->CreateVideoSendStream(config, video_streams_, NULL);
     scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer(
         test::FrameGeneratorCapturer::Create(
             send_stream_->Input(), 320, 240, 30, Clock::GetRealTimeClock()));
@@ -86,6 +87,8 @@
                           int start_time_ms,
                           int run_time_ms);
 
+  VideoSendStream::Config send_config_;
+  std::vector<VideoStream> video_streams_;
   VideoSendStream* send_stream_;
   test::FakeEncoder fake_encoder_;
 };
@@ -288,35 +291,34 @@
 
   test::FakeDecoder fake_decoder;
 
-  VideoSendStream::Config send_config = GetSendTestConfig(sender_call.get());
+  CreateTestConfig(sender_call.get());
 
   VideoReceiveStream::Config receive_config =
       receiver_call->GetDefaultReceiveConfig();
   assert(receive_config.codecs.empty());
   VideoCodec codec =
-      test::CreateDecoderVideoCodec(send_config.encoder_settings);
+      test::CreateDecoderVideoCodec(send_config_.encoder_settings);
   receive_config.codecs.push_back(codec);
   assert(receive_config.external_decoders.empty());
   ExternalVideoDecoder decoder;
   decoder.decoder = &fake_decoder;
-  decoder.payload_type = send_config.encoder_settings.payload_type;
+  decoder.payload_type = send_config_.encoder_settings.payload_type;
   receive_config.external_decoders.push_back(decoder);
-  receive_config.rtp.remote_ssrc = send_config.rtp.ssrcs[0];
+  receive_config.rtp.remote_ssrc = send_config_.rtp.ssrcs[0];
   receive_config.rtp.local_ssrc = kReceiverLocalSsrc;
   receive_config.renderer = &observer;
   receive_config.audio_channel_id = channel;
 
   VideoSendStream* send_stream =
-      sender_call->CreateVideoSendStream(send_config);
+      sender_call->CreateVideoSendStream(send_config_, video_streams_, NULL);
   VideoReceiveStream* receive_stream =
       receiver_call->CreateVideoReceiveStream(receive_config);
   scoped_ptr<test::FrameGeneratorCapturer> capturer(
-      test::FrameGeneratorCapturer::Create(
-          send_stream->Input(),
-          send_config.encoder_settings.streams[0].width,
-          send_config.encoder_settings.streams[0].height,
-          30,
-          Clock::GetRealTimeClock()));
+      test::FrameGeneratorCapturer::Create(send_stream->Input(),
+                                           video_streams_[0].width,
+                                           video_streams_[0].height,
+                                           30,
+                                           Clock::GetRealTimeClock()));
   receive_stream->Start();
   send_stream->Start();
   capturer->Start();
@@ -465,16 +467,15 @@
   observer.SetReceivers(receiver_call->Receiver(), sender_call->Receiver());
 
   // Configure send stream.
-  VideoSendStream::Config send_config = GetSendTestConfig(sender_call.get());
+  CreateTestConfig(sender_call.get());
   VideoSendStream* send_stream =
-      sender_call->CreateVideoSendStream(send_config);
+      sender_call->CreateVideoSendStream(send_config_, video_streams_, NULL);
   scoped_ptr<test::FrameGeneratorCapturer> capturer(
-      test::FrameGeneratorCapturer::Create(
-          send_stream->Input(),
-          send_config.encoder_settings.streams[0].width,
-          send_config.encoder_settings.streams[0].height,
-          30,
-          Clock::GetRealTimeClock()));
+      test::FrameGeneratorCapturer::Create(send_stream->Input(),
+                                           video_streams_[0].width,
+                                           video_streams_[0].height,
+                                           30,
+                                           Clock::GetRealTimeClock()));
   observer.SetCapturer(capturer.get());
 
   // Configure receive stream.
@@ -482,15 +483,15 @@
       receiver_call->GetDefaultReceiveConfig();
   assert(receive_config.codecs.empty());
   VideoCodec codec =
-      test::CreateDecoderVideoCodec(send_config.encoder_settings);
+      test::CreateDecoderVideoCodec(send_config_.encoder_settings);
   receive_config.codecs.push_back(codec);
   assert(receive_config.external_decoders.empty());
   ExternalVideoDecoder decoder;
   test::FakeDecoder fake_decoder;
   decoder.decoder = &fake_decoder;
-  decoder.payload_type = send_config.encoder_settings.payload_type;
+  decoder.payload_type = send_config_.encoder_settings.payload_type;
   receive_config.external_decoders.push_back(decoder);
-  receive_config.rtp.remote_ssrc = send_config.rtp.ssrcs[0];
+  receive_config.rtp.remote_ssrc = send_config_.rtp.ssrcs[0];
   receive_config.rtp.local_ssrc = kReceiverLocalSsrc;
   receive_config.renderer = &observer;
   // Enable the receiver side rtt calculation.
@@ -559,8 +560,8 @@
   call_config.overuse_callback = &observer;
   scoped_ptr<Call> call(Call::Create(call_config));
 
-  VideoSendStream::Config send_config = GetSendTestConfig(call.get());
-  RunVideoSendTest(call.get(), send_config, &observer);
+  CreateTestConfig(call.get());
+  RunVideoSendTest(call.get(), send_config_, &observer);
 }
 
 void CallPerfTest::TestMinTransmitBitrate(bool pad_to_min_bitrate) {
@@ -636,43 +637,42 @@
   scoped_ptr<Call> receiver_call(
       Call::Create(Call::Config(observer.ReceiveTransport())));
 
-  VideoSendStream::Config send_config = GetSendTestConfig(sender_call.get());
+  CreateTestConfig(sender_call.get());
   fake_encoder_.SetMaxBitrate(kMaxEncodeBitrateKbps);
 
   observer.SetReceivers(receiver_call->Receiver(), sender_call->Receiver());
 
-  send_config.pacing = true;
+  send_config_.pacing = true;
   if (pad_to_min_bitrate) {
-    send_config.rtp.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
+    send_config_.rtp.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
   } else {
-    assert(send_config.rtp.min_transmit_bitrate_bps == 0);
+    assert(send_config_.rtp.min_transmit_bitrate_bps == 0);
   }
 
   VideoReceiveStream::Config receive_config =
       receiver_call->GetDefaultReceiveConfig();
   receive_config.codecs.clear();
   VideoCodec codec =
-      test::CreateDecoderVideoCodec(send_config.encoder_settings);
+      test::CreateDecoderVideoCodec(send_config_.encoder_settings);
   receive_config.codecs.push_back(codec);
   test::FakeDecoder fake_decoder;
   ExternalVideoDecoder decoder;
   decoder.decoder = &fake_decoder;
-  decoder.payload_type = send_config.encoder_settings.payload_type;
+  decoder.payload_type = send_config_.encoder_settings.payload_type;
   receive_config.external_decoders.push_back(decoder);
-  receive_config.rtp.remote_ssrc = send_config.rtp.ssrcs[0];
+  receive_config.rtp.remote_ssrc = send_config_.rtp.ssrcs[0];
   receive_config.rtp.local_ssrc = kReceiverLocalSsrc;
 
   VideoSendStream* send_stream =
-      sender_call->CreateVideoSendStream(send_config);
+      sender_call->CreateVideoSendStream(send_config_, video_streams_, NULL);
   VideoReceiveStream* receive_stream =
       receiver_call->CreateVideoReceiveStream(receive_config);
   scoped_ptr<test::FrameGeneratorCapturer> capturer(
-      test::FrameGeneratorCapturer::Create(
-          send_stream->Input(),
-          send_config.encoder_settings.streams[0].width,
-          send_config.encoder_settings.streams[0].height,
-          30,
-          Clock::GetRealTimeClock()));
+      test::FrameGeneratorCapturer::Create(send_stream->Input(),
+                                           video_streams_[0].width,
+                                           video_streams_[0].height,
+                                           30,
+                                           Clock::GetRealTimeClock()));
   observer.SetSendStream(send_stream);
   receive_stream->Start();
   send_stream->Start();
diff --git a/webrtc/video/call_tests.cc b/webrtc/video/call_tests.cc
index 7b78af3..5bcf115 100644
--- a/webrtc/video/call_tests.cc
+++ b/webrtc/video/call_tests.cc
@@ -73,8 +73,10 @@
     receive_config_ = receiver_call_->GetDefaultReceiveConfig();
 
     send_config_.rtp.ssrcs.push_back(kSendSsrc);
-    send_config_.encoder_settings = test::CreateEncoderSettings(
-        &fake_encoder_, "FAKE", kSendPayloadType, 1);
+    send_config_.encoder_settings.encoder = &fake_encoder_;
+    send_config_.encoder_settings.payload_name = "FAKE";
+    send_config_.encoder_settings.payload_type = kSendPayloadType;
+    video_streams_ = test::CreateVideoStreams(1);
 
     assert(receive_config_.codecs.empty());
     VideoCodec codec =
@@ -92,17 +94,18 @@
     assert(send_stream_ == NULL);
     assert(receive_stream_ == NULL);
 
-    send_stream_ = sender_call_->CreateVideoSendStream(send_config_);
+    send_stream_ =
+        sender_call_->CreateVideoSendStream(send_config_, video_streams_, NULL);
     receive_stream_ = receiver_call_->CreateVideoReceiveStream(receive_config_);
   }
 
   void CreateFrameGenerator() {
-    frame_generator_capturer_.reset(test::FrameGeneratorCapturer::Create(
-        send_stream_->Input(),
-        send_config_.encoder_settings.streams[0].width,
-        send_config_.encoder_settings.streams[0].height,
-        30,
-        Clock::GetRealTimeClock()));
+    frame_generator_capturer_.reset(
+        test::FrameGeneratorCapturer::Create(send_stream_->Input(),
+                                             video_streams_[0].width,
+                                             video_streams_[0].height,
+                                             30,
+                                             Clock::GetRealTimeClock()));
   }
 
   void StartSending() {
@@ -139,6 +142,7 @@
   scoped_ptr<Call> receiver_call_;
 
   VideoSendStream::Config send_config_;
+  std::vector<VideoStream> video_streams_;
   VideoReceiveStream::Config receive_config_;
 
   VideoSendStream* send_stream_;
@@ -350,8 +354,7 @@
   StartSending();
 
   scoped_ptr<test::FrameGenerator> frame_generator(test::FrameGenerator::Create(
-      send_config_.encoder_settings.streams[0].width,
-      send_config_.encoder_settings.streams[0].height));
+      video_streams_[0].width, video_streams_[0].height));
   send_stream_->Input()->SwapFrame(frame_generator->NextFrame());
 
   EXPECT_EQ(kEventSignaled, renderer.Wait())
@@ -701,10 +704,9 @@
   scoped_ptr<VP8Encoder> encoder(VP8Encoder::Create());
   send_config_.encoder_settings.encoder = encoder.get();
   send_config_.encoder_settings.payload_name = "VP8";
-  ASSERT_EQ(1u, send_config_.encoder_settings.streams.size())
-      << "Test setup error.";
-  send_config_.encoder_settings.streams[0].width = kWidth;
-  send_config_.encoder_settings.streams[0].height = kHeight;
+  ASSERT_EQ(1u, video_streams_.size()) << "Test setup error.";
+  video_streams_[0].width = kWidth;
+  video_streams_[0].height = kHeight;
   send_config_.pre_encode_callback = &pre_encode_callback;
   receive_config_.codecs.clear();
   VideoCodec codec =
@@ -1055,15 +1057,18 @@
 
     VideoSendStream::Config send_config = sender_call->GetDefaultSendConfig();
     send_config.rtp.ssrcs.push_back(ssrc);
-    send_config.encoder_settings =
-        test::CreateEncoderSettings(encoders[i].get(), "VP8", 124, 1);
-    VideoStream* stream = &send_config.encoder_settings.streams[0];
+    send_config.encoder_settings.encoder = encoders[i].get();
+    send_config.encoder_settings.payload_name = "VP8";
+    send_config.encoder_settings.payload_type = 124;
+    std::vector<VideoStream> video_streams = test::CreateVideoStreams(1);
+    VideoStream* stream = &video_streams[0];
     stream->width = width;
     stream->height = height;
     stream->max_framerate = 5;
     stream->min_bitrate_bps = stream->target_bitrate_bps =
         stream->max_bitrate_bps = 100000;
-    send_streams[i] = sender_call->CreateVideoSendStream(send_config);
+    send_streams[i] =
+        sender_call->CreateVideoSendStream(send_config, video_streams, NULL);
     send_streams[i]->Start();
 
     VideoReceiveStream::Config receive_config =
@@ -1154,8 +1159,7 @@
   StartSending();
 
   scoped_ptr<test::FrameGenerator> frame_generator(test::FrameGenerator::Create(
-      send_config_.encoder_settings.streams[0].width,
-      send_config_.encoder_settings.streams[0].height));
+      video_streams_[0].width, video_streams_[0].height));
   send_stream_->Input()->SwapFrame(frame_generator->NextFrame());
 
   EXPECT_EQ(kEventSignaled, post_encode_observer.Wait())
diff --git a/webrtc/video/full_stack.cc b/webrtc/video/full_stack.cc
index cb97cd8..6b21cbe 100644
--- a/webrtc/video/full_stack.cc
+++ b/webrtc/video/full_stack.cc
@@ -398,16 +398,19 @@
   send_config.rtp.ssrcs.push_back(kSendSsrc);
 
   scoped_ptr<VP8Encoder> encoder(VP8Encoder::Create());
-  send_config.encoder_settings =
-      test::CreateEncoderSettings(encoder.get(), "VP8", 124, 1);
-  VideoStream* stream = &send_config.encoder_settings.streams[0];
+  send_config.encoder_settings.encoder = encoder.get();
+  send_config.encoder_settings.payload_name = "VP8";
+  send_config.encoder_settings.payload_type = 124;
+  std::vector<VideoStream> video_streams = test::CreateVideoStreams(1);
+  VideoStream* stream = &video_streams[0];
   stream->width = params.clip.width;
   stream->height = params.clip.height;
   stream->min_bitrate_bps = stream->target_bitrate_bps =
       stream->max_bitrate_bps = params.bitrate * 1000;
   stream->max_framerate = params.clip.fps;
 
-  VideoSendStream* send_stream = call->CreateVideoSendStream(send_config);
+  VideoSendStream* send_stream =
+      call->CreateVideoSendStream(send_config, video_streams, NULL);
   analyzer.input_ = send_stream->Input();
 
   scoped_ptr<test::FrameGeneratorCapturer> file_capturer(
diff --git a/webrtc/video/loopback.cc b/webrtc/video/loopback.cc
index eb2d5ae..ecc2089 100644
--- a/webrtc/video/loopback.cc
+++ b/webrtc/video/loopback.cc
@@ -72,19 +72,21 @@
   send_config.local_renderer = local_preview.get();
 
   scoped_ptr<VP8Encoder> encoder(VP8Encoder::Create());
-  send_config.encoder_settings =
-      test::CreateEncoderSettings(encoder.get(), "VP8", 124, 1);
-  VideoStream* stream = &send_config.encoder_settings.streams[0];
+  send_config.encoder_settings.encoder = encoder.get();
+  send_config.encoder_settings.payload_name = "VP8";
+  send_config.encoder_settings.payload_type = 124;
+  std::vector<VideoStream> video_streams = test::CreateVideoStreams(1);
+  VideoStream* stream = &video_streams[0];
   stream->width = flags::Width();
   stream->height = flags::Height();
   stream->min_bitrate_bps = static_cast<int>(flags::MinBitrate()) * 1000;
-  stream->target_bitrate_bps =
-      static_cast<int>(flags::MaxBitrate()) * 1000;
+  stream->target_bitrate_bps = static_cast<int>(flags::MaxBitrate()) * 1000;
   stream->max_bitrate_bps = static_cast<int>(flags::MaxBitrate()) * 1000;
   stream->max_framerate = 30;
   stream->max_qp = 56;
 
-  VideoSendStream* send_stream = call->CreateVideoSendStream(send_config);
+  VideoSendStream* send_stream =
+      call->CreateVideoSendStream(send_config, video_streams, NULL);
 
   Clock* test_clock = Clock::GetRealTimeClock();
 
diff --git a/webrtc/video/rampup_tests.cc b/webrtc/video/rampup_tests.cc
index c86963d..989deea 100644
--- a/webrtc/video/rampup_tests.cc
+++ b/webrtc/video/rampup_tests.cc
@@ -430,12 +430,15 @@
     receiver_transport.SetReceiver(call->Receiver());
 
     test::FakeEncoder encoder(Clock::GetRealTimeClock());
-    send_config.encoder_settings =
-        test::CreateEncoderSettings(&encoder, "FAKE", 125, num_streams);
+    send_config.encoder_settings.encoder = &encoder;
+    send_config.encoder_settings.payload_type = 125;
+    send_config.encoder_settings.payload_name = "FAKE";
+    std::vector<VideoStream> video_streams =
+        test::CreateVideoStreams(num_streams);
 
     if (num_streams == 1) {
-      send_config.encoder_settings.streams[0].target_bitrate_bps = 2000000;
-      send_config.encoder_settings.streams[0].max_bitrate_bps = 2000000;
+      video_streams[0].target_bitrate_bps = 2000000;
+      video_streams[0].max_bitrate_bps = 2000000;
     }
 
     send_config.pacing = pacing;
@@ -455,25 +458,22 @@
       // For multi stream rampup until all streams are being sent. That means
       // enough birate to sent all the target streams plus the min bitrate of
       // the last one.
-      int expected_bitrate_bps =
-          send_config.encoder_settings.streams.back().min_bitrate_bps;
-      for (size_t i = 0; i < send_config.encoder_settings.streams.size() - 1;
-           ++i) {
-        expected_bitrate_bps +=
-            send_config.encoder_settings.streams[i].target_bitrate_bps;
+      int expected_bitrate_bps = video_streams.back().min_bitrate_bps;
+      for (size_t i = 0; i < video_streams.size() - 1; ++i) {
+        expected_bitrate_bps += video_streams[i].target_bitrate_bps;
       }
       stream_observer.set_expected_bitrate_bps(expected_bitrate_bps);
     }
 
-    VideoSendStream* send_stream = call->CreateVideoSendStream(send_config);
+    VideoSendStream* send_stream =
+        call->CreateVideoSendStream(send_config, video_streams, NULL);
 
     scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer(
-        test::FrameGeneratorCapturer::Create(
-            send_stream->Input(),
-            send_config.encoder_settings.streams.back().width,
-            send_config.encoder_settings.streams.back().height,
-            send_config.encoder_settings.streams.back().max_framerate,
-            Clock::GetRealTimeClock()));
+        test::FrameGeneratorCapturer::Create(send_stream->Input(),
+                                             video_streams.back().width,
+                                             video_streams.back().height,
+                                             video_streams.back().max_framerate,
+                                             Clock::GetRealTimeClock()));
 
     send_stream->Start();
     frame_generator_capturer->Start();
@@ -504,23 +504,29 @@
     receiver_transport.SetReceiver(call->Receiver());
 
     test::FakeEncoder encoder(Clock::GetRealTimeClock());
-    send_config.encoder_settings =
-        test::CreateEncoderSettings(&encoder, "FAKE", 125, number_of_streams);
+    send_config.encoder_settings.encoder = &encoder;
+    send_config.encoder_settings.payload_type = 125;
+    send_config.encoder_settings.payload_name = "FAKE";
+    std::vector<VideoStream> video_streams =
+        test::CreateVideoStreams(number_of_streams);
+
     send_config.rtp.nack.rtp_history_ms = 1000;
     send_config.rtp.ssrcs.insert(
         send_config.rtp.ssrcs.begin(), ssrcs.begin(), ssrcs.end());
     send_config.rtp.extensions.push_back(
         RtpExtension(RtpExtension::kAbsSendTime, kAbsoluteSendTimeExtensionId));
     send_config.suspend_below_min_bitrate = true;
+    send_config.pacing = true;
 
-    VideoSendStream* send_stream = call->CreateVideoSendStream(send_config);
+    VideoSendStream* send_stream =
+        call->CreateVideoSendStream(send_config, video_streams, NULL);
     stream_observer.SetSendStream(send_stream);
 
     size_t width = 0;
     size_t height = 0;
-    for (size_t i = 0; i < send_config.encoder_settings.streams.size(); ++i) {
-      size_t stream_width = send_config.encoder_settings.streams[i].width;
-      size_t stream_height = send_config.encoder_settings.streams[i].height;
+    for (size_t i = 0; i < video_streams.size(); ++i) {
+      size_t stream_width = video_streams[i].width;
+      size_t stream_height = video_streams[i].height;
       if (stream_width > width)
         width = stream_width;
       if (stream_height > height)
diff --git a/webrtc/video/video_receive_stream.cc b/webrtc/video/video_receive_stream.cc
index 012ca68..9c3298c 100644
--- a/webrtc/video/video_receive_stream.cc
+++ b/webrtc/video/video_receive_stream.cc
@@ -150,13 +150,13 @@
 
   external_codec_ = ViEExternalCodec::GetInterface(video_engine);
   for (size_t i = 0; i < config_.external_decoders.size(); ++i) {
-    ExternalVideoDecoder* decoder = &config_.external_decoders[i];
+    const ExternalVideoDecoder& decoder = config_.external_decoders[i];
     if (external_codec_->RegisterExternalReceiveCodec(
             channel_,
-            decoder->payload_type,
-            decoder->decoder,
-            decoder->renderer,
-            decoder->expected_delay_ms) != 0) {
+            decoder.payload_type,
+            decoder.decoder,
+            decoder.renderer,
+            decoder.expected_delay_ms) != 0) {
       // TODO(pbos): Abort gracefully? Can this be a runtime error?
       abort();
     }
diff --git a/webrtc/video/video_receive_stream.h b/webrtc/video/video_receive_stream.h
index 4ff086a..2a3c6df 100644
--- a/webrtc/video/video_receive_stream.h
+++ b/webrtc/video/video_receive_stream.h
@@ -69,7 +69,7 @@
  private:
   TransportAdapter transport_adapter_;
   EncodedFrameCallbackAdapter encoded_frame_proxy_;
-  VideoReceiveStream::Config config_;
+  const VideoReceiveStream::Config config_;
   Clock* const clock_;
 
   ViEBase* video_engine_base_;
diff --git a/webrtc/video/video_send_stream.cc b/webrtc/video/video_send_stream.cc
index 886e3dc..8a43387 100644
--- a/webrtc/video/video_send_stream.cc
+++ b/webrtc/video/video_send_stream.cc
@@ -15,6 +15,7 @@
 #include <vector>
 
 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
+#include "webrtc/system_wrappers/interface/logging.h"
 #include "webrtc/video_engine/include/vie_base.h"
 #include "webrtc/video_engine/include/vie_capture.h"
 #include "webrtc/video_engine/include/vie_codec.h"
@@ -32,18 +33,7 @@
   ss << "{payload_name: " << payload_name;
   ss << ", payload_type: " << payload_type;
   if (encoder != NULL)
-    ss << ", (encoder)";
-  if (encoder_settings != NULL)
-    ss << ", (encoder_settings)";
-
-  ss << ", streams: {";
-  for (size_t i = 0; i < streams.size(); ++i) {
-    ss << streams[i].ToString();
-    if (i != streams.size() - 1)
-      ss << "}, {";
-  }
-  ss << '}';
-
+    ss << ", encoder: " << (encoder != NULL ? "(encoder)" : "NULL");
   ss << '}';
   return ss.str();
 }
@@ -124,10 +114,11 @@
                                  CpuOveruseObserver* overuse_observer,
                                  webrtc::VideoEngine* video_engine,
                                  const VideoSendStream::Config& config,
+                                 const std::vector<VideoStream> video_streams,
+                                 const void* encoder_settings,
                                  int base_channel)
     : transport_adapter_(transport),
       encoded_frame_proxy_(config.post_encode_callback),
-      codec_lock_(CriticalSectionWrapper::CreateCriticalSection()),
       config_(config),
       external_codec_(NULL),
       channel_(-1),
@@ -141,7 +132,7 @@
 
   assert(config_.rtp.ssrcs.size() > 0);
   if (config_.suspend_below_min_bitrate)
-    config_.pacing = true;
+    assert(config_.pacing);
   rtp_rtcp_->SetTransmissionSmoothingStatus(channel_, config_.pacing);
 
   assert(config_.rtp.min_transmit_bitrate_bps >= 0);
@@ -216,10 +207,8 @@
   }
 
   codec_ = ViECodec::GetInterface(video_engine);
-  if (!ReconfigureVideoEncoder(config_.encoder_settings.streams,
-                               config_.encoder_settings.encoder_settings)) {
+  if (!ReconfigureVideoEncoder(video_streams, encoder_settings))
     abort();
-  }
 
   if (overuse_observer)
     video_engine_base_->RegisterCpuOveruseObserver(channel_, overuse_observer);
@@ -232,9 +221,8 @@
                                                     &encoded_frame_proxy_);
   }
 
-  if (config_.suspend_below_min_bitrate) {
+  if (config_.suspend_below_min_bitrate)
     codec_->SuspendBelowMinBitrate(channel_);
-  }
 
   rtp_rtcp_->RegisterSendChannelRtcpStatisticsCallback(channel_,
                                                        stats_proxy_.get());
@@ -304,15 +292,12 @@
 
 bool VideoSendStream::ReconfigureVideoEncoder(
     const std::vector<VideoStream>& streams,
-    void* encoder_settings) {
+    const void* encoder_settings) {
   assert(!streams.empty());
   assert(config_.rtp.ssrcs.size() >= streams.size());
   // TODO(pbos): Wire encoder_settings.
   assert(encoder_settings == NULL);
 
-  // VideoStreams in config_.encoder_settings need to be locked.
-  CriticalSectionScoped crit(codec_lock_.get());
-
   VideoCodec video_codec;
   memset(&video_codec, 0, sizeof(video_codec));
   video_codec.codecType =
@@ -383,8 +368,8 @@
   if (video_codec.startBitrate > video_codec.maxBitrate)
     video_codec.startBitrate = video_codec.maxBitrate;
 
-  assert(config_.encoder_settings.streams[0].max_framerate > 0);
-  video_codec.maxFramerate = config_.encoder_settings.streams[0].max_framerate;
+  assert(streams[0].max_framerate > 0);
+  video_codec.maxFramerate = streams[0].max_framerate;
 
   if (codec_->SetSendCodec(channel_, video_codec) != 0)
     return false;
@@ -396,9 +381,6 @@
                             static_cast<unsigned char>(i));
   }
 
-  config_.encoder_settings.streams = streams;
-  config_.encoder_settings.encoder_settings = encoder_settings;
-
   if (config_.rtp.rtx.ssrcs.empty())
     return true;
 
diff --git a/webrtc/video/video_send_stream.h b/webrtc/video/video_send_stream.h
index a7e2267..125c7fd 100644
--- a/webrtc/video/video_send_stream.h
+++ b/webrtc/video/video_send_stream.h
@@ -42,6 +42,8 @@
                   CpuOveruseObserver* overuse_observer,
                   webrtc::VideoEngine* video_engine,
                   const VideoSendStream::Config& config,
+                  const std::vector<VideoStream> video_streams,
+                  const void* encoder_settings,
                   int base_channel);
 
   virtual ~VideoSendStream();
@@ -50,7 +52,7 @@
   virtual void Stop() OVERRIDE;
 
   virtual bool ReconfigureVideoEncoder(const std::vector<VideoStream>& streams,
-                                       void* encoder_settings) OVERRIDE;
+                                       const void* encoder_settings) OVERRIDE;
 
   virtual Stats GetStats() const OVERRIDE;
 
@@ -70,8 +72,7 @@
  private:
   TransportAdapter transport_adapter_;
   EncodedFrameCallbackAdapter encoded_frame_proxy_;
-  scoped_ptr<CriticalSectionWrapper> codec_lock_;
-  VideoSendStream::Config config_;
+  const VideoSendStream::Config config_;
 
   ViEBase* video_engine_base_;
   ViECapture* capture_;
diff --git a/webrtc/video/video_send_stream_tests.cc b/webrtc/video/video_send_stream_tests.cc
index 6662866..db71f54 100644
--- a/webrtc/video/video_send_stream_tests.cc
+++ b/webrtc/video/video_send_stream_tests.cc
@@ -45,9 +45,9 @@
 
  protected:
   void RunSendTest(Call* call,
-                   const VideoSendStream::Config& config,
                    test::RtpRtcpObserver* observer) {
-    send_stream_ = call->CreateVideoSendStream(config);
+    send_stream_ =
+        call->CreateVideoSendStream(send_config_, video_streams_, NULL);
     scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer(
         test::FrameGeneratorCapturer::Create(
             send_stream_->Input(), 320, 240, 30, Clock::GetRealTimeClock()));
@@ -62,17 +62,16 @@
     call->DestroyVideoSendStream(send_stream_);
   }
 
-  VideoSendStream::Config GetSendTestConfig(Call* call, size_t num_streams) {
+  void CreateTestConfig(Call* call, size_t num_streams) {
     assert(num_streams <= kNumSendSsrcs);
-    VideoSendStream::Config config = call->GetDefaultSendConfig();
-    config.encoder_settings = test::CreateEncoderSettings(
-        &fake_encoder_, "FAKE", kFakeSendPayloadType, num_streams);
-    config.encoder_settings.encoder = &fake_encoder_;
-    config.encoder_settings.payload_type = kFakeSendPayloadType;
+    send_config_ = call->GetDefaultSendConfig();
+    send_config_.encoder_settings.encoder = &fake_encoder_;
+    send_config_.encoder_settings.payload_name = "FAKE";
+    send_config_.encoder_settings.payload_type = kFakeSendPayloadType;
+    video_streams_ = test::CreateVideoStreams(num_streams);
+    send_config_.encoder_settings.payload_type = kFakeSendPayloadType;
     for (size_t i = 0; i < num_streams; ++i)
-      config.rtp.ssrcs.push_back(kSendSsrcs[i]);
-    config.pacing = true;
-    return config;
+      send_config_.rtp.ssrcs.push_back(kSendSsrcs[i]);
   }
 
   void TestNackRetransmission(uint32_t retransmit_ssrc,
@@ -91,6 +90,8 @@
   static const uint32_t kSendRtxSsrc;
   static const uint32_t kSendSsrcs[kNumSendSsrcs];
 
+  VideoSendStream::Config send_config_;
+  std::vector<VideoStream> video_streams_;
   VideoSendStream* send_stream_;
   test::FakeEncoder fake_encoder_;
 };
@@ -158,24 +159,23 @@
   Call::Config call_config(observer.SendTransport());
   scoped_ptr<Call> call(Call::Create(call_config));
 
-  VideoSendStream::Config send_config =
-      GetSendTestConfig(call.get(), num_ssrcs);
+  CreateTestConfig(call.get(), num_ssrcs);
 
   if (num_ssrcs > 1) {
     // Set low simulcast bitrates to not have to wait for bandwidth ramp-up.
-    std::vector<VideoStream>* streams = &send_config.encoder_settings.streams;
-    for (size_t i = 0; i < streams->size(); ++i) {
-      (*streams)[i].min_bitrate_bps = 10000;
-      (*streams)[i].target_bitrate_bps = 10000;
-      (*streams)[i].max_bitrate_bps = 10000;
+    for (size_t i = 0; i < video_streams_.size(); ++i) {
+      video_streams_[i].min_bitrate_bps = 10000;
+      video_streams_[i].target_bitrate_bps = 10000;
+      video_streams_[i].max_bitrate_bps = 10000;
     }
   }
 
-  std::vector<VideoStream> all_streams = send_config.encoder_settings.streams;
+  std::vector<VideoStream> all_streams = video_streams_;
   if (send_single_ssrc_first)
-    send_config.encoder_settings.streams.resize(1);
+    video_streams_.resize(1);
 
-  send_stream_ = call->CreateVideoSendStream(send_config);
+  send_stream_ =
+      call->CreateVideoSendStream(send_config_, video_streams_, NULL);
   scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer(
       test::FrameGeneratorCapturer::Create(
           send_stream_->Input(), 320, 240, 30, Clock::GetRealTimeClock()));
@@ -204,8 +204,9 @@
   Call::Config call_config(&transport);
   scoped_ptr<Call> call(Call::Create(call_config));
 
-  VideoSendStream::Config config = GetSendTestConfig(call.get(), 1);
-  VideoSendStream* stream = call->CreateVideoSendStream(config);
+  CreateTestConfig(call.get(), 1);
+  VideoSendStream* stream =
+      call->CreateVideoSendStream(send_config_, video_streams_, NULL);
   stream->Start();
   stream->Start();
   call->DestroyVideoSendStream(stream);
@@ -216,8 +217,9 @@
   Call::Config call_config(&transport);
   scoped_ptr<Call> call(Call::Create(call_config));
 
-  VideoSendStream::Config config = GetSendTestConfig(call.get(), 1);
-  VideoSendStream* stream = call->CreateVideoSendStream(config);
+  CreateTestConfig(call.get(), 1);
+  VideoSendStream* stream =
+      call->CreateVideoSendStream(send_config_, video_streams_, NULL);
   stream->Stop();
   stream->Stop();
   call->DestroyVideoSendStream(stream);
@@ -260,10 +262,10 @@
   Call::Config call_config(observer.SendTransport());
   scoped_ptr<Call> call(Call::Create(call_config));
 
-  VideoSendStream::Config send_config = GetSendTestConfig(call.get(), 1);
-  send_config.rtp.c_name = kCName;
+  CreateTestConfig(call.get(), 1);
+  send_config_.rtp.c_name = kCName;
 
-  RunSendTest(call.get(), send_config, &observer);
+  RunSendTest(call.get(), &observer);
 }
 
 TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) {
@@ -292,11 +294,11 @@
   Call::Config call_config(observer.SendTransport());
   scoped_ptr<Call> call(Call::Create(call_config));
 
-  VideoSendStream::Config send_config = GetSendTestConfig(call.get(), 1);
-  send_config.rtp.extensions.push_back(
+  CreateTestConfig(call.get(), 1);
+  send_config_.rtp.extensions.push_back(
       RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeExtensionId));
 
-  RunSendTest(call.get(), send_config, &observer);
+  RunSendTest(call.get(), &observer);
 }
 
 TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
@@ -339,12 +341,12 @@
   Call::Config call_config(observer.SendTransport());
   scoped_ptr<Call> call(Call::Create(call_config));
 
-  VideoSendStream::Config send_config = GetSendTestConfig(call.get(), 1);
-  send_config.encoder_settings.encoder = &encoder;
-  send_config.rtp.extensions.push_back(
+  CreateTestConfig(call.get(), 1);
+  send_config_.encoder_settings.encoder = &encoder;
+  send_config_.rtp.extensions.push_back(
       RtpExtension(RtpExtension::kTOffset, kTOffsetExtensionId));
 
-  RunSendTest(call.get(), send_config, &observer);
+  RunSendTest(call.get(), &observer);
 }
 
 class FakeReceiveStatistics : public NullReceiveStatistics {
@@ -413,8 +415,9 @@
   Call::Config call_config(&transport);
   scoped_ptr<Call> call(Call::Create(call_config));
 
-  VideoSendStream::Config send_config = GetSendTestConfig(call.get(), 1);
-  VideoSendStream* video_send_stream = call->CreateVideoSendStream(send_config);
+  CreateTestConfig(call.get(), 1);
+  VideoSendStream* video_send_stream =
+      call->CreateVideoSendStream(send_config_, video_streams_, NULL);
   video_send_stream->Start();
 
   I420VideoFrame frame;
@@ -492,11 +495,11 @@
 
   observer.SetReceivers(call->Receiver(), NULL);
 
-  VideoSendStream::Config send_config = GetSendTestConfig(call.get(), 1);
-  send_config.rtp.fec.red_payload_type = kRedPayloadType;
-  send_config.rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
+  CreateTestConfig(call.get(), 1);
+  send_config_.rtp.fec.red_payload_type = kRedPayloadType;
+  send_config_.rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
 
-  RunSendTest(call.get(), send_config, &observer);
+  RunSendTest(call.get(), &observer);
 }
 
 void VideoSendStreamTest::TestNackRetransmission(
@@ -568,14 +571,14 @@
   scoped_ptr<Call> call(Call::Create(call_config));
   observer.SetReceivers(call->Receiver(), NULL);
 
-  VideoSendStream::Config send_config = GetSendTestConfig(call.get(), 1);
-  send_config.rtp.nack.rtp_history_ms = 1000;
-  send_config.rtp.rtx.payload_type = retransmit_payload_type;
-  send_config.pacing = enable_pacing;
+  CreateTestConfig(call.get(), 1);
+  send_config_.rtp.nack.rtp_history_ms = 1000;
+  send_config_.rtp.rtx.payload_type = retransmit_payload_type;
+  send_config_.pacing = enable_pacing;
   if (retransmit_ssrc != kSendSsrc)
-    send_config.rtp.rtx.ssrcs.push_back(retransmit_ssrc);
+    send_config_.rtp.rtx.ssrcs.push_back(retransmit_ssrc);
 
-  RunSendTest(call.get(), send_config, &observer);
+  RunSendTest(call.get(), &observer);
 }
 
 TEST_F(VideoSendStreamTest, RetransmitsNack) {
@@ -762,27 +765,27 @@
 
   observer.SetReceivers(call->Receiver(), NULL);
 
-  VideoSendStream::Config send_config = GetSendTestConfig(call.get(), 1);
+  CreateTestConfig(call.get(), 1);
   if (with_fec) {
-    send_config.rtp.fec.red_payload_type = kRedPayloadType;
-    send_config.rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
+    send_config_.rtp.fec.red_payload_type = kRedPayloadType;
+    send_config_.rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
   }
 
   if (format == kVP8)
-    send_config.encoder_settings.payload_name = "VP8";
+    send_config_.encoder_settings.payload_name = "VP8";
 
-  send_config.pacing = false;
-  send_config.encoder_settings.encoder = &encoder;
-  send_config.rtp.max_packet_size = kMaxPacketSize;
-  send_config.post_encode_callback = &observer;
+  send_config_.pacing = false;
+  send_config_.encoder_settings.encoder = &encoder;
+  send_config_.rtp.max_packet_size = kMaxPacketSize;
+  send_config_.post_encode_callback = &observer;
 
   // Add an extension header, to make the RTP header larger than the base
   // length of 12 bytes.
   static const uint8_t kAbsSendTimeExtensionId = 13;
-  send_config.rtp.extensions.push_back(
+  send_config_.rtp.extensions.push_back(
       RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeExtensionId));
 
-  RunSendTest(call.get(), send_config, &observer);
+  RunSendTest(call.get(), &observer);
 }
 
 // TODO(sprang): Is there any way of speeding up these tests?
@@ -948,18 +951,19 @@
   scoped_ptr<Call> call(Call::Create(call_config));
   observer.SetReceiver(call->Receiver());
 
-  VideoSendStream::Config send_config = GetSendTestConfig(call.get(), 1);
-  send_config.rtp.nack.rtp_history_ms = 1000;
-  send_config.pre_encode_callback = &observer;
-  send_config.suspend_below_min_bitrate = true;
-  int min_bitrate_bps = send_config.encoder_settings.streams[0].min_bitrate_bps;
+  CreateTestConfig(call.get(), 1);
+  send_config_.rtp.nack.rtp_history_ms = 1000;
+  send_config_.pre_encode_callback = &observer;
+  send_config_.suspend_below_min_bitrate = true;
+  send_config_.pacing = true;
+  int min_bitrate_bps = video_streams_[0].min_bitrate_bps;
   observer.set_low_remb_bps(min_bitrate_bps - 10000);
   int threshold_window = std::max(min_bitrate_bps / 10, 10000);
-  ASSERT_GT(send_config.encoder_settings.streams[0].max_bitrate_bps,
+  ASSERT_GT(video_streams_[0].max_bitrate_bps,
             min_bitrate_bps + threshold_window + 5000);
   observer.set_high_remb_bps(min_bitrate_bps + threshold_window + 5000);
 
-  RunSendTest(call.get(), send_config, &observer);
+  RunSendTest(call.get(), &observer);
   observer.Stop();
 }
 
@@ -1022,9 +1026,10 @@
   scoped_ptr<Call> call(Call::Create(call_config));
   observer.SetReceivers(call->Receiver(), call->Receiver());
 
-  VideoSendStream::Config send_config = GetSendTestConfig(call.get(), 3);
+  CreateTestConfig(call.get(), 3);
 
-  send_stream_ = call->CreateVideoSendStream(send_config);
+  send_stream_ =
+      call->CreateVideoSendStream(send_config_, video_streams_, NULL);
   scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer(
       test::FrameGeneratorCapturer::Create(
           send_stream_->Input(), 320, 240, 30, Clock::GetRealTimeClock()));
@@ -1107,11 +1112,13 @@
   Call::Config call_config(observer.SendTransport());
   scoped_ptr<Call> call(Call::Create(call_config));
 
-  VideoSendStream::Config send_config = GetSendTestConfig(call.get(), 1);
-  send_config.rtp.c_name = kCName;
-  observer.SetConfig(send_config);
+  CreateTestConfig(call.get(), 1);
+  send_config_.rtp.c_name = kCName;
+  send_config_.pacing = true;
+  observer.SetConfig(send_config_);
 
-  send_stream_ = call->CreateVideoSendStream(send_config);
+  send_stream_ =
+      call->CreateVideoSendStream(send_config_, video_streams_, NULL);
   observer.SetSendStream(send_stream_);
   scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer(
       test::FrameGeneratorCapturer::Create(
@@ -1202,9 +1209,10 @@
   scoped_ptr<Call> call(Call::Create(call_config));
   observer.SetReceivers(&observer, call->Receiver());
 
-  VideoSendStream::Config send_config = GetSendTestConfig(call.get(), 1);
-  send_config.rtp.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
-  send_stream_ = call->CreateVideoSendStream(send_config);
+  CreateTestConfig(call.get(), 1);
+  send_config_.rtp.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
+  send_stream_ =
+      call->CreateVideoSendStream(send_config_, video_streams_, NULL);
   observer.SetSendStream(send_stream_);
 
   scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer(
diff --git a/webrtc/video_send_stream.h b/webrtc/video_send_stream.h
index e173e3b..b33f389 100644
--- a/webrtc/video_send_stream.h
+++ b/webrtc/video_send_stream.h
@@ -66,8 +66,7 @@
     std::string ToString() const;
 
     struct EncoderSettings {
-      EncoderSettings()
-          : payload_type(-1), encoder(NULL), encoder_settings(NULL) {}
+      EncoderSettings() : payload_type(-1), encoder(NULL) {}
       std::string ToString() const;
 
       std::string payload_name;
@@ -76,13 +75,6 @@
       // Uninitialized VideoEncoder instance to be used for encoding. Will be
       // initialized from inside the VideoSendStream.
       webrtc::VideoEncoder* encoder;
-      // TODO(pbos): Wire up encoder-specific settings.
-      // Encoder-specific settings, will be passed to the encoder during
-      // initialization.
-      void* encoder_settings;
-
-      // List of stream settings to encode (resolution, bitrates, framerate).
-      std::vector<VideoStream> streams;
     } encoder_settings;
 
     static const size_t kDefaultMaxPacketSize = 1500 - 40;  // TCP over IPv4.
@@ -155,8 +147,7 @@
     // True if the stream should be suspended when the available bitrate fall
     // below the minimum configured bitrate. If this variable is false, the
     // stream may send at a rate higher than the estimated available bitrate.
-    // Enabling suspend_below_min_bitrate will also enable pacing and padding,
-    // otherwise, the video will be unable to recover from suspension.
+    // |suspend_below_min_bitrate| requires |pacing| to be enabled as well.
     bool suspend_below_min_bitrate;
   };
 
@@ -171,7 +162,7 @@
   // in the config. Encoder settings are passed on to the encoder instance along
   // with the VideoStream settings.
   virtual bool ReconfigureVideoEncoder(const std::vector<VideoStream>& streams,
-                                       void* encoder_settings) = 0;
+                                       const void* encoder_settings) = 0;
 
   virtual Stats GetStats() const = 0;