1 /* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 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. 9 */ 10 11 12 /* 13 * This file includes unit tests for the RTCPSender. 14 */ 15 16 #include "testing/gmock/include/gmock/gmock.h" 17 #include "testing/gtest/include/gtest/gtest.h" 18 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" 30 31 namespace webrtc { 32 33 TEST(NACKStringBuilderTest, TestCase1) { 34 NACKStringBuilder builder; 35 builder.PushNACK(5); 36 builder.PushNACK(7); 37 builder.PushNACK(9); 38 builder.PushNACK(10); 39 builder.PushNACK(11); 40 builder.PushNACK(12); 41 builder.PushNACK(15); 42 builder.PushNACK(18); 43 builder.PushNACK(19); 44 EXPECT_EQ(std::string("5,7,9-12,15,18-19"), builder.GetResult()); 45 } 46 47 TEST(NACKStringBuilderTest, TestCase2) { 48 NACKStringBuilder builder; 49 builder.PushNACK(5); 50 builder.PushNACK(6); 51 builder.PushNACK(7); 52 builder.PushNACK(9); 53 builder.PushNACK(10); 54 builder.PushNACK(11); 55 builder.PushNACK(12); 56 builder.PushNACK(15); 57 builder.PushNACK(18); 58 builder.PushNACK(19); 59 EXPECT_EQ(std::string("5-7,9-12,15,18-19"), builder.GetResult()); 60 } 61 62 TEST(NACKStringBuilderTest, TestCase3) { 63 NACKStringBuilder builder; 64 builder.PushNACK(5); 65 builder.PushNACK(7); 66 builder.PushNACK(9); 67 builder.PushNACK(10); 68 builder.PushNACK(11); 69 builder.PushNACK(12); 70 builder.PushNACK(15); 71 builder.PushNACK(18); 72 builder.PushNACK(19); 73 builder.PushNACK(21); 74 EXPECT_EQ(std::string("5,7,9-12,15,18-19,21"), builder.GetResult()); 75 } 76 77 TEST(NACKStringBuilderTest, TestCase4) { 78 NACKStringBuilder builder; 79 builder.PushNACK(5); 80 builder.PushNACK(7); 81 builder.PushNACK(8); 82 builder.PushNACK(9); 83 builder.PushNACK(10); 84 builder.PushNACK(11); 85 builder.PushNACK(12); 86 builder.PushNACK(15); 87 builder.PushNACK(18); 88 builder.PushNACK(19); 89 EXPECT_EQ(std::string("5,7-12,15,18-19"), builder.GetResult()); 90 } 91 92 TEST(NACKStringBuilderTest, TestCase5) { 93 NACKStringBuilder builder; 94 builder.PushNACK(5); 95 builder.PushNACK(7); 96 builder.PushNACK(9); 97 builder.PushNACK(10); 98 builder.PushNACK(11); 99 builder.PushNACK(12); 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()); 105 } 106 107 TEST(NACKStringBuilderTest, TestCase6) { 108 NACKStringBuilder builder; 109 builder.PushNACK(5); 110 builder.PushNACK(7); 111 builder.PushNACK(9); 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()); 121 } 122 123 TEST(NACKStringBuilderTest, TestCase7) { 124 NACKStringBuilder builder; 125 builder.PushNACK(5); 126 builder.PushNACK(6); 127 builder.PushNACK(7); 128 builder.PushNACK(8); 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()); 135 } 136 137 TEST(NACKStringBuilderTest, TestCase8) { 138 NACKStringBuilder builder; 139 builder.PushNACK(5); 140 builder.PushNACK(7); 141 builder.PushNACK(9); 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()); 147 } 148 149 TEST(NACKStringBuilderTest, TestCase9) { 150 NACKStringBuilder builder; 151 builder.PushNACK(5); 152 builder.PushNACK(6); 153 builder.PushNACK(7); 154 builder.PushNACK(8); 155 builder.PushNACK(9); 156 builder.PushNACK(10); 157 builder.PushNACK(11); 158 builder.PushNACK(12); 159 EXPECT_EQ(std::string("5-12"), builder.GetResult()); 160 } 161 162 TEST(NACKStringBuilderTest, TestCase10) { 163 NACKStringBuilder builder; 164 builder.PushNACK(5); 165 EXPECT_EQ(std::string("5"), builder.GetResult()); 166 } 167 168 TEST(NACKStringBuilderTest, TestCase11) { 169 NACKStringBuilder builder; 170 EXPECT_EQ(std::string(""), builder.GetResult()); 171 } 172 173 TEST(NACKStringBuilderTest, TestCase12) { 174 NACKStringBuilder builder; 175 builder.PushNACK(5); 176 builder.PushNACK(6); 177 EXPECT_EQ(std::string("5-6"), builder.GetResult()); 178 } 179 180 TEST(NACKStringBuilderTest, TestCase13) { 181 NACKStringBuilder builder; 182 builder.PushNACK(5); 183 builder.PushNACK(6); 184 builder.PushNACK(9); 185 EXPECT_EQ(std::string("5-6,9"), builder.GetResult()); 186 } 187 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, 191 uint16_t* cur_pos) { 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; 219 } 220 221 class TestTransport : public Transport, 222 public NullRtpData { 223 public: 224 TestTransport() 225 : rtcp_receiver_(NULL) { 226 } 227 void SetRTCPReceiver(RTCPReceiver* rtcp_receiver) { 228 rtcp_receiver_ = rtcp_receiver; 229 } 230 virtual int SendPacket(int /*ch*/, const void* /*data*/, int /*len*/) { 231 return -1; 232 } 233 234 virtual int SendRTCPPacket(int /*ch*/, const void *packet, int packet_len) { 235 RTCPUtility::RTCPParserV2 rtcpParser((uint8_t*)packet, 236 (int32_t)packet_len, 237 true); // Allow non-compound RTCP 238 239 EXPECT_TRUE(rtcpParser.IsValid()); 240 RTCPHelp::RTCPPacketInformation rtcpPacketInformation; 241 EXPECT_EQ(0, rtcp_receiver_->IncomingRTCPPacket(rtcpPacketInformation, 242 &rtcpParser)); 243 rtcp_packet_info_.rtcpPacketTypeFlags = 244 rtcpPacketInformation.rtcpPacketTypeFlags; 245 rtcp_packet_info_.remoteSSRC = rtcpPacketInformation.remoteSSRC; 246 rtcp_packet_info_.applicationSubType = 247 rtcpPacketInformation.applicationSubType; 248 rtcp_packet_info_.applicationName = rtcpPacketInformation.applicationName; 249 rtcp_packet_info_.report_blocks = rtcpPacketInformation.report_blocks; 250 rtcp_packet_info_.rtt = rtcpPacketInformation.rtt; 251 rtcp_packet_info_.interArrivalJitter = 252 rtcpPacketInformation.interArrivalJitter; 253 rtcp_packet_info_.sliPictureId = rtcpPacketInformation.sliPictureId; 254 rtcp_packet_info_.rpsiPictureId = rtcpPacketInformation.rpsiPictureId; 255 rtcp_packet_info_.receiverEstimatedMaxBitrate = 256 rtcpPacketInformation.receiverEstimatedMaxBitrate; 257 rtcp_packet_info_.ntp_secs = rtcpPacketInformation.ntp_secs; 258 rtcp_packet_info_.ntp_frac = rtcpPacketInformation.ntp_frac; 259 rtcp_packet_info_.rtp_timestamp = rtcpPacketInformation.rtp_timestamp; 260 261 return packet_len; 262 } 263 264 virtual int OnReceivedPayloadData(const uint8_t* payloadData, 265 const uint16_t payloadSize, 266 const WebRtcRTPHeader* rtpHeader) { 267 return 0; 268 } 269 RTCPReceiver* rtcp_receiver_; 270 RTCPHelp::RTCPPacketInformation rtcp_packet_info_; 271 }; 272 273 class RtcpSenderTest : public ::testing::Test { 274 protected: 275 static const uint32_t kRemoteBitrateEstimatorMinBitrateBps = 30000; 276 277 RtcpSenderTest() 278 : over_use_detector_options_(), 279 clock_(1335900000), 280 rtp_payload_registry_(new RTPPayloadRegistry( 281 RTPPayloadStrategy::CreateStrategy(false))), 282 remote_bitrate_observer_(), 283 remote_bitrate_estimator_( 284 RemoteBitrateEstimatorFactory().Create( 285 &remote_bitrate_observer_, 286 &clock_, 287 kMimdControl, 288 kRemoteBitrateEstimatorMinBitrateBps)), 289 receive_statistics_(ReceiveStatistics::Create(&clock_)) { 290 test_transport_ = new TestTransport(); 291 292 RtpRtcp::Configuration configuration; 293 configuration.id = 0; 294 configuration.audio = false; 295 configuration.clock = &clock_; 296 configuration.outgoing_transport = test_transport_; 297 configuration.remote_bitrate_estimator = remote_bitrate_estimator_.get(); 298 299 rtp_rtcp_impl_ = new ModuleRtpRtcpImpl(configuration); 300 rtp_receiver_.reset(RtpReceiver::CreateVideoReceiver( 301 0, &clock_, test_transport_, NULL, rtp_payload_registry_.get())); 302 rtcp_sender_ = 303 new RTCPSender(0, false, &clock_, receive_statistics_.get()); 304 rtcp_receiver_ = new RTCPReceiver(0, &clock_, rtp_rtcp_impl_); 305 test_transport_->SetRTCPReceiver(rtcp_receiver_); 306 // Initialize 307 EXPECT_EQ(0, rtcp_sender_->RegisterSendTransport(test_transport_)); 308 } 309 ~RtcpSenderTest() { 310 delete rtcp_sender_; 311 delete rtcp_receiver_; 312 delete rtp_rtcp_impl_; 313 delete test_transport_; 314 } 315 316 // Helper function: Incoming RTCP has a specific packet type. 317 bool gotPacketType(RTCPPacketType packet_type) { 318 return ((test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags) & 319 packet_type) != 0U; 320 } 321 322 OverUseDetectorOptions over_use_detector_options_; 323 SimulatedClock clock_; 324 scoped_ptr<RTPPayloadRegistry> rtp_payload_registry_; 325 scoped_ptr<RtpReceiver> rtp_receiver_; 326 ModuleRtpRtcpImpl* rtp_rtcp_impl_; 327 RTCPSender* rtcp_sender_; 328 RTCPReceiver* rtcp_receiver_; 329 TestTransport* test_transport_; 330 MockRemoteBitrateObserver remote_bitrate_observer_; 331 scoped_ptr<RemoteBitrateEstimator> remote_bitrate_estimator_; 332 scoped_ptr<ReceiveStatistics> receive_statistics_; 333 334 enum {kMaxPacketLength = 1500}; 335 uint8_t packet_[kMaxPacketLength]; 336 }; 337 338 TEST_F(RtcpSenderTest, RtcpOff) { 339 EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpOff)); 340 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState(); 341 EXPECT_EQ(-1, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr)); 342 } 343 344 TEST_F(RtcpSenderTest, IJStatus) { 345 ASSERT_FALSE(rtcp_sender_->IJ()); 346 EXPECT_EQ(0, rtcp_sender_->SetIJStatus(true)); 347 ASSERT_TRUE(rtcp_sender_->IJ()); 348 } 349 350 TEST_F(RtcpSenderTest, TestCompound) { 351 const bool marker_bit = false; 352 const uint8_t payload = 100; 353 const uint16_t seq_num = 11111; 354 const uint32_t timestamp = 1234567; 355 const uint32_t ssrc = 0x11111111; 356 uint16_t packet_length = 0; 357 CreateRtpPacket(marker_bit, payload, seq_num, timestamp, ssrc, packet_, 358 &packet_length); 359 EXPECT_EQ(25, packet_length); 360 361 VideoCodec codec_inst; 362 strncpy(codec_inst.plName, "VP8", webrtc::kPayloadNameSize - 1); 363 codec_inst.codecType = webrtc::kVideoCodecVP8; 364 codec_inst.plType = payload; 365 EXPECT_EQ(0, rtp_receiver_->RegisterReceivePayload(codec_inst.plName, 366 codec_inst.plType, 367 90000, 368 0, 369 codec_inst.maxBitrate)); 370 371 // Make sure RTP packet has been received. 372 scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create()); 373 RTPHeader header; 374 EXPECT_TRUE(parser->Parse(packet_, packet_length, &header)); 375 PayloadUnion payload_specific; 376 EXPECT_TRUE(rtp_payload_registry_->GetPayloadSpecifics(header.payloadType, 377 &payload_specific)); 378 receive_statistics_->IncomingPacket(header, packet_length, false); 379 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(header, packet_, packet_length, 380 payload_specific, true)); 381 382 EXPECT_EQ(0, rtcp_sender_->SetIJStatus(true)); 383 EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound)); 384 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState(); 385 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpRr)); 386 387 // Transmission time offset packet should be received. 388 ASSERT_TRUE(test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags & 389 kRtcpTransmissionTimeOffset); 390 } 391 392 TEST_F(RtcpSenderTest, TestCompound_NoRtpReceived) { 393 EXPECT_EQ(0, rtcp_sender_->SetIJStatus(true)); 394 EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound)); 395 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState(); 396 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpRr)); 397 398 // Transmission time offset packet should not be received. 399 ASSERT_FALSE(test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags & 400 kRtcpTransmissionTimeOffset); 401 } 402 403 TEST_F(RtcpSenderTest, TestXrReceiverReferenceTime) { 404 EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound)); 405 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState(); 406 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state, false)); 407 rtcp_sender_->SendRtcpXrReceiverReferenceTime(true); 408 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport)); 409 410 EXPECT_TRUE(test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags & 411 kRtcpXrReceiverReferenceTime); 412 } 413 414 TEST_F(RtcpSenderTest, TestNoXrReceiverReferenceTimeIfSending) { 415 EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound)); 416 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState(); 417 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state, true)); 418 rtcp_sender_->SendRtcpXrReceiverReferenceTime(true); 419 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport)); 420 421 EXPECT_FALSE(test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags & 422 kRtcpXrReceiverReferenceTime); 423 } 424 425 TEST_F(RtcpSenderTest, TestNoXrReceiverReferenceTimeIfNotEnabled) { 426 EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound)); 427 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState(); 428 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state, false)); 429 rtcp_sender_->SendRtcpXrReceiverReferenceTime(false); 430 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport)); 431 432 EXPECT_FALSE(test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags & 433 kRtcpXrReceiverReferenceTime); 434 } 435 436 TEST_F(RtcpSenderTest, TestSendTimeOfXrRrReport) { 437 EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound)); 438 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState(); 439 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state, false)); 440 rtcp_sender_->SendRtcpXrReceiverReferenceTime(true); 441 uint32_t ntp_sec; 442 uint32_t ntp_frac; 443 clock_.CurrentNtp(ntp_sec, ntp_frac); 444 uint32_t initial_mid_ntp = RTCPUtility::MidNtp(ntp_sec, ntp_frac); 445 446 // No packet sent. 447 int64_t time_ms; 448 EXPECT_FALSE(rtcp_sender_->SendTimeOfXrRrReport(initial_mid_ntp, &time_ms)); 449 450 // Send XR RR packets. 451 for (int i = 0; i <= RTCP_NUMBER_OF_SR; ++i) { 452 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport)); 453 EXPECT_TRUE(test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags & 454 kRtcpXrReceiverReferenceTime); 455 456 clock_.CurrentNtp(ntp_sec, ntp_frac); 457 uint32_t mid_ntp = RTCPUtility::MidNtp(ntp_sec, ntp_frac); 458 EXPECT_TRUE(rtcp_sender_->SendTimeOfXrRrReport(mid_ntp, &time_ms)); 459 EXPECT_EQ(clock_.CurrentNtpInMilliseconds(), time_ms); 460 clock_.AdvanceTimeMilliseconds(1000); 461 } 462 463 // The first report should no longer be stored. 464 EXPECT_FALSE(rtcp_sender_->SendTimeOfXrRrReport(initial_mid_ntp, &time_ms)); 465 } 466 467 // This test is written to verify actual behaviour. It does not seem 468 // to make much sense to send an empty TMMBN, since there is no place 469 // to put an actual limit here. It's just information that no limit 470 // is set, which is kind of the starting assumption. 471 // See http://code.google.com/p/webrtc/issues/detail?id=468 for one 472 // situation where this caused confusion. 473 TEST_F(RtcpSenderTest, SendsTmmbnIfSetAndEmpty) { 474 EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound)); 475 TMMBRSet bounding_set; 476 EXPECT_EQ(0, rtcp_sender_->SetTMMBN(&bounding_set, 3)); 477 ASSERT_EQ(0U, test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags); 478 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState(); 479 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state,kRtcpSr)); 480 // We now expect the packet to show up in the rtcp_packet_info_ of 481 // test_transport_. 482 ASSERT_NE(0U, test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags); 483 EXPECT_TRUE(gotPacketType(kRtcpTmmbn)); 484 TMMBRSet* incoming_set = NULL; 485 bool owner = false; 486 // The BoundingSet function returns the number of members of the 487 // bounding set, and touches the incoming set only if there's > 1. 488 EXPECT_EQ(0, test_transport_->rtcp_receiver_->BoundingSet(owner, 489 incoming_set)); 490 } 491 492 TEST_F(RtcpSenderTest, SendsTmmbnIfSetAndValid) { 493 EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound)); 494 TMMBRSet bounding_set; 495 bounding_set.VerifyAndAllocateSet(1); 496 const uint32_t kSourceSsrc = 12345; 497 bounding_set.AddEntry(32768, 0, kSourceSsrc); 498 499 EXPECT_EQ(0, rtcp_sender_->SetTMMBN(&bounding_set, 3)); 500 ASSERT_EQ(0U, test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags); 501 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState(); 502 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr)); 503 // We now expect the packet to show up in the rtcp_packet_info_ of 504 // test_transport_. 505 ASSERT_NE(0U, test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags); 506 EXPECT_TRUE(gotPacketType(kRtcpTmmbn)); 507 TMMBRSet incoming_set; 508 bool owner = false; 509 // We expect 1 member of the incoming set. 510 EXPECT_EQ(1, test_transport_->rtcp_receiver_->BoundingSet(owner, 511 &incoming_set)); 512 EXPECT_EQ(kSourceSsrc, incoming_set.Ssrc(0)); 513 } 514 } // namespace webrtc 515