PacketBuffer is now ref counted.

Since all FrameObjects have a reference to its PacketBuffer and since
the PacketBuffer can be thrown away at any moment the PacketBuffer
has to be ref counted in order to avoid FrameObjects dereferencing a potentially
destroyed object.

BUG=webrtc:5514
R=danilchap@webrtc.org, mflodman@webrtc.org, stefan@webrtc.org

Review URL: https://codereview.webrtc.org/2199133004 .

Cr-Commit-Position: refs/heads/master@{#13725}
diff --git a/webrtc/modules/video_coding/frame_object.h b/webrtc/modules/video_coding/frame_object.h
index 5b299e6..a63ae99 100644
--- a/webrtc/modules/video_coding/frame_object.h
+++ b/webrtc/modules/video_coding/frame_object.h
@@ -75,7 +75,7 @@
   RTPVideoTypeHeader* GetCodecHeader() const;
 
  private:
-  PacketBuffer* packet_buffer_;
+  rtc::scoped_refptr<PacketBuffer> packet_buffer_;
   enum FrameType frame_type_;
   VideoCodecType codec_type_;
   uint16_t first_seq_num_;
diff --git a/webrtc/modules/video_coding/packet_buffer.cc b/webrtc/modules/video_coding/packet_buffer.cc
index df17350..0d36b9c 100644
--- a/webrtc/modules/video_coding/packet_buffer.cc
+++ b/webrtc/modules/video_coding/packet_buffer.cc
@@ -12,7 +12,9 @@
 
 #include <algorithm>
 #include <limits>
+#include <utility>
 
+#include "webrtc/base/atomicops.h"
 #include "webrtc/base/checks.h"
 #include "webrtc/base/logging.h"
 #include "webrtc/modules/video_coding/frame_object.h"
@@ -21,10 +23,19 @@
 namespace webrtc {
 namespace video_coding {
 
+rtc::scoped_refptr<PacketBuffer> PacketBuffer::Create(
+    Clock* clock,
+    size_t start_buffer_size,
+    size_t max_buffer_size,
+    OnReceivedFrameCallback* received_frame_callback) {
+  return rtc::scoped_refptr<PacketBuffer>(new PacketBuffer(
+      clock, start_buffer_size, max_buffer_size, received_frame_callback));
+}
+
 PacketBuffer::PacketBuffer(Clock* clock,
                            size_t start_buffer_size,
                            size_t max_buffer_size,
-                           OnCompleteFrameCallback* frame_callback)
+                           OnReceivedFrameCallback* received_frame_callback)
     : clock_(clock),
       size_(start_buffer_size),
       max_size_(max_buffer_size),
@@ -33,13 +44,15 @@
       first_packet_received_(false),
       data_buffer_(start_buffer_size),
       sequence_buffer_(start_buffer_size),
-      reference_finder_(frame_callback) {
+      received_frame_callback_(received_frame_callback) {
   RTC_DCHECK_LE(start_buffer_size, max_buffer_size);
   // Buffer size must always be a power of 2.
   RTC_DCHECK((start_buffer_size & (start_buffer_size - 1)) == 0);
   RTC_DCHECK((max_buffer_size & (max_buffer_size - 1)) == 0);
 }
 
+PacketBuffer::~PacketBuffer() {}
+
 bool PacketBuffer::InsertPacket(const VCMPacket& packet) {
   rtc::CritScope lock(&crit_);
   uint16_t seq_num = packet.seqNum;
@@ -69,12 +82,6 @@
   if (AheadOf(seq_num, last_seq_num_))
     last_seq_num_ = seq_num;
 
-  // If this is a padding or FEC packet, don't insert it.
-  if (packet.sizeBytes == 0) {
-    reference_finder_.PaddingReceived(packet.seqNum);
-    return true;
-  }
-
   sequence_buffer_[index].frame_begin = packet.isFirstPacket;
   sequence_buffer_[index].frame_end = packet.markerBit;
   sequence_buffer_[index].seq_num = packet.seqNum;
@@ -169,7 +176,8 @@
       std::unique_ptr<RtpFrameObject> frame(
           new RtpFrameObject(this, start_seq_num, seq_num, frame_size,
                              max_nack_count, clock_->TimeInMilliseconds()));
-      reference_finder_.ManageFrame(std::move(frame));
+
+      received_frame_callback_->OnReceivedFrame(std::move(frame));
     }
 
     index = (index + 1) % size_;
@@ -239,5 +247,17 @@
   first_packet_received_ = false;
 }
 
+int PacketBuffer::AddRef() const {
+  return rtc::AtomicOps::Increment(&ref_count_);
+}
+
+int PacketBuffer::Release() const {
+  int count = rtc::AtomicOps::Decrement(&ref_count_);
+  if (!count) {
+    delete this;
+  }
+  return count;
+}
+
 }  // namespace video_coding
 }  // namespace webrtc
diff --git a/webrtc/modules/video_coding/packet_buffer.h b/webrtc/modules/video_coding/packet_buffer.h
index ec187de..34a2d40 100644
--- a/webrtc/modules/video_coding/packet_buffer.h
+++ b/webrtc/modules/video_coding/packet_buffer.h
@@ -12,8 +12,10 @@
 #define WEBRTC_MODULES_VIDEO_CODING_PACKET_BUFFER_H_
 
 #include <vector>
+#include <memory>
 
 #include "webrtc/base/criticalsection.h"
+#include "webrtc/base/scoped_ref_ptr.h"
 #include "webrtc/base/thread_annotations.h"
 #include "webrtc/modules/include/module_common_types.h"
 #include "webrtc/modules/video_coding/packet.h"
@@ -29,23 +31,37 @@
 class FrameObject;
 class RtpFrameObject;
 
-class OnCompleteFrameCallback {
+// A received frame is a frame which has received all its packets.
+class OnReceivedFrameCallback {
  public:
-  virtual ~OnCompleteFrameCallback() {}
-  virtual void OnCompleteFrame(std::unique_ptr<FrameObject> frame) = 0;
+  virtual ~OnReceivedFrameCallback() {}
+  virtual void OnReceivedFrame(std::unique_ptr<RtpFrameObject> frame) = 0;
 };
 
 class PacketBuffer {
  public:
+  static rtc::scoped_refptr<PacketBuffer> Create(
+      Clock* clock,
+      size_t start_buffer_size,
+      size_t max_buffer_size,
+      OnReceivedFrameCallback* frame_callback);
+
+  virtual ~PacketBuffer();
+
+  // Made virtual for testing.
+  virtual bool InsertPacket(const VCMPacket& packet);
+  void ClearTo(uint16_t seq_num);
+  void Clear();
+
+  int AddRef() const;
+  int Release() const;
+
+ protected:
   // Both |start_buffer_size| and |max_buffer_size| must be a power of 2.
   PacketBuffer(Clock* clock,
                size_t start_buffer_size,
                size_t max_buffer_size,
-               OnCompleteFrameCallback* frame_callback);
-
-  bool InsertPacket(const VCMPacket& packet);
-  void ClearTo(uint16_t seq_num);
-  void Clear();
+               OnReceivedFrameCallback* frame_callback);
 
  private:
   friend RtpFrameObject;
@@ -85,13 +101,16 @@
   void FindFrames(uint16_t seq_num) EXCLUSIVE_LOCKS_REQUIRED(crit_);
 
   // Copy the bitstream for |frame| to |destination|.
-  bool GetBitstream(const RtpFrameObject& frame, uint8_t* destination);
+  // Virtual for testing.
+  virtual bool GetBitstream(const RtpFrameObject& frame, uint8_t* destination);
 
   // Get the packet with sequence number |seq_num|.
-  VCMPacket* GetPacket(uint16_t seq_num);
+  // Virtual for testing.
+  virtual VCMPacket* GetPacket(uint16_t seq_num);
 
   // Mark all slots used by |frame| as not used.
-  void ReturnFrame(RtpFrameObject* frame);
+  // Virtual for testing.
+  virtual void ReturnFrame(RtpFrameObject* frame);
 
   rtc::CriticalSection crit_;
 
@@ -115,9 +134,10 @@
   // and information needed to determine the continuity between packets.
   std::vector<ContinuityInfo> sequence_buffer_ GUARDED_BY(crit_);
 
-  // Frames that have received all their packets are handed off to the
-  // |reference_finder_| which finds the dependencies between the frames.
-  RtpFrameReferenceFinder reference_finder_;
+  // Called when a received frame is found.
+  OnReceivedFrameCallback* const received_frame_callback_;
+
+  mutable volatile int ref_count_ = 0;
 };
 
 }  // namespace video_coding
diff --git a/webrtc/modules/video_coding/rtp_frame_reference_finder.h b/webrtc/modules/video_coding/rtp_frame_reference_finder.h
index a12d6d8..a812303 100644
--- a/webrtc/modules/video_coding/rtp_frame_reference_finder.h
+++ b/webrtc/modules/video_coding/rtp_frame_reference_finder.h
@@ -26,8 +26,16 @@
 namespace webrtc {
 namespace video_coding {
 
+class FrameObject;
 class RtpFrameObject;
-class OnCompleteFrameCallback;
+
+// A complete frame is a frame which has received all its packets and all its
+// references are known.
+class OnCompleteFrameCallback {
+ public:
+  virtual ~OnCompleteFrameCallback() {}
+  virtual void OnCompleteFrame(std::unique_ptr<FrameObject> frame) = 0;
+};
 
 class RtpFrameReferenceFinder {
  public:
diff --git a/webrtc/modules/video_coding/rtp_frame_reference_finder_unittest.cc b/webrtc/modules/video_coding/rtp_frame_reference_finder_unittest.cc
new file mode 100644
index 0000000..967acfc
--- /dev/null
+++ b/webrtc/modules/video_coding/rtp_frame_reference_finder_unittest.cc
@@ -0,0 +1,1195 @@
+/*
+ *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <cstring>
+#include <limits>
+#include <map>
+#include <set>
+#include <utility>
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/base/random.h"
+#include "webrtc/base/refcount.h"
+#include "webrtc/modules/video_coding/frame_object.h"
+#include "webrtc/modules/video_coding/packet_buffer.h"
+#include "webrtc/system_wrappers/include/clock.h"
+
+namespace webrtc {
+namespace video_coding {
+
+class FakePacketBuffer : public PacketBuffer {
+ public:
+  FakePacketBuffer() : PacketBuffer(nullptr, 0, 0, nullptr) {}
+
+  VCMPacket* GetPacket(uint16_t seq_num) override {
+    auto packet_it = packets_.find(seq_num);
+    return packet_it == packets_.end() ? nullptr : &packet_it->second;
+  }
+
+  bool InsertPacket(const VCMPacket& packet) override {
+    packets_[packet.seqNum] = packet;
+    return true;
+  }
+
+  bool GetBitstream(const RtpFrameObject& frame,
+                    uint8_t* destination) override {
+    return true;
+  }
+
+  void ReturnFrame(RtpFrameObject* frame) override {
+    packets_.erase(frame->first_seq_num());
+  }
+
+ private:
+  std::map<uint16_t, VCMPacket> packets_;
+};
+
+class TestRtpFrameReferenceFinder : public ::testing::Test,
+                                    public OnCompleteFrameCallback {
+ protected:
+  TestRtpFrameReferenceFinder()
+      : rand_(0x8739211),
+        ref_packet_buffer_(new FakePacketBuffer()),
+        reference_finder_(new RtpFrameReferenceFinder(this)),
+        frames_from_callback_(FrameComp()) {}
+
+  uint16_t Rand() { return rand_.Rand(std::numeric_limits<uint16_t>::max()); }
+
+  void OnCompleteFrame(std::unique_ptr<FrameObject> frame) override {
+    uint16_t pid = frame->picture_id;
+    uint16_t sidx = frame->spatial_layer;
+    auto frame_it = frames_from_callback_.find(std::make_pair(pid, sidx));
+    if (frame_it != frames_from_callback_.end()) {
+      ADD_FAILURE() << "Already received frame with (pid:sidx): (" << pid << ":"
+                    << sidx << ")";
+      return;
+    }
+
+    frames_from_callback_.insert(
+        std::make_pair(std::make_pair(pid, sidx), std::move(frame)));
+  }
+
+  void InsertGeneric(uint16_t seq_num_start,
+                     uint16_t seq_num_end,
+                     bool keyframe) {
+    VCMPacket packet;
+    packet.codec = kVideoCodecGeneric;
+    packet.seqNum = seq_num_start;
+    packet.frameType = keyframe ? kVideoFrameKey : kVideoFrameDelta;
+
+    ref_packet_buffer_->InsertPacket(packet);
+    std::unique_ptr<RtpFrameObject> frame(new RtpFrameObject(
+        ref_packet_buffer_, seq_num_start, seq_num_end, 0, 0, 0));
+    reference_finder_->ManageFrame(std::move(frame));
+  }
+
+  void 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) {
+    VCMPacket packet;
+    packet.codec = kVideoCodecVP8;
+    packet.seqNum = seq_num_start;
+    packet.frameType = keyframe ? kVideoFrameKey : kVideoFrameDelta;
+    packet.video_header.codecHeader.VP8.pictureId = pid % (1 << 15);
+    packet.video_header.codecHeader.VP8.temporalIdx = tid;
+    packet.video_header.codecHeader.VP8.tl0PicIdx = tl0;
+    packet.video_header.codecHeader.VP8.layerSync = sync;
+
+    ref_packet_buffer_->InsertPacket(packet);
+    std::unique_ptr<RtpFrameObject> frame(new RtpFrameObject(
+        ref_packet_buffer_, seq_num_start, seq_num_end, 0, 0, 0));
+    reference_finder_->ManageFrame(std::move(frame));
+  }
+
+  void 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) {
+    VCMPacket packet;
+    packet.codec = kVideoCodecVP9;
+    packet.seqNum = seq_num_start;
+    packet.frameType = keyframe ? kVideoFrameKey : kVideoFrameDelta;
+    packet.video_header.codecHeader.VP9.flexible_mode = false;
+    packet.video_header.codecHeader.VP9.picture_id = pid % (1 << 15);
+    packet.video_header.codecHeader.VP9.temporal_idx = tid;
+    packet.video_header.codecHeader.VP9.spatial_idx = sid;
+    packet.video_header.codecHeader.VP9.tl0_pic_idx = tl0;
+    packet.video_header.codecHeader.VP9.temporal_up_switch = up_switch;
+    if (ss != nullptr) {
+      packet.video_header.codecHeader.VP9.ss_data_available = true;
+      packet.video_header.codecHeader.VP9.gof = *ss;
+    }
+
+    ref_packet_buffer_->InsertPacket(packet);
+    std::unique_ptr<RtpFrameObject> frame(new RtpFrameObject(
+        ref_packet_buffer_, seq_num_start, seq_num_end, 0, 0, 0));
+    reference_finder_->ManageFrame(std::move(frame));
+  }
+
+  void 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>()) {
+    VCMPacket packet;
+    packet.codec = kVideoCodecVP9;
+    packet.seqNum = seq_num_start;
+    packet.frameType = keyframe ? kVideoFrameKey : kVideoFrameDelta;
+    packet.video_header.codecHeader.VP9.inter_layer_predicted = inter;
+    packet.video_header.codecHeader.VP9.flexible_mode = true;
+    packet.video_header.codecHeader.VP9.picture_id = pid % (1 << 15);
+    packet.video_header.codecHeader.VP9.temporal_idx = tid;
+    packet.video_header.codecHeader.VP9.spatial_idx = sid;
+    packet.video_header.codecHeader.VP9.tl0_pic_idx = tl0;
+    packet.video_header.codecHeader.VP9.num_ref_pics = refs.size();
+    for (size_t i = 0; i < refs.size(); ++i)
+      packet.video_header.codecHeader.VP9.pid_diff[i] = refs[i];
+
+    ref_packet_buffer_->InsertPacket(packet);
+    std::unique_ptr<RtpFrameObject> frame(new RtpFrameObject(
+        ref_packet_buffer_, seq_num_start, seq_num_end, 0, 0, 0));
+    reference_finder_->ManageFrame(std::move(frame));
+  }
+
+  // Check if a frame with picture id |pid| and spatial index |sidx| has been
+  // delivered from the packet buffer, and if so, if it has the references
+  // specified by |refs|.
+  template <typename... T>
+  void CheckReferences(uint16_t pid, uint16_t sidx, T... refs) const {
+    auto frame_it = frames_from_callback_.find(std::make_pair(pid, sidx));
+    if (frame_it == frames_from_callback_.end()) {
+      ADD_FAILURE() << "Could not find frame with (pid:sidx): (" << pid << ":"
+                    << sidx << ")";
+      return;
+    }
+
+    std::set<uint16_t> actual_refs;
+    for (uint8_t r = 0; r < frame_it->second->num_references; ++r) {
+      actual_refs.insert(frame_it->second->references[r]);
+    }
+
+    std::set<uint16_t> expected_refs;
+    RefsToSet(&expected_refs, refs...);
+
+    ASSERT_EQ(expected_refs, actual_refs);
+  }
+
+  template <typename... T>
+  void CheckReferencesGeneric(uint16_t pid, T... refs) const {
+    CheckReferences(pid, 0, refs...);
+  }
+
+  template <typename... T>
+  void CheckReferencesVp8(uint16_t pid, T... refs) const {
+    CheckReferences(pid, 0, refs...);
+  }
+
+  template <typename... T>
+  void CheckReferencesVp9(uint16_t pid, uint8_t sidx, T... refs) const {
+    CheckReferences(pid, sidx, refs...);
+  }
+
+  template <typename... T>
+  void RefsToSet(std::set<uint16_t>* m, uint16_t ref, T... refs) const {
+    m->insert(ref);
+    RefsToSet(m, refs...);
+  }
+
+  void RefsToSet(std::set<uint16_t>* m) const {}
+
+  Random rand_;
+  rtc::scoped_refptr<FakePacketBuffer> ref_packet_buffer_;
+  std::unique_ptr<RtpFrameReferenceFinder> reference_finder_;
+  struct FrameComp {
+    bool operator()(const std::pair<uint16_t, uint8_t> f1,
+                    const std::pair<uint16_t, uint8_t> f2) const {
+      if (f1.first == f2.first)
+        return f1.second < f2.second;
+      return f1.first < f2.first;
+    }
+  };
+  std::map<std::pair<uint16_t, uint8_t>,
+           std::unique_ptr<FrameObject>,
+           FrameComp>
+      frames_from_callback_;
+};
+
+TEST_F(TestRtpFrameReferenceFinder, PaddingPackets) {
+  uint16_t sn = Rand();
+
+  InsertGeneric(sn, sn, true);
+  InsertGeneric(sn + 2, sn + 2, false);
+  EXPECT_EQ(1UL, frames_from_callback_.size());
+  reference_finder_->PaddingReceived(sn + 1);
+  EXPECT_EQ(2UL, frames_from_callback_.size());
+}
+
+TEST_F(TestRtpFrameReferenceFinder, PaddingPacketsReordered) {
+  uint16_t sn = Rand();
+
+  InsertGeneric(sn, sn, true);
+  reference_finder_->PaddingReceived(sn + 1);
+  reference_finder_->PaddingReceived(sn + 4);
+  InsertGeneric(sn + 2, sn + 3, false);
+
+  EXPECT_EQ(2UL, frames_from_callback_.size());
+  CheckReferencesGeneric(sn);
+  CheckReferencesGeneric(sn + 3, sn);
+}
+
+TEST_F(TestRtpFrameReferenceFinder, PaddingPacketsReorderedMultipleKeyframes) {
+  uint16_t sn = Rand();
+
+  InsertGeneric(sn, sn, true);
+  reference_finder_->PaddingReceived(sn + 1);
+  reference_finder_->PaddingReceived(sn + 4);
+  InsertGeneric(sn + 2, sn + 3, false);
+  InsertGeneric(sn + 5, sn + 5, true);
+  reference_finder_->PaddingReceived(sn + 6);
+  reference_finder_->PaddingReceived(sn + 9);
+  InsertGeneric(sn + 7, sn + 8, false);
+
+  EXPECT_EQ(4UL, frames_from_callback_.size());
+}
+
+TEST_F(TestRtpFrameReferenceFinder, Vp8NoPictureId) {
+  uint16_t sn = Rand();
+
+  InsertVp8(sn, sn + 2, true);
+  ASSERT_EQ(1UL, frames_from_callback_.size());
+
+  InsertVp8(sn + 3, sn + 4, false);
+  ASSERT_EQ(2UL, frames_from_callback_.size());
+
+  InsertVp8(sn + 5, sn + 8, false);
+  ASSERT_EQ(3UL, frames_from_callback_.size());
+
+  InsertVp8(sn + 9, sn + 9, false);
+  ASSERT_EQ(4UL, frames_from_callback_.size());
+
+  InsertVp8(sn + 10, sn + 11, false);
+  ASSERT_EQ(5UL, frames_from_callback_.size());
+
+  InsertVp8(sn + 12, sn + 12, true);
+  ASSERT_EQ(6UL, frames_from_callback_.size());
+
+  InsertVp8(sn + 13, sn + 17, false);
+  ASSERT_EQ(7UL, frames_from_callback_.size());
+
+  InsertVp8(sn + 18, sn + 18, false);
+  ASSERT_EQ(8UL, frames_from_callback_.size());
+
+  InsertVp8(sn + 19, sn + 20, false);
+  ASSERT_EQ(9UL, frames_from_callback_.size());
+
+  InsertVp8(sn + 21, sn + 21, false);
+
+  ASSERT_EQ(10UL, frames_from_callback_.size());
+  CheckReferencesVp8(sn + 2);
+  CheckReferencesVp8(sn + 4, sn + 2);
+  CheckReferencesVp8(sn + 8, sn + 4);
+  CheckReferencesVp8(sn + 9, sn + 8);
+  CheckReferencesVp8(sn + 11, sn + 9);
+  CheckReferencesVp8(sn + 12);
+  CheckReferencesVp8(sn + 17, sn + 12);
+  CheckReferencesVp8(sn + 18, sn + 17);
+  CheckReferencesVp8(sn + 20, sn + 18);
+  CheckReferencesVp8(sn + 21, sn + 20);
+}
+
+TEST_F(TestRtpFrameReferenceFinder, Vp8NoPictureIdReordered) {
+  uint16_t sn = 0xfffa;
+
+  InsertVp8(sn, sn + 2, true);
+  InsertVp8(sn + 3, sn + 4, false);
+  InsertVp8(sn + 5, sn + 8, false);
+  InsertVp8(sn + 9, sn + 9, false);
+  InsertVp8(sn + 10, sn + 11, false);
+  InsertVp8(sn + 12, sn + 12, true);
+  InsertVp8(sn + 13, sn + 17, false);
+  InsertVp8(sn + 18, sn + 18, false);
+  InsertVp8(sn + 19, sn + 20, false);
+  InsertVp8(sn + 21, sn + 21, false);
+
+  ASSERT_EQ(10UL, frames_from_callback_.size());
+  CheckReferencesVp8(sn + 2);
+  CheckReferencesVp8(sn + 4, sn + 2);
+  CheckReferencesVp8(sn + 8, sn + 4);
+  CheckReferencesVp8(sn + 9, sn + 8);
+  CheckReferencesVp8(sn + 11, sn + 9);
+  CheckReferencesVp8(sn + 12);
+  CheckReferencesVp8(sn + 17, sn + 12);
+  CheckReferencesVp8(sn + 18, sn + 17);
+  CheckReferencesVp8(sn + 20, sn + 18);
+  CheckReferencesVp8(sn + 21, sn + 20);
+}
+
+TEST_F(TestRtpFrameReferenceFinder, Vp8KeyFrameReferences) {
+  uint16_t sn = Rand();
+  InsertVp8(sn, sn, true);
+
+  ASSERT_EQ(1UL, frames_from_callback_.size());
+  CheckReferencesVp8(sn);
+}
+
+// Test with 1 temporal layer.
+TEST_F(TestRtpFrameReferenceFinder, Vp8TemporalLayers_0) {
+  uint16_t pid = Rand();
+  uint16_t sn = Rand();
+
+  InsertVp8(sn, sn, true, pid, 0, 1);
+  InsertVp8(sn + 1, sn + 1, false, pid + 1, 0, 2);
+  InsertVp8(sn + 2, sn + 2, false, pid + 2, 0, 3);
+  InsertVp8(sn + 3, sn + 3, false, pid + 3, 0, 4);
+
+  ASSERT_EQ(4UL, frames_from_callback_.size());
+  CheckReferencesVp8(pid);
+  CheckReferencesVp8(pid + 1, pid);
+  CheckReferencesVp8(pid + 2, pid + 1);
+  CheckReferencesVp8(pid + 3, pid + 2);
+}
+
+// Test with 1 temporal layer.
+TEST_F(TestRtpFrameReferenceFinder, Vp8TemporalLayersReordering_0) {
+  uint16_t pid = Rand();
+  uint16_t sn = Rand();
+
+  InsertVp8(sn, sn, true, pid, 0, 1);
+  InsertVp8(sn + 1, sn + 1, false, pid + 1, 0, 2);
+  InsertVp8(sn + 3, sn + 3, false, pid + 3, 0, 4);
+  InsertVp8(sn + 2, sn + 2, false, pid + 2, 0, 3);
+  InsertVp8(sn + 5, sn + 5, false, pid + 5, 0, 6);
+  InsertVp8(sn + 6, sn + 6, false, pid + 6, 0, 7);
+  InsertVp8(sn + 4, sn + 4, false, pid + 4, 0, 5);
+
+  ASSERT_EQ(7UL, frames_from_callback_.size());
+  CheckReferencesVp8(pid);
+  CheckReferencesVp8(pid + 1, pid);
+  CheckReferencesVp8(pid + 2, pid + 1);
+  CheckReferencesVp8(pid + 3, pid + 2);
+  CheckReferencesVp8(pid + 4, pid + 3);
+  CheckReferencesVp8(pid + 5, pid + 4);
+  CheckReferencesVp8(pid + 6, pid + 5);
+}
+
+// Test with 2 temporal layers in a 01 pattern.
+TEST_F(TestRtpFrameReferenceFinder, Vp8TemporalLayers_01) {
+  uint16_t pid = Rand();
+  uint16_t sn = Rand();
+
+  InsertVp8(sn, sn, true, pid, 0, 255);
+  InsertVp8(sn + 1, sn + 1, false, pid + 1, 1, 255, true);
+  InsertVp8(sn + 2, sn + 2, false, pid + 2, 0, 0);
+  InsertVp8(sn + 3, sn + 3, false, pid + 3, 1, 0);
+
+  ASSERT_EQ(4UL, frames_from_callback_.size());
+  CheckReferencesVp8(pid);
+  CheckReferencesVp8(pid + 1, pid);
+  CheckReferencesVp8(pid + 2, pid);
+  CheckReferencesVp8(pid + 3, pid + 1, pid + 2);
+}
+
+// Test with 2 temporal layers in a 01 pattern.
+TEST_F(TestRtpFrameReferenceFinder, Vp8TemporalLayersReordering_01) {
+  uint16_t pid = Rand();
+  uint16_t sn = Rand();
+
+  InsertVp8(sn + 1, sn + 1, false, pid + 1, 1, 255, true);
+  InsertVp8(sn, sn, true, pid, 0, 255);
+  InsertVp8(sn + 3, sn + 3, false, pid + 3, 1, 0);
+  InsertVp8(sn + 5, sn + 5, false, pid + 5, 1, 1);
+  InsertVp8(sn + 2, sn + 2, false, pid + 2, 0, 0);
+  InsertVp8(sn + 4, sn + 4, false, pid + 4, 0, 1);
+  InsertVp8(sn + 6, sn + 6, false, pid + 6, 0, 2);
+  InsertVp8(sn + 7, sn + 7, false, pid + 7, 1, 2);
+
+  ASSERT_EQ(8UL, frames_from_callback_.size());
+  CheckReferencesVp8(pid);
+  CheckReferencesVp8(pid + 1, pid);
+  CheckReferencesVp8(pid + 2, pid);
+  CheckReferencesVp8(pid + 3, pid + 1, pid + 2);
+  CheckReferencesVp8(pid + 4, pid + 2);
+  CheckReferencesVp8(pid + 5, pid + 3, pid + 4);
+  CheckReferencesVp8(pid + 6, pid + 4);
+  CheckReferencesVp8(pid + 7, pid + 5, pid + 6);
+}
+
+// Test with 3 temporal layers in a 0212 pattern.
+TEST_F(TestRtpFrameReferenceFinder, Vp8TemporalLayers_0212) {
+  uint16_t pid = Rand();
+  uint16_t sn = Rand();
+
+  InsertVp8(sn, sn, true, pid, 0, 55);
+  InsertVp8(sn + 1, sn + 1, false, pid + 1, 2, 55, true);
+  InsertVp8(sn + 2, sn + 2, false, pid + 2, 1, 55, true);
+  InsertVp8(sn + 3, sn + 3, false, pid + 3, 2, 55);
+  InsertVp8(sn + 4, sn + 4, false, pid + 4, 0, 56);
+  InsertVp8(sn + 5, sn + 5, false, pid + 5, 2, 56);
+  InsertVp8(sn + 6, sn + 6, false, pid + 6, 1, 56);
+  InsertVp8(sn + 7, sn + 7, false, pid + 7, 2, 56);
+  InsertVp8(sn + 8, sn + 8, false, pid + 8, 0, 57);
+  InsertVp8(sn + 9, sn + 9, false, pid + 9, 2, 57, true);
+  InsertVp8(sn + 10, sn + 10, false, pid + 10, 1, 57, true);
+  InsertVp8(sn + 11, sn + 11, false, pid + 11, 2, 57);
+
+  ASSERT_EQ(12UL, frames_from_callback_.size());
+  CheckReferencesVp8(pid);
+  CheckReferencesVp8(pid + 1, pid);
+  CheckReferencesVp8(pid + 2, pid);
+  CheckReferencesVp8(pid + 3, pid, pid + 1, pid + 2);
+  CheckReferencesVp8(pid + 4, pid);
+  CheckReferencesVp8(pid + 5, pid + 2, pid + 3, pid + 4);
+  CheckReferencesVp8(pid + 6, pid + 2, pid + 4);
+  CheckReferencesVp8(pid + 7, pid + 4, pid + 5, pid + 6);
+  CheckReferencesVp8(pid + 8, pid + 4);
+  CheckReferencesVp8(pid + 9, pid + 8);
+  CheckReferencesVp8(pid + 10, pid + 8);
+  CheckReferencesVp8(pid + 11, pid + 8, pid + 9, pid + 10);
+}
+
+// Test with 3 temporal layers in a 0212 pattern.
+TEST_F(TestRtpFrameReferenceFinder, Vp8TemporalLayersMissingFrame_0212) {
+  uint16_t pid = Rand();
+  uint16_t sn = Rand();
+
+  InsertVp8(sn, sn, true, pid, 0, 55, false);
+  InsertVp8(sn + 2, sn + 2, false, pid + 2, 1, 55, true);
+  InsertVp8(sn + 3, sn + 3, false, pid + 3, 2, 55, false);
+
+  ASSERT_EQ(2UL, frames_from_callback_.size());
+  CheckReferencesVp8(pid);
+  CheckReferencesVp8(pid + 2, pid);
+}
+
+// Test with 3 temporal layers in a 0212 pattern.
+TEST_F(TestRtpFrameReferenceFinder, Vp8TemporalLayersReordering_0212) {
+  uint16_t pid = 126;
+  uint16_t sn = Rand();
+
+  InsertVp8(sn + 1, sn + 1, false, pid + 1, 2, 55, true);
+  InsertVp8(sn, sn, true, pid, 0, 55, false);
+  InsertVp8(sn + 2, sn + 2, false, pid + 2, 1, 55, true);
+  InsertVp8(sn + 4, sn + 4, false, pid + 4, 0, 56, false);
+  InsertVp8(sn + 5, sn + 5, false, pid + 5, 2, 56, false);
+  InsertVp8(sn + 3, sn + 3, false, pid + 3, 2, 55, false);
+  InsertVp8(sn + 7, sn + 7, false, pid + 7, 2, 56, false);
+  InsertVp8(sn + 9, sn + 9, false, pid + 9, 2, 57, true);
+  InsertVp8(sn + 6, sn + 6, false, pid + 6, 1, 56, false);
+  InsertVp8(sn + 8, sn + 8, false, pid + 8, 0, 57, false);
+  InsertVp8(sn + 11, sn + 11, false, pid + 11, 2, 57, false);
+  InsertVp8(sn + 10, sn + 10, false, pid + 10, 1, 57, true);
+
+  ASSERT_EQ(12UL, frames_from_callback_.size());
+  CheckReferencesVp8(pid);
+  CheckReferencesVp8(pid + 1, pid);
+  CheckReferencesVp8(pid + 2, pid);
+  CheckReferencesVp8(pid + 3, pid, pid + 1, pid + 2);
+  CheckReferencesVp8(pid + 4, pid);
+  CheckReferencesVp8(pid + 5, pid + 2, pid + 3, pid + 4);
+  CheckReferencesVp8(pid + 6, pid + 2, pid + 4);
+  CheckReferencesVp8(pid + 7, pid + 4, pid + 5, pid + 6);
+  CheckReferencesVp8(pid + 8, pid + 4);
+  CheckReferencesVp8(pid + 9, pid + 8);
+  CheckReferencesVp8(pid + 10, pid + 8);
+  CheckReferencesVp8(pid + 11, pid + 8, pid + 9, pid + 10);
+}
+
+TEST_F(TestRtpFrameReferenceFinder, Vp8InsertManyFrames_0212) {
+  uint16_t pid = Rand();
+  uint16_t sn = Rand();
+
+  const int keyframes_to_insert = 50;
+  const int frames_per_keyframe = 120;  // Should be a multiple of 4.
+  uint8_t tl0 = 128;
+
+  for (int k = 0; k < keyframes_to_insert; ++k) {
+    InsertVp8(sn, sn, true, pid, 0, tl0, false);
+    InsertVp8(sn + 1, sn + 1, false, pid + 1, 2, tl0, true);
+    InsertVp8(sn + 2, sn + 2, false, pid + 2, 1, tl0, true);
+    InsertVp8(sn + 3, sn + 3, false, pid + 3, 2, tl0, false);
+    CheckReferencesVp8(pid);
+    CheckReferencesVp8(pid + 1, pid);
+    CheckReferencesVp8(pid + 2, pid);
+    CheckReferencesVp8(pid + 3, pid, pid + 1, pid + 2);
+    frames_from_callback_.clear();
+    ++tl0;
+
+    for (int f = 4; f < frames_per_keyframe; f += 4) {
+      uint16_t sf = sn + f;
+      uint16_t pidf = pid + f;
+
+      InsertVp8(sf, sf, false, pidf, 0, tl0, false);
+      InsertVp8(sf + 1, sf + 1, false, pidf + 1, 2, tl0, false);
+      InsertVp8(sf + 2, sf + 2, false, pidf + 2, 1, tl0, false);
+      InsertVp8(sf + 3, sf + 3, false, pidf + 3, 2, tl0, false);
+      CheckReferencesVp8(pidf, pidf - 4);
+      CheckReferencesVp8(pidf + 1, pidf, pidf - 1, pidf - 2);
+      CheckReferencesVp8(pidf + 2, pidf, pidf - 2);
+      CheckReferencesVp8(pidf + 3, pidf, pidf + 1, pidf + 2);
+      frames_from_callback_.clear();
+      ++tl0;
+    }
+
+    pid += frames_per_keyframe;
+    sn += frames_per_keyframe;
+  }
+}
+
+TEST_F(TestRtpFrameReferenceFinder, Vp8LayerSync) {
+  uint16_t pid = Rand();
+  uint16_t sn = Rand();
+
+  InsertVp8(sn, sn, true, pid, 0, 0, false);
+  InsertVp8(sn + 1, sn + 1, false, pid + 1, 1, 0, true);
+  InsertVp8(sn + 2, sn + 2, false, pid + 2, 0, 1, false);
+  ASSERT_EQ(3UL, frames_from_callback_.size());
+
+  InsertVp8(sn + 4, sn + 4, false, pid + 4, 0, 2, false);
+  InsertVp8(sn + 5, sn + 5, false, pid + 5, 1, 2, true);
+  InsertVp8(sn + 6, sn + 6, false, pid + 6, 0, 3, false);
+  InsertVp8(sn + 7, sn + 7, false, pid + 7, 1, 3, false);
+
+  ASSERT_EQ(7UL, frames_from_callback_.size());
+  CheckReferencesVp8(pid);
+  CheckReferencesVp8(pid + 1, pid);
+  CheckReferencesVp8(pid + 2, pid);
+  CheckReferencesVp8(pid + 4, pid + 2);
+  CheckReferencesVp8(pid + 5, pid + 4);
+  CheckReferencesVp8(pid + 6, pid + 4);
+  CheckReferencesVp8(pid + 7, pid + 6, pid + 5);
+}
+
+TEST_F(TestRtpFrameReferenceFinder, Vp9GofInsertOneFrame) {
+  uint16_t pid = Rand();
+  uint16_t sn = Rand();
+  GofInfoVP9 ss;
+  ss.SetGofInfoVP9(kTemporalStructureMode1);
+
+  InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, &ss);
+
+  CheckReferencesVp9(pid, 0);
+}
+
+TEST_F(TestRtpFrameReferenceFinder, Vp9NoPictureIdReordered) {
+  uint16_t sn = 0xfffa;
+
+  InsertVp9Gof(sn, sn + 2, true);
+  InsertVp9Gof(sn + 3, sn + 4, false);
+  InsertVp9Gof(sn + 9, sn + 9, false);
+  InsertVp9Gof(sn + 5, sn + 8, false);
+  InsertVp9Gof(sn + 12, sn + 12, true);
+  InsertVp9Gof(sn + 10, sn + 11, false);
+  InsertVp9Gof(sn + 13, sn + 17, false);
+  InsertVp9Gof(sn + 19, sn + 20, false);
+  InsertVp9Gof(sn + 21, sn + 21, false);
+  InsertVp9Gof(sn + 18, sn + 18, false);
+
+  ASSERT_EQ(10UL, frames_from_callback_.size());
+  CheckReferencesVp9(sn + 2, 0);
+  CheckReferencesVp9(sn + 4, 0, sn + 2);
+  CheckReferencesVp9(sn + 8, 0, sn + 4);
+  CheckReferencesVp9(sn + 9, 0, sn + 8);
+  CheckReferencesVp9(sn + 11, 0, sn + 9);
+  CheckReferencesVp9(sn + 12, 0);
+  CheckReferencesVp9(sn + 17, 0, sn + 12);
+  CheckReferencesVp9(sn + 18, 0, sn + 17);
+  CheckReferencesVp9(sn + 20, 0, sn + 18);
+  CheckReferencesVp9(sn + 21, 0, sn + 20);
+}
+
+TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayers_0) {
+  uint16_t pid = Rand();
+  uint16_t sn = Rand();
+  GofInfoVP9 ss;
+  ss.SetGofInfoVP9(kTemporalStructureMode1);  // Only 1 spatial layer.
+
+  InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, &ss);
+  InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 0, 1, false);
+  InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 0, 2, false);
+  InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 0, 3, false);
+  InsertVp9Gof(sn + 4, sn + 4, false, pid + 4, 0, 0, 4, false);
+  InsertVp9Gof(sn + 5, sn + 5, false, pid + 5, 0, 0, 5, false);
+  InsertVp9Gof(sn + 6, sn + 6, false, pid + 6, 0, 0, 6, false);
+  InsertVp9Gof(sn + 7, sn + 7, false, pid + 7, 0, 0, 7, false);
+  InsertVp9Gof(sn + 8, sn + 8, false, pid + 8, 0, 0, 8, false);
+  InsertVp9Gof(sn + 9, sn + 9, false, pid + 9, 0, 0, 9, false);
+  InsertVp9Gof(sn + 10, sn + 10, false, pid + 10, 0, 0, 10, false);
+  InsertVp9Gof(sn + 11, sn + 11, false, pid + 11, 0, 0, 11, false);
+  InsertVp9Gof(sn + 12, sn + 12, false, pid + 12, 0, 0, 12, false);
+  InsertVp9Gof(sn + 13, sn + 13, false, pid + 13, 0, 0, 13, false);
+  InsertVp9Gof(sn + 14, sn + 14, false, pid + 14, 0, 0, 14, false);
+  InsertVp9Gof(sn + 15, sn + 15, false, pid + 15, 0, 0, 15, false);
+  InsertVp9Gof(sn + 16, sn + 16, false, pid + 16, 0, 0, 16, false);
+  InsertVp9Gof(sn + 17, sn + 17, false, pid + 17, 0, 0, 17, false);
+  InsertVp9Gof(sn + 18, sn + 18, false, pid + 18, 0, 0, 18, false);
+  InsertVp9Gof(sn + 19, sn + 19, false, pid + 19, 0, 0, 19, false);
+
+  ASSERT_EQ(20UL, frames_from_callback_.size());
+  CheckReferencesVp9(pid, 0);
+  CheckReferencesVp9(pid + 1, 0, pid);
+  CheckReferencesVp9(pid + 2, 0, pid + 1);
+  CheckReferencesVp9(pid + 3, 0, pid + 2);
+  CheckReferencesVp9(pid + 4, 0, pid + 3);
+  CheckReferencesVp9(pid + 5, 0, pid + 4);
+  CheckReferencesVp9(pid + 6, 0, pid + 5);
+  CheckReferencesVp9(pid + 7, 0, pid + 6);
+  CheckReferencesVp9(pid + 8, 0, pid + 7);
+  CheckReferencesVp9(pid + 9, 0, pid + 8);
+  CheckReferencesVp9(pid + 10, 0, pid + 9);
+  CheckReferencesVp9(pid + 11, 0, pid + 10);
+  CheckReferencesVp9(pid + 12, 0, pid + 11);
+  CheckReferencesVp9(pid + 13, 0, pid + 12);
+  CheckReferencesVp9(pid + 14, 0, pid + 13);
+  CheckReferencesVp9(pid + 15, 0, pid + 14);
+  CheckReferencesVp9(pid + 16, 0, pid + 15);
+  CheckReferencesVp9(pid + 17, 0, pid + 16);
+  CheckReferencesVp9(pid + 18, 0, pid + 17);
+  CheckReferencesVp9(pid + 19, 0, pid + 18);
+}
+
+TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayersReordered_0) {
+  uint16_t pid = Rand();
+  uint16_t sn = Rand();
+  GofInfoVP9 ss;
+  ss.SetGofInfoVP9(kTemporalStructureMode1);  // Only 1 spatial layer.
+
+  InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 0, 2, false);
+  InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 0, 1, false);
+  InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, &ss);
+  InsertVp9Gof(sn + 4, sn + 4, false, pid + 4, 0, 0, 4, false);
+  InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 0, 3, false);
+  InsertVp9Gof(sn + 5, sn + 5, false, pid + 5, 0, 0, 5, false);
+  InsertVp9Gof(sn + 7, sn + 7, false, pid + 7, 0, 0, 7, false);
+  InsertVp9Gof(sn + 6, sn + 6, false, pid + 6, 0, 0, 6, false);
+  InsertVp9Gof(sn + 8, sn + 8, false, pid + 8, 0, 0, 8, false);
+  InsertVp9Gof(sn + 10, sn + 10, false, pid + 10, 0, 0, 10, false);
+  InsertVp9Gof(sn + 13, sn + 13, false, pid + 13, 0, 0, 13, false);
+  InsertVp9Gof(sn + 11, sn + 11, false, pid + 11, 0, 0, 11, false);
+  InsertVp9Gof(sn + 9, sn + 9, false, pid + 9, 0, 0, 9, false);
+  InsertVp9Gof(sn + 16, sn + 16, false, pid + 16, 0, 0, 16, false);
+  InsertVp9Gof(sn + 14, sn + 14, false, pid + 14, 0, 0, 14, false);
+  InsertVp9Gof(sn + 15, sn + 15, false, pid + 15, 0, 0, 15, false);
+  InsertVp9Gof(sn + 12, sn + 12, false, pid + 12, 0, 0, 12, false);
+  InsertVp9Gof(sn + 17, sn + 17, false, pid + 17, 0, 0, 17, false);
+  InsertVp9Gof(sn + 19, sn + 19, false, pid + 19, 0, 0, 19, false);
+  InsertVp9Gof(sn + 18, sn + 18, false, pid + 18, 0, 0, 18, false);
+
+  ASSERT_EQ(20UL, frames_from_callback_.size());
+  CheckReferencesVp9(pid, 0);
+  CheckReferencesVp9(pid + 1, 0, pid);
+  CheckReferencesVp9(pid + 2, 0, pid + 1);
+  CheckReferencesVp9(pid + 3, 0, pid + 2);
+  CheckReferencesVp9(pid + 4, 0, pid + 3);
+  CheckReferencesVp9(pid + 5, 0, pid + 4);
+  CheckReferencesVp9(pid + 6, 0, pid + 5);
+  CheckReferencesVp9(pid + 7, 0, pid + 6);
+  CheckReferencesVp9(pid + 8, 0, pid + 7);
+  CheckReferencesVp9(pid + 9, 0, pid + 8);
+  CheckReferencesVp9(pid + 10, 0, pid + 9);
+  CheckReferencesVp9(pid + 11, 0, pid + 10);
+  CheckReferencesVp9(pid + 12, 0, pid + 11);
+  CheckReferencesVp9(pid + 13, 0, pid + 12);
+  CheckReferencesVp9(pid + 14, 0, pid + 13);
+  CheckReferencesVp9(pid + 15, 0, pid + 14);
+  CheckReferencesVp9(pid + 16, 0, pid + 15);
+  CheckReferencesVp9(pid + 17, 0, pid + 16);
+  CheckReferencesVp9(pid + 18, 0, pid + 17);
+  CheckReferencesVp9(pid + 19, 0, pid + 18);
+}
+
+TEST_F(TestRtpFrameReferenceFinder, Vp9GofSkipFramesTemporalLayers_01) {
+  uint16_t pid = Rand();
+  uint16_t sn = Rand();
+  GofInfoVP9 ss;
+  ss.SetGofInfoVP9(kTemporalStructureMode2);  // 0101 pattern
+
+  InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, &ss);
+  InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 1, 0, false);
+  // Skip GOF with tl0 1
+  InsertVp9Gof(sn + 4, sn + 4, true, pid + 4, 0, 0, 2, false, &ss);
+  InsertVp9Gof(sn + 5, sn + 5, false, pid + 5, 0, 1, 2, false);
+  // Skip GOF with tl0 3
+  // Skip GOF with tl0 4
+  InsertVp9Gof(sn + 10, sn + 10, false, pid + 10, 0, 0, 5, false, &ss);
+  InsertVp9Gof(sn + 11, sn + 11, false, pid + 11, 0, 1, 5, false);
+
+  ASSERT_EQ(6UL, frames_from_callback_.size());
+  CheckReferencesVp9(pid, 0);
+  CheckReferencesVp9(pid + 1, 0, pid);
+  CheckReferencesVp9(pid + 4, 0);
+  CheckReferencesVp9(pid + 5, 0, pid + 4);
+  CheckReferencesVp9(pid + 10, 0, pid + 8);
+  CheckReferencesVp9(pid + 11, 0, pid + 10);
+}
+
+TEST_F(TestRtpFrameReferenceFinder, Vp9GofSkipFramesTemporalLayers_0212) {
+  uint16_t pid = Rand();
+  uint16_t sn = Rand();
+  GofInfoVP9 ss;
+  ss.SetGofInfoVP9(kTemporalStructureMode3);  // 02120212 pattern
+
+  InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, &ss);
+  InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 2, 0, false);
+  InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 1, 0, false);
+  InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 2, 0, false);
+
+  ASSERT_EQ(4UL, frames_from_callback_.size());
+  CheckReferencesVp9(pid, 0);
+  CheckReferencesVp9(pid + 1, 0, pid);
+  CheckReferencesVp9(pid + 2, 0, pid);
+  CheckReferencesVp9(pid + 3, 0, pid + 1, pid + 2);
+
+  // Skip frames with tl0 = 1
+
+  InsertVp9Gof(sn + 8, sn + 8, true, pid + 8, 0, 0, 2, false, &ss);
+  InsertVp9Gof(sn + 9, sn + 9, false, pid + 9, 0, 2, 2, false);
+  InsertVp9Gof(sn + 10, sn + 10, false, pid + 10, 0, 1, 2, false);
+  InsertVp9Gof(sn + 11, sn + 11, false, pid + 11, 0, 2, 2, false);
+
+  ASSERT_EQ(8UL, frames_from_callback_.size());
+  CheckReferencesVp9(pid + 8, 0);
+  CheckReferencesVp9(pid + 9, 0, pid + 8);
+  CheckReferencesVp9(pid + 10, 0, pid + 8);
+  CheckReferencesVp9(pid + 11, 0, pid + 9, pid + 10);
+
+  // Now insert frames with tl0 = 1
+  InsertVp9Gof(sn + 4, sn + 4, true, pid + 4, 0, 0, 1, false, &ss);
+  InsertVp9Gof(sn + 7, sn + 7, false, pid + 7, 0, 2, 1, false);
+
+  ASSERT_EQ(9UL, frames_from_callback_.size());
+  CheckReferencesVp9(pid + 4, 0);
+
+  // Rest of frames belonging to tl0 = 1
+  InsertVp9Gof(sn + 5, sn + 5, false, pid + 5, 0, 2, 1, false);
+  InsertVp9Gof(sn + 6, sn + 6, false, pid + 6, 0, 1, 1, true);  // up-switch
+
+  ASSERT_EQ(12UL, frames_from_callback_.size());
+  CheckReferencesVp9(pid + 5, 0, pid + 4);
+  CheckReferencesVp9(pid + 6, 0, pid + 4);
+  CheckReferencesVp9(pid + 7, 0, pid + 6);
+}
+
+TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayers_01) {
+  uint16_t pid = Rand();
+  uint16_t sn = Rand();
+  GofInfoVP9 ss;
+  ss.SetGofInfoVP9(kTemporalStructureMode2);  // 0101 pattern
+
+  InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, &ss);
+  InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 1, 0, false);
+  InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 0, 1, false);
+  InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 1, 1, false);
+  InsertVp9Gof(sn + 4, sn + 4, false, pid + 4, 0, 0, 2, false);
+  InsertVp9Gof(sn + 5, sn + 5, false, pid + 5, 0, 1, 2, false);
+  InsertVp9Gof(sn + 6, sn + 6, false, pid + 6, 0, 0, 3, false);
+  InsertVp9Gof(sn + 7, sn + 7, false, pid + 7, 0, 1, 3, false);
+  InsertVp9Gof(sn + 8, sn + 8, false, pid + 8, 0, 0, 4, false);
+  InsertVp9Gof(sn + 9, sn + 9, false, pid + 9, 0, 1, 4, false);
+  InsertVp9Gof(sn + 10, sn + 10, false, pid + 10, 0, 0, 5, false);
+  InsertVp9Gof(sn + 11, sn + 11, false, pid + 11, 0, 1, 5, false);
+  InsertVp9Gof(sn + 12, sn + 12, false, pid + 12, 0, 0, 6, false);
+  InsertVp9Gof(sn + 13, sn + 13, false, pid + 13, 0, 1, 6, false);
+  InsertVp9Gof(sn + 14, sn + 14, false, pid + 14, 0, 0, 7, false);
+  InsertVp9Gof(sn + 15, sn + 15, false, pid + 15, 0, 1, 7, false);
+  InsertVp9Gof(sn + 16, sn + 16, false, pid + 16, 0, 0, 8, false);
+  InsertVp9Gof(sn + 17, sn + 17, false, pid + 17, 0, 1, 8, false);
+  InsertVp9Gof(sn + 18, sn + 18, false, pid + 18, 0, 0, 9, false);
+  InsertVp9Gof(sn + 19, sn + 19, false, pid + 19, 0, 1, 9, false);
+
+  ASSERT_EQ(20UL, frames_from_callback_.size());
+  CheckReferencesVp9(pid, 0);
+  CheckReferencesVp9(pid + 1, 0, pid);
+  CheckReferencesVp9(pid + 2, 0, pid);
+  CheckReferencesVp9(pid + 3, 0, pid + 2);
+  CheckReferencesVp9(pid + 4, 0, pid + 2);
+  CheckReferencesVp9(pid + 5, 0, pid + 4);
+  CheckReferencesVp9(pid + 6, 0, pid + 4);
+  CheckReferencesVp9(pid + 7, 0, pid + 6);
+  CheckReferencesVp9(pid + 8, 0, pid + 6);
+  CheckReferencesVp9(pid + 9, 0, pid + 8);
+  CheckReferencesVp9(pid + 10, 0, pid + 8);
+  CheckReferencesVp9(pid + 11, 0, pid + 10);
+  CheckReferencesVp9(pid + 12, 0, pid + 10);
+  CheckReferencesVp9(pid + 13, 0, pid + 12);
+  CheckReferencesVp9(pid + 14, 0, pid + 12);
+  CheckReferencesVp9(pid + 15, 0, pid + 14);
+  CheckReferencesVp9(pid + 16, 0, pid + 14);
+  CheckReferencesVp9(pid + 17, 0, pid + 16);
+  CheckReferencesVp9(pid + 18, 0, pid + 16);
+  CheckReferencesVp9(pid + 19, 0, pid + 18);
+}
+
+TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayersReordered_01) {
+  uint16_t pid = Rand();
+  uint16_t sn = Rand();
+  GofInfoVP9 ss;
+  ss.SetGofInfoVP9(kTemporalStructureMode2);  // 01 pattern
+
+  InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 1, 0, false);
+  InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, &ss);
+  InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 0, 1, false);
+  InsertVp9Gof(sn + 4, sn + 4, false, pid + 4, 0, 0, 2, false);
+  InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 1, 1, false);
+  InsertVp9Gof(sn + 5, sn + 5, false, pid + 5, 0, 1, 2, false);
+  InsertVp9Gof(sn + 7, sn + 7, false, pid + 7, 0, 1, 3, false);
+  InsertVp9Gof(sn + 6, sn + 6, false, pid + 6, 0, 0, 3, false);
+  InsertVp9Gof(sn + 10, sn + 10, false, pid + 10, 0, 0, 5, false);
+  InsertVp9Gof(sn + 8, sn + 8, false, pid + 8, 0, 0, 4, false);
+  InsertVp9Gof(sn + 9, sn + 9, false, pid + 9, 0, 1, 4, false);
+  InsertVp9Gof(sn + 11, sn + 11, false, pid + 11, 0, 1, 5, false);
+  InsertVp9Gof(sn + 13, sn + 13, false, pid + 13, 0, 1, 6, false);
+  InsertVp9Gof(sn + 16, sn + 16, false, pid + 16, 0, 0, 8, false);
+  InsertVp9Gof(sn + 12, sn + 12, false, pid + 12, 0, 0, 6, false);
+  InsertVp9Gof(sn + 14, sn + 14, false, pid + 14, 0, 0, 7, false);
+  InsertVp9Gof(sn + 17, sn + 17, false, pid + 17, 0, 1, 8, false);
+  InsertVp9Gof(sn + 19, sn + 19, false, pid + 19, 0, 1, 9, false);
+  InsertVp9Gof(sn + 15, sn + 15, false, pid + 15, 0, 1, 7, false);
+  InsertVp9Gof(sn + 18, sn + 18, false, pid + 18, 0, 0, 9, false);
+
+  ASSERT_EQ(20UL, frames_from_callback_.size());
+  CheckReferencesVp9(pid, 0);
+  CheckReferencesVp9(pid + 1, 0, pid);
+  CheckReferencesVp9(pid + 2, 0, pid);
+  CheckReferencesVp9(pid + 3, 0, pid + 2);
+  CheckReferencesVp9(pid + 4, 0, pid + 2);
+  CheckReferencesVp9(pid + 5, 0, pid + 4);
+  CheckReferencesVp9(pid + 6, 0, pid + 4);
+  CheckReferencesVp9(pid + 7, 0, pid + 6);
+  CheckReferencesVp9(pid + 8, 0, pid + 6);
+  CheckReferencesVp9(pid + 9, 0, pid + 8);
+  CheckReferencesVp9(pid + 10, 0, pid + 8);
+  CheckReferencesVp9(pid + 11, 0, pid + 10);
+  CheckReferencesVp9(pid + 12, 0, pid + 10);
+  CheckReferencesVp9(pid + 13, 0, pid + 12);
+  CheckReferencesVp9(pid + 14, 0, pid + 12);
+  CheckReferencesVp9(pid + 15, 0, pid + 14);
+  CheckReferencesVp9(pid + 16, 0, pid + 14);
+  CheckReferencesVp9(pid + 17, 0, pid + 16);
+  CheckReferencesVp9(pid + 18, 0, pid + 16);
+  CheckReferencesVp9(pid + 19, 0, pid + 18);
+}
+
+TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayers_0212) {
+  uint16_t pid = Rand();
+  uint16_t sn = Rand();
+  GofInfoVP9 ss;
+  ss.SetGofInfoVP9(kTemporalStructureMode3);  // 0212 pattern
+
+  InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, &ss);
+  InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 2, 0, false);
+  InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 1, 0, false);
+  InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 2, 0, false);
+  InsertVp9Gof(sn + 4, sn + 4, false, pid + 4, 0, 0, 1, false);
+  InsertVp9Gof(sn + 5, sn + 5, false, pid + 5, 0, 2, 1, false);
+  InsertVp9Gof(sn + 6, sn + 6, false, pid + 6, 0, 1, 1, false);
+  InsertVp9Gof(sn + 7, sn + 7, false, pid + 7, 0, 2, 1, false);
+  InsertVp9Gof(sn + 8, sn + 8, false, pid + 8, 0, 0, 2, false);
+  InsertVp9Gof(sn + 9, sn + 9, false, pid + 9, 0, 2, 2, false);
+  InsertVp9Gof(sn + 10, sn + 10, false, pid + 10, 0, 1, 2, false);
+  InsertVp9Gof(sn + 11, sn + 11, false, pid + 11, 0, 2, 2, false);
+  InsertVp9Gof(sn + 12, sn + 12, false, pid + 12, 0, 0, 3, false);
+  InsertVp9Gof(sn + 13, sn + 13, false, pid + 13, 0, 2, 3, false);
+  InsertVp9Gof(sn + 14, sn + 14, false, pid + 14, 0, 1, 3, false);
+  InsertVp9Gof(sn + 15, sn + 15, false, pid + 15, 0, 2, 3, false);
+  InsertVp9Gof(sn + 16, sn + 16, false, pid + 16, 0, 0, 4, false);
+  InsertVp9Gof(sn + 17, sn + 17, false, pid + 17, 0, 2, 4, false);
+  InsertVp9Gof(sn + 18, sn + 18, false, pid + 18, 0, 1, 4, false);
+  InsertVp9Gof(sn + 19, sn + 19, false, pid + 19, 0, 2, 4, false);
+
+  ASSERT_EQ(20UL, frames_from_callback_.size());
+  CheckReferencesVp9(pid, 0);
+  CheckReferencesVp9(pid + 1, 0, pid);
+  CheckReferencesVp9(pid + 2, 0, pid);
+  CheckReferencesVp9(pid + 3, 0, pid + 1, pid + 2);
+  CheckReferencesVp9(pid + 4, 0, pid);
+  CheckReferencesVp9(pid + 5, 0, pid + 4);
+  CheckReferencesVp9(pid + 6, 0, pid + 4);
+  CheckReferencesVp9(pid + 7, 0, pid + 5, pid + 6);
+  CheckReferencesVp9(pid + 8, 0, pid + 4);
+  CheckReferencesVp9(pid + 9, 0, pid + 8);
+  CheckReferencesVp9(pid + 10, 0, pid + 8);
+  CheckReferencesVp9(pid + 11, 0, pid + 9, pid + 10);
+  CheckReferencesVp9(pid + 12, 0, pid + 8);
+  CheckReferencesVp9(pid + 13, 0, pid + 12);
+  CheckReferencesVp9(pid + 14, 0, pid + 12);
+  CheckReferencesVp9(pid + 15, 0, pid + 13, pid + 14);
+  CheckReferencesVp9(pid + 16, 0, pid + 12);
+  CheckReferencesVp9(pid + 17, 0, pid + 16);
+  CheckReferencesVp9(pid + 18, 0, pid + 16);
+  CheckReferencesVp9(pid + 19, 0, pid + 17, pid + 18);
+}
+
+TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayersReordered_0212) {
+  uint16_t pid = Rand();
+  uint16_t sn = Rand();
+  GofInfoVP9 ss;
+  ss.SetGofInfoVP9(kTemporalStructureMode3);  // 0212 pattern
+
+  InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 1, 0, false);
+  InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 2, 0, false);
+  InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, &ss);
+  InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 2, 0, false);
+  InsertVp9Gof(sn + 6, sn + 6, false, pid + 6, 0, 1, 1, false);
+  InsertVp9Gof(sn + 5, sn + 5, false, pid + 5, 0, 2, 1, false);
+  InsertVp9Gof(sn + 4, sn + 4, false, pid + 4, 0, 0, 1, false);
+  InsertVp9Gof(sn + 9, sn + 9, false, pid + 9, 0, 2, 2, false);
+  InsertVp9Gof(sn + 7, sn + 7, false, pid + 7, 0, 2, 1, false);
+  InsertVp9Gof(sn + 8, sn + 8, false, pid + 8, 0, 0, 2, false);
+  InsertVp9Gof(sn + 11, sn + 11, false, pid + 11, 0, 2, 2, false);
+  InsertVp9Gof(sn + 10, sn + 10, false, pid + 10, 0, 1, 2, false);
+  InsertVp9Gof(sn + 13, sn + 13, false, pid + 13, 0, 2, 3, false);
+  InsertVp9Gof(sn + 12, sn + 12, false, pid + 12, 0, 0, 3, false);
+  InsertVp9Gof(sn + 14, sn + 14, false, pid + 14, 0, 1, 3, false);
+  InsertVp9Gof(sn + 16, sn + 16, false, pid + 16, 0, 0, 4, false);
+  InsertVp9Gof(sn + 15, sn + 15, false, pid + 15, 0, 2, 3, false);
+  InsertVp9Gof(sn + 17, sn + 17, false, pid + 17, 0, 2, 4, false);
+  InsertVp9Gof(sn + 19, sn + 19, false, pid + 19, 0, 2, 4, false);
+  InsertVp9Gof(sn + 18, sn + 18, false, pid + 18, 0, 1, 4, false);
+
+  ASSERT_EQ(20UL, frames_from_callback_.size());
+  CheckReferencesVp9(pid, 0);
+  CheckReferencesVp9(pid + 1, 0, pid);
+  CheckReferencesVp9(pid + 2, 0, pid);
+  CheckReferencesVp9(pid + 3, 0, pid + 1, pid + 2);
+  CheckReferencesVp9(pid + 4, 0, pid);
+  CheckReferencesVp9(pid + 5, 0, pid + 4);
+  CheckReferencesVp9(pid + 6, 0, pid + 4);
+  CheckReferencesVp9(pid + 7, 0, pid + 5, pid + 6);
+  CheckReferencesVp9(pid + 8, 0, pid + 4);
+  CheckReferencesVp9(pid + 9, 0, pid + 8);
+  CheckReferencesVp9(pid + 10, 0, pid + 8);
+  CheckReferencesVp9(pid + 11, 0, pid + 9, pid + 10);
+  CheckReferencesVp9(pid + 12, 0, pid + 8);
+  CheckReferencesVp9(pid + 13, 0, pid + 12);
+  CheckReferencesVp9(pid + 14, 0, pid + 12);
+  CheckReferencesVp9(pid + 15, 0, pid + 13, pid + 14);
+  CheckReferencesVp9(pid + 16, 0, pid + 12);
+  CheckReferencesVp9(pid + 17, 0, pid + 16);
+  CheckReferencesVp9(pid + 18, 0, pid + 16);
+  CheckReferencesVp9(pid + 19, 0, pid + 17, pid + 18);
+}
+
+TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayersUpSwitch_02120212) {
+  uint16_t pid = Rand();
+  uint16_t sn = Rand();
+  GofInfoVP9 ss;
+  ss.SetGofInfoVP9(kTemporalStructureMode4);  // 02120212 pattern
+
+  InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, &ss);
+  InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 2, 0, false);
+  InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 1, 0, false);
+  InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 2, 0, false);
+  InsertVp9Gof(sn + 4, sn + 4, false, pid + 4, 0, 0, 1, false);
+  InsertVp9Gof(sn + 5, sn + 5, false, pid + 5, 0, 2, 1, false);
+  InsertVp9Gof(sn + 6, sn + 6, false, pid + 6, 0, 1, 1, true);
+  InsertVp9Gof(sn + 7, sn + 7, false, pid + 7, 0, 2, 1, false);
+  InsertVp9Gof(sn + 8, sn + 8, false, pid + 8, 0, 0, 2, true);
+  InsertVp9Gof(sn + 9, sn + 9, false, pid + 9, 0, 2, 2, false);
+  InsertVp9Gof(sn + 10, sn + 10, false, pid + 10, 0, 1, 2, false);
+  InsertVp9Gof(sn + 11, sn + 11, false, pid + 11, 0, 2, 2, true);
+  InsertVp9Gof(sn + 12, sn + 12, false, pid + 12, 0, 0, 3, false);
+  InsertVp9Gof(sn + 13, sn + 13, false, pid + 13, 0, 2, 3, false);
+  InsertVp9Gof(sn + 14, sn + 14, false, pid + 14, 0, 1, 3, false);
+  InsertVp9Gof(sn + 15, sn + 15, false, pid + 15, 0, 2, 3, false);
+
+  ASSERT_EQ(16UL, frames_from_callback_.size());
+  CheckReferencesVp9(pid, 0);
+  CheckReferencesVp9(pid + 1, 0, pid);
+  CheckReferencesVp9(pid + 2, 0, pid);
+  CheckReferencesVp9(pid + 3, 0, pid + 1, pid + 2);
+  CheckReferencesVp9(pid + 4, 0, pid);
+  CheckReferencesVp9(pid + 5, 0, pid + 3, pid + 4);
+  CheckReferencesVp9(pid + 6, 0, pid + 2, pid + 4);
+  CheckReferencesVp9(pid + 7, 0, pid + 6);
+  CheckReferencesVp9(pid + 8, 0, pid + 4);
+  CheckReferencesVp9(pid + 9, 0, pid + 8);
+  CheckReferencesVp9(pid + 10, 0, pid + 8);
+  CheckReferencesVp9(pid + 11, 0, pid + 9, pid + 10);
+  CheckReferencesVp9(pid + 12, 0, pid + 8);
+  CheckReferencesVp9(pid + 13, 0, pid + 11, pid + 12);
+  CheckReferencesVp9(pid + 14, 0, pid + 10, pid + 12);
+  CheckReferencesVp9(pid + 15, 0, pid + 13, pid + 14);
+}
+
+TEST_F(TestRtpFrameReferenceFinder,
+       Vp9GofTemporalLayersUpSwitchReordered_02120212) {
+  uint16_t pid = Rand();
+  uint16_t sn = Rand();
+  GofInfoVP9 ss;
+  ss.SetGofInfoVP9(kTemporalStructureMode4);  // 02120212 pattern
+
+  InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 2, 0, false);
+  InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, &ss);
+  InsertVp9Gof(sn + 4, sn + 4, false, pid + 4, 0, 0, 1, false);
+  InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 1, 0, false);
+  InsertVp9Gof(sn + 5, sn + 5, false, pid + 5, 0, 2, 1, false);
+  InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 2, 0, false);
+  InsertVp9Gof(sn + 7, sn + 7, false, pid + 7, 0, 2, 1, false);
+  InsertVp9Gof(sn + 9, sn + 9, false, pid + 9, 0, 2, 2, false);
+  InsertVp9Gof(sn + 6, sn + 6, false, pid + 6, 0, 1, 1, true);
+  InsertVp9Gof(sn + 12, sn + 12, false, pid + 12, 0, 0, 3, false);
+  InsertVp9Gof(sn + 10, sn + 10, false, pid + 10, 0, 1, 2, false);
+  InsertVp9Gof(sn + 8, sn + 8, false, pid + 8, 0, 0, 2, true);
+  InsertVp9Gof(sn + 11, sn + 11, false, pid + 11, 0, 2, 2, true);
+  InsertVp9Gof(sn + 13, sn + 13, false, pid + 13, 0, 2, 3, false);
+  InsertVp9Gof(sn + 15, sn + 15, false, pid + 15, 0, 2, 3, false);
+  InsertVp9Gof(sn + 14, sn + 14, false, pid + 14, 0, 1, 3, false);
+
+  ASSERT_EQ(16UL, frames_from_callback_.size());
+  CheckReferencesVp9(pid, 0);
+  CheckReferencesVp9(pid + 1, 0, pid);
+  CheckReferencesVp9(pid + 2, 0, pid);
+  CheckReferencesVp9(pid + 3, 0, pid + 1, pid + 2);
+  CheckReferencesVp9(pid + 4, 0, pid);
+  CheckReferencesVp9(pid + 5, 0, pid + 3, pid + 4);
+  CheckReferencesVp9(pid + 6, 0, pid + 2, pid + 4);
+  CheckReferencesVp9(pid + 7, 0, pid + 6);
+  CheckReferencesVp9(pid + 8, 0, pid + 4);
+  CheckReferencesVp9(pid + 9, 0, pid + 8);
+  CheckReferencesVp9(pid + 10, 0, pid + 8);
+  CheckReferencesVp9(pid + 11, 0, pid + 9, pid + 10);
+  CheckReferencesVp9(pid + 12, 0, pid + 8);
+  CheckReferencesVp9(pid + 13, 0, pid + 11, pid + 12);
+  CheckReferencesVp9(pid + 14, 0, pid + 10, pid + 12);
+  CheckReferencesVp9(pid + 15, 0, pid + 13, pid + 14);
+}
+
+TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayersReordered_01_0212) {
+  uint16_t pid = Rand();
+  uint16_t sn = Rand();
+  GofInfoVP9 ss;
+  ss.SetGofInfoVP9(kTemporalStructureMode2);  // 01 pattern
+
+  InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 1, 0, false);
+  InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, &ss);
+  InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 1, 1, false);
+  InsertVp9Gof(sn + 6, sn + 6, false, pid + 6, 0, 1, 2, false);
+  ss.SetGofInfoVP9(kTemporalStructureMode3);  // 0212 pattern
+  InsertVp9Gof(sn + 4, sn + 4, false, pid + 4, 0, 0, 2, false, &ss);
+  InsertVp9Gof(sn + 2, sn + 2, false, pid + 2, 0, 0, 1, false);
+  InsertVp9Gof(sn + 5, sn + 5, false, pid + 5, 0, 2, 2, false);
+  InsertVp9Gof(sn + 8, sn + 8, false, pid + 8, 0, 0, 3, false);
+  InsertVp9Gof(sn + 10, sn + 10, false, pid + 10, 0, 1, 3, false);
+  InsertVp9Gof(sn + 7, sn + 7, false, pid + 7, 0, 2, 2, false);
+  InsertVp9Gof(sn + 11, sn + 11, false, pid + 11, 0, 2, 3, false);
+  InsertVp9Gof(sn + 9, sn + 9, false, pid + 9, 0, 2, 3, false);
+
+  ASSERT_EQ(12UL, frames_from_callback_.size());
+  CheckReferencesVp9(pid, 0);
+  CheckReferencesVp9(pid + 1, 0, pid);
+  CheckReferencesVp9(pid + 2, 0, pid);
+  CheckReferencesVp9(pid + 3, 0, pid + 2);
+  CheckReferencesVp9(pid + 4, 0, pid);
+  CheckReferencesVp9(pid + 5, 0, pid + 4);
+  CheckReferencesVp9(pid + 6, 0, pid + 4);
+  CheckReferencesVp9(pid + 7, 0, pid + 5, pid + 6);
+  CheckReferencesVp9(pid + 8, 0, pid + 4);
+  CheckReferencesVp9(pid + 9, 0, pid + 8);
+  CheckReferencesVp9(pid + 10, 0, pid + 8);
+  CheckReferencesVp9(pid + 11, 0, pid + 9, pid + 10);
+}
+
+TEST_F(TestRtpFrameReferenceFinder, Vp9FlexibleModeOneFrame) {
+  uint16_t pid = Rand();
+  uint16_t sn = Rand();
+
+  InsertVp9Flex(sn, sn, true, pid, 0, 0, 0, false);
+
+  ASSERT_EQ(1UL, frames_from_callback_.size());
+  CheckReferencesVp9(pid, 0);
+}
+
+TEST_F(TestRtpFrameReferenceFinder, Vp9FlexibleModeTwoSpatialLayers) {
+  uint16_t pid = Rand();
+  uint16_t sn = Rand();
+
+  InsertVp9Flex(sn, sn, true, pid, 0, 0, 0, false);
+  InsertVp9Flex(sn + 1, sn + 1, true, pid, 1, 0, 0, true);
+  InsertVp9Flex(sn + 2, sn + 2, false, pid + 1, 1, 0, 0, false, {1});
+  InsertVp9Flex(sn + 3, sn + 3, false, pid + 2, 0, 0, 1, false, {2});
+  InsertVp9Flex(sn + 4, sn + 4, false, pid + 2, 1, 0, 1, false, {1});
+  InsertVp9Flex(sn + 5, sn + 5, false, pid + 3, 1, 0, 1, false, {1});
+  InsertVp9Flex(sn + 6, sn + 6, false, pid + 4, 0, 0, 2, false, {2});
+  InsertVp9Flex(sn + 7, sn + 7, false, pid + 4, 1, 0, 2, false, {1});
+  InsertVp9Flex(sn + 8, sn + 8, false, pid + 5, 1, 0, 2, false, {1});
+  InsertVp9Flex(sn + 9, sn + 9, false, pid + 6, 0, 0, 3, false, {2});
+  InsertVp9Flex(sn + 10, sn + 10, false, pid + 6, 1, 0, 3, false, {1});
+  InsertVp9Flex(sn + 11, sn + 11, false, pid + 7, 1, 0, 3, false, {1});
+  InsertVp9Flex(sn + 12, sn + 12, false, pid + 8, 0, 0, 4, false, {2});
+  InsertVp9Flex(sn + 13, sn + 13, false, pid + 8, 1, 0, 4, false, {1});
+
+  ASSERT_EQ(14UL, frames_from_callback_.size());
+  CheckReferencesVp9(pid, 0);
+  CheckReferencesVp9(pid, 1);
+  CheckReferencesVp9(pid + 1, 1, pid);
+  CheckReferencesVp9(pid + 2, 0, pid);
+  CheckReferencesVp9(pid + 2, 1, pid + 1);
+  CheckReferencesVp9(pid + 3, 1, pid + 2);
+  CheckReferencesVp9(pid + 4, 0, pid + 2);
+  CheckReferencesVp9(pid + 4, 1, pid + 3);
+  CheckReferencesVp9(pid + 5, 1, pid + 4);
+  CheckReferencesVp9(pid + 6, 0, pid + 4);
+  CheckReferencesVp9(pid + 6, 1, pid + 5);
+  CheckReferencesVp9(pid + 7, 1, pid + 6);
+  CheckReferencesVp9(pid + 8, 0, pid + 6);
+  CheckReferencesVp9(pid + 8, 1, pid + 7);
+}
+
+TEST_F(TestRtpFrameReferenceFinder, Vp9FlexibleModeTwoSpatialLayersReordered) {
+  uint16_t pid = Rand();
+  uint16_t sn = Rand();
+
+  InsertVp9Flex(sn + 1, sn + 1, true, pid, 1, 0, 0, true);
+  InsertVp9Flex(sn + 2, sn + 2, false, pid + 1, 1, 0, 0, false, {1});
+  InsertVp9Flex(sn, sn, true, pid, 0, 0, 0, false);
+  InsertVp9Flex(sn + 4, sn + 4, false, pid + 2, 1, 0, 1, false, {1});
+  InsertVp9Flex(sn + 5, sn + 5, false, pid + 3, 1, 0, 1, false, {1});
+  InsertVp9Flex(sn + 3, sn + 3, false, pid + 2, 0, 0, 1, false, {2});
+  InsertVp9Flex(sn + 7, sn + 7, false, pid + 4, 1, 0, 2, false, {1});
+  InsertVp9Flex(sn + 6, sn + 6, false, pid + 4, 0, 0, 2, false, {2});
+  InsertVp9Flex(sn + 8, sn + 8, false, pid + 5, 1, 0, 2, false, {1});
+  InsertVp9Flex(sn + 9, sn + 9, false, pid + 6, 0, 0, 3, false, {2});
+  InsertVp9Flex(sn + 11, sn + 11, false, pid + 7, 1, 0, 3, false, {1});
+  InsertVp9Flex(sn + 10, sn + 10, false, pid + 6, 1, 0, 3, false, {1});
+  InsertVp9Flex(sn + 13, sn + 13, false, pid + 8, 1, 0, 4, false, {1});
+  InsertVp9Flex(sn + 12, sn + 12, false, pid + 8, 0, 0, 4, false, {2});
+
+  ASSERT_EQ(14UL, frames_from_callback_.size());
+  CheckReferencesVp9(pid, 0);
+  CheckReferencesVp9(pid, 1);
+  CheckReferencesVp9(pid + 1, 1, pid);
+  CheckReferencesVp9(pid + 2, 0, pid);
+  CheckReferencesVp9(pid + 2, 1, pid + 1);
+  CheckReferencesVp9(pid + 3, 1, pid + 2);
+  CheckReferencesVp9(pid + 4, 0, pid + 2);
+  CheckReferencesVp9(pid + 4, 1, pid + 3);
+  CheckReferencesVp9(pid + 5, 1, pid + 4);
+  CheckReferencesVp9(pid + 6, 0, pid + 4);
+  CheckReferencesVp9(pid + 6, 1, pid + 5);
+  CheckReferencesVp9(pid + 7, 1, pid + 6);
+  CheckReferencesVp9(pid + 8, 0, pid + 6);
+  CheckReferencesVp9(pid + 8, 1, pid + 7);
+}
+
+}  // namespace video_coding
+}  // namespace webrtc
diff --git a/webrtc/modules/video_coding/video_packet_buffer_unittest.cc b/webrtc/modules/video_coding/video_packet_buffer_unittest.cc
index ee9a853..f4ae5c7 100644
--- a/webrtc/modules/video_coding/video_packet_buffer_unittest.cc
+++ b/webrtc/modules/video_coding/video_packet_buffer_unittest.cc
@@ -9,7 +9,6 @@
  */
 
 #include <cstring>
-#include <limits>
 #include <map>
 #include <set>
 #include <utility>
@@ -24,274 +23,83 @@
 namespace video_coding {
 
 class TestPacketBuffer : public ::testing::Test,
-                         public OnCompleteFrameCallback {
+                         public OnReceivedFrameCallback {
  protected:
   TestPacketBuffer()
-      : rand_(0x8739211),
+      : rand_(0x7732213),
         clock_(new SimulatedClock(0)),
-        packet_buffer_(new PacketBuffer(clock_.get(),
-                       kStartSize,
-                       kMaxSize,
-                       this)),
-        frames_from_callback_(FrameComp()),
-        dummy_data_(new uint8_t[kDummyDataSize]()) {}
+        packet_buffer_(
+            PacketBuffer::Create(clock_.get(), kStartSize, kMaxSize, this)) {}
 
-  uint16_t Rand() { return rand_.Rand(std::numeric_limits<uint16_t>::max()); }
+  uint16_t Rand() { return rand_.Rand<uint16_t>(); }
 
-  void OnCompleteFrame(std::unique_ptr<FrameObject> frame) override {
-    uint16_t pid = frame->picture_id;
-    uint16_t sidx = frame->spatial_layer;
-    auto frame_it = frames_from_callback_.find(std::make_pair(pid, sidx));
-    if (frame_it != frames_from_callback_.end()) {
-      ADD_FAILURE() << "Already received frame with (pid:sidx): ("
-                    << pid << ":" << sidx << ")";
+  void OnReceivedFrame(std::unique_ptr<RtpFrameObject> frame) override {
+    uint16_t first_seq_num = frame->first_seq_num();
+    if (frames_from_callback_.find(first_seq_num) !=
+        frames_from_callback_.end()) {
+      ADD_FAILURE() << "Already received frame with first sequence number "
+                    << first_seq_num << ".";
       return;
     }
-
     frames_from_callback_.insert(
-        std::make_pair(std::make_pair(pid, sidx), std::move(frame)));
+        std::make_pair(frame->first_seq_num(), std::move(frame)));
   }
 
-  void TearDown() override {
-    // All frame objects must be destroyed before the packet buffer since
-    // a frame object will try to remove itself from the packet buffer
-    // upon destruction.
-    frames_from_callback_.clear();
-  }
+  enum IsKeyFrame { kKeyFrame, kDeltaFrame };
+  enum IsFirst { kFirst, kNotFirst };
+  enum IsLast { kLast, kNotLast };
 
-  // Short version of true and false.
-  enum {
-    kT = true,
-    kF = false
-  };
-
-  // Insert a generic packet into the packet buffer.
-  void InsertGeneric(uint16_t seq_num,           // packet sequence number
-                     bool keyframe,              // is keyframe
-                     bool first,                 // is first packet of frame
-                     bool last,                  // is last packet of frame
-                     int data_size = -1,         // size of data
-                     uint8_t* data = nullptr) {  // data pointer
-    if (data_size == -1) {
-      data_size = kDummyDataSize;
-      data = dummy_data_.get();
-    }
-
+  void InsertPacket(uint16_t seq_num,           // packet sequence number
+                    IsKeyFrame keyframe,        // is keyframe
+                    IsFirst first,              // is first packet of frame
+                    IsLast last,                // is last packet of frame
+                    int data_size = 0,          // size of data
+                    uint8_t* data = nullptr) {  // data pointer
     VCMPacket packet;
     packet.codec = kVideoCodecGeneric;
     packet.seqNum = seq_num;
     packet.frameType = keyframe ? kVideoFrameKey : kVideoFrameDelta;
-    packet.isFirstPacket = first;
-    packet.markerBit = last;
+    packet.isFirstPacket = first == kFirst;
+    packet.markerBit = last == kLast;
     packet.sizeBytes = data_size;
     packet.dataPtr = data;
 
     EXPECT_TRUE(packet_buffer_->InsertPacket(packet));
   }
 
-  // Insert a Vp8 packet into the packet buffer.
-  void InsertVp8(uint16_t seq_num,              // packet sequence number
-                 bool keyframe,                 // is keyframe
-                 bool first,                    // is first packet of frame
-                 bool last,                     // is last packet of frame
-                 bool sync = false,             // is sync frame
-                 int32_t pid = kNoPictureId,    // picture id
-                 uint8_t tid = kNoTemporalIdx,  // temporal id
-                 int32_t tl0 = kNoTl0PicIdx,    // tl0 pic index
-                 int data_size = -1,            // size of data
-                 uint8_t* data = nullptr) {     // data pointer
-    if (data_size == -1) {
-      data_size = kDummyDataSize;
-      data = dummy_data_.get();
-    }
-
-    VCMPacket packet;
-    packet.codec = kVideoCodecVP8;
-    packet.seqNum = seq_num;
-    packet.frameType = keyframe ? kVideoFrameKey : kVideoFrameDelta;
-    packet.isFirstPacket = first;
-    packet.markerBit = last;
-    packet.sizeBytes = data_size;
-    packet.dataPtr = data;
-    packet.video_header.codecHeader.VP8.pictureId = pid % (1 << 15);
-    packet.video_header.codecHeader.VP8.temporalIdx = tid;
-    packet.video_header.codecHeader.VP8.tl0PicIdx = tl0;
-    packet.video_header.codecHeader.VP8.layerSync = sync;
-
-    EXPECT_TRUE(packet_buffer_->InsertPacket(packet));
+  void CheckFrame(uint16_t first_seq_num) {
+    auto frame_it = frames_from_callback_.find(first_seq_num);
+    ASSERT_FALSE(frame_it == frames_from_callback_.end())
+        << "Could not find frame with first sequence number " << first_seq_num
+        << ".";
   }
 
-  // Insert a Vp9 packet into the packet buffer.
-  void InsertVp9Gof(uint16_t seq_num,              // packet sequence number
-                    bool keyframe,                 // is keyframe
-                    bool first,                    // is first packet of frame
-                    bool last,                     // is last packet of frame
-                    bool up = false,               // frame is up-switch point
-                    int32_t pid = kNoPictureId,    // picture id
-                    uint8_t sid = kNoSpatialIdx,   // spatial id
-                    uint8_t tid = kNoTemporalIdx,  // temporal id
-                    int32_t tl0 = kNoTl0PicIdx,    // tl0 pic index
-                    GofInfoVP9* ss = nullptr,      // scalability structure
-                    int data_size = -1,            // size of data
-                    uint8_t* data = nullptr) {     // data pointer
-    if (data_size == -1) {
-      data_size = kDummyDataSize;
-      data = dummy_data_.get();
-    }
-
-    VCMPacket packet;
-    packet.codec = kVideoCodecVP9;
-    packet.seqNum = seq_num;
-    packet.frameType = keyframe ? kVideoFrameKey : kVideoFrameDelta;
-    packet.isFirstPacket = first;
-    packet.markerBit = last;
-    packet.sizeBytes = data_size;
-    packet.dataPtr = data;
-    packet.video_header.codecHeader.VP9.flexible_mode = false;
-    packet.video_header.codecHeader.VP9.picture_id = pid % (1 << 15);
-    packet.video_header.codecHeader.VP9.temporal_idx = tid;
-    packet.video_header.codecHeader.VP9.spatial_idx = sid;
-    packet.video_header.codecHeader.VP9.tl0_pic_idx = tl0;
-    packet.video_header.codecHeader.VP9.temporal_up_switch = up;
-    if (ss != nullptr) {
-      packet.video_header.codecHeader.VP9.ss_data_available = true;
-      packet.video_header.codecHeader.VP9.gof = *ss;
-    }
-
-    EXPECT_TRUE(packet_buffer_->InsertPacket(packet));
-  }
-
-  // Insert a Vp9 packet into the packet buffer.
-  void InsertVp9Flex(
-      uint16_t seq_num,              // packet sequence number
-      bool keyframe,                 // is keyframe
-      bool first,                    // is first packet of frame
-      bool last,                     // is last packet of frame
-      bool inter,                    // depends on S-1 layer
-      int32_t pid = kNoPictureId,    // picture id
-      uint8_t sid = kNoSpatialIdx,   // spatial id
-      uint8_t tid = kNoTemporalIdx,  // temporal id
-      int32_t tl0 = kNoTl0PicIdx,    // tl0 pic index
-      std::vector<uint8_t> refs = std::vector<uint8_t>(),  // frame references
-      int data_size = -1,                                  // size of data
-      uint8_t* data = nullptr) {                           // data pointer
-    if (data_size == -1) {
-      data_size = kDummyDataSize;
-      data = dummy_data_.get();
-    }
-
-    VCMPacket packet;
-    packet.codec = kVideoCodecVP9;
-    packet.seqNum = seq_num;
-    packet.frameType = keyframe ? kVideoFrameKey : kVideoFrameDelta;
-    packet.isFirstPacket = first;
-    packet.markerBit = last;
-    packet.sizeBytes = data_size;
-    packet.dataPtr = data;
-    packet.video_header.codecHeader.VP9.inter_layer_predicted = inter;
-    packet.video_header.codecHeader.VP9.flexible_mode = true;
-    packet.video_header.codecHeader.VP9.picture_id = pid % (1 << 15);
-    packet.video_header.codecHeader.VP9.temporal_idx = tid;
-    packet.video_header.codecHeader.VP9.spatial_idx = sid;
-    packet.video_header.codecHeader.VP9.tl0_pic_idx = tl0;
-    packet.video_header.codecHeader.VP9.num_ref_pics = refs.size();
-    for (size_t i = 0; i < refs.size(); ++i)
-      packet.video_header.codecHeader.VP9.pid_diff[i] = refs[i];
-
-    EXPECT_TRUE(packet_buffer_->InsertPacket(packet));
-  }
-
-  // Check if a frame with picture id |pid| and spatial index |sidx| has been
-  // delivered from the packet buffer, and if so, if it has the references
-  // specified by |refs|.
-  template <typename... T>
-  void CheckReferences(uint16_t pid, uint16_t sidx, T... refs) const {
-    auto frame_it = frames_from_callback_.find(std::make_pair(pid, sidx));
-    if (frame_it == frames_from_callback_.end()) {
-      ADD_FAILURE() << "Could not find frame with (pid:sidx): ("
-                    << pid << ":" << sidx << ")";
-      return;
-    }
-
-    std::set<uint16_t> actual_refs;
-    for (uint8_t r = 0; r < frame_it->second->num_references; ++r) {
-      actual_refs.insert(frame_it->second->references[r]);
-    }
-
-    std::set<uint16_t> expected_refs;
-    RefsToSet(&expected_refs, refs...);
-
-    ASSERT_EQ(expected_refs, actual_refs);
-  }
-
-  template <typename... T>
-  void CheckReferencesGeneric(uint16_t pid, T... refs) const {
-    CheckReferences(pid, 0, refs...);
-  }
-
-  template <typename... T>
-  void CheckReferencesVp8(uint16_t pid, T... refs) const {
-    CheckReferences(pid, 0, refs...);
-  }
-
-  template <typename... T>
-  void CheckReferencesVp9(uint16_t pid, uint8_t sidx, T... refs) const {
-    CheckReferences(pid, sidx, refs...);
-  }
-
-  template <typename... T>
-  void RefsToSet(std::set<uint16_t>* m, uint16_t ref, T... refs) const {
-    m->insert(ref);
-    RefsToSet(m, refs...);
-  }
-
-  void RefsToSet(std::set<uint16_t>* m) const {}
-
   const int kStartSize = 16;
   const int kMaxSize = 64;
-  const int kDummyDataSize = 4;
 
   Random rand_;
   std::unique_ptr<Clock> clock_;
-  std::unique_ptr<PacketBuffer> packet_buffer_;
-  struct FrameComp {
-    bool operator()(const std::pair<uint16_t, uint8_t> f1,
-                    const std::pair<uint16_t, uint8_t> f2) const {
-                      if (f1.first == f2.first)
-                        return f1.second < f2.second;
-                      return f1.first < f2.first;
-                    }
-  };
-  std::map<std::pair<uint16_t, uint8_t>,
-           std::unique_ptr<FrameObject>,
-           FrameComp> frames_from_callback_;
-
-  std::unique_ptr<uint8_t[]> dummy_data_;
+  rtc::scoped_refptr<PacketBuffer> packet_buffer_;
+  std::map<uint16_t, std::unique_ptr<RtpFrameObject>> frames_from_callback_;
 };
 
 TEST_F(TestPacketBuffer, InsertOnePacket) {
-  VCMPacket packet;
-  packet.seqNum = Rand();
-  EXPECT_TRUE(packet_buffer_->InsertPacket(packet));
+  uint16_t seq_num = Rand();
+  InsertPacket(seq_num, kKeyFrame, kFirst, kLast);
 }
 
 TEST_F(TestPacketBuffer, InsertMultiplePackets) {
-  VCMPacket packet;
-  packet.seqNum = Rand();
-  EXPECT_TRUE(packet_buffer_->InsertPacket(packet));
-  ++packet.seqNum;
-  EXPECT_TRUE(packet_buffer_->InsertPacket(packet));
-  ++packet.seqNum;
-  EXPECT_TRUE(packet_buffer_->InsertPacket(packet));
+  uint16_t seq_num = Rand();
+  InsertPacket(seq_num, kKeyFrame, kFirst, kLast);
+  InsertPacket(seq_num + 1, kKeyFrame, kFirst, kLast);
+  InsertPacket(seq_num + 2, kKeyFrame, kFirst, kLast);
+  InsertPacket(seq_num + 3, kKeyFrame, kFirst, kLast);
 }
 
 TEST_F(TestPacketBuffer, InsertDuplicatePacket) {
-  VCMPacket packet;
-  packet.seqNum = Rand();
-  EXPECT_TRUE(packet_buffer_->InsertPacket(packet));
-  ++packet.seqNum;
-  EXPECT_TRUE(packet_buffer_->InsertPacket(packet));
-  EXPECT_TRUE(packet_buffer_->InsertPacket(packet));
+  uint16_t seq_num = Rand();
+  InsertPacket(seq_num, kKeyFrame, kFirst, kLast);
+  InsertPacket(seq_num, kKeyFrame, kFirst, kLast);
 }
 
 TEST_F(TestPacketBuffer, NackCount) {
@@ -303,8 +111,6 @@
   packet.frameType = kVideoFrameKey;
   packet.isFirstPacket = true;
   packet.markerBit = false;
-  packet.dataPtr = dummy_data_.get();
-  packet.sizeBytes = kDummyDataSize;
   packet.timesNacked = 0;
 
   packet_buffer_->InsertPacket(packet);
@@ -325,20 +131,18 @@
 
 
   ASSERT_EQ(1UL, frames_from_callback_.size());
-  FrameObject* frame = frames_from_callback_.begin()->second.get();
-  RtpFrameObject* rtp_frame = static_cast<RtpFrameObject*>(frame);
-  EXPECT_EQ(3, rtp_frame->times_nacked());
+  RtpFrameObject* frame = frames_from_callback_.begin()->second.get();
+  EXPECT_EQ(3, frame->times_nacked());
 }
 
 TEST_F(TestPacketBuffer, FrameSize) {
   uint16_t seq_num = Rand();
   uint8_t data[] = {1, 2, 3, 4, 5};
 
-  //            seq_num    , kf, frst, lst, size, data
-  InsertGeneric(seq_num    , kT, kT  , kF , 5   , data);
-  InsertGeneric(seq_num + 1, kT, kF  , kF , 5   , data);
-  InsertGeneric(seq_num + 2, kT, kF  , kF , 5   , data);
-  InsertGeneric(seq_num + 3, kT, kF  , kT , 5   , data);
+  InsertPacket(seq_num, kKeyFrame, kFirst, kNotLast, 5, data);
+  InsertPacket(seq_num + 1, kKeyFrame, kNotFirst, kNotLast, 5, data);
+  InsertPacket(seq_num + 2, kKeyFrame, kNotFirst, kNotLast, 5, data);
+  InsertPacket(seq_num + 3, kKeyFrame, kNotFirst, kLast, 5, data);
 
   ASSERT_EQ(1UL, frames_from_callback_.size());
   EXPECT_EQ(20UL, frames_from_callback_.begin()->second->size);
@@ -348,8 +152,7 @@
   uint16_t seq_num = Rand();
 
   for (int i = 0; i < kStartSize + 1; ++i) {
-    //            seq_num    , kf, frst, lst
-    InsertGeneric(seq_num + i, kT, kT  , kT);
+    InsertPacket(seq_num + i, kKeyFrame, kFirst, kLast);
   }
 }
 
@@ -357,58 +160,55 @@
   uint16_t seq_num = Rand();
 
   for (int i = 0; i < kMaxSize; ++i) {
-    //            seq_num    , kf, frst, lst
-    InsertGeneric(seq_num + i, kT, kT  , kT);
+    InsertPacket(seq_num + i, kKeyFrame, kFirst, kLast);
   }
 
   VCMPacket packet;
   packet.seqNum = seq_num + kMaxSize + 1;
-  packet.sizeBytes = 1;
   EXPECT_FALSE(packet_buffer_->InsertPacket(packet));
 }
 
-TEST_F(TestPacketBuffer, GenericOnePacketOneFrame) {
-  //            seq_num, kf, frst, lst
-  InsertGeneric(Rand() , kT, kT  , kT);
+TEST_F(TestPacketBuffer, OnePacketOneFrame) {
+  uint16_t seq_num = Rand();
+  InsertPacket(seq_num, kKeyFrame, kFirst, kLast);
   ASSERT_EQ(1UL, frames_from_callback_.size());
+  CheckFrame(seq_num);
 }
 
-TEST_F(TestPacketBuffer, GenericTwoPacketsTwoFrames) {
+TEST_F(TestPacketBuffer, TwoPacketsTwoFrames) {
   uint16_t seq_num = Rand();
 
-  //            seq_num    , kf, frst, lst
-  InsertGeneric(seq_num    , kT, kT  , kT);
-  InsertGeneric(seq_num + 1, kT, kT  , kT);
+  InsertPacket(seq_num, kKeyFrame, kFirst, kLast);
+  InsertPacket(seq_num + 1, kKeyFrame, kFirst, kLast);
 
   EXPECT_EQ(2UL, frames_from_callback_.size());
+  CheckFrame(seq_num);
+  CheckFrame(seq_num + 1);
 }
 
-TEST_F(TestPacketBuffer, GenericTwoPacketsOneFrames) {
+TEST_F(TestPacketBuffer, TwoPacketsOneFrames) {
   uint16_t seq_num = Rand();
 
-  //            seq_num    , kf, frst, lst
-  InsertGeneric(seq_num    , kT, kT  , kF);
-  InsertGeneric(seq_num + 1, kT, kF  , kT);
+  InsertPacket(seq_num, kKeyFrame, kFirst, kNotLast);
+  InsertPacket(seq_num + 1, kKeyFrame, kNotFirst, kLast);
 
   EXPECT_EQ(1UL, frames_from_callback_.size());
+  CheckFrame(seq_num);
 }
 
-TEST_F(TestPacketBuffer, GenericThreePacketReorderingOneFrame) {
+TEST_F(TestPacketBuffer, ThreePacketReorderingOneFrame) {
   uint16_t seq_num = Rand();
 
-  //            seq_num    , kf, frst, lst
-  InsertGeneric(seq_num    , kT, kT  , kF);
-  InsertGeneric(seq_num + 2, kT, kF  , kT);
-  InsertGeneric(seq_num + 1, kT, kF  , kF);
+  InsertPacket(seq_num, kKeyFrame, kFirst, kNotLast);
+  InsertPacket(seq_num + 2, kKeyFrame, kNotFirst, kLast);
+  InsertPacket(seq_num + 1, kKeyFrame, kNotFirst, kNotLast);
 
   EXPECT_EQ(1UL, frames_from_callback_.size());
+  CheckFrame(seq_num);
 }
 
 TEST_F(TestPacketBuffer, DiscardOldPacket) {
-  uint16_t seq_num = Rand();
   VCMPacket packet;
-  packet.dataPtr = dummy_data_.get();
-  packet.sizeBytes = kDummyDataSize;
   packet.seqNum = Rand();
   EXPECT_TRUE(packet_buffer_->InsertPacket(packet));
   packet.seqNum += 2;
@@ -421,15 +221,13 @@
 
   ++packet.seqNum;
   EXPECT_FALSE(packet_buffer_->InsertPacket(packet));
-  packet_buffer_->ClearTo(seq_num + 1);
+  packet_buffer_->ClearTo(packet.seqNum + 1);
   EXPECT_TRUE(packet_buffer_->InsertPacket(packet));
 }
 
 TEST_F(TestPacketBuffer, DiscardMultipleOldPackets) {
   uint16_t seq_num = Rand();
   VCMPacket packet;
-  packet.dataPtr = dummy_data_.get();
-  packet.sizeBytes = kDummyDataSize;
   packet.seqNum = seq_num;
   EXPECT_TRUE(packet_buffer_->InsertPacket(packet));
   packet.seqNum += 2;
@@ -451,36 +249,34 @@
   }
 }
 
-TEST_F(TestPacketBuffer, GenericFrames) {
+TEST_F(TestPacketBuffer, Frames) {
   uint16_t seq_num = Rand();
 
-  //            seq_num    , keyf , first, last
-  InsertGeneric(seq_num    , true , true , true);
-  InsertGeneric(seq_num + 1, false, true , true);
-  InsertGeneric(seq_num + 2, false, true , true);
-  InsertGeneric(seq_num + 3, false, true , true);
+  InsertPacket(seq_num, kKeyFrame, kFirst, kLast);
+  InsertPacket(seq_num + 1, kDeltaFrame, kFirst, kLast);
+  InsertPacket(seq_num + 2, kDeltaFrame, kFirst, kLast);
+  InsertPacket(seq_num + 3, kDeltaFrame, kFirst, kLast);
 
   ASSERT_EQ(4UL, frames_from_callback_.size());
-  CheckReferencesGeneric(seq_num);
-  CheckReferencesGeneric(seq_num + 1, seq_num);
-  CheckReferencesGeneric(seq_num + 2, seq_num + 1);
-  CheckReferencesGeneric(seq_num + 3, seq_num + 2);
+  CheckFrame(seq_num);
+  CheckFrame(seq_num + 1);
+  CheckFrame(seq_num + 2);
+  CheckFrame(seq_num + 3);
 }
 
-TEST_F(TestPacketBuffer, GenericFramesReordered) {
+TEST_F(TestPacketBuffer, FramesReordered) {
   uint16_t seq_num = Rand();
 
-  //            seq_num    , keyf , first, last
-  InsertGeneric(seq_num + 1, false, true , true);
-  InsertGeneric(seq_num    , true , true , true);
-  InsertGeneric(seq_num + 3, false, true , true);
-  InsertGeneric(seq_num + 2, false, true , true);
+  InsertPacket(seq_num + 1, kDeltaFrame, kFirst, kLast);
+  InsertPacket(seq_num, kKeyFrame, kFirst, kLast);
+  InsertPacket(seq_num + 3, kDeltaFrame, kFirst, kLast);
+  InsertPacket(seq_num + 2, kDeltaFrame, kFirst, kLast);
 
   ASSERT_EQ(4UL, frames_from_callback_.size());
-  CheckReferencesGeneric(seq_num);
-  CheckReferencesGeneric(seq_num + 1, seq_num);
-  CheckReferencesGeneric(seq_num + 2, seq_num + 1);
-  CheckReferencesGeneric(seq_num + 3, seq_num + 2);
+  CheckFrame(seq_num);
+  CheckFrame(seq_num + 1);
+  CheckFrame(seq_num + 2);
+  CheckFrame(seq_num + 3);
 }
 
 TEST_F(TestPacketBuffer, GetBitstreamFromFrame) {
@@ -495,63 +291,62 @@
 
   uint16_t seq_num = Rand();
 
-  //            seq_num    , kf, frst, lst, data_size        , data
-  InsertGeneric(seq_num    , kT, kT  , kF , sizeof(many)     , many);
-  InsertGeneric(seq_num + 1, kF, kF  , kF , sizeof(bitstream), bitstream);
-  InsertGeneric(seq_num + 2, kF, kF  , kF , sizeof(such)     , such);
-  InsertGeneric(seq_num + 3, kF, kF  , kT , sizeof(data)     , data);
+  InsertPacket(seq_num, kKeyFrame, kFirst, kNotLast, sizeof(many), many);
+  InsertPacket(seq_num + 1, kDeltaFrame, kNotFirst, kNotLast, sizeof(bitstream),
+               bitstream);
+  InsertPacket(seq_num + 2, kDeltaFrame, kNotFirst, kNotLast, sizeof(such),
+               such);
+  InsertPacket(seq_num + 3, kDeltaFrame, kNotFirst, kLast, sizeof(data), data);
 
   ASSERT_EQ(1UL, frames_from_callback_.size());
-  CheckReferencesVp8(seq_num + 3);
-  EXPECT_TRUE(frames_from_callback_[std::make_pair(seq_num + 3, 0)]->
-                                                          GetBitstream(result));
+  CheckFrame(seq_num);
+  EXPECT_TRUE(frames_from_callback_[seq_num]->GetBitstream(result));
   EXPECT_EQ(memcmp(result, "many bitstream, such data", sizeof(result)), 0);
 }
 
 TEST_F(TestPacketBuffer, FreeSlotsOnFrameDestruction) {
   uint16_t seq_num = Rand();
 
-  //            seq_num    , kf, frst, lst
-  InsertGeneric(seq_num    , kT, kT  , kF);
-  InsertGeneric(seq_num + 1, kF, kF  , kF);
-  InsertGeneric(seq_num + 2, kF, kF  , kT);
+  InsertPacket(seq_num, kKeyFrame, kFirst, kNotLast);
+  InsertPacket(seq_num + 1, kDeltaFrame, kNotFirst, kNotLast);
+  InsertPacket(seq_num + 2, kDeltaFrame, kNotFirst, kLast);
   EXPECT_EQ(1UL, frames_from_callback_.size());
+  CheckFrame(seq_num);
 
   frames_from_callback_.clear();
 
-  //            seq_num    , kf, frst, lst
-  InsertGeneric(seq_num    , kT, kT  , kF);
-  InsertGeneric(seq_num + 1, kF, kF  , kF);
-  InsertGeneric(seq_num + 2, kF, kF  , kT);
+  // Insert frame that fills the whole buffer.
+  InsertPacket(seq_num + 3, kKeyFrame, kFirst, kNotLast);
+  for (int i = 0; i < kMaxSize - 2; ++i)
+    InsertPacket(seq_num + i + 4, kDeltaFrame, kNotFirst, kNotLast);
+  InsertPacket(seq_num + kMaxSize + 2, kKeyFrame, kNotFirst, kLast);
   EXPECT_EQ(1UL, frames_from_callback_.size());
+  CheckFrame(seq_num + 3);
 }
 
 TEST_F(TestPacketBuffer, Clear) {
   uint16_t seq_num = Rand();
 
-  //            seq_num    , kf, frst, lst
-  InsertGeneric(seq_num    , kT, kT  , kF);
-  InsertGeneric(seq_num + 1, kF, kF  , kF);
-  InsertGeneric(seq_num + 2, kF, kF  , kT);
+  InsertPacket(seq_num, kKeyFrame, kFirst, kNotLast);
+  InsertPacket(seq_num + 1, kDeltaFrame, kNotFirst, kNotLast);
+  InsertPacket(seq_num + 2, kDeltaFrame, kNotFirst, kLast);
   EXPECT_EQ(1UL, frames_from_callback_.size());
+  CheckFrame(seq_num);
 
   packet_buffer_->Clear();
 
-  //            seq_num                 , kf, frst, lst
-  InsertGeneric(seq_num + kStartSize    , kT, kT  , kF);
-  InsertGeneric(seq_num + kStartSize + 1, kF, kF  , kF);
-  InsertGeneric(seq_num + kStartSize + 2, kF, kF  , kT);
+  InsertPacket(seq_num + kStartSize, kKeyFrame, kFirst, kNotLast);
+  InsertPacket(seq_num + kStartSize + 1, kDeltaFrame, kNotFirst, kNotLast);
+  InsertPacket(seq_num + kStartSize + 2, kDeltaFrame, kNotFirst, kLast);
   EXPECT_EQ(2UL, frames_from_callback_.size());
+  CheckFrame(seq_num + kStartSize);
 }
 
 TEST_F(TestPacketBuffer, InvalidateFrameByClearing) {
   VCMPacket packet;
-  packet.dataPtr = dummy_data_.get();
-  packet.sizeBytes = kDummyDataSize;
-  packet.codec = kVideoCodecGeneric;
   packet.frameType = kVideoFrameKey;
-  packet.isFirstPacket = kT;
-  packet.markerBit = kT;
+  packet.isFirstPacket = true;
+  packet.markerBit = true;
   packet.seqNum = Rand();
   EXPECT_TRUE(packet_buffer_->InsertPacket(packet));
   ASSERT_EQ(1UL, frames_from_callback_.size());
@@ -560,1051 +355,5 @@
   EXPECT_FALSE(frames_from_callback_.begin()->second->GetBitstream(nullptr));
 }
 
-TEST_F(TestPacketBuffer, PaddingPackets) {
-  uint16_t seq_num = Rand();
-
-  //            seq_num    , kf, frst, lst
-  InsertGeneric(seq_num    , kT, kT  , kT);
-  InsertGeneric(seq_num + 1, kF, kF  , kF, 0, nullptr);
-  InsertGeneric(seq_num + 3, kF, kT  , kT);
-  EXPECT_EQ(1UL, frames_from_callback_.size());
-  InsertGeneric(seq_num + 2, kF, kF  , kF, 0, nullptr);
-  EXPECT_EQ(2UL, frames_from_callback_.size());
-}
-
-TEST_F(TestPacketBuffer, PaddingPacketsReordered) {
-  uint16_t seq_num = Rand();
-
-  //            seq_num    , kf, frst, lst
-  InsertGeneric(seq_num    , kT, kT  , kT);
-  InsertGeneric(seq_num + 1, kF, kF  , kF, 0, nullptr);
-  InsertGeneric(seq_num + 2, kF, kT  , kF);
-  InsertGeneric(seq_num + 4, kF, kF  , kF, 0, nullptr);
-  InsertGeneric(seq_num + 3, kF, kF  , kT);
-  EXPECT_EQ(2UL, frames_from_callback_.size());
-  CheckReferencesGeneric(seq_num);
-  CheckReferencesGeneric(seq_num + 3, seq_num);
-}
-
-TEST_F(TestPacketBuffer, PaddingPacketsReorderedMultipleKeyframes) {
-  uint16_t seq_num = Rand();
-
-  //            seq_num    , kf, frst, lst
-  InsertGeneric(seq_num    , kT, kT  , kT);
-  InsertGeneric(seq_num + 2, kF, kT  , kF);
-  InsertGeneric(seq_num + 1, kF, kF  , kF, 0, nullptr);
-  InsertGeneric(seq_num + 4, kF, kF  , kF, 0, nullptr);
-  InsertGeneric(seq_num + 5, kT, kT  , kT);
-  InsertGeneric(seq_num + 3, kF, kF  , kT);
-  InsertGeneric(seq_num + 6, kF, kF  , kF, 0, nullptr);
-  InsertGeneric(seq_num + 9, kF, kF  , kF, 0, nullptr);
-  InsertGeneric(seq_num + 8, kF, kF  , kT);
-  InsertGeneric(seq_num + 7, kF, kT  , kF);
-  EXPECT_EQ(4UL, frames_from_callback_.size());
-}
-
-TEST_F(TestPacketBuffer, Vp8NoPictureId) {
-  uint16_t seq_num = Rand();
-
-  //        seq_num     , kf, frst, lst
-  InsertVp8(seq_num     , kT, kT  , kF);
-  InsertVp8(seq_num + 1 , kF, kF  , kF);
-  InsertVp8(seq_num + 2 , kF, kF  , kT);
-  ASSERT_EQ(1UL, frames_from_callback_.size());
-
-  InsertVp8(seq_num + 3 , kF, kT  , kF);
-  InsertVp8(seq_num + 4 , kF, kF  , kT);
-  ASSERT_EQ(2UL, frames_from_callback_.size());
-
-  InsertVp8(seq_num + 5 , kF, kT  , kF);
-  InsertVp8(seq_num + 6 , kF, kF  , kF);
-  InsertVp8(seq_num + 7 , kF, kF  , kF);
-  InsertVp8(seq_num + 8 , kF, kF  , kT);
-  ASSERT_EQ(3UL, frames_from_callback_.size());
-
-  InsertVp8(seq_num + 9 , kF, kT  , kT);
-  ASSERT_EQ(4UL, frames_from_callback_.size());
-
-  InsertVp8(seq_num + 10, kF, kT  , kF);
-  InsertVp8(seq_num + 11, kF, kF  , kT);
-  ASSERT_EQ(5UL, frames_from_callback_.size());
-
-  InsertVp8(seq_num + 12, kT, kT  , kT);
-  ASSERT_EQ(6UL, frames_from_callback_.size());
-
-  InsertVp8(seq_num + 13, kF, kT  , kF);
-  InsertVp8(seq_num + 14, kF, kF  , kF);
-  InsertVp8(seq_num + 15, kF, kF  , kF);
-  InsertVp8(seq_num + 16, kF, kF  , kF);
-  InsertVp8(seq_num + 17, kF, kF  , kT);
-  ASSERT_EQ(7UL, frames_from_callback_.size());
-
-  InsertVp8(seq_num + 18, kF, kT  , kT);
-  ASSERT_EQ(8UL, frames_from_callback_.size());
-
-  InsertVp8(seq_num + 19, kF, kT  , kF);
-  InsertVp8(seq_num + 20, kF, kF  , kT);
-  ASSERT_EQ(9UL, frames_from_callback_.size());
-
-  InsertVp8(seq_num + 21, kF, kT  , kT);
-
-  ASSERT_EQ(10UL, frames_from_callback_.size());
-  CheckReferencesVp8(seq_num + 2);
-  CheckReferencesVp8(seq_num + 4, seq_num + 2);
-  CheckReferencesVp8(seq_num + 8, seq_num + 4);
-  CheckReferencesVp8(seq_num + 9, seq_num + 8);
-  CheckReferencesVp8(seq_num + 11, seq_num + 9);
-  CheckReferencesVp8(seq_num + 12);
-  CheckReferencesVp8(seq_num + 17, seq_num + 12);
-  CheckReferencesVp8(seq_num + 18, seq_num + 17);
-  CheckReferencesVp8(seq_num + 20, seq_num + 18);
-  CheckReferencesVp8(seq_num + 21, seq_num + 20);
-}
-
-TEST_F(TestPacketBuffer, Vp8NoPictureIdReordered) {
-  uint16_t seq_num = 0xfffa;
-
-  //        seq_num     , kf, frst, lst
-  InsertVp8(seq_num + 1 , kF, kF  , kF);
-  InsertVp8(seq_num     , kT, kT  , kF);
-  InsertVp8(seq_num + 2 , kF, kF  , kT);
-  InsertVp8(seq_num + 4 , kF, kF  , kT);
-  InsertVp8(seq_num + 6 , kF, kF  , kF);
-  InsertVp8(seq_num + 3 , kF, kT  , kF);
-  InsertVp8(seq_num + 7 , kF, kF  , kF);
-  InsertVp8(seq_num + 5 , kF, kT  , kF);
-  InsertVp8(seq_num + 9 , kF, kT  , kT);
-  InsertVp8(seq_num + 10, kF, kT  , kF);
-  InsertVp8(seq_num + 8 , kF, kF  , kT);
-  InsertVp8(seq_num + 13, kF, kT  , kF);
-  InsertVp8(seq_num + 14, kF, kF  , kF);
-  InsertVp8(seq_num + 12, kT, kT  , kT);
-  InsertVp8(seq_num + 11, kF, kF  , kT);
-  InsertVp8(seq_num + 16, kF, kF  , kF);
-  InsertVp8(seq_num + 19, kF, kT  , kF);
-  InsertVp8(seq_num + 15, kF, kF  , kF);
-  InsertVp8(seq_num + 17, kF, kF  , kT);
-  InsertVp8(seq_num + 20, kF, kF  , kT);
-  InsertVp8(seq_num + 21, kF, kT  , kT);
-  InsertVp8(seq_num + 18, kF, kT  , kT);
-
-  ASSERT_EQ(10UL, frames_from_callback_.size());
-  CheckReferencesVp8(seq_num + 2);
-  CheckReferencesVp8(seq_num + 4, seq_num + 2);
-  CheckReferencesVp8(seq_num + 8, seq_num + 4);
-  CheckReferencesVp8(seq_num + 9, seq_num + 8);
-  CheckReferencesVp8(seq_num + 11, seq_num + 9);
-  CheckReferencesVp8(seq_num + 12);
-  CheckReferencesVp8(seq_num + 17, seq_num + 12);
-  CheckReferencesVp8(seq_num + 18, seq_num + 17);
-  CheckReferencesVp8(seq_num + 20, seq_num + 18);
-  CheckReferencesVp8(seq_num + 21, seq_num + 20);
-}
-
-
-TEST_F(TestPacketBuffer, Vp8KeyFrameReferences) {
-  uint16_t pid = Rand();
-  //        seq_num, kf, frst, lst, sync, pid, tid, tl0
-  InsertVp8(Rand() , kT, kT  , kT , kF  , pid, 0  , 0);
-
-  ASSERT_EQ(1UL, frames_from_callback_.size());
-  CheckReferencesVp8(pid);
-}
-
-// Test with 1 temporal layer.
-TEST_F(TestPacketBuffer, Vp8TemporalLayers_0) {
-  uint16_t pid = Rand();
-  uint16_t seq_num = Rand();
-
-  //        seq_num    , kf, frst, lst, sync, pid    , tid, tl0
-  InsertVp8(seq_num    , kT, kT  , kT , kF  , pid    , 0  , 1);
-  InsertVp8(seq_num + 1, kF, kT  , kT , kF  , pid + 1, 0  , 2);
-  InsertVp8(seq_num + 2, kF, kT  , kT , kF  , pid + 2, 0  , 3);
-  InsertVp8(seq_num + 3, kF, kT  , kT , kF  , pid + 3, 0  , 4);
-
-  ASSERT_EQ(4UL, frames_from_callback_.size());
-  CheckReferencesVp8(pid);
-  CheckReferencesVp8(pid + 1, pid);
-  CheckReferencesVp8(pid + 2, pid + 1);
-  CheckReferencesVp8(pid + 3, pid + 2);
-}
-
-// Test with 1 temporal layer.
-TEST_F(TestPacketBuffer, Vp8TemporalLayersReordering_0) {
-  uint16_t pid = Rand();
-  uint16_t seq_num = Rand();
-
-  //        seq_num    , kf, frst, lst, sync, pid    , tid, tl0
-  InsertVp8(seq_num    , kT, kT  , kT , kF  , pid    , 0  , 1);
-  InsertVp8(seq_num + 1, kF, kT  , kT , kF  , pid + 1, 0  , 2);
-  InsertVp8(seq_num + 3, kF, kT  , kT , kF  , pid + 3, 0  , 4);
-  InsertVp8(seq_num + 2, kF, kT  , kT , kF  , pid + 2, 0  , 3);
-  InsertVp8(seq_num + 5, kF, kT  , kT , kF  , pid + 5, 0  , 6);
-  InsertVp8(seq_num + 6, kF, kT  , kT , kF  , pid + 6, 0  , 7);
-  InsertVp8(seq_num + 4, kF, kT  , kT , kF  , pid + 4, 0  , 5);
-
-  ASSERT_EQ(7UL, frames_from_callback_.size());
-  CheckReferencesVp8(pid);
-  CheckReferencesVp8(pid + 1, pid);
-  CheckReferencesVp8(pid + 2, pid + 1);
-  CheckReferencesVp8(pid + 3, pid + 2);
-  CheckReferencesVp8(pid + 4, pid + 3);
-  CheckReferencesVp8(pid + 5, pid + 4);
-  CheckReferencesVp8(pid + 6, pid + 5);
-}
-
-// Test with 2 temporal layers in a 01 pattern.
-TEST_F(TestPacketBuffer, Vp8TemporalLayers_01) {
-  uint16_t pid = Rand();
-  uint16_t seq_num = Rand();
-
-  //        seq_num    , kf, frst, lst, sync, pid    , tid, tl0
-  InsertVp8(seq_num    , kT, kT  , kT , kF  , pid    , 0, 255);
-  InsertVp8(seq_num + 1, kF, kT  , kT , kT  , pid + 1, 1, 255);
-  InsertVp8(seq_num + 2, kF, kT  , kT , kF  , pid + 2, 0, 0);
-  InsertVp8(seq_num + 3, kF, kT  , kT , kF  , pid + 3, 1, 0);
-
-  ASSERT_EQ(4UL, frames_from_callback_.size());
-  CheckReferencesVp8(pid);
-  CheckReferencesVp8(pid + 1, pid);
-  CheckReferencesVp8(pid + 2, pid);
-  CheckReferencesVp8(pid + 3, pid + 1, pid + 2);
-}
-
-// Test with 2 temporal layers in a 01 pattern.
-TEST_F(TestPacketBuffer, Vp8TemporalLayersReordering_01) {
-  uint16_t pid = Rand();
-  uint16_t seq_num = Rand();
-
-  //        seq_num    , kf, frst, lst, sync, pid    , tid, tl0
-  InsertVp8(seq_num + 1, kF, kT  , kT , kT  , pid + 1, 1  , 255);
-  InsertVp8(seq_num    , kT, kT  , kT , kF  , pid    , 0  , 255);
-  InsertVp8(seq_num + 3, kF, kT  , kT , kF  , pid + 3, 1  , 0);
-  InsertVp8(seq_num + 5, kF, kT  , kT , kF  , pid + 5, 1  , 1);
-  InsertVp8(seq_num + 2, kF, kT  , kT , kF  , pid + 2, 0  , 0);
-  InsertVp8(seq_num + 4, kF, kT  , kT , kF  , pid + 4, 0  , 1);
-  InsertVp8(seq_num + 6, kF, kT  , kT , kF  , pid + 6, 0  , 2);
-  InsertVp8(seq_num + 7, kF, kT  , kT , kF  , pid + 7, 1  , 2);
-
-  ASSERT_EQ(8UL, frames_from_callback_.size());
-  CheckReferencesVp8(pid);
-  CheckReferencesVp8(pid + 1, pid);
-  CheckReferencesVp8(pid + 2, pid);
-  CheckReferencesVp8(pid + 3, pid + 1, pid + 2);
-  CheckReferencesVp8(pid + 4, pid + 2);
-  CheckReferencesVp8(pid + 5, pid + 3, pid + 4);
-  CheckReferencesVp8(pid + 6, pid + 4);
-  CheckReferencesVp8(pid + 7, pid + 5, pid + 6);
-}
-
-// Test with 3 temporal layers in a 0212 pattern.
-TEST_F(TestPacketBuffer, Vp8TemporalLayers_0212) {
-  uint16_t pid = Rand();
-  uint16_t seq_num = Rand();
-
-  //        seq_num     , kf, frst, lst, sync, pid     , tid, tl0
-  InsertVp8(seq_num     , kT, kT  , kT , kF  , pid     , 0  , 55);
-  InsertVp8(seq_num + 1 , kF, kT  , kT , kT  , pid + 1 , 2  , 55);
-  InsertVp8(seq_num + 2 , kF, kT  , kT , kT  , pid + 2 , 1  , 55);
-  InsertVp8(seq_num + 3 , kF, kT  , kT , kF  , pid + 3 , 2  , 55);
-  InsertVp8(seq_num + 4 , kF, kT  , kT , kF  , pid + 4 , 0  , 56);
-  InsertVp8(seq_num + 5 , kF, kT  , kT , kF  , pid + 5 , 2  , 56);
-  InsertVp8(seq_num + 6 , kF, kT  , kT , kF  , pid + 6 , 1  , 56);
-  InsertVp8(seq_num + 7 , kF, kT  , kT , kF  , pid + 7 , 2  , 56);
-  InsertVp8(seq_num + 8 , kF, kT  , kT , kF  , pid + 8 , 0  , 57);
-  InsertVp8(seq_num + 9 , kF, kT  , kT , kT  , pid + 9 , 2  , 57);
-  InsertVp8(seq_num + 10, kF, kT  , kT , kT  , pid + 10, 1  , 57);
-  InsertVp8(seq_num + 11, kF, kT  , kT , kF  , pid + 11, 2  , 57);
-
-  ASSERT_EQ(12UL, frames_from_callback_.size());
-  CheckReferencesVp8(pid);
-  CheckReferencesVp8(pid + 1 , pid);
-  CheckReferencesVp8(pid + 2 , pid);
-  CheckReferencesVp8(pid + 3 , pid, pid + 1, pid + 2);
-  CheckReferencesVp8(pid + 4 , pid);
-  CheckReferencesVp8(pid + 5 , pid + 2, pid + 3, pid + 4);
-  CheckReferencesVp8(pid + 6 , pid + 2, pid + 4);
-  CheckReferencesVp8(pid + 7 , pid + 4, pid + 5, pid + 6);
-  CheckReferencesVp8(pid + 8 , pid + 4);
-  CheckReferencesVp8(pid + 9 , pid + 8);
-  CheckReferencesVp8(pid + 10, pid + 8);
-  CheckReferencesVp8(pid + 11, pid + 8, pid + 9, pid + 10);
-}
-
-// Test with 3 temporal layers in a 0212 pattern.
-TEST_F(TestPacketBuffer, Vp8TemporalLayersReordering_0212) {
-  uint16_t pid = 126;
-  uint16_t seq_num = Rand();
-
-  //        seq_num     , kf, frst, lst, sync, pid     , tid, tl0
-  InsertVp8(seq_num + 1 , kF, kT  , kT , kT  , pid + 1 , 2  , 55);
-  InsertVp8(seq_num     , kT, kT  , kT , kF  , pid     , 0  , 55);
-  InsertVp8(seq_num + 2 , kF, kT  , kT , kT  , pid + 2 , 1  , 55);
-  InsertVp8(seq_num + 4 , kF, kT  , kT , kF  , pid + 4 , 0  , 56);
-  InsertVp8(seq_num + 5 , kF, kT  , kT , kF  , pid + 5 , 2  , 56);
-  InsertVp8(seq_num + 3 , kF, kT  , kT , kF  , pid + 3 , 2  , 55);
-  InsertVp8(seq_num + 7 , kF, kT  , kT , kF  , pid + 7 , 2  , 56);
-  InsertVp8(seq_num + 9 , kF, kT  , kT , kT  , pid + 9 , 2  , 57);
-  InsertVp8(seq_num + 6 , kF, kT  , kT , kF  , pid + 6 , 1  , 56);
-  InsertVp8(seq_num + 8 , kF, kT  , kT , kF  , pid + 8 , 0  , 57);
-  InsertVp8(seq_num + 11, kF, kT  , kT , kF  , pid + 11, 2  , 57);
-  InsertVp8(seq_num + 10, kF, kT  , kT , kT  , pid + 10, 1  , 57);
-
-  ASSERT_EQ(12UL, frames_from_callback_.size());
-  CheckReferencesVp8(pid);
-  CheckReferencesVp8(pid + 1 , pid);
-  CheckReferencesVp8(pid + 2 , pid);
-  CheckReferencesVp8(pid + 3 , pid, pid + 1, pid + 2);
-  CheckReferencesVp8(pid + 4 , pid);
-  CheckReferencesVp8(pid + 5 , pid + 2, pid + 3, pid + 4);
-  CheckReferencesVp8(pid + 6 , pid + 2, pid + 4);
-  CheckReferencesVp8(pid + 7 , pid + 4, pid + 5, pid + 6);
-  CheckReferencesVp8(pid + 8 , pid + 4);
-  CheckReferencesVp8(pid + 9 , pid + 8);
-  CheckReferencesVp8(pid + 10, pid + 8);
-  CheckReferencesVp8(pid + 11, pid + 8, pid + 9, pid + 10);
-}
-
-TEST_F(TestPacketBuffer, Vp8InsertManyFrames_0212) {
-  uint16_t pid = Rand();
-  uint16_t seq_num = Rand();
-
-  const int keyframes_to_insert = 50;
-  const int frames_per_keyframe = 120;  // Should be a multiple of 4.
-  uint8_t tl0 = 128;
-
-  for (int k = 0; k < keyframes_to_insert; ++k) {
-    //        seq_num    , keyf, frst, lst, sync, pid    , tid, tl0
-    InsertVp8(seq_num    , kT  , kT  , kT , kF  , pid    , 0  , tl0);
-    InsertVp8(seq_num + 1, kF  , kT  , kT , kT  , pid + 1, 2  , tl0);
-    InsertVp8(seq_num + 2, kF  , kT  , kT , kT  , pid + 2, 1  , tl0);
-    InsertVp8(seq_num + 3, kF  , kT  , kT , kF  , pid + 3, 2  , tl0);
-    CheckReferencesVp8(pid);
-    CheckReferencesVp8(pid + 1, pid);
-    CheckReferencesVp8(pid + 2, pid);
-    CheckReferencesVp8(pid + 3, pid, pid + 1, pid + 2);
-    frames_from_callback_.clear();
-    ++tl0;
-
-    for (int f = 4; f < frames_per_keyframe; f += 4) {
-      uint16_t sf = seq_num + f;
-      uint16_t pidf = pid + f;
-
-      //        seq_num, keyf, frst, lst, sync, pid     , tid, tl0
-      InsertVp8(sf     , kF  , kT  , kT , kF  , pidf    , 0  , tl0);
-      InsertVp8(sf + 1 , kF  , kT  , kT , kF  , pidf + 1, 2  , tl0);
-      InsertVp8(sf + 2 , kF  , kT  , kT , kF  , pidf + 2, 1  , tl0);
-      InsertVp8(sf + 3 , kF  , kT  , kT , kF  , pidf + 3, 2  , tl0);
-      CheckReferencesVp8(pidf, pidf - 4);
-      CheckReferencesVp8(pidf + 1, pidf, pidf - 1, pidf - 2);
-      CheckReferencesVp8(pidf + 2, pidf, pidf - 2);
-      CheckReferencesVp8(pidf + 3, pidf, pidf + 1, pidf + 2);
-      frames_from_callback_.clear();
-      ++tl0;
-    }
-
-    pid += frames_per_keyframe;
-    seq_num += frames_per_keyframe;
-  }
-}
-
-TEST_F(TestPacketBuffer, Vp8LayerSync) {
-  uint16_t pid = Rand();
-  uint16_t seq_num = Rand();
-
-  //        seq_num     , keyf, frst, lst, sync, pid     , tid, tl0
-  InsertVp8(seq_num     , kT  , kT  , kT , kF  , pid     , 0  , 0);
-  InsertVp8(seq_num + 1 , kF  , kT  , kT , kT  , pid + 1 , 1  , 0);
-  InsertVp8(seq_num + 2 , kF  , kT  , kT , kF  , pid + 2 , 0  , 1);
-  ASSERT_EQ(3UL, frames_from_callback_.size());
-
-  InsertVp8(seq_num + 4 , kF  , kT  , kT , kF  , pid + 4 , 0  , 2);
-  InsertVp8(seq_num + 5 , kF  , kT  , kT , kT  , pid + 5 , 1  , 2);
-  InsertVp8(seq_num + 6 , kF  , kT  , kT , kF  , pid + 6 , 0  , 3);
-  InsertVp8(seq_num + 7 , kF  , kT  , kT , kF  , pid + 7 , 1  , 3);
-
-  ASSERT_EQ(7UL, frames_from_callback_.size());
-  CheckReferencesVp8(pid);
-  CheckReferencesVp8(pid + 1, pid);
-  CheckReferencesVp8(pid + 2, pid);
-  CheckReferencesVp8(pid + 4, pid + 2);
-  CheckReferencesVp8(pid + 5, pid + 4);
-  CheckReferencesVp8(pid + 6, pid + 4);
-  CheckReferencesVp8(pid + 7, pid + 6, pid + 5);
-}
-
-TEST_F(TestPacketBuffer, Vp8InsertLargeFrames) {
-  packet_buffer_.reset(new PacketBuffer(clock_.get(), 1 << 3, 1 << 12, this));
-  uint16_t pid = Rand();
-  uint16_t seq_num = Rand();
-
-  const uint16_t packets_per_frame = 1000;
-  uint16_t current = seq_num;
-  uint16_t end = current + packets_per_frame;
-
-  //        seq_num  , keyf, frst, lst, sync, pid, tid, tl0
-  InsertVp8(current++, kT  , kT  , kF , kF  , pid, 0  , 0);
-  while (current != end)
-    InsertVp8(current++, kF  , kF  , kF , kF  , pid, 0  , 0);
-  InsertVp8(current++, kF  , kF  , kT , kF  , pid, 0  , 0);
-  end = current + packets_per_frame;
-
-  for (int f = 1; f < 4; ++f) {
-    InsertVp8(current++, kF  , kT  , kF , kF  , pid + f, 0, f);
-    while (current != end)
-      InsertVp8(current++, kF  , kF  , kF , kF  , pid + f, 0, f);
-    InsertVp8(current++, kF  , kF  , kT , kF  , pid + f, 0, f);
-    end = current + packets_per_frame;
-  }
-
-  ASSERT_EQ(4UL, frames_from_callback_.size());
-  CheckReferencesVp8(pid);
-  CheckReferencesVp8(pid + 1, pid);
-  CheckReferencesVp8(pid + 2, pid + 1);
-  CheckReferencesVp8(pid + 3, pid + 2);
-}
-
-TEST_F(TestPacketBuffer, Vp9GofInsertOneFrame) {
-  uint16_t pid = Rand();
-  uint16_t seq_num = Rand();
-  GofInfoVP9 ss;
-  ss.SetGofInfoVP9(kTemporalStructureMode1);
-
-  //           seq_num, keyf, frst, lst, up, pid, sid, tid, tl0, ss
-  InsertVp9Gof(seq_num, kT  , kT  , kT , kF, pid, 0  , 0  , 0  , &ss);
-
-  CheckReferencesVp9(pid, 0);
-}
-
-TEST_F(TestPacketBuffer, Vp9NoPictureIdReordered) {
-  uint16_t sn = 0xfffa;
-
-  //           sn     , kf, frst, lst
-  InsertVp9Gof(sn + 1 , kF, kF  , kF);
-  InsertVp9Gof(sn     , kT, kT  , kF);
-  InsertVp9Gof(sn + 2 , kF, kF  , kT);
-  InsertVp9Gof(sn + 4 , kF, kF  , kT);
-  InsertVp9Gof(sn + 6 , kF, kF  , kF);
-  InsertVp9Gof(sn + 3 , kF, kT  , kF);
-  InsertVp9Gof(sn + 7 , kF, kF  , kF);
-  InsertVp9Gof(sn + 5 , kF, kT  , kF);
-  InsertVp9Gof(sn + 9 , kF, kT  , kT);
-  InsertVp9Gof(sn + 10, kF, kT  , kF);
-  InsertVp9Gof(sn + 8 , kF, kF  , kT);
-  InsertVp9Gof(sn + 13, kF, kT  , kF);
-  InsertVp9Gof(sn + 14, kF, kF  , kF);
-  InsertVp9Gof(sn + 12, kT, kT  , kT);
-  InsertVp9Gof(sn + 11, kF, kF  , kT);
-  InsertVp9Gof(sn + 16, kF, kF  , kF);
-  InsertVp9Gof(sn + 19, kF, kT  , kF);
-  InsertVp9Gof(sn + 15, kF, kF  , kF);
-  InsertVp9Gof(sn + 17, kF, kF  , kT);
-  InsertVp9Gof(sn + 20, kF, kF  , kT);
-  InsertVp9Gof(sn + 21, kF, kT  , kT);
-  InsertVp9Gof(sn + 18, kF, kT  , kT);
-
-  ASSERT_EQ(10UL, frames_from_callback_.size());
-  CheckReferencesVp9(sn + 2 , 0);
-  CheckReferencesVp9(sn + 4 , 0, sn + 2);
-  CheckReferencesVp9(sn + 8 , 0, sn + 4);
-  CheckReferencesVp9(sn + 9 , 0, sn + 8);
-  CheckReferencesVp9(sn + 11, 0, sn + 9);
-  CheckReferencesVp9(sn + 12, 0);
-  CheckReferencesVp9(sn + 17, 0, sn + 12);
-  CheckReferencesVp9(sn + 18, 0, sn + 17);
-  CheckReferencesVp9(sn + 20, 0, sn + 18);
-  CheckReferencesVp9(sn + 21, 0, sn + 20);
-}
-
-TEST_F(TestPacketBuffer, Vp9GofTemporalLayers_0) {
-  uint16_t pid = Rand();
-  uint16_t sn = Rand();
-  GofInfoVP9 ss;
-  ss.SetGofInfoVP9(kTemporalStructureMode1);  // Only 1 spatial layer.
-
-  //           sn     , kf, frst, lst, up, pid     , sid, tid, tl0, ss
-  InsertVp9Gof(sn     , kT, kT  , kT , kF, pid     , 0  , 0  , 0  , &ss);
-  InsertVp9Gof(sn + 1 , kF, kT  , kT , kF, pid + 1 , 0  , 0  , 1);
-  InsertVp9Gof(sn + 2 , kF, kT  , kT , kF, pid + 2 , 0  , 0  , 2);
-  InsertVp9Gof(sn + 3 , kF, kT  , kT , kF, pid + 3 , 0  , 0  , 3);
-  InsertVp9Gof(sn + 4 , kF, kT  , kT , kF, pid + 4 , 0  , 0  , 4);
-  InsertVp9Gof(sn + 5 , kF, kT  , kT , kF, pid + 5 , 0  , 0  , 5);
-  InsertVp9Gof(sn + 6 , kF, kT  , kT , kF, pid + 6 , 0  , 0  , 6);
-  InsertVp9Gof(sn + 7 , kF, kT  , kT , kF, pid + 7 , 0  , 0  , 7);
-  InsertVp9Gof(sn + 8 , kF, kT  , kT , kF, pid + 8 , 0  , 0  , 8);
-  InsertVp9Gof(sn + 9 , kF, kT  , kT , kF, pid + 9 , 0  , 0  , 9);
-  InsertVp9Gof(sn + 10, kF, kT  , kT , kF, pid + 10, 0  , 0  , 10);
-  InsertVp9Gof(sn + 11, kF, kT  , kT , kF, pid + 11, 0  , 0  , 11);
-  InsertVp9Gof(sn + 12, kF, kT  , kT , kF, pid + 12, 0  , 0  , 12);
-  InsertVp9Gof(sn + 13, kF, kT  , kT , kF, pid + 13, 0  , 0  , 13);
-  InsertVp9Gof(sn + 14, kF, kT  , kT , kF, pid + 14, 0  , 0  , 14);
-  InsertVp9Gof(sn + 15, kF, kT  , kT , kF, pid + 15, 0  , 0  , 15);
-  InsertVp9Gof(sn + 16, kF, kT  , kT , kF, pid + 16, 0  , 0  , 16);
-  InsertVp9Gof(sn + 17, kF, kT  , kT , kF, pid + 17, 0  , 0  , 17);
-  InsertVp9Gof(sn + 18, kF, kT  , kT , kF, pid + 18, 0  , 0  , 18);
-  InsertVp9Gof(sn + 19, kF, kT  , kT , kF, pid + 19, 0  , 0  , 19);
-
-  ASSERT_EQ(20UL, frames_from_callback_.size());
-  CheckReferencesVp9(pid, 0);
-  CheckReferencesVp9(pid + 1 , 0, pid);
-  CheckReferencesVp9(pid + 2 , 0, pid + 1);
-  CheckReferencesVp9(pid + 3 , 0, pid + 2);
-  CheckReferencesVp9(pid + 4 , 0, pid + 3);
-  CheckReferencesVp9(pid + 5 , 0, pid + 4);
-  CheckReferencesVp9(pid + 6 , 0, pid + 5);
-  CheckReferencesVp9(pid + 7 , 0, pid + 6);
-  CheckReferencesVp9(pid + 8 , 0, pid + 7);
-  CheckReferencesVp9(pid + 9 , 0, pid + 8);
-  CheckReferencesVp9(pid + 10, 0, pid + 9);
-  CheckReferencesVp9(pid + 11, 0, pid + 10);
-  CheckReferencesVp9(pid + 12, 0, pid + 11);
-  CheckReferencesVp9(pid + 13, 0, pid + 12);
-  CheckReferencesVp9(pid + 14, 0, pid + 13);
-  CheckReferencesVp9(pid + 15, 0, pid + 14);
-  CheckReferencesVp9(pid + 16, 0, pid + 15);
-  CheckReferencesVp9(pid + 17, 0, pid + 16);
-  CheckReferencesVp9(pid + 18, 0, pid + 17);
-  CheckReferencesVp9(pid + 19, 0, pid + 18);
-}
-
-TEST_F(TestPacketBuffer, Vp9GofTemporalLayersReordered_0) {
-  uint16_t pid = Rand();
-  uint16_t sn = Rand();
-  GofInfoVP9 ss;
-  ss.SetGofInfoVP9(kTemporalStructureMode1);  // Only 1 spatial layer.
-
-  //           sn     , kf, frst, lst, up, pid     , sid, tid, tl0, ss
-  InsertVp9Gof(sn + 2 , kF, kT  , kT , kF, pid + 2 , 0  , 0  , 2);
-  InsertVp9Gof(sn + 1 , kF, kT  , kT , kF, pid + 1 , 0  , 0  , 1);
-  InsertVp9Gof(sn     , kT, kT  , kT , kF, pid     , 0  , 0  , 0  , &ss);
-  InsertVp9Gof(sn + 4 , kF, kT  , kT , kF, pid + 4 , 0  , 0  , 4);
-  InsertVp9Gof(sn + 3 , kF, kT  , kT , kF, pid + 3 , 0  , 0  , 3);
-  InsertVp9Gof(sn + 5 , kF, kT  , kT , kF, pid + 5 , 0  , 0  , 5);
-  InsertVp9Gof(sn + 7 , kF, kT  , kT , kF, pid + 7 , 0  , 0  , 7);
-  InsertVp9Gof(sn + 6 , kF, kT  , kT , kF, pid + 6 , 0  , 0  , 6);
-  InsertVp9Gof(sn + 8 , kF, kT  , kT , kF, pid + 8 , 0  , 0  , 8);
-  InsertVp9Gof(sn + 10, kF, kT  , kT , kF, pid + 10, 0  , 0  , 10);
-  InsertVp9Gof(sn + 13, kF, kT  , kT , kF, pid + 13, 0  , 0  , 13);
-  InsertVp9Gof(sn + 11, kF, kT  , kT , kF, pid + 11, 0  , 0  , 11);
-  InsertVp9Gof(sn + 9 , kF, kT  , kT , kF, pid + 9 , 0  , 0  , 9);
-  InsertVp9Gof(sn + 16, kF, kT  , kT , kF, pid + 16, 0  , 0  , 16);
-  InsertVp9Gof(sn + 14, kF, kT  , kT , kF, pid + 14, 0  , 0  , 14);
-  InsertVp9Gof(sn + 15, kF, kT  , kT , kF, pid + 15, 0  , 0  , 15);
-  InsertVp9Gof(sn + 12, kF, kT  , kT , kF, pid + 12, 0  , 0  , 12);
-  InsertVp9Gof(sn + 17, kF, kT  , kT , kF, pid + 17, 0  , 0  , 17);
-  InsertVp9Gof(sn + 19, kF, kT  , kT , kF, pid + 19, 0  , 0  , 19);
-  InsertVp9Gof(sn + 18, kF, kT  , kT , kF, pid + 18, 0  , 0  , 18);
-
-  ASSERT_EQ(20UL, frames_from_callback_.size());
-  CheckReferencesVp9(pid, 0);
-  CheckReferencesVp9(pid + 1 , 0, pid);
-  CheckReferencesVp9(pid + 2 , 0, pid + 1);
-  CheckReferencesVp9(pid + 3 , 0, pid + 2);
-  CheckReferencesVp9(pid + 4 , 0, pid + 3);
-  CheckReferencesVp9(pid + 5 , 0, pid + 4);
-  CheckReferencesVp9(pid + 6 , 0, pid + 5);
-  CheckReferencesVp9(pid + 7 , 0, pid + 6);
-  CheckReferencesVp9(pid + 8 , 0, pid + 7);
-  CheckReferencesVp9(pid + 9 , 0, pid + 8);
-  CheckReferencesVp9(pid + 10, 0, pid + 9);
-  CheckReferencesVp9(pid + 11, 0, pid + 10);
-  CheckReferencesVp9(pid + 12, 0, pid + 11);
-  CheckReferencesVp9(pid + 13, 0, pid + 12);
-  CheckReferencesVp9(pid + 14, 0, pid + 13);
-  CheckReferencesVp9(pid + 15, 0, pid + 14);
-  CheckReferencesVp9(pid + 16, 0, pid + 15);
-  CheckReferencesVp9(pid + 17, 0, pid + 16);
-  CheckReferencesVp9(pid + 18, 0, pid + 17);
-  CheckReferencesVp9(pid + 19, 0, pid + 18);
-}
-
-TEST_F(TestPacketBuffer, Vp9GofSkipFramesTemporalLayers_01) {
-  uint16_t pid = Rand();
-  uint16_t sn = Rand();
-  GofInfoVP9 ss;
-  ss.SetGofInfoVP9(kTemporalStructureMode2);  // 0101 pattern
-
-  //           sn     , kf, frst, lst, up, pid     , sid, tid, tl0, ss
-  InsertVp9Gof(sn     , kT, kT  , kT , kF, pid     , 0  , 0  , 0  , &ss);
-  InsertVp9Gof(sn + 1 , kF, kT  , kT , kF, pid + 1 , 0  , 1  , 0);
-  // Skip GOF with tl0 1
-  InsertVp9Gof(sn + 4 , kT, kT  , kT , kF, pid + 4 , 0  , 0  , 2  , &ss);
-  InsertVp9Gof(sn + 5 , kF, kT  , kT , kF, pid + 5 , 0  , 1  , 2);
-  // Skip GOF with tl0 3
-  // Skip GOF with tl0 4
-  InsertVp9Gof(sn + 10, kF, kT  , kT , kF, pid + 10, 0  , 0  , 5  , &ss);
-  InsertVp9Gof(sn + 11, kF, kT  , kT , kF, pid + 11, 0  , 1  , 5);
-
-  ASSERT_EQ(6UL, frames_from_callback_.size());
-  CheckReferencesVp9(pid, 0);
-  CheckReferencesVp9(pid + 1 , 0, pid);
-  CheckReferencesVp9(pid + 4 , 0);
-  CheckReferencesVp9(pid + 5 , 0, pid + 4);
-  CheckReferencesVp9(pid + 10, 0, pid + 8);
-  CheckReferencesVp9(pid + 11, 0, pid + 10);
-}
-
-TEST_F(TestPacketBuffer, Vp9GofSkipFramesTemporalLayers_0212) {
-  uint16_t pid = Rand();
-  uint16_t sn = Rand();
-  GofInfoVP9 ss;
-  ss.SetGofInfoVP9(kTemporalStructureMode3);  // 02120212 pattern
-
-  //           sn     , kf, frst, lst, up, pid     , sid, tid, tl0, ss
-  InsertVp9Gof(sn     , kT, kT  , kT , kF, pid     , 0  , 0  , 0  , &ss);
-  InsertVp9Gof(sn + 1 , kF, kT  , kT , kF, pid + 1 , 0  , 2  , 0);
-  InsertVp9Gof(sn + 2 , kF, kT  , kT , kF, pid + 2 , 0  , 1  , 0);
-  InsertVp9Gof(sn + 3 , kF, kT  , kT , kF, pid + 3 , 0  , 2  , 0);
-
-  ASSERT_EQ(4UL, frames_from_callback_.size());
-  CheckReferencesVp9(pid, 0);
-  CheckReferencesVp9(pid + 1 , 0, pid);
-  CheckReferencesVp9(pid + 2 , 0, pid);
-  CheckReferencesVp9(pid + 3 , 0, pid + 1, pid + 2);
-
-  // Skip frames with tl0 = 1
-
-  //           sn     , kf, frst, lst, up, pid     , sid, tid, tl0, ss
-  InsertVp9Gof(sn + 8 , kT, kT  , kT , kF, pid + 8 , 0  , 0  , 2  , &ss);
-  InsertVp9Gof(sn + 9 , kF, kT  , kT , kF, pid + 9 , 0  , 2  , 2);
-  InsertVp9Gof(sn + 10, kF, kT  , kT , kF, pid + 10, 0  , 1  , 2);
-  InsertVp9Gof(sn + 11, kF, kT  , kT , kF, pid + 11, 0  , 2  , 2);
-
-  ASSERT_EQ(8UL, frames_from_callback_.size());
-  CheckReferencesVp9(pid + 8, 0);
-  CheckReferencesVp9(pid + 9 , 0, pid + 8);
-  CheckReferencesVp9(pid + 10, 0, pid + 8);
-  CheckReferencesVp9(pid + 11, 0, pid + 9, pid + 10);
-
-  // Now insert frames with tl0 = 1
-  //           sn     , kf, frst, lst, up, pid     , sid, tid, tl0, ss
-  InsertVp9Gof(sn + 4 , kT, kT  , kT , kF, pid + 4 , 0  , 0  , 1  , &ss);
-  InsertVp9Gof(sn + 7 , kF, kT  , kT , kF, pid + 7 , 0  , 2  , 1);
-
-  ASSERT_EQ(9UL, frames_from_callback_.size());
-  CheckReferencesVp9(pid + 4, 0);
-
-  // Rest of frames belonging to tl0 = 1
-  //           sn     , kf, frst, lst, up, pid     , sid, tid, tl0, ss
-  InsertVp9Gof(sn + 5 , kF, kT  , kT , kF, pid + 5 , 0  , 2  , 1);
-  InsertVp9Gof(sn + 6 , kF, kT  , kT , kT, pid + 6 , 0  , 1  , 1);  // up-switch
-
-  ASSERT_EQ(12UL, frames_from_callback_.size());
-  CheckReferencesVp9(pid + 5 , 0, pid + 4);
-  CheckReferencesVp9(pid + 6 , 0, pid + 4);
-  CheckReferencesVp9(pid + 7 , 0, pid + 6);
-}
-
-TEST_F(TestPacketBuffer, Vp9GofTemporalLayers_01) {
-  uint16_t pid = Rand();
-  uint16_t sn = Rand();
-  GofInfoVP9 ss;
-  ss.SetGofInfoVP9(kTemporalStructureMode2);  // 0101 pattern
-
-  //           sn     , kf, frst, lst, up, pid     , sid, tid, tl0, ss
-  InsertVp9Gof(sn     , kT, kT  , kT , kF, pid     , 0  , 0  , 0  , &ss);
-  InsertVp9Gof(sn + 1 , kF, kT  , kT , kF, pid + 1 , 0  , 1  , 0);
-  InsertVp9Gof(sn + 2 , kF, kT  , kT , kF, pid + 2 , 0  , 0  , 1);
-  InsertVp9Gof(sn + 3 , kF, kT  , kT , kF, pid + 3 , 0  , 1  , 1);
-  InsertVp9Gof(sn + 4 , kF, kT  , kT , kF, pid + 4 , 0  , 0  , 2);
-  InsertVp9Gof(sn + 5 , kF, kT  , kT , kF, pid + 5 , 0  , 1  , 2);
-  InsertVp9Gof(sn + 6 , kF, kT  , kT , kF, pid + 6 , 0  , 0  , 3);
-  InsertVp9Gof(sn + 7 , kF, kT  , kT , kF, pid + 7 , 0  , 1  , 3);
-  InsertVp9Gof(sn + 8 , kF, kT  , kT , kF, pid + 8 , 0  , 0  , 4);
-  InsertVp9Gof(sn + 9 , kF, kT  , kT , kF, pid + 9 , 0  , 1  , 4);
-  InsertVp9Gof(sn + 10, kF, kT  , kT , kF, pid + 10, 0  , 0  , 5);
-  InsertVp9Gof(sn + 11, kF, kT  , kT , kF, pid + 11, 0  , 1  , 5);
-  InsertVp9Gof(sn + 12, kF, kT  , kT , kF, pid + 12, 0  , 0  , 6);
-  InsertVp9Gof(sn + 13, kF, kT  , kT , kF, pid + 13, 0  , 1  , 6);
-  InsertVp9Gof(sn + 14, kF, kT  , kT , kF, pid + 14, 0  , 0  , 7);
-  InsertVp9Gof(sn + 15, kF, kT  , kT , kF, pid + 15, 0  , 1  , 7);
-  InsertVp9Gof(sn + 16, kF, kT  , kT , kF, pid + 16, 0  , 0  , 8);
-  InsertVp9Gof(sn + 17, kF, kT  , kT , kF, pid + 17, 0  , 1  , 8);
-  InsertVp9Gof(sn + 18, kF, kT  , kT , kF, pid + 18, 0  , 0  , 9);
-  InsertVp9Gof(sn + 19, kF, kT  , kT , kF, pid + 19, 0  , 1  , 9);
-
-  ASSERT_EQ(20UL, frames_from_callback_.size());
-  CheckReferencesVp9(pid, 0);
-  CheckReferencesVp9(pid + 1 , 0, pid);
-  CheckReferencesVp9(pid + 2 , 0, pid);
-  CheckReferencesVp9(pid + 3 , 0, pid + 2);
-  CheckReferencesVp9(pid + 4 , 0, pid + 2);
-  CheckReferencesVp9(pid + 5 , 0, pid + 4);
-  CheckReferencesVp9(pid + 6 , 0, pid + 4);
-  CheckReferencesVp9(pid + 7 , 0, pid + 6);
-  CheckReferencesVp9(pid + 8 , 0, pid + 6);
-  CheckReferencesVp9(pid + 9 , 0, pid + 8);
-  CheckReferencesVp9(pid + 10, 0, pid + 8);
-  CheckReferencesVp9(pid + 11, 0, pid + 10);
-  CheckReferencesVp9(pid + 12, 0, pid + 10);
-  CheckReferencesVp9(pid + 13, 0, pid + 12);
-  CheckReferencesVp9(pid + 14, 0, pid + 12);
-  CheckReferencesVp9(pid + 15, 0, pid + 14);
-  CheckReferencesVp9(pid + 16, 0, pid + 14);
-  CheckReferencesVp9(pid + 17, 0, pid + 16);
-  CheckReferencesVp9(pid + 18, 0, pid + 16);
-  CheckReferencesVp9(pid + 19, 0, pid + 18);
-}
-
-TEST_F(TestPacketBuffer, Vp9GofTemporalLayersReordered_01) {
-  uint16_t pid = Rand();
-  uint16_t sn = Rand();
-  GofInfoVP9 ss;
-  ss.SetGofInfoVP9(kTemporalStructureMode2);  // 01 pattern
-
-  //           sn     , kf, frst, lst, up, pid     , sid, tid, tl0, ss
-  InsertVp9Gof(sn + 1 , kF, kT  , kT , kF, pid + 1 , 0  , 1  , 0);
-  InsertVp9Gof(sn     , kT, kT  , kT , kF, pid     , 0  , 0  , 0  , &ss);
-  InsertVp9Gof(sn + 2 , kF, kT  , kT , kF, pid + 2 , 0  , 0  , 1);
-  InsertVp9Gof(sn + 4 , kF, kT  , kT , kF, pid + 4 , 0  , 0  , 2);
-  InsertVp9Gof(sn + 3 , kF, kT  , kT , kF, pid + 3 , 0  , 1  , 1);
-  InsertVp9Gof(sn + 5 , kF, kT  , kT , kF, pid + 5 , 0  , 1  , 2);
-  InsertVp9Gof(sn + 7 , kF, kT  , kT , kF, pid + 7 , 0  , 1  , 3);
-  InsertVp9Gof(sn + 6 , kF, kT  , kT , kF, pid + 6 , 0  , 0  , 3);
-  InsertVp9Gof(sn + 10, kF, kT  , kT , kF, pid + 10, 0  , 0  , 5);
-  InsertVp9Gof(sn + 8 , kF, kT  , kT , kF, pid + 8 , 0  , 0  , 4);
-  InsertVp9Gof(sn + 9 , kF, kT  , kT , kF, pid + 9 , 0  , 1  , 4);
-  InsertVp9Gof(sn + 11, kF, kT  , kT , kF, pid + 11, 0  , 1  , 5);
-  InsertVp9Gof(sn + 13, kF, kT  , kT , kF, pid + 13, 0  , 1  , 6);
-  InsertVp9Gof(sn + 16, kF, kT  , kT , kF, pid + 16, 0  , 0  , 8);
-  InsertVp9Gof(sn + 12, kF, kT  , kT , kF, pid + 12, 0  , 0  , 6);
-  InsertVp9Gof(sn + 14, kF, kT  , kT , kF, pid + 14, 0  , 0  , 7);
-  InsertVp9Gof(sn + 17, kF, kT  , kT , kF, pid + 17, 0  , 1  , 8);
-  InsertVp9Gof(sn + 19, kF, kT  , kT , kF, pid + 19, 0  , 1  , 9);
-  InsertVp9Gof(sn + 15, kF, kT  , kT , kF, pid + 15, 0  , 1  , 7);
-  InsertVp9Gof(sn + 18, kF, kT  , kT , kF, pid + 18, 0  , 0  , 9);
-
-  ASSERT_EQ(20UL, frames_from_callback_.size());
-  CheckReferencesVp9(pid, 0);
-  CheckReferencesVp9(pid + 1 , 0, pid);
-  CheckReferencesVp9(pid + 2 , 0, pid);
-  CheckReferencesVp9(pid + 3 , 0, pid + 2);
-  CheckReferencesVp9(pid + 4 , 0, pid + 2);
-  CheckReferencesVp9(pid + 5 , 0, pid + 4);
-  CheckReferencesVp9(pid + 6 , 0, pid + 4);
-  CheckReferencesVp9(pid + 7 , 0, pid + 6);
-  CheckReferencesVp9(pid + 8 , 0, pid + 6);
-  CheckReferencesVp9(pid + 9 , 0, pid + 8);
-  CheckReferencesVp9(pid + 10, 0, pid + 8);
-  CheckReferencesVp9(pid + 11, 0, pid + 10);
-  CheckReferencesVp9(pid + 12, 0, pid + 10);
-  CheckReferencesVp9(pid + 13, 0, pid + 12);
-  CheckReferencesVp9(pid + 14, 0, pid + 12);
-  CheckReferencesVp9(pid + 15, 0, pid + 14);
-  CheckReferencesVp9(pid + 16, 0, pid + 14);
-  CheckReferencesVp9(pid + 17, 0, pid + 16);
-  CheckReferencesVp9(pid + 18, 0, pid + 16);
-  CheckReferencesVp9(pid + 19, 0, pid + 18);
-}
-
-TEST_F(TestPacketBuffer, Vp9GofTemporalLayers_0212) {
-  uint16_t pid = Rand();
-  uint16_t sn = Rand();
-  GofInfoVP9 ss;
-  ss.SetGofInfoVP9(kTemporalStructureMode3);  // 0212 pattern
-
-  //           sn     , kf, frst, lst, up, pid     , sid, tid, tl0, ss
-  InsertVp9Gof(sn     , kT, kT  , kT , kF, pid     , 0  , 0  , 0  , &ss);
-  InsertVp9Gof(sn + 1 , kF, kT  , kT , kF, pid + 1 , 0  , 2  , 0);
-  InsertVp9Gof(sn + 2 , kF, kT  , kT , kF, pid + 2 , 0  , 1  , 0);
-  InsertVp9Gof(sn + 3 , kF, kT  , kT , kF, pid + 3 , 0  , 2  , 0);
-  InsertVp9Gof(sn + 4 , kF, kT  , kT , kF, pid + 4 , 0  , 0  , 1);
-  InsertVp9Gof(sn + 5 , kF, kT  , kT , kF, pid + 5 , 0  , 2  , 1);
-  InsertVp9Gof(sn + 6 , kF, kT  , kT , kF, pid + 6 , 0  , 1  , 1);
-  InsertVp9Gof(sn + 7 , kF, kT  , kT , kF, pid + 7 , 0  , 2  , 1);
-  InsertVp9Gof(sn + 8 , kF, kT  , kT , kF, pid + 8 , 0  , 0  , 2);
-  InsertVp9Gof(sn + 9 , kF, kT  , kT , kF, pid + 9 , 0  , 2  , 2);
-  InsertVp9Gof(sn + 10, kF, kT  , kT , kF, pid + 10, 0  , 1  , 2);
-  InsertVp9Gof(sn + 11, kF, kT  , kT , kF, pid + 11, 0  , 2  , 2);
-  InsertVp9Gof(sn + 12, kF, kT  , kT , kF, pid + 12, 0  , 0  , 3);
-  InsertVp9Gof(sn + 13, kF, kT  , kT , kF, pid + 13, 0  , 2  , 3);
-  InsertVp9Gof(sn + 14, kF, kT  , kT , kF, pid + 14, 0  , 1  , 3);
-  InsertVp9Gof(sn + 15, kF, kT  , kT , kF, pid + 15, 0  , 2  , 3);
-  InsertVp9Gof(sn + 16, kF, kT  , kT , kF, pid + 16, 0  , 0  , 4);
-  InsertVp9Gof(sn + 17, kF, kT  , kT , kF, pid + 17, 0  , 2  , 4);
-  InsertVp9Gof(sn + 18, kF, kT  , kT , kF, pid + 18, 0  , 1  , 4);
-  InsertVp9Gof(sn + 19, kF, kT  , kT , kF, pid + 19, 0  , 2  , 4);
-
-  ASSERT_EQ(20UL, frames_from_callback_.size());
-  CheckReferencesVp9(pid, 0);
-  CheckReferencesVp9(pid + 1 , 0, pid);
-  CheckReferencesVp9(pid + 2 , 0, pid);
-  CheckReferencesVp9(pid + 3 , 0, pid + 1, pid + 2);
-  CheckReferencesVp9(pid + 4 , 0, pid);
-  CheckReferencesVp9(pid + 5 , 0, pid + 4);
-  CheckReferencesVp9(pid + 6 , 0, pid + 4);
-  CheckReferencesVp9(pid + 7 , 0, pid + 5, pid + 6);
-  CheckReferencesVp9(pid + 8 , 0, pid + 4);
-  CheckReferencesVp9(pid + 9 , 0, pid + 8);
-  CheckReferencesVp9(pid + 10, 0, pid + 8);
-  CheckReferencesVp9(pid + 11, 0, pid + 9, pid + 10);
-  CheckReferencesVp9(pid + 12, 0, pid + 8);
-  CheckReferencesVp9(pid + 13, 0, pid + 12);
-  CheckReferencesVp9(pid + 14, 0, pid + 12);
-  CheckReferencesVp9(pid + 15, 0, pid + 13, pid + 14);
-  CheckReferencesVp9(pid + 16, 0, pid + 12);
-  CheckReferencesVp9(pid + 17, 0, pid + 16);
-  CheckReferencesVp9(pid + 18, 0, pid + 16);
-  CheckReferencesVp9(pid + 19, 0, pid + 17, pid + 18);
-}
-
-TEST_F(TestPacketBuffer, Vp9GofTemporalLayersReordered_0212) {
-  uint16_t pid = Rand();
-  uint16_t sn = Rand();
-  GofInfoVP9 ss;
-  ss.SetGofInfoVP9(kTemporalStructureMode3);  // 0212 pattern
-
-  //           sn     , kf, frst, lst, up, pid     , sid, tid, tl0, ss
-  InsertVp9Gof(sn + 2 , kF, kT  , kT , kF, pid + 2 , 0  , 1  , 0);
-  InsertVp9Gof(sn + 1 , kF, kT  , kT , kF, pid + 1 , 0  , 2  , 0);
-  InsertVp9Gof(sn     , kT, kT  , kT , kF, pid     , 0  , 0  , 0  , &ss);
-  InsertVp9Gof(sn + 3 , kF, kT  , kT , kF, pid + 3 , 0  , 2  , 0);
-  InsertVp9Gof(sn + 6 , kF, kT  , kT , kF, pid + 6 , 0  , 1  , 1);
-  InsertVp9Gof(sn + 5 , kF, kT  , kT , kF, pid + 5 , 0  , 2  , 1);
-  InsertVp9Gof(sn + 4 , kF, kT  , kT , kF, pid + 4 , 0  , 0  , 1);
-  InsertVp9Gof(sn + 9 , kF, kT  , kT , kF, pid + 9 , 0  , 2  , 2);
-  InsertVp9Gof(sn + 7 , kF, kT  , kT , kF, pid + 7 , 0  , 2  , 1);
-  InsertVp9Gof(sn + 8 , kF, kT  , kT , kF, pid + 8 , 0  , 0  , 2);
-  InsertVp9Gof(sn + 11, kF, kT  , kT , kF, pid + 11, 0  , 2  , 2);
-  InsertVp9Gof(sn + 10, kF, kT  , kT , kF, pid + 10, 0  , 1  , 2);
-  InsertVp9Gof(sn + 13, kF, kT  , kT , kF, pid + 13, 0  , 2  , 3);
-  InsertVp9Gof(sn + 12, kF, kT  , kT , kF, pid + 12, 0  , 0  , 3);
-  InsertVp9Gof(sn + 14, kF, kT  , kT , kF, pid + 14, 0  , 1  , 3);
-  InsertVp9Gof(sn + 16, kF, kT  , kT , kF, pid + 16, 0  , 0  , 4);
-  InsertVp9Gof(sn + 15, kF, kT  , kT , kF, pid + 15, 0  , 2  , 3);
-  InsertVp9Gof(sn + 17, kF, kT  , kT , kF, pid + 17, 0  , 2  , 4);
-  InsertVp9Gof(sn + 19, kF, kT  , kT , kF, pid + 19, 0  , 2  , 4);
-  InsertVp9Gof(sn + 18, kF, kT  , kT , kF, pid + 18, 0  , 1  , 4);
-
-  ASSERT_EQ(20UL, frames_from_callback_.size());
-  CheckReferencesVp9(pid, 0);
-  CheckReferencesVp9(pid + 1 , 0, pid);
-  CheckReferencesVp9(pid + 2 , 0, pid);
-  CheckReferencesVp9(pid + 3 , 0, pid + 1, pid + 2);
-  CheckReferencesVp9(pid + 4 , 0, pid);
-  CheckReferencesVp9(pid + 5 , 0, pid + 4);
-  CheckReferencesVp9(pid + 6 , 0, pid + 4);
-  CheckReferencesVp9(pid + 7 , 0, pid + 5, pid + 6);
-  CheckReferencesVp9(pid + 8 , 0, pid + 4);
-  CheckReferencesVp9(pid + 9 , 0, pid + 8);
-  CheckReferencesVp9(pid + 10, 0, pid + 8);
-  CheckReferencesVp9(pid + 11, 0, pid + 9, pid + 10);
-  CheckReferencesVp9(pid + 12, 0, pid + 8);
-  CheckReferencesVp9(pid + 13, 0, pid + 12);
-  CheckReferencesVp9(pid + 14, 0, pid + 12);
-  CheckReferencesVp9(pid + 15, 0, pid + 13, pid + 14);
-  CheckReferencesVp9(pid + 16, 0, pid + 12);
-  CheckReferencesVp9(pid + 17, 0, pid + 16);
-  CheckReferencesVp9(pid + 18, 0, pid + 16);
-  CheckReferencesVp9(pid + 19, 0, pid + 17, pid + 18);
-}
-
-TEST_F(TestPacketBuffer, Vp9GofTemporalLayersUpSwitch_02120212) {
-  uint16_t pid = Rand();
-  uint16_t sn = Rand();
-  GofInfoVP9 ss;
-  ss.SetGofInfoVP9(kTemporalStructureMode4);  // 02120212 pattern
-
-  //           sn     , kf, frst, lst, up, pid     , sid, tid, tl0, ss
-  InsertVp9Gof(sn     , kT, kT  , kT , kF, pid     , 0  , 0  , 0  , &ss);
-  InsertVp9Gof(sn + 1 , kF, kT  , kT , kF, pid + 1 , 0  , 2  , 0);
-  InsertVp9Gof(sn + 2 , kF, kT  , kT , kF, pid + 2 , 0  , 1  , 0);
-  InsertVp9Gof(sn + 3 , kF, kT  , kT , kF, pid + 3 , 0  , 2  , 0);
-  InsertVp9Gof(sn + 4 , kF, kT  , kT , kF, pid + 4 , 0  , 0  , 1);
-  InsertVp9Gof(sn + 5 , kF, kT  , kT , kF, pid + 5 , 0  , 2  , 1);
-  InsertVp9Gof(sn + 6 , kF, kT  , kT , kT, pid + 6 , 0  , 1  , 1);
-  InsertVp9Gof(sn + 7 , kF, kT  , kT , kF, pid + 7 , 0  , 2  , 1);
-  InsertVp9Gof(sn + 8 , kF, kT  , kT , kT, pid + 8 , 0  , 0  , 2);
-  InsertVp9Gof(sn + 9 , kF, kT  , kT , kF, pid + 9 , 0  , 2  , 2);
-  InsertVp9Gof(sn + 10, kF, kT  , kT , kF, pid + 10, 0  , 1  , 2);
-  InsertVp9Gof(sn + 11, kF, kT  , kT , kT, pid + 11, 0  , 2  , 2);
-  InsertVp9Gof(sn + 12, kF, kT  , kT , kF, pid + 12, 0  , 0  , 3);
-  InsertVp9Gof(sn + 13, kF, kT  , kT , kF, pid + 13, 0  , 2  , 3);
-  InsertVp9Gof(sn + 14, kF, kT  , kT , kF, pid + 14, 0  , 1  , 3);
-  InsertVp9Gof(sn + 15, kF, kT  , kT , kF, pid + 15, 0  , 2  , 3);
-
-  ASSERT_EQ(16UL, frames_from_callback_.size());
-  CheckReferencesVp9(pid, 0);
-  CheckReferencesVp9(pid + 1 , 0, pid);
-  CheckReferencesVp9(pid + 2 , 0, pid);
-  CheckReferencesVp9(pid + 3 , 0, pid + 1, pid + 2);
-  CheckReferencesVp9(pid + 4 , 0, pid);
-  CheckReferencesVp9(pid + 5 , 0, pid + 3, pid + 4);
-  CheckReferencesVp9(pid + 6 , 0, pid + 2, pid + 4);
-  CheckReferencesVp9(pid + 7 , 0, pid + 6);
-  CheckReferencesVp9(pid + 8 , 0, pid + 4);
-  CheckReferencesVp9(pid + 9 , 0, pid + 8);
-  CheckReferencesVp9(pid + 10, 0, pid + 8);
-  CheckReferencesVp9(pid + 11, 0, pid + 9, pid + 10);
-  CheckReferencesVp9(pid + 12, 0, pid + 8);
-  CheckReferencesVp9(pid + 13, 0, pid + 11, pid + 12);
-  CheckReferencesVp9(pid + 14, 0, pid + 10, pid + 12);
-  CheckReferencesVp9(pid + 15, 0, pid + 13, pid + 14);
-}
-
-TEST_F(TestPacketBuffer, Vp9GofTemporalLayersUpSwitchReordered_02120212) {
-  uint16_t pid = Rand();
-  uint16_t sn = Rand();
-  GofInfoVP9 ss;
-  ss.SetGofInfoVP9(kTemporalStructureMode4);  // 02120212 pattern
-
-  //           sn     , kf, frst, lst, up, pid     , sid, tid, tl0, ss
-  InsertVp9Gof(sn + 1 , kF, kT  , kT , kF, pid + 1 , 0  , 2  , 0);
-  InsertVp9Gof(sn     , kT, kT  , kT , kF, pid     , 0  , 0  , 0  , &ss);
-  InsertVp9Gof(sn + 4 , kF, kT  , kT , kF, pid + 4 , 0  , 0  , 1);
-  InsertVp9Gof(sn + 2 , kF, kT  , kT , kF, pid + 2 , 0  , 1  , 0);
-  InsertVp9Gof(sn + 5 , kF, kT  , kT , kF, pid + 5 , 0  , 2  , 1);
-  InsertVp9Gof(sn + 3 , kF, kT  , kT , kF, pid + 3 , 0  , 2  , 0);
-  InsertVp9Gof(sn + 7 , kF, kT  , kT , kF, pid + 7 , 0  , 2  , 1);
-  InsertVp9Gof(sn + 9 , kF, kT  , kT , kF, pid + 9 , 0  , 2  , 2);
-  InsertVp9Gof(sn + 6 , kF, kT  , kT , kT, pid + 6 , 0  , 1  , 1);
-  InsertVp9Gof(sn + 12, kF, kT  , kT , kF, pid + 12, 0  , 0  , 3);
-  InsertVp9Gof(sn + 10, kF, kT  , kT , kF, pid + 10, 0  , 1  , 2);
-  InsertVp9Gof(sn + 8 , kF, kT  , kT , kT, pid + 8 , 0  , 0  , 2);
-  InsertVp9Gof(sn + 11, kF, kT  , kT , kT, pid + 11, 0  , 2  , 2);
-  InsertVp9Gof(sn + 13, kF, kT  , kT , kF, pid + 13, 0  , 2  , 3);
-  InsertVp9Gof(sn + 15, kF, kT  , kT , kF, pid + 15, 0  , 2  , 3);
-  InsertVp9Gof(sn + 14, kF, kT  , kT , kF, pid + 14, 0  , 1  , 3);
-
-  ASSERT_EQ(16UL, frames_from_callback_.size());
-  CheckReferencesVp9(pid, 0);
-  CheckReferencesVp9(pid + 1 , 0, pid);
-  CheckReferencesVp9(pid + 2 , 0, pid);
-  CheckReferencesVp9(pid + 3 , 0, pid + 1, pid + 2);
-  CheckReferencesVp9(pid + 4 , 0, pid);
-  CheckReferencesVp9(pid + 5 , 0, pid + 3, pid + 4);
-  CheckReferencesVp9(pid + 6 , 0, pid + 2, pid + 4);
-  CheckReferencesVp9(pid + 7 , 0, pid + 6);
-  CheckReferencesVp9(pid + 8 , 0, pid + 4);
-  CheckReferencesVp9(pid + 9 , 0, pid + 8);
-  CheckReferencesVp9(pid + 10, 0, pid + 8);
-  CheckReferencesVp9(pid + 11, 0, pid + 9, pid + 10);
-  CheckReferencesVp9(pid + 12, 0, pid + 8);
-  CheckReferencesVp9(pid + 13, 0, pid + 11, pid + 12);
-  CheckReferencesVp9(pid + 14, 0, pid + 10, pid + 12);
-  CheckReferencesVp9(pid + 15, 0, pid + 13, pid + 14);
-}
-
-TEST_F(TestPacketBuffer, Vp9GofTemporalLayersReordered_01_0212) {
-  uint16_t pid = Rand();
-  uint16_t sn = Rand();
-  GofInfoVP9 ss;
-  ss.SetGofInfoVP9(kTemporalStructureMode2);  // 01 pattern
-
-  //           sn     , kf, frst, lst, up, pid     , sid, tid, tl0, ss
-  InsertVp9Gof(sn + 1 , kF, kT  , kT , kF, pid + 1 , 0  , 1  , 0);
-  InsertVp9Gof(sn     , kT, kT  , kT , kF, pid     , 0  , 0  , 0  , &ss);
-  InsertVp9Gof(sn + 3 , kF, kT  , kT , kF, pid + 3 , 0  , 1  , 1);
-  InsertVp9Gof(sn + 6 , kF, kT  , kT , kF, pid + 6 , 0  , 1  , 2);
-  ss.SetGofInfoVP9(kTemporalStructureMode3);  // 0212 pattern
-  InsertVp9Gof(sn + 4 , kF, kT  , kT , kF, pid + 4 , 0  , 0  , 2  , &ss);
-  InsertVp9Gof(sn + 2 , kF, kT  , kT , kF, pid + 2 , 0  , 0  , 1);
-  InsertVp9Gof(sn + 5 , kF, kT  , kT , kF, pid + 5 , 0  , 2  , 2);
-  InsertVp9Gof(sn + 8 , kF, kT  , kT , kF, pid + 8 , 0  , 0  , 3);
-  InsertVp9Gof(sn + 10, kF, kT  , kT , kF, pid + 10, 0  , 1  , 3);
-  InsertVp9Gof(sn + 7 , kF, kT  , kT , kF, pid + 7 , 0  , 2  , 2);
-  InsertVp9Gof(sn + 11, kF, kT  , kT , kF, pid + 11, 0  , 2  , 3);
-  InsertVp9Gof(sn + 9 , kF, kT  , kT , kF, pid + 9 , 0  , 2  , 3);
-
-  ASSERT_EQ(12UL, frames_from_callback_.size());
-  CheckReferencesVp9(pid, 0);
-  CheckReferencesVp9(pid + 1 , 0, pid);
-  CheckReferencesVp9(pid + 2 , 0, pid);
-  CheckReferencesVp9(pid + 3 , 0, pid + 2);
-  CheckReferencesVp9(pid + 4 , 0, pid);
-  CheckReferencesVp9(pid + 5 , 0, pid + 4);
-  CheckReferencesVp9(pid + 6 , 0, pid + 4);
-  CheckReferencesVp9(pid + 7 , 0, pid + 5, pid + 6);
-  CheckReferencesVp9(pid + 8 , 0, pid + 4);
-  CheckReferencesVp9(pid + 9 , 0, pid + 8);
-  CheckReferencesVp9(pid + 10, 0, pid + 8);
-  CheckReferencesVp9(pid + 11, 0, pid + 9, pid + 10);
-}
-
-TEST_F(TestPacketBuffer, Vp9FlexibleModeOneFrame) {
-  uint16_t pid = Rand();
-  uint16_t sn = Rand();
-
-  //            sn, kf, frst, lst, intr, pid, sid, tid, tl0
-  InsertVp9Flex(sn, kT, kT  , kT , kF  , pid, 0  , 0  , 0);
-
-  ASSERT_EQ(1UL, frames_from_callback_.size());
-  CheckReferencesVp9(pid, 0);
-}
-
-TEST_F(TestPacketBuffer, Vp9FlexibleModeTwoSpatialLayers) {
-  uint16_t pid = Rand();
-  uint16_t sn = Rand();
-
-  //            sn     , kf, frst, lst, intr, pid    , sid, tid, tl0, refs
-  InsertVp9Flex(sn     , kT, kT  , kT , kF  , pid    , 0  , 0  , 0);
-  InsertVp9Flex(sn + 1 , kT, kT  , kT , kT  , pid    , 1  , 0  , 0);
-  InsertVp9Flex(sn + 2 , kF, kT  , kT , kF  , pid + 1, 1  , 0  , 0  , {1});
-  InsertVp9Flex(sn + 3 , kF, kT  , kT , kF  , pid + 2, 0  , 0  , 1  , {2});
-  InsertVp9Flex(sn + 4 , kF, kT  , kT , kF  , pid + 2, 1  , 0  , 1  , {1});
-  InsertVp9Flex(sn + 5 , kF, kT  , kT , kF  , pid + 3, 1  , 0  , 1  , {1});
-  InsertVp9Flex(sn + 6 , kF, kT  , kT , kF  , pid + 4, 0  , 0  , 2  , {2});
-  InsertVp9Flex(sn + 7 , kF, kT  , kT , kF  , pid + 4, 1  , 0  , 2  , {1});
-  InsertVp9Flex(sn + 8 , kF, kT  , kT , kF  , pid + 5, 1  , 0  , 2  , {1});
-  InsertVp9Flex(sn + 9 , kF, kT  , kT , kF  , pid + 6, 0  , 0  , 3  , {2});
-  InsertVp9Flex(sn + 10, kF, kT  , kT , kF  , pid + 6, 1  , 0  , 3  , {1});
-  InsertVp9Flex(sn + 11, kF, kT  , kT , kF  , pid + 7, 1  , 0  , 3  , {1});
-  InsertVp9Flex(sn + 12, kF, kT  , kT , kF  , pid + 8, 0  , 0  , 4  , {2});
-  InsertVp9Flex(sn + 13, kF, kT  , kT , kF  , pid + 8, 1  , 0  , 4  , {1});
-
-  ASSERT_EQ(14UL, frames_from_callback_.size());
-  CheckReferencesVp9(pid    , 0);
-  CheckReferencesVp9(pid    , 1);
-  CheckReferencesVp9(pid + 1, 1, pid);
-  CheckReferencesVp9(pid + 2, 0, pid);
-  CheckReferencesVp9(pid + 2, 1, pid + 1);
-  CheckReferencesVp9(pid + 3, 1, pid + 2);
-  CheckReferencesVp9(pid + 4, 0, pid + 2);
-  CheckReferencesVp9(pid + 4, 1, pid + 3);
-  CheckReferencesVp9(pid + 5, 1, pid + 4);
-  CheckReferencesVp9(pid + 6, 0, pid + 4);
-  CheckReferencesVp9(pid + 6, 1, pid + 5);
-  CheckReferencesVp9(pid + 7, 1, pid + 6);
-  CheckReferencesVp9(pid + 8, 0, pid + 6);
-  CheckReferencesVp9(pid + 8, 1, pid + 7);
-}
-
-TEST_F(TestPacketBuffer, Vp9FlexibleModeTwoSpatialLayersReordered) {
-  uint16_t pid = Rand();
-  uint16_t sn = Rand();
-
-  //            sn     , kf, frst, lst, intr, pid    , sid, tid, tl0, refs
-  InsertVp9Flex(sn + 1 , kT, kT  , kT , kT  , pid    , 1  , 0  , 0);
-  InsertVp9Flex(sn + 2 , kF, kT  , kT , kF  , pid + 1, 1  , 0  , 0  , {1});
-  InsertVp9Flex(sn     , kT, kT  , kT , kF  , pid    , 0  , 0  , 0);
-  InsertVp9Flex(sn + 4 , kF, kT  , kT , kF  , pid + 2, 1  , 0  , 1  , {1});
-  InsertVp9Flex(sn + 5 , kF, kT  , kT , kF  , pid + 3, 1  , 0  , 1  , {1});
-  InsertVp9Flex(sn + 3 , kF, kT  , kT , kF  , pid + 2, 0  , 0  , 1  , {2});
-  InsertVp9Flex(sn + 7 , kF, kT  , kT , kF  , pid + 4, 1  , 0  , 2  , {1});
-  InsertVp9Flex(sn + 6 , kF, kT  , kT , kF  , pid + 4, 0  , 0  , 2  , {2});
-  InsertVp9Flex(sn + 8 , kF, kT  , kT , kF  , pid + 5, 1  , 0  , 2  , {1});
-  InsertVp9Flex(sn + 9 , kF, kT  , kT , kF  , pid + 6, 0  , 0  , 3  , {2});
-  InsertVp9Flex(sn + 11, kF, kT  , kT , kF  , pid + 7, 1  , 0  , 3  , {1});
-  InsertVp9Flex(sn + 10, kF, kT  , kT , kF  , pid + 6, 1  , 0  , 3  , {1});
-  InsertVp9Flex(sn + 13, kF, kT  , kT , kF  , pid + 8, 1  , 0  , 4  , {1});
-  InsertVp9Flex(sn + 12, kF, kT  , kT , kF  , pid + 8, 0  , 0  , 4  , {2});
-
-  ASSERT_EQ(14UL, frames_from_callback_.size());
-  CheckReferencesVp9(pid    , 0);
-  CheckReferencesVp9(pid    , 1);
-  CheckReferencesVp9(pid + 1, 1, pid);
-  CheckReferencesVp9(pid + 2, 0, pid);
-  CheckReferencesVp9(pid + 2, 1, pid + 1);
-  CheckReferencesVp9(pid + 3, 1, pid + 2);
-  CheckReferencesVp9(pid + 4, 0, pid + 2);
-  CheckReferencesVp9(pid + 4, 1, pid + 3);
-  CheckReferencesVp9(pid + 5, 1, pid + 4);
-  CheckReferencesVp9(pid + 6, 0, pid + 4);
-  CheckReferencesVp9(pid + 6, 1, pid + 5);
-  CheckReferencesVp9(pid + 7, 1, pid + 6);
-  CheckReferencesVp9(pid + 8, 0, pid + 6);
-  CheckReferencesVp9(pid + 8, 1, pid + 7);
-}
-
 }  // namespace video_coding
 }  // namespace webrtc