1 /*
2 * Copyright (c) 2015 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_format_vp9.h"
12
13 #include <memory>
14 #include <vector>
15
16 #include "api/array_view.h"
17 #include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
18 #include "modules/rtp_rtcp/source/video_rtp_depacketizer_vp9.h"
19 #include "test/gmock.h"
20 #include "test/gtest.h"
21
22 namespace webrtc {
23 namespace {
VerifyHeader(const RTPVideoHeaderVP9 & expected,const RTPVideoHeaderVP9 & actual)24 void VerifyHeader(const RTPVideoHeaderVP9& expected,
25 const RTPVideoHeaderVP9& actual) {
26 EXPECT_EQ(expected.inter_layer_predicted, actual.inter_layer_predicted);
27 EXPECT_EQ(expected.inter_pic_predicted, actual.inter_pic_predicted);
28 EXPECT_EQ(expected.flexible_mode, actual.flexible_mode);
29 EXPECT_EQ(expected.beginning_of_frame, actual.beginning_of_frame);
30 EXPECT_EQ(expected.end_of_frame, actual.end_of_frame);
31 EXPECT_EQ(expected.ss_data_available, actual.ss_data_available);
32 EXPECT_EQ(expected.non_ref_for_inter_layer_pred,
33 actual.non_ref_for_inter_layer_pred);
34 EXPECT_EQ(expected.picture_id, actual.picture_id);
35 EXPECT_EQ(expected.max_picture_id, actual.max_picture_id);
36 EXPECT_EQ(expected.temporal_idx, actual.temporal_idx);
37 EXPECT_EQ(expected.spatial_idx, actual.spatial_idx);
38 EXPECT_EQ(expected.gof_idx, actual.gof_idx);
39 EXPECT_EQ(expected.tl0_pic_idx, actual.tl0_pic_idx);
40 EXPECT_EQ(expected.temporal_up_switch, actual.temporal_up_switch);
41
42 EXPECT_EQ(expected.num_ref_pics, actual.num_ref_pics);
43 for (uint8_t i = 0; i < expected.num_ref_pics; ++i) {
44 EXPECT_EQ(expected.pid_diff[i], actual.pid_diff[i]);
45 EXPECT_EQ(expected.ref_picture_id[i], actual.ref_picture_id[i]);
46 }
47 if (expected.ss_data_available) {
48 EXPECT_EQ(expected.spatial_layer_resolution_present,
49 actual.spatial_layer_resolution_present);
50 EXPECT_EQ(expected.num_spatial_layers, actual.num_spatial_layers);
51 if (expected.spatial_layer_resolution_present) {
52 for (size_t i = 0; i < expected.num_spatial_layers; i++) {
53 EXPECT_EQ(expected.width[i], actual.width[i]);
54 EXPECT_EQ(expected.height[i], actual.height[i]);
55 }
56 }
57 EXPECT_EQ(expected.gof.num_frames_in_gof, actual.gof.num_frames_in_gof);
58 for (size_t i = 0; i < expected.gof.num_frames_in_gof; i++) {
59 EXPECT_EQ(expected.gof.temporal_up_switch[i],
60 actual.gof.temporal_up_switch[i]);
61 EXPECT_EQ(expected.gof.temporal_idx[i], actual.gof.temporal_idx[i]);
62 EXPECT_EQ(expected.gof.num_ref_pics[i], actual.gof.num_ref_pics[i]);
63 for (uint8_t j = 0; j < expected.gof.num_ref_pics[i]; j++) {
64 EXPECT_EQ(expected.gof.pid_diff[i][j], actual.gof.pid_diff[i][j]);
65 }
66 }
67 }
68 }
69
ParseAndCheckPacket(const uint8_t * packet,const RTPVideoHeaderVP9 & expected,int expected_hdr_length,size_t expected_length)70 void ParseAndCheckPacket(const uint8_t* packet,
71 const RTPVideoHeaderVP9& expected,
72 int expected_hdr_length,
73 size_t expected_length) {
74 RTPVideoHeader video_header;
75 EXPECT_EQ(VideoRtpDepacketizerVp9::ParseRtpPayload(
76 rtc::MakeArrayView(packet, expected_length), &video_header),
77 expected_hdr_length);
78 EXPECT_EQ(kVideoCodecVP9, video_header.codec);
79 auto& vp9_header =
80 absl::get<RTPVideoHeaderVP9>(video_header.video_type_header);
81 VerifyHeader(expected, vp9_header);
82 }
83
84 // Payload descriptor for flexible mode
85 // 0 1 2 3 4 5 6 7
86 // +-+-+-+-+-+-+-+-+
87 // |I|P|L|F|B|E|V|Z| (REQUIRED)
88 // +-+-+-+-+-+-+-+-+
89 // I: |M| PICTURE ID | (RECOMMENDED)
90 // +-+-+-+-+-+-+-+-+
91 // M: | EXTENDED PID | (RECOMMENDED)
92 // +-+-+-+-+-+-+-+-+
93 // L: | T |U| S |D| (CONDITIONALLY RECOMMENDED)
94 // +-+-+-+-+-+-+-+-+ -|
95 // P,F: | P_DIFF |N| (CONDITIONALLY RECOMMENDED) . up to 3 times
96 // +-+-+-+-+-+-+-+-+ -|
97 // V: | SS |
98 // | .. |
99 // +-+-+-+-+-+-+-+-+
100 //
101 // Payload descriptor for non-flexible mode
102 // 0 1 2 3 4 5 6 7
103 // +-+-+-+-+-+-+-+-+
104 // |I|P|L|F|B|E|V|Z| (REQUIRED)
105 // +-+-+-+-+-+-+-+-+
106 // I: |M| PICTURE ID | (RECOMMENDED)
107 // +-+-+-+-+-+-+-+-+
108 // M: | EXTENDED PID | (RECOMMENDED)
109 // +-+-+-+-+-+-+-+-+
110 // L: | T |U| S |D| (CONDITIONALLY RECOMMENDED)
111 // +-+-+-+-+-+-+-+-+
112 // | TL0PICIDX | (CONDITIONALLY REQUIRED)
113 // +-+-+-+-+-+-+-+-+
114 // V: | SS |
115 // | .. |
116 // +-+-+-+-+-+-+-+-+
117
118 class RtpPacketizerVp9Test : public ::testing::Test {
119 protected:
120 static constexpr RtpPacketToSend::ExtensionManager* kNoExtensions = nullptr;
121 static constexpr size_t kMaxPacketSize = 1200;
122
RtpPacketizerVp9Test()123 RtpPacketizerVp9Test() : packet_(kNoExtensions, kMaxPacketSize) {}
SetUp()124 void SetUp() override { expected_.InitRTPVideoHeaderVP9(); }
125
126 RtpPacketToSend packet_;
127 std::vector<uint8_t> payload_;
128 size_t payload_pos_;
129 RTPVideoHeaderVP9 expected_;
130 std::unique_ptr<RtpPacketizerVp9> packetizer_;
131 size_t num_packets_;
132
Init(size_t payload_size,size_t packet_size)133 void Init(size_t payload_size, size_t packet_size) {
134 payload_.assign(payload_size, 7);
135 payload_pos_ = 0;
136 RtpPacketizer::PayloadSizeLimits limits;
137 limits.max_payload_len = packet_size;
138 packetizer_.reset(new RtpPacketizerVp9(payload_, limits, expected_));
139 num_packets_ = packetizer_->NumPackets();
140 }
141
CheckPayload(const uint8_t * packet,size_t start_pos,size_t end_pos,bool last)142 void CheckPayload(const uint8_t* packet,
143 size_t start_pos,
144 size_t end_pos,
145 bool last) {
146 for (size_t i = start_pos; i < end_pos; ++i) {
147 EXPECT_EQ(packet[i], payload_[payload_pos_++]);
148 }
149 EXPECT_EQ(last, payload_pos_ == payload_.size());
150 }
151
CreateParseAndCheckPackets(rtc::ArrayView<const size_t> expected_hdr_sizes,rtc::ArrayView<const size_t> expected_sizes)152 void CreateParseAndCheckPackets(
153 rtc::ArrayView<const size_t> expected_hdr_sizes,
154 rtc::ArrayView<const size_t> expected_sizes) {
155 ASSERT_EQ(expected_hdr_sizes.size(), expected_sizes.size());
156 ASSERT_TRUE(packetizer_ != nullptr);
157 EXPECT_EQ(expected_sizes.size(), num_packets_);
158 for (size_t i = 0; i < expected_sizes.size(); ++i) {
159 EXPECT_TRUE(packetizer_->NextPacket(&packet_));
160 auto rtp_payload = packet_.payload();
161 EXPECT_EQ(expected_sizes[i], rtp_payload.size());
162 RTPVideoHeaderVP9 hdr = expected_;
163 hdr.beginning_of_frame = (i == 0);
164 hdr.end_of_frame = (i + 1) == expected_sizes.size();
165 ParseAndCheckPacket(rtp_payload.data(), hdr, expected_hdr_sizes[i],
166 rtp_payload.size());
167 CheckPayload(rtp_payload.data(), expected_hdr_sizes[i],
168 rtp_payload.size(), (i + 1) == expected_sizes.size());
169 expected_.ss_data_available = false;
170 }
171 }
172
CreateParseAndCheckPacketsLayers(size_t num_spatial_layers,size_t expected_layer)173 void CreateParseAndCheckPacketsLayers(size_t num_spatial_layers,
174 size_t expected_layer) {
175 ASSERT_TRUE(packetizer_ != nullptr);
176 for (size_t i = 0; i < num_packets_; ++i) {
177 EXPECT_TRUE(packetizer_->NextPacket(&packet_));
178 RTPVideoHeader video_header;
179 VideoRtpDepacketizerVp9::ParseRtpPayload(packet_.payload(),
180 &video_header);
181 const auto& vp9_header =
182 absl::get<RTPVideoHeaderVP9>(video_header.video_type_header);
183 EXPECT_EQ(vp9_header.spatial_idx, expected_layer);
184 EXPECT_EQ(vp9_header.num_spatial_layers, num_spatial_layers);
185 }
186 }
187 };
188
TEST_F(RtpPacketizerVp9Test,TestEqualSizedMode_OnePacket)189 TEST_F(RtpPacketizerVp9Test, TestEqualSizedMode_OnePacket) {
190 const size_t kFrameSize = 25;
191 const size_t kPacketSize = 26;
192 Init(kFrameSize, kPacketSize);
193
194 // One packet:
195 // I:0, P:0, L:0, F:0, B:1, E:1, V:0, Z:0 (1hdr + 25 payload)
196 const size_t kExpectedHdrSizes[] = {1};
197 const size_t kExpectedSizes[] = {26};
198 CreateParseAndCheckPackets(kExpectedHdrSizes, kExpectedSizes);
199 }
200
TEST_F(RtpPacketizerVp9Test,TestEqualSizedMode_TwoPackets)201 TEST_F(RtpPacketizerVp9Test, TestEqualSizedMode_TwoPackets) {
202 const size_t kFrameSize = 27;
203 const size_t kPacketSize = 27;
204 Init(kFrameSize, kPacketSize);
205
206 // Two packets:
207 // I:0, P:0, L:0, F:0, B:1, E:0, V:0, Z:0 (1hdr + 14 payload)
208 // I:0, P:0, L:0, F:0, B:0, E:1, V:0, Z:0 (1hdr + 13 payload)
209 const size_t kExpectedHdrSizes[] = {1, 1};
210 const size_t kExpectedSizes[] = {14, 15};
211 CreateParseAndCheckPackets(kExpectedHdrSizes, kExpectedSizes);
212 }
213
TEST_F(RtpPacketizerVp9Test,TestTooShortBufferToFitPayload)214 TEST_F(RtpPacketizerVp9Test, TestTooShortBufferToFitPayload) {
215 const size_t kFrameSize = 1;
216 const size_t kPacketSize = 1;
217 Init(kFrameSize, kPacketSize); // 1hdr + 1 payload
218
219 EXPECT_FALSE(packetizer_->NextPacket(&packet_));
220 }
221
TEST_F(RtpPacketizerVp9Test,TestOneBytePictureId)222 TEST_F(RtpPacketizerVp9Test, TestOneBytePictureId) {
223 const size_t kFrameSize = 30;
224 const size_t kPacketSize = 12;
225
226 expected_.picture_id = kMaxOneBytePictureId; // 2 byte payload descriptor
227 expected_.max_picture_id = kMaxOneBytePictureId;
228 Init(kFrameSize, kPacketSize);
229
230 // Three packets:
231 // I:1, P:0, L:0, F:0, B:1, E:0, V:0, Z:0 (2hdr + 10 payload)
232 // I:1, P:0, L:0, F:0, B:0, E:0, V:0, Z:0 (2hdr + 10 payload)
233 // I:1, P:0, L:0, F:0, B:0, E:1, V:0, Z:0 (2hdr + 10 payload)
234 const size_t kExpectedHdrSizes[] = {2, 2, 2};
235 const size_t kExpectedSizes[] = {12, 12, 12};
236 CreateParseAndCheckPackets(kExpectedHdrSizes, kExpectedSizes);
237 }
238
TEST_F(RtpPacketizerVp9Test,TestTwoBytePictureId)239 TEST_F(RtpPacketizerVp9Test, TestTwoBytePictureId) {
240 const size_t kFrameSize = 31;
241 const size_t kPacketSize = 13;
242
243 expected_.picture_id = kMaxTwoBytePictureId; // 3 byte payload descriptor
244 Init(kFrameSize, kPacketSize);
245
246 // Four packets:
247 // I:1, P:0, L:0, F:0, B:1, E:0, V:0, Z:0 (3hdr + 8 payload)
248 // I:1, P:0, L:0, F:0, B:0, E:0, V:0, Z:0 (3hdr + 8 payload)
249 // I:1, P:0, L:0, F:0, B:0, E:0, V:0, Z:0 (3hdr + 8 payload)
250 // I:1, P:0, L:0, F:0, B:0, E:1, V:0, Z:0 (3hdr + 7 payload)
251 const size_t kExpectedHdrSizes[] = {3, 3, 3, 3};
252 const size_t kExpectedSizes[] = {10, 11, 11, 11};
253 CreateParseAndCheckPackets(kExpectedHdrSizes, kExpectedSizes);
254 }
255
TEST_F(RtpPacketizerVp9Test,TestLayerInfoWithNonFlexibleMode)256 TEST_F(RtpPacketizerVp9Test, TestLayerInfoWithNonFlexibleMode) {
257 const size_t kFrameSize = 30;
258 const size_t kPacketSize = 25;
259
260 expected_.temporal_idx = 3;
261 expected_.temporal_up_switch = true; // U
262 expected_.num_spatial_layers = 3;
263 expected_.spatial_idx = 2;
264 expected_.inter_layer_predicted = true; // D
265 expected_.tl0_pic_idx = 117;
266 Init(kFrameSize, kPacketSize);
267
268 // Two packets:
269 // | I:0, P:0, L:1, F:0, B:1, E:0, V:0 Z:0 | (3hdr + 15 payload)
270 // L: | T:3, U:1, S:2, D:1 | TL0PICIDX:117 |
271 // | I:0, P:0, L:1, F:0, B:0, E:1, V:0 Z:0 | (3hdr + 15 payload)
272 // L: | T:3, U:1, S:2, D:1 | TL0PICIDX:117 |
273 const size_t kExpectedHdrSizes[] = {3, 3};
274 const size_t kExpectedSizes[] = {18, 18};
275 CreateParseAndCheckPackets(kExpectedHdrSizes, kExpectedSizes);
276 }
277
TEST_F(RtpPacketizerVp9Test,TestLayerInfoWithFlexibleMode)278 TEST_F(RtpPacketizerVp9Test, TestLayerInfoWithFlexibleMode) {
279 const size_t kFrameSize = 21;
280 const size_t kPacketSize = 23;
281
282 expected_.flexible_mode = true;
283 expected_.temporal_idx = 3;
284 expected_.temporal_up_switch = true; // U
285 expected_.num_spatial_layers = 3;
286 expected_.spatial_idx = 2;
287 expected_.inter_layer_predicted = false; // D
288 Init(kFrameSize, kPacketSize);
289
290 // One packet:
291 // I:0, P:0, L:1, F:1, B:1, E:1, V:0 (2hdr + 21 payload)
292 // L: T:3, U:1, S:2, D:0
293 const size_t kExpectedHdrSizes[] = {2};
294 const size_t kExpectedSizes[] = {23};
295 CreateParseAndCheckPackets(kExpectedHdrSizes, kExpectedSizes);
296 }
297
TEST_F(RtpPacketizerVp9Test,TestRefIdx)298 TEST_F(RtpPacketizerVp9Test, TestRefIdx) {
299 const size_t kFrameSize = 16;
300 const size_t kPacketSize = 21;
301
302 expected_.inter_pic_predicted = true; // P
303 expected_.flexible_mode = true; // F
304 expected_.picture_id = 2;
305 expected_.max_picture_id = kMaxOneBytePictureId;
306
307 expected_.num_ref_pics = 3;
308 expected_.pid_diff[0] = 1;
309 expected_.pid_diff[1] = 3;
310 expected_.pid_diff[2] = 127;
311 expected_.ref_picture_id[0] = 1; // 2 - 1 = 1
312 expected_.ref_picture_id[1] = 127; // (kMaxPictureId + 1) + 2 - 3 = 127
313 expected_.ref_picture_id[2] = 3; // (kMaxPictureId + 1) + 2 - 127 = 3
314 Init(kFrameSize, kPacketSize);
315
316 // Two packets:
317 // I:1, P:1, L:0, F:1, B:1, E:1, V:0, Z:0 (5hdr + 16 payload)
318 // I: 2
319 // P,F: P_DIFF:1, N:1
320 // P_DIFF:3, N:1
321 // P_DIFF:127, N:0
322 const size_t kExpectedHdrSizes[] = {5};
323 const size_t kExpectedSizes[] = {21};
324 CreateParseAndCheckPackets(kExpectedHdrSizes, kExpectedSizes);
325 }
326
TEST_F(RtpPacketizerVp9Test,TestRefIdxFailsWithoutPictureId)327 TEST_F(RtpPacketizerVp9Test, TestRefIdxFailsWithoutPictureId) {
328 const size_t kFrameSize = 16;
329 const size_t kPacketSize = 21;
330
331 expected_.inter_pic_predicted = true;
332 expected_.flexible_mode = true;
333 expected_.num_ref_pics = 1;
334 expected_.pid_diff[0] = 3;
335 Init(kFrameSize, kPacketSize);
336
337 EXPECT_FALSE(packetizer_->NextPacket(&packet_));
338 }
339
TEST_F(RtpPacketizerVp9Test,TestSsDataWithoutSpatialResolutionPresent)340 TEST_F(RtpPacketizerVp9Test, TestSsDataWithoutSpatialResolutionPresent) {
341 const size_t kFrameSize = 21;
342 const size_t kPacketSize = 26;
343
344 expected_.ss_data_available = true;
345 expected_.num_spatial_layers = 1;
346 expected_.spatial_layer_resolution_present = false;
347 expected_.gof.num_frames_in_gof = 1;
348 expected_.gof.temporal_idx[0] = 0;
349 expected_.gof.temporal_up_switch[0] = true;
350 expected_.gof.num_ref_pics[0] = 1;
351 expected_.gof.pid_diff[0][0] = 4;
352 Init(kFrameSize, kPacketSize);
353
354 // One packet:
355 // I:0, P:0, L:0, F:0, B:1, E:1, V:1, Z:0 (5hdr + 21 payload)
356 // N_S:0, Y:0, G:1
357 // N_G:1
358 // T:0, U:1, R:1 | P_DIFF[0][0]:4
359 const size_t kExpectedHdrSizes[] = {5};
360 const size_t kExpectedSizes[] = {26};
361 CreateParseAndCheckPackets(kExpectedHdrSizes, kExpectedSizes);
362 }
363
TEST_F(RtpPacketizerVp9Test,TestSsDataWithoutGbitPresent)364 TEST_F(RtpPacketizerVp9Test, TestSsDataWithoutGbitPresent) {
365 const size_t kFrameSize = 21;
366 const size_t kPacketSize = 23;
367
368 expected_.ss_data_available = true;
369 expected_.num_spatial_layers = 1;
370 expected_.spatial_layer_resolution_present = false;
371 expected_.gof.num_frames_in_gof = 0;
372 Init(kFrameSize, kPacketSize);
373
374 // One packet:
375 // I:0, P:0, L:0, F:0, B:1, E:1, V:1, Z:0 (2hdr + 21 payload)
376 // N_S:0, Y:0, G:0
377 const size_t kExpectedHdrSizes[] = {2};
378 const size_t kExpectedSizes[] = {23};
379 CreateParseAndCheckPackets(kExpectedHdrSizes, kExpectedSizes);
380 }
381
TEST_F(RtpPacketizerVp9Test,TestSsData)382 TEST_F(RtpPacketizerVp9Test, TestSsData) {
383 const size_t kFrameSize = 21;
384 const size_t kPacketSize = 40;
385
386 expected_.ss_data_available = true;
387 expected_.num_spatial_layers = 2;
388 expected_.spatial_layer_resolution_present = true;
389 expected_.width[0] = 640;
390 expected_.width[1] = 1280;
391 expected_.height[0] = 360;
392 expected_.height[1] = 720;
393 expected_.gof.num_frames_in_gof = 3;
394 expected_.gof.temporal_idx[0] = 0;
395 expected_.gof.temporal_idx[1] = 1;
396 expected_.gof.temporal_idx[2] = 2;
397 expected_.gof.temporal_up_switch[0] = true;
398 expected_.gof.temporal_up_switch[1] = true;
399 expected_.gof.temporal_up_switch[2] = false;
400 expected_.gof.num_ref_pics[0] = 0;
401 expected_.gof.num_ref_pics[1] = 3;
402 expected_.gof.num_ref_pics[2] = 2;
403 expected_.gof.pid_diff[1][0] = 5;
404 expected_.gof.pid_diff[1][1] = 6;
405 expected_.gof.pid_diff[1][2] = 7;
406 expected_.gof.pid_diff[2][0] = 8;
407 expected_.gof.pid_diff[2][1] = 9;
408 Init(kFrameSize, kPacketSize);
409
410 // One packet:
411 // I:0, P:0, L:0, F:0, B:1, E:1, V:1, Z:0 (19hdr + 21 payload)
412 // N_S:1, Y:1, G:1
413 // WIDTH:640 // 2 bytes
414 // HEIGHT:360 // 2 bytes
415 // WIDTH:1280 // 2 bytes
416 // HEIGHT:720 // 2 bytes
417 // N_G:3
418 // T:0, U:1, R:0
419 // T:1, U:1, R:3 | P_DIFF[1][0]:5 | P_DIFF[1][1]:6 | P_DIFF[1][2]:7
420 // T:2, U:0, R:2 | P_DIFF[2][0]:8 | P_DIFF[2][0]:9
421 const size_t kExpectedHdrSizes[] = {19};
422 const size_t kExpectedSizes[] = {40};
423 CreateParseAndCheckPackets(kExpectedHdrSizes, kExpectedSizes);
424 }
425
TEST_F(RtpPacketizerVp9Test,TestSsDataDoesNotFitInAveragePacket)426 TEST_F(RtpPacketizerVp9Test, TestSsDataDoesNotFitInAveragePacket) {
427 const size_t kFrameSize = 24;
428 const size_t kPacketSize = 20;
429
430 expected_.ss_data_available = true;
431 expected_.num_spatial_layers = 2;
432 expected_.spatial_layer_resolution_present = true;
433 expected_.width[0] = 640;
434 expected_.width[1] = 1280;
435 expected_.height[0] = 360;
436 expected_.height[1] = 720;
437 expected_.gof.num_frames_in_gof = 3;
438 expected_.gof.temporal_idx[0] = 0;
439 expected_.gof.temporal_idx[1] = 1;
440 expected_.gof.temporal_idx[2] = 2;
441 expected_.gof.temporal_up_switch[0] = true;
442 expected_.gof.temporal_up_switch[1] = true;
443 expected_.gof.temporal_up_switch[2] = false;
444 expected_.gof.num_ref_pics[0] = 0;
445 expected_.gof.num_ref_pics[1] = 3;
446 expected_.gof.num_ref_pics[2] = 2;
447 expected_.gof.pid_diff[1][0] = 5;
448 expected_.gof.pid_diff[1][1] = 6;
449 expected_.gof.pid_diff[1][2] = 7;
450 expected_.gof.pid_diff[2][0] = 8;
451 expected_.gof.pid_diff[2][1] = 9;
452 Init(kFrameSize, kPacketSize);
453
454 // Three packets:
455 // I:0, P:0, L:0, F:0, B:1, E:1, V:1, Z:0 (19hdr + 1 payload)
456 // N_S:1, Y:1, G:1
457 // WIDTH:640 // 2 bytes
458 // HEIGHT:360 // 2 bytes
459 // WIDTH:1280 // 2 bytes
460 // HEIGHT:720 // 2 bytes
461 // N_G:3
462 // T:0, U:1, R:0
463 // T:1, U:1, R:3 | P_DIFF[1][0]:5 | P_DIFF[1][1]:6 | P_DIFF[1][2]:7
464 // T:2, U:0, R:2 | P_DIFF[2][0]:8 | P_DIFF[2][0]:9
465 // Last two packets 1 bytes vp9 hdrs and the rest of payload 14 and 9 bytes.
466 const size_t kExpectedHdrSizes[] = {19, 1, 1};
467 const size_t kExpectedSizes[] = {20, 15, 10};
468 CreateParseAndCheckPackets(kExpectedHdrSizes, kExpectedSizes);
469 }
470
TEST_F(RtpPacketizerVp9Test,EndOfPictureSetsSetMarker)471 TEST_F(RtpPacketizerVp9Test, EndOfPictureSetsSetMarker) {
472 const size_t kFrameSize = 10;
473 RtpPacketizer::PayloadSizeLimits limits;
474 limits.max_payload_len = 8;
475 const uint8_t kFrame[kFrameSize] = {7};
476
477 RTPVideoHeaderVP9 vp9_header;
478 vp9_header.InitRTPVideoHeaderVP9();
479 vp9_header.flexible_mode = true;
480 vp9_header.num_spatial_layers = 3;
481
482 RtpPacketToSend packet(kNoExtensions);
483
484 // Drop top layer and ensure that marker bit is set on last encoded layer.
485 for (size_t spatial_idx = 0; spatial_idx < vp9_header.num_spatial_layers - 1;
486 ++spatial_idx) {
487 const bool end_of_picture =
488 spatial_idx + 1 == vp9_header.num_spatial_layers - 1;
489 vp9_header.spatial_idx = spatial_idx;
490 vp9_header.end_of_picture = end_of_picture;
491 RtpPacketizerVp9 packetizer(kFrame, limits, vp9_header);
492 ASSERT_TRUE(packetizer.NextPacket(&packet));
493 EXPECT_FALSE(packet.Marker());
494 ASSERT_TRUE(packetizer.NextPacket(&packet));
495 EXPECT_EQ(packet.Marker(), end_of_picture);
496 }
497 }
498
TEST_F(RtpPacketizerVp9Test,TestGeneratesMinimumNumberOfPackets)499 TEST_F(RtpPacketizerVp9Test, TestGeneratesMinimumNumberOfPackets) {
500 const size_t kFrameSize = 10;
501 RtpPacketizer::PayloadSizeLimits limits;
502 limits.max_payload_len = 8;
503 // Calculated by hand. One packet can contain
504 // `kPacketSize` - `kVp9MinDiscriptorSize` = 6 bytes of the frame payload,
505 // thus to fit 10 bytes two packets are required.
506 const size_t kMinNumberOfPackets = 2;
507 const uint8_t kFrame[kFrameSize] = {7};
508
509 RTPVideoHeaderVP9 vp9_header;
510 vp9_header.InitRTPVideoHeaderVP9();
511
512 RtpPacketToSend packet(kNoExtensions);
513
514 RtpPacketizerVp9 packetizer(kFrame, limits, vp9_header);
515 EXPECT_EQ(packetizer.NumPackets(), kMinNumberOfPackets);
516 ASSERT_TRUE(packetizer.NextPacket(&packet));
517 EXPECT_FALSE(packet.Marker());
518 ASSERT_TRUE(packetizer.NextPacket(&packet));
519 EXPECT_TRUE(packet.Marker());
520 }
521
TEST_F(RtpPacketizerVp9Test,TestRespectsLastPacketReductionLen)522 TEST_F(RtpPacketizerVp9Test, TestRespectsLastPacketReductionLen) {
523 const size_t kFrameSize = 10;
524 RtpPacketizer::PayloadSizeLimits limits;
525 limits.max_payload_len = 8;
526 limits.last_packet_reduction_len = 5;
527 // Calculated by hand. VP9 payload descriptor is 2 bytes. Like in the test
528 // above, 1 packet is not enough. 2 packets can contain
529 // 2*(`kPacketSize` - `kVp9MinDiscriptorSize`) - `kLastPacketReductionLen` = 7
530 // But three packets are enough, since they have capacity of 3*(8-2)-5=13
531 // bytes.
532 const size_t kMinNumberOfPackets = 3;
533 const uint8_t kFrame[kFrameSize] = {7};
534
535 RTPVideoHeaderVP9 vp9_header;
536 vp9_header.InitRTPVideoHeaderVP9();
537 vp9_header.flexible_mode = true;
538
539 RtpPacketToSend packet(kNoExtensions);
540
541 RtpPacketizerVp9 packetizer0(kFrame, limits, vp9_header);
542 EXPECT_EQ(packetizer0.NumPackets(), kMinNumberOfPackets);
543 ASSERT_TRUE(packetizer0.NextPacket(&packet));
544 EXPECT_FALSE(packet.Marker());
545 ASSERT_TRUE(packetizer0.NextPacket(&packet));
546 EXPECT_FALSE(packet.Marker());
547 ASSERT_TRUE(packetizer0.NextPacket(&packet));
548 EXPECT_TRUE(packet.Marker());
549 }
550
TEST_F(RtpPacketizerVp9Test,TestNonRefForInterLayerPred)551 TEST_F(RtpPacketizerVp9Test, TestNonRefForInterLayerPred) {
552 const size_t kFrameSize = 25;
553 const size_t kPacketSize = 26;
554
555 expected_.non_ref_for_inter_layer_pred = true;
556 Init(kFrameSize, kPacketSize);
557
558 // I:0, P:0, L:0, F:0, B:1, E:1, V:0, Z:1 (1hdr + 25 payload)
559 const size_t kExpectedHdrSizes[] = {1};
560 const size_t kExpectedSizes[] = {26};
561 CreateParseAndCheckPackets(kExpectedHdrSizes, kExpectedSizes);
562 }
563
TEST_F(RtpPacketizerVp9Test,ShiftsSpatialLayersTowardZeroWhenFirstLayersAreDisabled)564 TEST_F(RtpPacketizerVp9Test,
565 ShiftsSpatialLayersTowardZeroWhenFirstLayersAreDisabled) {
566 const size_t kFrameSize = 25;
567 const size_t kPacketSize = 1024;
568
569 expected_.width[0] = 0;
570 expected_.height[0] = 0;
571 expected_.width[1] = 640;
572 expected_.height[1] = 360;
573 expected_.width[2] = 1280;
574 expected_.height[2] = 720;
575 expected_.num_spatial_layers = 3;
576 expected_.first_active_layer = 1;
577 expected_.ss_data_available = true;
578 expected_.spatial_layer_resolution_present = true;
579 expected_.gof.num_frames_in_gof = 3;
580 expected_.gof.temporal_idx[0] = 0;
581 expected_.gof.temporal_idx[1] = 1;
582 expected_.gof.temporal_idx[2] = 2;
583 expected_.gof.temporal_up_switch[0] = true;
584 expected_.gof.temporal_up_switch[1] = true;
585 expected_.gof.temporal_up_switch[2] = false;
586 expected_.gof.num_ref_pics[0] = 0;
587 expected_.gof.num_ref_pics[1] = 3;
588 expected_.gof.num_ref_pics[2] = 2;
589 expected_.gof.pid_diff[1][0] = 5;
590 expected_.gof.pid_diff[1][1] = 6;
591 expected_.gof.pid_diff[1][2] = 7;
592 expected_.gof.pid_diff[2][0] = 8;
593 expected_.gof.pid_diff[2][1] = 9;
594
595 expected_.spatial_idx = 1;
596 Init(kFrameSize, kPacketSize);
597 CreateParseAndCheckPacketsLayers(/*num_spatial_layers=*/2,
598 /*expected_layer=*/0);
599
600 // Now check for SL 2;
601 expected_.spatial_idx = 2;
602 Init(kFrameSize, kPacketSize);
603 CreateParseAndCheckPacketsLayers(/*num_spatial_layers=*/2,
604 /*expected_layer=*/1);
605 }
606
607 } // namespace
608 } // namespace webrtc
609