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