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
This commit is contained in:
pbos@webrtc.org 2014-06-30 13:19:09 +00:00
parent cd9b90ab53
commit be9d2a4549
10 changed files with 362 additions and 340 deletions

View File

@ -16,7 +16,6 @@ namespace test {
CallTest::CallTest()
: send_stream_(NULL),
receive_stream_(NULL),
fake_encoder_(Clock::GetRealTimeClock()) {
}
CallTest::~CallTest() {
@ -39,9 +38,9 @@ void CallTest::RunBaseTest(BaseTest* test) {
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::RunBaseTest(BaseTest* test) {
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 @@ void CallTest::CreateSendConfig(size_t num_streams) {
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);
}
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);
}
receive_config_.rtp.remote_ssrc = send_config_.rtp.ssrcs[0];
receive_config_.rtp.local_ssrc = kReceiverLocalSsrc;
}
void CallTest::CreateFrameGeneratorCapturer() {
@ -121,22 +125,24 @@ void CallTest::CreateFrameGeneratorCapturer() {
}
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 @@ size_t BaseTest::GetNumStreams() const {
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(

View File

@ -64,8 +64,8 @@ class CallTest : public ::testing::Test {
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 @@ class BaseTest : public RtpRtcpObserver {
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);

View File

@ -254,8 +254,8 @@ TEST_F(CallPerfTest, PlaysOutAudioAndVideoInSync) {
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 @@ void CallPerfTest::TestCaptureNtpTime(const FakeNetworkPipe::Config& net_config,
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 @@ void CallPerfTest::TestMinTransmitBitrate(bool pad_to_min_bitrate) {
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;

View File

@ -49,39 +49,15 @@ class EndToEndTest : public test::CallTest {
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 @@ TEST_F(EndToEndTest, ReceiverCanBeStartedTwice) {
CreateStreams();
receive_stream_->Start();
receive_stream_->Start();
receive_streams_[0]->Start();
receive_streams_[0]->Start();
DestroyStreams();
}
@ -108,8 +84,8 @@ TEST_F(EndToEndTest, ReceiverCanBeStoppedTwice) {
CreateStreams();
receive_stream_->Stop();
receive_stream_->Stop();
receive_streams_[0]->Stop();
receive_streams_[0]->Stop();
DestroyStreams();
}
@ -163,11 +139,11 @@ TEST_F(EndToEndTest, RendersSingleDelayedFrame) {
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 @@ TEST_F(EndToEndTest, RendersSingleDelayedFrame) {
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 @@ TEST_F(EndToEndTest, TransmitsFirstFrame) {
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 @@ TEST_F(EndToEndTest, TransmitsFirstFrame) {
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 @@ TEST_F(EndToEndTest, ReceivesAndRetransmitsNack) {
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 @@ TEST_F(EndToEndTest, DISABLED_CanReceiveFec) {
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 @@ void EndToEndTest::DecodesRetransmittedFrame(bool retransmit_over_rtx) {
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 @@ TEST_F(EndToEndTest, UsesFrameCallbacks) {
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 @@ TEST_F(EndToEndTest, UsesFrameCallbacks) {
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 @@ void EndToEndTest::ReceivesPliAndRecovers(int rtp_history_ms) {
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 @@ TEST_F(EndToEndTest, UnknownRtpPacketGivesUnknownSsrcReturnCode) {
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 @@ void EndToEndTest::RespectsRtcpMode(newapi::RtcpMode rtcp_mode) {
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 @@ TEST_F(EndToEndTest, ObserversEncodedFrames) {
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 @@ TEST_F(EndToEndTest, ObserversEncodedFrames) {
post_encode_observer.ExpectEqualFrames(pre_decode_observer);
StopSending();
Stop();
sender_transport.StopSending();
receiver_transport.StopSending();
@ -1170,10 +1146,11 @@ void EndToEndTest::TestXrReceiverReferenceTimeReport(bool enable_rrtr) {
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 @@ void EndToEndTest::TestXrReceiverReferenceTimeReport(bool enable_rrtr) {
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 @@ TEST_F(EndToEndTest, GetStats) {
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 @@ TEST_F(EndToEndTest, GetStats) {
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 @@ TEST_F(EndToEndTest, TestReceivedRtpPacketStats) {
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 @@ TEST_F(EndToEndTest, TestReceivedRtpPacketStats) {
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

View File

@ -396,7 +396,7 @@ void FullStackTest::TestWithoutPacketLoss(const FullStackTestParams& params) {
stream->max_framerate = params.clip.fps;
CreateMatchingReceiveConfigs();
receive_config_.renderer = &analyzer;
receive_configs_[0].renderer = &analyzer;
CreateStreams();
analyzer.input_ = send_stream_->Input();

View File

@ -173,6 +173,8 @@ VideoSendStream::VideoSendStream(newapi::Transport* transport,
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 @@ bool VideoSendStream::ReconfigureVideoEncoder(
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 @@ std::string VideoSendStream::GetCName() {
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

View File

@ -71,6 +71,7 @@ class VideoSendStream : public webrtc::VideoSendStream,
virtual std::string GetCName() OVERRIDE;
private:
void ConfigureSsrcs();
TransportAdapter transport_adapter_;
EncodedFrameCallbackAdapter encoded_frame_proxy_;
const VideoSendStream::Config config_;

View File

@ -60,113 +60,8 @@ class VideoSendStreamTest : public test::CallTest {
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 @@ TEST_F(VideoSendStreamTest, CanStopStoppedStream) {
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 @@ TEST_F(VideoSendStreamTest, SupportsCName) {
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 @@ TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) {
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 @@ TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
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 @@ TEST_F(VideoSendStreamTest, SupportsFec) {
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 @@ void VideoSendStreamTest::TestNackRetransmission(
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 @@ void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
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 @@ TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) {
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 @@ TEST_F(VideoSendStreamTest, ProducesStats) {
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 @@ TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
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 @@ TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
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;
}

View File

@ -244,31 +244,25 @@ int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec,
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 @@ int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec,
}
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::EnableKeyFrameRequestCallback(const bool enable) {
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::SetRemoteSSRCType(const StreamType usage,
}
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 @@ void ViEChannel::OnRttUpdate(uint32_t rtt) {
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_) {

View File

@ -362,6 +362,11 @@ class ViEChannel
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();