Reserve RTP/RTCP modules in SetSSRC.
Allows setting SSRCs for future simulcast layers even though no set send
codec uses them.
Also re-enabling CanSwitchToUseAllSsrcs as an end-to-end test, required
for bitrate ramp-up, instead of send-side only (resolving issue 3078).
This test was used to verify reserved modules' SSRCs are preserved
correctly.
To enable a multiple-stream end-to-end test test::CallTest was modified
to work on a vector of receive streams instead of just one.
BUG=3078
R=kjellander@webrtc.org, stefan@webrtc.org
Review URL: https://webrtc-codereview.appspot.com/15859005
git-svn-id: http://webrtc.googlecode.com/svn/trunk@6565 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/test/call_test.cc b/webrtc/test/call_test.cc
index ad2416f..5d8b8e6 100644
--- a/webrtc/test/call_test.cc
+++ b/webrtc/test/call_test.cc
@@ -16,7 +16,6 @@
CallTest::CallTest()
: send_stream_(NULL),
- receive_stream_(NULL),
fake_encoder_(Clock::GetRealTimeClock()) {
}
CallTest::~CallTest() {
@@ -39,9 +38,9 @@
if (test->ShouldCreateReceivers()) {
CreateMatchingReceiveConfigs();
}
- test->ModifyConfigs(&send_config_, &receive_config_, &video_streams_);
+ test->ModifyConfigs(&send_config_, &receive_configs_, &video_streams_);
CreateStreams();
- test->OnStreamsCreated(send_stream_, receive_stream_);
+ test->OnStreamsCreated(send_stream_, receive_streams_);
CreateFrameGeneratorCapturer();
test->OnFrameGeneratorCapturerCreated(frame_generator_capturer_.get());
@@ -56,15 +55,17 @@
void CallTest::Start() {
send_stream_->Start();
- if (receive_stream_ != NULL)
- receive_stream_->Start();
- frame_generator_capturer_->Start();
+ for (size_t i = 0; i < receive_streams_.size(); ++i)
+ receive_streams_[i]->Start();
+ if (frame_generator_capturer_.get() != NULL)
+ frame_generator_capturer_->Start();
}
void CallTest::Stop() {
- frame_generator_capturer_->Stop();
- if (receive_stream_ != NULL)
- receive_stream_->Stop();
+ if (frame_generator_capturer_.get() != NULL)
+ frame_generator_capturer_->Stop();
+ for (size_t i = 0; i < receive_streams_.size(); ++i)
+ receive_streams_[i]->Stop();
send_stream_->Stop();
}
@@ -93,21 +94,24 @@
send_config_.rtp.ssrcs.push_back(kSendSsrcs[i]);
}
-// TODO(pbos): Make receive configs into a vector.
void CallTest::CreateMatchingReceiveConfigs() {
- assert(send_config_.rtp.ssrcs.size() == 1);
- receive_config_ = receiver_call_->GetDefaultReceiveConfig();
+ assert(!send_config_.rtp.ssrcs.empty());
+ assert(receive_configs_.empty());
+ VideoReceiveStream::Config config = receiver_call_->GetDefaultReceiveConfig();
VideoCodec codec =
test::CreateDecoderVideoCodec(send_config_.encoder_settings);
- receive_config_.codecs.push_back(codec);
+ config.codecs.push_back(codec);
if (send_config_.encoder_settings.encoder == &fake_encoder_) {
ExternalVideoDecoder decoder;
decoder.decoder = &fake_decoder_;
decoder.payload_type = send_config_.encoder_settings.payload_type;
- receive_config_.external_decoders.push_back(decoder);
+ config.external_decoders.push_back(decoder);
}
- receive_config_.rtp.remote_ssrc = send_config_.rtp.ssrcs[0];
- receive_config_.rtp.local_ssrc = kReceiverLocalSsrc;
+ config.rtp.local_ssrc = kReceiverLocalSsrc;
+ for (size_t i = 0; i < send_config_.rtp.ssrcs.size(); ++i) {
+ config.rtp.remote_ssrc = send_config_.rtp.ssrcs[i];
+ receive_configs_.push_back(config);
+ }
}
void CallTest::CreateFrameGeneratorCapturer() {
@@ -121,22 +125,24 @@
}
void CallTest::CreateStreams() {
assert(send_stream_ == NULL);
- assert(receive_stream_ == NULL);
+ assert(receive_streams_.empty());
send_stream_ =
sender_call_->CreateVideoSendStream(send_config_, video_streams_, NULL);
- if (receiver_call_.get() != NULL)
- receive_stream_ = receiver_call_->CreateVideoReceiveStream(receive_config_);
+ for (size_t i = 0; i < receive_configs_.size(); ++i) {
+ receive_streams_.push_back(
+ receiver_call_->CreateVideoReceiveStream(receive_configs_[i]));
+ }
}
void CallTest::DestroyStreams() {
if (send_stream_ != NULL)
sender_call_->DestroyVideoSendStream(send_stream_);
- if (receive_stream_ != NULL)
- receiver_call_->DestroyVideoReceiveStream(receive_stream_);
send_stream_ = NULL;
- receive_stream_ = NULL;
+ for (size_t i = 0; i < receive_streams_.size(); ++i)
+ receiver_call_->DestroyVideoReceiveStream(receive_streams_[i]);
+ receive_streams_.clear();
}
const unsigned int CallTest::kDefaultTimeoutMs = 30 * 1000;
@@ -175,13 +181,15 @@
return 1;
}
-void BaseTest::ModifyConfigs(VideoSendStream::Config* send_config,
- VideoReceiveStream::Config* receive_config,
- std::vector<VideoStream>* video_streams) {
+void BaseTest::ModifyConfigs(
+ VideoSendStream::Config* send_config,
+ std::vector<VideoReceiveStream::Config>* receive_configs,
+ std::vector<VideoStream>* video_streams) {
}
-void BaseTest::OnStreamsCreated(VideoSendStream* send_stream,
- VideoReceiveStream* receive_stream) {
+void BaseTest::OnStreamsCreated(
+ VideoSendStream* send_stream,
+ const std::vector<VideoReceiveStream*>& receive_streams) {
}
void BaseTest::OnFrameGeneratorCapturerCreated(
diff --git a/webrtc/test/call_test.h b/webrtc/test/call_test.h
index 94ac2fa..37a883d 100644
--- a/webrtc/test/call_test.h
+++ b/webrtc/test/call_test.h
@@ -64,8 +64,8 @@
VideoSendStream* send_stream_;
scoped_ptr<Call> receiver_call_;
- VideoReceiveStream::Config receive_config_;
- VideoReceiveStream* receive_stream_;
+ std::vector<VideoReceiveStream::Config> receive_configs_;
+ std::vector<VideoReceiveStream*> receive_streams_;
scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer_;
test::FakeEncoder fake_encoder_;
@@ -87,11 +87,13 @@
virtual Call::Config GetReceiverCallConfig();
virtual void OnCallsCreated(Call* sender_call, Call* receiver_call);
- virtual void ModifyConfigs(VideoSendStream::Config* send_config,
- VideoReceiveStream::Config* receive_config,
- std::vector<VideoStream>* video_streams);
- virtual void OnStreamsCreated(VideoSendStream* send_stream,
- VideoReceiveStream* receive_stream);
+ virtual void ModifyConfigs(
+ VideoSendStream::Config* send_config,
+ std::vector<VideoReceiveStream::Config>* receive_configs,
+ std::vector<VideoStream>* video_streams);
+ virtual void OnStreamsCreated(
+ VideoSendStream* send_stream,
+ const std::vector<VideoReceiveStream*>& receive_streams);
virtual void OnFrameGeneratorCapturerCreated(
FrameGeneratorCapturer* frame_generator_capturer);
diff --git a/webrtc/video/call_perf_tests.cc b/webrtc/video/call_perf_tests.cc
index b6e2b34..1824616 100644
--- a/webrtc/video/call_perf_tests.cc
+++ b/webrtc/video/call_perf_tests.cc
@@ -254,8 +254,8 @@
CreateSendConfig(1);
CreateMatchingReceiveConfigs();
- receive_config_.renderer = &observer;
- receive_config_.audio_channel_id = channel;
+ receive_configs_[0].renderer = &observer;
+ receive_configs_[0].audio_channel_id = channel;
CreateStreams();
@@ -379,11 +379,11 @@
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
- VideoReceiveStream::Config* receive_config,
+ std::vector<VideoReceiveStream::Config>* receive_configs,
std::vector<VideoStream>* video_streams) OVERRIDE {
- receive_config->renderer = this;
+ (*receive_configs)[0].renderer = this;
// Enable the receiver side rtt calculation.
- receive_config->rtp.rtcp_xr.receiver_reference_time_report = true;
+ (*receive_configs)[0].rtp.rtcp_xr.receiver_reference_time_report = true;
}
virtual void PerformTest() OVERRIDE {
@@ -518,14 +518,15 @@
return send_transport_receiver_->DeliverPacket(packet, length);
}
- virtual void OnStreamsCreated(VideoSendStream* send_stream,
- VideoReceiveStream* receive_stream) {
+ virtual void OnStreamsCreated(
+ VideoSendStream* send_stream,
+ const std::vector<VideoReceiveStream*>& receive_streams) OVERRIDE {
send_stream_ = send_stream;
}
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
- VideoReceiveStream::Config* receive_config,
+ std::vector<VideoReceiveStream::Config>* receive_configs,
std::vector<VideoStream>* video_streams) OVERRIDE {
if (pad_to_min_bitrate_) {
send_config->rtp.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
diff --git a/webrtc/video/end_to_end_tests.cc b/webrtc/video/end_to_end_tests.cc
index 0f6f2dc..fa3d3cf 100644
--- a/webrtc/video/end_to_end_tests.cc
+++ b/webrtc/video/end_to_end_tests.cc
@@ -49,39 +49,15 @@
virtual ~EndToEndTest() {
EXPECT_EQ(NULL, send_stream_);
- EXPECT_EQ(NULL, receive_stream_);
+ EXPECT_TRUE(receive_streams_.empty());
}
protected:
- void CreateFrameGenerator() {
- frame_generator_capturer_.reset(
- test::FrameGeneratorCapturer::Create(send_stream_->Input(),
- video_streams_[0].width,
- video_streams_[0].height,
- 30,
- Clock::GetRealTimeClock()));
- }
-
- void StartSending() {
- receive_stream_->Start();
- send_stream_->Start();
- if (frame_generator_capturer_.get() != NULL)
- frame_generator_capturer_->Start();
- }
-
- void StopSending() {
- if (frame_generator_capturer_.get() != NULL)
- frame_generator_capturer_->Stop();
- if (send_stream_ != NULL)
- send_stream_->Stop();
- if (receive_stream_ != NULL)
- receive_stream_->Stop();
- }
-
void DecodesRetransmittedFrame(bool retransmit_over_rtx);
void ReceivesPliAndRecovers(int rtp_history_ms);
void RespectsRtcpMode(newapi::RtcpMode rtcp_mode);
void TestXrReceiverReferenceTimeReport(bool enable_rrtr);
+ void TestSendsSetSsrcs(size_t num_ssrcs, bool send_single_ssrc_first);
};
TEST_F(EndToEndTest, ReceiverCanBeStartedTwice) {
@@ -93,8 +69,8 @@
CreateStreams();
- receive_stream_->Start();
- receive_stream_->Start();
+ receive_streams_[0]->Start();
+ receive_streams_[0]->Start();
DestroyStreams();
}
@@ -108,8 +84,8 @@
CreateStreams();
- receive_stream_->Stop();
- receive_stream_->Stop();
+ receive_streams_[0]->Stop();
+ receive_streams_[0]->Stop();
DestroyStreams();
}
@@ -163,11 +139,11 @@
CreateMatchingReceiveConfigs();
TestFrameCallback pre_render_callback;
- receive_config_.pre_render_callback = &pre_render_callback;
- receive_config_.renderer = &renderer;
+ receive_configs_[0].pre_render_callback = &pre_render_callback;
+ receive_configs_[0].renderer = &renderer;
CreateStreams();
- StartSending();
+ Start();
// Create frames that are smaller than the send width/height, this is done to
// check that the callbacks are done after processing video.
@@ -179,7 +155,7 @@
EXPECT_EQ(kEventSignaled, renderer.Wait())
<< "Timed out while waiting for the frame to render.";
- StopSending();
+ Stop();
sender_transport.StopSending();
receiver_transport.StopSending();
@@ -212,10 +188,10 @@
CreateSendConfig(1);
CreateMatchingReceiveConfigs();
- receive_config_.renderer = &renderer;
+ receive_configs_[0].renderer = &renderer;
CreateStreams();
- StartSending();
+ Start();
scoped_ptr<test::FrameGenerator> frame_generator(test::FrameGenerator::Create(
video_streams_[0].width, video_streams_[0].height));
@@ -224,7 +200,7 @@
EXPECT_EQ(kEventSignaled, renderer.Wait())
<< "Timed out while waiting for the frame to render.";
- StopSending();
+ Stop();
sender_transport.StopSending();
receiver_transport.StopSending();
@@ -328,10 +304,10 @@
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
- VideoReceiveStream::Config* receive_config,
+ std::vector<VideoReceiveStream::Config>* receive_configs,
std::vector<VideoStream>* video_streams) OVERRIDE {
send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
- receive_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
+ (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
}
virtual void PerformTest() OVERRIDE {
@@ -422,18 +398,18 @@
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
- VideoReceiveStream::Config* receive_config,
+ std::vector<VideoReceiveStream::Config>* receive_configs,
std::vector<VideoStream>* video_streams) OVERRIDE {
// TODO(pbos): Run this test with combined NACK/FEC enabled as well.
// int rtp_history_ms = 1000;
- // receive_config->rtp.nack.rtp_history_ms = rtp_history_ms;
+ // (*receive_configs)[0].rtp.nack.rtp_history_ms = rtp_history_ms;
// send_config->rtp.nack.rtp_history_ms = rtp_history_ms;
send_config->rtp.fec.red_payload_type = kRedPayloadType;
send_config->rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
- receive_config->rtp.fec.red_payload_type = kRedPayloadType;
- receive_config->rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
- receive_config->renderer = this;
+ (*receive_configs)[0].rtp.fec.red_payload_type = kRedPayloadType;
+ (*receive_configs)[0].rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
+ (*receive_configs)[0].renderer = this;
}
virtual void PerformTest() OVERRIDE {
@@ -500,16 +476,16 @@
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
- VideoReceiveStream::Config* receive_config,
+ std::vector<VideoReceiveStream::Config>* receive_configs,
std::vector<VideoStream>* video_streams) OVERRIDE {
send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
- receive_config->pre_render_callback = this;
- receive_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
+ (*receive_configs)[0].pre_render_callback = this;
+ (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
if (retransmission_ssrc_ == kSendRtxSsrc) {
send_config->rtp.rtx.ssrcs.push_back(kSendRtxSsrc);
send_config->rtp.rtx.payload_type = kSendRtxPayloadType;
- receive_config->rtp.rtx[kSendRtxPayloadType].ssrc = kSendRtxSsrc;
- receive_config->rtp.rtx[kSendRtxPayloadType].payload_type =
+ (*receive_configs)[0].rtp.rtx[kSendRtxPayloadType].ssrc = kSendRtxSsrc;
+ (*receive_configs)[0].rtp.rtx[kSendRtxPayloadType].payload_type =
kSendRtxPayloadType;
}
}
@@ -611,11 +587,11 @@
send_config_.pre_encode_callback = &pre_encode_callback;
CreateMatchingReceiveConfigs();
- receive_config_.pre_render_callback = &pre_render_callback;
- receive_config_.renderer = &renderer;
+ receive_configs_[0].pre_render_callback = &pre_render_callback;
+ receive_configs_[0].renderer = &renderer;
CreateStreams();
- StartSending();
+ Start();
// Create frames that are smaller than the send width/height, this is done to
// check that the callbacks are done after processing video.
@@ -630,7 +606,7 @@
EXPECT_EQ(kEventSignaled, renderer.Wait())
<< "Timed out while waiting for the frame to render.";
- StopSending();
+ Stop();
sender_transport.StopSending();
receiver_transport.StopSending();
@@ -701,11 +677,11 @@
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
- VideoReceiveStream::Config* receive_config,
+ std::vector<VideoReceiveStream::Config>* receive_configs,
std::vector<VideoStream>* video_streams) OVERRIDE {
send_config->rtp.nack.rtp_history_ms = rtp_history_ms_;
- receive_config->rtp.nack.rtp_history_ms = rtp_history_ms_;
- receive_config->renderer = this;
+ (*receive_configs)[0].rtp.nack.rtp_history_ms = rtp_history_ms_;
+ (*receive_configs)[0].renderer = this;
}
virtual void PerformTest() OVERRIDE {
@@ -773,16 +749,16 @@
CreateMatchingReceiveConfigs();
CreateStreams();
- CreateFrameGenerator();
- StartSending();
+ CreateFrameGeneratorCapturer();
+ Start();
- receiver_call_->DestroyVideoReceiveStream(receive_stream_);
- receive_stream_ = NULL;
+ receiver_call_->DestroyVideoReceiveStream(receive_streams_[0]);
+ receive_streams_.clear();
// Wait() waits for a received packet.
EXPECT_EQ(kEventSignaled, input_observer.Wait());
- StopSending();
+ Stop();
DestroyStreams();
@@ -848,11 +824,11 @@
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
- VideoReceiveStream::Config* receive_config,
+ std::vector<VideoReceiveStream::Config>* receive_configs,
std::vector<VideoStream>* video_streams) OVERRIDE {
send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
- receive_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
- receive_config->rtp.rtcp_mode = rtcp_mode_;
+ (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
+ (*receive_configs)[0].rtp.rtcp_mode = rtcp_mode_;
}
virtual void PerformTest() OVERRIDE {
@@ -1040,10 +1016,10 @@
CreateSendConfig(1);
CreateMatchingReceiveConfigs();
send_config_.post_encode_callback = &post_encode_observer;
- receive_config_.pre_decode_callback = &pre_decode_observer;
+ receive_configs_[0].pre_decode_callback = &pre_decode_observer;
CreateStreams();
- StartSending();
+ Start();
scoped_ptr<test::FrameGenerator> frame_generator(test::FrameGenerator::Create(
video_streams_[0].width, video_streams_[0].height));
@@ -1057,7 +1033,7 @@
post_encode_observer.ExpectEqualFrames(pre_decode_observer);
- StopSending();
+ Stop();
sender_transport.StopSending();
receiver_transport.StopSending();
@@ -1170,10 +1146,11 @@
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
- VideoReceiveStream::Config* receive_config,
+ std::vector<VideoReceiveStream::Config>* receive_configs,
std::vector<VideoStream>* video_streams) OVERRIDE {
- receive_config->rtp.rtcp_mode = newapi::kRtcpReducedSize;
- receive_config->rtp.rtcp_xr.receiver_reference_time_report = enable_rrtr_;
+ (*receive_configs)[0].rtp.rtcp_mode = newapi::kRtcpReducedSize;
+ (*receive_configs)[0].rtp.rtcp_xr.receiver_reference_time_report =
+ enable_rrtr_;
}
virtual void PerformTest() OVERRIDE {
@@ -1191,6 +1168,104 @@
RunBaseTest(&test);
}
+void EndToEndTest::TestSendsSetSsrcs(size_t num_ssrcs,
+ bool send_single_ssrc_first) {
+ class SendsSetSsrcs : public test::EndToEndTest {
+ public:
+ SendsSetSsrcs(const uint32_t* ssrcs,
+ size_t num_ssrcs,
+ bool send_single_ssrc_first)
+ : EndToEndTest(kDefaultTimeoutMs),
+ num_ssrcs_(num_ssrcs),
+ send_single_ssrc_first_(send_single_ssrc_first),
+ ssrcs_to_observe_(num_ssrcs),
+ expect_single_ssrc_(send_single_ssrc_first) {
+ for (size_t i = 0; i < num_ssrcs; ++i)
+ valid_ssrcs_[ssrcs[i]] = true;
+ }
+
+ private:
+ virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
+ RTPHeader header;
+ EXPECT_TRUE(parser_->Parse(packet, static_cast<int>(length), &header));
+
+ EXPECT_TRUE(valid_ssrcs_[header.ssrc])
+ << "Received unknown SSRC: " << header.ssrc;
+
+ if (!valid_ssrcs_[header.ssrc])
+ observation_complete_->Set();
+
+ if (!is_observed_[header.ssrc]) {
+ is_observed_[header.ssrc] = true;
+ --ssrcs_to_observe_;
+ if (expect_single_ssrc_) {
+ expect_single_ssrc_ = false;
+ observation_complete_->Set();
+ }
+ }
+
+ if (ssrcs_to_observe_ == 0)
+ observation_complete_->Set();
+
+ return SEND_PACKET;
+ }
+
+ virtual size_t GetNumStreams() const OVERRIDE { return num_ssrcs_; }
+
+ virtual void ModifyConfigs(
+ VideoSendStream::Config* send_config,
+ std::vector<VideoReceiveStream::Config>* receive_configs,
+ std::vector<VideoStream>* video_streams) OVERRIDE {
+ if (num_ssrcs_ > 1) {
+ // Set low simulcast bitrates to not have to wait for bandwidth ramp-up.
+ for (size_t i = 0; i < video_streams->size(); ++i) {
+ (*video_streams)[i].min_bitrate_bps = 10000;
+ (*video_streams)[i].target_bitrate_bps = 15000;
+ (*video_streams)[i].max_bitrate_bps = 20000;
+ }
+ }
+
+ all_streams_ = *video_streams;
+ if (send_single_ssrc_first_)
+ video_streams->resize(1);
+ }
+
+ virtual void OnStreamsCreated(
+ VideoSendStream* send_stream,
+ const std::vector<VideoReceiveStream*>& receive_streams) OVERRIDE {
+ send_stream_ = send_stream;
+ }
+
+ virtual void PerformTest() OVERRIDE {
+ EXPECT_EQ(kEventSignaled, Wait())
+ << "Timed out while waiting for "
+ << (send_single_ssrc_first_ ? "first SSRC." : "SSRCs.");
+
+ if (send_single_ssrc_first_) {
+ // Set full simulcast and continue with the rest of the SSRCs.
+ send_stream_->ReconfigureVideoEncoder(all_streams_, NULL);
+ EXPECT_EQ(kEventSignaled, Wait())
+ << "Timed out while waiting on additional SSRCs.";
+ }
+ }
+
+ private:
+ std::map<uint32_t, bool> valid_ssrcs_;
+ std::map<uint32_t, bool> is_observed_;
+
+ const size_t num_ssrcs_;
+ const bool send_single_ssrc_first_;
+
+ size_t ssrcs_to_observe_;
+ bool expect_single_ssrc_;
+
+ VideoSendStream* send_stream_;
+ std::vector<VideoStream> all_streams_;
+ } test(kSendSsrcs, num_ssrcs, send_single_ssrc_first);
+
+ RunBaseTest(&test);
+}
+
TEST_F(EndToEndTest, GetStats) {
class StatsObserver : public test::EndToEndTest, public I420FrameCallback {
public:
@@ -1332,12 +1407,12 @@
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
- VideoReceiveStream::Config* receive_config,
+ std::vector<VideoReceiveStream::Config>* receive_configs,
std::vector<VideoStream>* video_streams) OVERRIDE {
send_config->pre_encode_callback = this; // Used to inject delay.
send_config->rtp.c_name = "SomeCName";
- expected_receive_ssrc_ = receive_config->rtp.local_ssrc;
+ expected_receive_ssrc_ = (*receive_configs)[0].rtp.local_ssrc;
const std::vector<uint32_t>& ssrcs = send_config->rtp.ssrcs;
for (size_t i = 0; i < ssrcs.size(); ++i)
expected_send_ssrcs_.insert(ssrcs[i]);
@@ -1345,10 +1420,11 @@
expected_cname_ = send_config->rtp.c_name;
}
- virtual void OnStreamsCreated(VideoSendStream* send_stream,
- VideoReceiveStream* receive_stream) OVERRIDE {
+ virtual void OnStreamsCreated(
+ VideoSendStream* send_stream,
+ const std::vector<VideoReceiveStream*>& receive_streams) OVERRIDE {
send_stream_ = send_stream;
- receive_stream_ = receive_stream;
+ receive_stream_ = receive_streams[0];
}
virtual void PerformTest() OVERRIDE {
@@ -1427,9 +1503,10 @@
sent_rtp_(0) {}
private:
- virtual void OnStreamsCreated(VideoSendStream* send_stream,
- VideoReceiveStream* receive_stream) OVERRIDE {
- receive_stream_ = receive_stream;
+ virtual void OnStreamsCreated(
+ VideoSendStream* send_stream,
+ const std::vector<VideoReceiveStream*>& receive_streams) OVERRIDE {
+ receive_stream_ = receive_streams[0];
}
virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
@@ -1456,4 +1533,14 @@
RunBaseTest(&test);
}
+TEST_F(EndToEndTest, SendsSetSsrc) { TestSendsSetSsrcs(1, false); }
+
+TEST_F(EndToEndTest, SendsSetSimulcastSsrcs) {
+ TestSendsSetSsrcs(kNumSsrcs, false);
+}
+
+TEST_F(EndToEndTest, CanSwitchToUseAllSsrcs) {
+ TestSendsSetSsrcs(kNumSsrcs, true);
+}
+
} // namespace webrtc
diff --git a/webrtc/video/full_stack.cc b/webrtc/video/full_stack.cc
index 1c03042..e2a8e86 100644
--- a/webrtc/video/full_stack.cc
+++ b/webrtc/video/full_stack.cc
@@ -396,7 +396,7 @@
stream->max_framerate = params.clip.fps;
CreateMatchingReceiveConfigs();
- receive_config_.renderer = &analyzer;
+ receive_configs_[0].renderer = &analyzer;
CreateStreams();
analyzer.input_ = send_stream_->Input();
diff --git a/webrtc/video/video_send_stream.cc b/webrtc/video/video_send_stream.cc
index f9bbd57..4d32ab4 100644
--- a/webrtc/video/video_send_stream.cc
+++ b/webrtc/video/video_send_stream.cc
@@ -173,6 +173,8 @@
rtp_rtcp_->SetNACKStatus(channel_, config_.rtp.nack.rtp_history_ms > 0);
}
+ ConfigureSsrcs();
+
char rtcp_cname[ViERTP_RTCP::KMaxRTCPCNameLength];
assert(config_.rtp.c_name.length() < ViERTP_RTCP::KMaxRTCPCNameLength);
strncpy(rtcp_cname, config_.rtp.c_name.c_str(), sizeof(rtcp_cname) - 1);
@@ -373,38 +375,7 @@
assert(streams[0].max_framerate > 0);
video_codec.maxFramerate = streams[0].max_framerate;
- if (codec_->SetSendCodec(channel_, video_codec) != 0)
- return false;
-
- for (size_t i = 0; i < config_.rtp.ssrcs.size(); ++i) {
- rtp_rtcp_->SetLocalSSRC(channel_,
- config_.rtp.ssrcs[i],
- kViEStreamTypeNormal,
- static_cast<unsigned char>(i));
- }
-
- if (config_.rtp.rtx.ssrcs.empty()) {
- assert(!config_.rtp.rtx.pad_with_redundant_payloads);
- return true;
- }
-
- // Set up RTX.
- assert(config_.rtp.rtx.ssrcs.size() == config_.rtp.ssrcs.size());
- for (size_t i = 0; i < config_.rtp.ssrcs.size(); ++i) {
- rtp_rtcp_->SetLocalSSRC(channel_,
- config_.rtp.rtx.ssrcs[i],
- kViEStreamTypeRtx,
- static_cast<unsigned char>(i));
- }
-
- if (config_.rtp.rtx.pad_with_redundant_payloads) {
- rtp_rtcp_->SetPadWithRedundantPayloads(channel_, true);
- }
-
- assert(config_.rtp.rtx.payload_type >= 0);
- rtp_rtcp_->SetRtxSendPayloadType(channel_, config_.rtp.rtx.payload_type);
-
- return true;
+ return codec_->SetSendCodec(channel_, video_codec) == 0;
}
bool VideoSendStream::DeliverRtcp(const uint8_t* packet, size_t length) {
@@ -427,5 +398,34 @@
return rtcp_cname;
}
+void VideoSendStream::ConfigureSsrcs() {
+ for (size_t i = 0; i < config_.rtp.ssrcs.size(); ++i) {
+ uint32_t ssrc = config_.rtp.ssrcs[i];
+ rtp_rtcp_->SetLocalSSRC(
+ channel_, ssrc, kViEStreamTypeNormal, static_cast<unsigned char>(i));
+ }
+
+ if (config_.rtp.rtx.ssrcs.empty()) {
+ assert(!config_.rtp.rtx.pad_with_redundant_payloads);
+ return;
+ }
+
+ // Set up RTX.
+ assert(config_.rtp.rtx.ssrcs.size() == config_.rtp.ssrcs.size());
+ for (size_t i = 0; i < config_.rtp.ssrcs.size(); ++i) {
+ rtp_rtcp_->SetLocalSSRC(channel_,
+ config_.rtp.rtx.ssrcs[i],
+ kViEStreamTypeRtx,
+ static_cast<unsigned char>(i));
+ }
+
+ if (config_.rtp.rtx.pad_with_redundant_payloads) {
+ rtp_rtcp_->SetPadWithRedundantPayloads(channel_, true);
+ }
+
+ assert(config_.rtp.rtx.payload_type >= 0);
+ rtp_rtcp_->SetRtxSendPayloadType(channel_, config_.rtp.rtx.payload_type);
+}
+
} // namespace internal
} // namespace webrtc
diff --git a/webrtc/video/video_send_stream.h b/webrtc/video/video_send_stream.h
index ed77665..df65b74 100644
--- a/webrtc/video/video_send_stream.h
+++ b/webrtc/video/video_send_stream.h
@@ -71,6 +71,7 @@
virtual std::string GetCName() OVERRIDE;
private:
+ void ConfigureSsrcs();
TransportAdapter transport_adapter_;
EncodedFrameCallbackAdapter encoded_frame_proxy_;
const VideoSendStream::Config config_;
diff --git a/webrtc/video/video_send_stream_tests.cc b/webrtc/video/video_send_stream_tests.cc
index 2d9bf5b..b1197ef 100644
--- a/webrtc/video/video_send_stream_tests.cc
+++ b/webrtc/video/video_send_stream_tests.cc
@@ -60,113 +60,8 @@
void TestNackRetransmission(uint32_t retransmit_ssrc,
uint8_t retransmit_payload_type);
void TestPacketFragmentationSize(VideoFormat format, bool with_fec);
- void SendsSetSsrcs(size_t num_ssrcs, bool send_single_ssrc_first);
-
};
-void VideoSendStreamTest::SendsSetSsrcs(size_t num_ssrcs,
- bool send_single_ssrc_first) {
- class SendsSetSsrcs : public test::SendTest {
- public:
- SendsSetSsrcs(const uint32_t* ssrcs,
- size_t num_ssrcs,
- bool send_single_ssrc_first)
- : SendTest(kDefaultTimeoutMs),
- num_ssrcs_(num_ssrcs),
- send_single_ssrc_first_(send_single_ssrc_first),
- ssrcs_to_observe_(num_ssrcs),
- expect_single_ssrc_(send_single_ssrc_first) {
- for (size_t i = 0; i < num_ssrcs; ++i)
- valid_ssrcs_[ssrcs[i]] = true;
- }
-
- private:
- virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
- RTPHeader header;
- EXPECT_TRUE(parser_->Parse(packet, static_cast<int>(length), &header));
-
- // TODO(pbos): Reenable this part of the test when #1695 is resolved and
- // all SSRCs are allocated on startup. This test was
- // observed
- // to fail on TSan as the codec gets set before the SSRCs
- // are
- // set up and some frames are sent on a random-generated
- // SSRC
- // before the correct SSRC gets set.
- // EXPECT_TRUE(valid_ssrcs_[header.ssrc])
- // << "Received unknown SSRC: " << header.ssrc;
- //
- // if (!valid_ssrcs_[header.ssrc])
- // observation_complete_->Set();
-
- if (!is_observed_[header.ssrc]) {
- is_observed_[header.ssrc] = true;
- --ssrcs_to_observe_;
- if (expect_single_ssrc_) {
- expect_single_ssrc_ = false;
- observation_complete_->Set();
- }
- }
-
- if (ssrcs_to_observe_ == 0)
- observation_complete_->Set();
-
- return SEND_PACKET;
- }
-
- virtual void ModifyConfigs(
- VideoSendStream::Config* send_config,
- VideoReceiveStream::Config* receive_config,
- std::vector<VideoStream>* video_streams) OVERRIDE {
- if (num_ssrcs_ > 1) {
- // Set low simulcast bitrates to not have to wait for bandwidth ramp-up.
- 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;
- }
- }
-
- all_streams_ = *video_streams;
- if (send_single_ssrc_first_)
- video_streams->resize(1);
- }
-
- virtual void OnStreamsCreated(VideoSendStream* send_stream,
- VideoReceiveStream* receive_stream) OVERRIDE {
- send_stream_ = send_stream;
- }
-
- virtual void PerformTest() OVERRIDE {
- EXPECT_EQ(kEventSignaled, Wait())
- << "Timed out while waiting for "
- << (send_single_ssrc_first_ ? "first SSRC." : "SSRCs.");
-
- if (send_single_ssrc_first_) {
- // Set full simulcast and continue with the rest of the SSRCs.
- send_stream_->ReconfigureVideoEncoder(all_streams_, NULL);
- EXPECT_EQ(kEventSignaled, Wait())
- << "Timed out while waiting on additional SSRCs.";
- }
- }
-
- private:
- std::map<uint32_t, bool> valid_ssrcs_;
- std::map<uint32_t, bool> is_observed_;
-
- const size_t num_ssrcs_;
- const bool send_single_ssrc_first_;
-
- size_t ssrcs_to_observe_;
- bool expect_single_ssrc_;
-
- VideoSendStream* send_stream_;
- std::vector<VideoStream> all_streams_;
- } test(kSendSsrcs, num_ssrcs, send_single_ssrc_first);
-
- RunBaseTest(&test);
-}
-
TEST_F(VideoSendStreamTest, CanStartStartedStream) {
test::NullTransport transport;
Call::Config call_config(&transport);
@@ -191,16 +86,6 @@
DestroyStreams();
}
-TEST_F(VideoSendStreamTest, SendsSetSsrc) { SendsSetSsrcs(1, false); }
-
-TEST_F(VideoSendStreamTest, DISABLED_SendsSetSimulcastSsrcs) {
- SendsSetSsrcs(kNumSsrcs, false);
-}
-
-TEST_F(VideoSendStreamTest, DISABLED_CanSwitchToUseAllSsrcs) {
- SendsSetSsrcs(kNumSsrcs, true);
-}
-
TEST_F(VideoSendStreamTest, SupportsCName) {
static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo=";
class CNameObserver : public test::SendTest {
@@ -227,7 +112,7 @@
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
- VideoReceiveStream::Config* receive_config,
+ std::vector<VideoReceiveStream::Config>* receive_configs,
std::vector<VideoStream>* video_streams) OVERRIDE {
send_config->rtp.c_name = kCName;
}
@@ -265,7 +150,7 @@
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
- VideoReceiveStream::Config* receive_config,
+ std::vector<VideoReceiveStream::Config>* receive_configs,
std::vector<VideoStream>* video_streams) OVERRIDE {
send_config->rtp.extensions.push_back(
RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeExtensionId));
@@ -306,7 +191,7 @@
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
- VideoReceiveStream::Config* receive_config,
+ std::vector<VideoReceiveStream::Config>* receive_configs,
std::vector<VideoStream>* video_streams) OVERRIDE {
send_config->encoder_settings.encoder = &encoder_;
send_config->rtp.extensions.push_back(
@@ -475,7 +360,7 @@
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
- VideoReceiveStream::Config* receive_config,
+ std::vector<VideoReceiveStream::Config>* receive_configs,
std::vector<VideoStream>* video_streams) OVERRIDE {
send_config->rtp.fec.red_payload_type = kRedPayloadType;
send_config->rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
@@ -555,9 +440,9 @@
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
- VideoReceiveStream::Config* receive_config,
+ std::vector<VideoReceiveStream::Config>* receive_configs,
std::vector<VideoStream>* video_streams) OVERRIDE {
- send_config->rtp.nack.rtp_history_ms = 1000;
+ send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
send_config->rtp.rtx.payload_type = retransmit_payload_type_;
if (retransmit_ssrc_ != kSendSsrcs[0])
send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_);
@@ -730,7 +615,7 @@
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
- VideoReceiveStream::Config* receive_config,
+ std::vector<VideoReceiveStream::Config>* receive_configs,
std::vector<VideoStream>* video_streams) OVERRIDE {
if (use_fec_) {
send_config->rtp.fec.red_payload_type = kRedPayloadType;
@@ -897,16 +782,17 @@
transport_.SetReceiver(send_transport_receiver);
}
- virtual void OnStreamsCreated(VideoSendStream* send_stream,
- VideoReceiveStream* receive_stream) OVERRIDE {
+ virtual void OnStreamsCreated(
+ VideoSendStream* send_stream,
+ const std::vector<VideoReceiveStream*>& receive_streams) OVERRIDE {
stream_ = send_stream;
}
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
- VideoReceiveStream::Config* receive_config,
+ std::vector<VideoReceiveStream::Config>* receive_configs,
std::vector<VideoStream>* video_streams) OVERRIDE {
- send_config->rtp.nack.rtp_history_ms = 1000;
+ send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
send_config->pre_encode_callback = this;
send_config->suspend_below_min_bitrate = true;
int min_bitrate_bps = (*video_streams)[0].min_bitrate_bps;
@@ -1095,14 +981,15 @@
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
- VideoReceiveStream::Config* receive_config,
+ std::vector<VideoReceiveStream::Config>* receive_configs,
std::vector<VideoStream>* video_streams) OVERRIDE {
send_config->rtp.c_name = kCName;
SetConfig(*send_config);
}
- virtual void OnStreamsCreated(VideoSendStream* send_stream,
- VideoReceiveStream* receive_stream) OVERRIDE {
+ virtual void OnStreamsCreated(
+ VideoSendStream* send_stream,
+ const std::vector<VideoReceiveStream*>& receive_streams) OVERRIDE {
stream_ = send_stream;
}
@@ -1145,8 +1032,9 @@
rtp_rtcp_->SetRTCPStatus(kRtcpNonCompound);
}
- virtual void OnStreamsCreated(VideoSendStream* send_stream,
- VideoReceiveStream* receive_stream) OVERRIDE {
+ virtual void OnStreamsCreated(
+ VideoSendStream* send_stream,
+ const std::vector<VideoReceiveStream*>& receive_streams) OVERRIDE {
stream_ = send_stream;
}
@@ -1191,7 +1079,7 @@
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
- VideoReceiveStream::Config* receive_config,
+ std::vector<VideoReceiveStream::Config>* receive_configs,
std::vector<VideoStream>* video_streams) OVERRIDE {
send_config->rtp.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
}
diff --git a/webrtc/video_engine/vie_channel.cc b/webrtc/video_engine/vie_channel.cc
index 62bb095..80d3065 100644
--- a/webrtc/video_engine/vie_channel.cc
+++ b/webrtc/video_engine/vie_channel.cc
@@ -244,31 +244,25 @@
num_modules_to_add = 0;
}
- while (removed_rtp_rtcp_.size() > 0 && num_modules_to_add > 0) {
- RtpRtcp* rtp_rtcp = removed_rtp_rtcp_.front();
+ // Add back removed rtp modules. Order is important (allocate from front of
+ // removed modules) to preserve RTP settings such as SSRCs for simulcast
+ // streams.
+ std::list<RtpRtcp*> new_rtp_modules;
+ for (; removed_rtp_rtcp_.size() > 0 && num_modules_to_add > 0;
+ --num_modules_to_add) {
+ new_rtp_modules.push_back(removed_rtp_rtcp_.front());
removed_rtp_rtcp_.pop_front();
- simulcast_rtp_rtcp_.push_back(rtp_rtcp);
- rtp_rtcp->SetSendingStatus(rtp_rtcp_->Sending());
- rtp_rtcp->SetSendingMediaStatus(rtp_rtcp_->SendingMedia());
- module_process_thread_.RegisterModule(rtp_rtcp);
- --num_modules_to_add;
}
- for (int i = 0; i < num_modules_to_add; ++i) {
- RtpRtcp::Configuration configuration;
- configuration.id = ViEModuleId(engine_id_, channel_id_);
- configuration.audio = false; // Video.
- configuration.default_module = default_rtp_rtcp_;
- configuration.outgoing_transport = &vie_sender_;
- configuration.intra_frame_callback = intra_frame_observer_;
- configuration.bandwidth_callback = bandwidth_observer_.get();
- configuration.rtt_stats = rtt_stats_;
- configuration.paced_sender = paced_sender_;
+ for (int i = 0; i < num_modules_to_add; ++i)
+ new_rtp_modules.push_back(CreateRtpRtcpModule());
- RtpRtcp* rtp_rtcp = RtpRtcp::CreateRtpRtcp(configuration);
+ // Initialize newly added modules.
+ for (std::list<RtpRtcp*>::iterator it = new_rtp_modules.begin();
+ it != new_rtp_modules.end();
+ ++it) {
+ RtpRtcp* rtp_rtcp = *it;
- // Silently ignore error.
- module_process_thread_.RegisterModule(rtp_rtcp);
rtp_rtcp->SetRTCPStatus(rtp_rtcp_->RTCP());
if (rtp_rtcp_->StorePackets()) {
@@ -278,13 +272,18 @@
}
if (fec_enabled) {
- rtp_rtcp->SetGenericFECStatus(fec_enabled, payload_type_red,
- payload_type_fec);
+ rtp_rtcp->SetGenericFECStatus(
+ fec_enabled, payload_type_red, payload_type_fec);
}
rtp_rtcp->SetSendingStatus(rtp_rtcp_->Sending());
rtp_rtcp->SetSendingMediaStatus(rtp_rtcp_->SendingMedia());
+
simulcast_rtp_rtcp_.push_back(rtp_rtcp);
+
+ // Silently ignore error.
+ module_process_thread_.RegisterModule(rtp_rtcp);
}
+
// Remove last in list if we have too many.
for (int j = simulcast_rtp_rtcp_.size();
j > (video_codec.numberOfSimulcastStreams - 1);
@@ -792,29 +791,15 @@
int32_t ViEChannel::SetSSRC(const uint32_t SSRC,
const StreamType usage,
const uint8_t simulcast_idx) {
- if (simulcast_idx == 0) {
- if (usage == kViEStreamTypeRtx) {
- rtp_rtcp_->SetRtxSsrc(SSRC);
- } else {
- rtp_rtcp_->SetSSRC(SSRC);
- }
- return 0;
- }
CriticalSectionScoped cs(rtp_rtcp_cs_.get());
- if (simulcast_idx > simulcast_rtp_rtcp_.size()) {
- return -1;
- }
- std::list<RtpRtcp*>::const_iterator it = simulcast_rtp_rtcp_.begin();
- for (int i = 1; i < simulcast_idx; ++i, ++it) {
- if (it == simulcast_rtp_rtcp_.end()) {
- return -1;
- }
- }
- RtpRtcp* rtp_rtcp_module = *it;
+ ReserveRtpRtcpModules(simulcast_idx + 1);
+ RtpRtcp* rtp_rtcp = GetRtpRtcpModule(simulcast_idx);
+ if (rtp_rtcp == NULL)
+ return -1;
if (usage == kViEStreamTypeRtx) {
- rtp_rtcp_module->SetRtxSsrc(SSRC);
+ rtp_rtcp->SetRtxSsrc(SSRC);
} else {
- rtp_rtcp_module->SetSSRC(SSRC);
+ rtp_rtcp->SetSSRC(SSRC);
}
return 0;
}
@@ -826,21 +811,11 @@
}
int32_t ViEChannel::GetLocalSSRC(uint8_t idx, unsigned int* ssrc) {
- if (idx == 0) {
- *ssrc = rtp_rtcp_->SSRC();
- return 0;
- }
CriticalSectionScoped cs(rtp_rtcp_cs_.get());
- if (idx > simulcast_rtp_rtcp_.size()) {
+ RtpRtcp* rtp_rtcp = GetRtpRtcpModule(idx);
+ if (rtp_rtcp == NULL)
return -1;
- }
- std::list<RtpRtcp*>::const_iterator it = simulcast_rtp_rtcp_.begin();
- for (int i = 1; i < idx; ++i, ++it) {
- if (it == simulcast_rtp_rtcp_.end()) {
- return -1;
- }
- }
- *ssrc = (*it)->SSRC();
+ *ssrc = rtp_rtcp->SSRC();
return 0;
}
@@ -1530,6 +1505,61 @@
vcm_->SetReceiveChannelParameters(rtt);
}
+void ViEChannel::ReserveRtpRtcpModules(size_t num_modules) {
+ for (size_t total_modules =
+ 1 + simulcast_rtp_rtcp_.size() + removed_rtp_rtcp_.size();
+ total_modules < num_modules;
+ ++total_modules) {
+ RtpRtcp* rtp_rtcp = CreateRtpRtcpModule();
+ rtp_rtcp->SetSendingStatus(false);
+ rtp_rtcp->SetSendingMediaStatus(false);
+ rtp_rtcp->RegisterSendFrameCountObserver(NULL);
+ rtp_rtcp->RegisterSendChannelRtcpStatisticsCallback(NULL);
+ rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(NULL);
+ rtp_rtcp->RegisterVideoBitrateObserver(NULL);
+ removed_rtp_rtcp_.push_back(rtp_rtcp);
+ }
+}
+
+RtpRtcp* ViEChannel::GetRtpRtcpModule(size_t index) const {
+ if (index == 0)
+ return rtp_rtcp_.get();
+ if (index <= simulcast_rtp_rtcp_.size()) {
+ std::list<RtpRtcp*>::const_iterator it = simulcast_rtp_rtcp_.begin();
+ for (size_t i = 1; i < index; ++i) {
+ ++it;
+ }
+ return *it;
+ }
+
+ // If the requested module exists it must be in the removed list. Index
+ // translation to this list must remove the default module as well as all
+ // active simulcast modules.
+ size_t removed_idx = index - simulcast_rtp_rtcp_.size() - 1;
+ if (removed_idx >= removed_rtp_rtcp_.size())
+ return NULL;
+
+ std::list<RtpRtcp*>::const_iterator it = removed_rtp_rtcp_.begin();
+ while (removed_idx-- > 0)
+ ++it;
+
+ return *it;
+}
+
+RtpRtcp* ViEChannel::CreateRtpRtcpModule() {
+ RtpRtcp::Configuration configuration;
+ configuration.id = ViEModuleId(engine_id_, channel_id_);
+ configuration.audio = false; // Video.
+ configuration.default_module = default_rtp_rtcp_;
+ configuration.outgoing_transport = &vie_sender_;
+ configuration.intra_frame_callback = intra_frame_observer_;
+ configuration.bandwidth_callback = bandwidth_observer_.get();
+ configuration.rtt_stats = rtt_stats_;
+ configuration.paced_sender = paced_sender_;
+
+ return RtpRtcp::CreateRtpRtcp(configuration);
+}
+
int32_t ViEChannel::StartDecodeThread() {
// Start the decode thread
if (decode_thread_) {
diff --git a/webrtc/video_engine/vie_channel.h b/webrtc/video_engine/vie_channel.h
index 23b7e5e..c76d129 100644
--- a/webrtc/video_engine/vie_channel.h
+++ b/webrtc/video_engine/vie_channel.h
@@ -362,6 +362,11 @@
void OnRttUpdate(uint32_t rtt);
private:
+ void ReserveRtpRtcpModules(size_t total_modules)
+ EXCLUSIVE_LOCKS_REQUIRED(rtp_rtcp_cs_);
+ RtpRtcp* GetRtpRtcpModule(size_t simulcast_idx) const
+ EXCLUSIVE_LOCKS_REQUIRED(rtp_rtcp_cs_);
+ RtpRtcp* CreateRtpRtcpModule();
// Assumed to be protected.
int32_t StartDecodeThread();
int32_t StopDecodeThread();