(Auto)update libjingle 81063831-> 81073932

git-svn-id: http://webrtc.googlecode.com/svn/trunk@7774 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/talk/media/webrtc/webrtcvideoengine.cc b/talk/media/webrtc/webrtcvideoengine.cc
index 3bcec4d..0926b07 100644
--- a/talk/media/webrtc/webrtcvideoengine.cc
+++ b/talk/media/webrtc/webrtcvideoengine.cc
@@ -3216,6 +3216,10 @@
   if (!send_channel) {
     return false;
   }
+
+  bool changed;
+  send_channel->SetLastCapturedFrameInfo(frame, is_screencast, &changed);
+
   if (!send_codec_) {
     // Send codec has not been set. No reason to process the frame any further.
     return false;
@@ -3229,8 +3233,6 @@
     return true;
   }
 
-  bool changed;
-  send_channel->SetLastCapturedFrameInfo(frame, is_screencast, &changed);
   if (changed) {
     // If the last captured frame info changed, then calling
     // SetSendParams will update to the latest resolution.
@@ -3877,20 +3879,32 @@
   MaybeRegisterExternalEncoder(send_channel, send_params.codec);
 
   CapturedFrameInfo frame;
-  send_channel->last_captured_frame_info().Get(&frame);
+  if (!send_channel->last_captured_frame_info().Get(&frame)) {
+    // When we don't have a frame yet, configure the encoder with a
+    // 2x2 frame (the smallest possible I420 frame).  This gives us
+    // low memory usage but also makes it so configuration errors are
+    // discovered at the time we apply the settings rather than when
+    // we get the first frame (waiting for the first frame to know
+    // that you gave a bad codec parameter could make debugging hard).
+    frame.width = 2;
+    frame.height = 2;
+
+    // TODO(pthatcher): Evaluate the risk of not setting up an encoder
+    // at all until we have a frame.  Once we feel it's worth the
+    // risk, we can do something like this:
+    // send_channel->set_send_params(send_params);
+    // return true;
+  }
 
   // TODO(pthatcher): This checking of the max height and width is
   // only needed because some unit tests bypass the VideoAdapter, and
   // others expect behavior from the adapter different than what it
   // actually does.  We should fix the tests and remove this block.
   VideoFormat max = send_channel->adapt_format();
-  size_t max_width = static_cast<size_t>(max.width);
-  size_t max_height = static_cast<size_t>(max.height);
-  if (!send_channel->last_captured_frame_info().IsSet() ||
-      (!frame.screencast &&
-       (frame.width > max_width || frame.height > max_height))) {
-    frame.width = max_width;
-    frame.height = max_height;
+  if ((!frame.screencast &&
+       (frame.width > max.width || frame.height > max.height))) {
+    frame.width = max.width;
+    frame.height = max.height;
   }
 
   webrtc::VideoCodec codec;
diff --git a/talk/media/webrtc/webrtcvideoengine_unittest.cc b/talk/media/webrtc/webrtcvideoengine_unittest.cc
index 00d6e4b..5dcba8e 100644
--- a/talk/media/webrtc/webrtcvideoengine_unittest.cc
+++ b/talk/media/webrtc/webrtcvideoengine_unittest.cc
@@ -371,6 +371,7 @@
   EXPECT_TRUE(SetupEngine());
   int channel_num = vie_.GetLastChannel();
   std::vector<cricket::VideoCodec> codecs(engine_.codecs());
+  SendI420Frame(kVP8Codec.width, kVP8Codec.height);
   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
   VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height);
   EXPECT_TRUE(vie_.GetHybridNackFecStatus(channel_num));
@@ -379,12 +380,21 @@
   // TODO(juberti): Check RTCP, PLI, TMMBR.
 }
 
+TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsBeforeFrameRegistersTinyFormat) {
+  EXPECT_TRUE(SetupEngine());
+  int channel_num = vie_.GetLastChannel();
+  std::vector<cricket::VideoCodec> codecs(engine_.codecs());
+  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
+  VerifyVP8SendCodec(channel_num, 2, 2);
+}
+
 // Test that ViE Channel doesn't call SetSendCodec again if same codec is tried
 // to apply.
 TEST_F(WebRtcVideoEngineTestFake, DontResetSetSendCodec) {
   EXPECT_TRUE(SetupEngine());
   int channel_num = vie_.GetLastChannel();
   std::vector<cricket::VideoCodec> codecs(engine_.codecs());
+  SendI420Frame(kVP8Codec.width, kVP8Codec.height);
   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
   VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height);
   EXPECT_TRUE(vie_.GetHybridNackFecStatus(channel_num));
@@ -403,6 +413,7 @@
   std::vector<cricket::VideoCodec> codecs(engine_.codecs());
   codecs[0].params[cricket::kCodecParamMinBitrate] = "10";
   codecs[0].params[cricket::kCodecParamMaxBitrate] = "20";
+  SendI420Frame(kVP8Codec.width, kVP8Codec.height);
   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
   VerifyVP8SendCodec(
@@ -419,6 +430,7 @@
   int channel_num = vie_.GetLastChannel();
   std::vector<cricket::VideoCodec> codecs(engine_.codecs());
   codecs[0].params[cricket::kCodecParamStartBitrate] = "450";
+  SendI420Frame(kVP8Codec.width, kVP8Codec.height);
   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
   VerifyVP8SendCodec(channel_num,
@@ -441,6 +453,7 @@
   codecs[0].params[cricket::kCodecParamMinBitrate] = "10";
   codecs[0].params[cricket::kCodecParamMaxBitrate] = "20";
   codecs[0].params[cricket::kCodecParamStartBitrate] = "14";
+  SendI420Frame(kVP8Codec.width, kVP8Codec.height);
   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
   VerifyVP8SendCodec(
@@ -458,6 +471,7 @@
   std::vector<cricket::VideoCodec> codecs(engine_.codecs());
   codecs[0].params[cricket::kCodecParamMinBitrate] = "30";
   codecs[0].params[cricket::kCodecParamMaxBitrate] = "20";
+  SendI420Frame(kVP8Codec.width, kVP8Codec.height);
   EXPECT_FALSE(channel_->SetSendCodecs(codecs));
 }
 
@@ -467,6 +481,7 @@
   std::vector<cricket::VideoCodec> codecs(engine_.codecs());
   codecs[0].params[cricket::kCodecParamMinBitrate] = "1000";
   codecs[0].params[cricket::kCodecParamMaxBitrate] = "3000";
+  SendI420Frame(kVP8Codec.width, kVP8Codec.height);
   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
   VerifyVP8SendCodec(
@@ -479,6 +494,7 @@
   int channel_num = vie_.GetLastChannel();
   std::vector<cricket::VideoCodec> codecs(engine_.codecs());
   codecs[0].params[cricket::kCodecParamMaxQuantization] = "21";
+  SendI420Frame(kVP8Codec.width, kVP8Codec.height);
   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
   VerifyVP8SendCodec(channel_num,
@@ -502,6 +518,7 @@
   std::vector<cricket::VideoCodec> codecs(engine_.codecs());
   codecs[0].params[cricket::kCodecParamMinBitrate] = "10";
   codecs[0].params[cricket::kCodecParamMaxBitrate] = "20";
+  SendI420Frame(kVP8Codec.width, kVP8Codec.height);
   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
   VerifyVP8SendCodec(
@@ -527,6 +544,7 @@
   std::vector<cricket::VideoCodec> codecs(engine_.codecs());
   codecs[0].params[cricket::kCodecParamMinBitrate] = "10";
   codecs[0].params[cricket::kCodecParamMaxBitrate] = "20";
+  SendI420Frame(kVP8Codec.width, kVP8Codec.height);
   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
   VerifyVP8SendCodec(
@@ -552,6 +570,7 @@
   cricket::VideoCodec codec(kVP8Codec);
   std::vector<cricket::VideoCodec> codec_list;
   codec_list.push_back(codec);
+  SendI420Frame(kVP8Codec.width, kVP8Codec.height);
   EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
   VerifyVP8SendCodec(send_channel, kVP8Codec.width, kVP8Codec.height, 0,
                      kMaxBandwidthKbps, kMinBandwidthKbps,
@@ -601,6 +620,7 @@
   codec_list.push_back(codec);
 
   // Set send codec and verify codec has been constrained.
+  SendI420Frame(kVP8Codec.width, kVP8Codec.height);
   EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
   VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height);
 }
@@ -617,6 +637,7 @@
   codec_list.push_back(codec);
 
   // Verify SetSendCodecs failed and send codec is not changed on engine.
+  SendI420Frame(kVP8Codec.width, kVP8Codec.height);
   EXPECT_FALSE(channel_->SetSendCodecs(codec_list));
   webrtc::VideoCodec gcodec;
   // Set plType to something other than the value to test against ensuring
@@ -650,6 +671,7 @@
   codec_list.push_back(codec);
 
   // Verify SetSendCodecs failed and send codec is not changed on engine.
+  SendI420Frame(kVP8Codec.width, kVP8Codec.height);
   EXPECT_FALSE(channel_->SetSendCodecs(codec_list));
   webrtc::VideoCodec gcodec;
   // Set plType to something other than the value to test against ensuring
@@ -667,6 +689,7 @@
   // Set send codec.
   std::vector<cricket::VideoCodec> codec_list;
   codec_list.push_back(kVP8Codec);
+  SendI420Frame(kVP8Codec.width, kVP8Codec.height);
   EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
   EXPECT_TRUE(channel_->AddSendStream(
       cricket::StreamParams::CreateLegacy(123)));
@@ -1019,6 +1042,7 @@
 TEST_F(WebRtcVideoEngineTestFake, AdditiveVideoOptions) {
   EXPECT_TRUE(SetupEngine());
   EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1)));
+  SendI420Frame(kVP8Codec.width, kVP8Codec.height);
   channel_->SetSendCodecs(engine_.codecs());
 
   int first_send_channel = vie_.GetLastChannel();
@@ -1428,6 +1452,7 @@
 TEST_F(WebRtcVideoEngineTestFake, SetBandwidthAuto) {
   EXPECT_TRUE(SetupEngine());
   int channel_num = vie_.GetLastChannel();
+  SendI420Frame(kVP8Codec.width, kVP8Codec.height);
   EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
   EXPECT_TRUE(channel_->SetMaxSendBandwidth(cricket::kAutoBandwidth));
   VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height);
@@ -1437,6 +1462,7 @@
 TEST_F(WebRtcVideoEngineTestFake, SetBandwidthCapped) {
   EXPECT_TRUE(SetupEngine());
   int channel_num = vie_.GetLastChannel();
+  SendI420Frame(kVP8Codec.width, kVP8Codec.height);
   EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
   EXPECT_TRUE(channel_->SetMaxSendBandwidth(768000));
   VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height, 0, 768U);
@@ -1447,6 +1473,7 @@
 TEST_F(WebRtcVideoEngineTestFake, SetMaxBandwidthBelowDefaultStart) {
   EXPECT_TRUE(SetupEngine());
   int channel_num = vie_.GetLastChannel();
+  SendI420Frame(kVP8Codec.width, kVP8Codec.height);
   EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
   int max_bandwidth_kbps = (kMinBandwidthKbps + kStartBandwidthKbps) / 2;
   EXPECT_TRUE(channel_->SetMaxSendBandwidth(max_bandwidth_kbps * 1000));
@@ -1459,6 +1486,7 @@
 TEST_F(WebRtcVideoEngineTestFake, SetMaxBandwidthBelowMin) {
   EXPECT_TRUE(SetupEngine());
   int channel_num = vie_.GetLastChannel();
+  SendI420Frame(kVP8Codec.width, kVP8Codec.height);
   EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
   int max_bandwidth_kbps = kMinBandwidthKbps / 2;
   EXPECT_TRUE(channel_->SetMaxSendBandwidth(max_bandwidth_kbps * 1000));
@@ -1471,6 +1499,7 @@
   EXPECT_TRUE(SetupEngine());
   int channel_num = vie_.GetLastChannel();
   EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
+  SendI420Frame(kVP8Codec.width, kVP8Codec.height);
   VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height, 0,
       kMaxBandwidthKbps, kMinBandwidthKbps, kStartBandwidthKbps);
 
@@ -1493,6 +1522,7 @@
   cricket::VideoOptions options;
   options.conference_mode.Set(true);
   EXPECT_TRUE(channel_->SetOptions(options));
+  SendI420Frame(kVP8Codec.width, kVP8Codec.height);
   EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
   VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height);