Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(85)

Unified Diff: webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc

Issue 2999063002: Add flag enabling more packets to be retransmittable. (Closed)
Patch Set: Addressed comments Created 3 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/modules/rtp_rtcp/source/rtp_sender.cc ('k') | webrtc/modules/rtp_rtcp/source/rtp_sender_video.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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(
« no previous file with comments | « webrtc/modules/rtp_rtcp/source/rtp_sender.cc ('k') | webrtc/modules/rtp_rtcp/source/rtp_sender_video.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698