Implement RTX tests+fixes in WebRtcVideoEngine2.

BUG=1788
R=pthatcher@webrtc.org

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk/talk@6430 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/media/webrtc/webrtcvideoengine2_unittest.cc b/media/webrtc/webrtcvideoengine2_unittest.cc
index 4d40ac4..4dd27bc 100644
--- a/media/webrtc/webrtcvideoengine2_unittest.cc
+++ b/media/webrtc/webrtcvideoengine2_unittest.cc
@@ -328,6 +328,62 @@
       << "Different VoiceChannel set than the provided one.";
 }
 
+TEST_F(WebRtcVideoEngine2Test, FindCodec) {
+  const std::vector<cricket::VideoCodec>& c = engine_.codecs();
+  EXPECT_EQ(4U, c.size());
+
+  cricket::VideoCodec vp8(104, "VP8", 320, 200, 30, 0);
+  EXPECT_TRUE(engine_.FindCodec(vp8));
+
+  cricket::VideoCodec vp8_ci(104, "vp8", 320, 200, 30, 0);
+  EXPECT_TRUE(engine_.FindCodec(vp8));
+
+  cricket::VideoCodec vp8_diff_fr_diff_pref(104, "VP8", 320, 200, 50, 50);
+  EXPECT_TRUE(engine_.FindCodec(vp8_diff_fr_diff_pref));
+
+  cricket::VideoCodec vp8_diff_id(95, "VP8", 320, 200, 30, 0);
+  EXPECT_FALSE(engine_.FindCodec(vp8_diff_id));
+  vp8_diff_id.id = 97;
+  EXPECT_TRUE(engine_.FindCodec(vp8_diff_id));
+
+  cricket::VideoCodec vp8_diff_res(104, "VP8", 320, 111, 30, 0);
+  EXPECT_FALSE(engine_.FindCodec(vp8_diff_res));
+
+  // PeerConnection doesn't negotiate the resolution at this point.
+  // Test that FindCodec can handle the case when width/height is 0.
+  cricket::VideoCodec vp8_zero_res(104, "VP8", 0, 0, 30, 0);
+  EXPECT_TRUE(engine_.FindCodec(vp8_zero_res));
+
+  cricket::VideoCodec red(101, "RED", 0, 0, 30, 0);
+  EXPECT_TRUE(engine_.FindCodec(red));
+
+  cricket::VideoCodec red_ci(101, "red", 0, 0, 30, 0);
+  EXPECT_TRUE(engine_.FindCodec(red));
+
+  cricket::VideoCodec fec(102, "ULPFEC", 0, 0, 30, 0);
+  EXPECT_TRUE(engine_.FindCodec(fec));
+
+  cricket::VideoCodec fec_ci(102, "ulpfec", 0, 0, 30, 0);
+  EXPECT_TRUE(engine_.FindCodec(fec));
+
+  cricket::VideoCodec rtx(96, "rtx", 0, 0, 30, 0);
+  EXPECT_TRUE(engine_.FindCodec(rtx));
+}
+
+TEST_F(WebRtcVideoEngine2Test, DefaultRtxCodecHasAssociatedPayloadTypeSet) {
+  std::vector<VideoCodec> engine_codecs = engine_.codecs();
+  for (size_t i = 0; i < engine_codecs.size(); ++i) {
+    if (engine_codecs[i].name != kRtxCodecName)
+      continue;
+    int associated_payload_type;
+    EXPECT_TRUE(engine_codecs[i].GetParam(kCodecParamAssociatedPayloadType,
+                                           &associated_payload_type));
+    EXPECT_EQ(default_codec_.id, associated_payload_type);
+    return;
+  }
+  FAIL() << "No RTX codec found among default codecs.";
+}
+
 class WebRtcVideoChannel2BaseTest
     : public VideoMediaChannelTest<WebRtcVideoEngine2, WebRtcVideoChannel2> {
  protected:
@@ -607,7 +663,7 @@
   FAIL() << "Not implemented.";  // TODO(pbos): Implement.
 }
 
-TEST_F(WebRtcVideoChannel2Test, RecvStreamWithRtx) {
+TEST_F(WebRtcVideoChannel2Test, RecvStreamWithSimAndRtx) {
   EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
   EXPECT_TRUE(channel_->SetSend(true));
   cricket::VideoOptions options;
@@ -636,12 +692,23 @@
   // TODO(pbos): Make sure we set the RTX for correct payloads etc.
 }
 
-TEST_F(WebRtcVideoChannel2Test, DISABLED_RecvStreamWithRtxOnMultiplePayloads) {
-  FAIL() << "Not implemented.";
+TEST_F(WebRtcVideoChannel2Test, RecvStreamWithRtx) {
+  // Setup one channel with an associated RTX stream.
+  cricket::StreamParams params =
+      cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
+  params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
+  FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
+  ASSERT_EQ(1u, recv_stream->GetConfig().rtp.rtx.size());
+  EXPECT_EQ(kRtxSsrcs1[0],
+            recv_stream->GetConfig().rtp.rtx.begin()->second.ssrc);
 }
 
-TEST_F(WebRtcVideoChannel2Test, DISABLED_RecvStreamNoRtx) {
-  FAIL() << "Not implemented.";  // TODO(pbos): Implement.
+TEST_F(WebRtcVideoChannel2Test, RecvStreamNoRtx) {
+  // Setup one channel without an associated RTX stream.
+  cricket::StreamParams params =
+      cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
+  FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
+  ASSERT_TRUE(recv_stream->GetConfig().rtp.rtx.empty());
 }
 
 TEST_F(WebRtcVideoChannel2Test, DISABLED_RtpTimestampOffsetHeaderExtensions) {
@@ -777,61 +844,6 @@
   FAIL() << "Not implemented.";  // TODO(pbos): Implement.
 }
 
-TEST_F(WebRtcVideoEngine2Test, FindCodec) {
-  const std::vector<cricket::VideoCodec>& c = engine_.codecs();
-  EXPECT_EQ(4U, c.size());
-
-  cricket::VideoCodec vp8(104, "VP8", 320, 200, 30, 0);
-  EXPECT_TRUE(engine_.FindCodec(vp8));
-
-  cricket::VideoCodec vp8_ci(104, "vp8", 320, 200, 30, 0);
-  EXPECT_TRUE(engine_.FindCodec(vp8));
-
-  cricket::VideoCodec vp8_diff_fr_diff_pref(104, "VP8", 320, 200, 50, 50);
-  EXPECT_TRUE(engine_.FindCodec(vp8_diff_fr_diff_pref));
-
-  cricket::VideoCodec vp8_diff_id(95, "VP8", 320, 200, 30, 0);
-  EXPECT_FALSE(engine_.FindCodec(vp8_diff_id));
-  vp8_diff_id.id = 97;
-  EXPECT_TRUE(engine_.FindCodec(vp8_diff_id));
-
-  cricket::VideoCodec vp8_diff_res(104, "VP8", 320, 111, 30, 0);
-  EXPECT_FALSE(engine_.FindCodec(vp8_diff_res));
-
-  // PeerConnection doesn't negotiate the resolution at this point.
-  // Test that FindCodec can handle the case when width/height is 0.
-  cricket::VideoCodec vp8_zero_res(104, "VP8", 0, 0, 30, 0);
-  EXPECT_TRUE(engine_.FindCodec(vp8_zero_res));
-
-  cricket::VideoCodec red(101, "RED", 0, 0, 30, 0);
-  EXPECT_TRUE(engine_.FindCodec(red));
-
-  cricket::VideoCodec red_ci(101, "red", 0, 0, 30, 0);
-  EXPECT_TRUE(engine_.FindCodec(red));
-
-  cricket::VideoCodec fec(102, "ULPFEC", 0, 0, 30, 0);
-  EXPECT_TRUE(engine_.FindCodec(fec));
-
-  cricket::VideoCodec fec_ci(102, "ulpfec", 0, 0, 30, 0);
-  EXPECT_TRUE(engine_.FindCodec(fec));
-
-  cricket::VideoCodec rtx(96, "rtx", 0, 0, 30, 0);
-  EXPECT_TRUE(engine_.FindCodec(rtx));
-}
-
-TEST_F(WebRtcVideoEngine2Test, DefaultRtxCodecHasAssociatedPayloadTypeSet) {
-  for (size_t i = 0; i < engine_.codecs().size(); ++i) {
-    if (engine_.codecs()[i].name != kRtxCodecName)
-      continue;
-    int associated_payload_type;
-    EXPECT_TRUE(engine_.codecs()[i].GetParam(kCodecParamAssociatedPayloadType,
-                                             &associated_payload_type));
-    EXPECT_EQ(default_codec_.id, associated_payload_type);
-    return;
-  }
-  FAIL() << "No RTX codec found among default codecs.";
-}
-
 TEST_F(WebRtcVideoChannel2Test, SetDefaultSendCodecs) {
   ASSERT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
 
@@ -975,6 +987,31 @@
   EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
 }
 
+// Test that we set our inbound RTX codecs properly.
+TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithRtx) {
+  std::vector<cricket::VideoCodec> codecs;
+  codecs.push_back(kVp8Codec);
+  cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0);
+  codecs.push_back(rtx_codec);
+  EXPECT_FALSE(channel_->SetRecvCodecs(codecs))
+      << "RTX codec without associated payload should be rejected.";
+
+  codecs[1].SetParam("apt", kVp8Codec.id + 1);
+  EXPECT_FALSE(channel_->SetRecvCodecs(codecs))
+      << "RTX codec with invalid associated payload type should be rejected.";
+
+  codecs[1].SetParam("apt", kVp8Codec.id);
+  EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
+
+  cricket::VideoCodec rtx_codec2(97, "rtx", 0, 0, 0, 0);
+  rtx_codec2.SetParam("apt", rtx_codec.id);
+  codecs.push_back(rtx_codec2);
+
+  EXPECT_FALSE(channel_->SetRecvCodecs(codecs)) << "RTX codec with another RTX "
+                                                   "as associated payload type "
+                                                   "should be rejected.";
+}
+
 TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsDifferentPayloadType) {
   std::vector<cricket::VideoCodec> codecs;
   codecs.push_back(kVp8Codec);