1 /*
2 * Copyright (c) 2019 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/rtp_sender_video.h"
12
13 #include <memory>
14 #include <string>
15 #include <utility>
16 #include <vector>
17
18 #include "api/test/mock_frame_encryptor.h"
19 #include "api/transport/rtp/dependency_descriptor.h"
20 #include "api/video/video_codec_constants.h"
21 #include "api/video/video_timing.h"
22 #include "common_video/generic_frame_descriptor/generic_frame_info.h"
23 #include "modules/rtp_rtcp/include/rtp_cvo.h"
24 #include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
25 #include "modules/rtp_rtcp/include/rtp_rtcp.h"
26 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
27 #include "modules/rtp_rtcp/source/rtp_dependency_descriptor_extension.h"
28 #include "modules/rtp_rtcp/source/rtp_descriptor_authentication.h"
29 #include "modules/rtp_rtcp/source/rtp_format_video_generic.h"
30 #include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h"
31 #include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.h"
32 #include "modules/rtp_rtcp/source/rtp_header_extensions.h"
33 #include "modules/rtp_rtcp/source/rtp_packet_received.h"
34 #include "modules/rtp_rtcp/source/time_util.h"
35 #include "rtc_base/arraysize.h"
36 #include "rtc_base/rate_limiter.h"
37 #include "test/gmock.h"
38 #include "test/gtest.h"
39
40 namespace webrtc {
41
42 namespace {
43
44 using ::testing::_;
45 using ::testing::ElementsAre;
46 using ::testing::ElementsAreArray;
47 using ::testing::IsEmpty;
48 using ::testing::NiceMock;
49 using ::testing::Return;
50 using ::testing::ReturnArg;
51 using ::testing::SizeIs;
52 using ::testing::WithArgs;
53
54 enum : int { // The first valid value is 1.
55 kAbsoluteSendTimeExtensionId = 1,
56 kFrameMarkingExtensionId,
57 kGenericDescriptorId00,
58 kGenericDescriptorId01,
59 kDependencyDescriptorId,
60 kTransmissionTimeOffsetExtensionId,
61 kTransportSequenceNumberExtensionId,
62 kVideoRotationExtensionId,
63 kVideoTimingExtensionId,
64 kAbsoluteCaptureTimeExtensionId,
65 kPlayoutDelayExtensionId
66 };
67
68 constexpr int kPayload = 100;
69 constexpr VideoCodecType kType = VideoCodecType::kVideoCodecGeneric;
70 constexpr uint32_t kTimestamp = 10;
71 constexpr uint16_t kSeqNum = 33;
72 constexpr uint32_t kSsrc = 725242;
73 constexpr int kMaxPacketLength = 1500;
74 constexpr uint64_t kStartTime = 123456789;
75 constexpr int64_t kDefaultExpectedRetransmissionTimeMs = 125;
76
77 class LoopbackTransportTest : public webrtc::Transport {
78 public:
LoopbackTransportTest()79 LoopbackTransportTest() {
80 receivers_extensions_.Register<TransmissionOffset>(
81 kTransmissionTimeOffsetExtensionId);
82 receivers_extensions_.Register<AbsoluteSendTime>(
83 kAbsoluteSendTimeExtensionId);
84 receivers_extensions_.Register<TransportSequenceNumber>(
85 kTransportSequenceNumberExtensionId);
86 receivers_extensions_.Register<VideoOrientation>(kVideoRotationExtensionId);
87 receivers_extensions_.Register<VideoTimingExtension>(
88 kVideoTimingExtensionId);
89 receivers_extensions_.Register<RtpGenericFrameDescriptorExtension00>(
90 kGenericDescriptorId00);
91 receivers_extensions_.Register<RtpGenericFrameDescriptorExtension01>(
92 kGenericDescriptorId01);
93 receivers_extensions_.Register<RtpDependencyDescriptorExtension>(
94 kDependencyDescriptorId);
95 receivers_extensions_.Register<FrameMarkingExtension>(
96 kFrameMarkingExtensionId);
97 receivers_extensions_.Register<AbsoluteCaptureTimeExtension>(
98 kAbsoluteCaptureTimeExtensionId);
99 receivers_extensions_.Register<PlayoutDelayLimits>(
100 kPlayoutDelayExtensionId);
101 }
102
SendRtp(const uint8_t * data,size_t len,const PacketOptions & options)103 bool SendRtp(const uint8_t* data,
104 size_t len,
105 const PacketOptions& options) override {
106 sent_packets_.push_back(RtpPacketReceived(&receivers_extensions_));
107 EXPECT_TRUE(sent_packets_.back().Parse(data, len));
108 return true;
109 }
SendRtcp(const uint8_t * data,size_t len)110 bool SendRtcp(const uint8_t* data, size_t len) override { return false; }
last_sent_packet()111 const RtpPacketReceived& last_sent_packet() { return sent_packets_.back(); }
packets_sent()112 int packets_sent() { return sent_packets_.size(); }
sent_packets() const113 const std::vector<RtpPacketReceived>& sent_packets() const {
114 return sent_packets_;
115 }
116
117 private:
118 RtpHeaderExtensionMap receivers_extensions_;
119 std::vector<RtpPacketReceived> sent_packets_;
120 };
121
122 } // namespace
123
124 class TestRtpSenderVideo : public RTPSenderVideo {
125 public:
TestRtpSenderVideo(Clock * clock,RTPSender * rtp_sender,FlexfecSender * flexfec_sender,const WebRtcKeyValueConfig & field_trials)126 TestRtpSenderVideo(Clock* clock,
127 RTPSender* rtp_sender,
128 FlexfecSender* flexfec_sender,
129 const WebRtcKeyValueConfig& field_trials)
130 : RTPSenderVideo([&] {
131 Config config;
132 config.clock = clock;
133 config.rtp_sender = rtp_sender;
134 config.fec_generator = flexfec_sender;
135 config.field_trials = &field_trials;
136 return config;
137 }()) {}
~TestRtpSenderVideo()138 ~TestRtpSenderVideo() override {}
139
AllowRetransmission(const RTPVideoHeader & header,int32_t retransmission_settings,int64_t expected_retransmission_time_ms)140 bool AllowRetransmission(const RTPVideoHeader& header,
141 int32_t retransmission_settings,
142 int64_t expected_retransmission_time_ms) {
143 return RTPSenderVideo::AllowRetransmission(GetTemporalId(header),
144 retransmission_settings,
145 expected_retransmission_time_ms);
146 }
147 };
148
149 class FieldTrials : public WebRtcKeyValueConfig {
150 public:
FieldTrials(bool use_send_side_bwe_with_overhead)151 explicit FieldTrials(bool use_send_side_bwe_with_overhead)
152 : use_send_side_bwe_with_overhead_(use_send_side_bwe_with_overhead) {}
153
Lookup(absl::string_view key) const154 std::string Lookup(absl::string_view key) const override {
155 return key == "WebRTC-SendSideBwe-WithOverhead" &&
156 use_send_side_bwe_with_overhead_
157 ? "Enabled"
158 : "";
159 }
160
161 private:
162 bool use_send_side_bwe_with_overhead_;
163 };
164
165 class RtpSenderVideoTest : public ::testing::TestWithParam<bool> {
166 public:
RtpSenderVideoTest()167 RtpSenderVideoTest()
168 : field_trials_(GetParam()),
169 fake_clock_(kStartTime),
170 retransmission_rate_limiter_(&fake_clock_, 1000),
171 rtp_module_(RtpRtcp::Create([&] {
172 RtpRtcp::Configuration config;
173 config.clock = &fake_clock_;
174 config.outgoing_transport = &transport_;
175 config.retransmission_rate_limiter = &retransmission_rate_limiter_;
176 config.field_trials = &field_trials_;
177 config.local_media_ssrc = kSsrc;
178 return config;
179 }())),
180 rtp_sender_video_(&fake_clock_,
181 rtp_module_->RtpSender(),
182 nullptr,
183 field_trials_) {
184 rtp_module_->SetSequenceNumber(kSeqNum);
185 rtp_module_->SetStartTimestamp(0);
186 }
187
188 void PopulateGenericFrameDescriptor(int version);
189
190 void UsesMinimalVp8DescriptorWhenGenericFrameDescriptorExtensionIsUsed(
191 int version);
192
193 protected:
194 const RtpRtcp::Configuration config_;
195 FieldTrials field_trials_;
196 SimulatedClock fake_clock_;
197 LoopbackTransportTest transport_;
198 RateLimiter retransmission_rate_limiter_;
199 std::unique_ptr<RtpRtcp> rtp_module_;
200 TestRtpSenderVideo rtp_sender_video_;
201 };
202
TEST_P(RtpSenderVideoTest,KeyFrameHasCVO)203 TEST_P(RtpSenderVideoTest, KeyFrameHasCVO) {
204 uint8_t kFrame[kMaxPacketLength];
205 rtp_module_->RegisterRtpHeaderExtension(VideoOrientation::kUri,
206 kVideoRotationExtensionId);
207
208 RTPVideoHeader hdr;
209 hdr.rotation = kVideoRotation_0;
210 hdr.frame_type = VideoFrameType::kVideoFrameKey;
211 rtp_sender_video_.SendVideo(kPayload, kType, kTimestamp, 0, kFrame, nullptr,
212 hdr, kDefaultExpectedRetransmissionTimeMs);
213
214 VideoRotation rotation;
215 EXPECT_TRUE(
216 transport_.last_sent_packet().GetExtension<VideoOrientation>(&rotation));
217 EXPECT_EQ(kVideoRotation_0, rotation);
218 }
219
TEST_P(RtpSenderVideoTest,TimingFrameHasPacketizationTimstampSet)220 TEST_P(RtpSenderVideoTest, TimingFrameHasPacketizationTimstampSet) {
221 uint8_t kFrame[kMaxPacketLength];
222 const int64_t kPacketizationTimeMs = 100;
223 const int64_t kEncodeStartDeltaMs = 10;
224 const int64_t kEncodeFinishDeltaMs = 50;
225 rtp_module_->RegisterRtpHeaderExtension(VideoTimingExtension::kUri,
226 kVideoTimingExtensionId);
227
228 const int64_t kCaptureTimestamp = fake_clock_.TimeInMilliseconds();
229
230 RTPVideoHeader hdr;
231 hdr.video_timing.flags = VideoSendTiming::kTriggeredByTimer;
232 hdr.video_timing.encode_start_delta_ms = kEncodeStartDeltaMs;
233 hdr.video_timing.encode_finish_delta_ms = kEncodeFinishDeltaMs;
234
235 fake_clock_.AdvanceTimeMilliseconds(kPacketizationTimeMs);
236 hdr.frame_type = VideoFrameType::kVideoFrameKey;
237 rtp_sender_video_.SendVideo(kPayload, kType, kTimestamp, kCaptureTimestamp,
238 kFrame, nullptr, hdr,
239 kDefaultExpectedRetransmissionTimeMs);
240 VideoSendTiming timing;
241 EXPECT_TRUE(transport_.last_sent_packet().GetExtension<VideoTimingExtension>(
242 &timing));
243 EXPECT_EQ(kPacketizationTimeMs, timing.packetization_finish_delta_ms);
244 EXPECT_EQ(kEncodeStartDeltaMs, timing.encode_start_delta_ms);
245 EXPECT_EQ(kEncodeFinishDeltaMs, timing.encode_finish_delta_ms);
246 }
247
TEST_P(RtpSenderVideoTest,DeltaFrameHasCVOWhenChanged)248 TEST_P(RtpSenderVideoTest, DeltaFrameHasCVOWhenChanged) {
249 uint8_t kFrame[kMaxPacketLength];
250 rtp_module_->RegisterRtpHeaderExtension(VideoOrientation::kUri,
251 kVideoRotationExtensionId);
252
253 RTPVideoHeader hdr;
254 hdr.rotation = kVideoRotation_90;
255 hdr.frame_type = VideoFrameType::kVideoFrameKey;
256 EXPECT_TRUE(rtp_sender_video_.SendVideo(
257 kPayload, kType, kTimestamp, 0, kFrame, nullptr, hdr,
258 kDefaultExpectedRetransmissionTimeMs));
259
260 hdr.rotation = kVideoRotation_0;
261 hdr.frame_type = VideoFrameType::kVideoFrameDelta;
262 EXPECT_TRUE(rtp_sender_video_.SendVideo(
263 kPayload, kType, kTimestamp + 1, 0, kFrame, nullptr, hdr,
264 kDefaultExpectedRetransmissionTimeMs));
265
266 VideoRotation rotation;
267 EXPECT_TRUE(
268 transport_.last_sent_packet().GetExtension<VideoOrientation>(&rotation));
269 EXPECT_EQ(kVideoRotation_0, rotation);
270 }
271
TEST_P(RtpSenderVideoTest,DeltaFrameHasCVOWhenNonZero)272 TEST_P(RtpSenderVideoTest, DeltaFrameHasCVOWhenNonZero) {
273 uint8_t kFrame[kMaxPacketLength];
274 rtp_module_->RegisterRtpHeaderExtension(VideoOrientation::kUri,
275 kVideoRotationExtensionId);
276
277 RTPVideoHeader hdr;
278 hdr.rotation = kVideoRotation_90;
279 hdr.frame_type = VideoFrameType::kVideoFrameKey;
280 EXPECT_TRUE(rtp_sender_video_.SendVideo(
281 kPayload, kType, kTimestamp, 0, kFrame, nullptr, hdr,
282 kDefaultExpectedRetransmissionTimeMs));
283
284 hdr.frame_type = VideoFrameType::kVideoFrameDelta;
285 EXPECT_TRUE(rtp_sender_video_.SendVideo(
286 kPayload, kType, kTimestamp + 1, 0, kFrame, nullptr, hdr,
287 kDefaultExpectedRetransmissionTimeMs));
288
289 VideoRotation rotation;
290 EXPECT_TRUE(
291 transport_.last_sent_packet().GetExtension<VideoOrientation>(&rotation));
292 EXPECT_EQ(kVideoRotation_90, rotation);
293 }
294
TEST_P(RtpSenderVideoTest,CheckH264FrameMarking)295 TEST_P(RtpSenderVideoTest, CheckH264FrameMarking) {
296 uint8_t kFrame[kMaxPacketLength];
297 rtp_module_->RegisterRtpHeaderExtension(FrameMarkingExtension::kUri,
298 kFrameMarkingExtensionId);
299
300 RTPFragmentationHeader frag;
301 frag.VerifyAndAllocateFragmentationHeader(1);
302 frag.fragmentationOffset[0] = 0;
303 frag.fragmentationLength[0] = sizeof(kFrame);
304
305 RTPVideoHeader hdr;
306 hdr.video_type_header.emplace<RTPVideoHeaderH264>().packetization_mode =
307 H264PacketizationMode::NonInterleaved;
308 hdr.codec = kVideoCodecH264;
309 hdr.frame_marking.temporal_id = kNoTemporalIdx;
310 hdr.frame_marking.tl0_pic_idx = 99;
311 hdr.frame_marking.base_layer_sync = true;
312 hdr.frame_type = VideoFrameType::kVideoFrameDelta;
313 rtp_sender_video_.SendVideo(kPayload, kType, kTimestamp, 0, kFrame, &frag,
314 hdr, kDefaultExpectedRetransmissionTimeMs);
315
316 FrameMarking fm;
317 EXPECT_FALSE(
318 transport_.last_sent_packet().GetExtension<FrameMarkingExtension>(&fm));
319
320 hdr.frame_marking.temporal_id = 0;
321 hdr.frame_type = VideoFrameType::kVideoFrameDelta;
322 rtp_sender_video_.SendVideo(kPayload, kType, kTimestamp + 1, 0, kFrame, &frag,
323 hdr, kDefaultExpectedRetransmissionTimeMs);
324
325 EXPECT_TRUE(
326 transport_.last_sent_packet().GetExtension<FrameMarkingExtension>(&fm));
327 EXPECT_EQ(hdr.frame_marking.temporal_id, fm.temporal_id);
328 EXPECT_EQ(hdr.frame_marking.tl0_pic_idx, fm.tl0_pic_idx);
329 EXPECT_EQ(hdr.frame_marking.base_layer_sync, fm.base_layer_sync);
330 }
331
332 // Make sure rotation is parsed correctly when the Camera (C) and Flip (F) bits
333 // are set in the CVO byte.
TEST_P(RtpSenderVideoTest,SendVideoWithCameraAndFlipCVO)334 TEST_P(RtpSenderVideoTest, SendVideoWithCameraAndFlipCVO) {
335 // Test extracting rotation when Camera (C) and Flip (F) bits are zero.
336 EXPECT_EQ(kVideoRotation_0, ConvertCVOByteToVideoRotation(0));
337 EXPECT_EQ(kVideoRotation_90, ConvertCVOByteToVideoRotation(1));
338 EXPECT_EQ(kVideoRotation_180, ConvertCVOByteToVideoRotation(2));
339 EXPECT_EQ(kVideoRotation_270, ConvertCVOByteToVideoRotation(3));
340 // Test extracting rotation when Camera (C) and Flip (F) bits are set.
341 const int flip_bit = 1 << 2;
342 const int camera_bit = 1 << 3;
343 EXPECT_EQ(kVideoRotation_0,
344 ConvertCVOByteToVideoRotation(flip_bit | camera_bit | 0));
345 EXPECT_EQ(kVideoRotation_90,
346 ConvertCVOByteToVideoRotation(flip_bit | camera_bit | 1));
347 EXPECT_EQ(kVideoRotation_180,
348 ConvertCVOByteToVideoRotation(flip_bit | camera_bit | 2));
349 EXPECT_EQ(kVideoRotation_270,
350 ConvertCVOByteToVideoRotation(flip_bit | camera_bit | 3));
351 }
352
TEST_P(RtpSenderVideoTest,RetransmissionTypesGeneric)353 TEST_P(RtpSenderVideoTest, RetransmissionTypesGeneric) {
354 RTPVideoHeader header;
355 header.codec = kVideoCodecGeneric;
356
357 EXPECT_FALSE(rtp_sender_video_.AllowRetransmission(
358 header, kRetransmitOff, kDefaultExpectedRetransmissionTimeMs));
359 EXPECT_TRUE(rtp_sender_video_.AllowRetransmission(
360 header, kRetransmitBaseLayer, kDefaultExpectedRetransmissionTimeMs));
361 EXPECT_TRUE(rtp_sender_video_.AllowRetransmission(
362 header, kRetransmitHigherLayers, kDefaultExpectedRetransmissionTimeMs));
363 EXPECT_TRUE(rtp_sender_video_.AllowRetransmission(
364 header, kConditionallyRetransmitHigherLayers,
365 kDefaultExpectedRetransmissionTimeMs));
366 }
367
TEST_P(RtpSenderVideoTest,RetransmissionTypesH264)368 TEST_P(RtpSenderVideoTest, RetransmissionTypesH264) {
369 RTPVideoHeader header;
370 header.video_type_header.emplace<RTPVideoHeaderH264>().packetization_mode =
371 H264PacketizationMode::NonInterleaved;
372 header.codec = kVideoCodecH264;
373 header.frame_marking.temporal_id = kNoTemporalIdx;
374
375 EXPECT_FALSE(rtp_sender_video_.AllowRetransmission(
376 header, kRetransmitOff, kDefaultExpectedRetransmissionTimeMs));
377 EXPECT_TRUE(rtp_sender_video_.AllowRetransmission(
378 header, kRetransmitBaseLayer, kDefaultExpectedRetransmissionTimeMs));
379 EXPECT_TRUE(rtp_sender_video_.AllowRetransmission(
380 header, kRetransmitHigherLayers, kDefaultExpectedRetransmissionTimeMs));
381 EXPECT_TRUE(rtp_sender_video_.AllowRetransmission(
382 header, kConditionallyRetransmitHigherLayers,
383 kDefaultExpectedRetransmissionTimeMs));
384
385 // Test higher level retransmit.
386 for (int tid = 0; tid <= kMaxTemporalStreams; ++tid) {
387 header.frame_marking.temporal_id = tid;
388 EXPECT_TRUE(rtp_sender_video_.AllowRetransmission(
389 header, kRetransmitHigherLayers | kRetransmitBaseLayer,
390 kDefaultExpectedRetransmissionTimeMs));
391 }
392 }
393
TEST_P(RtpSenderVideoTest,RetransmissionTypesVP8BaseLayer)394 TEST_P(RtpSenderVideoTest, RetransmissionTypesVP8BaseLayer) {
395 RTPVideoHeader header;
396 header.codec = kVideoCodecVP8;
397 auto& vp8_header = header.video_type_header.emplace<RTPVideoHeaderVP8>();
398 vp8_header.temporalIdx = 0;
399
400 EXPECT_FALSE(rtp_sender_video_.AllowRetransmission(
401 header, kRetransmitOff, kDefaultExpectedRetransmissionTimeMs));
402 EXPECT_TRUE(rtp_sender_video_.AllowRetransmission(
403 header, kRetransmitBaseLayer, kDefaultExpectedRetransmissionTimeMs));
404 EXPECT_FALSE(rtp_sender_video_.AllowRetransmission(
405 header, kRetransmitHigherLayers, kDefaultExpectedRetransmissionTimeMs));
406 EXPECT_TRUE(rtp_sender_video_.AllowRetransmission(
407 header, kRetransmitHigherLayers | kRetransmitBaseLayer,
408 kDefaultExpectedRetransmissionTimeMs));
409 EXPECT_FALSE(rtp_sender_video_.AllowRetransmission(
410 header, kConditionallyRetransmitHigherLayers,
411 kDefaultExpectedRetransmissionTimeMs));
412 EXPECT_TRUE(rtp_sender_video_.AllowRetransmission(
413 header, kRetransmitBaseLayer | kConditionallyRetransmitHigherLayers,
414 kDefaultExpectedRetransmissionTimeMs));
415 }
416
TEST_P(RtpSenderVideoTest,RetransmissionTypesVP8HigherLayers)417 TEST_P(RtpSenderVideoTest, RetransmissionTypesVP8HigherLayers) {
418 RTPVideoHeader header;
419 header.codec = kVideoCodecVP8;
420
421 auto& vp8_header = header.video_type_header.emplace<RTPVideoHeaderVP8>();
422 for (int tid = 1; tid <= kMaxTemporalStreams; ++tid) {
423 vp8_header.temporalIdx = tid;
424
425 EXPECT_FALSE(rtp_sender_video_.AllowRetransmission(
426 header, kRetransmitOff, kDefaultExpectedRetransmissionTimeMs));
427 EXPECT_FALSE(rtp_sender_video_.AllowRetransmission(
428 header, kRetransmitBaseLayer, kDefaultExpectedRetransmissionTimeMs));
429 EXPECT_TRUE(rtp_sender_video_.AllowRetransmission(
430 header, kRetransmitHigherLayers, kDefaultExpectedRetransmissionTimeMs));
431 EXPECT_TRUE(rtp_sender_video_.AllowRetransmission(
432 header, kRetransmitHigherLayers | kRetransmitBaseLayer,
433 kDefaultExpectedRetransmissionTimeMs));
434 }
435 }
436
TEST_P(RtpSenderVideoTest,RetransmissionTypesVP9)437 TEST_P(RtpSenderVideoTest, RetransmissionTypesVP9) {
438 RTPVideoHeader header;
439 header.codec = kVideoCodecVP9;
440
441 auto& vp9_header = header.video_type_header.emplace<RTPVideoHeaderVP9>();
442 for (int tid = 1; tid <= kMaxTemporalStreams; ++tid) {
443 vp9_header.temporal_idx = tid;
444
445 EXPECT_FALSE(rtp_sender_video_.AllowRetransmission(
446 header, kRetransmitOff, kDefaultExpectedRetransmissionTimeMs));
447 EXPECT_FALSE(rtp_sender_video_.AllowRetransmission(
448 header, kRetransmitBaseLayer, kDefaultExpectedRetransmissionTimeMs));
449 EXPECT_TRUE(rtp_sender_video_.AllowRetransmission(
450 header, kRetransmitHigherLayers, kDefaultExpectedRetransmissionTimeMs));
451 EXPECT_TRUE(rtp_sender_video_.AllowRetransmission(
452 header, kRetransmitHigherLayers | kRetransmitBaseLayer,
453 kDefaultExpectedRetransmissionTimeMs));
454 }
455 }
456
TEST_P(RtpSenderVideoTest,ConditionalRetransmit)457 TEST_P(RtpSenderVideoTest, ConditionalRetransmit) {
458 const int64_t kFrameIntervalMs = 33;
459 const int64_t kRttMs = (kFrameIntervalMs * 3) / 2;
460 const uint8_t kSettings =
461 kRetransmitBaseLayer | kConditionallyRetransmitHigherLayers;
462
463 // Insert VP8 frames for all temporal layers, but stop before the final index.
464 RTPVideoHeader header;
465 header.codec = kVideoCodecVP8;
466
467 // Fill averaging window to prevent rounding errors.
468 constexpr int kNumRepetitions =
469 (RTPSenderVideo::kTLRateWindowSizeMs + (kFrameIntervalMs / 2)) /
470 kFrameIntervalMs;
471 constexpr int kPattern[] = {0, 2, 1, 2};
472 auto& vp8_header = header.video_type_header.emplace<RTPVideoHeaderVP8>();
473 for (size_t i = 0; i < arraysize(kPattern) * kNumRepetitions; ++i) {
474 vp8_header.temporalIdx = kPattern[i % arraysize(kPattern)];
475 rtp_sender_video_.AllowRetransmission(header, kSettings, kRttMs);
476 fake_clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
477 }
478
479 // Since we're at the start of the pattern, the next expected frame in TL0 is
480 // right now. We will wait at most one expected retransmission time before
481 // acknowledging that it did not arrive, which means this frame and the next
482 // will not be retransmitted.
483 vp8_header.temporalIdx = 1;
484 EXPECT_FALSE(
485 rtp_sender_video_.AllowRetransmission(header, kSettings, kRttMs));
486 fake_clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
487 EXPECT_FALSE(
488 rtp_sender_video_.AllowRetransmission(header, kSettings, kRttMs));
489 fake_clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
490
491 // The TL0 frame did not arrive. So allow retransmission.
492 EXPECT_TRUE(rtp_sender_video_.AllowRetransmission(header, kSettings, kRttMs));
493 fake_clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
494
495 // Insert a frame for TL2. We just had frame in TL1, so the next one there is
496 // in three frames away. TL0 is still too far in the past. So, allow
497 // retransmission.
498 vp8_header.temporalIdx = 2;
499 EXPECT_TRUE(rtp_sender_video_.AllowRetransmission(header, kSettings, kRttMs));
500 fake_clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
501
502 // Another TL2, next in TL1 is two frames away. Allow again.
503 EXPECT_TRUE(rtp_sender_video_.AllowRetransmission(header, kSettings, kRttMs));
504 fake_clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
505
506 // Yet another TL2, next in TL1 is now only one frame away, so don't store
507 // for retransmission.
508 EXPECT_FALSE(
509 rtp_sender_video_.AllowRetransmission(header, kSettings, kRttMs));
510 }
511
TEST_P(RtpSenderVideoTest,ConditionalRetransmitLimit)512 TEST_P(RtpSenderVideoTest, ConditionalRetransmitLimit) {
513 const int64_t kFrameIntervalMs = 200;
514 const int64_t kRttMs = (kFrameIntervalMs * 3) / 2;
515 const int32_t kSettings =
516 kRetransmitBaseLayer | kConditionallyRetransmitHigherLayers;
517
518 // Insert VP8 frames for all temporal layers, but stop before the final index.
519 RTPVideoHeader header;
520 header.codec = kVideoCodecVP8;
521
522 // Fill averaging window to prevent rounding errors.
523 constexpr int kNumRepetitions =
524 (RTPSenderVideo::kTLRateWindowSizeMs + (kFrameIntervalMs / 2)) /
525 kFrameIntervalMs;
526 constexpr int kPattern[] = {0, 2, 2, 2};
527 auto& vp8_header = header.video_type_header.emplace<RTPVideoHeaderVP8>();
528 for (size_t i = 0; i < arraysize(kPattern) * kNumRepetitions; ++i) {
529 vp8_header.temporalIdx = kPattern[i % arraysize(kPattern)];
530
531 rtp_sender_video_.AllowRetransmission(header, kSettings, kRttMs);
532 fake_clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
533 }
534
535 // Since we're at the start of the pattern, the next expected frame will be
536 // right now in TL0. Put it in TL1 instead. Regular rules would dictate that
537 // we don't store for retransmission because we expect a frame in a lower
538 // layer, but that last frame in TL1 was a long time ago in absolute terms,
539 // so allow retransmission anyway.
540 vp8_header.temporalIdx = 1;
541 EXPECT_TRUE(rtp_sender_video_.AllowRetransmission(header, kSettings, kRttMs));
542 }
543
TEST_P(RtpSenderVideoTest,SendsDependencyDescriptorWhenVideoStructureIsSet)544 TEST_P(RtpSenderVideoTest, SendsDependencyDescriptorWhenVideoStructureIsSet) {
545 const int64_t kFrameId = 100000;
546 uint8_t kFrame[100];
547 rtp_module_->RegisterRtpHeaderExtension(
548 RtpDependencyDescriptorExtension::kUri, kDependencyDescriptorId);
549 FrameDependencyStructure video_structure;
550 video_structure.num_decode_targets = 2;
551 video_structure.templates = {
552 GenericFrameInfo::Builder().S(0).T(0).Dtis("SS").Build(),
553 GenericFrameInfo::Builder().S(1).T(0).Dtis("-S").Build(),
554 GenericFrameInfo::Builder().S(1).T(1).Dtis("-D").Build(),
555 };
556 rtp_sender_video_.SetVideoStructure(&video_structure);
557
558 // Send key frame.
559 RTPVideoHeader hdr;
560 RTPVideoHeader::GenericDescriptorInfo& generic = hdr.generic.emplace();
561 generic.frame_id = kFrameId;
562 generic.temporal_index = 0;
563 generic.spatial_index = 0;
564 generic.decode_target_indications = {DecodeTargetIndication::kSwitch,
565 DecodeTargetIndication::kSwitch};
566 hdr.frame_type = VideoFrameType::kVideoFrameKey;
567 rtp_sender_video_.SendVideo(kPayload, kType, kTimestamp, 0, kFrame, nullptr,
568 hdr, kDefaultExpectedRetransmissionTimeMs);
569
570 ASSERT_EQ(transport_.packets_sent(), 1);
571 DependencyDescriptor descriptor_key;
572 ASSERT_TRUE(transport_.last_sent_packet()
573 .GetExtension<RtpDependencyDescriptorExtension>(
574 nullptr, &descriptor_key));
575 ASSERT_TRUE(descriptor_key.attached_structure);
576 EXPECT_EQ(descriptor_key.attached_structure->num_decode_targets, 2);
577 EXPECT_THAT(descriptor_key.attached_structure->templates, SizeIs(3));
578 EXPECT_EQ(descriptor_key.frame_number, kFrameId & 0xFFFF);
579 EXPECT_EQ(descriptor_key.frame_dependencies.spatial_id, 0);
580 EXPECT_EQ(descriptor_key.frame_dependencies.temporal_id, 0);
581 EXPECT_EQ(descriptor_key.frame_dependencies.decode_target_indications,
582 generic.decode_target_indications);
583 EXPECT_THAT(descriptor_key.frame_dependencies.frame_diffs, IsEmpty());
584
585 // Send delta frame.
586 generic.frame_id = kFrameId + 1;
587 generic.temporal_index = 1;
588 generic.spatial_index = 1;
589 generic.dependencies = {kFrameId, kFrameId - 500};
590 generic.decode_target_indications = {DecodeTargetIndication::kNotPresent,
591 DecodeTargetIndication::kRequired};
592 hdr.frame_type = VideoFrameType::kVideoFrameDelta;
593 rtp_sender_video_.SendVideo(kPayload, kType, kTimestamp, 0, kFrame, nullptr,
594 hdr, kDefaultExpectedRetransmissionTimeMs);
595
596 EXPECT_EQ(transport_.packets_sent(), 2);
597 DependencyDescriptor descriptor_delta;
598 ASSERT_TRUE(
599 transport_.last_sent_packet()
600 .GetExtension<RtpDependencyDescriptorExtension>(
601 descriptor_key.attached_structure.get(), &descriptor_delta));
602 EXPECT_EQ(descriptor_delta.attached_structure, nullptr);
603 EXPECT_EQ(descriptor_delta.frame_number, (kFrameId + 1) & 0xFFFF);
604 EXPECT_EQ(descriptor_delta.frame_dependencies.spatial_id, 1);
605 EXPECT_EQ(descriptor_delta.frame_dependencies.temporal_id, 1);
606 EXPECT_EQ(descriptor_delta.frame_dependencies.decode_target_indications,
607 generic.decode_target_indications);
608 EXPECT_THAT(descriptor_delta.frame_dependencies.frame_diffs,
609 ElementsAre(1, 501));
610 }
611
TEST_P(RtpSenderVideoTest,SetDiffentVideoStructureAvoidsCollisionWithThePreviousStructure)612 TEST_P(RtpSenderVideoTest,
613 SetDiffentVideoStructureAvoidsCollisionWithThePreviousStructure) {
614 const int64_t kFrameId = 100000;
615 uint8_t kFrame[100];
616 rtp_module_->RegisterRtpHeaderExtension(
617 RtpDependencyDescriptorExtension::kUri, kDependencyDescriptorId);
618 FrameDependencyStructure video_structure1;
619 video_structure1.num_decode_targets = 2;
620 video_structure1.templates = {
621 GenericFrameInfo::Builder().S(0).T(0).Dtis("SS").Build(),
622 GenericFrameInfo::Builder().S(0).T(1).Dtis("D-").Build(),
623 };
624 FrameDependencyStructure video_structure2;
625 video_structure2.num_decode_targets = 2;
626 video_structure2.templates = {
627 GenericFrameInfo::Builder().S(0).T(0).Dtis("SS").Build(),
628 GenericFrameInfo::Builder().S(0).T(1).Dtis("R-").Build(),
629 };
630
631 // Send 1st key frame.
632 RTPVideoHeader hdr;
633 RTPVideoHeader::GenericDescriptorInfo& generic = hdr.generic.emplace();
634 generic.frame_id = kFrameId;
635 generic.decode_target_indications = {DecodeTargetIndication::kSwitch,
636 DecodeTargetIndication::kSwitch};
637 hdr.frame_type = VideoFrameType::kVideoFrameKey;
638 rtp_sender_video_.SetVideoStructure(&video_structure1);
639 rtp_sender_video_.SendVideo(kPayload, kType, kTimestamp, 0, kFrame, nullptr,
640 hdr, kDefaultExpectedRetransmissionTimeMs);
641 // Parse 1st extension.
642 ASSERT_EQ(transport_.packets_sent(), 1);
643 DependencyDescriptor descriptor_key1;
644 ASSERT_TRUE(transport_.last_sent_packet()
645 .GetExtension<RtpDependencyDescriptorExtension>(
646 nullptr, &descriptor_key1));
647 ASSERT_TRUE(descriptor_key1.attached_structure);
648
649 // Send the delta frame.
650 generic.frame_id = kFrameId + 1;
651 generic.temporal_index = 1;
652 generic.decode_target_indications = {DecodeTargetIndication::kDiscardable,
653 DecodeTargetIndication::kNotPresent};
654 hdr.frame_type = VideoFrameType::kVideoFrameDelta;
655 rtp_sender_video_.SendVideo(kPayload, kType, kTimestamp, 0, kFrame, nullptr,
656 hdr, kDefaultExpectedRetransmissionTimeMs);
657
658 ASSERT_EQ(transport_.packets_sent(), 2);
659 RtpPacket delta_packet = transport_.last_sent_packet();
660
661 // Send 2nd key frame.
662 generic.frame_id = kFrameId + 2;
663 generic.decode_target_indications = {DecodeTargetIndication::kSwitch,
664 DecodeTargetIndication::kSwitch};
665 hdr.frame_type = VideoFrameType::kVideoFrameKey;
666 rtp_sender_video_.SetVideoStructure(&video_structure2);
667 rtp_sender_video_.SendVideo(kPayload, kType, kTimestamp, 0, kFrame, nullptr,
668 hdr, kDefaultExpectedRetransmissionTimeMs);
669 // Parse the 2nd key frame.
670 ASSERT_EQ(transport_.packets_sent(), 3);
671 DependencyDescriptor descriptor_key2;
672 ASSERT_TRUE(transport_.last_sent_packet()
673 .GetExtension<RtpDependencyDescriptorExtension>(
674 nullptr, &descriptor_key2));
675 ASSERT_TRUE(descriptor_key2.attached_structure);
676
677 // Try to parse the 1st delta frame. It should parseble using the structure
678 // from the 1st key frame, but not using the structure from the 2nd key frame.
679 DependencyDescriptor descriptor_delta;
680 EXPECT_TRUE(delta_packet.GetExtension<RtpDependencyDescriptorExtension>(
681 descriptor_key1.attached_structure.get(), &descriptor_delta));
682 EXPECT_FALSE(delta_packet.GetExtension<RtpDependencyDescriptorExtension>(
683 descriptor_key2.attached_structure.get(), &descriptor_delta));
684 }
685
TEST_P(RtpSenderVideoTest,AuthenticateVideoHeaderWhenDependencyDescriptorExtensionIsUsed)686 TEST_P(RtpSenderVideoTest,
687 AuthenticateVideoHeaderWhenDependencyDescriptorExtensionIsUsed) {
688 static constexpr size_t kFrameSize = 100;
689 uint8_t kFrame[kFrameSize] = {1, 2, 3, 4};
690
691 rtp_module_->RegisterRtpHeaderExtension(
692 RtpDependencyDescriptorExtension::kUri, kDependencyDescriptorId);
693 rtc::scoped_refptr<MockFrameEncryptor> encryptor(
694 new rtc::RefCountedObject<NiceMock<MockFrameEncryptor>>);
695 ON_CALL(*encryptor, GetMaxCiphertextByteSize).WillByDefault(ReturnArg<1>());
696 ON_CALL(*encryptor, Encrypt)
697 .WillByDefault(WithArgs<3, 5>(
698 [](rtc::ArrayView<const uint8_t> frame, size_t* bytes_written) {
699 *bytes_written = frame.size();
700 return 0;
701 }));
702 RTPSenderVideo::Config config;
703 config.clock = &fake_clock_;
704 config.rtp_sender = rtp_module_->RtpSender();
705 config.field_trials = &field_trials_;
706 config.frame_encryptor = encryptor;
707 RTPSenderVideo rtp_sender_video(config);
708
709 FrameDependencyStructure video_structure;
710 video_structure.num_decode_targets = 1;
711 video_structure.templates = {GenericFrameInfo::Builder().Dtis("S").Build()};
712 rtp_sender_video.SetVideoStructure(&video_structure);
713
714 // Send key frame.
715 RTPVideoHeader hdr;
716 hdr.frame_type = VideoFrameType::kVideoFrameKey;
717 hdr.generic.emplace().decode_target_indications =
718 video_structure.templates[0].decode_target_indications;
719
720 EXPECT_CALL(*encryptor,
721 Encrypt(_, _, Not(IsEmpty()), ElementsAreArray(kFrame), _, _));
722 rtp_sender_video.SendVideo(kPayload, kType, kTimestamp, 0, kFrame, nullptr,
723 hdr, kDefaultExpectedRetransmissionTimeMs);
724 // Double check packet with the dependency descriptor is sent.
725 ASSERT_EQ(transport_.packets_sent(), 1);
726 EXPECT_TRUE(transport_.last_sent_packet()
727 .HasExtension<RtpDependencyDescriptorExtension>());
728 }
729
PopulateGenericFrameDescriptor(int version)730 void RtpSenderVideoTest::PopulateGenericFrameDescriptor(int version) {
731 const absl::string_view ext_uri =
732 (version == 0) ? RtpGenericFrameDescriptorExtension00::kUri
733 : RtpGenericFrameDescriptorExtension01::kUri;
734 const int ext_id =
735 (version == 0) ? kGenericDescriptorId00 : kGenericDescriptorId01;
736
737 const int64_t kFrameId = 100000;
738 uint8_t kFrame[100];
739 rtp_module_->RegisterRtpHeaderExtension(ext_uri, ext_id);
740
741 RTPVideoHeader hdr;
742 RTPVideoHeader::GenericDescriptorInfo& generic = hdr.generic.emplace();
743 generic.frame_id = kFrameId;
744 generic.temporal_index = 3;
745 generic.spatial_index = 2;
746 generic.dependencies.push_back(kFrameId - 1);
747 generic.dependencies.push_back(kFrameId - 500);
748 hdr.frame_type = VideoFrameType::kVideoFrameDelta;
749 rtp_sender_video_.SendVideo(kPayload, kType, kTimestamp, 0, kFrame, nullptr,
750 hdr, kDefaultExpectedRetransmissionTimeMs);
751
752 RtpGenericFrameDescriptor descriptor_wire;
753 EXPECT_EQ(1, transport_.packets_sent());
754 if (version == 0) {
755 ASSERT_TRUE(transport_.last_sent_packet()
756 .GetExtension<RtpGenericFrameDescriptorExtension00>(
757 &descriptor_wire));
758 } else {
759 ASSERT_TRUE(transport_.last_sent_packet()
760 .GetExtension<RtpGenericFrameDescriptorExtension01>(
761 &descriptor_wire));
762 }
763 EXPECT_EQ(static_cast<uint16_t>(generic.frame_id), descriptor_wire.FrameId());
764 EXPECT_EQ(generic.temporal_index, descriptor_wire.TemporalLayer());
765 EXPECT_THAT(descriptor_wire.FrameDependenciesDiffs(), ElementsAre(1, 500));
766 EXPECT_EQ(descriptor_wire.SpatialLayersBitmask(), 0b0000'0100);
767 }
768
TEST_P(RtpSenderVideoTest,PopulateGenericFrameDescriptor00)769 TEST_P(RtpSenderVideoTest, PopulateGenericFrameDescriptor00) {
770 PopulateGenericFrameDescriptor(0);
771 }
772
TEST_P(RtpSenderVideoTest,PopulateGenericFrameDescriptor01)773 TEST_P(RtpSenderVideoTest, PopulateGenericFrameDescriptor01) {
774 PopulateGenericFrameDescriptor(1);
775 }
776
777 void RtpSenderVideoTest::
UsesMinimalVp8DescriptorWhenGenericFrameDescriptorExtensionIsUsed(int version)778 UsesMinimalVp8DescriptorWhenGenericFrameDescriptorExtensionIsUsed(
779 int version) {
780 const int64_t kFrameId = 100000;
781 const size_t kFrameSize = 100;
782 uint8_t kFrame[kFrameSize];
783
784 if (version == 0) {
785 rtp_module_->RegisterRtpHeaderExtension(
786 RtpGenericFrameDescriptorExtension00::kUri, kGenericDescriptorId00);
787 } else {
788 rtp_module_->RegisterRtpHeaderExtension(
789 RtpGenericFrameDescriptorExtension01::kUri, kGenericDescriptorId01);
790 }
791
792 RTPVideoHeader hdr;
793 hdr.codec = kVideoCodecVP8;
794 RTPVideoHeaderVP8& vp8 = hdr.video_type_header.emplace<RTPVideoHeaderVP8>();
795 vp8.pictureId = kFrameId % 0X7FFF;
796 vp8.tl0PicIdx = 13;
797 vp8.temporalIdx = 1;
798 vp8.keyIdx = 2;
799 RTPVideoHeader::GenericDescriptorInfo& generic = hdr.generic.emplace();
800 generic.frame_id = kFrameId;
801 hdr.frame_type = VideoFrameType::kVideoFrameDelta;
802 rtp_sender_video_.SendVideo(kPayload, VideoCodecType::kVideoCodecVP8,
803 kTimestamp, 0, kFrame, nullptr, hdr,
804 kDefaultExpectedRetransmissionTimeMs);
805
806 ASSERT_EQ(transport_.packets_sent(), 1);
807 // Expect only minimal 1-byte vp8 descriptor was generated.
808 EXPECT_EQ(transport_.last_sent_packet().payload_size(), 1 + kFrameSize);
809 }
810
TEST_P(RtpSenderVideoTest,UsesMinimalVp8DescriptorWhenGenericFrameDescriptorExtensionIsUsed00)811 TEST_P(RtpSenderVideoTest,
812 UsesMinimalVp8DescriptorWhenGenericFrameDescriptorExtensionIsUsed00) {
813 UsesMinimalVp8DescriptorWhenGenericFrameDescriptorExtensionIsUsed(0);
814 }
815
TEST_P(RtpSenderVideoTest,UsesMinimalVp8DescriptorWhenGenericFrameDescriptorExtensionIsUsed01)816 TEST_P(RtpSenderVideoTest,
817 UsesMinimalVp8DescriptorWhenGenericFrameDescriptorExtensionIsUsed01) {
818 UsesMinimalVp8DescriptorWhenGenericFrameDescriptorExtensionIsUsed(1);
819 }
820
TEST_P(RtpSenderVideoTest,AbsoluteCaptureTime)821 TEST_P(RtpSenderVideoTest, AbsoluteCaptureTime) {
822 constexpr int64_t kAbsoluteCaptureTimestampMs = 12345678;
823 uint8_t kFrame[kMaxPacketLength];
824 rtp_module_->RegisterRtpHeaderExtension(AbsoluteCaptureTimeExtension::kUri,
825 kAbsoluteCaptureTimeExtensionId);
826
827 RTPVideoHeader hdr;
828 hdr.frame_type = VideoFrameType::kVideoFrameKey;
829 rtp_sender_video_.SendVideo(kPayload, kType, kTimestamp,
830 kAbsoluteCaptureTimestampMs, kFrame, nullptr, hdr,
831 kDefaultExpectedRetransmissionTimeMs);
832
833 // It is expected that one and only one of the packets sent on this video
834 // frame has absolute capture time header extension.
835 int packets_with_abs_capture_time = 0;
836 for (const RtpPacketReceived& packet : transport_.sent_packets()) {
837 auto absolute_capture_time =
838 packet.GetExtension<AbsoluteCaptureTimeExtension>();
839 if (absolute_capture_time) {
840 ++packets_with_abs_capture_time;
841 EXPECT_EQ(absolute_capture_time->absolute_capture_timestamp,
842 Int64MsToUQ32x32(kAbsoluteCaptureTimestampMs + NtpOffsetMs()));
843 }
844 }
845 EXPECT_EQ(packets_with_abs_capture_time, 1);
846 }
847
TEST_P(RtpSenderVideoTest,PopulatesPlayoutDelay)848 TEST_P(RtpSenderVideoTest, PopulatesPlayoutDelay) {
849 // Single packet frames.
850 constexpr size_t kPacketSize = 123;
851 uint8_t kFrame[kPacketSize];
852 rtp_module_->RegisterRtpHeaderExtension(PlayoutDelayLimits::kUri,
853 kPlayoutDelayExtensionId);
854 const PlayoutDelay kExpectedDelay = {10, 20};
855
856 // Send initial key-frame without playout delay.
857 RTPVideoHeader hdr;
858 hdr.frame_type = VideoFrameType::kVideoFrameKey;
859 hdr.codec = VideoCodecType::kVideoCodecVP8;
860 auto& vp8_header = hdr.video_type_header.emplace<RTPVideoHeaderVP8>();
861 vp8_header.temporalIdx = 0;
862
863 rtp_sender_video_.SendVideo(kPayload, kType, kTimestamp, 0, kFrame, nullptr,
864 hdr, kDefaultExpectedRetransmissionTimeMs);
865 EXPECT_FALSE(
866 transport_.last_sent_packet().HasExtension<PlayoutDelayLimits>());
867
868 // Set playout delay on a discardable frame.
869 hdr.playout_delay = kExpectedDelay;
870 hdr.frame_type = VideoFrameType::kVideoFrameDelta;
871 vp8_header.temporalIdx = 1;
872 rtp_sender_video_.SendVideo(kPayload, kType, kTimestamp, 0, kFrame, nullptr,
873 hdr, kDefaultExpectedRetransmissionTimeMs);
874 PlayoutDelay received_delay = PlayoutDelay::Noop();
875 ASSERT_TRUE(transport_.last_sent_packet().GetExtension<PlayoutDelayLimits>(
876 &received_delay));
877 EXPECT_EQ(received_delay, kExpectedDelay);
878
879 // Set playout delay on a non-discardable frame, the extension should still
880 // be populated since dilvery wasn't guaranteed on the last one.
881 hdr.playout_delay = PlayoutDelay::Noop(); // Inidcates "no change".
882 vp8_header.temporalIdx = 0;
883 rtp_sender_video_.SendVideo(kPayload, kType, kTimestamp, 0, kFrame, nullptr,
884 hdr, kDefaultExpectedRetransmissionTimeMs);
885 ASSERT_TRUE(transport_.last_sent_packet().GetExtension<PlayoutDelayLimits>(
886 &received_delay));
887 EXPECT_EQ(received_delay, kExpectedDelay);
888
889 // The next frame does not need the extensions since it's delivery has
890 // already been guaranteed.
891 rtp_sender_video_.SendVideo(kPayload, kType, kTimestamp, 0, kFrame, nullptr,
892 hdr, kDefaultExpectedRetransmissionTimeMs);
893 EXPECT_FALSE(
894 transport_.last_sent_packet().HasExtension<PlayoutDelayLimits>());
895
896 // Insert key-frame, we need to refresh the state here.
897 hdr.frame_type = VideoFrameType::kVideoFrameKey;
898 rtp_sender_video_.SendVideo(kPayload, kType, kTimestamp, 0, kFrame, nullptr,
899 hdr, kDefaultExpectedRetransmissionTimeMs);
900 ASSERT_TRUE(transport_.last_sent_packet().GetExtension<PlayoutDelayLimits>(
901 &received_delay));
902 EXPECT_EQ(received_delay, kExpectedDelay);
903 }
904
905 class MockFrameTransformer : public FrameTransformerInterface {
906 public:
907 MOCK_METHOD3(TransformFrame,
908 void(std::unique_ptr<video_coding::EncodedFrame> frame,
909 std::vector<uint8_t> additional_data,
910 uint32_t ssrc));
911 MOCK_METHOD2(RegisterTransformedFrameSinkCallback,
912 void(rtc::scoped_refptr<TransformedFrameCallback>, uint32_t));
913 MOCK_METHOD1(UnregisterTransformedFrameSinkCallback, void(uint32_t));
914 };
915
TEST_P(RtpSenderVideoTest,SendEncodedImageWithFrameTransformer)916 TEST_P(RtpSenderVideoTest, SendEncodedImageWithFrameTransformer) {
917 rtc::scoped_refptr<MockFrameTransformer> transformer =
918 new rtc::RefCountedObject<MockFrameTransformer>();
919 RTPSenderVideo::Config config;
920 config.clock = &fake_clock_;
921 config.rtp_sender = rtp_module_->RtpSender();
922 config.field_trials = &field_trials_;
923 config.frame_transformer = transformer;
924
925 EXPECT_CALL(*transformer, RegisterTransformedFrameSinkCallback);
926 std::unique_ptr<RTPSenderVideo> rtp_sender_video =
927 std::make_unique<RTPSenderVideo>(config);
928
929 const uint8_t data[] = {1, 2, 3, 4};
930 EncodedImage encoded_image;
931 encoded_image.SetEncodedData(
932 webrtc::EncodedImageBuffer::Create(data, sizeof(data)));
933 RTPVideoHeader hdr;
934 EXPECT_CALL(*transformer, TransformFrame(_, RtpDescriptorAuthentication(hdr),
935 rtp_module_->RtpSender()->SSRC()));
936 rtp_sender_video->SendEncodedImage(kPayload, kType, kTimestamp, encoded_image,
937 nullptr, hdr,
938 kDefaultExpectedRetransmissionTimeMs);
939
940 EXPECT_CALL(*transformer, UnregisterTransformedFrameSinkCallback);
941 rtp_sender_video.reset();
942 }
943
944 INSTANTIATE_TEST_SUITE_P(WithAndWithoutOverhead,
945 RtpSenderVideoTest,
946 ::testing::Bool());
947
948 } // namespace webrtc
949