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