2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
13 * This file includes unit tests for the RTCPSender.
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
19 #include "webrtc/common_types.h"
20 #include "webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_observer.h"
21 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
22 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
23 #include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
24 #include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
25 #include "webrtc/modules/rtp_rtcp/source/rtcp_receiver.h"
26 #include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h"
27 #include "webrtc/modules/rtp_rtcp/source/rtp_receiver_video.h"
28 #include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
29 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
33 TEST(NACKStringBuilderTest, TestCase1) {
34 NACKStringBuilder builder;
44 EXPECT_EQ(std::string("5,7,9-12,15,18-19"), builder.GetResult());
47 TEST(NACKStringBuilderTest, TestCase2) {
48 NACKStringBuilder builder;
59 EXPECT_EQ(std::string("5-7,9-12,15,18-19"), builder.GetResult());
62 TEST(NACKStringBuilderTest, TestCase3) {
63 NACKStringBuilder builder;
74 EXPECT_EQ(std::string("5,7,9-12,15,18-19,21"), builder.GetResult());
77 TEST(NACKStringBuilderTest, TestCase4) {
78 NACKStringBuilder builder;
89 EXPECT_EQ(std::string("5,7-12,15,18-19"), builder.GetResult());
92 TEST(NACKStringBuilderTest, TestCase5) {
93 NACKStringBuilder builder;
100 builder.PushNACK(15);
101 builder.PushNACK(16);
102 builder.PushNACK(18);
103 builder.PushNACK(19);
104 EXPECT_EQ(std::string("5,7,9-12,15-16,18-19"), builder.GetResult());
107 TEST(NACKStringBuilderTest, TestCase6) {
108 NACKStringBuilder builder;
112 builder.PushNACK(10);
113 builder.PushNACK(11);
114 builder.PushNACK(12);
115 builder.PushNACK(15);
116 builder.PushNACK(16);
117 builder.PushNACK(17);
118 builder.PushNACK(18);
119 builder.PushNACK(19);
120 EXPECT_EQ(std::string("5,7,9-12,15-19"), builder.GetResult());
123 TEST(NACKStringBuilderTest, TestCase7) {
124 NACKStringBuilder builder;
129 builder.PushNACK(11);
130 builder.PushNACK(12);
131 builder.PushNACK(13);
132 builder.PushNACK(14);
133 builder.PushNACK(15);
134 EXPECT_EQ(std::string("5-8,11-15"), builder.GetResult());
137 TEST(NACKStringBuilderTest, TestCase8) {
138 NACKStringBuilder builder;
142 builder.PushNACK(11);
143 builder.PushNACK(15);
144 builder.PushNACK(17);
145 builder.PushNACK(19);
146 EXPECT_EQ(std::string("5,7,9,11,15,17,19"), builder.GetResult());
149 TEST(NACKStringBuilderTest, TestCase9) {
150 NACKStringBuilder builder;
156 builder.PushNACK(10);
157 builder.PushNACK(11);
158 builder.PushNACK(12);
159 EXPECT_EQ(std::string("5-12"), builder.GetResult());
162 TEST(NACKStringBuilderTest, TestCase10) {
163 NACKStringBuilder builder;
165 EXPECT_EQ(std::string("5"), builder.GetResult());
168 TEST(NACKStringBuilderTest, TestCase11) {
169 NACKStringBuilder builder;
170 EXPECT_EQ(std::string(""), builder.GetResult());
173 TEST(NACKStringBuilderTest, TestCase12) {
174 NACKStringBuilder builder;
177 EXPECT_EQ(std::string("5-6"), builder.GetResult());
180 TEST(NACKStringBuilderTest, TestCase13) {
181 NACKStringBuilder builder;
185 EXPECT_EQ(std::string("5-6,9"), builder.GetResult());
188 void CreateRtpPacket(const bool marker_bit, const uint8_t payload,
189 const uint16_t seq_num, const uint32_t timestamp,
190 const uint32_t ssrc, uint8_t* array,
192 ASSERT_TRUE(payload <= 127);
193 array[(*cur_pos)++] = 0x80;
194 array[(*cur_pos)++] = payload | (marker_bit ? 0x80 : 0);
195 array[(*cur_pos)++] = seq_num >> 8;
196 array[(*cur_pos)++] = seq_num;
197 array[(*cur_pos)++] = timestamp >> 24;
198 array[(*cur_pos)++] = timestamp >> 16;
199 array[(*cur_pos)++] = timestamp >> 8;
200 array[(*cur_pos)++] = timestamp;
201 array[(*cur_pos)++] = ssrc >> 24;
202 array[(*cur_pos)++] = ssrc >> 16;
203 array[(*cur_pos)++] = ssrc >> 8;
204 array[(*cur_pos)++] = ssrc;
205 // VP8 payload header
206 array[(*cur_pos)++] = 0x90; // X bit = 1
207 array[(*cur_pos)++] = 0x20; // T bit = 1
208 array[(*cur_pos)++] = 0x00; // TID = 0
209 array[(*cur_pos)++] = 0x00; // Key frame
210 array[(*cur_pos)++] = 0x00;
211 array[(*cur_pos)++] = 0x00;
212 array[(*cur_pos)++] = 0x9d;
213 array[(*cur_pos)++] = 0x01;
214 array[(*cur_pos)++] = 0x2a;
215 array[(*cur_pos)++] = 128;
216 array[(*cur_pos)++] = 0;
217 array[(*cur_pos)++] = 96;
218 array[(*cur_pos)++] = 0;
221 class TestTransport : public Transport,
225 : rtcp_receiver_(NULL) {
227 void SetRTCPReceiver(RTCPReceiver* rtcp_receiver) {
228 rtcp_receiver_ = rtcp_receiver;
230 virtual int SendPacket(int /*ch*/,
231 const void* /*data*/,
232 int /*len*/) OVERRIDE {
236 virtual int SendRTCPPacket(int /*ch*/,
238 int packet_len) OVERRIDE {
239 RTCPUtility::RTCPParserV2 rtcpParser((uint8_t*)packet,
241 true); // Allow non-compound RTCP
243 EXPECT_TRUE(rtcpParser.IsValid());
244 RTCPHelp::RTCPPacketInformation rtcpPacketInformation;
245 EXPECT_EQ(0, rtcp_receiver_->IncomingRTCPPacket(rtcpPacketInformation,
247 rtcp_packet_info_.rtcpPacketTypeFlags =
248 rtcpPacketInformation.rtcpPacketTypeFlags;
249 rtcp_packet_info_.remoteSSRC = rtcpPacketInformation.remoteSSRC;
250 rtcp_packet_info_.applicationSubType =
251 rtcpPacketInformation.applicationSubType;
252 rtcp_packet_info_.applicationName = rtcpPacketInformation.applicationName;
253 rtcp_packet_info_.report_blocks = rtcpPacketInformation.report_blocks;
254 rtcp_packet_info_.rtt = rtcpPacketInformation.rtt;
255 rtcp_packet_info_.interArrivalJitter =
256 rtcpPacketInformation.interArrivalJitter;
257 rtcp_packet_info_.sliPictureId = rtcpPacketInformation.sliPictureId;
258 rtcp_packet_info_.rpsiPictureId = rtcpPacketInformation.rpsiPictureId;
259 rtcp_packet_info_.receiverEstimatedMaxBitrate =
260 rtcpPacketInformation.receiverEstimatedMaxBitrate;
261 rtcp_packet_info_.ntp_secs = rtcpPacketInformation.ntp_secs;
262 rtcp_packet_info_.ntp_frac = rtcpPacketInformation.ntp_frac;
263 rtcp_packet_info_.rtp_timestamp = rtcpPacketInformation.rtp_timestamp;
268 virtual int OnReceivedPayloadData(const uint8_t* payloadData,
269 const uint16_t payloadSize,
270 const WebRtcRTPHeader* rtpHeader) OVERRIDE {
273 RTCPReceiver* rtcp_receiver_;
274 RTCPHelp::RTCPPacketInformation rtcp_packet_info_;
277 class RtcpSenderTest : public ::testing::Test {
279 static const uint32_t kRemoteBitrateEstimatorMinBitrateBps = 30000;
282 : over_use_detector_options_(),
284 rtp_payload_registry_(new RTPPayloadRegistry(
285 RTPPayloadStrategy::CreateStrategy(false))),
286 remote_bitrate_observer_(),
287 remote_bitrate_estimator_(
288 RemoteBitrateEstimatorFactory().Create(
289 &remote_bitrate_observer_,
292 kRemoteBitrateEstimatorMinBitrateBps)),
293 receive_statistics_(ReceiveStatistics::Create(&clock_)) {
294 test_transport_ = new TestTransport();
296 RtpRtcp::Configuration configuration;
297 configuration.id = 0;
298 configuration.audio = false;
299 configuration.clock = &clock_;
300 configuration.outgoing_transport = test_transport_;
301 configuration.remote_bitrate_estimator = remote_bitrate_estimator_.get();
303 rtp_rtcp_impl_ = new ModuleRtpRtcpImpl(configuration);
304 rtp_receiver_.reset(RtpReceiver::CreateVideoReceiver(
305 0, &clock_, test_transport_, NULL, rtp_payload_registry_.get()));
307 new RTCPSender(0, false, &clock_, receive_statistics_.get());
308 rtcp_receiver_ = new RTCPReceiver(0, &clock_, rtp_rtcp_impl_);
309 test_transport_->SetRTCPReceiver(rtcp_receiver_);
311 EXPECT_EQ(0, rtcp_sender_->RegisterSendTransport(test_transport_));
315 delete rtcp_receiver_;
316 delete rtp_rtcp_impl_;
317 delete test_transport_;
320 // Helper function: Incoming RTCP has a specific packet type.
321 bool gotPacketType(RTCPPacketType packet_type) {
322 return ((test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags) &
326 OverUseDetectorOptions over_use_detector_options_;
327 SimulatedClock clock_;
328 scoped_ptr<RTPPayloadRegistry> rtp_payload_registry_;
329 scoped_ptr<RtpReceiver> rtp_receiver_;
330 ModuleRtpRtcpImpl* rtp_rtcp_impl_;
331 RTCPSender* rtcp_sender_;
332 RTCPReceiver* rtcp_receiver_;
333 TestTransport* test_transport_;
334 MockRemoteBitrateObserver remote_bitrate_observer_;
335 scoped_ptr<RemoteBitrateEstimator> remote_bitrate_estimator_;
336 scoped_ptr<ReceiveStatistics> receive_statistics_;
338 enum {kMaxPacketLength = 1500};
339 uint8_t packet_[kMaxPacketLength];
342 TEST_F(RtcpSenderTest, RtcpOff) {
343 EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpOff));
344 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
345 EXPECT_EQ(-1, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr));
348 TEST_F(RtcpSenderTest, IJStatus) {
349 ASSERT_FALSE(rtcp_sender_->IJ());
350 EXPECT_EQ(0, rtcp_sender_->SetIJStatus(true));
351 ASSERT_TRUE(rtcp_sender_->IJ());
354 TEST_F(RtcpSenderTest, TestCompound) {
355 const bool marker_bit = false;
356 const uint8_t payload = 100;
357 const uint16_t seq_num = 11111;
358 const uint32_t timestamp = 1234567;
359 const uint32_t ssrc = 0x11111111;
360 uint16_t packet_length = 0;
361 CreateRtpPacket(marker_bit, payload, seq_num, timestamp, ssrc, packet_,
363 EXPECT_EQ(25, packet_length);
365 VideoCodec codec_inst;
366 strncpy(codec_inst.plName, "VP8", webrtc::kPayloadNameSize - 1);
367 codec_inst.codecType = webrtc::kVideoCodecVP8;
368 codec_inst.plType = payload;
369 EXPECT_EQ(0, rtp_receiver_->RegisterReceivePayload(codec_inst.plName,
373 codec_inst.maxBitrate));
375 // Make sure RTP packet has been received.
376 scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
378 EXPECT_TRUE(parser->Parse(packet_, packet_length, &header));
379 PayloadUnion payload_specific;
380 EXPECT_TRUE(rtp_payload_registry_->GetPayloadSpecifics(header.payloadType,
382 receive_statistics_->IncomingPacket(header, packet_length, false);
383 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(header, packet_, packet_length,
384 payload_specific, true));
386 EXPECT_EQ(0, rtcp_sender_->SetIJStatus(true));
387 EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound));
388 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
389 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpRr));
391 // Transmission time offset packet should be received.
392 ASSERT_TRUE(test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags &
393 kRtcpTransmissionTimeOffset);
396 TEST_F(RtcpSenderTest, TestCompound_NoRtpReceived) {
397 EXPECT_EQ(0, rtcp_sender_->SetIJStatus(true));
398 EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound));
399 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
400 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpRr));
402 // Transmission time offset packet should not be received.
403 ASSERT_FALSE(test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags &
404 kRtcpTransmissionTimeOffset);
407 TEST_F(RtcpSenderTest, TestXrReceiverReferenceTime) {
408 EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound));
409 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
410 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state, false));
411 rtcp_sender_->SendRtcpXrReceiverReferenceTime(true);
412 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport));
414 EXPECT_TRUE(test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags &
415 kRtcpXrReceiverReferenceTime);
418 TEST_F(RtcpSenderTest, TestNoXrReceiverReferenceTimeIfSending) {
419 EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound));
420 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
421 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state, true));
422 rtcp_sender_->SendRtcpXrReceiverReferenceTime(true);
423 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport));
425 EXPECT_FALSE(test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags &
426 kRtcpXrReceiverReferenceTime);
429 TEST_F(RtcpSenderTest, TestNoXrReceiverReferenceTimeIfNotEnabled) {
430 EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound));
431 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
432 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state, false));
433 rtcp_sender_->SendRtcpXrReceiverReferenceTime(false);
434 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport));
436 EXPECT_FALSE(test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags &
437 kRtcpXrReceiverReferenceTime);
440 TEST_F(RtcpSenderTest, TestSendTimeOfXrRrReport) {
441 EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound));
442 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
443 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state, false));
444 rtcp_sender_->SendRtcpXrReceiverReferenceTime(true);
447 clock_.CurrentNtp(ntp_sec, ntp_frac);
448 uint32_t initial_mid_ntp = RTCPUtility::MidNtp(ntp_sec, ntp_frac);
452 EXPECT_FALSE(rtcp_sender_->SendTimeOfXrRrReport(initial_mid_ntp, &time_ms));
454 // Send XR RR packets.
455 for (int i = 0; i <= RTCP_NUMBER_OF_SR; ++i) {
456 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport));
457 EXPECT_TRUE(test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags &
458 kRtcpXrReceiverReferenceTime);
460 clock_.CurrentNtp(ntp_sec, ntp_frac);
461 uint32_t mid_ntp = RTCPUtility::MidNtp(ntp_sec, ntp_frac);
462 EXPECT_TRUE(rtcp_sender_->SendTimeOfXrRrReport(mid_ntp, &time_ms));
463 EXPECT_EQ(clock_.CurrentNtpInMilliseconds(), time_ms);
464 clock_.AdvanceTimeMilliseconds(1000);
467 // The first report should no longer be stored.
468 EXPECT_FALSE(rtcp_sender_->SendTimeOfXrRrReport(initial_mid_ntp, &time_ms));
471 // This test is written to verify actual behaviour. It does not seem
472 // to make much sense to send an empty TMMBN, since there is no place
473 // to put an actual limit here. It's just information that no limit
474 // is set, which is kind of the starting assumption.
475 // See http://code.google.com/p/webrtc/issues/detail?id=468 for one
476 // situation where this caused confusion.
477 TEST_F(RtcpSenderTest, SendsTmmbnIfSetAndEmpty) {
478 EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound));
479 TMMBRSet bounding_set;
480 EXPECT_EQ(0, rtcp_sender_->SetTMMBN(&bounding_set, 3));
481 ASSERT_EQ(0U, test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags);
482 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
483 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state,kRtcpSr));
484 // We now expect the packet to show up in the rtcp_packet_info_ of
486 ASSERT_NE(0U, test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags);
487 EXPECT_TRUE(gotPacketType(kRtcpTmmbn));
488 TMMBRSet* incoming_set = NULL;
490 // The BoundingSet function returns the number of members of the
491 // bounding set, and touches the incoming set only if there's > 1.
492 EXPECT_EQ(0, test_transport_->rtcp_receiver_->BoundingSet(owner,
496 TEST_F(RtcpSenderTest, SendsTmmbnIfSetAndValid) {
497 EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound));
498 TMMBRSet bounding_set;
499 bounding_set.VerifyAndAllocateSet(1);
500 const uint32_t kSourceSsrc = 12345;
501 bounding_set.AddEntry(32768, 0, kSourceSsrc);
503 EXPECT_EQ(0, rtcp_sender_->SetTMMBN(&bounding_set, 3));
504 ASSERT_EQ(0U, test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags);
505 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
506 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr));
507 // We now expect the packet to show up in the rtcp_packet_info_ of
509 ASSERT_NE(0U, test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags);
510 EXPECT_TRUE(gotPacketType(kRtcpTmmbn));
511 TMMBRSet incoming_set;
513 // We expect 1 member of the incoming set.
514 EXPECT_EQ(1, test_transport_->rtcp_receiver_->BoundingSet(owner,
516 EXPECT_EQ(kSourceSsrc, incoming_set.Ssrc(0));
518 } // namespace webrtc