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