Ported more jitter buffer tests to unit tests.
BUG= TEST=jitter_buffer_unittest Review URL: http://webrtc-codereview.appspot.com/350009 git-svn-id: http://webrtc.googlecode.com/svn/trunk@1433 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "modules/video_coding/main/source/jitter_buffer.h"
|
#include "modules/video_coding/main/source/jitter_buffer.h"
|
||||||
#include "modules/video_coding/main/source/media_opt_util.h"
|
#include "modules/video_coding/main/source/media_opt_util.h"
|
||||||
@@ -22,57 +24,116 @@ class StreamGenerator {
|
|||||||
public:
|
public:
|
||||||
StreamGenerator(uint16_t start_seq_num, uint32_t start_timestamp,
|
StreamGenerator(uint16_t start_seq_num, uint32_t start_timestamp,
|
||||||
int64_t current_time)
|
int64_t current_time)
|
||||||
: sequence_number_(start_seq_num),
|
: packets_(),
|
||||||
|
sequence_number_(start_seq_num),
|
||||||
timestamp_(start_timestamp),
|
timestamp_(start_timestamp),
|
||||||
start_time_(current_time),
|
start_time_(current_time) {}
|
||||||
num_packets_(0),
|
|
||||||
type_(kVideoFrameKey),
|
|
||||||
first_packet_(true) {}
|
|
||||||
|
|
||||||
void GenerateFrame(FrameType type, int num_packets, int64_t current_time) {
|
void Init(uint16_t start_seq_num, uint32_t start_timestamp,
|
||||||
|
int64_t current_time) {
|
||||||
|
packets_.clear();
|
||||||
|
sequence_number_ = start_seq_num;
|
||||||
|
timestamp_ = start_timestamp;
|
||||||
|
start_time_ = current_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenerateFrame(FrameType type, int num_media_packets,
|
||||||
|
int num_empty_packets, int64_t current_time) {
|
||||||
timestamp_ += 90 * (current_time - start_time_);
|
timestamp_ += 90 * (current_time - start_time_);
|
||||||
// Move the sequence number counter if all packets from the previous frame
|
// Move the sequence number counter if all packets from the previous frame
|
||||||
// wasn't collected.
|
// wasn't collected.
|
||||||
sequence_number_ += num_packets_;
|
sequence_number_ += packets_.size();
|
||||||
num_packets_ = num_packets;
|
packets_.clear();
|
||||||
type_ = type;
|
for (int i = 0; i < num_media_packets; ++i) {
|
||||||
first_packet_ = true;
|
packets_.push_back(GeneratePacket(sequence_number_,
|
||||||
|
timestamp_,
|
||||||
|
(i == 0),
|
||||||
|
(i == num_media_packets - 1),
|
||||||
|
type));
|
||||||
|
++sequence_number_;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < num_empty_packets; ++i) {
|
||||||
|
packets_.push_back(GeneratePacket(sequence_number_,
|
||||||
|
timestamp_,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
kFrameEmpty));
|
||||||
|
++sequence_number_;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NextPacket(VCMPacket* packet) {
|
static VCMPacket GeneratePacket(uint16_t sequence_number,
|
||||||
if (num_packets_ == 0) {
|
uint32_t timestamp,
|
||||||
|
bool first_packet,
|
||||||
|
bool marker_bit,
|
||||||
|
FrameType type) {
|
||||||
|
VCMPacket packet;
|
||||||
|
packet.seqNum = sequence_number;
|
||||||
|
packet.timestamp = timestamp;
|
||||||
|
packet.frameType = type;
|
||||||
|
packet.isFirstPacket = first_packet;
|
||||||
|
packet.markerBit = marker_bit;
|
||||||
|
if (packet.isFirstPacket)
|
||||||
|
packet.completeNALU = kNaluStart;
|
||||||
|
else if (packet.markerBit)
|
||||||
|
packet.completeNALU = kNaluEnd;
|
||||||
|
else
|
||||||
|
packet.completeNALU = kNaluIncomplete;
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PopPacket(VCMPacket* packet, int index) {
|
||||||
|
std::list<VCMPacket>::iterator it = GetPacketIterator(index);
|
||||||
|
if (it == packets_.end())
|
||||||
return false;
|
return false;
|
||||||
}
|
if (packet)
|
||||||
--num_packets_;
|
*packet = (*it);
|
||||||
if (packet) {
|
packets_.erase(it);
|
||||||
packet->seqNum = sequence_number_;
|
|
||||||
packet->timestamp = timestamp_;
|
|
||||||
packet->frameType = type_;
|
|
||||||
packet->isFirstPacket = first_packet_;
|
|
||||||
packet->markerBit = (num_packets_ == 0);
|
|
||||||
if (packet->isFirstPacket)
|
|
||||||
packet->completeNALU = kNaluStart;
|
|
||||||
else if (packet->markerBit)
|
|
||||||
packet->completeNALU = kNaluEnd;
|
|
||||||
else
|
|
||||||
packet->completeNALU = kNaluIncomplete;
|
|
||||||
}
|
|
||||||
++sequence_number_;
|
|
||||||
first_packet_ = false;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GetPacket(VCMPacket* packet, int index) {
|
||||||
|
std::list<VCMPacket>::iterator it = GetPacketIterator(index);
|
||||||
|
if (it == packets_.end())
|
||||||
|
return false;
|
||||||
|
if (packet)
|
||||||
|
*packet = (*it);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NextPacket(VCMPacket* packet) {
|
||||||
|
if (packets_.empty())
|
||||||
|
return false;
|
||||||
|
if (packet != NULL)
|
||||||
|
*packet = packets_.front();
|
||||||
|
packets_.pop_front();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t NextSequenceNumber() const {
|
||||||
|
if (packets_.empty())
|
||||||
|
return sequence_number_;
|
||||||
|
return packets_.front().seqNum;
|
||||||
|
}
|
||||||
|
|
||||||
int PacketsRemaining() const {
|
int PacketsRemaining() const {
|
||||||
return num_packets_;
|
return packets_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::list<VCMPacket>::iterator GetPacketIterator(int index) {
|
||||||
|
std::list<VCMPacket>::iterator it = packets_.begin();
|
||||||
|
for (int i = 0; i < index; ++i) {
|
||||||
|
++it;
|
||||||
|
if (it == packets_.end()) break;
|
||||||
|
}
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::list<VCMPacket> packets_;
|
||||||
uint16_t sequence_number_;
|
uint16_t sequence_number_;
|
||||||
uint32_t timestamp_;
|
uint32_t timestamp_;
|
||||||
int64_t start_time_;
|
int64_t start_time_;
|
||||||
int num_packets_;
|
|
||||||
FrameType type_;
|
|
||||||
bool first_packet_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(StreamGenerator);
|
DISALLOW_COPY_AND_ASSIGN(StreamGenerator);
|
||||||
};
|
};
|
||||||
@@ -99,11 +160,25 @@ class TestRunningJitterBuffer : public ::testing::Test {
|
|||||||
delete clock_;
|
delete clock_;
|
||||||
}
|
}
|
||||||
|
|
||||||
VCMFrameBufferEnum InsertNextPacket() {
|
VCMFrameBufferEnum InsertPacketAndPop(int index) {
|
||||||
VCMPacket packet;
|
VCMPacket packet;
|
||||||
packet.dataPtr = data_buffer_;
|
|
||||||
VCMEncodedFrame* frame;
|
VCMEncodedFrame* frame;
|
||||||
bool packet_available = stream_generator->NextPacket(&packet);
|
|
||||||
|
packet.dataPtr = data_buffer_;
|
||||||
|
bool packet_available = stream_generator->PopPacket(&packet, index);
|
||||||
|
EXPECT_TRUE(packet_available);
|
||||||
|
if (!packet_available)
|
||||||
|
return kStateError; // Return here to avoid crashes below.
|
||||||
|
EXPECT_EQ(VCM_OK, jitter_buffer_->GetFrame(packet, frame));
|
||||||
|
return jitter_buffer_->InsertPacket(frame, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
VCMFrameBufferEnum InsertPacket(int index) {
|
||||||
|
VCMPacket packet;
|
||||||
|
VCMEncodedFrame* frame;
|
||||||
|
|
||||||
|
packet.dataPtr = data_buffer_;
|
||||||
|
bool packet_available = stream_generator->GetPacket(&packet, index);
|
||||||
EXPECT_TRUE(packet_available);
|
EXPECT_TRUE(packet_available);
|
||||||
if (!packet_available)
|
if (!packet_available)
|
||||||
return kStateError; // Return here to avoid crashes below.
|
return kStateError; // Return here to avoid crashes below.
|
||||||
@@ -112,31 +187,47 @@ class TestRunningJitterBuffer : public ::testing::Test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void InsertFrame(FrameType frame_type) {
|
void InsertFrame(FrameType frame_type) {
|
||||||
stream_generator->GenerateFrame(frame_type, 1,
|
stream_generator->GenerateFrame(frame_type,
|
||||||
|
(frame_type != kFrameEmpty) ? 1 : 0,
|
||||||
|
(frame_type == kFrameEmpty) ? 1 : 0,
|
||||||
clock_->MillisecondTimestamp());
|
clock_->MillisecondTimestamp());
|
||||||
EXPECT_EQ(kFirstPacket, InsertNextPacket());
|
EXPECT_EQ(kFirstPacket, InsertPacketAndPop(0));
|
||||||
clock_->IncrementDebugClock(kDefaultFramePeriodMs);
|
clock_->IncrementDebugClock(kDefaultFramePeriodMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InsertFrames(int num_frames) {
|
void InsertFrames(int num_frames, FrameType frame_type) {
|
||||||
for (int i = 0; i < num_frames; ++i) {
|
for (int i = 0; i < num_frames; ++i) {
|
||||||
InsertFrame(kVideoFrameDelta);
|
InsertFrame(frame_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DropFrame(int num_packets) {
|
void DropFrame(int num_packets) {
|
||||||
stream_generator->GenerateFrame(kVideoFrameDelta, num_packets,
|
stream_generator->GenerateFrame(kVideoFrameDelta, num_packets, 0,
|
||||||
clock_->MillisecondTimestamp());
|
clock_->MillisecondTimestamp());
|
||||||
clock_->IncrementDebugClock(kDefaultFramePeriodMs);
|
clock_->IncrementDebugClock(kDefaultFramePeriodMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DecodeCompleteFrame() {
|
||||||
|
VCMEncodedFrame* frame = jitter_buffer_->GetCompleteFrameForDecoding(0);
|
||||||
|
bool ret = (frame != NULL);
|
||||||
|
jitter_buffer_->ReleaseFrame(frame);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DecodeFrame() {
|
||||||
|
VCMEncodedFrame* frame = jitter_buffer_->GetFrameForDecoding();
|
||||||
|
bool ret = (frame != NULL);
|
||||||
|
jitter_buffer_->ReleaseFrame(frame);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
VCMJitterBuffer* jitter_buffer_;
|
VCMJitterBuffer* jitter_buffer_;
|
||||||
StreamGenerator* stream_generator;
|
StreamGenerator* stream_generator;
|
||||||
FakeTickTime* clock_;
|
FakeTickTime* clock_;
|
||||||
uint8_t data_buffer_[kDataBufferSize];
|
uint8_t data_buffer_[kDataBufferSize];
|
||||||
};
|
};
|
||||||
|
|
||||||
class TestNack : public TestRunningJitterBuffer {
|
class TestJitterBufferNack : public TestRunningJitterBuffer {
|
||||||
protected:
|
protected:
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
TestRunningJitterBuffer::SetUp();
|
TestRunningJitterBuffer::SetUp();
|
||||||
@@ -148,32 +239,51 @@ class TestNack : public TestRunningJitterBuffer {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(TestNack, TestJitterBufferFull) {
|
TEST_F(TestRunningJitterBuffer, TestFull) {
|
||||||
// Insert a key frame and decode it.
|
// Insert a key frame and decode it.
|
||||||
InsertFrame(kVideoFrameKey);
|
InsertFrame(kVideoFrameKey);
|
||||||
EXPECT_TRUE(jitter_buffer_->GetCompleteFrameForDecoding(0) != NULL);
|
EXPECT_TRUE(DecodeCompleteFrame());
|
||||||
DropFrame(1);
|
DropFrame(1);
|
||||||
// Fill the jitter buffer.
|
// Fill the jitter buffer.
|
||||||
InsertFrames(kMaxNumberOfFrames);
|
InsertFrames(kMaxNumberOfFrames, kVideoFrameDelta);
|
||||||
// Make sure we can't decode these frames.
|
// Make sure we can't decode these frames.
|
||||||
EXPECT_TRUE(jitter_buffer_->GetCompleteFrameForDecoding(0) == NULL);
|
EXPECT_FALSE(DecodeCompleteFrame());
|
||||||
// This frame will make the jitter buffer recycle frames until a key frame.
|
// This frame will make the jitter buffer recycle frames until a key frame.
|
||||||
// Since none is found it will have to wait until the next key frame before
|
// Since none is found it will have to wait until the next key frame before
|
||||||
// decoding.
|
// decoding.
|
||||||
InsertFrame(kVideoFrameDelta);
|
InsertFrame(kVideoFrameDelta);
|
||||||
EXPECT_TRUE(jitter_buffer_->GetCompleteFrameForDecoding(0) == NULL);
|
EXPECT_FALSE(DecodeCompleteFrame());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestNack, TestNackListFull) {
|
TEST_F(TestRunningJitterBuffer, TestEmptyPackets) {
|
||||||
|
// Make sure a frame can get complete even though empty packets are missing.
|
||||||
|
stream_generator->GenerateFrame(kVideoFrameKey, 3, 3,
|
||||||
|
clock_->MillisecondTimestamp());
|
||||||
|
EXPECT_EQ(kFirstPacket, InsertPacketAndPop(4));
|
||||||
|
EXPECT_EQ(kIncomplete, InsertPacketAndPop(4));
|
||||||
|
EXPECT_EQ(kIncomplete, InsertPacketAndPop(0));
|
||||||
|
EXPECT_EQ(kIncomplete, InsertPacketAndPop(0));
|
||||||
|
EXPECT_EQ(kCompleteSession, InsertPacketAndPop(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestJitterBufferNack, TestEmptyPackets) {
|
||||||
|
// Make sure empty packets doesn't clog the jitter buffer.
|
||||||
|
jitter_buffer_->SetNackMode(kNackHybrid, kLowRttNackMs, -1);
|
||||||
|
InsertFrames(kMaxNumberOfFrames, kFrameEmpty);
|
||||||
|
InsertFrame(kVideoFrameKey);
|
||||||
|
EXPECT_TRUE(DecodeCompleteFrame());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestJitterBufferNack, TestNackListFull) {
|
||||||
// Insert a key frame and decode it.
|
// Insert a key frame and decode it.
|
||||||
InsertFrame(kVideoFrameKey);
|
InsertFrame(kVideoFrameKey);
|
||||||
EXPECT_TRUE(jitter_buffer_->GetCompleteFrameForDecoding(0) != NULL);
|
EXPECT_TRUE(DecodeCompleteFrame());
|
||||||
|
|
||||||
// Generate and drop |kNackHistoryLength| packets to fill the NACK list.
|
// Generate and drop |kNackHistoryLength| packets to fill the NACK list.
|
||||||
DropFrame(kNackHistoryLength);
|
DropFrame(kNackHistoryLength);
|
||||||
// Insert a frame which should trigger a recycle until the next key frame.
|
// Insert a frame which should trigger a recycle until the next key frame.
|
||||||
InsertFrame(kVideoFrameDelta);
|
InsertFrame(kVideoFrameDelta);
|
||||||
EXPECT_TRUE(jitter_buffer_->GetCompleteFrameForDecoding(0) == NULL);
|
EXPECT_FALSE(DecodeCompleteFrame());
|
||||||
|
|
||||||
uint16_t nack_list_length = kNackHistoryLength;
|
uint16_t nack_list_length = kNackHistoryLength;
|
||||||
bool extended;
|
bool extended;
|
||||||
@@ -182,11 +292,11 @@ TEST_F(TestNack, TestNackListFull) {
|
|||||||
EXPECT_TRUE(nack_list_length == 0xffff && nack_list == NULL);
|
EXPECT_TRUE(nack_list_length == 0xffff && nack_list == NULL);
|
||||||
|
|
||||||
InsertFrame(kVideoFrameDelta);
|
InsertFrame(kVideoFrameDelta);
|
||||||
EXPECT_TRUE(jitter_buffer_->GetCompleteFrameForDecoding(0) == NULL);
|
EXPECT_FALSE(DecodeCompleteFrame());
|
||||||
EXPECT_TRUE(jitter_buffer_->GetFrameForDecoding() == NULL);
|
EXPECT_FALSE(DecodeFrame());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestNack, TestNackBeforeDecode) {
|
TEST_F(TestJitterBufferNack, TestNackBeforeDecode) {
|
||||||
DropFrame(10);
|
DropFrame(10);
|
||||||
// Insert a frame and try to generate a NACK list. Shouldn't get one.
|
// Insert a frame and try to generate a NACK list. Shouldn't get one.
|
||||||
InsertFrame(kVideoFrameDelta);
|
InsertFrame(kVideoFrameDelta);
|
||||||
@@ -195,44 +305,72 @@ TEST_F(TestNack, TestNackBeforeDecode) {
|
|||||||
uint16_t* list = jitter_buffer_->GetNackList(nack_list_size, extended);
|
uint16_t* list = jitter_buffer_->GetNackList(nack_list_size, extended);
|
||||||
// No list generated, and a key frame request is signaled.
|
// No list generated, and a key frame request is signaled.
|
||||||
EXPECT_TRUE(list == NULL);
|
EXPECT_TRUE(list == NULL);
|
||||||
EXPECT_TRUE(nack_list_size == 0xFFFF);
|
EXPECT_EQ(0xFFFF, nack_list_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestNack, TestNormalOperation) {
|
TEST_F(TestJitterBufferNack, TestNormalOperation) {
|
||||||
EXPECT_EQ(kNackInfinite, jitter_buffer_->GetNackMode());
|
EXPECT_EQ(kNackInfinite, jitter_buffer_->GetNackMode());
|
||||||
|
|
||||||
InsertFrame(kVideoFrameKey);
|
InsertFrame(kVideoFrameKey);
|
||||||
EXPECT_TRUE(jitter_buffer_->GetCompleteFrameForDecoding(0) != NULL);
|
EXPECT_TRUE(DecodeFrame());
|
||||||
|
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
// | 1 | 2 | .. | 8 | 9 | x | 11 | 12 | .. | 19 | x | 21 | .. | 100 |
|
// | 1 | 2 | .. | 8 | 9 | x | 11 | 12 | .. | 19 | x | 21 | .. | 100 |
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
stream_generator->GenerateFrame(kVideoFrameKey, 100,
|
stream_generator->GenerateFrame(kVideoFrameKey, 100, 0,
|
||||||
clock_->MillisecondTimestamp());
|
clock_->MillisecondTimestamp());
|
||||||
clock_->IncrementDebugClock(kDefaultFramePeriodMs);
|
clock_->IncrementDebugClock(kDefaultFramePeriodMs);
|
||||||
EXPECT_EQ(kFirstPacket, InsertNextPacket());
|
EXPECT_EQ(kFirstPacket, InsertPacketAndPop(0));
|
||||||
// Verify that the frame is incomplete.
|
// Verify that the frame is incomplete.
|
||||||
EXPECT_TRUE(jitter_buffer_->GetCompleteFrameForDecoding(0) == NULL);
|
EXPECT_FALSE(DecodeCompleteFrame());
|
||||||
int i = 2;
|
|
||||||
while (stream_generator->PacketsRemaining() > 1) {
|
while (stream_generator->PacketsRemaining() > 1) {
|
||||||
if (i % 10 != 0)
|
if (stream_generator->NextSequenceNumber() % 10 != 0)
|
||||||
EXPECT_EQ(kIncomplete, InsertNextPacket());
|
EXPECT_EQ(kIncomplete, InsertPacketAndPop(0));
|
||||||
else
|
else
|
||||||
stream_generator->NextPacket(NULL); // Drop packet
|
stream_generator->NextPacket(NULL); // Drop packet
|
||||||
++i;
|
|
||||||
}
|
}
|
||||||
EXPECT_EQ(kIncomplete, InsertNextPacket());
|
EXPECT_EQ(kIncomplete, InsertPacketAndPop(0));
|
||||||
EXPECT_EQ(0, stream_generator->PacketsRemaining());
|
EXPECT_EQ(0, stream_generator->PacketsRemaining());
|
||||||
EXPECT_TRUE(jitter_buffer_->GetCompleteFrameForDecoding(0) == NULL);
|
EXPECT_FALSE(DecodeCompleteFrame());
|
||||||
EXPECT_TRUE(jitter_buffer_->GetFrameForDecoding() == NULL);
|
EXPECT_FALSE(DecodeFrame());
|
||||||
uint16_t nack_list_size = 0;
|
uint16_t nack_list_size = 0;
|
||||||
bool extended = false;
|
bool extended = false;
|
||||||
uint16_t* list = jitter_buffer_->GetNackList(nack_list_size, extended);
|
uint16_t* list = jitter_buffer_->GetNackList(nack_list_size, extended);
|
||||||
// Verify the NACK list.
|
// Verify the NACK list.
|
||||||
const int kExpectedNackSize = 9;
|
const int kExpectedNackSize = 9;
|
||||||
ASSERT_EQ(kExpectedNackSize, nack_list_size);
|
ASSERT_EQ(kExpectedNackSize, nack_list_size);
|
||||||
for (i = 0; i < nack_list_size; ++i)
|
for (int i = 0; i < nack_list_size; ++i)
|
||||||
EXPECT_EQ((1 + i) * 10, list[i]);
|
EXPECT_EQ((1 + i) * 10, list[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(TestJitterBufferNack, TestNormalOperationWrap) {
|
||||||
|
// ------- ------------------------------------------------------------
|
||||||
|
// | 65532 | | 65533 | 65534 | 65535 | x | 1 | .. | 9 | x | 11 |.....| 96 |
|
||||||
|
// ------- ------------------------------------------------------------
|
||||||
|
stream_generator->Init(65532, 0, clock_->MillisecondTimestamp());
|
||||||
|
InsertFrame(kVideoFrameKey);
|
||||||
|
EXPECT_TRUE(DecodeCompleteFrame());
|
||||||
|
stream_generator->GenerateFrame(kVideoFrameDelta, 100, 0,
|
||||||
|
clock_->MillisecondTimestamp());
|
||||||
|
EXPECT_EQ(kFirstPacket, InsertPacketAndPop(0));
|
||||||
|
while (stream_generator->PacketsRemaining() > 1) {
|
||||||
|
if (stream_generator->NextSequenceNumber() % 10 != 0)
|
||||||
|
EXPECT_EQ(kIncomplete, InsertPacketAndPop(0));
|
||||||
|
else
|
||||||
|
stream_generator->NextPacket(NULL); // Drop packet
|
||||||
|
}
|
||||||
|
EXPECT_EQ(kIncomplete, InsertPacketAndPop(0));
|
||||||
|
EXPECT_EQ(0, stream_generator->PacketsRemaining());
|
||||||
|
EXPECT_FALSE(DecodeCompleteFrame());
|
||||||
|
EXPECT_FALSE(DecodeCompleteFrame());
|
||||||
|
uint16_t nack_list_size = 0;
|
||||||
|
bool extended = false;
|
||||||
|
uint16_t* list = jitter_buffer_->GetNackList(nack_list_size, extended);
|
||||||
|
// Verify the NACK list.
|
||||||
|
const int kExpectedNackSize = 10;
|
||||||
|
ASSERT_EQ(kExpectedNackSize, nack_list_size);
|
||||||
|
for (int i = 0; i < nack_list_size; ++i)
|
||||||
|
EXPECT_EQ(i * 10, list[i]);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@@ -1292,6 +1292,8 @@ int JitterBufferTest(CmdArgs& args)
|
|||||||
// check the frame type
|
// check the frame type
|
||||||
TEST(frameOut->FrameType() == kVideoFrameDelta);
|
TEST(frameOut->FrameType() == kVideoFrameDelta);
|
||||||
|
|
||||||
|
jb.ReleaseFrame(frameOut);
|
||||||
|
|
||||||
seqNum--;
|
seqNum--;
|
||||||
timeStamp = 2000;
|
timeStamp = 2000;
|
||||||
packet.frameType = kVideoFrameDelta;
|
packet.frameType = kVideoFrameDelta;
|
||||||
@@ -1344,6 +1346,8 @@ int JitterBufferTest(CmdArgs& args)
|
|||||||
// check the frame type
|
// check the frame type
|
||||||
TEST(frameOut->FrameType() == kVideoFrameDelta);
|
TEST(frameOut->FrameType() == kVideoFrameDelta);
|
||||||
|
|
||||||
|
jb.ReleaseFrame(frameOut);
|
||||||
|
|
||||||
seqNum--;
|
seqNum--;
|
||||||
timeStamp = 0xffffff00;
|
timeStamp = 0xffffff00;
|
||||||
packet.frameType = kVideoFrameDelta;
|
packet.frameType = kVideoFrameDelta;
|
||||||
@@ -1407,6 +1411,8 @@ int JitterBufferTest(CmdArgs& args)
|
|||||||
|
|
||||||
TEST(CheckOutFrame(frameOut, size*2, false) == 0);
|
TEST(CheckOutFrame(frameOut, size*2, false) == 0);
|
||||||
|
|
||||||
|
jb.ReleaseFrame(frameOut);
|
||||||
|
|
||||||
seqNum++;
|
seqNum++;
|
||||||
timeStamp += 33*90;
|
timeStamp += 33*90;
|
||||||
packet.frameType = kVideoFrameDelta;
|
packet.frameType = kVideoFrameDelta;
|
||||||
@@ -1607,230 +1613,6 @@ int JitterBufferTest(CmdArgs& args)
|
|||||||
|
|
||||||
//printf("DONE insert 2 frames (1 packet) re-ordered with wrap in timestamp\n");
|
//printf("DONE insert 2 frames (1 packet) re-ordered with wrap in timestamp\n");
|
||||||
|
|
||||||
//
|
|
||||||
// TEST NACK
|
|
||||||
//
|
|
||||||
// ---------------------------------------------------------------------------------------------
|
|
||||||
// | 3 | 4 | 5 | 6 | 7 | 9 | x | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | x | 21 |.....| 102 |
|
|
||||||
// ---------------------------------------------------------------------------------------------
|
|
||||||
jb.SetNackMode(kNackInfinite, -1, -1);
|
|
||||||
|
|
||||||
TEST(jb.GetNackMode() == kNackInfinite);
|
|
||||||
|
|
||||||
// insert first packet
|
|
||||||
timeStamp += 33*90;
|
|
||||||
seqNum += 2;
|
|
||||||
packet.frameType = kVideoFrameKey;
|
|
||||||
packet.isFirstPacket = true;
|
|
||||||
packet.markerBit = false;
|
|
||||||
packet.seqNum = seqNum;
|
|
||||||
packet.timestamp = timeStamp;
|
|
||||||
|
|
||||||
frameIn = jb.GetFrame(packet);
|
|
||||||
TEST(frameIn != 0);
|
|
||||||
|
|
||||||
// Insert a packet into a frame
|
|
||||||
TEST(kFirstPacket == jb.InsertPacket(frameIn, packet));
|
|
||||||
|
|
||||||
// get packet notification
|
|
||||||
TEST(timeStamp == jb.GetNextTimeStamp(10, incomingFrameType, renderTimeMs));
|
|
||||||
|
|
||||||
// check incoming frame type
|
|
||||||
TEST(incomingFrameType == kVideoFrameKey);
|
|
||||||
|
|
||||||
// get the frame
|
|
||||||
frameOut = jb.GetCompleteFrameForDecoding(10);
|
|
||||||
|
|
||||||
// it should not be complete
|
|
||||||
TEST(frameOut == 0);
|
|
||||||
|
|
||||||
// insert 98 packets
|
|
||||||
loop = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
seqNum++;
|
|
||||||
if(seqNum % 10 != 0)
|
|
||||||
{
|
|
||||||
packet.isFirstPacket = false;
|
|
||||||
packet.markerBit = false;
|
|
||||||
packet.seqNum = seqNum;
|
|
||||||
|
|
||||||
frameIn = jb.GetFrame(packet);
|
|
||||||
TEST(frameIn != 0);
|
|
||||||
|
|
||||||
// Insert a packet into a frame
|
|
||||||
TEST(kIncomplete == jb.InsertPacket(frameIn, packet));
|
|
||||||
}
|
|
||||||
loop++;
|
|
||||||
} while (loop < 98);
|
|
||||||
|
|
||||||
// insert last packet
|
|
||||||
seqNum++;
|
|
||||||
packet.isFirstPacket = false;
|
|
||||||
packet.markerBit = true;
|
|
||||||
packet.seqNum = seqNum;
|
|
||||||
|
|
||||||
frameIn = jb.GetFrame(packet);
|
|
||||||
TEST(frameIn != 0);
|
|
||||||
|
|
||||||
// Insert a packet into a frame
|
|
||||||
TEST(kIncomplete == jb.InsertPacket(frameIn, packet));
|
|
||||||
|
|
||||||
// try to get the frame, should fail
|
|
||||||
frameOut = jb.GetCompleteFrameForDecoding(10);
|
|
||||||
TEST(frameOut == 0);
|
|
||||||
|
|
||||||
// try to get the frame, should fail
|
|
||||||
frameOut = jb.GetFrameForDecoding();
|
|
||||||
TEST(frameOut == 0);
|
|
||||||
|
|
||||||
WebRtc_UWord16 nackSize = 0;
|
|
||||||
bool extended = false;
|
|
||||||
WebRtc_UWord16* list = jb.GetNackList(nackSize, extended);
|
|
||||||
|
|
||||||
TEST(nackSize == 10);
|
|
||||||
|
|
||||||
for(int i = 0; i < nackSize; i++)
|
|
||||||
{
|
|
||||||
TEST(list[i] == (1+i)*10);
|
|
||||||
}
|
|
||||||
|
|
||||||
jb.Stop();
|
|
||||||
|
|
||||||
//printf("DONE NACK\n");
|
|
||||||
|
|
||||||
//
|
|
||||||
// TEST NACK with wrap in seqNum
|
|
||||||
//
|
|
||||||
// ------- -----------------------------------------------------------------------------------
|
|
||||||
// | 65532 | | 65533 | 65534 | 65535 | x | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | x | 11 |.....| 96 |
|
|
||||||
// ------- -----------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
jb.Flush();
|
|
||||||
jb.Start();
|
|
||||||
|
|
||||||
// insert first frame
|
|
||||||
timeStamp = 33*90;
|
|
||||||
seqNum = 65532;
|
|
||||||
packet.frameType = kVideoFrameKey;
|
|
||||||
packet.isFirstPacket = true;
|
|
||||||
packet.markerBit = true;
|
|
||||||
packet.seqNum = seqNum;
|
|
||||||
packet.timestamp = timeStamp;
|
|
||||||
|
|
||||||
frameIn = jb.GetFrame(packet);
|
|
||||||
TEST(frameIn != 0);
|
|
||||||
|
|
||||||
// Insert a packet into a frame
|
|
||||||
TEST(kFirstPacket == jb.InsertPacket(frameIn, packet));
|
|
||||||
|
|
||||||
// get packet notification
|
|
||||||
TEST(timeStamp == jb.GetNextTimeStamp(10, incomingFrameType, renderTimeMs));
|
|
||||||
|
|
||||||
// check incoming frame type
|
|
||||||
TEST(incomingFrameType == kVideoFrameKey);
|
|
||||||
|
|
||||||
// get the frame
|
|
||||||
frameOut = jb.GetCompleteFrameForDecoding(10);
|
|
||||||
|
|
||||||
TEST(CheckOutFrame(frameOut, size, false) == 0);
|
|
||||||
|
|
||||||
// check the frame type
|
|
||||||
TEST(frameOut->FrameType() == kVideoFrameKey);
|
|
||||||
|
|
||||||
// Release frame (when done with decoding)
|
|
||||||
jb.ReleaseFrame(frameOut);
|
|
||||||
|
|
||||||
|
|
||||||
// insert first packet
|
|
||||||
timeStamp += 33*90;
|
|
||||||
seqNum++;
|
|
||||||
packet.frameType = kVideoFrameDelta;
|
|
||||||
packet.isFirstPacket = true;
|
|
||||||
packet.markerBit = false;
|
|
||||||
packet.seqNum = seqNum;
|
|
||||||
packet.timestamp = timeStamp;
|
|
||||||
|
|
||||||
frameIn = jb.GetFrame(packet);
|
|
||||||
TEST(frameIn != 0);
|
|
||||||
|
|
||||||
// Insert a packet into a frame
|
|
||||||
TEST(kFirstPacket == jb.InsertPacket(frameIn, packet));
|
|
||||||
|
|
||||||
// get packet notification
|
|
||||||
TEST(timeStamp == jb.GetNextTimeStamp(10, incomingFrameType, renderTimeMs));
|
|
||||||
|
|
||||||
// check incoming frame type
|
|
||||||
TEST(incomingFrameType == kVideoFrameDelta);
|
|
||||||
|
|
||||||
// get the frame
|
|
||||||
frameOut = jb.GetCompleteFrameForDecoding(10);
|
|
||||||
|
|
||||||
// it should not be complete
|
|
||||||
TEST(frameOut == 0);
|
|
||||||
|
|
||||||
// insert 98 packets
|
|
||||||
loop = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
seqNum++;
|
|
||||||
if (seqNum % 10 != 0)
|
|
||||||
{
|
|
||||||
packet.isFirstPacket = false;
|
|
||||||
packet.markerBit = false;
|
|
||||||
packet.seqNum = seqNum;
|
|
||||||
|
|
||||||
frameIn = jb.GetFrame(packet);
|
|
||||||
TEST(frameIn != 0);
|
|
||||||
|
|
||||||
// Insert a packet into a frame
|
|
||||||
TEST(kIncomplete == jb.InsertPacket(frameIn, packet));
|
|
||||||
|
|
||||||
// try to get the frame, should fail
|
|
||||||
frameOut = jb.GetCompleteFrameForDecoding(1);
|
|
||||||
TEST(frameOut == 0);
|
|
||||||
|
|
||||||
// try to get the frame, should fail
|
|
||||||
frameOut = jb.GetFrameForDecoding();
|
|
||||||
TEST(frameOut == 0);
|
|
||||||
}
|
|
||||||
loop++;
|
|
||||||
} while (loop < 98);
|
|
||||||
|
|
||||||
// insert last packet
|
|
||||||
seqNum++;
|
|
||||||
packet.isFirstPacket = false;
|
|
||||||
packet.markerBit = true;
|
|
||||||
packet.seqNum = seqNum;
|
|
||||||
|
|
||||||
frameIn = jb.GetFrame(packet);
|
|
||||||
TEST(frameIn != 0);
|
|
||||||
|
|
||||||
// Insert a packet into a frame
|
|
||||||
TEST(kIncomplete == jb.InsertPacket(frameIn, packet));
|
|
||||||
|
|
||||||
// try to get the frame, should fail
|
|
||||||
frameOut = jb.GetCompleteFrameForDecoding(10);
|
|
||||||
TEST(frameOut == 0);
|
|
||||||
|
|
||||||
// try to get the frame, should fail
|
|
||||||
frameOut = jb.GetFrameForDecoding();
|
|
||||||
TEST(frameOut == 0);
|
|
||||||
|
|
||||||
nackSize = 0;
|
|
||||||
list = jb.GetNackList(nackSize, extended);
|
|
||||||
|
|
||||||
TEST(nackSize == 10);
|
|
||||||
|
|
||||||
for(int i = 0; i < nackSize; i++)
|
|
||||||
{
|
|
||||||
TEST(list[i] == i*10);
|
|
||||||
}
|
|
||||||
|
|
||||||
jb.Stop();
|
|
||||||
|
|
||||||
//printf("DONE NACK with wrap in seqNum\n");
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// TEST delta frame with more than max number of packets
|
// TEST delta frame with more than max number of packets
|
||||||
//
|
//
|
||||||
@@ -1889,52 +1671,6 @@ int JitterBufferTest(CmdArgs& args)
|
|||||||
|
|
||||||
//printf("DONE fill frame - packets > max number of packets\n");
|
//printf("DONE fill frame - packets > max number of packets\n");
|
||||||
|
|
||||||
//
|
|
||||||
// TEST fill JB with more than max number of delta frame
|
|
||||||
//
|
|
||||||
|
|
||||||
loop = 0;
|
|
||||||
WebRtc_UWord32 timeStampStart = timeStamp + 33*90;
|
|
||||||
// insert MAX_NUMBER_OF_FRAMES frames
|
|
||||||
do
|
|
||||||
{
|
|
||||||
timeStamp += 33*90;
|
|
||||||
seqNum++;
|
|
||||||
packet.isFirstPacket = true;
|
|
||||||
packet.markerBit = true;
|
|
||||||
packet.seqNum = seqNum;
|
|
||||||
packet.timestamp = timeStamp;
|
|
||||||
|
|
||||||
frameIn = jb.GetFrame(packet);
|
|
||||||
TEST(frameIn != 0);
|
|
||||||
|
|
||||||
// Insert frame
|
|
||||||
TEST(kFirstPacket == jb.InsertPacket(frameIn, packet));
|
|
||||||
|
|
||||||
// get packet notification
|
|
||||||
TEST(timeStampStart == jb.GetNextTimeStamp(10, incomingFrameType, renderTimeMs));
|
|
||||||
|
|
||||||
// check incoming frame type
|
|
||||||
TEST(incomingFrameType == kVideoFrameDelta);
|
|
||||||
|
|
||||||
loop++;
|
|
||||||
} while (loop < kMaxNumberOfFrames);
|
|
||||||
|
|
||||||
// Max number of frames inserted
|
|
||||||
|
|
||||||
// Insert one more frame
|
|
||||||
timeStamp += 33*90;
|
|
||||||
seqNum++;
|
|
||||||
packet.isFirstPacket = true;
|
|
||||||
packet.markerBit = true;
|
|
||||||
packet.seqNum = seqNum;
|
|
||||||
|
|
||||||
// Now, no free frame - frames will be recycled until first key frame
|
|
||||||
frameIn = jb.GetFrame(packet);
|
|
||||||
TEST(frameIn); // no key, so we have recycled all frames
|
|
||||||
|
|
||||||
//printf("DONE fill JB - number of delta frames > max number of frames\n");
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// TEST fill JB with more than max number of frame (50 delta frames +
|
// TEST fill JB with more than max number of frame (50 delta frames +
|
||||||
// 51 key frames) with wrap in seqNum
|
// 51 key frames) with wrap in seqNum
|
||||||
@@ -1948,7 +1684,7 @@ int JitterBufferTest(CmdArgs& args)
|
|||||||
|
|
||||||
loop = 0;
|
loop = 0;
|
||||||
seqNum = 65485;
|
seqNum = 65485;
|
||||||
timeStampStart = timeStamp + 33*90;
|
WebRtc_UWord32 timeStampStart = timeStamp + 33*90;
|
||||||
WebRtc_UWord32 timeStampFirstKey = 0;
|
WebRtc_UWord32 timeStampFirstKey = 0;
|
||||||
VCMEncodedFrame* ptrLastDeltaFrame = NULL;
|
VCMEncodedFrame* ptrLastDeltaFrame = NULL;
|
||||||
VCMEncodedFrame* ptrFirstKeyFrame = NULL;
|
VCMEncodedFrame* ptrFirstKeyFrame = NULL;
|
||||||
@@ -2031,93 +1767,11 @@ int JitterBufferTest(CmdArgs& args)
|
|||||||
// printf("DONE fill JB - nr of delta + key frames (w/ wrap in seqNum) >
|
// printf("DONE fill JB - nr of delta + key frames (w/ wrap in seqNum) >
|
||||||
// max nr of frames\n");
|
// max nr of frames\n");
|
||||||
|
|
||||||
// Test handling empty packets
|
|
||||||
// first insert 2 empty packets
|
|
||||||
jb.ReleaseFrame(frameIn);
|
|
||||||
timeStamp = 33 * 90;
|
|
||||||
seqNum = 5;
|
|
||||||
packet.isFirstPacket = false;
|
|
||||||
packet.markerBit = false;
|
|
||||||
packet.seqNum = seqNum;
|
|
||||||
packet.timestamp = timeStamp;
|
|
||||||
packet.frameType = kFrameEmpty;
|
|
||||||
frameIn = jb.GetFrame(packet);
|
|
||||||
TEST(frameIn);
|
|
||||||
TEST(kFirstPacket == jb.InsertPacket(frameIn, packet));
|
|
||||||
|
|
||||||
seqNum = 6;
|
|
||||||
packet.isFirstPacket = false;
|
|
||||||
packet.markerBit = false;
|
|
||||||
packet.seqNum = seqNum;
|
|
||||||
packet.timestamp = timeStamp;
|
|
||||||
packet.frameType = kFrameEmpty;
|
|
||||||
TEST(kIncomplete == jb.InsertPacket(frameIn, packet));
|
|
||||||
// now insert the first data packet
|
|
||||||
seqNum = 1;
|
|
||||||
packet.isFirstPacket = true;
|
|
||||||
packet.markerBit = false;
|
|
||||||
packet.seqNum = seqNum;
|
|
||||||
packet.timestamp = timeStamp;
|
|
||||||
packet.frameType = kVideoFrameDelta;
|
|
||||||
TEST(kIncomplete == jb.InsertPacket(frameIn, packet));
|
|
||||||
// insert an additional data packet
|
|
||||||
seqNum = 2;
|
|
||||||
packet.isFirstPacket = false;
|
|
||||||
packet.markerBit = false;
|
|
||||||
packet.seqNum = seqNum;
|
|
||||||
packet.timestamp = timeStamp;
|
|
||||||
packet.frameType = kVideoFrameDelta;
|
|
||||||
TEST(kIncomplete == jb.InsertPacket(frameIn, packet));
|
|
||||||
|
|
||||||
// insert the last packet and verify frame completness
|
|
||||||
// (even though packet 4 (empty) is missing)
|
|
||||||
seqNum = 3;
|
|
||||||
packet.isFirstPacket = false;
|
|
||||||
packet.markerBit = true;
|
|
||||||
packet.seqNum = seqNum;
|
|
||||||
packet.timestamp = timeStamp;
|
|
||||||
packet.frameType = kVideoFrameDelta;
|
|
||||||
TEST(kCompleteSession == jb.InsertPacket(frameIn, packet));
|
|
||||||
jb.Flush();
|
|
||||||
|
|
||||||
// testing that empty packets do not clog the jitter buffer
|
|
||||||
// Set hybrid mode
|
|
||||||
jb.SetNackMode(kNackHybrid, kLowRttNackMs, -1);
|
|
||||||
TEST(jb.GetNackMode() == kNackHybrid);
|
|
||||||
|
|
||||||
int maxSize = 100;
|
|
||||||
seqNum = 3;
|
|
||||||
VCMEncodedFrame* testFrame;
|
|
||||||
for (int i = 0; i < maxSize + 10; i++)
|
|
||||||
{
|
|
||||||
timeStamp += 33 * 90;
|
|
||||||
packet.isFirstPacket = false;
|
|
||||||
packet.markerBit = false;
|
|
||||||
packet.seqNum = seqNum;
|
|
||||||
packet.timestamp = timeStamp;
|
|
||||||
packet.frameType = kFrameEmpty;
|
|
||||||
testFrame = jb.GetFrame(packet);
|
|
||||||
TEST(frameIn != 0);
|
|
||||||
TEST(kFirstPacket == jb.InsertPacket(testFrame, packet));
|
|
||||||
}
|
|
||||||
// verify insertion of a data packet (old empty frames will be flushed)
|
|
||||||
timeStamp += 33 * 90;
|
|
||||||
packet.isFirstPacket = true;
|
|
||||||
packet.markerBit = false;
|
|
||||||
packet.seqNum = seqNum;
|
|
||||||
packet.timestamp = timeStamp;
|
|
||||||
packet.frameType = kFrameEmpty;
|
|
||||||
testFrame = jb.GetFrame(packet);
|
|
||||||
TEST(frameIn != 0);
|
|
||||||
|
|
||||||
jb.SetNackMode(kNoNack, -1, -1);
|
|
||||||
jb.Flush();
|
|
||||||
|
|
||||||
// Testing that 1 empty packet inserted last will not be set for decoding
|
// Testing that 1 empty packet inserted last will not be set for decoding
|
||||||
seqNum = 3;
|
seqNum = 3;
|
||||||
// Insert one empty packet per frame, should never return the last timestamp
|
// Insert one empty packet per frame, should never return the last timestamp
|
||||||
// inserted. Only return empty frames in the presence of subsequent frames.
|
// inserted. Only return empty frames in the presence of subsequent frames.
|
||||||
maxSize = 1000;
|
int maxSize = 1000;
|
||||||
for (int i = 0; i < maxSize + 10; i++)
|
for (int i = 0; i < maxSize + 10; i++)
|
||||||
{
|
{
|
||||||
timeStamp += 33 * 90;
|
timeStamp += 33 * 90;
|
||||||
@@ -2127,7 +1781,7 @@ int JitterBufferTest(CmdArgs& args)
|
|||||||
packet.seqNum = seqNum;
|
packet.seqNum = seqNum;
|
||||||
packet.timestamp = timeStamp;
|
packet.timestamp = timeStamp;
|
||||||
packet.frameType = kFrameEmpty;
|
packet.frameType = kFrameEmpty;
|
||||||
testFrame = jb.GetFrameForDecoding();
|
VCMEncodedFrame* testFrame = jb.GetFrameForDecoding();
|
||||||
// timestamp should bever be the last TS inserted
|
// timestamp should bever be the last TS inserted
|
||||||
if (testFrame != NULL)
|
if (testFrame != NULL)
|
||||||
{
|
{
|
||||||
@@ -2325,6 +1979,8 @@ int JitterBufferTest(CmdArgs& args)
|
|||||||
// Only last NALU is complete
|
// Only last NALU is complete
|
||||||
TEST(CheckOutFrame(frameOut, packet.sizeBytes, false) == 0);
|
TEST(CheckOutFrame(frameOut, packet.sizeBytes, false) == 0);
|
||||||
|
|
||||||
|
jb.ReleaseFrame(frameOut);
|
||||||
|
|
||||||
jb.Flush();
|
jb.Flush();
|
||||||
|
|
||||||
// Three reordered H263 packets with bits.
|
// Three reordered H263 packets with bits.
|
||||||
@@ -2366,6 +2022,7 @@ int JitterBufferTest(CmdArgs& args)
|
|||||||
TEST(frameOut != NULL);
|
TEST(frameOut != NULL);
|
||||||
const WebRtc_UWord8* buf = frameOut->Buffer();
|
const WebRtc_UWord8* buf = frameOut->Buffer();
|
||||||
TEST(buf[packet.sizeBytes - 1] == (startByte | endByte));
|
TEST(buf[packet.sizeBytes - 1] == (startByte | endByte));
|
||||||
|
jb.ReleaseFrame(frameOut);
|
||||||
// First packet lost, second packet with bits.
|
// First packet lost, second packet with bits.
|
||||||
|
|
||||||
// The JB only outputs frame if the next one arrives:
|
// The JB only outputs frame if the next one arrives:
|
||||||
@@ -2392,6 +2049,7 @@ int JitterBufferTest(CmdArgs& args)
|
|||||||
frameOut = jb.GetFrameForDecoding();
|
frameOut = jb.GetFrameForDecoding();
|
||||||
TEST(frameOut != NULL);
|
TEST(frameOut != NULL);
|
||||||
TEST(frameOut->Length() == 0);
|
TEST(frameOut->Length() == 0);
|
||||||
|
jb.ReleaseFrame(frameOut);
|
||||||
|
|
||||||
data[0] = oldData1;
|
data[0] = oldData1;
|
||||||
data[packet.sizeBytes - 1] = oldData2;
|
data[packet.sizeBytes - 1] = oldData2;
|
||||||
@@ -2425,6 +2083,7 @@ int JitterBufferTest(CmdArgs& args)
|
|||||||
|
|
||||||
TEST(frameOut != NULL);
|
TEST(frameOut != NULL);
|
||||||
TEST(CheckOutFrame(frameOut, packet.sizeBytes, false) == 0);
|
TEST(CheckOutFrame(frameOut, packet.sizeBytes, false) == 0);
|
||||||
|
jb.ReleaseFrame(frameOut);
|
||||||
|
|
||||||
jb.Stop();
|
jb.Stop();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user