| Index: webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc
|
| diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc
|
| index 14bbff781c50bfc3fc4ebff9b43da808043298ac..5a4775959e7b8cdc5232d8440ab02bcfb559a525 100644
|
| --- a/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc
|
| +++ b/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc
|
| @@ -25,7 +25,9 @@
|
| #include "webrtc/modules/rtp_rtcp/source/rtp_sender.h"
|
| #include "webrtc/modules/rtp_rtcp/source/rtp_sender_video.h"
|
| #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
|
| +#include "webrtc/rtc_base/arraysize.h"
|
| #include "webrtc/rtc_base/buffer.h"
|
| +#include "webrtc/rtc_base/ptr_util.h"
|
| #include "webrtc/rtc_base/rate_limiter.h"
|
| #include "webrtc/test/field_trial.h"
|
| #include "webrtc/test/gmock.h"
|
| @@ -55,6 +57,7 @@ const size_t kMaxPaddingSize = 224u;
|
| const int kVideoRotationExtensionId = 5;
|
| const size_t kGenericHeaderLength = 1;
|
| const uint8_t kPayloadData[] = {47, 11, 32, 93, 89};
|
| +const int64_t kDefaultExpectedRetransmissionTimeMs = 125;
|
|
|
| using ::testing::_;
|
| using ::testing::ElementsAreArray;
|
| @@ -238,7 +241,8 @@ class RtpSenderTest : public ::testing::TestWithParam<bool> {
|
|
|
| EXPECT_TRUE(rtp_sender_->SendOutgoingData(
|
| kVideoFrameKey, kPayloadType, kTimestamp, kCaptureTimeMs, kPayloadData,
|
| - sizeof(kPayloadData), nullptr, nullptr, nullptr));
|
| + sizeof(kPayloadData), nullptr, nullptr, nullptr,
|
| + kDefaultExpectedRetransmissionTimeMs));
|
| }
|
| };
|
|
|
| @@ -249,15 +253,32 @@ class RtpSenderTestWithoutPacer : public RtpSenderTest {
|
| void SetUp() override { SetUpRtpSender(false); }
|
| };
|
|
|
| +class TestRtpSenderVideo : public RTPSenderVideo {
|
| + public:
|
| + TestRtpSenderVideo(Clock* clock,
|
| + RTPSender* rtp_sender,
|
| + FlexfecSender* flexfec_sender)
|
| + : RTPSenderVideo(clock, rtp_sender, flexfec_sender) {}
|
| + ~TestRtpSenderVideo() override {}
|
| +
|
| + StorageType GetStorageType(const RTPVideoHeader& header,
|
| + int32_t retransmission_settings,
|
| + int64_t expected_retransmission_time_ms) {
|
| + return RTPSenderVideo::GetStorageType(GetTemporalId(header),
|
| + retransmission_settings,
|
| + expected_retransmission_time_ms);
|
| + }
|
| +};
|
| +
|
| class RtpSenderVideoTest : public RtpSenderTest {
|
| protected:
|
| void SetUp() override {
|
| // TODO(pbos): Set up to use pacer.
|
| SetUpRtpSender(false);
|
| rtp_sender_video_.reset(
|
| - new RTPSenderVideo(&fake_clock_, rtp_sender_.get(), nullptr));
|
| + new TestRtpSenderVideo(&fake_clock_, rtp_sender_.get(), nullptr));
|
| }
|
| - std::unique_ptr<RTPSenderVideo> rtp_sender_video_;
|
| + std::unique_ptr<TestRtpSenderVideo> rtp_sender_video_;
|
| };
|
|
|
| TEST_P(RtpSenderTestWithoutPacer, AllocatePacketSetCsrc) {
|
| @@ -861,9 +882,9 @@ TEST_P(RtpSenderTestWithoutPacer, SendGenericVideo) {
|
| uint8_t payload[] = {47, 11, 32, 93, 89};
|
|
|
| // Send keyframe
|
| - ASSERT_TRUE(rtp_sender_->SendOutgoingData(kVideoFrameKey, payload_type, 1234,
|
| - 4321, payload, sizeof(payload),
|
| - nullptr, nullptr, nullptr));
|
| + ASSERT_TRUE(rtp_sender_->SendOutgoingData(
|
| + kVideoFrameKey, payload_type, 1234, 4321, payload, sizeof(payload),
|
| + nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs));
|
|
|
| auto sent_payload = transport_.last_sent_packet().payload();
|
| uint8_t generic_header = sent_payload[0];
|
| @@ -878,7 +899,7 @@ TEST_P(RtpSenderTestWithoutPacer, SendGenericVideo) {
|
|
|
| ASSERT_TRUE(rtp_sender_->SendOutgoingData(
|
| kVideoFrameDelta, payload_type, 1234, 4321, payload, sizeof(payload),
|
| - nullptr, nullptr, nullptr));
|
| + nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs));
|
|
|
| sent_payload = transport_.last_sent_packet().payload();
|
| generic_header = sent_payload[0];
|
| @@ -998,7 +1019,8 @@ TEST_P(RtpSenderTest, NoFlexfecForTimingFrames) {
|
| video_header.video_timing.flags = TimingFrameFlags::kTriggeredByTimer;
|
| EXPECT_TRUE(rtp_sender_->SendOutgoingData(
|
| kVideoFrameKey, kPayloadType, kTimestamp, kCaptureTimeMs, kPayloadData,
|
| - sizeof(kPayloadData), nullptr, &video_header, nullptr));
|
| + sizeof(kPayloadData), nullptr, &video_header, nullptr,
|
| + kDefaultExpectedRetransmissionTimeMs));
|
|
|
| EXPECT_CALL(mock_rtc_event_log_,
|
| LogRtpHeader(PacketDirection::kOutgoingPacket, _, _, _))
|
| @@ -1023,7 +1045,8 @@ TEST_P(RtpSenderTest, NoFlexfecForTimingFrames) {
|
| video_header.video_timing.flags = TimingFrameFlags::kInvalid;
|
| EXPECT_TRUE(rtp_sender_->SendOutgoingData(
|
| kVideoFrameKey, kPayloadType, kTimestamp + 1, kCaptureTimeMs + 1,
|
| - kPayloadData, sizeof(kPayloadData), nullptr, &video_header, nullptr));
|
| + kPayloadData, sizeof(kPayloadData), nullptr, &video_header, nullptr,
|
| + kDefaultExpectedRetransmissionTimeMs));
|
|
|
| EXPECT_CALL(mock_rtc_event_log_,
|
| LogRtpHeader(PacketDirection::kOutgoingPacket, _, _, _))
|
| @@ -1168,9 +1191,9 @@ TEST_P(RtpSenderTest, FrameCountCallbacks) {
|
| EXPECT_CALL(mock_paced_sender_, InsertPacket(_, _, _, _, _, _))
|
| .Times(::testing::AtLeast(2));
|
|
|
| - ASSERT_TRUE(rtp_sender_->SendOutgoingData(kVideoFrameKey, payload_type, 1234,
|
| - 4321, payload, sizeof(payload),
|
| - nullptr, nullptr, nullptr));
|
| + ASSERT_TRUE(rtp_sender_->SendOutgoingData(
|
| + kVideoFrameKey, payload_type, 1234, 4321, payload, sizeof(payload),
|
| + nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs));
|
|
|
| EXPECT_EQ(1U, callback.num_calls_);
|
| EXPECT_EQ(ssrc, callback.ssrc_);
|
| @@ -1179,7 +1202,7 @@ TEST_P(RtpSenderTest, FrameCountCallbacks) {
|
|
|
| ASSERT_TRUE(rtp_sender_->SendOutgoingData(
|
| kVideoFrameDelta, payload_type, 1234, 4321, payload, sizeof(payload),
|
| - nullptr, nullptr, nullptr));
|
| + nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs));
|
|
|
| EXPECT_EQ(2U, callback.num_calls_);
|
| EXPECT_EQ(ssrc, callback.ssrc_);
|
| @@ -1245,7 +1268,7 @@ TEST_P(RtpSenderTest, BitrateCallbacks) {
|
| for (uint32_t i = 0; i < kNumPackets; ++i) {
|
| ASSERT_TRUE(rtp_sender_->SendOutgoingData(
|
| kVideoFrameKey, payload_type, 1234, 4321, payload, sizeof(payload),
|
| - nullptr, nullptr, nullptr));
|
| + nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs));
|
| fake_clock_.AdvanceTimeMilliseconds(kPacketInterval);
|
| }
|
|
|
| @@ -1327,8 +1350,8 @@ TEST_P(RtpSenderTestWithoutPacer, StreamDataCountersCallbacks) {
|
|
|
| // Send a frame.
|
| ASSERT_TRUE(rtp_sender_->SendOutgoingData(
|
| - kVideoFrameKey, payload_type, 1234, 4321, payload,
|
| - sizeof(payload), nullptr, nullptr, nullptr));
|
| + kVideoFrameKey, payload_type, 1234, 4321, payload, sizeof(payload),
|
| + nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs));
|
| StreamDataCounters expected;
|
| expected.transmitted.payload_bytes = 6;
|
| expected.transmitted.header_bytes = 12;
|
| @@ -1369,8 +1392,8 @@ TEST_P(RtpSenderTestWithoutPacer, StreamDataCountersCallbacks) {
|
| fec_params.max_fec_frames = 1;
|
| rtp_sender_->SetFecParameters(fec_params, fec_params);
|
| ASSERT_TRUE(rtp_sender_->SendOutgoingData(
|
| - kVideoFrameDelta, payload_type, 1234, 4321, payload,
|
| - sizeof(payload), nullptr, nullptr, nullptr));
|
| + kVideoFrameDelta, payload_type, 1234, 4321, payload, sizeof(payload),
|
| + nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs));
|
| expected.transmitted.payload_bytes = 40;
|
| expected.transmitted.header_bytes = 60;
|
| expected.transmitted.packets = 5;
|
| @@ -1388,8 +1411,8 @@ TEST_P(RtpSenderAudioTest, SendAudio) {
|
| uint8_t payload[] = {47, 11, 32, 93, 89};
|
|
|
| ASSERT_TRUE(rtp_sender_->SendOutgoingData(
|
| - kAudioFrameCN, payload_type, 1234, 4321, payload,
|
| - sizeof(payload), nullptr, nullptr, nullptr));
|
| + kAudioFrameCN, payload_type, 1234, 4321, payload, sizeof(payload),
|
| + nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs));
|
|
|
| auto sent_payload = transport_.last_sent_packet().payload();
|
| EXPECT_THAT(sent_payload, ElementsAreArray(payload));
|
| @@ -1407,8 +1430,8 @@ TEST_P(RtpSenderAudioTest, SendAudioWithAudioLevelExtension) {
|
| uint8_t payload[] = {47, 11, 32, 93, 89};
|
|
|
| ASSERT_TRUE(rtp_sender_->SendOutgoingData(
|
| - kAudioFrameCN, payload_type, 1234, 4321, payload,
|
| - sizeof(payload), nullptr, nullptr, nullptr));
|
| + kAudioFrameCN, payload_type, 1234, 4321, payload, sizeof(payload),
|
| + nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs));
|
|
|
| auto sent_payload = transport_.last_sent_packet().payload();
|
| EXPECT_THAT(sent_payload, ElementsAreArray(payload));
|
| @@ -1445,22 +1468,22 @@ TEST_P(RtpSenderAudioTest, CheckMarkerBitForTelephoneEvents) {
|
| // During start, it takes the starting timestamp as last sent timestamp.
|
| // The duration is calculated as the difference of current and last sent
|
| // timestamp. So for first call it will skip since the duration is zero.
|
| - ASSERT_TRUE(rtp_sender_->SendOutgoingData(kEmptyFrame, kPayloadType,
|
| - capture_time_ms, 0, nullptr, 0,
|
| - nullptr, nullptr, nullptr));
|
| + ASSERT_TRUE(rtp_sender_->SendOutgoingData(
|
| + kEmptyFrame, kPayloadType, capture_time_ms, 0, nullptr, 0, nullptr,
|
| + nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs));
|
| // DTMF Sample Length is (Frequency/1000) * Duration.
|
| // So in this case, it is (8000/1000) * 500 = 4000.
|
| // Sending it as two packets.
|
| ASSERT_TRUE(rtp_sender_->SendOutgoingData(
|
| - kEmptyFrame, kPayloadType, capture_time_ms + 2000, 0,
|
| - nullptr, 0, nullptr, nullptr, nullptr));
|
| + kEmptyFrame, kPayloadType, capture_time_ms + 2000, 0, nullptr, 0, nullptr,
|
| + nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs));
|
|
|
| // Marker Bit should be set to 1 for first packet.
|
| EXPECT_TRUE(transport_.last_sent_packet().Marker());
|
|
|
| ASSERT_TRUE(rtp_sender_->SendOutgoingData(
|
| - kEmptyFrame, kPayloadType, capture_time_ms + 4000, 0,
|
| - nullptr, 0, nullptr, nullptr, nullptr));
|
| + kEmptyFrame, kPayloadType, capture_time_ms + 4000, 0, nullptr, 0, nullptr,
|
| + nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs));
|
| // Marker Bit should be set to 0 for rest of the packets.
|
| EXPECT_FALSE(transport_.last_sent_packet().Marker());
|
| }
|
| @@ -1478,8 +1501,8 @@ TEST_P(RtpSenderTestWithoutPacer, BytesReportedCorrectly) {
|
| uint8_t payload[] = {47, 11, 32, 93, 89};
|
|
|
| ASSERT_TRUE(rtp_sender_->SendOutgoingData(
|
| - kVideoFrameKey, kPayloadType, 1234, 4321, payload,
|
| - sizeof(payload), nullptr, nullptr, nullptr));
|
| + kVideoFrameKey, kPayloadType, 1234, 4321, payload, sizeof(payload),
|
| + nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs));
|
|
|
| // Will send 2 full-size padding packets.
|
| rtp_sender_->TimeToSendPadding(1, PacedPacketInfo());
|
| @@ -1553,7 +1576,7 @@ TEST_P(RtpSenderVideoTest, KeyFrameHasCVO) {
|
| hdr.rotation = kVideoRotation_0;
|
| rtp_sender_video_->SendVideo(kRtpVideoGeneric, kVideoFrameKey, kPayload,
|
| kTimestamp, 0, kFrame, sizeof(kFrame), nullptr,
|
| - &hdr);
|
| + &hdr, kDefaultExpectedRetransmissionTimeMs);
|
|
|
| VideoRotation rotation;
|
| EXPECT_TRUE(
|
| @@ -1579,7 +1602,8 @@ TEST_P(RtpSenderVideoTest, TimingFrameHasPacketizationTimstampSet) {
|
| fake_clock_.AdvanceTimeMilliseconds(kPacketizationTimeMs);
|
| rtp_sender_video_->SendVideo(kRtpVideoGeneric, kVideoFrameKey, kPayload,
|
| kTimestamp, kCaptureTimestamp, kFrame,
|
| - sizeof(kFrame), nullptr, &hdr);
|
| + sizeof(kFrame), nullptr, &hdr,
|
| + kDefaultExpectedRetransmissionTimeMs);
|
| VideoSendTiming timing;
|
| EXPECT_TRUE(transport_.last_sent_packet().GetExtension<VideoTimingExtension>(
|
| &timing));
|
| @@ -1595,14 +1619,14 @@ TEST_P(RtpSenderVideoTest, DeltaFrameHasCVOWhenChanged) {
|
|
|
| RTPVideoHeader hdr = {0};
|
| hdr.rotation = kVideoRotation_90;
|
| - EXPECT_TRUE(rtp_sender_video_->SendVideo(kRtpVideoGeneric, kVideoFrameKey,
|
| - kPayload, kTimestamp, 0, kFrame,
|
| - sizeof(kFrame), nullptr, &hdr));
|
| + EXPECT_TRUE(rtp_sender_video_->SendVideo(
|
| + kRtpVideoGeneric, kVideoFrameKey, kPayload, kTimestamp, 0, kFrame,
|
| + sizeof(kFrame), nullptr, &hdr, kDefaultExpectedRetransmissionTimeMs));
|
|
|
| hdr.rotation = kVideoRotation_0;
|
| - EXPECT_TRUE(rtp_sender_video_->SendVideo(kRtpVideoGeneric, kVideoFrameDelta,
|
| - kPayload, kTimestamp + 1, 0, kFrame,
|
| - sizeof(kFrame), nullptr, &hdr));
|
| + EXPECT_TRUE(rtp_sender_video_->SendVideo(
|
| + kRtpVideoGeneric, kVideoFrameDelta, kPayload, kTimestamp + 1, 0, kFrame,
|
| + sizeof(kFrame), nullptr, &hdr, kDefaultExpectedRetransmissionTimeMs));
|
|
|
| VideoRotation rotation;
|
| EXPECT_TRUE(
|
| @@ -1617,13 +1641,13 @@ TEST_P(RtpSenderVideoTest, DeltaFrameHasCVOWhenNonZero) {
|
|
|
| RTPVideoHeader hdr = {0};
|
| hdr.rotation = kVideoRotation_90;
|
| - EXPECT_TRUE(rtp_sender_video_->SendVideo(kRtpVideoGeneric, kVideoFrameKey,
|
| - kPayload, kTimestamp, 0, kFrame,
|
| - sizeof(kFrame), nullptr, &hdr));
|
| + EXPECT_TRUE(rtp_sender_video_->SendVideo(
|
| + kRtpVideoGeneric, kVideoFrameKey, kPayload, kTimestamp, 0, kFrame,
|
| + sizeof(kFrame), nullptr, &hdr, kDefaultExpectedRetransmissionTimeMs));
|
|
|
| - EXPECT_TRUE(rtp_sender_video_->SendVideo(kRtpVideoGeneric, kVideoFrameDelta,
|
| - kPayload, kTimestamp + 1, 0, kFrame,
|
| - sizeof(kFrame), nullptr, &hdr));
|
| + EXPECT_TRUE(rtp_sender_video_->SendVideo(
|
| + kRtpVideoGeneric, kVideoFrameDelta, kPayload, kTimestamp + 1, 0, kFrame,
|
| + sizeof(kFrame), nullptr, &hdr, kDefaultExpectedRetransmissionTimeMs));
|
|
|
| VideoRotation rotation;
|
| EXPECT_TRUE(
|
| @@ -1652,6 +1676,224 @@ TEST_P(RtpSenderVideoTest, SendVideoWithCameraAndFlipCVO) {
|
| ConvertCVOByteToVideoRotation(flip_bit | camera_bit | 3));
|
| }
|
|
|
| +TEST_P(RtpSenderVideoTest, RetransmissionTypesGeneric) {
|
| + RTPVideoHeader header;
|
| + header.codec = kRtpVideoGeneric;
|
| +
|
| + EXPECT_EQ(kDontRetransmit,
|
| + rtp_sender_video_->GetStorageType(
|
| + header, kRetransmitOff, kDefaultExpectedRetransmissionTimeMs));
|
| + EXPECT_EQ(kAllowRetransmission, rtp_sender_video_->GetStorageType(
|
| + header, kRetransmitBaseLayer,
|
| + kDefaultExpectedRetransmissionTimeMs));
|
| + EXPECT_EQ(kAllowRetransmission, rtp_sender_video_->GetStorageType(
|
| + header, kRetransmitHigherLayers,
|
| + kDefaultExpectedRetransmissionTimeMs));
|
| + EXPECT_EQ(kAllowRetransmission,
|
| + rtp_sender_video_->GetStorageType(
|
| + header, kConditionallyRetransmitHigherLayers,
|
| + kDefaultExpectedRetransmissionTimeMs));
|
| + EXPECT_EQ(kAllowRetransmission, rtp_sender_video_->GetStorageType(
|
| + header, kRetransmitAllPackets,
|
| + kDefaultExpectedRetransmissionTimeMs));
|
| +}
|
| +
|
| +TEST_P(RtpSenderVideoTest, RetransmissionTypesH264) {
|
| + RTPVideoHeader header;
|
| + header.codec = kRtpVideoH264;
|
| + header.codecHeader.H264.packetization_mode =
|
| + H264PacketizationMode::NonInterleaved;
|
| +
|
| + EXPECT_EQ(kDontRetransmit,
|
| + rtp_sender_video_->GetStorageType(
|
| + header, kRetransmitOff, kDefaultExpectedRetransmissionTimeMs));
|
| + EXPECT_EQ(kAllowRetransmission, rtp_sender_video_->GetStorageType(
|
| + header, kRetransmitBaseLayer,
|
| + kDefaultExpectedRetransmissionTimeMs));
|
| + EXPECT_EQ(kAllowRetransmission, rtp_sender_video_->GetStorageType(
|
| + header, kRetransmitHigherLayers,
|
| + kDefaultExpectedRetransmissionTimeMs));
|
| + EXPECT_EQ(kAllowRetransmission,
|
| + rtp_sender_video_->GetStorageType(
|
| + header, kConditionallyRetransmitHigherLayers,
|
| + kDefaultExpectedRetransmissionTimeMs));
|
| + EXPECT_EQ(kAllowRetransmission, rtp_sender_video_->GetStorageType(
|
| + header, kRetransmitAllPackets,
|
| + kDefaultExpectedRetransmissionTimeMs));
|
| +}
|
| +
|
| +TEST_P(RtpSenderVideoTest, RetransmissionTypesVP8BaseLayer) {
|
| + RTPVideoHeader header;
|
| + header.codec = kRtpVideoVp8;
|
| + header.codecHeader.VP8.temporalIdx = 0;
|
| +
|
| + EXPECT_EQ(kDontRetransmit,
|
| + rtp_sender_video_->GetStorageType(
|
| + header, kRetransmitOff, kDefaultExpectedRetransmissionTimeMs));
|
| + EXPECT_EQ(kAllowRetransmission, rtp_sender_video_->GetStorageType(
|
| + header, kRetransmitBaseLayer,
|
| + kDefaultExpectedRetransmissionTimeMs));
|
| + EXPECT_EQ(kDontRetransmit, rtp_sender_video_->GetStorageType(
|
| + header, kRetransmitHigherLayers,
|
| + kDefaultExpectedRetransmissionTimeMs));
|
| + EXPECT_EQ(kAllowRetransmission,
|
| + rtp_sender_video_->GetStorageType(
|
| + header, kRetransmitHigherLayers | kRetransmitBaseLayer,
|
| + kDefaultExpectedRetransmissionTimeMs));
|
| + EXPECT_EQ(kDontRetransmit, rtp_sender_video_->GetStorageType(
|
| + header, kConditionallyRetransmitHigherLayers,
|
| + kDefaultExpectedRetransmissionTimeMs));
|
| + EXPECT_EQ(
|
| + kAllowRetransmission,
|
| + rtp_sender_video_->GetStorageType(
|
| + header, kRetransmitBaseLayer | kConditionallyRetransmitHigherLayers,
|
| + kDefaultExpectedRetransmissionTimeMs));
|
| + EXPECT_EQ(kAllowRetransmission, rtp_sender_video_->GetStorageType(
|
| + header, kRetransmitAllPackets,
|
| + kDefaultExpectedRetransmissionTimeMs));
|
| +}
|
| +
|
| +TEST_P(RtpSenderVideoTest, RetransmissionTypesVP8HigherLayers) {
|
| + RTPVideoHeader header;
|
| + header.codec = kRtpVideoVp8;
|
| +
|
| + for (int tid = 1; tid <= kMaxTemporalStreams; ++tid) {
|
| + header.codecHeader.VP8.temporalIdx = tid;
|
| +
|
| + EXPECT_EQ(kDontRetransmit, rtp_sender_video_->GetStorageType(
|
| + header, kRetransmitOff,
|
| + kDefaultExpectedRetransmissionTimeMs));
|
| + EXPECT_EQ(kDontRetransmit, rtp_sender_video_->GetStorageType(
|
| + header, kRetransmitBaseLayer,
|
| + kDefaultExpectedRetransmissionTimeMs));
|
| + EXPECT_EQ(kAllowRetransmission, rtp_sender_video_->GetStorageType(
|
| + header, kRetransmitHigherLayers,
|
| + kDefaultExpectedRetransmissionTimeMs));
|
| + EXPECT_EQ(kAllowRetransmission,
|
| + rtp_sender_video_->GetStorageType(
|
| + header, kRetransmitHigherLayers | kRetransmitBaseLayer,
|
| + kDefaultExpectedRetransmissionTimeMs));
|
| + EXPECT_EQ(kAllowRetransmission, rtp_sender_video_->GetStorageType(
|
| + header, kRetransmitAllPackets,
|
| + kDefaultExpectedRetransmissionTimeMs));
|
| + }
|
| +}
|
| +
|
| +TEST_P(RtpSenderVideoTest, RetransmissionTypesVP9) {
|
| + RTPVideoHeader header;
|
| + header.codec = kRtpVideoVp9;
|
| +
|
| + for (int tid = 1; tid <= kMaxTemporalStreams; ++tid) {
|
| + header.codecHeader.VP9.temporal_idx = tid;
|
| +
|
| + EXPECT_EQ(kDontRetransmit, rtp_sender_video_->GetStorageType(
|
| + header, kRetransmitOff,
|
| + kDefaultExpectedRetransmissionTimeMs));
|
| + EXPECT_EQ(kDontRetransmit, rtp_sender_video_->GetStorageType(
|
| + header, kRetransmitBaseLayer,
|
| + kDefaultExpectedRetransmissionTimeMs));
|
| + EXPECT_EQ(kAllowRetransmission, rtp_sender_video_->GetStorageType(
|
| + header, kRetransmitHigherLayers,
|
| + kDefaultExpectedRetransmissionTimeMs));
|
| + EXPECT_EQ(kAllowRetransmission,
|
| + rtp_sender_video_->GetStorageType(
|
| + header, kRetransmitHigherLayers | kRetransmitBaseLayer,
|
| + kDefaultExpectedRetransmissionTimeMs));
|
| + EXPECT_EQ(kAllowRetransmission, rtp_sender_video_->GetStorageType(
|
| + header, kRetransmitAllPackets,
|
| + kDefaultExpectedRetransmissionTimeMs));
|
| + }
|
| +}
|
| +
|
| +TEST_P(RtpSenderVideoTest, ConditionalRetransmit) {
|
| + const int64_t kFrameIntervalMs = 33;
|
| + const int64_t kRttMs = (kFrameIntervalMs * 3) / 2;
|
| + const uint8_t kSettings =
|
| + kRetransmitBaseLayer | kConditionallyRetransmitHigherLayers;
|
| +
|
| + // Insert VP8 frames for all temporal layers, but stop before the final index.
|
| + RTPVideoHeader header;
|
| + header.codec = kRtpVideoVp8;
|
| +
|
| + // Fill averaging window to prevent rounding errors.
|
| + constexpr int kNumRepetitions =
|
| + (RTPSenderVideo::kTLRateWindowSizeMs + (kFrameIntervalMs / 2)) /
|
| + kFrameIntervalMs;
|
| + constexpr int kPattern[] = {0, 2, 1, 2};
|
| + for (size_t i = 0; i < arraysize(kPattern) * kNumRepetitions; ++i) {
|
| + header.codecHeader.VP8.temporalIdx = kPattern[i % arraysize(kPattern)];
|
| + rtp_sender_video_->GetStorageType(header, kSettings, kRttMs);
|
| + fake_clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
|
| + }
|
| +
|
| + // Since we're at the start of the pattern, the next expected frame in TL0 is
|
| + // right now. We will wait at most one expected retransmission time before
|
| + // acknowledging that it did not arrive, which means this frame and the next
|
| + // will not be retransmitted.
|
| + header.codecHeader.VP8.temporalIdx = 1;
|
| + EXPECT_EQ(StorageType::kDontRetransmit,
|
| + rtp_sender_video_->GetStorageType(header, kSettings, kRttMs));
|
| + fake_clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
|
| + EXPECT_EQ(StorageType::kDontRetransmit,
|
| + rtp_sender_video_->GetStorageType(header, kSettings, kRttMs));
|
| + fake_clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
|
| +
|
| + // The TL0 frame did not arrive. So allow retransmission.
|
| + EXPECT_EQ(StorageType::kAllowRetransmission,
|
| + rtp_sender_video_->GetStorageType(header, kSettings, kRttMs));
|
| + fake_clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
|
| +
|
| + // Insert a frame for TL2. We just had frame in TL1, so the next one there is
|
| + // in three frames away. TL0 is still too far in the past. So, allow
|
| + // retransmission.
|
| + header.codecHeader.VP8.temporalIdx = 2;
|
| + EXPECT_EQ(StorageType::kAllowRetransmission,
|
| + rtp_sender_video_->GetStorageType(header, kSettings, kRttMs));
|
| + fake_clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
|
| +
|
| + // Another TL2, next in TL1 is two frames away. Allow again.
|
| + EXPECT_EQ(StorageType::kAllowRetransmission,
|
| + rtp_sender_video_->GetStorageType(header, kSettings, kRttMs));
|
| + fake_clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
|
| +
|
| + // Yet another TL2, next in TL1 is now only one frame away, so don't store
|
| + // for retransmission.
|
| + EXPECT_EQ(StorageType::kDontRetransmit,
|
| + rtp_sender_video_->GetStorageType(header, kSettings, kRttMs));
|
| +}
|
| +
|
| +TEST_P(RtpSenderVideoTest, ConditionalRetransmitLimit) {
|
| + const int64_t kFrameIntervalMs = 200;
|
| + const int64_t kRttMs = (kFrameIntervalMs * 3) / 2;
|
| + const int32_t kSettings =
|
| + kRetransmitBaseLayer | kConditionallyRetransmitHigherLayers;
|
| +
|
| + // Insert VP8 frames for all temporal layers, but stop before the final index.
|
| + RTPVideoHeader header;
|
| + header.codec = kRtpVideoVp8;
|
| +
|
| + // Fill averaging window to prevent rounding errors.
|
| + constexpr int kNumRepetitions =
|
| + (RTPSenderVideo::kTLRateWindowSizeMs + (kFrameIntervalMs / 2)) /
|
| + kFrameIntervalMs;
|
| + constexpr int kPattern[] = {0, 2, 2, 2};
|
| + for (size_t i = 0; i < arraysize(kPattern) * kNumRepetitions; ++i) {
|
| + header.codecHeader.VP8.temporalIdx = kPattern[i % arraysize(kPattern)];
|
| +
|
| + rtp_sender_video_->GetStorageType(header, kSettings, kRttMs);
|
| + fake_clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
|
| + }
|
| +
|
| + // Since we're at the start of the pattern, the next expected frame will be
|
| + // right now in TL0. Put it in TL1 instead. Regular rules would dictate that
|
| + // we don't store for retransmission because we expect a frame in a lower
|
| + // layer, but that last frame in TL1 was a long time ago in absolute terms,
|
| + // so allow retransmission anyway.
|
| + header.codecHeader.VP8.temporalIdx = 1;
|
| + EXPECT_EQ(StorageType::kAllowRetransmission,
|
| + rtp_sender_video_->GetStorageType(header, kSettings, kRttMs));
|
| +}
|
| +
|
| TEST_P(RtpSenderTest, OnOverheadChanged) {
|
| MockOverheadObserver mock_overhead_observer;
|
| rtp_sender_.reset(
|
|
|