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