From e2b9fc6909a5d7a951f84375622d2718eba69811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Spr=C3=A5ng?= Date: Thu, 20 May 2021 15:26:56 +0200 Subject: [PATCH] Move FecOverheadRate, BitrateCallbacks to rtp_sender_egress_unittest. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: webrtc:11340 Change-Id: I33dcaea0146429de94d7610b46592b41e0c5549a Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/219685 Commit-Queue: Erik Språng Reviewed-by: Danil Chapovalov Cr-Commit-Position: refs/heads/master@{#34068} --- .../source/rtp_sender_egress_unittest.cc | 75 +++++++++ .../rtp_rtcp/source/rtp_sender_unittest.cc | 144 +----------------- 2 files changed, 76 insertions(+), 143 deletions(-) diff --git a/modules/rtp_rtcp/source/rtp_sender_egress_unittest.cc b/modules/rtp_rtcp/source/rtp_sender_egress_unittest.cc index 8089bd8e6e..ab8d85e757 100644 --- a/modules/rtp_rtcp/source/rtp_sender_egress_unittest.cc +++ b/modules/rtp_rtcp/source/rtp_sender_egress_unittest.cc @@ -31,6 +31,7 @@ namespace webrtc { namespace { +using ::testing::_; using ::testing::Field; using ::testing::NiceMock; using ::testing::StrictMock; @@ -403,6 +404,80 @@ TEST_P(RtpSenderEgressTest, OnSendPacketNotUpdatedForRetransmits) { sender->SendPacket(packet.get(), PacedPacketInfo()); } +TEST_P(RtpSenderEgressTest, ReportsFecRate) { + constexpr int kNumPackets = 10; + constexpr TimeDelta kTimeBetweenPackets = TimeDelta::Millis(33); + + std::unique_ptr sender = CreateRtpSenderEgress(); + DataSize total_fec_data_sent = DataSize::Zero(); + // Send some packets, alternating between media and FEC. + for (size_t i = 0; i < kNumPackets; ++i) { + std::unique_ptr media_packet = BuildRtpPacket(); + media_packet->set_packet_type(RtpPacketMediaType::kVideo); + media_packet->SetPayloadSize(500); + sender->SendPacket(media_packet.get(), PacedPacketInfo()); + + std::unique_ptr fec_packet = BuildRtpPacket(); + fec_packet->set_packet_type(RtpPacketMediaType::kForwardErrorCorrection); + fec_packet->SetPayloadSize(123); + sender->SendPacket(fec_packet.get(), PacedPacketInfo()); + total_fec_data_sent += DataSize::Bytes(fec_packet->size()); + + time_controller_.AdvanceTime(kTimeBetweenPackets); + } + + EXPECT_NEAR( + (sender->GetSendRates()[RtpPacketMediaType::kForwardErrorCorrection]) + .bps(), + (total_fec_data_sent / (kTimeBetweenPackets * kNumPackets)).bps(), 500); +} + +TEST_P(RtpSenderEgressTest, BitrateCallbacks) { + class MockBitrateStaticsObserver : public BitrateStatisticsObserver { + public: + MOCK_METHOD(void, Notify, (uint32_t, uint32_t, uint32_t), (override)); + } observer; + + RtpRtcpInterface::Configuration config = DefaultConfig(); + config.send_bitrate_observer = &observer; + auto sender = std::make_unique(config, &packet_history_); + + // Simulate kNumPackets sent with kPacketInterval intervals, with the + // number of packets selected so that we fill (but don't overflow) the one + // second averaging window. + const TimeDelta kWindowSize = TimeDelta::Seconds(1); + const TimeDelta kPacketInterval = TimeDelta::Millis(20); + const int kNumPackets = (kWindowSize - kPacketInterval) / kPacketInterval; + + DataSize total_data_sent = DataSize::Zero(); + + // Send all but on of the packets, expect a call for each packet but don't + // verify bitrate yet (noisy measurements in the beginning). + for (int i = 0; i < kNumPackets; ++i) { + std::unique_ptr packet = BuildRtpPacket(); + packet->SetPayloadSize(500); + // Mark all packets as retransmissions - will cause total and retransmission + // rates to be equal. + packet->set_packet_type(RtpPacketMediaType::kRetransmission); + total_data_sent += DataSize::Bytes(packet->size()); + + EXPECT_CALL(observer, Notify(_, _, kSsrc)) + .WillOnce([&](uint32_t total_bitrate_bps, + uint32_t retransmission_bitrate_bps, uint32_t /*ssrc*/) { + TimeDelta window_size = i * kPacketInterval + TimeDelta::Millis(1); + // If there is just a single data point, there is no well defined + // averaging window so a bitrate of zero will be reported. + const double expected_bitrate_bps = + i == 0 ? 0.0 : (total_data_sent / window_size).bps(); + EXPECT_NEAR(total_bitrate_bps, expected_bitrate_bps, 500); + EXPECT_NEAR(retransmission_bitrate_bps, expected_bitrate_bps, 500); + }); + + sender->SendPacket(packet.get(), PacedPacketInfo()); + time_controller_.AdvanceTime(kPacketInterval); + } +} + INSTANTIATE_TEST_SUITE_P(WithAndWithoutOverhead, RtpSenderEgressTest, ::testing::Values(TestConfig(false), diff --git a/modules/rtp_rtcp/source/rtp_sender_unittest.cc b/modules/rtp_rtcp/source/rtp_sender_unittest.cc index a2ebbf173b..23fcc8b114 100644 --- a/modules/rtp_rtcp/source/rtp_sender_unittest.cc +++ b/modules/rtp_rtcp/source/rtp_sender_unittest.cc @@ -72,8 +72,6 @@ const uint64_t kStartTime = 123456789; const size_t kMaxPaddingSize = 224u; const uint8_t kPayloadData[] = {47, 11, 32, 93, 89}; const int64_t kDefaultExpectedRetransmissionTimeMs = 125; -const char kNoRid[] = ""; -const char kNoMid[] = ""; const size_t kMaxPaddingLength = 224; // Value taken from rtp_sender.cc. const uint32_t kTimestampTicksPerMs = 90; // 90kHz clock. @@ -775,6 +773,7 @@ TEST_P(RtpSenderTestWithoutPacer, RidIncludedOnSentPackets) { TEST_P(RtpSenderTestWithoutPacer, RidIncludedOnRtxSentPackets) { const char kRid[] = "f"; + const char kNoRid[] = ""; EnableRtx(); EnableRidSending(kRid); @@ -1012,147 +1011,6 @@ TEST_P(RtpSenderTestWithoutPacer, EXPECT_FALSE(rtx_packet.HasExtension()); } -TEST_P(RtpSenderTest, FecOverheadRate) { - constexpr uint32_t kTimestamp = 1234; - constexpr int kMediaPayloadType = 127; - constexpr VideoCodecType kCodecType = VideoCodecType::kVideoCodecGeneric; - constexpr int kFlexfecPayloadType = 118; - const std::vector kNoRtpExtensions; - const std::vector kNoRtpExtensionSizes; - FlexfecSender flexfec_sender(kFlexfecPayloadType, kFlexFecSsrc, kSsrc, kNoMid, - kNoRtpExtensions, kNoRtpExtensionSizes, - nullptr /* rtp_state */, clock_); - - // Reset |rtp_sender_| to use this FlexFEC instance. - SetUpRtpSender(false, false, false, &flexfec_sender); - - FieldTrialBasedConfig field_trials; - RTPSenderVideo::Config video_config; - video_config.clock = clock_; - video_config.rtp_sender = rtp_sender(); - video_config.fec_type = flexfec_sender.GetFecType(); - video_config.fec_overhead_bytes = flexfec_sender.MaxPacketOverhead(); - video_config.field_trials = &field_trials; - RTPSenderVideo rtp_sender_video(video_config); - // Parameters selected to generate a single FEC packet per media packet. - FecProtectionParams params; - params.fec_rate = 15; - params.max_fec_frames = 1; - params.fec_mask_type = kFecMaskRandom; - rtp_egress()->SetFecProtectionParameters(params, params); - - constexpr size_t kNumMediaPackets = 10; - constexpr size_t kNumFecPackets = kNumMediaPackets; - constexpr int64_t kTimeBetweenPacketsMs = 10; - for (size_t i = 0; i < kNumMediaPackets; ++i) { - RTPVideoHeader video_header; - - video_header.frame_type = VideoFrameType::kVideoFrameKey; - EXPECT_TRUE(rtp_sender_video.SendVideo( - kMediaPayloadType, kCodecType, kTimestamp, clock_->TimeInMilliseconds(), - kPayloadData, video_header, kDefaultExpectedRetransmissionTimeMs)); - - time_controller_.AdvanceTime(TimeDelta::Millis(kTimeBetweenPacketsMs)); - } - constexpr size_t kRtpHeaderLength = 12; - constexpr size_t kFlexfecHeaderLength = 20; - constexpr size_t kGenericCodecHeaderLength = 1; - constexpr size_t kPayloadLength = sizeof(kPayloadData); - constexpr size_t kPacketLength = kRtpHeaderLength + kFlexfecHeaderLength + - kGenericCodecHeaderLength + kPayloadLength; - - EXPECT_NEAR( - kNumFecPackets * kPacketLength * 8 / - (kNumFecPackets * kTimeBetweenPacketsMs / 1000.0f), - rtp_egress() - ->GetSendRates()[RtpPacketMediaType::kForwardErrorCorrection] - .bps(), - 500); -} - -TEST_P(RtpSenderTest, BitrateCallbacks) { - class TestCallback : public BitrateStatisticsObserver { - public: - TestCallback() - : BitrateStatisticsObserver(), - num_calls_(0), - ssrc_(0), - total_bitrate_(0), - retransmit_bitrate_(0) {} - ~TestCallback() override = default; - - void Notify(uint32_t total_bitrate, - uint32_t retransmit_bitrate, - uint32_t ssrc) override { - ++num_calls_; - ssrc_ = ssrc; - total_bitrate_ = total_bitrate; - retransmit_bitrate_ = retransmit_bitrate; - } - - uint32_t num_calls_; - uint32_t ssrc_; - uint32_t total_bitrate_; - uint32_t retransmit_bitrate_; - } callback; - - RtpRtcpInterface::Configuration config; - config.clock = clock_; - config.outgoing_transport = &transport_; - config.local_media_ssrc = kSsrc; - config.send_bitrate_observer = &callback; - config.retransmission_rate_limiter = &retransmission_rate_limiter_; - rtp_sender_context_ = - std::make_unique(config, &time_controller_); - - FieldTrialBasedConfig field_trials; - RTPSenderVideo::Config video_config; - video_config.clock = clock_; - video_config.rtp_sender = rtp_sender(); - video_config.field_trials = &field_trials; - RTPSenderVideo rtp_sender_video(video_config); - const VideoCodecType kCodecType = VideoCodecType::kVideoCodecGeneric; - const uint8_t kPayloadType = 127; - - // Simulate kNumPackets sent with kPacketInterval ms intervals, with the - // number of packets selected so that we fill (but don't overflow) the one - // second averaging window. - const uint32_t kWindowSizeMs = 1000; - const uint32_t kPacketInterval = 20; - const uint32_t kNumPackets = - (kWindowSizeMs - kPacketInterval) / kPacketInterval; - // Overhead = 12 bytes RTP header + 1 byte generic header. - const uint32_t kPacketOverhead = 13; - - uint8_t payload[] = {47, 11, 32, 93, 89}; - rtp_sender_context_->packet_history_.SetStorePacketsStatus( - RtpPacketHistory::StorageMode::kStoreAndCull, 1); - uint32_t ssrc = rtp_sender()->SSRC(); - - // Send a few frames. - RTPVideoHeader video_header; - for (uint32_t i = 0; i < kNumPackets; ++i) { - video_header.frame_type = VideoFrameType::kVideoFrameKey; - ASSERT_TRUE(rtp_sender_video.SendVideo( - kPayloadType, kCodecType, 1234, 4321, payload, video_header, - kDefaultExpectedRetransmissionTimeMs)); - time_controller_.AdvanceTime(TimeDelta::Millis(kPacketInterval)); - } - - // We get one call for every stats updated, thus two calls since both the - // stream stats and the retransmit stats are updated once. - EXPECT_EQ(kNumPackets, callback.num_calls_); - EXPECT_EQ(ssrc, callback.ssrc_); - const uint32_t kTotalPacketSize = kPacketOverhead + sizeof(payload); - // Bitrate measured over delta between last and first timestamp, plus one. - const uint32_t kExpectedWindowMs = (kNumPackets - 1) * kPacketInterval + 1; - const uint32_t kExpectedBitsAccumulated = kTotalPacketSize * kNumPackets * 8; - const uint32_t kExpectedRateBps = - (kExpectedBitsAccumulated * 1000 + (kExpectedWindowMs / 2)) / - kExpectedWindowMs; - EXPECT_EQ(kExpectedRateBps, callback.total_bitrate_); -} - TEST_P(RtpSenderTestWithoutPacer, StreamDataCountersCallbacks) { const uint8_t kPayloadType = 127; const VideoCodecType kCodecType = VideoCodecType::kVideoCodecGeneric;