1 /*
2 * Copyright (c) 2016 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 <cstring>
12 #include <limits>
13 #include <map>
14 #include <set>
15 #include <utility>
16 #include <vector>
17
18 #include "modules/video_coding/frame_object.h"
19 #include "modules/video_coding/packet_buffer.h"
20 #include "modules/video_coding/rtp_frame_reference_finder.h"
21 #include "rtc_base/random.h"
22 #include "rtc_base/ref_count.h"
23 #include "system_wrappers/include/clock.h"
24 #include "test/gtest.h"
25
26 namespace webrtc {
27 namespace video_coding {
28
29 namespace {
CreateFrame(uint16_t seq_num_start,uint16_t seq_num_end,bool keyframe,VideoCodecType codec,const RTPVideoTypeHeader & video_type_header)30 std::unique_ptr<RtpFrameObject> CreateFrame(
31 uint16_t seq_num_start,
32 uint16_t seq_num_end,
33 bool keyframe,
34 VideoCodecType codec,
35 const RTPVideoTypeHeader& video_type_header) {
36 RTPVideoHeader video_header;
37 video_header.frame_type = keyframe ? VideoFrameType::kVideoFrameKey
38 : VideoFrameType::kVideoFrameDelta;
39 video_header.video_type_header = video_type_header;
40
41 // clang-format off
42 return std::make_unique<RtpFrameObject>(
43 seq_num_start,
44 seq_num_end,
45 /*markerBit=*/true,
46 /*times_nacked=*/0,
47 /*first_packet_received_time=*/0,
48 /*last_packet_received_time=*/0,
49 /*rtp_timestamp=*/0,
50 /*ntp_time_ms=*/0,
51 VideoSendTiming(),
52 /*payload_type=*/0,
53 codec,
54 kVideoRotation_0,
55 VideoContentType::UNSPECIFIED,
56 video_header,
57 /*color_space=*/absl::nullopt,
58 RtpPacketInfos(),
59 EncodedImageBuffer::Create(/*size=*/0));
60 // clang-format on
61 }
62 } // namespace
63
64 class TestRtpFrameReferenceFinder : public ::testing::Test,
65 public OnCompleteFrameCallback {
66 protected:
TestRtpFrameReferenceFinder()67 TestRtpFrameReferenceFinder()
68 : rand_(0x8739211),
69 reference_finder_(new RtpFrameReferenceFinder(this)),
70 frames_from_callback_(FrameComp()) {}
71
Rand()72 uint16_t Rand() { return rand_.Rand<uint16_t>(); }
73
OnCompleteFrame(std::unique_ptr<EncodedFrame> frame)74 void OnCompleteFrame(std::unique_ptr<EncodedFrame> frame) override {
75 int64_t pid = frame->id.picture_id;
76 uint16_t sidx = frame->id.spatial_layer;
77 auto frame_it = frames_from_callback_.find(std::make_pair(pid, sidx));
78 if (frame_it != frames_from_callback_.end()) {
79 ADD_FAILURE() << "Already received frame with (pid:sidx): (" << pid << ":"
80 << sidx << ")";
81 return;
82 }
83
84 frames_from_callback_.insert(
85 std::make_pair(std::make_pair(pid, sidx), std::move(frame)));
86 }
87
InsertGeneric(uint16_t seq_num_start,uint16_t seq_num_end,bool keyframe)88 void InsertGeneric(uint16_t seq_num_start,
89 uint16_t seq_num_end,
90 bool keyframe) {
91 std::unique_ptr<RtpFrameObject> frame =
92 CreateFrame(seq_num_start, seq_num_end, keyframe, kVideoCodecGeneric,
93 RTPVideoTypeHeader());
94
95 reference_finder_->ManageFrame(std::move(frame));
96 }
97
InsertVp8(uint16_t seq_num_start,uint16_t seq_num_end,bool keyframe,int32_t pid=kNoPictureId,uint8_t tid=kNoTemporalIdx,int32_t tl0=kNoTl0PicIdx,bool sync=false)98 void InsertVp8(uint16_t seq_num_start,
99 uint16_t seq_num_end,
100 bool keyframe,
101 int32_t pid = kNoPictureId,
102 uint8_t tid = kNoTemporalIdx,
103 int32_t tl0 = kNoTl0PicIdx,
104 bool sync = false) {
105 RTPVideoHeaderVP8 vp8_header{};
106 vp8_header.pictureId = pid % (1 << 15);
107 vp8_header.temporalIdx = tid;
108 vp8_header.tl0PicIdx = tl0;
109 vp8_header.layerSync = sync;
110
111 std::unique_ptr<RtpFrameObject> frame = CreateFrame(
112 seq_num_start, seq_num_end, keyframe, kVideoCodecVP8, vp8_header);
113
114 reference_finder_->ManageFrame(std::move(frame));
115 }
116
InsertVp9Gof(uint16_t seq_num_start,uint16_t seq_num_end,bool keyframe,int32_t pid=kNoPictureId,uint8_t sid=kNoSpatialIdx,uint8_t tid=kNoTemporalIdx,int32_t tl0=kNoTl0PicIdx,bool up_switch=false,bool inter_pic_predicted=true,GofInfoVP9 * ss=nullptr)117 void InsertVp9Gof(uint16_t seq_num_start,
118 uint16_t seq_num_end,
119 bool keyframe,
120 int32_t pid = kNoPictureId,
121 uint8_t sid = kNoSpatialIdx,
122 uint8_t tid = kNoTemporalIdx,
123 int32_t tl0 = kNoTl0PicIdx,
124 bool up_switch = false,
125 bool inter_pic_predicted = true,
126 GofInfoVP9* ss = nullptr) {
127 RTPVideoHeaderVP9 vp9_header{};
128 vp9_header.flexible_mode = false;
129 vp9_header.picture_id = pid % (1 << 15);
130 vp9_header.temporal_idx = tid;
131 vp9_header.spatial_idx = sid;
132 vp9_header.tl0_pic_idx = tl0;
133 vp9_header.temporal_up_switch = up_switch;
134 vp9_header.inter_pic_predicted = inter_pic_predicted && !keyframe;
135 if (ss != nullptr) {
136 vp9_header.ss_data_available = true;
137 vp9_header.gof = *ss;
138 }
139
140 std::unique_ptr<RtpFrameObject> frame = CreateFrame(
141 seq_num_start, seq_num_end, keyframe, kVideoCodecVP9, vp9_header);
142
143 reference_finder_->ManageFrame(std::move(frame));
144 }
145
InsertVp9Flex(uint16_t seq_num_start,uint16_t seq_num_end,bool keyframe,int32_t pid=kNoPictureId,uint8_t sid=kNoSpatialIdx,uint8_t tid=kNoTemporalIdx,bool inter=false,std::vector<uint8_t> refs=std::vector<uint8_t> ())146 void InsertVp9Flex(uint16_t seq_num_start,
147 uint16_t seq_num_end,
148 bool keyframe,
149 int32_t pid = kNoPictureId,
150 uint8_t sid = kNoSpatialIdx,
151 uint8_t tid = kNoTemporalIdx,
152 bool inter = false,
153 std::vector<uint8_t> refs = std::vector<uint8_t>()) {
154 RTPVideoHeaderVP9 vp9_header{};
155 vp9_header.inter_layer_predicted = inter;
156 vp9_header.flexible_mode = true;
157 vp9_header.picture_id = pid % (1 << 15);
158 vp9_header.temporal_idx = tid;
159 vp9_header.spatial_idx = sid;
160 vp9_header.tl0_pic_idx = kNoTl0PicIdx;
161 vp9_header.num_ref_pics = refs.size();
162 for (size_t i = 0; i < refs.size(); ++i)
163 vp9_header.pid_diff[i] = refs[i];
164
165 std::unique_ptr<RtpFrameObject> frame = CreateFrame(
166 seq_num_start, seq_num_end, keyframe, kVideoCodecVP9, vp9_header);
167 reference_finder_->ManageFrame(std::move(frame));
168 }
169
InsertH264(uint16_t seq_num_start,uint16_t seq_num_end,bool keyframe)170 void InsertH264(uint16_t seq_num_start, uint16_t seq_num_end, bool keyframe) {
171 std::unique_ptr<RtpFrameObject> frame =
172 CreateFrame(seq_num_start, seq_num_end, keyframe, kVideoCodecH264,
173 RTPVideoTypeHeader());
174 reference_finder_->ManageFrame(std::move(frame));
175 }
176
177 // Check if a frame with picture id |pid| and spatial index |sidx| has been
178 // delivered from the packet buffer, and if so, if it has the references
179 // specified by |refs|.
180 template <typename... T>
CheckReferences(int64_t picture_id_offset,uint16_t sidx,T...refs) const181 void CheckReferences(int64_t picture_id_offset,
182 uint16_t sidx,
183 T... refs) const {
184 int64_t pid = picture_id_offset;
185 auto frame_it = frames_from_callback_.find(std::make_pair(pid, sidx));
186 if (frame_it == frames_from_callback_.end()) {
187 ADD_FAILURE() << "Could not find frame with (pid:sidx): (" << pid << ":"
188 << sidx << ")";
189 return;
190 }
191
192 std::set<int64_t> actual_refs;
193 for (uint8_t r = 0; r < frame_it->second->num_references; ++r)
194 actual_refs.insert(frame_it->second->references[r]);
195
196 std::set<int64_t> expected_refs;
197 RefsToSet(&expected_refs, refs...);
198
199 ASSERT_EQ(expected_refs, actual_refs);
200 }
201
202 template <typename... T>
CheckReferencesGeneric(int64_t pid,T...refs) const203 void CheckReferencesGeneric(int64_t pid, T... refs) const {
204 CheckReferences(pid, 0, refs...);
205 }
206
207 template <typename... T>
CheckReferencesVp8(int64_t pid,T...refs) const208 void CheckReferencesVp8(int64_t pid, T... refs) const {
209 CheckReferences(pid, 0, refs...);
210 }
211
212 template <typename... T>
CheckReferencesVp9(int64_t pid,uint8_t sidx,T...refs) const213 void CheckReferencesVp9(int64_t pid, uint8_t sidx, T... refs) const {
214 CheckReferences(pid, sidx, refs...);
215 }
216
217 template <typename... T>
CheckReferencesH264(int64_t pid,T...refs) const218 void CheckReferencesH264(int64_t pid, T... refs) const {
219 CheckReferences(pid, 0, refs...);
220 }
221
222 template <typename... T>
RefsToSet(std::set<int64_t> * m,int64_t ref,T...refs) const223 void RefsToSet(std::set<int64_t>* m, int64_t ref, T... refs) const {
224 m->insert(ref);
225 RefsToSet(m, refs...);
226 }
227
RefsToSet(std::set<int64_t> * m) const228 void RefsToSet(std::set<int64_t>* m) const {}
229
230 Random rand_;
231 std::unique_ptr<RtpFrameReferenceFinder> reference_finder_;
232 struct FrameComp {
operator ()webrtc::video_coding::TestRtpFrameReferenceFinder::FrameComp233 bool operator()(const std::pair<int64_t, uint8_t> f1,
234 const std::pair<int64_t, uint8_t> f2) const {
235 if (f1.first == f2.first)
236 return f1.second < f2.second;
237 return f1.first < f2.first;
238 }
239 };
240 std::
241 map<std::pair<int64_t, uint8_t>, std::unique_ptr<EncodedFrame>, FrameComp>
242 frames_from_callback_;
243 };
244
TEST_F(TestRtpFrameReferenceFinder,PaddingPackets)245 TEST_F(TestRtpFrameReferenceFinder, PaddingPackets) {
246 uint16_t sn = Rand();
247
248 InsertGeneric(sn, sn, true);
249 InsertGeneric(sn + 2, sn + 2, false);
250 EXPECT_EQ(1UL, frames_from_callback_.size());
251 reference_finder_->PaddingReceived(sn + 1);
252 EXPECT_EQ(2UL, frames_from_callback_.size());
253 }
254
TEST_F(TestRtpFrameReferenceFinder,PaddingPacketsReordered)255 TEST_F(TestRtpFrameReferenceFinder, PaddingPacketsReordered) {
256 uint16_t sn = Rand();
257
258 InsertGeneric(sn, sn, true);
259 reference_finder_->PaddingReceived(sn + 1);
260 reference_finder_->PaddingReceived(sn + 4);
261 InsertGeneric(sn + 2, sn + 3, false);
262
263 EXPECT_EQ(2UL, frames_from_callback_.size());
264 CheckReferencesGeneric(sn);
265 CheckReferencesGeneric(sn + 3, sn + 0);
266 }
267
TEST_F(TestRtpFrameReferenceFinder,PaddingPacketsReorderedMultipleKeyframes)268 TEST_F(TestRtpFrameReferenceFinder, PaddingPacketsReorderedMultipleKeyframes) {
269 uint16_t sn = Rand();
270
271 InsertGeneric(sn, sn, true);
272 reference_finder_->PaddingReceived(sn + 1);
273 reference_finder_->PaddingReceived(sn + 4);
274 InsertGeneric(sn + 2, sn + 3, false);
275 InsertGeneric(sn + 5, sn + 5, true);
276 reference_finder_->PaddingReceived(sn + 6);
277 reference_finder_->PaddingReceived(sn + 9);
278 InsertGeneric(sn + 7, sn + 8, false);
279
280 EXPECT_EQ(4UL, frames_from_callback_.size());
281 }
282
TEST_F(TestRtpFrameReferenceFinder,AdvanceSavedKeyframe)283 TEST_F(TestRtpFrameReferenceFinder, AdvanceSavedKeyframe) {
284 uint16_t sn = Rand();
285
286 InsertGeneric(sn, sn, true);
287 InsertGeneric(sn + 1, sn + 1, true);
288 InsertGeneric(sn + 2, sn + 10000, false);
289 InsertGeneric(sn + 10001, sn + 20000, false);
290 InsertGeneric(sn + 20001, sn + 30000, false);
291 InsertGeneric(sn + 30001, sn + 40000, false);
292
293 EXPECT_EQ(6UL, frames_from_callback_.size());
294 }
295
TEST_F(TestRtpFrameReferenceFinder,AdvanceSavedKeyframeBigJump)296 TEST_F(TestRtpFrameReferenceFinder, AdvanceSavedKeyframeBigJump) {
297 InsertVp9Flex(0, 0, true);
298 InsertVp9Flex(1, 1, true);
299 reference_finder_->PaddingReceived(32768);
300 }
301
TEST_F(TestRtpFrameReferenceFinder,ClearTo)302 TEST_F(TestRtpFrameReferenceFinder, ClearTo) {
303 uint16_t sn = Rand();
304
305 InsertGeneric(sn, sn + 1, true);
306 InsertGeneric(sn + 4, sn + 5, false); // stashed
307 EXPECT_EQ(1UL, frames_from_callback_.size());
308
309 InsertGeneric(sn + 6, sn + 7, true); // keyframe
310 EXPECT_EQ(2UL, frames_from_callback_.size());
311 reference_finder_->ClearTo(sn + 7);
312
313 InsertGeneric(sn + 8, sn + 9, false); // first frame after keyframe.
314 EXPECT_EQ(3UL, frames_from_callback_.size());
315
316 InsertGeneric(sn + 2, sn + 3, false); // late, cleared past this frame.
317 EXPECT_EQ(3UL, frames_from_callback_.size());
318 }
319
TEST_F(TestRtpFrameReferenceFinder,Vp8NoPictureId)320 TEST_F(TestRtpFrameReferenceFinder, Vp8NoPictureId) {
321 uint16_t sn = Rand();
322
323 InsertVp8(sn, sn + 2, true);
324 ASSERT_EQ(1UL, frames_from_callback_.size());
325
326 InsertVp8(sn + 3, sn + 4, false);
327 ASSERT_EQ(2UL, frames_from_callback_.size());
328
329 InsertVp8(sn + 5, sn + 8, false);
330 ASSERT_EQ(3UL, frames_from_callback_.size());
331
332 InsertVp8(sn + 9, sn + 9, false);
333 ASSERT_EQ(4UL, frames_from_callback_.size());
334
335 InsertVp8(sn + 10, sn + 11, false);
336 ASSERT_EQ(5UL, frames_from_callback_.size());
337
338 InsertVp8(sn + 12, sn + 12, true);
339 ASSERT_EQ(6UL, frames_from_callback_.size());
340
341 InsertVp8(sn + 13, sn + 17, false);
342 ASSERT_EQ(7UL, frames_from_callback_.size());
343
344 InsertVp8(sn + 18, sn + 18, false);
345 ASSERT_EQ(8UL, frames_from_callback_.size());
346
347 InsertVp8(sn + 19, sn + 20, false);
348 ASSERT_EQ(9UL, frames_from_callback_.size());
349
350 InsertVp8(sn + 21, sn + 21, false);
351
352 ASSERT_EQ(10UL, frames_from_callback_.size());
353 CheckReferencesVp8(sn + 2);
354 CheckReferencesVp8(sn + 4, sn + 2);
355 CheckReferencesVp8(sn + 8, sn + 4);
356 CheckReferencesVp8(sn + 9, sn + 8);
357 CheckReferencesVp8(sn + 11, sn + 9);
358 CheckReferencesVp8(sn + 12);
359 CheckReferencesVp8(sn + 17, sn + 12);
360 CheckReferencesVp8(sn + 18, sn + 17);
361 CheckReferencesVp8(sn + 20, sn + 18);
362 CheckReferencesVp8(sn + 21, sn + 20);
363 }
364
TEST_F(TestRtpFrameReferenceFinder,Vp8NoPictureIdReordered)365 TEST_F(TestRtpFrameReferenceFinder, Vp8NoPictureIdReordered) {
366 uint16_t sn = 0xfffa;
367
368 InsertVp8(sn, sn + 2, true);
369 InsertVp8(sn + 3, sn + 4, false);
370 InsertVp8(sn + 5, sn + 8, false);
371 InsertVp8(sn + 9, sn + 9, false);
372 InsertVp8(sn + 10, sn + 11, false);
373 InsertVp8(sn + 12, sn + 12, true);
374 InsertVp8(sn + 13, sn + 17, false);
375 InsertVp8(sn + 18, sn + 18, false);
376 InsertVp8(sn + 19, sn + 20, false);
377 InsertVp8(sn + 21, sn + 21, false);
378
379 ASSERT_EQ(10UL, frames_from_callback_.size());
380 CheckReferencesVp8(sn + 2);
381 CheckReferencesVp8(sn + 4, sn + 2);
382 CheckReferencesVp8(sn + 8, sn + 4);
383 CheckReferencesVp8(sn + 9, sn + 8);
384 CheckReferencesVp8(sn + 11, sn + 9);
385 CheckReferencesVp8(sn + 12);
386 CheckReferencesVp8(sn + 17, sn + 12);
387 CheckReferencesVp8(sn + 18, sn + 17);
388 CheckReferencesVp8(sn + 20, sn + 18);
389 CheckReferencesVp8(sn + 21, sn + 20);
390 }
391
TEST_F(TestRtpFrameReferenceFinder,Vp8KeyFrameReferences)392 TEST_F(TestRtpFrameReferenceFinder, Vp8KeyFrameReferences) {
393 uint16_t sn = Rand();
394 InsertVp8(sn, sn, true);
395
396 ASSERT_EQ(1UL, frames_from_callback_.size());
397 CheckReferencesVp8(sn);
398 }
399
TEST_F(TestRtpFrameReferenceFinder,Vp8RepeatedFrame_0)400 TEST_F(TestRtpFrameReferenceFinder, Vp8RepeatedFrame_0) {
401 uint16_t pid = Rand();
402 uint16_t sn = Rand();
403
404 InsertVp8(sn, sn, true, pid, 0, 1);
405 InsertVp8(sn + 1, sn + 1, false, pid + 1, 0, 2);
406 InsertVp8(sn + 1, sn + 1, false, pid + 1, 0, 2);
407
408 ASSERT_EQ(2UL, frames_from_callback_.size());
409 CheckReferencesVp8(pid);
410 CheckReferencesVp8(pid + 1, pid);
411 }
412
TEST_F(TestRtpFrameReferenceFinder,Vp8RepeatedFrameLayerSync_01)413 TEST_F(TestRtpFrameReferenceFinder, Vp8RepeatedFrameLayerSync_01) {
414 uint16_t pid = Rand();
415 uint16_t sn = Rand();
416
417 InsertVp8(sn, sn, true, pid, 0, 1);
418 InsertVp8(sn + 1, sn + 1, false, pid + 1, 1, 1, true);
419 ASSERT_EQ(2UL, frames_from_callback_.size());
420 InsertVp8(sn + 1, sn + 1, false, pid + 1, 1, 1, true);
421
422 ASSERT_EQ(2UL, frames_from_callback_.size());
423 CheckReferencesVp8(pid);
424 CheckReferencesVp8(pid + 1, pid);
425 }
426
TEST_F(TestRtpFrameReferenceFinder,Vp8RepeatedFrame_01)427 TEST_F(TestRtpFrameReferenceFinder, Vp8RepeatedFrame_01) {
428 uint16_t pid = Rand();
429 uint16_t sn = Rand();
430
431 InsertVp8(sn, sn, true, pid, 0, 1);
432 InsertVp8(sn + 1, sn + 1, false, pid + 1, 0, 2, true);
433 InsertVp8(sn + 2, sn + 2, false, pid + 2, 0, 3);
434 InsertVp8(sn + 3, sn + 3, false, pid + 3, 0, 4);
435 InsertVp8(sn + 3, sn + 3, false, pid + 3, 0, 4);
436
437 ASSERT_EQ(4UL, frames_from_callback_.size());
438 CheckReferencesVp8(pid);
439 CheckReferencesVp8(pid + 1, pid);
440 CheckReferencesVp8(pid + 2, pid + 1);
441 CheckReferencesVp8(pid + 3, pid + 2);
442 }
443
444 // Test with 1 temporal layer.
TEST_F(TestRtpFrameReferenceFinder,Vp8TemporalLayers_0)445 TEST_F(TestRtpFrameReferenceFinder, Vp8TemporalLayers_0) {
446 uint16_t pid = Rand();
447 uint16_t sn = Rand();
448
449 InsertVp8(sn, sn, true, pid, 0, 1);
450 InsertVp8(sn + 1, sn + 1, false, pid + 1, 0, 2);
451 InsertVp8(sn + 2, sn + 2, false, pid + 2, 0, 3);
452 InsertVp8(sn + 3, sn + 3, false, pid + 3, 0, 4);
453
454 ASSERT_EQ(4UL, frames_from_callback_.size());
455 CheckReferencesVp8(pid);
456 CheckReferencesVp8(pid + 1, pid);
457 CheckReferencesVp8(pid + 2, pid + 1);
458 CheckReferencesVp8(pid + 3, pid + 2);
459 }
460
TEST_F(TestRtpFrameReferenceFinder,Vp8DuplicateTl1Frames)461 TEST_F(TestRtpFrameReferenceFinder, Vp8DuplicateTl1Frames) {
462 uint16_t pid = Rand();
463 uint16_t sn = Rand();
464
465 InsertVp8(sn, sn, true, pid, 0, 0);
466 InsertVp8(sn + 1, sn + 1, false, pid + 1, 1, 0, true);
467 InsertVp8(sn + 2, sn + 2, false, pid + 2, 0, 1);
468 InsertVp8(sn + 3, sn + 3, false, pid + 3, 1, 1);
469 InsertVp8(sn + 3, sn + 3, false, pid + 3, 1, 1);
470 InsertVp8(sn + 4, sn + 4, false, pid + 4, 0, 2);
471 InsertVp8(sn + 5, sn + 5, false, pid + 5, 1, 2);
472
473 ASSERT_EQ(6UL, frames_from_callback_.size());
474 CheckReferencesVp8(pid);
475 CheckReferencesVp8(pid + 1, pid);
476 CheckReferencesVp8(pid + 2, pid);
477 CheckReferencesVp8(pid + 3, pid + 1, pid + 2);
478 CheckReferencesVp8(pid + 4, pid + 2);
479 CheckReferencesVp8(pid + 5, pid + 3, pid + 4);
480 }
481
482 // Test with 1 temporal layer.
TEST_F(TestRtpFrameReferenceFinder,Vp8TemporalLayersReordering_0)483 TEST_F(TestRtpFrameReferenceFinder, Vp8TemporalLayersReordering_0) {
484 uint16_t pid = Rand();
485 uint16_t sn = Rand();
486
487 InsertVp8(sn, sn, true, pid, 0, 1);
488 InsertVp8(sn + 1, sn + 1, false, pid + 1, 0, 2);
489 InsertVp8(sn + 3, sn + 3, false, pid + 3, 0, 4);
490 InsertVp8(sn + 2, sn + 2, false, pid + 2, 0, 3);
491 InsertVp8(sn + 5, sn + 5, false, pid + 5, 0, 6);
492 InsertVp8(sn + 6, sn + 6, false, pid + 6, 0, 7);
493 InsertVp8(sn + 4, sn + 4, false, pid + 4, 0, 5);
494
495 ASSERT_EQ(7UL, frames_from_callback_.size());
496 CheckReferencesVp8(pid);
497 CheckReferencesVp8(pid + 1, pid);
498 CheckReferencesVp8(pid + 2, pid + 1);
499 CheckReferencesVp8(pid + 3, pid + 2);
500 CheckReferencesVp8(pid + 4, pid + 3);
501 CheckReferencesVp8(pid + 5, pid + 4);
502 CheckReferencesVp8(pid + 6, pid + 5);
503 }
504
505 // Test with 2 temporal layers in a 01 pattern.
TEST_F(TestRtpFrameReferenceFinder,Vp8TemporalLayers_01)506 TEST_F(TestRtpFrameReferenceFinder, Vp8TemporalLayers_01) {
507 uint16_t pid = Rand();
508 uint16_t sn = Rand();
509
510 InsertVp8(sn, sn, true, pid, 0, 255);
511 InsertVp8(sn + 1, sn + 1, false, pid + 1, 1, 255, true);
512 InsertVp8(sn + 2, sn + 2, false, pid + 2, 0, 0);
513 InsertVp8(sn + 3, sn + 3, false, pid + 3, 1, 0);
514
515 ASSERT_EQ(4UL, frames_from_callback_.size());
516 CheckReferencesVp8(pid);
517 CheckReferencesVp8(pid + 1, pid);
518 CheckReferencesVp8(pid + 2, pid);
519 CheckReferencesVp8(pid + 3, pid + 1, pid + 2);
520 }
521
522 // Test with 2 temporal layers in a 01 pattern.
TEST_F(TestRtpFrameReferenceFinder,Vp8TemporalLayersReordering_01)523 TEST_F(TestRtpFrameReferenceFinder, Vp8TemporalLayersReordering_01) {
524 uint16_t pid = Rand();
525 uint16_t sn = Rand();
526
527 InsertVp8(sn + 1, sn + 1, false, pid + 1, 1, 255, true);
528 InsertVp8(sn, sn, true, pid, 0, 255);
529 InsertVp8(sn + 3, sn + 3, false, pid + 3, 1, 0);
530 InsertVp8(sn + 5, sn + 5, false, pid + 5, 1, 1);
531 InsertVp8(sn + 2, sn + 2, false, pid + 2, 0, 0);
532 InsertVp8(sn + 4, sn + 4, false, pid + 4, 0, 1);
533 InsertVp8(sn + 6, sn + 6, false, pid + 6, 0, 2);
534 InsertVp8(sn + 7, sn + 7, false, pid + 7, 1, 2);
535
536 ASSERT_EQ(8UL, frames_from_callback_.size());
537 CheckReferencesVp8(pid);
538 CheckReferencesVp8(pid + 1, pid);
539 CheckReferencesVp8(pid + 2, pid);
540 CheckReferencesVp8(pid + 3, pid + 1, pid + 2);
541 CheckReferencesVp8(pid + 4, pid + 2);
542 CheckReferencesVp8(pid + 5, pid + 3, pid + 4);
543 CheckReferencesVp8(pid + 6, pid + 4);
544 CheckReferencesVp8(pid + 7, pid + 5, pid + 6);
545 }
546
547 // Test with 3 temporal layers in a 0212 pattern.
TEST_F(TestRtpFrameReferenceFinder,Vp8TemporalLayers_0212)548 TEST_F(TestRtpFrameReferenceFinder, Vp8TemporalLayers_0212) {
549 uint16_t pid = Rand();
550 uint16_t sn = Rand();
551
552 InsertVp8(sn, sn, true, pid, 0, 55);
553 InsertVp8(sn + 1, sn + 1, false, pid + 1, 2, 55, true);
554 InsertVp8(sn + 2, sn + 2, false, pid + 2, 1, 55, true);
555 InsertVp8(sn + 3, sn + 3, false, pid + 3, 2, 55);
556 InsertVp8(sn + 4, sn + 4, false, pid + 4, 0, 56);
557 InsertVp8(sn + 5, sn + 5, false, pid + 5, 2, 56);
558 InsertVp8(sn + 6, sn + 6, false, pid + 6, 1, 56);
559 InsertVp8(sn + 7, sn + 7, false, pid + 7, 2, 56);
560 InsertVp8(sn + 8, sn + 8, false, pid + 8, 0, 57);
561 InsertVp8(sn + 9, sn + 9, false, pid + 9, 2, 57, true);
562 InsertVp8(sn + 10, sn + 10, false, pid + 10, 1, 57, true);
563 InsertVp8(sn + 11, sn + 11, false, pid + 11, 2, 57);
564
565 ASSERT_EQ(12UL, frames_from_callback_.size());
566 CheckReferencesVp8(pid);
567 CheckReferencesVp8(pid + 1, pid);
568 CheckReferencesVp8(pid + 2, pid);
569 CheckReferencesVp8(pid + 3, pid, pid + 1, pid + 2);
570 CheckReferencesVp8(pid + 4, pid);
571 CheckReferencesVp8(pid + 5, pid + 2, pid + 3, pid + 4);
572 CheckReferencesVp8(pid + 6, pid + 2, pid + 4);
573 CheckReferencesVp8(pid + 7, pid + 4, pid + 5, pid + 6);
574 CheckReferencesVp8(pid + 8, pid + 4);
575 CheckReferencesVp8(pid + 9, pid + 8);
576 CheckReferencesVp8(pid + 10, pid + 8);
577 CheckReferencesVp8(pid + 11, pid + 8, pid + 9, pid + 10);
578 }
579
580 // Test with 3 temporal layers in a 0212 pattern.
TEST_F(TestRtpFrameReferenceFinder,Vp8TemporalLayersMissingFrame_0212)581 TEST_F(TestRtpFrameReferenceFinder, Vp8TemporalLayersMissingFrame_0212) {
582 uint16_t pid = Rand();
583 uint16_t sn = Rand();
584
585 InsertVp8(sn, sn, true, pid, 0, 55, false);
586 InsertVp8(sn + 2, sn + 2, false, pid + 2, 1, 55, true);
587 InsertVp8(sn + 3, sn + 3, false, pid + 3, 2, 55, false);
588
589 ASSERT_EQ(2UL, frames_from_callback_.size());
590 CheckReferencesVp8(pid);
591 CheckReferencesVp8(pid + 2, pid);
592 }
593
594 // Test with 3 temporal layers in a 0212 pattern.
TEST_F(TestRtpFrameReferenceFinder,Vp8TemporalLayersReordering_0212)595 TEST_F(TestRtpFrameReferenceFinder, Vp8TemporalLayersReordering_0212) {
596 uint16_t pid = 126;
597 uint16_t sn = Rand();
598
599 InsertVp8(sn + 1, sn + 1, false, pid + 1, 2, 55, true);
600 InsertVp8(sn, sn, true, pid, 0, 55, false);
601 InsertVp8(sn + 2, sn + 2, false, pid + 2, 1, 55, true);
602 InsertVp8(sn + 4, sn + 4, false, pid + 4, 0, 56, false);
603 InsertVp8(sn + 5, sn + 5, false, pid + 5, 2, 56, false);
604 InsertVp8(sn + 3, sn + 3, false, pid + 3, 2, 55, false);
605 InsertVp8(sn + 7, sn + 7, false, pid + 7, 2, 56, false);
606 InsertVp8(sn + 9, sn + 9, false, pid + 9, 2, 57, true);
607 InsertVp8(sn + 6, sn + 6, false, pid + 6, 1, 56, false);
608 InsertVp8(sn + 8, sn + 8, false, pid + 8, 0, 57, false);
609 InsertVp8(sn + 11, sn + 11, false, pid + 11, 2, 57, false);
610 InsertVp8(sn + 10, sn + 10, false, pid + 10, 1, 57, true);
611
612 ASSERT_EQ(12UL, frames_from_callback_.size());
613 CheckReferencesVp8(pid);
614 CheckReferencesVp8(pid + 1, pid);
615 CheckReferencesVp8(pid + 2, pid);
616 CheckReferencesVp8(pid + 3, pid, pid + 1, pid + 2);
617 CheckReferencesVp8(pid + 4, pid);
618 CheckReferencesVp8(pid + 5, pid + 2, pid + 3, pid + 4);
619 CheckReferencesVp8(pid + 6, pid + 2, pid + 4);
620 CheckReferencesVp8(pid + 7, pid + 4, pid + 5, pid + 6);
621 CheckReferencesVp8(pid + 8, pid + 4);
622 CheckReferencesVp8(pid + 9, pid + 8);
623 CheckReferencesVp8(pid + 10, pid + 8);
624 CheckReferencesVp8(pid + 11, pid + 8, pid + 9, pid + 10);
625 }
626
TEST_F(TestRtpFrameReferenceFinder,Vp8InsertManyFrames_0212)627 TEST_F(TestRtpFrameReferenceFinder, Vp8InsertManyFrames_0212) {
628 uint16_t pid = Rand();
629 uint16_t sn = Rand();
630
631 const int keyframes_to_insert = 50;
632 const int frames_per_keyframe = 120; // Should be a multiple of 4.
633 uint8_t tl0 = 128;
634
635 for (int k = 0; k < keyframes_to_insert; ++k) {
636 InsertVp8(sn, sn, true, pid, 0, tl0, false);
637 InsertVp8(sn + 1, sn + 1, false, pid + 1, 2, tl0, true);
638 InsertVp8(sn + 2, sn + 2, false, pid + 2, 1, tl0, true);
639 InsertVp8(sn + 3, sn + 3, false, pid + 3, 2, tl0, false);
640 CheckReferencesVp8(pid);
641 CheckReferencesVp8(pid + 1, pid);
642 CheckReferencesVp8(pid + 2, pid);
643 CheckReferencesVp8(pid + 3, pid, pid + 1, pid + 2);
644 frames_from_callback_.clear();
645 ++tl0;
646
647 for (int f = 4; f < frames_per_keyframe; f += 4) {
648 uint16_t sf = sn + f;
649 int64_t pidf = pid + f;
650
651 InsertVp8(sf, sf, false, pidf, 0, tl0, false);
652 InsertVp8(sf + 1, sf + 1, false, pidf + 1, 2, tl0, false);
653 InsertVp8(sf + 2, sf + 2, false, pidf + 2, 1, tl0, false);
654 InsertVp8(sf + 3, sf + 3, false, pidf + 3, 2, tl0, false);
655 CheckReferencesVp8(pidf, pidf - 4);
656 CheckReferencesVp8(pidf + 1, pidf, pidf - 1, pidf - 2);
657 CheckReferencesVp8(pidf + 2, pidf, pidf - 2);
658 CheckReferencesVp8(pidf + 3, pidf, pidf + 1, pidf + 2);
659 frames_from_callback_.clear();
660 ++tl0;
661 }
662
663 pid += frames_per_keyframe;
664 sn += frames_per_keyframe;
665 }
666 }
667
TEST_F(TestRtpFrameReferenceFinder,Vp8LayerSync)668 TEST_F(TestRtpFrameReferenceFinder, Vp8LayerSync) {
669 uint16_t pid = Rand();
670 uint16_t sn = Rand();
671
672 InsertVp8(sn, sn, true, pid, 0, 0, false);
673 InsertVp8(sn + 1, sn + 1, false, pid + 1, 1, 0, true);
674 InsertVp8(sn + 2, sn + 2, false, pid + 2, 0, 1, false);
675 ASSERT_EQ(3UL, frames_from_callback_.size());
676
677 InsertVp8(sn + 4, sn + 4, false, pid + 4, 0, 2, false);
678 InsertVp8(sn + 5, sn + 5, false, pid + 5, 1, 2, true);
679 InsertVp8(sn + 6, sn + 6, false, pid + 6, 0, 3, false);
680 InsertVp8(sn + 7, sn + 7, false, pid + 7, 1, 3, false);
681
682 ASSERT_EQ(7UL, frames_from_callback_.size());
683 CheckReferencesVp8(pid);
684 CheckReferencesVp8(pid + 1, pid);
685 CheckReferencesVp8(pid + 2, pid);
686 CheckReferencesVp8(pid + 4, pid + 2);
687 CheckReferencesVp8(pid + 5, pid + 4);
688 CheckReferencesVp8(pid + 6, pid + 4);
689 CheckReferencesVp8(pid + 7, pid + 6, pid + 5);
690 }
691
TEST_F(TestRtpFrameReferenceFinder,Vp8Tl1SyncFrameAfterTl1Frame)692 TEST_F(TestRtpFrameReferenceFinder, Vp8Tl1SyncFrameAfterTl1Frame) {
693 InsertVp8(1000, 1000, true, 1, 0, 247, true);
694 InsertVp8(1001, 1001, false, 3, 0, 248, false);
695 InsertVp8(1002, 1002, false, 4, 1, 248, false); // Will be dropped
696 InsertVp8(1003, 1003, false, 5, 1, 248, true); // due to this frame.
697
698 ASSERT_EQ(3UL, frames_from_callback_.size());
699 CheckReferencesVp8(1);
700 CheckReferencesVp8(3, 1);
701 CheckReferencesVp8(5, 3);
702 }
703
TEST_F(TestRtpFrameReferenceFinder,Vp8DetectMissingFrame_0212)704 TEST_F(TestRtpFrameReferenceFinder, Vp8DetectMissingFrame_0212) {
705 InsertVp8(1, 1, true, 1, 0, 1, false);
706 InsertVp8(2, 2, false, 2, 2, 1, true);
707 InsertVp8(3, 3, false, 3, 1, 1, true);
708 InsertVp8(4, 4, false, 4, 2, 1, false);
709
710 InsertVp8(6, 6, false, 6, 2, 2, false);
711 InsertVp8(7, 7, false, 7, 1, 2, false);
712 InsertVp8(8, 8, false, 8, 2, 2, false);
713 ASSERT_EQ(4UL, frames_from_callback_.size());
714
715 InsertVp8(5, 5, false, 5, 0, 2, false);
716 ASSERT_EQ(8UL, frames_from_callback_.size());
717
718 CheckReferencesVp8(1);
719 CheckReferencesVp8(2, 1);
720 CheckReferencesVp8(3, 1);
721 CheckReferencesVp8(4, 3, 2, 1);
722
723 CheckReferencesVp8(5, 1);
724 CheckReferencesVp8(6, 5, 4, 3);
725 CheckReferencesVp8(7, 5, 3);
726 CheckReferencesVp8(8, 7, 6, 5);
727 }
728
TEST_F(TestRtpFrameReferenceFinder,Vp9GofInsertOneFrame)729 TEST_F(TestRtpFrameReferenceFinder, Vp9GofInsertOneFrame) {
730 uint16_t pid = Rand();
731 uint16_t sn = Rand();
732 GofInfoVP9 ss;
733 ss.SetGofInfoVP9(kTemporalStructureMode1);
734
735 InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
736
737 CheckReferencesVp9(pid, 0);
738 }
739
TEST_F(TestRtpFrameReferenceFinder,Vp9NoPictureIdReordered)740 TEST_F(TestRtpFrameReferenceFinder, Vp9NoPictureIdReordered) {
741 uint16_t sn = 0xfffa;
742
743 InsertVp9Gof(sn, sn + 2, true);
744 InsertVp9Gof(sn + 3, sn + 4, false);
745 InsertVp9Gof(sn + 9, sn + 9, false);
746 InsertVp9Gof(sn + 5, sn + 8, false);
747 InsertVp9Gof(sn + 12, sn + 12, true);
748 InsertVp9Gof(sn + 10, sn + 11, false);
749 InsertVp9Gof(sn + 13, sn + 17, false);
750 InsertVp9Gof(sn + 19, sn + 20, false);
751 InsertVp9Gof(sn + 21, sn + 21, false);
752 InsertVp9Gof(sn + 18, sn + 18, false);
753
754 ASSERT_EQ(10UL, frames_from_callback_.size());
755 CheckReferencesVp9(sn + 2, 0);
756 CheckReferencesVp9(sn + 4, 0, sn + 2);
757 CheckReferencesVp9(sn + 8, 0, sn + 4);
758 CheckReferencesVp9(sn + 9, 0, sn + 8);
759 CheckReferencesVp9(sn + 11, 0, sn + 9);
760 CheckReferencesVp9(sn + 12, 0);
761 CheckReferencesVp9(sn + 17, 0, sn + 12);
762 CheckReferencesVp9(sn + 18, 0, sn + 17);
763 CheckReferencesVp9(sn + 20, 0, sn + 18);
764 CheckReferencesVp9(sn + 21, 0, sn + 20);
765 }
766
TEST_F(TestRtpFrameReferenceFinder,Vp9GofTemporalLayers_0)767 TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayers_0) {
768 uint16_t pid = Rand();
769 uint16_t sn = Rand();
770 GofInfoVP9 ss;
771 ss.SetGofInfoVP9(kTemporalStructureMode1); // Only 1 spatial layer.
772
773 InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
774 InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 0, 1, false);
775 InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 0, 2, false);
776 InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 0, 3, false);
777 InsertVp9Gof(sn + 4, sn + 4, false, pid + 4, 0, 0, 4, false);
778 InsertVp9Gof(sn + 5, sn + 5, false, pid + 5, 0, 0, 5, false);
779 InsertVp9Gof(sn + 6, sn + 6, false, pid + 6, 0, 0, 6, false);
780 InsertVp9Gof(sn + 7, sn + 7, false, pid + 7, 0, 0, 7, false);
781 InsertVp9Gof(sn + 8, sn + 8, false, pid + 8, 0, 0, 8, false);
782 InsertVp9Gof(sn + 9, sn + 9, false, pid + 9, 0, 0, 9, false);
783 InsertVp9Gof(sn + 10, sn + 10, false, pid + 10, 0, 0, 10, false);
784 InsertVp9Gof(sn + 11, sn + 11, false, pid + 11, 0, 0, 11, false);
785 InsertVp9Gof(sn + 12, sn + 12, false, pid + 12, 0, 0, 12, false);
786 InsertVp9Gof(sn + 13, sn + 13, false, pid + 13, 0, 0, 13, false);
787 InsertVp9Gof(sn + 14, sn + 14, false, pid + 14, 0, 0, 14, false);
788 InsertVp9Gof(sn + 15, sn + 15, false, pid + 15, 0, 0, 15, false);
789 InsertVp9Gof(sn + 16, sn + 16, false, pid + 16, 0, 0, 16, false);
790 InsertVp9Gof(sn + 17, sn + 17, false, pid + 17, 0, 0, 17, false);
791 InsertVp9Gof(sn + 18, sn + 18, false, pid + 18, 0, 0, 18, false);
792 InsertVp9Gof(sn + 19, sn + 19, false, pid + 19, 0, 0, 19, false);
793
794 ASSERT_EQ(20UL, frames_from_callback_.size());
795 CheckReferencesVp9(pid, 0);
796 CheckReferencesVp9(pid + 1, 0, pid);
797 CheckReferencesVp9(pid + 2, 0, pid + 1);
798 CheckReferencesVp9(pid + 3, 0, pid + 2);
799 CheckReferencesVp9(pid + 4, 0, pid + 3);
800 CheckReferencesVp9(pid + 5, 0, pid + 4);
801 CheckReferencesVp9(pid + 6, 0, pid + 5);
802 CheckReferencesVp9(pid + 7, 0, pid + 6);
803 CheckReferencesVp9(pid + 8, 0, pid + 7);
804 CheckReferencesVp9(pid + 9, 0, pid + 8);
805 CheckReferencesVp9(pid + 10, 0, pid + 9);
806 CheckReferencesVp9(pid + 11, 0, pid + 10);
807 CheckReferencesVp9(pid + 12, 0, pid + 11);
808 CheckReferencesVp9(pid + 13, 0, pid + 12);
809 CheckReferencesVp9(pid + 14, 0, pid + 13);
810 CheckReferencesVp9(pid + 15, 0, pid + 14);
811 CheckReferencesVp9(pid + 16, 0, pid + 15);
812 CheckReferencesVp9(pid + 17, 0, pid + 16);
813 CheckReferencesVp9(pid + 18, 0, pid + 17);
814 CheckReferencesVp9(pid + 19, 0, pid + 18);
815 }
816
TEST_F(TestRtpFrameReferenceFinder,Vp9GofSpatialLayers_2)817 TEST_F(TestRtpFrameReferenceFinder, Vp9GofSpatialLayers_2) {
818 uint16_t pid = Rand();
819 uint16_t sn = Rand();
820 GofInfoVP9 ss;
821 ss.SetGofInfoVP9(kTemporalStructureMode1); // Only 1 spatial layer.
822
823 InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
824 InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 0, 1, false, true);
825 // Not inter_pic_predicted because it's the first frame with this layer.
826 InsertVp9Gof(sn + 2, sn + 2, false, pid + 1, 1, 0, 1, false, false);
827 InsertVp9Gof(sn + 3, sn + 3, false, pid + 2, 0, 0, 1, false, true);
828 InsertVp9Gof(sn + 4, sn + 4, false, pid + 2, 1, 0, 1, false, true);
829
830 ASSERT_EQ(5UL, frames_from_callback_.size());
831 CheckReferencesVp9(pid, 0);
832 CheckReferencesVp9(pid + 1, 0, pid);
833 CheckReferencesVp9(pid + 1, 1);
834 CheckReferencesVp9(pid + 2, 0, pid + 1);
835 CheckReferencesVp9(pid + 2, 1, pid + 1);
836 }
837
TEST_F(TestRtpFrameReferenceFinder,Vp9GofTemporalLayersReordered_0)838 TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayersReordered_0) {
839 uint16_t pid = Rand();
840 uint16_t sn = Rand();
841 GofInfoVP9 ss;
842 ss.SetGofInfoVP9(kTemporalStructureMode1); // Only 1 spatial layer.
843
844 InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 0, 2, false);
845 InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 0, 1, false);
846 InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
847 InsertVp9Gof(sn + 4, sn + 4, false, pid + 4, 0, 0, 4, false);
848 InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 0, 3, false);
849 InsertVp9Gof(sn + 5, sn + 5, false, pid + 5, 0, 0, 5, false);
850 InsertVp9Gof(sn + 7, sn + 7, false, pid + 7, 0, 0, 7, false);
851 InsertVp9Gof(sn + 6, sn + 6, false, pid + 6, 0, 0, 6, false);
852 InsertVp9Gof(sn + 8, sn + 8, false, pid + 8, 0, 0, 8, false);
853 InsertVp9Gof(sn + 10, sn + 10, false, pid + 10, 0, 0, 10, false);
854 InsertVp9Gof(sn + 13, sn + 13, false, pid + 13, 0, 0, 13, false);
855 InsertVp9Gof(sn + 11, sn + 11, false, pid + 11, 0, 0, 11, false);
856 InsertVp9Gof(sn + 9, sn + 9, false, pid + 9, 0, 0, 9, false);
857 InsertVp9Gof(sn + 16, sn + 16, false, pid + 16, 0, 0, 16, false);
858 InsertVp9Gof(sn + 14, sn + 14, false, pid + 14, 0, 0, 14, false);
859 InsertVp9Gof(sn + 15, sn + 15, false, pid + 15, 0, 0, 15, false);
860 InsertVp9Gof(sn + 12, sn + 12, false, pid + 12, 0, 0, 12, false);
861 InsertVp9Gof(sn + 17, sn + 17, false, pid + 17, 0, 0, 17, false);
862 InsertVp9Gof(sn + 19, sn + 19, false, pid + 19, 0, 0, 19, false);
863 InsertVp9Gof(sn + 18, sn + 18, false, pid + 18, 0, 0, 18, false);
864
865 ASSERT_EQ(20UL, frames_from_callback_.size());
866 CheckReferencesVp9(pid, 0);
867 CheckReferencesVp9(pid + 1, 0, pid);
868 CheckReferencesVp9(pid + 2, 0, pid + 1);
869 CheckReferencesVp9(pid + 3, 0, pid + 2);
870 CheckReferencesVp9(pid + 4, 0, pid + 3);
871 CheckReferencesVp9(pid + 5, 0, pid + 4);
872 CheckReferencesVp9(pid + 6, 0, pid + 5);
873 CheckReferencesVp9(pid + 7, 0, pid + 6);
874 CheckReferencesVp9(pid + 8, 0, pid + 7);
875 CheckReferencesVp9(pid + 9, 0, pid + 8);
876 CheckReferencesVp9(pid + 10, 0, pid + 9);
877 CheckReferencesVp9(pid + 11, 0, pid + 10);
878 CheckReferencesVp9(pid + 12, 0, pid + 11);
879 CheckReferencesVp9(pid + 13, 0, pid + 12);
880 CheckReferencesVp9(pid + 14, 0, pid + 13);
881 CheckReferencesVp9(pid + 15, 0, pid + 14);
882 CheckReferencesVp9(pid + 16, 0, pid + 15);
883 CheckReferencesVp9(pid + 17, 0, pid + 16);
884 CheckReferencesVp9(pid + 18, 0, pid + 17);
885 CheckReferencesVp9(pid + 19, 0, pid + 18);
886 }
887
TEST_F(TestRtpFrameReferenceFinder,Vp9GofSkipFramesTemporalLayers_01)888 TEST_F(TestRtpFrameReferenceFinder, Vp9GofSkipFramesTemporalLayers_01) {
889 uint16_t pid = Rand();
890 uint16_t sn = Rand();
891 GofInfoVP9 ss;
892 ss.SetGofInfoVP9(kTemporalStructureMode2); // 0101 pattern
893
894 InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
895 InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 1, 0, false);
896 // Skip GOF with tl0 1
897 InsertVp9Gof(sn + 4, sn + 4, true, pid + 4, 0, 0, 2, false, true, &ss);
898 InsertVp9Gof(sn + 5, sn + 5, false, pid + 5, 0, 1, 2, false);
899 // Skip GOF with tl0 3
900 // Skip GOF with tl0 4
901 InsertVp9Gof(sn + 10, sn + 10, false, pid + 10, 0, 0, 5, false, true, &ss);
902 InsertVp9Gof(sn + 11, sn + 11, false, pid + 11, 0, 1, 5, false);
903
904 ASSERT_EQ(6UL, frames_from_callback_.size());
905 CheckReferencesVp9(pid, 0);
906 CheckReferencesVp9(pid + 1, 0, pid);
907 CheckReferencesVp9(pid + 4, 0);
908 CheckReferencesVp9(pid + 5, 0, pid + 4);
909 CheckReferencesVp9(pid + 10, 0, pid + 8);
910 CheckReferencesVp9(pid + 11, 0, pid + 10);
911 }
912
TEST_F(TestRtpFrameReferenceFinder,Vp9GofSkipFramesTemporalLayers_0212)913 TEST_F(TestRtpFrameReferenceFinder, Vp9GofSkipFramesTemporalLayers_0212) {
914 uint16_t pid = Rand();
915 uint16_t sn = Rand();
916 GofInfoVP9 ss;
917 ss.SetGofInfoVP9(kTemporalStructureMode3); // 02120212 pattern
918
919 InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
920 InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 2, 0, false);
921 InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 1, 0, false);
922 InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 2, 0, false);
923
924 ASSERT_EQ(4UL, frames_from_callback_.size());
925 CheckReferencesVp9(pid, 0);
926 CheckReferencesVp9(pid + 1, 0, pid);
927 CheckReferencesVp9(pid + 2, 0, pid);
928 CheckReferencesVp9(pid + 3, 0, pid + 2);
929
930 // Skip frames with tl0 = 1
931
932 InsertVp9Gof(sn + 8, sn + 8, true, pid + 8, 0, 0, 2, false, false, &ss);
933 InsertVp9Gof(sn + 9, sn + 9, false, pid + 9, 0, 2, 2, false);
934 InsertVp9Gof(sn + 10, sn + 10, false, pid + 10, 0, 1, 2, false);
935 InsertVp9Gof(sn + 11, sn + 11, false, pid + 11, 0, 2, 2, false);
936
937 ASSERT_EQ(8UL, frames_from_callback_.size());
938 CheckReferencesVp9(pid + 8, 0);
939 CheckReferencesVp9(pid + 9, 0, pid + 8);
940 CheckReferencesVp9(pid + 10, 0, pid + 8);
941 CheckReferencesVp9(pid + 11, 0, pid + 10);
942
943 // Now insert frames with tl0 = 1
944 InsertVp9Gof(sn + 4, sn + 4, true, pid + 4, 0, 0, 1, false, true, &ss);
945 InsertVp9Gof(sn + 7, sn + 7, false, pid + 7, 0, 2, 1, false);
946
947 ASSERT_EQ(9UL, frames_from_callback_.size());
948 CheckReferencesVp9(pid + 4, 0);
949
950 // Rest of frames belonging to tl0 = 1
951 InsertVp9Gof(sn + 5, sn + 5, false, pid + 5, 0, 2, 1, false);
952 InsertVp9Gof(sn + 6, sn + 6, false, pid + 6, 0, 1, 1, true); // up-switch
953
954 ASSERT_EQ(12UL, frames_from_callback_.size());
955 CheckReferencesVp9(pid + 5, 0, pid + 4);
956 CheckReferencesVp9(pid + 6, 0, pid + 4);
957 CheckReferencesVp9(pid + 7, 0, pid + 6);
958 }
959
TEST_F(TestRtpFrameReferenceFinder,Vp9GofTemporalLayers_01)960 TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayers_01) {
961 uint16_t pid = Rand();
962 uint16_t sn = Rand();
963 GofInfoVP9 ss;
964 ss.SetGofInfoVP9(kTemporalStructureMode2); // 0101 pattern
965
966 InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
967 InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 1, 0, false);
968 InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 0, 1, false);
969 InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 1, 1, false);
970 InsertVp9Gof(sn + 4, sn + 4, false, pid + 4, 0, 0, 2, false);
971 InsertVp9Gof(sn + 5, sn + 5, false, pid + 5, 0, 1, 2, false);
972 InsertVp9Gof(sn + 6, sn + 6, false, pid + 6, 0, 0, 3, false);
973 InsertVp9Gof(sn + 7, sn + 7, false, pid + 7, 0, 1, 3, false);
974 InsertVp9Gof(sn + 8, sn + 8, false, pid + 8, 0, 0, 4, false);
975 InsertVp9Gof(sn + 9, sn + 9, false, pid + 9, 0, 1, 4, false);
976 InsertVp9Gof(sn + 10, sn + 10, false, pid + 10, 0, 0, 5, false);
977 InsertVp9Gof(sn + 11, sn + 11, false, pid + 11, 0, 1, 5, false);
978 InsertVp9Gof(sn + 12, sn + 12, false, pid + 12, 0, 0, 6, false);
979 InsertVp9Gof(sn + 13, sn + 13, false, pid + 13, 0, 1, 6, false);
980 InsertVp9Gof(sn + 14, sn + 14, false, pid + 14, 0, 0, 7, false);
981 InsertVp9Gof(sn + 15, sn + 15, false, pid + 15, 0, 1, 7, false);
982 InsertVp9Gof(sn + 16, sn + 16, false, pid + 16, 0, 0, 8, false);
983 InsertVp9Gof(sn + 17, sn + 17, false, pid + 17, 0, 1, 8, false);
984 InsertVp9Gof(sn + 18, sn + 18, false, pid + 18, 0, 0, 9, false);
985 InsertVp9Gof(sn + 19, sn + 19, false, pid + 19, 0, 1, 9, false);
986
987 ASSERT_EQ(20UL, frames_from_callback_.size());
988 CheckReferencesVp9(pid, 0);
989 CheckReferencesVp9(pid + 1, 0, pid);
990 CheckReferencesVp9(pid + 2, 0, pid);
991 CheckReferencesVp9(pid + 3, 0, pid + 2);
992 CheckReferencesVp9(pid + 4, 0, pid + 2);
993 CheckReferencesVp9(pid + 5, 0, pid + 4);
994 CheckReferencesVp9(pid + 6, 0, pid + 4);
995 CheckReferencesVp9(pid + 7, 0, pid + 6);
996 CheckReferencesVp9(pid + 8, 0, pid + 6);
997 CheckReferencesVp9(pid + 9, 0, pid + 8);
998 CheckReferencesVp9(pid + 10, 0, pid + 8);
999 CheckReferencesVp9(pid + 11, 0, pid + 10);
1000 CheckReferencesVp9(pid + 12, 0, pid + 10);
1001 CheckReferencesVp9(pid + 13, 0, pid + 12);
1002 CheckReferencesVp9(pid + 14, 0, pid + 12);
1003 CheckReferencesVp9(pid + 15, 0, pid + 14);
1004 CheckReferencesVp9(pid + 16, 0, pid + 14);
1005 CheckReferencesVp9(pid + 17, 0, pid + 16);
1006 CheckReferencesVp9(pid + 18, 0, pid + 16);
1007 CheckReferencesVp9(pid + 19, 0, pid + 18);
1008 }
1009
TEST_F(TestRtpFrameReferenceFinder,Vp9GofTemporalLayersReordered_01)1010 TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayersReordered_01) {
1011 uint16_t pid = Rand();
1012 uint16_t sn = Rand();
1013 GofInfoVP9 ss;
1014 ss.SetGofInfoVP9(kTemporalStructureMode2); // 01 pattern
1015
1016 InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 1, 0, false);
1017 InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
1018 InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 0, 1, false);
1019 InsertVp9Gof(sn + 4, sn + 4, false, pid + 4, 0, 0, 2, false);
1020 InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 1, 1, false);
1021 InsertVp9Gof(sn + 5, sn + 5, false, pid + 5, 0, 1, 2, false);
1022 InsertVp9Gof(sn + 7, sn + 7, false, pid + 7, 0, 1, 3, false);
1023 InsertVp9Gof(sn + 6, sn + 6, false, pid + 6, 0, 0, 3, false);
1024 InsertVp9Gof(sn + 10, sn + 10, false, pid + 10, 0, 0, 5, false);
1025 InsertVp9Gof(sn + 8, sn + 8, false, pid + 8, 0, 0, 4, false);
1026 InsertVp9Gof(sn + 9, sn + 9, false, pid + 9, 0, 1, 4, false);
1027 InsertVp9Gof(sn + 11, sn + 11, false, pid + 11, 0, 1, 5, false);
1028 InsertVp9Gof(sn + 13, sn + 13, false, pid + 13, 0, 1, 6, false);
1029 InsertVp9Gof(sn + 16, sn + 16, false, pid + 16, 0, 0, 8, false);
1030 InsertVp9Gof(sn + 12, sn + 12, false, pid + 12, 0, 0, 6, false);
1031 InsertVp9Gof(sn + 14, sn + 14, false, pid + 14, 0, 0, 7, false);
1032 InsertVp9Gof(sn + 17, sn + 17, false, pid + 17, 0, 1, 8, false);
1033 InsertVp9Gof(sn + 19, sn + 19, false, pid + 19, 0, 1, 9, false);
1034 InsertVp9Gof(sn + 15, sn + 15, false, pid + 15, 0, 1, 7, false);
1035 InsertVp9Gof(sn + 18, sn + 18, false, pid + 18, 0, 0, 9, false);
1036
1037 ASSERT_EQ(20UL, frames_from_callback_.size());
1038 CheckReferencesVp9(pid, 0);
1039 CheckReferencesVp9(pid + 1, 0, pid);
1040 CheckReferencesVp9(pid + 2, 0, pid);
1041 CheckReferencesVp9(pid + 3, 0, pid + 2);
1042 CheckReferencesVp9(pid + 4, 0, pid + 2);
1043 CheckReferencesVp9(pid + 5, 0, pid + 4);
1044 CheckReferencesVp9(pid + 6, 0, pid + 4);
1045 CheckReferencesVp9(pid + 7, 0, pid + 6);
1046 CheckReferencesVp9(pid + 8, 0, pid + 6);
1047 CheckReferencesVp9(pid + 9, 0, pid + 8);
1048 CheckReferencesVp9(pid + 10, 0, pid + 8);
1049 CheckReferencesVp9(pid + 11, 0, pid + 10);
1050 CheckReferencesVp9(pid + 12, 0, pid + 10);
1051 CheckReferencesVp9(pid + 13, 0, pid + 12);
1052 CheckReferencesVp9(pid + 14, 0, pid + 12);
1053 CheckReferencesVp9(pid + 15, 0, pid + 14);
1054 CheckReferencesVp9(pid + 16, 0, pid + 14);
1055 CheckReferencesVp9(pid + 17, 0, pid + 16);
1056 CheckReferencesVp9(pid + 18, 0, pid + 16);
1057 CheckReferencesVp9(pid + 19, 0, pid + 18);
1058 }
1059
TEST_F(TestRtpFrameReferenceFinder,Vp9GofTemporalLayers_0212)1060 TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayers_0212) {
1061 uint16_t pid = Rand();
1062 uint16_t sn = Rand();
1063 GofInfoVP9 ss;
1064 ss.SetGofInfoVP9(kTemporalStructureMode3); // 0212 pattern
1065
1066 InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
1067 InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 2, 0, false);
1068 InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 1, 0, false);
1069 InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 2, 0, false);
1070 InsertVp9Gof(sn + 4, sn + 4, false, pid + 4, 0, 0, 1, false);
1071 InsertVp9Gof(sn + 5, sn + 5, false, pid + 5, 0, 2, 1, false);
1072 InsertVp9Gof(sn + 6, sn + 6, false, pid + 6, 0, 1, 1, false);
1073 InsertVp9Gof(sn + 7, sn + 7, false, pid + 7, 0, 2, 1, false);
1074 InsertVp9Gof(sn + 8, sn + 8, false, pid + 8, 0, 0, 2, false);
1075 InsertVp9Gof(sn + 9, sn + 9, false, pid + 9, 0, 2, 2, false);
1076 InsertVp9Gof(sn + 10, sn + 10, false, pid + 10, 0, 1, 2, false);
1077 InsertVp9Gof(sn + 11, sn + 11, false, pid + 11, 0, 2, 2, false);
1078 InsertVp9Gof(sn + 12, sn + 12, false, pid + 12, 0, 0, 3, false);
1079 InsertVp9Gof(sn + 13, sn + 13, false, pid + 13, 0, 2, 3, false);
1080 InsertVp9Gof(sn + 14, sn + 14, false, pid + 14, 0, 1, 3, false);
1081 InsertVp9Gof(sn + 15, sn + 15, false, pid + 15, 0, 2, 3, false);
1082 InsertVp9Gof(sn + 16, sn + 16, false, pid + 16, 0, 0, 4, false);
1083 InsertVp9Gof(sn + 17, sn + 17, false, pid + 17, 0, 2, 4, false);
1084 InsertVp9Gof(sn + 18, sn + 18, false, pid + 18, 0, 1, 4, false);
1085 InsertVp9Gof(sn + 19, sn + 19, false, pid + 19, 0, 2, 4, false);
1086
1087 ASSERT_EQ(20UL, frames_from_callback_.size());
1088 CheckReferencesVp9(pid, 0);
1089 CheckReferencesVp9(pid + 1, 0, pid);
1090 CheckReferencesVp9(pid + 2, 0, pid);
1091 CheckReferencesVp9(pid + 3, 0, pid + 2);
1092 CheckReferencesVp9(pid + 4, 0, pid);
1093 CheckReferencesVp9(pid + 5, 0, pid + 4);
1094 CheckReferencesVp9(pid + 6, 0, pid + 4);
1095 CheckReferencesVp9(pid + 7, 0, pid + 6);
1096 CheckReferencesVp9(pid + 8, 0, pid + 4);
1097 CheckReferencesVp9(pid + 9, 0, pid + 8);
1098 CheckReferencesVp9(pid + 10, 0, pid + 8);
1099 CheckReferencesVp9(pid + 11, 0, pid + 10);
1100 CheckReferencesVp9(pid + 12, 0, pid + 8);
1101 CheckReferencesVp9(pid + 13, 0, pid + 12);
1102 CheckReferencesVp9(pid + 14, 0, pid + 12);
1103 CheckReferencesVp9(pid + 15, 0, pid + 14);
1104 CheckReferencesVp9(pid + 16, 0, pid + 12);
1105 CheckReferencesVp9(pid + 17, 0, pid + 16);
1106 CheckReferencesVp9(pid + 18, 0, pid + 16);
1107 CheckReferencesVp9(pid + 19, 0, pid + 18);
1108 }
1109
TEST_F(TestRtpFrameReferenceFinder,Vp9GofTemporalLayersReordered_0212)1110 TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayersReordered_0212) {
1111 uint16_t pid = Rand();
1112 uint16_t sn = Rand();
1113 GofInfoVP9 ss;
1114 ss.SetGofInfoVP9(kTemporalStructureMode3); // 0212 pattern
1115
1116 InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 1, 0, false);
1117 InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 2, 0, false);
1118 InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
1119 InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 2, 0, false);
1120 InsertVp9Gof(sn + 6, sn + 6, false, pid + 6, 0, 1, 1, false);
1121 InsertVp9Gof(sn + 5, sn + 5, false, pid + 5, 0, 2, 1, false);
1122 InsertVp9Gof(sn + 4, sn + 4, false, pid + 4, 0, 0, 1, false);
1123 InsertVp9Gof(sn + 9, sn + 9, false, pid + 9, 0, 2, 2, false);
1124 InsertVp9Gof(sn + 7, sn + 7, false, pid + 7, 0, 2, 1, false);
1125 InsertVp9Gof(sn + 8, sn + 8, false, pid + 8, 0, 0, 2, false);
1126 InsertVp9Gof(sn + 11, sn + 11, false, pid + 11, 0, 2, 2, false);
1127 InsertVp9Gof(sn + 10, sn + 10, false, pid + 10, 0, 1, 2, false);
1128 InsertVp9Gof(sn + 13, sn + 13, false, pid + 13, 0, 2, 3, false);
1129 InsertVp9Gof(sn + 12, sn + 12, false, pid + 12, 0, 0, 3, false);
1130 InsertVp9Gof(sn + 14, sn + 14, false, pid + 14, 0, 1, 3, false);
1131 InsertVp9Gof(sn + 16, sn + 16, false, pid + 16, 0, 0, 4, false);
1132 InsertVp9Gof(sn + 15, sn + 15, false, pid + 15, 0, 2, 3, false);
1133 InsertVp9Gof(sn + 17, sn + 17, false, pid + 17, 0, 2, 4, false);
1134 InsertVp9Gof(sn + 19, sn + 19, false, pid + 19, 0, 2, 4, false);
1135 InsertVp9Gof(sn + 18, sn + 18, false, pid + 18, 0, 1, 4, false);
1136
1137 ASSERT_EQ(20UL, frames_from_callback_.size());
1138 CheckReferencesVp9(pid, 0);
1139 CheckReferencesVp9(pid + 1, 0, pid);
1140 CheckReferencesVp9(pid + 2, 0, pid);
1141 CheckReferencesVp9(pid + 3, 0, pid + 2);
1142 CheckReferencesVp9(pid + 4, 0, pid);
1143 CheckReferencesVp9(pid + 5, 0, pid + 4);
1144 CheckReferencesVp9(pid + 6, 0, pid + 4);
1145 CheckReferencesVp9(pid + 7, 0, pid + 6);
1146 CheckReferencesVp9(pid + 8, 0, pid + 4);
1147 CheckReferencesVp9(pid + 9, 0, pid + 8);
1148 CheckReferencesVp9(pid + 10, 0, pid + 8);
1149 CheckReferencesVp9(pid + 11, 0, pid + 10);
1150 CheckReferencesVp9(pid + 12, 0, pid + 8);
1151 CheckReferencesVp9(pid + 13, 0, pid + 12);
1152 CheckReferencesVp9(pid + 14, 0, pid + 12);
1153 CheckReferencesVp9(pid + 15, 0, pid + 14);
1154 CheckReferencesVp9(pid + 16, 0, pid + 12);
1155 CheckReferencesVp9(pid + 17, 0, pid + 16);
1156 CheckReferencesVp9(pid + 18, 0, pid + 16);
1157 CheckReferencesVp9(pid + 19, 0, pid + 18);
1158 }
1159
TEST_F(TestRtpFrameReferenceFinder,Vp9GofTemporalLayersUpSwitch_02120212)1160 TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayersUpSwitch_02120212) {
1161 uint16_t pid = Rand();
1162 uint16_t sn = Rand();
1163 GofInfoVP9 ss;
1164 ss.SetGofInfoVP9(kTemporalStructureMode4); // 02120212 pattern
1165
1166 InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
1167 InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 2, 0, false);
1168 InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 1, 0, false);
1169 InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 2, 0, false);
1170 InsertVp9Gof(sn + 4, sn + 4, false, pid + 4, 0, 0, 1, false);
1171 InsertVp9Gof(sn + 5, sn + 5, false, pid + 5, 0, 2, 1, false);
1172 InsertVp9Gof(sn + 6, sn + 6, false, pid + 6, 0, 1, 1, true);
1173 InsertVp9Gof(sn + 7, sn + 7, false, pid + 7, 0, 2, 1, false);
1174 InsertVp9Gof(sn + 8, sn + 8, false, pid + 8, 0, 0, 2, true);
1175 InsertVp9Gof(sn + 9, sn + 9, false, pid + 9, 0, 2, 2, false);
1176 InsertVp9Gof(sn + 10, sn + 10, false, pid + 10, 0, 1, 2, false);
1177 InsertVp9Gof(sn + 11, sn + 11, false, pid + 11, 0, 2, 2, true);
1178 InsertVp9Gof(sn + 12, sn + 12, false, pid + 12, 0, 0, 3, false);
1179 InsertVp9Gof(sn + 13, sn + 13, false, pid + 13, 0, 2, 3, false);
1180 InsertVp9Gof(sn + 14, sn + 14, false, pid + 14, 0, 1, 3, false);
1181 InsertVp9Gof(sn + 15, sn + 15, false, pid + 15, 0, 2, 3, false);
1182
1183 ASSERT_EQ(16UL, frames_from_callback_.size());
1184 CheckReferencesVp9(pid, 0);
1185 CheckReferencesVp9(pid + 1, 0, pid);
1186 CheckReferencesVp9(pid + 2, 0, pid);
1187 CheckReferencesVp9(pid + 3, 0, pid + 1, pid + 2);
1188 CheckReferencesVp9(pid + 4, 0, pid);
1189 CheckReferencesVp9(pid + 5, 0, pid + 3, pid + 4);
1190 CheckReferencesVp9(pid + 6, 0, pid + 2, pid + 4);
1191 CheckReferencesVp9(pid + 7, 0, pid + 6);
1192 CheckReferencesVp9(pid + 8, 0, pid + 4);
1193 CheckReferencesVp9(pid + 9, 0, pid + 8);
1194 CheckReferencesVp9(pid + 10, 0, pid + 8);
1195 CheckReferencesVp9(pid + 11, 0, pid + 9, pid + 10);
1196 CheckReferencesVp9(pid + 12, 0, pid + 8);
1197 CheckReferencesVp9(pid + 13, 0, pid + 11, pid + 12);
1198 CheckReferencesVp9(pid + 14, 0, pid + 10, pid + 12);
1199 CheckReferencesVp9(pid + 15, 0, pid + 13, pid + 14);
1200 }
1201
TEST_F(TestRtpFrameReferenceFinder,Vp9GofTemporalLayersUpSwitchReordered_02120212)1202 TEST_F(TestRtpFrameReferenceFinder,
1203 Vp9GofTemporalLayersUpSwitchReordered_02120212) {
1204 uint16_t pid = Rand();
1205 uint16_t sn = Rand();
1206 GofInfoVP9 ss;
1207 ss.SetGofInfoVP9(kTemporalStructureMode4); // 02120212 pattern
1208
1209 InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 2, 0, false);
1210 InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
1211 InsertVp9Gof(sn + 4, sn + 4, false, pid + 4, 0, 0, 1, false);
1212 InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 1, 0, false);
1213 InsertVp9Gof(sn + 5, sn + 5, false, pid + 5, 0, 2, 1, false);
1214 InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 2, 0, false);
1215 InsertVp9Gof(sn + 7, sn + 7, false, pid + 7, 0, 2, 1, false);
1216 InsertVp9Gof(sn + 9, sn + 9, false, pid + 9, 0, 2, 2, false);
1217 InsertVp9Gof(sn + 6, sn + 6, false, pid + 6, 0, 1, 1, true);
1218 InsertVp9Gof(sn + 12, sn + 12, false, pid + 12, 0, 0, 3, false);
1219 InsertVp9Gof(sn + 10, sn + 10, false, pid + 10, 0, 1, 2, false);
1220 InsertVp9Gof(sn + 8, sn + 8, false, pid + 8, 0, 0, 2, true);
1221 InsertVp9Gof(sn + 11, sn + 11, false, pid + 11, 0, 2, 2, true);
1222 InsertVp9Gof(sn + 13, sn + 13, false, pid + 13, 0, 2, 3, false);
1223 InsertVp9Gof(sn + 15, sn + 15, false, pid + 15, 0, 2, 3, false);
1224 InsertVp9Gof(sn + 14, sn + 14, false, pid + 14, 0, 1, 3, false);
1225
1226 ASSERT_EQ(16UL, frames_from_callback_.size());
1227 CheckReferencesVp9(pid, 0);
1228 CheckReferencesVp9(pid + 1, 0, pid);
1229 CheckReferencesVp9(pid + 2, 0, pid);
1230 CheckReferencesVp9(pid + 3, 0, pid + 1, pid + 2);
1231 CheckReferencesVp9(pid + 4, 0, pid);
1232 CheckReferencesVp9(pid + 5, 0, pid + 3, pid + 4);
1233 CheckReferencesVp9(pid + 6, 0, pid + 2, pid + 4);
1234 CheckReferencesVp9(pid + 7, 0, pid + 6);
1235 CheckReferencesVp9(pid + 8, 0, pid + 4);
1236 CheckReferencesVp9(pid + 9, 0, pid + 8);
1237 CheckReferencesVp9(pid + 10, 0, pid + 8);
1238 CheckReferencesVp9(pid + 11, 0, pid + 9, pid + 10);
1239 CheckReferencesVp9(pid + 12, 0, pid + 8);
1240 CheckReferencesVp9(pid + 13, 0, pid + 11, pid + 12);
1241 CheckReferencesVp9(pid + 14, 0, pid + 10, pid + 12);
1242 CheckReferencesVp9(pid + 15, 0, pid + 13, pid + 14);
1243 }
1244
TEST_F(TestRtpFrameReferenceFinder,Vp9GofTemporalLayersReordered_01_0212)1245 TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayersReordered_01_0212) {
1246 uint16_t pid = Rand();
1247 uint16_t sn = Rand();
1248 GofInfoVP9 ss;
1249 ss.SetGofInfoVP9(kTemporalStructureMode2); // 01 pattern
1250
1251 InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 1, 0, false);
1252 InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
1253 InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 1, 1, false);
1254 InsertVp9Gof(sn + 6, sn + 6, false, pid + 6, 0, 1, 2, false);
1255 ss.SetGofInfoVP9(kTemporalStructureMode3); // 0212 pattern
1256 InsertVp9Gof(sn + 4, sn + 4, false, pid + 4, 0, 0, 2, false, true, &ss);
1257 InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 0, 1, false);
1258 InsertVp9Gof(sn + 5, sn + 5, false, pid + 5, 0, 2, 2, false);
1259 InsertVp9Gof(sn + 8, sn + 8, false, pid + 8, 0, 0, 3, false);
1260 InsertVp9Gof(sn + 10, sn + 10, false, pid + 10, 0, 1, 3, false);
1261 InsertVp9Gof(sn + 7, sn + 7, false, pid + 7, 0, 2, 2, false);
1262 InsertVp9Gof(sn + 11, sn + 11, false, pid + 11, 0, 2, 3, false);
1263 InsertVp9Gof(sn + 9, sn + 9, false, pid + 9, 0, 2, 3, false);
1264
1265 ASSERT_EQ(12UL, frames_from_callback_.size());
1266 CheckReferencesVp9(pid, 0);
1267 CheckReferencesVp9(pid + 1, 0, pid);
1268 CheckReferencesVp9(pid + 2, 0, pid);
1269 CheckReferencesVp9(pid + 3, 0, pid + 2);
1270 CheckReferencesVp9(pid + 4, 0, pid);
1271 CheckReferencesVp9(pid + 5, 0, pid + 4);
1272 CheckReferencesVp9(pid + 6, 0, pid + 4);
1273 CheckReferencesVp9(pid + 7, 0, pid + 6);
1274 CheckReferencesVp9(pid + 8, 0, pid + 4);
1275 CheckReferencesVp9(pid + 9, 0, pid + 8);
1276 CheckReferencesVp9(pid + 10, 0, pid + 8);
1277 CheckReferencesVp9(pid + 11, 0, pid + 10);
1278 }
1279
TEST_F(TestRtpFrameReferenceFinder,Vp9FlexibleModeOneFrame)1280 TEST_F(TestRtpFrameReferenceFinder, Vp9FlexibleModeOneFrame) {
1281 uint16_t pid = Rand();
1282 uint16_t sn = Rand();
1283
1284 InsertVp9Flex(sn, sn, true, pid, 0, 0, false);
1285
1286 ASSERT_EQ(1UL, frames_from_callback_.size());
1287 CheckReferencesVp9(pid, 0);
1288 }
1289
TEST_F(TestRtpFrameReferenceFinder,Vp9FlexibleModeTwoSpatialLayers)1290 TEST_F(TestRtpFrameReferenceFinder, Vp9FlexibleModeTwoSpatialLayers) {
1291 uint16_t pid = Rand();
1292 uint16_t sn = Rand();
1293
1294 InsertVp9Flex(sn, sn, true, pid, 0, 0, false);
1295 InsertVp9Flex(sn + 1, sn + 1, true, pid, 1, 0, true);
1296 InsertVp9Flex(sn + 2, sn + 2, false, pid + 1, 1, 0, false, {1});
1297 InsertVp9Flex(sn + 3, sn + 3, false, pid + 2, 0, 0, false, {2});
1298 InsertVp9Flex(sn + 4, sn + 4, false, pid + 2, 1, 0, false, {1});
1299 InsertVp9Flex(sn + 5, sn + 5, false, pid + 3, 1, 0, false, {1});
1300 InsertVp9Flex(sn + 6, sn + 6, false, pid + 4, 0, 0, false, {2});
1301 InsertVp9Flex(sn + 7, sn + 7, false, pid + 4, 1, 0, false, {1});
1302 InsertVp9Flex(sn + 8, sn + 8, false, pid + 5, 1, 0, false, {1});
1303 InsertVp9Flex(sn + 9, sn + 9, false, pid + 6, 0, 0, false, {2});
1304 InsertVp9Flex(sn + 10, sn + 10, false, pid + 6, 1, 0, false, {1});
1305 InsertVp9Flex(sn + 11, sn + 11, false, pid + 7, 1, 0, false, {1});
1306 InsertVp9Flex(sn + 12, sn + 12, false, pid + 8, 0, 0, false, {2});
1307 InsertVp9Flex(sn + 13, sn + 13, false, pid + 8, 1, 0, false, {1});
1308
1309 ASSERT_EQ(14UL, frames_from_callback_.size());
1310 CheckReferencesVp9(pid, 0);
1311 CheckReferencesVp9(pid, 1);
1312 CheckReferencesVp9(pid + 1, 1, pid);
1313 CheckReferencesVp9(pid + 2, 0, pid);
1314 CheckReferencesVp9(pid + 2, 1, pid + 1);
1315 CheckReferencesVp9(pid + 3, 1, pid + 2);
1316 CheckReferencesVp9(pid + 4, 0, pid + 2);
1317 CheckReferencesVp9(pid + 4, 1, pid + 3);
1318 CheckReferencesVp9(pid + 5, 1, pid + 4);
1319 CheckReferencesVp9(pid + 6, 0, pid + 4);
1320 CheckReferencesVp9(pid + 6, 1, pid + 5);
1321 CheckReferencesVp9(pid + 7, 1, pid + 6);
1322 CheckReferencesVp9(pid + 8, 0, pid + 6);
1323 CheckReferencesVp9(pid + 8, 1, pid + 7);
1324 }
1325
TEST_F(TestRtpFrameReferenceFinder,Vp9FlexibleModeTwoSpatialLayersReordered)1326 TEST_F(TestRtpFrameReferenceFinder, Vp9FlexibleModeTwoSpatialLayersReordered) {
1327 uint16_t pid = Rand();
1328 uint16_t sn = Rand();
1329
1330 InsertVp9Flex(sn + 1, sn + 1, true, pid, 1, 0, true);
1331 InsertVp9Flex(sn + 2, sn + 2, false, pid + 1, 1, 0, false, {1});
1332 InsertVp9Flex(sn, sn, true, pid, 0, 0, false);
1333 InsertVp9Flex(sn + 4, sn + 4, false, pid + 2, 1, 0, false, {1});
1334 InsertVp9Flex(sn + 5, sn + 5, false, pid + 3, 1, 0, false, {1});
1335 InsertVp9Flex(sn + 3, sn + 3, false, pid + 2, 0, 0, false, {2});
1336 InsertVp9Flex(sn + 7, sn + 7, false, pid + 4, 1, 0, false, {1});
1337 InsertVp9Flex(sn + 6, sn + 6, false, pid + 4, 0, 0, false, {2});
1338 InsertVp9Flex(sn + 8, sn + 8, false, pid + 5, 1, 0, false, {1});
1339 InsertVp9Flex(sn + 9, sn + 9, false, pid + 6, 0, 0, false, {2});
1340 InsertVp9Flex(sn + 11, sn + 11, false, pid + 7, 1, 0, false, {1});
1341 InsertVp9Flex(sn + 10, sn + 10, false, pid + 6, 1, 0, false, {1});
1342 InsertVp9Flex(sn + 13, sn + 13, false, pid + 8, 1, 0, false, {1});
1343 InsertVp9Flex(sn + 12, sn + 12, false, pid + 8, 0, 0, false, {2});
1344
1345 ASSERT_EQ(14UL, frames_from_callback_.size());
1346 CheckReferencesVp9(pid, 0);
1347 CheckReferencesVp9(pid, 1);
1348 CheckReferencesVp9(pid + 1, 1, pid);
1349 CheckReferencesVp9(pid + 2, 0, pid);
1350 CheckReferencesVp9(pid + 2, 1, pid + 1);
1351 CheckReferencesVp9(pid + 3, 1, pid + 2);
1352 CheckReferencesVp9(pid + 4, 0, pid + 2);
1353 CheckReferencesVp9(pid + 4, 1, pid + 3);
1354 CheckReferencesVp9(pid + 5, 1, pid + 4);
1355 CheckReferencesVp9(pid + 6, 0, pid + 4);
1356 CheckReferencesVp9(pid + 6, 1, pid + 5);
1357 CheckReferencesVp9(pid + 7, 1, pid + 6);
1358 CheckReferencesVp9(pid + 8, 0, pid + 6);
1359 CheckReferencesVp9(pid + 8, 1, pid + 7);
1360 }
1361
TEST_F(TestRtpFrameReferenceFinder,WrappingFlexReference)1362 TEST_F(TestRtpFrameReferenceFinder, WrappingFlexReference) {
1363 InsertVp9Flex(0, 0, false, 0, 0, 0, false, {1});
1364
1365 ASSERT_EQ(1UL, frames_from_callback_.size());
1366 const EncodedFrame& frame = *frames_from_callback_.begin()->second;
1367 ASSERT_EQ(frame.id.picture_id - frame.references[0], 1);
1368 }
1369
TEST_F(TestRtpFrameReferenceFinder,Vp9GofPidJump)1370 TEST_F(TestRtpFrameReferenceFinder, Vp9GofPidJump) {
1371 uint16_t pid = Rand();
1372 uint16_t sn = Rand();
1373 GofInfoVP9 ss;
1374 ss.SetGofInfoVP9(kTemporalStructureMode3);
1375
1376 InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
1377 InsertVp9Gof(sn + 1, sn + 1, false, pid + 1000, 0, 0, 1);
1378 }
1379
TEST_F(TestRtpFrameReferenceFinder,Vp9GofTl0Jump)1380 TEST_F(TestRtpFrameReferenceFinder, Vp9GofTl0Jump) {
1381 uint16_t pid = Rand();
1382 uint16_t sn = Rand();
1383 GofInfoVP9 ss;
1384 ss.SetGofInfoVP9(kTemporalStructureMode3);
1385
1386 InsertVp9Gof(sn, sn, true, pid, 0, 0, 125, true, false, &ss);
1387 InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 0, 0, false, true, &ss);
1388 }
1389
TEST_F(TestRtpFrameReferenceFinder,Vp9GofTidTooHigh)1390 TEST_F(TestRtpFrameReferenceFinder, Vp9GofTidTooHigh) {
1391 // Same as RtpFrameReferenceFinder::kMaxTemporalLayers.
1392 const int kMaxTemporalLayers = 5;
1393 uint16_t pid = Rand();
1394 uint16_t sn = Rand();
1395 GofInfoVP9 ss;
1396 ss.SetGofInfoVP9(kTemporalStructureMode2);
1397 ss.temporal_idx[1] = kMaxTemporalLayers;
1398
1399 InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
1400 InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 0, 1);
1401
1402 ASSERT_EQ(1UL, frames_from_callback_.size());
1403 CheckReferencesVp9(pid, 0);
1404 }
1405
TEST_F(TestRtpFrameReferenceFinder,Vp9GofZeroFrames)1406 TEST_F(TestRtpFrameReferenceFinder, Vp9GofZeroFrames) {
1407 uint16_t pid = Rand();
1408 uint16_t sn = Rand();
1409 GofInfoVP9 ss;
1410 ss.num_frames_in_gof = 0;
1411
1412 InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss);
1413 InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 0, 1);
1414
1415 ASSERT_EQ(2UL, frames_from_callback_.size());
1416 CheckReferencesVp9(pid, 0);
1417 CheckReferencesVp9(pid + 1, 0, pid);
1418 }
1419
TEST_F(TestRtpFrameReferenceFinder,H264KeyFrameReferences)1420 TEST_F(TestRtpFrameReferenceFinder, H264KeyFrameReferences) {
1421 uint16_t sn = Rand();
1422 InsertH264(sn, sn, true);
1423
1424 ASSERT_EQ(1UL, frames_from_callback_.size());
1425 CheckReferencesH264(sn);
1426 }
1427
TEST_F(TestRtpFrameReferenceFinder,H264SequenceNumberWrap)1428 TEST_F(TestRtpFrameReferenceFinder, H264SequenceNumberWrap) {
1429 uint16_t sn = 0xFFFF;
1430
1431 InsertH264(sn - 1, sn - 1, true);
1432 InsertH264(sn, sn, false);
1433 InsertH264(sn + 1, sn + 1, false);
1434 InsertH264(sn + 2, sn + 2, false);
1435
1436 ASSERT_EQ(4UL, frames_from_callback_.size());
1437 CheckReferencesH264(sn - 1);
1438 CheckReferencesH264(sn, sn - 1);
1439 CheckReferencesH264(sn + 1, sn);
1440 CheckReferencesH264(sn + 2, sn + 1);
1441 }
1442
TEST_F(TestRtpFrameReferenceFinder,H264Frames)1443 TEST_F(TestRtpFrameReferenceFinder, H264Frames) {
1444 uint16_t sn = Rand();
1445
1446 InsertH264(sn, sn, true);
1447 InsertH264(sn + 1, sn + 1, false);
1448 InsertH264(sn + 2, sn + 2, false);
1449 InsertH264(sn + 3, sn + 3, false);
1450
1451 ASSERT_EQ(4UL, frames_from_callback_.size());
1452 CheckReferencesH264(sn);
1453 CheckReferencesH264(sn + 1, sn);
1454 CheckReferencesH264(sn + 2, sn + 1);
1455 CheckReferencesH264(sn + 3, sn + 2);
1456 }
1457
TEST_F(TestRtpFrameReferenceFinder,H264Reordering)1458 TEST_F(TestRtpFrameReferenceFinder, H264Reordering) {
1459 uint16_t sn = Rand();
1460
1461 InsertH264(sn, sn, true);
1462 InsertH264(sn + 1, sn + 1, false);
1463 InsertH264(sn + 3, sn + 3, false);
1464 InsertH264(sn + 2, sn + 2, false);
1465 InsertH264(sn + 5, sn + 5, false);
1466 InsertH264(sn + 6, sn + 6, false);
1467 InsertH264(sn + 4, sn + 4, false);
1468
1469 ASSERT_EQ(7UL, frames_from_callback_.size());
1470 CheckReferencesH264(sn);
1471 CheckReferencesH264(sn + 1, sn);
1472 CheckReferencesH264(sn + 2, sn + 1);
1473 CheckReferencesH264(sn + 3, sn + 2);
1474 CheckReferencesH264(sn + 4, sn + 3);
1475 CheckReferencesH264(sn + 5, sn + 4);
1476 CheckReferencesH264(sn + 6, sn + 5);
1477 }
1478
TEST_F(TestRtpFrameReferenceFinder,H264SequenceNumberWrapMulti)1479 TEST_F(TestRtpFrameReferenceFinder, H264SequenceNumberWrapMulti) {
1480 uint16_t sn = 0xFFFF;
1481
1482 InsertH264(sn - 3, sn - 2, true);
1483 InsertH264(sn - 1, sn + 1, false);
1484 InsertH264(sn + 2, sn + 3, false);
1485 InsertH264(sn + 4, sn + 7, false);
1486
1487 ASSERT_EQ(4UL, frames_from_callback_.size());
1488 CheckReferencesH264(sn - 2);
1489 CheckReferencesH264(sn + 1, sn - 2);
1490 CheckReferencesH264(sn + 3, sn + 1);
1491 CheckReferencesH264(sn + 7, sn + 3);
1492 }
1493
1494 } // namespace video_coding
1495 } // namespace webrtc
1496