Set local SSRC for VideoReceiveStream.

As a bonus, also removes GenerateRandomSsrc, which only worked on sender
configs. There's no point to generate random SSRCs in tests.

BUG=2691
R=mflodman@webrtc.org, stefan@webrtc.org

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk/webrtc@5201 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/call.cc b/call.cc
index 9e23b24..5736947 100644
--- a/call.cc
+++ b/call.cc
@@ -260,8 +260,8 @@
       video_engine_, config, config_.send_transport, config_.voice_engine);
 
   WriteLockScoped write_lock(*receive_lock_);
-  assert(receive_ssrcs_.find(config.rtp.ssrc) == receive_ssrcs_.end());
-  receive_ssrcs_[config.rtp.ssrc] = receive_stream;
+  assert(receive_ssrcs_.find(config.rtp.remote_ssrc) == receive_ssrcs_.end());
+  receive_ssrcs_[config.rtp.remote_ssrc] = receive_stream;
   return receive_stream;
 }
 
diff --git a/call_tests.cc b/call_tests.cc
index 5393286..ec7d4cc 100644
--- a/call_tests.cc
+++ b/call_tests.cc
@@ -37,7 +37,6 @@
 #include "webrtc/test/fake_decoder.h"
 #include "webrtc/test/fake_encoder.h"
 #include "webrtc/test/frame_generator_capturer.h"
-#include "webrtc/test/generate_ssrcs.h"
 #include "webrtc/test/rtp_rtcp_observer.h"
 #include "webrtc/test/testsupport/perf_test.h"
 
@@ -45,6 +44,8 @@
 
 static unsigned int kDefaultTimeoutMs = 30 * 1000;
 static unsigned int kLongTimeoutMs = 120 * 1000;
+static const uint32_t kSendSsrc = 0x654321;
+static const uint32_t kReceiverLocalSsrc = 0x123456;
 static const uint8_t kSendPayloadType = 125;
 
 class CallTest : public ::testing::Test {
@@ -70,7 +71,7 @@
     send_config_ = sender_call_->GetDefaultSendConfig();
     receive_config_ = receiver_call_->GetDefaultReceiveConfig();
 
-    test::GenerateRandomSsrcs(&send_config_, &reserved_ssrcs_);
+    send_config_.rtp.ssrcs.push_back(kSendSsrc);
     send_config_.encoder = &fake_encoder_;
     send_config_.internal_source = false;
     test::FakeEncoder::SetCodecSettings(&send_config_.codec, 1);
@@ -82,7 +83,8 @@
     decoder.decoder = &fake_decoder_;
     decoder.payload_type = send_config_.codec.plType;
     receive_config_.external_decoders.push_back(decoder);
-    receive_config_.rtp.ssrc = send_config_.rtp.ssrcs[0];
+    receive_config_.rtp.remote_ssrc = send_config_.rtp.ssrcs[0];
+    receive_config_.rtp.local_ssrc = kReceiverLocalSsrc;
   }
 
   void CreateStreams() {
@@ -144,8 +146,6 @@
 
   test::FakeEncoder fake_encoder_;
   test::FakeDecoder fake_decoder_;
-
-  std::map<uint32_t, bool> reserved_ssrcs_;
 };
 
 class NackObserver : public test::RtpRtcpObserver {
@@ -349,6 +349,48 @@
   DestroyStreams();
 }
 
+TEST_F(CallTest, ReceiverUsesLocalSsrc) {
+  class SyncRtcpObserver : public test::RtpRtcpObserver {
+   public:
+    SyncRtcpObserver() : test::RtpRtcpObserver(kDefaultTimeoutMs) {}
+
+    virtual Action OnReceiveRtcp(const uint8_t* packet,
+                                 size_t length) OVERRIDE {
+      RTCPUtility::RTCPParserV2 parser(packet, length, true);
+      EXPECT_TRUE(parser.IsValid());
+      uint32_t ssrc = 0;
+      ssrc |= static_cast<uint32_t>(packet[4]) << 24;
+      ssrc |= static_cast<uint32_t>(packet[5]) << 16;
+      ssrc |= static_cast<uint32_t>(packet[6]) << 8;
+      ssrc |= static_cast<uint32_t>(packet[7]) << 0;
+      EXPECT_EQ(kReceiverLocalSsrc, ssrc);
+      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 packet to be sent.";
+
+  StopSending();
+
+  observer.StopSending();
+
+  DestroyStreams();
+}
+
 TEST_F(CallTest, ReceivesAndRetransmitsNack) {
   NackObserver observer;
 
@@ -787,7 +829,8 @@
     VideoReceiveStream::Config receive_config =
         receiver_call->GetDefaultReceiveConfig();
     receive_config.renderer = observers[i];
-    receive_config.rtp.ssrc = ssrc;
+    receive_config.rtp.remote_ssrc = ssrc;
+    receive_config.rtp.local_ssrc = kReceiverLocalSsrc;
     receive_streams[i] =
         receiver_call->CreateVideoReceiveStream(receive_config);
     receive_streams[i]->StartReceiving();
diff --git a/loopback.cc b/loopback.cc
index e07138a..dc5afce 100644
--- a/loopback.cc
+++ b/loopback.cc
@@ -19,7 +19,6 @@
 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
 #include "webrtc/test/direct_transport.h"
 #include "webrtc/test/flags.h"
-#include "webrtc/test/generate_ssrcs.h"
 #include "webrtc/test/run_loop.h"
 #include "webrtc/test/run_tests.h"
 #include "webrtc/test/video_capturer.h"
@@ -33,6 +32,9 @@
   std::map<uint32_t, bool> reserved_ssrcs_;
 };
 
+static const uint32_t kSendSsrc = 0x654321;
+static const uint32_t kReceiverLocalSsrc = 0x123456;
+
 TEST_F(LoopbackTest, Test) {
   scoped_ptr<test::VideoRenderer> local_preview(test::VideoRenderer::Create(
       "Local Preview", test::flags::Width(), test::flags::Height()));
@@ -48,7 +50,7 @@
   transport.SetReceiver(call->Receiver());
 
   VideoSendStream::Config send_config = call->GetDefaultSendConfig();
-  test::GenerateRandomSsrcs(&send_config, &reserved_ssrcs_);
+  send_config.rtp.ssrcs.push_back(kSendSsrc);
 
   send_config.local_renderer = local_preview.get();
 
@@ -75,7 +77,8 @@
                                   test_clock));
 
   VideoReceiveStream::Config receive_config = call->GetDefaultReceiveConfig();
-  receive_config.rtp.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 = loopback_video.get();
 
   VideoReceiveStream* receive_stream =
diff --git a/test/generate_ssrcs.cc b/test/generate_ssrcs.cc
deleted file mode 100644
index ea7e28d..0000000
--- a/test/generate_ssrcs.cc
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "webrtc/test/generate_ssrcs.h"
-
-#include <assert.h>
-#include <stdlib.h>
-
-#include "webrtc/video_send_stream.h"
-
-namespace webrtc {
-namespace test {
-
-void GenerateRandomSsrcs(VideoSendStream::Config* config,
-                         std::map<uint32_t, bool>* reserved_ssrcs) {
-  size_t num_ssrcs = config->codec.numberOfSimulcastStreams;
-  std::vector<uint32_t>* ssrcs = &config->rtp.ssrcs;
-  assert(ssrcs->size() == 0);
-
-  if (num_ssrcs == 0) {
-    num_ssrcs = 1;
-  }
-
-  while (ssrcs->size() < num_ssrcs) {
-    uint32_t rand_ssrc = static_cast<uint32_t>(rand() + 1);  // NOLINT
-
-    // Make sure the ssrc is unique per-call
-    while (true) {
-      if (!(*reserved_ssrcs)[rand_ssrc]) {
-        (*reserved_ssrcs)[rand_ssrc] = true;
-        break;
-      }
-      ++rand_ssrc;
-    }
-
-    ssrcs->push_back(rand_ssrc);
-  }
-}
-
-}  // namespace test
-}  // namespace webrtc
diff --git a/test/generate_ssrcs.h b/test/generate_ssrcs.h
deleted file mode 100644
index 1d3c9d9..0000000
--- a/test/generate_ssrcs.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef WEBRTC_VIDEO_ENGINE_TEST_COMMON_GENERATE_SSRCS_H_
-#define WEBRTC_VIDEO_ENGINE_TEST_COMMON_GENERATE_SSRCS_H_
-
-#include <map>
-#include <vector>
-
-#include "webrtc/typedefs.h"
-#include "webrtc/video_send_stream.h"
-
-namespace webrtc {
-namespace test {
-
-void GenerateRandomSsrcs(VideoSendStream::Config* config,
-                         std::map<uint32_t, bool>* reserved_ssrcs);
-
-}  // test
-}  // webrtc
-
-#endif  // WEBRTC_VIDEO_ENGINE_TEST_COMMON_GENERATE_SSRCS_H_
diff --git a/test/webrtc_test_common.gyp b/test/webrtc_test_common.gyp
index 5b546c7..12216a3 100644
--- a/test/webrtc_test_common.gyp
+++ b/test/webrtc_test_common.gyp
@@ -26,8 +26,6 @@
         'flags.h',
         'frame_generator_capturer.cc',
         'frame_generator_capturer.h',
-        'generate_ssrcs.cc',
-        'generate_ssrcs.h',
         'gl/gl_renderer.cc',
         'gl/gl_renderer.h',
         'linux/glx_renderer.cc',
diff --git a/video/full_stack.cc b/video/full_stack.cc
index 17e7686..f4e07e0 100644
--- a/video/full_stack.cc
+++ b/video/full_stack.cc
@@ -26,7 +26,6 @@
 #include "webrtc/test/testsupport/fileutils.h"
 #include "webrtc/test/direct_transport.h"
 #include "webrtc/test/frame_generator_capturer.h"
-#include "webrtc/test/generate_ssrcs.h"
 #include "webrtc/test/statistics.h"
 #include "webrtc/test/video_renderer.h"
 #include "webrtc/typedefs.h"
@@ -35,6 +34,8 @@
 
 namespace webrtc {
 
+static const uint32_t kSendSsrc = 0x654321;
+
 struct FullStackTestParams {
   const char* test_label;
   struct {
@@ -375,6 +376,7 @@
 };
 
 TEST_P(FullStackTest, NoPacketLoss) {
+  static const uint32_t kReceiverLocalSsrc = 0x123456;
   FullStackTestParams params = GetParam();
 
   test::DirectTransport transport;
@@ -392,7 +394,7 @@
   transport.SetReceiver(&analyzer);
 
   VideoSendStream::Config send_config = call->GetDefaultSendConfig();
-  test::GenerateRandomSsrcs(&send_config, &reserved_ssrcs_);
+  send_config.rtp.ssrcs.push_back(kSendSsrc);
 
   // TODO(pbos): static_cast shouldn't be required after mflodman refactors the
   //             VideoCodec struct.
@@ -418,7 +420,8 @@
       << ".yuv. Is this resource file present?";
 
   VideoReceiveStream::Config receive_config = call->GetDefaultReceiveConfig();
-  receive_config.rtp.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 = &analyzer;
 
   VideoReceiveStream* receive_stream =
diff --git a/video/rampup_tests.cc b/video/rampup_tests.cc
index b294c70..90a882c 100644
--- a/video/rampup_tests.cc
+++ b/video/rampup_tests.cc
@@ -26,7 +26,6 @@
 #include "webrtc/test/fake_decoder.h"
 #include "webrtc/test/fake_encoder.h"
 #include "webrtc/test/frame_generator_capturer.h"
-#include "webrtc/test/generate_ssrcs.h"
 #include "webrtc/video/transport_adapter.h"
 
 namespace webrtc {
@@ -117,9 +116,10 @@
 };
 
 TEST_P(RampUpTest, RampUpWithPadding) {
+  static const size_t kNumStreams = 3;
   test::DirectTransport receiver_transport;
   StreamObserver stream_observer(
-      3, &receiver_transport, Clock::GetRealTimeClock());
+      kNumStreams, &receiver_transport, Clock::GetRealTimeClock());
   Call::Config call_config(&stream_observer);
   scoped_ptr<Call> call(Call::Create(call_config));
   VideoSendStream::Config send_config = call->GetDefaultSendConfig();
@@ -129,22 +129,17 @@
   test::FakeEncoder encoder(Clock::GetRealTimeClock());
   send_config.encoder = &encoder;
   send_config.internal_source = false;
-  test::FakeEncoder::SetCodecSettings(&send_config.codec, 3);
+  test::FakeEncoder::SetCodecSettings(&send_config.codec, kNumStreams);
   send_config.codec.plType = 125;
   send_config.pacing = GetParam();
   send_config.rtp.extensions.push_back(
       RtpExtension(RtpExtension::kTOffset, kTOffsetExtensionId));
 
-  test::GenerateRandomSsrcs(&send_config, &reserved_ssrcs_);
+  for (size_t i = 0; i < kNumStreams; ++i)
+    send_config.rtp.ssrcs.push_back(static_cast<uint32_t>(i + 1));
 
   VideoSendStream* send_stream = call->CreateVideoSendStream(send_config);
 
-  VideoReceiveStream::Config receive_config;
-  receive_config.rtp.ssrc = send_config.rtp.ssrcs[0];
-  receive_config.rtp.nack.rtp_history_ms = send_config.rtp.nack.rtp_history_ms;
-  VideoReceiveStream* receive_stream =
-      call->CreateVideoReceiveStream(receive_config);
-
   scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer(
       test::FrameGeneratorCapturer::Create(send_stream->Input(),
                                            send_config.codec.width,
@@ -152,7 +147,6 @@
                                            30,
                                            Clock::GetRealTimeClock()));
 
-  receive_stream->StartReceiving();
   send_stream->StartSending();
   frame_generator_capturer->Start();
 
@@ -160,9 +154,7 @@
 
   frame_generator_capturer->Stop();
   send_stream->StopSending();
-  receive_stream->StopReceiving();
 
-  call->DestroyVideoReceiveStream(receive_stream);
   call->DestroyVideoSendStream(send_stream);
 }
 
diff --git a/video/video_receive_stream.cc b/video/video_receive_stream.cc
index 5157237..b6aac0b 100644
--- a/video/video_receive_stream.cc
+++ b/video/video_receive_stream.cc
@@ -56,7 +56,11 @@
       break;
   }
 
-  assert(config_.rtp.ssrc != 0);
+  assert(config_.rtp.remote_ssrc != 0);
+  assert(config_.rtp.local_ssrc != 0);
+  assert(config_.rtp.remote_ssrc != config_.rtp.local_ssrc);
+
+  rtp_rtcp_->SetLocalSSRC(channel_, config_.rtp.local_ssrc);
 
   network_ = ViENetwork::GetInterface(video_engine);
   assert(network_ != NULL);
diff --git a/video/video_send_stream_tests.cc b/video/video_send_stream_tests.cc
index 9507bf0..71cb96e 100644
--- a/video/video_send_stream_tests.cc
+++ b/video/video_send_stream_tests.cc
@@ -25,7 +25,6 @@
 #include "webrtc/test/direct_transport.h"
 #include "webrtc/test/fake_encoder.h"
 #include "webrtc/test/frame_generator_capturer.h"
-#include "webrtc/test/generate_ssrcs.h"
 #include "webrtc/test/null_transport.h"
 #include "webrtc/test/rtp_rtcp_observer.h"
 #include "webrtc/video/transport_adapter.h"
diff --git a/video_receive_stream.h b/video_receive_stream.h
index 8b4f643..e5a6829 100644
--- a/video_receive_stream.h
+++ b/video_receive_stream.h
@@ -105,11 +105,15 @@
 
     // Receive-stream specific RTP settings.
     struct Rtp {
-      Rtp() : ssrc(0), rtcp_mode(newapi::kRtcpReducedSize) {}
+      Rtp()
+          : remote_ssrc(0),
+            local_ssrc(0),
+            rtcp_mode(newapi::kRtcpReducedSize) {}
 
-      // TODO(mflodman) Do we require a set ssrc? What happens if the ssrc
-      // changes?
-      uint32_t ssrc;
+      // Synchronization source (stream identifier) to be received.
+      uint32_t remote_ssrc;
+      // Sender SSRC used for sending RTCP (such as receiver reports).
+      uint32_t local_ssrc;
 
       // See RtcpMode for description.
       newapi::RtcpMode rtcp_mode;