xref: /aosp_15_r20/external/webrtc/modules/rtp_rtcp/source/rtp_format_vp9_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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