rtcp_sender_unittest.cc (36147B)
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 #include "modules/rtp_rtcp/source/rtcp_sender.h" 12 13 #include <cstddef> 14 #include <cstdint> 15 #include <memory> 16 #include <optional> 17 #include <utility> 18 #include <vector> 19 20 #include "api/array_view.h" 21 #include "api/call/transport.h" 22 #include "api/environment/environment.h" 23 #include "api/environment/environment_factory.h" 24 #include "api/rtp_headers.h" 25 #include "api/units/time_delta.h" 26 #include "api/units/timestamp.h" 27 #include "api/video/video_bitrate_allocation.h" 28 #include "modules/rtp_rtcp/include/receive_statistics.h" 29 #include "modules/rtp_rtcp/include/rtcp_statistics.h" 30 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" 31 #include "modules/rtp_rtcp/source/rtcp_packet.h" 32 #include "modules/rtp_rtcp/source/rtcp_packet/bye.h" 33 #include "modules/rtp_rtcp/source/rtcp_packet/common_header.h" 34 #include "modules/rtp_rtcp/source/rtcp_packet/dlrr.h" 35 #include "modules/rtp_rtcp/source/rtcp_packet/remote_estimate.h" 36 #include "modules/rtp_rtcp/source/rtcp_packet/report_block.h" 37 #include "modules/rtp_rtcp/source/rtcp_packet/target_bitrate.h" 38 #include "modules/rtp_rtcp/source/rtcp_packet/tmmb_item.h" 39 #include "modules/rtp_rtcp/source/rtp_packet_received.h" 40 #include "modules/rtp_rtcp/source/rtp_rtcp_impl2.h" 41 #include "modules/rtp_rtcp/source/rtp_rtcp_interface.h" 42 #include "rtc_base/rate_limiter.h" 43 #include "rtc_base/thread.h" 44 #include "system_wrappers/include/clock.h" 45 #include "system_wrappers/include/ntp_time.h" 46 #include "test/gmock.h" 47 #include "test/gtest.h" 48 #include "test/mock_transport.h" 49 #include "test/rtcp_packet_parser.h" 50 51 namespace webrtc { 52 namespace { 53 54 using ::testing::_; 55 using ::testing::ElementsAre; 56 using ::testing::Eq; 57 using ::testing::Invoke; 58 using ::testing::Property; 59 using ::testing::SizeIs; 60 61 class RtcpPacketTypeCounterObserverImpl : public RtcpPacketTypeCounterObserver { 62 public: 63 RtcpPacketTypeCounterObserverImpl() : ssrc_(0) {} 64 ~RtcpPacketTypeCounterObserverImpl() override = default; 65 void RtcpPacketTypesCounterUpdated( 66 uint32_t ssrc, 67 const RtcpPacketTypeCounter& packet_counter) override { 68 ssrc_ = ssrc; 69 counter_ = packet_counter; 70 } 71 uint32_t ssrc_; 72 RtcpPacketTypeCounter counter_; 73 }; 74 75 class TestTransport : public Transport { 76 public: 77 TestTransport() {} 78 79 bool SendRtp(ArrayView<const uint8_t> /*data*/, 80 const PacketOptions& /* options */) override { 81 return false; 82 } 83 bool SendRtcp(ArrayView<const uint8_t> data, 84 const PacketOptions& options) override { 85 EXPECT_FALSE(options.is_media); 86 parser_.Parse(data); 87 return true; 88 } 89 test::RtcpPacketParser parser_; 90 }; 91 92 constexpr uint32_t kSenderSsrc = 0x11111111; 93 constexpr uint32_t kRemoteSsrc = 0x22222222; 94 constexpr uint32_t kStartRtpTimestamp = 0x34567; 95 constexpr uint32_t kRtpTimestamp = 0x45678; 96 97 class RtcpSenderTest : public ::testing::Test { 98 protected: 99 RtcpSenderTest() 100 : clock_(1335900000), 101 env_(CreateEnvironment(&clock_)), 102 receive_statistics_(ReceiveStatistics::Create(&clock_)), 103 rtp_rtcp_impl_(env_, GetDefaultRtpRtcpConfig()) {} 104 105 RTCPSender::Configuration GetDefaultConfig() { 106 RTCPSender::Configuration configuration; 107 configuration.audio = false; 108 configuration.outgoing_transport = &test_transport_; 109 configuration.rtcp_report_interval = TimeDelta::Seconds(1); 110 configuration.receive_statistics = receive_statistics_.get(); 111 configuration.local_media_ssrc = kSenderSsrc; 112 configuration.schedule_next_rtcp_send_evaluation = [](TimeDelta) {}; 113 return configuration; 114 } 115 116 RtpRtcpInterface::Configuration GetDefaultRtpRtcpConfig() { 117 RTCPSender::Configuration config = GetDefaultConfig(); 118 RtpRtcpInterface::Configuration result; 119 result.audio = config.audio; 120 result.outgoing_transport = config.outgoing_transport; 121 result.rtcp_report_interval_ms = config.rtcp_report_interval.ms(); 122 result.receive_statistics = config.receive_statistics; 123 result.local_media_ssrc = config.local_media_ssrc; 124 return result; 125 } 126 127 std::unique_ptr<RTCPSender> CreateRtcpSender(RTCPSender::Configuration config, 128 bool init_timestamps = true) { 129 auto rtcp_sender = std::make_unique<RTCPSender>(env_, std::move(config)); 130 rtcp_sender->SetRemoteSSRC(kRemoteSsrc); 131 if (init_timestamps) { 132 rtcp_sender->SetTimestampOffset(kStartRtpTimestamp); 133 rtcp_sender->SetLastRtpTime(kRtpTimestamp, env_.clock().CurrentTime(), 134 /*payload_type=*/0); 135 } 136 return rtcp_sender; 137 } 138 139 void InsertIncomingPacket(uint32_t remote_ssrc, uint16_t seq_num) { 140 RtpPacketReceived packet; 141 packet.SetSsrc(remote_ssrc); 142 packet.SetSequenceNumber(seq_num); 143 packet.SetTimestamp(12345); 144 packet.SetPayloadSize(100 - 12); 145 receive_statistics_->OnRtpPacket(packet); 146 } 147 148 test::RtcpPacketParser* parser() { return &test_transport_.parser_; } 149 150 RTCPSender::FeedbackState feedback_state() { 151 return rtp_rtcp_impl_.GetFeedbackState(); 152 } 153 154 AutoThread main_thread_; 155 SimulatedClock clock_; 156 const Environment env_; 157 TestTransport test_transport_; 158 std::unique_ptr<ReceiveStatistics> receive_statistics_; 159 ModuleRtpRtcpImpl2 rtp_rtcp_impl_; 160 }; 161 162 TEST_F(RtcpSenderTest, SetRtcpStatus) { 163 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 164 EXPECT_EQ(RtcpMode::kOff, rtcp_sender->Status()); 165 rtcp_sender->SetRTCPStatus(RtcpMode::kReducedSize); 166 EXPECT_EQ(RtcpMode::kReducedSize, rtcp_sender->Status()); 167 } 168 169 TEST_F(RtcpSenderTest, SetSendingStatus) { 170 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 171 EXPECT_FALSE(rtcp_sender->Sending()); 172 rtcp_sender->SetSendingStatus(feedback_state(), true); 173 EXPECT_TRUE(rtcp_sender->Sending()); 174 } 175 176 TEST_F(RtcpSenderTest, NoPacketSentIfOff) { 177 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 178 rtcp_sender->SetRTCPStatus(RtcpMode::kOff); 179 EXPECT_EQ(-1, rtcp_sender->SendRTCP(feedback_state(), kRtcpSr)); 180 } 181 182 TEST_F(RtcpSenderTest, SendSr) { 183 const uint32_t kPacketCount = 0x12345; 184 const uint32_t kOctetCount = 0x23456; 185 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 186 rtcp_sender->SetRTCPStatus(RtcpMode::kReducedSize); 187 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_.GetFeedbackState(); 188 rtcp_sender->SetSendingStatus(feedback_state, true); 189 feedback_state.packets_sent = kPacketCount; 190 feedback_state.media_bytes_sent = kOctetCount; 191 NtpTime ntp = clock_.CurrentNtpTime(); 192 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state, kRtcpSr)); 193 EXPECT_EQ(1, parser()->sender_report()->num_packets()); 194 EXPECT_EQ(kSenderSsrc, parser()->sender_report()->sender_ssrc()); 195 EXPECT_EQ(ntp, parser()->sender_report()->ntp()); 196 EXPECT_EQ(kPacketCount, parser()->sender_report()->sender_packet_count()); 197 EXPECT_EQ(kOctetCount, parser()->sender_report()->sender_octet_count()); 198 EXPECT_EQ(kStartRtpTimestamp + kRtpTimestamp, 199 parser()->sender_report()->rtp_timestamp()); 200 EXPECT_EQ(0U, parser()->sender_report()->report_blocks().size()); 201 } 202 203 TEST_F(RtcpSenderTest, SendConsecutiveSrWithExactSlope) { 204 const uint32_t kPacketCount = 0x12345; 205 const uint32_t kOctetCount = 0x23456; 206 const int kTimeBetweenSRsUs = 10043; // Not exact value in milliseconds. 207 const int kExtraPackets = 30; 208 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 209 // Make sure clock is not exactly at some milliseconds point. 210 clock_.AdvanceTimeMicroseconds(kTimeBetweenSRsUs); 211 rtcp_sender->SetRTCPStatus(RtcpMode::kReducedSize); 212 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_.GetFeedbackState(); 213 rtcp_sender->SetSendingStatus(feedback_state, true); 214 feedback_state.packets_sent = kPacketCount; 215 feedback_state.media_bytes_sent = kOctetCount; 216 217 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state, kRtcpSr)); 218 EXPECT_EQ(1, parser()->sender_report()->num_packets()); 219 NtpTime ntp1 = parser()->sender_report()->ntp(); 220 uint32_t rtp1 = parser()->sender_report()->rtp_timestamp(); 221 222 // Send more SRs to ensure slope is always exact for different offsets 223 for (int packets = 1; packets <= kExtraPackets; ++packets) { 224 clock_.AdvanceTimeMicroseconds(kTimeBetweenSRsUs); 225 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state, kRtcpSr)); 226 EXPECT_EQ(packets + 1, parser()->sender_report()->num_packets()); 227 228 NtpTime ntp2 = parser()->sender_report()->ntp(); 229 uint32_t rtp2 = parser()->sender_report()->rtp_timestamp(); 230 231 uint32_t ntp_diff_in_rtp_units = 232 (ntp2.ToMs() - ntp1.ToMs()) * (kVideoPayloadTypeFrequency / 1000); 233 EXPECT_EQ(rtp2 - rtp1, ntp_diff_in_rtp_units); 234 } 235 } 236 237 TEST_F(RtcpSenderTest, DoNotSendSrBeforeRtp) { 238 auto rtcp_sender = 239 CreateRtcpSender(GetDefaultConfig(), /*init_timestamps=*/false); 240 rtcp_sender->SetRTCPStatus(RtcpMode::kReducedSize); 241 rtcp_sender->SetSendingStatus(feedback_state(), true); 242 243 // Sender Report shouldn't be send as an SR nor as a Report. 244 rtcp_sender->SendRTCP(feedback_state(), kRtcpSr); 245 EXPECT_EQ(0, parser()->sender_report()->num_packets()); 246 rtcp_sender->SendRTCP(feedback_state(), kRtcpReport); 247 EXPECT_EQ(0, parser()->sender_report()->num_packets()); 248 // Other packets (e.g. Pli) are allowed, even if useless. 249 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpPli)); 250 EXPECT_EQ(1, parser()->pli()->num_packets()); 251 } 252 253 TEST_F(RtcpSenderTest, DoNotSendCompundBeforeRtp) { 254 auto rtcp_sender = 255 CreateRtcpSender(GetDefaultConfig(), /*init_timestamps=*/false); 256 rtcp_sender->SetRTCPStatus(RtcpMode::kCompound); 257 rtcp_sender->SetSendingStatus(feedback_state(), true); 258 259 // In compound mode no packets are allowed (e.g. Pli) because compound mode 260 // should start with Sender Report. 261 EXPECT_EQ(-1, rtcp_sender->SendRTCP(feedback_state(), kRtcpPli)); 262 EXPECT_EQ(0, parser()->pli()->num_packets()); 263 } 264 265 TEST_F(RtcpSenderTest, SendRr) { 266 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 267 rtcp_sender->SetRTCPStatus(RtcpMode::kCompound); 268 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpRr)); 269 EXPECT_EQ(1, parser()->receiver_report()->num_packets()); 270 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc()); 271 EXPECT_EQ(0U, parser()->receiver_report()->report_blocks().size()); 272 } 273 274 TEST_F(RtcpSenderTest, DoesntSendEmptyRrInReducedSizeMode) { 275 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 276 rtcp_sender->SetRTCPStatus(RtcpMode::kReducedSize); 277 rtcp_sender->SendRTCP(feedback_state(), kRtcpRr); 278 EXPECT_EQ(parser()->receiver_report()->num_packets(), 0); 279 } 280 281 TEST_F(RtcpSenderTest, SendRrWithOneReportBlock) { 282 const uint16_t kSeqNum = 11111; 283 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 284 InsertIncomingPacket(kRemoteSsrc, kSeqNum); 285 rtcp_sender->SetRTCPStatus(RtcpMode::kCompound); 286 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpRr)); 287 EXPECT_EQ(1, parser()->receiver_report()->num_packets()); 288 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc()); 289 ASSERT_EQ(1U, parser()->receiver_report()->report_blocks().size()); 290 const rtcp::ReportBlock& rb = parser()->receiver_report()->report_blocks()[0]; 291 EXPECT_EQ(kRemoteSsrc, rb.source_ssrc()); 292 EXPECT_EQ(0U, rb.fraction_lost()); 293 EXPECT_EQ(0, rb.cumulative_lost()); 294 EXPECT_EQ(kSeqNum, rb.extended_high_seq_num()); 295 } 296 297 TEST_F(RtcpSenderTest, SendRrWithTwoReportBlocks) { 298 const uint16_t kSeqNum = 11111; 299 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 300 InsertIncomingPacket(kRemoteSsrc, kSeqNum); 301 InsertIncomingPacket(kRemoteSsrc + 1, kSeqNum + 1); 302 rtcp_sender->SetRTCPStatus(RtcpMode::kCompound); 303 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpRr)); 304 EXPECT_EQ(1, parser()->receiver_report()->num_packets()); 305 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc()); 306 EXPECT_THAT( 307 parser()->receiver_report()->report_blocks(), 308 UnorderedElementsAre( 309 Property(&rtcp::ReportBlock::source_ssrc, Eq(kRemoteSsrc)), 310 Property(&rtcp::ReportBlock::source_ssrc, Eq(kRemoteSsrc + 1)))); 311 } 312 313 TEST_F(RtcpSenderTest, SendSdes) { 314 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 315 rtcp_sender->SetRTCPStatus(RtcpMode::kReducedSize); 316 EXPECT_EQ(0, rtcp_sender->SetCNAME("alice@host")); 317 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpSdes)); 318 EXPECT_EQ(1, parser()->sdes()->num_packets()); 319 EXPECT_EQ(1U, parser()->sdes()->chunks().size()); 320 EXPECT_EQ(kSenderSsrc, parser()->sdes()->chunks()[0].ssrc); 321 EXPECT_EQ("alice@host", parser()->sdes()->chunks()[0].cname); 322 } 323 324 TEST_F(RtcpSenderTest, SdesIncludedInCompoundPacket) { 325 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 326 rtcp_sender->SetRTCPStatus(RtcpMode::kCompound); 327 EXPECT_EQ(0, rtcp_sender->SetCNAME("alice@host")); 328 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpReport)); 329 EXPECT_EQ(1, parser()->receiver_report()->num_packets()); 330 EXPECT_EQ(1, parser()->sdes()->num_packets()); 331 EXPECT_EQ(1U, parser()->sdes()->chunks().size()); 332 } 333 334 TEST_F(RtcpSenderTest, SendBye) { 335 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 336 rtcp_sender->SetRTCPStatus(RtcpMode::kReducedSize); 337 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpBye)); 338 EXPECT_EQ(1, parser()->bye()->num_packets()); 339 EXPECT_EQ(kSenderSsrc, parser()->bye()->sender_ssrc()); 340 } 341 342 TEST_F(RtcpSenderTest, StopSendingTriggersBye) { 343 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 344 rtcp_sender->SetRTCPStatus(RtcpMode::kReducedSize); 345 rtcp_sender->SetSendingStatus(feedback_state(), true); 346 rtcp_sender->SetSendingStatus(feedback_state(), false); 347 EXPECT_EQ(1, parser()->bye()->num_packets()); 348 EXPECT_EQ(kSenderSsrc, parser()->bye()->sender_ssrc()); 349 } 350 351 TEST_F(RtcpSenderTest, SendFir) { 352 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 353 rtcp_sender->SetRTCPStatus(RtcpMode::kReducedSize); 354 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpFir)); 355 EXPECT_EQ(1, parser()->fir()->num_packets()); 356 EXPECT_EQ(kSenderSsrc, parser()->fir()->sender_ssrc()); 357 EXPECT_EQ(1U, parser()->fir()->requests().size()); 358 EXPECT_EQ(kRemoteSsrc, parser()->fir()->requests()[0].ssrc); 359 uint8_t seq = parser()->fir()->requests()[0].seq_nr; 360 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpFir)); 361 EXPECT_EQ(2, parser()->fir()->num_packets()); 362 EXPECT_EQ(seq + 1, parser()->fir()->requests()[0].seq_nr); 363 } 364 365 TEST_F(RtcpSenderTest, SendPli) { 366 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 367 rtcp_sender->SetRTCPStatus(RtcpMode::kReducedSize); 368 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpPli)); 369 EXPECT_EQ(1, parser()->pli()->num_packets()); 370 EXPECT_EQ(kSenderSsrc, parser()->pli()->sender_ssrc()); 371 EXPECT_EQ(kRemoteSsrc, parser()->pli()->media_ssrc()); 372 } 373 374 TEST_F(RtcpSenderTest, SendNack) { 375 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 376 rtcp_sender->SetRTCPStatus(RtcpMode::kReducedSize); 377 const uint16_t kList[] = {0, 1, 16}; 378 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpNack, kList)); 379 EXPECT_EQ(1, parser()->nack()->num_packets()); 380 EXPECT_EQ(kSenderSsrc, parser()->nack()->sender_ssrc()); 381 EXPECT_EQ(kRemoteSsrc, parser()->nack()->media_ssrc()); 382 EXPECT_THAT(parser()->nack()->packet_ids(), ElementsAre(0, 1, 16)); 383 } 384 385 TEST_F(RtcpSenderTest, SendLossNotificationBufferingNotAllowed) { 386 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 387 rtcp_sender->SetRTCPStatus(RtcpMode::kReducedSize); 388 constexpr uint16_t kLastDecoded = 0x1234; 389 constexpr uint16_t kLastReceived = 0x4321; 390 constexpr bool kDecodabilityFlag = true; 391 constexpr bool kBufferingAllowed = false; 392 EXPECT_EQ(rtcp_sender->SendLossNotification(feedback_state(), kLastDecoded, 393 kLastReceived, kDecodabilityFlag, 394 kBufferingAllowed), 395 0); 396 EXPECT_EQ(parser()->processed_rtcp_packets(), 1u); 397 EXPECT_EQ(parser()->loss_notification()->num_packets(), 1); 398 EXPECT_EQ(kSenderSsrc, parser()->loss_notification()->sender_ssrc()); 399 EXPECT_EQ(kRemoteSsrc, parser()->loss_notification()->media_ssrc()); 400 } 401 402 TEST_F(RtcpSenderTest, SendLossNotificationBufferingAllowed) { 403 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 404 rtcp_sender->SetRTCPStatus(RtcpMode::kReducedSize); 405 constexpr uint16_t kLastDecoded = 0x1234; 406 constexpr uint16_t kLastReceived = 0x4321; 407 constexpr bool kDecodabilityFlag = true; 408 constexpr bool kBufferingAllowed = true; 409 EXPECT_EQ(rtcp_sender->SendLossNotification(feedback_state(), kLastDecoded, 410 kLastReceived, kDecodabilityFlag, 411 kBufferingAllowed), 412 0); 413 414 // No RTCP messages sent yet. 415 ASSERT_EQ(parser()->processed_rtcp_packets(), 0u); 416 417 // Sending another messages triggers sending the LNTF messages as well. 418 const uint16_t kList[] = {0, 1, 16}; 419 EXPECT_EQ(rtcp_sender->SendRTCP(feedback_state(), kRtcpNack, kList), 0); 420 421 // Exactly one packet was produced, and it contained both the buffered LNTF 422 // as well as the message that had triggered the packet. 423 EXPECT_EQ(parser()->processed_rtcp_packets(), 1u); 424 EXPECT_EQ(parser()->loss_notification()->num_packets(), 1); 425 EXPECT_EQ(parser()->loss_notification()->sender_ssrc(), kSenderSsrc); 426 EXPECT_EQ(parser()->loss_notification()->media_ssrc(), kRemoteSsrc); 427 EXPECT_EQ(parser()->nack()->num_packets(), 1); 428 EXPECT_EQ(parser()->nack()->sender_ssrc(), kSenderSsrc); 429 EXPECT_EQ(parser()->nack()->media_ssrc(), kRemoteSsrc); 430 } 431 432 TEST_F(RtcpSenderTest, RembNotIncludedBeforeSet) { 433 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 434 rtcp_sender->SetRTCPStatus(RtcpMode::kCompound); 435 436 rtcp_sender->SendRTCP(feedback_state(), kRtcpRr); 437 438 ASSERT_EQ(1, parser()->receiver_report()->num_packets()); 439 EXPECT_EQ(0, parser()->remb()->num_packets()); 440 } 441 442 TEST_F(RtcpSenderTest, RembNotIncludedAfterUnset) { 443 const int64_t kBitrate = 261011; 444 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1}; 445 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 446 rtcp_sender->SetRTCPStatus(RtcpMode::kCompound); 447 rtcp_sender->SetRemb(kBitrate, kSsrcs); 448 rtcp_sender->SendRTCP(feedback_state(), kRtcpRr); 449 ASSERT_EQ(1, parser()->receiver_report()->num_packets()); 450 EXPECT_EQ(1, parser()->remb()->num_packets()); 451 452 // Turn off REMB. rtcp_sender no longer should send it. 453 rtcp_sender->UnsetRemb(); 454 rtcp_sender->SendRTCP(feedback_state(), kRtcpRr); 455 ASSERT_EQ(2, parser()->receiver_report()->num_packets()); 456 EXPECT_EQ(1, parser()->remb()->num_packets()); 457 } 458 459 TEST_F(RtcpSenderTest, SendRemb) { 460 const int64_t kBitrate = 261011; 461 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1}; 462 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 463 rtcp_sender->SetRTCPStatus(RtcpMode::kReducedSize); 464 rtcp_sender->SetRemb(kBitrate, kSsrcs); 465 466 rtcp_sender->SendRTCP(feedback_state(), kRtcpRemb); 467 468 EXPECT_EQ(1, parser()->remb()->num_packets()); 469 EXPECT_EQ(kSenderSsrc, parser()->remb()->sender_ssrc()); 470 EXPECT_EQ(kBitrate, parser()->remb()->bitrate_bps()); 471 EXPECT_THAT(parser()->remb()->ssrcs(), 472 ElementsAre(kRemoteSsrc, kRemoteSsrc + 1)); 473 } 474 475 TEST_F(RtcpSenderTest, RembIncludedInEachCompoundPacketAfterSet) { 476 const int kBitrate = 261011; 477 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1}; 478 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 479 rtcp_sender->SetRTCPStatus(RtcpMode::kCompound); 480 rtcp_sender->SetRemb(kBitrate, kSsrcs); 481 482 rtcp_sender->SendRTCP(feedback_state(), kRtcpReport); 483 EXPECT_EQ(1, parser()->remb()->num_packets()); 484 // REMB should be included in each compound packet. 485 rtcp_sender->SendRTCP(feedback_state(), kRtcpReport); 486 EXPECT_EQ(2, parser()->remb()->num_packets()); 487 } 488 489 TEST_F(RtcpSenderTest, SendXrWithDlrr) { 490 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 491 rtcp_sender->SetRTCPStatus(RtcpMode::kCompound); 492 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_.GetFeedbackState(); 493 rtcp::ReceiveTimeInfo last_xr_rr; 494 last_xr_rr.ssrc = 0x11111111; 495 last_xr_rr.last_rr = 0x22222222; 496 last_xr_rr.delay_since_last_rr = 0x33333333; 497 feedback_state.last_xr_rtis.push_back(last_xr_rr); 498 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state, kRtcpReport)); 499 EXPECT_EQ(1, parser()->xr()->num_packets()); 500 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc()); 501 ASSERT_THAT(parser()->xr()->dlrr().sub_blocks(), SizeIs(1)); 502 EXPECT_EQ(last_xr_rr.ssrc, parser()->xr()->dlrr().sub_blocks()[0].ssrc); 503 EXPECT_EQ(last_xr_rr.last_rr, parser()->xr()->dlrr().sub_blocks()[0].last_rr); 504 EXPECT_EQ(last_xr_rr.delay_since_last_rr, 505 parser()->xr()->dlrr().sub_blocks()[0].delay_since_last_rr); 506 } 507 508 TEST_F(RtcpSenderTest, SendXrWithMultipleDlrrSubBlocks) { 509 const size_t kNumReceivers = 2; 510 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 511 rtcp_sender->SetRTCPStatus(RtcpMode::kCompound); 512 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_.GetFeedbackState(); 513 for (size_t i = 0; i < kNumReceivers; ++i) { 514 rtcp::ReceiveTimeInfo last_xr_rr; 515 last_xr_rr.ssrc = i; 516 last_xr_rr.last_rr = (i + 1) * 100; 517 last_xr_rr.delay_since_last_rr = (i + 2) * 200; 518 feedback_state.last_xr_rtis.push_back(last_xr_rr); 519 } 520 521 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state, kRtcpReport)); 522 EXPECT_EQ(1, parser()->xr()->num_packets()); 523 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc()); 524 ASSERT_THAT(parser()->xr()->dlrr().sub_blocks(), SizeIs(kNumReceivers)); 525 for (size_t i = 0; i < kNumReceivers; ++i) { 526 EXPECT_EQ(feedback_state.last_xr_rtis[i].ssrc, 527 parser()->xr()->dlrr().sub_blocks()[i].ssrc); 528 EXPECT_EQ(feedback_state.last_xr_rtis[i].last_rr, 529 parser()->xr()->dlrr().sub_blocks()[i].last_rr); 530 EXPECT_EQ(feedback_state.last_xr_rtis[i].delay_since_last_rr, 531 parser()->xr()->dlrr().sub_blocks()[i].delay_since_last_rr); 532 } 533 } 534 535 TEST_F(RtcpSenderTest, SendXrWithRrtr) { 536 RTCPSender::Configuration config = GetDefaultConfig(); 537 config.non_sender_rtt_measurement = true; 538 auto rtcp_sender = CreateRtcpSender(std::move(config)); 539 rtcp_sender->SetRTCPStatus(RtcpMode::kCompound); 540 rtcp_sender->SetSendingStatus(feedback_state(), false); 541 NtpTime ntp = clock_.CurrentNtpTime(); 542 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpReport)); 543 EXPECT_EQ(1, parser()->xr()->num_packets()); 544 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc()); 545 EXPECT_FALSE(parser()->xr()->dlrr()); 546 ASSERT_TRUE(parser()->xr()->rrtr()); 547 EXPECT_EQ(ntp, parser()->xr()->rrtr()->ntp()); 548 } 549 550 // Same test as above, but enable Rrtr with the setter. 551 TEST_F(RtcpSenderTest, SendXrWithRrtrUsingSetter) { 552 RTCPSender::Configuration config = GetDefaultConfig(); 553 config.non_sender_rtt_measurement = false; 554 auto rtcp_sender = CreateRtcpSender(std::move(config)); 555 rtcp_sender->SetNonSenderRttMeasurement(true); 556 rtcp_sender->SetRTCPStatus(RtcpMode::kCompound); 557 rtcp_sender->SetSendingStatus(feedback_state(), false); 558 NtpTime ntp = clock_.CurrentNtpTime(); 559 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpReport)); 560 EXPECT_EQ(1, parser()->xr()->num_packets()); 561 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc()); 562 EXPECT_FALSE(parser()->xr()->dlrr()); 563 ASSERT_TRUE(parser()->xr()->rrtr()); 564 EXPECT_EQ(ntp, parser()->xr()->rrtr()->ntp()); 565 } 566 567 // Same test as above, but disable Rrtr with the setter. 568 TEST_F(RtcpSenderTest, SendsNoRrtrUsingSetter) { 569 RTCPSender::Configuration config = GetDefaultConfig(); 570 config.non_sender_rtt_measurement = true; 571 auto rtcp_sender = CreateRtcpSender(std::move(config)); 572 rtcp_sender->SetNonSenderRttMeasurement(false); 573 rtcp_sender->SetRTCPStatus(RtcpMode::kCompound); 574 rtcp_sender->SetSendingStatus(feedback_state(), false); 575 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpReport)); 576 EXPECT_EQ(0, parser()->xr()->num_packets()); 577 } 578 579 TEST_F(RtcpSenderTest, TestNoXrRrtrSentIfSending) { 580 RTCPSender::Configuration config = GetDefaultConfig(); 581 config.non_sender_rtt_measurement = true; 582 auto rtcp_sender = CreateRtcpSender(std::move(config)); 583 rtcp_sender->SetRTCPStatus(RtcpMode::kCompound); 584 rtcp_sender->SetSendingStatus(feedback_state(), true); 585 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpReport)); 586 EXPECT_EQ(0, parser()->xr()->num_packets()); 587 } 588 589 TEST_F(RtcpSenderTest, TestNoXrRrtrSentIfNotEnabled) { 590 RTCPSender::Configuration config = GetDefaultConfig(); 591 config.non_sender_rtt_measurement = false; 592 auto rtcp_sender = CreateRtcpSender(std::move(config)); 593 rtcp_sender->SetRTCPStatus(RtcpMode::kCompound); 594 rtcp_sender->SetSendingStatus(feedback_state(), false); 595 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpReport)); 596 EXPECT_EQ(0, parser()->xr()->num_packets()); 597 } 598 599 TEST_F(RtcpSenderTest, TestRegisterRtcpPacketTypeObserver) { 600 RtcpPacketTypeCounterObserverImpl observer; 601 RTCPSender::Configuration config = GetDefaultConfig(); 602 config.rtcp_packet_type_counter_observer = &observer; 603 auto rtcp_sender = CreateRtcpSender(std::move(config)); 604 rtcp_sender->SetRTCPStatus(RtcpMode::kReducedSize); 605 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpPli)); 606 EXPECT_EQ(1, parser()->pli()->num_packets()); 607 EXPECT_EQ(kRemoteSsrc, observer.ssrc_); 608 EXPECT_EQ(1U, observer.counter_.pli_packets); 609 } 610 611 TEST_F(RtcpSenderTest, SendTmmbr) { 612 const unsigned int kBitrateBps = 312000; 613 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 614 rtcp_sender->SetRTCPStatus(RtcpMode::kReducedSize); 615 rtcp_sender->SetTargetBitrate(kBitrateBps); 616 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpTmmbr)); 617 EXPECT_EQ(1, parser()->tmmbr()->num_packets()); 618 EXPECT_EQ(kSenderSsrc, parser()->tmmbr()->sender_ssrc()); 619 EXPECT_EQ(1U, parser()->tmmbr()->requests().size()); 620 EXPECT_EQ(kBitrateBps, parser()->tmmbr()->requests()[0].bitrate_bps()); 621 // TODO(asapersson): tmmbr_item()->Overhead() looks broken, always zero. 622 } 623 624 TEST_F(RtcpSenderTest, SendTmmbn) { 625 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 626 rtcp_sender->SetRTCPStatus(RtcpMode::kCompound); 627 rtcp_sender->SetSendingStatus(feedback_state(), true); 628 std::vector<rtcp::TmmbItem> bounding_set; 629 const uint32_t kBitrateBps = 32768000; 630 const uint32_t kPacketOh = 40; 631 const uint32_t kSourceSsrc = 12345; 632 const rtcp::TmmbItem tmmbn(kSourceSsrc, kBitrateBps, kPacketOh); 633 bounding_set.push_back(tmmbn); 634 rtcp_sender->SetTmmbn(bounding_set); 635 636 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpSr)); 637 EXPECT_EQ(1, parser()->sender_report()->num_packets()); 638 EXPECT_EQ(1, parser()->tmmbn()->num_packets()); 639 EXPECT_EQ(kSenderSsrc, parser()->tmmbn()->sender_ssrc()); 640 EXPECT_EQ(1U, parser()->tmmbn()->items().size()); 641 EXPECT_EQ(kBitrateBps, parser()->tmmbn()->items()[0].bitrate_bps()); 642 EXPECT_EQ(kPacketOh, parser()->tmmbn()->items()[0].packet_overhead()); 643 EXPECT_EQ(kSourceSsrc, parser()->tmmbn()->items()[0].ssrc()); 644 } 645 646 // This test is written to verify actual behaviour. It does not seem 647 // to make much sense to send an empty TMMBN, since there is no place 648 // to put an actual limit here. It's just information that no limit 649 // is set, which is kind of the starting assumption. 650 // See http://code.google.com/p/webrtc/issues/detail?id=468 for one 651 // situation where this caused confusion. 652 TEST_F(RtcpSenderTest, SendsTmmbnIfSetAndEmpty) { 653 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 654 rtcp_sender->SetRTCPStatus(RtcpMode::kCompound); 655 rtcp_sender->SetSendingStatus(feedback_state(), true); 656 std::vector<rtcp::TmmbItem> bounding_set; 657 rtcp_sender->SetTmmbn(bounding_set); 658 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpSr)); 659 EXPECT_EQ(1, parser()->sender_report()->num_packets()); 660 EXPECT_EQ(1, parser()->tmmbn()->num_packets()); 661 EXPECT_EQ(kSenderSsrc, parser()->tmmbn()->sender_ssrc()); 662 EXPECT_EQ(0U, parser()->tmmbn()->items().size()); 663 } 664 665 // This test is written to verify that BYE is always the last packet 666 // type in a RTCP compoud packet. The rtcp_sender is recreated with 667 // mock_transport, which is used to check for whether BYE at the end 668 // of a RTCP compound packet. 669 TEST_F(RtcpSenderTest, ByeMustBeLast) { 670 MockTransport mock_transport; 671 EXPECT_CALL(mock_transport, SendRtcp(_, _)) 672 .WillOnce(Invoke([](ArrayView<const uint8_t> data, ::testing::Unused) { 673 const uint8_t* next_packet = data.data(); 674 const uint8_t* const packet_end = data.data() + data.size(); 675 rtcp::CommonHeader packet; 676 while (next_packet < packet_end) { 677 EXPECT_TRUE(packet.Parse(next_packet, packet_end - next_packet)); 678 next_packet = packet.NextPacket(); 679 if (packet.type() == 680 rtcp::Bye::kPacketType) // Main test expectation. 681 EXPECT_EQ(0, packet_end - next_packet) 682 << "Bye packet should be last in a compound RTCP packet."; 683 if (next_packet == packet_end) // Validate test was set correctly. 684 EXPECT_EQ(packet.type(), rtcp::Bye::kPacketType) 685 << "Last packet in this test expected to be Bye."; 686 } 687 688 return true; 689 })); 690 691 // Re-configure rtcp_sender with mock_transport_ 692 RTCPSender::Configuration config = GetDefaultConfig(); 693 config.outgoing_transport = &mock_transport; 694 auto rtcp_sender = CreateRtcpSender(std::move(config)); 695 696 rtcp_sender->SetTimestampOffset(kStartRtpTimestamp); 697 rtcp_sender->SetLastRtpTime(kRtpTimestamp, clock_.CurrentTime(), 698 /*payload_type=*/0); 699 700 // Set up REMB info to be included with BYE. 701 rtcp_sender->SetRTCPStatus(RtcpMode::kCompound); 702 rtcp_sender->SetRemb(1234, {}); 703 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpBye)); 704 } 705 706 TEST_F(RtcpSenderTest, SendXrWithTargetBitrate) { 707 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 708 rtcp_sender->SetRTCPStatus(RtcpMode::kCompound); 709 const size_t kNumSpatialLayers = 2; 710 const size_t kNumTemporalLayers = 2; 711 VideoBitrateAllocation allocation; 712 for (size_t sl = 0; sl < kNumSpatialLayers; ++sl) { 713 uint32_t start_bitrate_bps = (sl + 1) * 100000; 714 for (size_t tl = 0; tl < kNumTemporalLayers; ++tl) 715 allocation.SetBitrate(sl, tl, start_bitrate_bps + (tl * 20000)); 716 } 717 rtcp_sender->SetVideoBitrateAllocation(allocation); 718 719 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpReport)); 720 EXPECT_EQ(1, parser()->xr()->num_packets()); 721 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc()); 722 const std::optional<rtcp::TargetBitrate>& target_bitrate = 723 parser()->xr()->target_bitrate(); 724 ASSERT_TRUE(target_bitrate); 725 const std::vector<rtcp::TargetBitrate::BitrateItem>& bitrates = 726 target_bitrate->GetTargetBitrates(); 727 EXPECT_EQ(kNumSpatialLayers * kNumTemporalLayers, bitrates.size()); 728 729 for (size_t sl = 0; sl < kNumSpatialLayers; ++sl) { 730 uint32_t start_bitrate_bps = (sl + 1) * 100000; 731 for (size_t tl = 0; tl < kNumTemporalLayers; ++tl) { 732 size_t index = (sl * kNumSpatialLayers) + tl; 733 const rtcp::TargetBitrate::BitrateItem& item = bitrates[index]; 734 EXPECT_EQ(sl, item.spatial_layer); 735 EXPECT_EQ(tl, item.temporal_layer); 736 EXPECT_EQ(start_bitrate_bps + (tl * 20000), 737 item.target_bitrate_kbps * 1000); 738 } 739 } 740 } 741 742 TEST_F(RtcpSenderTest, SendImmediateXrWithTargetBitrate) { 743 // Initialize. Send a first report right away. 744 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 745 rtcp_sender->SetRTCPStatus(RtcpMode::kCompound); 746 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpReport)); 747 clock_.AdvanceTimeMilliseconds(5); 748 749 // Video bitrate allocation generated, save until next time we send a report. 750 VideoBitrateAllocation allocation; 751 allocation.SetBitrate(0, 0, 100000); 752 rtcp_sender->SetVideoBitrateAllocation(allocation); 753 // First seen instance will be sent immediately. 754 EXPECT_TRUE(rtcp_sender->TimeToSendRTCPReport(false)); 755 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpReport)); 756 clock_.AdvanceTimeMilliseconds(5); 757 758 // Update bitrate of existing layer, does not quality for immediate sending. 759 allocation.SetBitrate(0, 0, 150000); 760 rtcp_sender->SetVideoBitrateAllocation(allocation); 761 EXPECT_FALSE(rtcp_sender->TimeToSendRTCPReport(false)); 762 763 // A new spatial layer enabled, signal this as soon as possible. 764 allocation.SetBitrate(1, 0, 200000); 765 rtcp_sender->SetVideoBitrateAllocation(allocation); 766 EXPECT_TRUE(rtcp_sender->TimeToSendRTCPReport(false)); 767 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpReport)); 768 clock_.AdvanceTimeMilliseconds(5); 769 770 // Explicitly disable top layer. The same set of layers now has a bitrate 771 // defined, but the explicit 0 indicates shutdown. Signal immediately. 772 allocation.SetBitrate(1, 0, 0); 773 EXPECT_FALSE(rtcp_sender->TimeToSendRTCPReport(false)); 774 rtcp_sender->SetVideoBitrateAllocation(allocation); 775 EXPECT_TRUE(rtcp_sender->TimeToSendRTCPReport(false)); 776 } 777 778 TEST_F(RtcpSenderTest, SendTargetBitrateExplicitZeroOnStreamRemoval) { 779 // Set up and send a bitrate allocation with two layers. 780 781 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 782 rtcp_sender->SetRTCPStatus(RtcpMode::kCompound); 783 VideoBitrateAllocation allocation; 784 allocation.SetBitrate(0, 0, 100000); 785 allocation.SetBitrate(1, 0, 200000); 786 rtcp_sender->SetVideoBitrateAllocation(allocation); 787 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpReport)); 788 std::optional<rtcp::TargetBitrate> target_bitrate = 789 parser()->xr()->target_bitrate(); 790 ASSERT_TRUE(target_bitrate); 791 std::vector<rtcp::TargetBitrate::BitrateItem> bitrates = 792 target_bitrate->GetTargetBitrates(); 793 ASSERT_EQ(2u, bitrates.size()); 794 EXPECT_EQ(bitrates[0].target_bitrate_kbps, 795 allocation.GetBitrate(0, 0) / 1000); 796 EXPECT_EQ(bitrates[1].target_bitrate_kbps, 797 allocation.GetBitrate(1, 0) / 1000); 798 799 // Create a new allocation, where the second stream is no longer available. 800 VideoBitrateAllocation new_allocation; 801 new_allocation.SetBitrate(0, 0, 150000); 802 rtcp_sender->SetVideoBitrateAllocation(new_allocation); 803 EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpReport)); 804 target_bitrate = parser()->xr()->target_bitrate(); 805 ASSERT_TRUE(target_bitrate); 806 bitrates = target_bitrate->GetTargetBitrates(); 807 808 // Two bitrates should still be set, with an explicit entry indicating the 809 // removed stream is gone. 810 ASSERT_EQ(2u, bitrates.size()); 811 EXPECT_EQ(bitrates[0].target_bitrate_kbps, 812 new_allocation.GetBitrate(0, 0) / 1000); 813 EXPECT_EQ(bitrates[1].target_bitrate_kbps, 0u); 814 } 815 816 TEST_F(RtcpSenderTest, DoesntSchedulesInitialReportWhenSsrcSetOnConstruction) { 817 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 818 rtcp_sender->SetRTCPStatus(RtcpMode::kReducedSize); 819 rtcp_sender->SetRemoteSSRC(kRemoteSsrc); 820 // New report should not have been scheduled yet. 821 clock_.AdvanceTimeMilliseconds(100); 822 EXPECT_FALSE(rtcp_sender->TimeToSendRTCPReport(false)); 823 } 824 825 TEST_F(RtcpSenderTest, SendsCombinedRtcpPacket) { 826 auto rtcp_sender = CreateRtcpSender(GetDefaultConfig()); 827 rtcp_sender->SetRTCPStatus(RtcpMode::kReducedSize); 828 829 std::vector<std::unique_ptr<rtcp::RtcpPacket>> packets; 830 auto transport_feedback = std::make_unique<rtcp::TransportFeedback>(); 831 transport_feedback->AddReceivedPacket(321, Timestamp::Millis(10)); 832 packets.push_back(std::move(transport_feedback)); 833 auto remote_estimate = std::make_unique<rtcp::RemoteEstimate>(); 834 packets.push_back(std::move(remote_estimate)); 835 rtcp_sender->SendCombinedRtcpPacket(std::move(packets)); 836 837 EXPECT_EQ(parser()->transport_feedback()->num_packets(), 1); 838 EXPECT_EQ(parser()->transport_feedback()->sender_ssrc(), kSenderSsrc); 839 EXPECT_EQ(parser()->app()->num_packets(), 1); 840 EXPECT_EQ(parser()->app()->sender_ssrc(), kSenderSsrc); 841 } 842 843 } // namespace 844 } // namespace webrtc