Adding REMB to receive stream configuration, the send side will always
react to incoming REMB for now.

Adding a test to verify the receive side is generating RTCP REMB and
will follow up with a send side test as soon as the bitrate stats are
wired up for the new API.

TEST=See above.
R=pbos@webrtc.org

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk/webrtc@5286 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/video/call.cc b/video/call.cc
index 69e8f84..12daa8e 100644
--- a/video/call.cc
+++ b/video/call.cc
@@ -277,7 +277,9 @@
 }
 
 VideoReceiveStream::Config Call::GetDefaultReceiveConfig() {
-  return VideoReceiveStream::Config();
+  VideoReceiveStream::Config config;
+  config.rtp.remb = true;
+  return config;
 }
 
 VideoReceiveStream* Call::CreateVideoReceiveStream(
diff --git a/video/call_tests.cc b/video/call_tests.cc
index 34931d1..96ad832 100644
--- a/video/call_tests.cc
+++ b/video/call_tests.cc
@@ -936,4 +936,53 @@
 
   DestroyStreams();
 }
+
+TEST_F(CallTest, ReceiveStreamSendsRemb) {
+  class RembObserver : public test::RtpRtcpObserver {
+   public:
+    RembObserver() : test::RtpRtcpObserver(kDefaultTimeoutMs) {}
+
+    virtual Action OnReceiveRtcp(const uint8_t* packet,
+                                 size_t length) OVERRIDE {
+      RTCPUtility::RTCPParserV2 parser(packet, length, true);
+      EXPECT_TRUE(parser.IsValid());
+
+      bool received_psfb = false;
+      bool received_remb = false;
+      RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
+      while (packet_type != RTCPUtility::kRtcpNotValidCode) {
+        if (packet_type == RTCPUtility::kRtcpPsfbRembCode) {
+          const RTCPUtility::RTCPPacket& packet = parser.Packet();
+          EXPECT_EQ(packet.PSFBAPP.SenderSSRC, kReceiverLocalSsrc);
+          received_psfb = true;
+        } else if (packet_type == RTCPUtility::kRtcpPsfbRembItemCode) {
+          const RTCPUtility::RTCPPacket& packet = parser.Packet();
+          EXPECT_GT(packet.REMBItem.BitRate, 0u);
+          EXPECT_EQ(packet.REMBItem.NumberOfSSRCs, 1u);
+          EXPECT_EQ(packet.REMBItem.SSRCs[0], kSendSsrc);
+          received_remb = true;
+        }
+        packet_type = parser.Iterate();
+      }
+      if (received_psfb && received_remb)
+        observation_complete_->Set();
+      return SEND_PACKET;
+    }
+  } observer;
+
+  CreateCalls(Call::Config(observer.SendTransport()),
+              Call::Config(observer.ReceiveTransport()));
+  observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());
+  CreateTestConfigs();
+  CreateStreams();
+  CreateFrameGenerator();
+  StartSending();
+
+  EXPECT_EQ(kEventSignaled, observer.Wait())
+      << "Timed out while waiting for a receiver RTCP REMB packet to be sent.";
+
+  StopSending();
+  observer.StopSending();
+  DestroyStreams();
+}
 }  // namespace webrtc
diff --git a/video/video_receive_stream.cc b/video/video_receive_stream.cc
index 27dafc9..31c8524 100644
--- a/video/video_receive_stream.cc
+++ b/video/video_receive_stream.cc
@@ -61,6 +61,7 @@
   assert(config_.rtp.remote_ssrc != config_.rtp.local_ssrc);
 
   rtp_rtcp_->SetLocalSSRC(channel_, config_.rtp.local_ssrc);
+  rtp_rtcp_->SetRembStatus(channel_, false, config_.rtp.remb);
 
   network_ = ViENetwork::GetInterface(video_engine);
   assert(network_ != NULL);
diff --git a/video/video_send_stream.cc b/video/video_send_stream.cc
index df03b13..713cdb9 100644
--- a/video/video_send_stream.cc
+++ b/video/video_send_stream.cc
@@ -115,6 +115,8 @@
     }
   }
 
+  rtp_rtcp_->SetRembStatus(channel_, true, false);
+
   // Enable NACK, FEC or both.
   if (config_.rtp.fec.red_payload_type != -1) {
     assert(config_.rtp.fec.ulpfec_payload_type != -1);
diff --git a/video_receive_stream.h b/video_receive_stream.h
index e5a6829..e548728 100644
--- a/video_receive_stream.h
+++ b/video_receive_stream.h
@@ -108,7 +108,8 @@
       Rtp()
           : remote_ssrc(0),
             local_ssrc(0),
-            rtcp_mode(newapi::kRtcpReducedSize) {}
+            rtcp_mode(newapi::kRtcpReducedSize),
+            remb(false) {}
 
       // Synchronization source (stream identifier) to be received.
       uint32_t remote_ssrc;
@@ -118,6 +119,9 @@
       // See RtcpMode for description.
       newapi::RtcpMode rtcp_mode;
 
+      // See draft-alvestrand-rmcat-remb for information.
+      bool remb;
+
       // See NackConfig for description.
       NackConfig nack;