VCM/JB: Porting jitter_buffer_test to gtest.
Tests were not modified, but ported as is.
R=stefan@webrtc.org
Review URL: https://webrtc-codereview.appspot.com/1391004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@3956 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/modules/video_coding/main/source/jitter_buffer_unittest.cc b/webrtc/modules/video_coding/main/source/jitter_buffer_unittest.cc
index cac7a22..3c377cf 100644
--- a/webrtc/modules/video_coding/main/source/jitter_buffer_unittest.cc
+++ b/webrtc/modules/video_coding/main/source/jitter_buffer_unittest.cc
@@ -13,6 +13,7 @@
#include <list>
#include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/modules/video_coding/main/source/frame_buffer.h"
#include "webrtc/modules/video_coding/main/source/jitter_buffer.h"
#include "webrtc/modules/video_coding/main/source/media_opt_util.h"
#include "webrtc/modules/video_coding/main/source/packet.h"
@@ -22,6 +23,101 @@
namespace webrtc {
+class TestBasicJitterBuffer : public ::testing::Test {
+ protected:
+ virtual void SetUp() {
+ clock_.reset(new SimulatedClock(0));
+ jitter_buffer_.reset(new VCMJitterBuffer(clock_.get(),
+ &event_factory_, -1, -1, true));
+ jitter_buffer_->Start();
+ seq_num_ = 1234;
+ timestamp_ = 0;
+ size_ = 1400;
+ // Data vector - 0, 0, 0x80, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0x80, 3....
+ data_[0] = 0;
+ data_[1] = 0;
+ data_[2] = 0x80;
+ int count = 3;
+ for (unsigned int i = 3; i < sizeof(data_) - 3; ++i) {
+ data_[i] = count;
+ count++;
+ if (count == 10) {
+ data_[i + 1] = 0;
+ data_[i + 2] = 0;
+ data_[i + 3] = 0x80;
+ count = 3;
+ i += 3;
+ }
+ }
+ packet_.reset(new VCMPacket(data_, size_, seq_num_, timestamp_, true));
+ }
+
+ VCMEncodedFrame* DecodeCompleteFrame() {
+ uint32_t timestamp = 0;
+ bool found_frame = jitter_buffer_->NextCompleteTimestamp(10, ×tamp);
+ if (!found_frame)
+ return NULL;
+ VCMEncodedFrame* frame = jitter_buffer_->ExtractAndSetDecode(timestamp);
+ return frame;
+ }
+
+ VCMEncodedFrame* DecodeIncompleteFrame() {
+ uint32_t timestamp = 0;
+ bool found_frame = jitter_buffer_->NextMaybeIncompleteTimestamp(×tamp);
+ if (!found_frame)
+ return NULL;
+ VCMEncodedFrame* frame = jitter_buffer_->ExtractAndSetDecode(timestamp);
+ return frame;
+ }
+ int CheckOutFrame(VCMEncodedFrame* frame_out,
+ unsigned int size,
+ bool startCode) {
+ EXPECT_FALSE(frame_out == NULL);
+
+ const uint8_t* outData = frame_out->Buffer();
+ unsigned int i = 0;
+
+ if (startCode) {
+ EXPECT_EQ(0, outData[0]);
+ EXPECT_EQ(0, outData[1]);
+ EXPECT_EQ(0, outData[2]);
+ EXPECT_EQ(1, outData[3]);
+ i += 4;
+ }
+
+ EXPECT_EQ(size, frame_out->Length());
+ int count = 3;
+ for (; i < size; i++) {
+ if (outData[i] == 0 && outData[i + 1] == 0 && outData[i + 2] == 0x80) {
+ i += 2;
+ } else if (startCode && outData[i] == 0 && outData[i + 1] == 0) {
+ EXPECT_EQ(0, outData[0]);
+ EXPECT_EQ(0, outData[1]);
+ EXPECT_EQ(0, outData[2]);
+ EXPECT_EQ(1, outData[3]);
+ i += 3;
+ } else {
+ EXPECT_EQ(count, outData[i]);
+ count++;
+ if (count == 10) {
+ count = 3;
+ }
+ }
+ }
+ return 0;
+ }
+
+ uint16_t seq_num_;
+ uint32_t timestamp_;
+ int size_;
+ uint8_t data_[1500];
+ scoped_ptr<VCMJitterBuffer> jitter_buffer_;
+ scoped_ptr<VCMPacket> packet_;
+ scoped_ptr<SimulatedClock> clock_;
+ NullEventFactory event_factory_;
+};
+
+
class TestRunningJitterBuffer : public ::testing::Test {
protected:
enum { kDataBufferSize = 10 };
@@ -144,6 +240,1169 @@
}
};
+TEST_F(TestBasicJitterBuffer, StopRunning) {
+ jitter_buffer_->Stop();
+ EXPECT_EQ(0, jitter_buffer_->GetFrame(*packet_));
+ EXPECT_TRUE(NULL == DecodeCompleteFrame());
+ EXPECT_TRUE(NULL == DecodeIncompleteFrame());
+ jitter_buffer_->Start();
+ // Allow decoding with errors.
+ jitter_buffer_->DecodeWithErrors(true);
+
+ VCMEncodedFrame* frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+ // No packets inserted.
+ EXPECT_TRUE(NULL == DecodeCompleteFrame());
+ EXPECT_TRUE(NULL == DecodeIncompleteFrame());
+}
+
+TEST_F(TestBasicJitterBuffer, SinglePacketFrame) {
+ // Always start with a complete key frame.
+ packet_->frameType = kVideoFrameKey;
+ packet_->isFirstPacket = true;
+ packet_->markerBit = true;
+ packet_->timestamp += 123*90;
+
+ // Insert the packet to the jitter buffer and get a frame.
+ VCMEncodedFrame* frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_EQ(kCompleteSession, jitter_buffer_->InsertPacket(frame_in, *packet_));
+ VCMEncodedFrame* frame_out = DecodeCompleteFrame();
+ EXPECT_EQ(0, CheckOutFrame(frame_out, size_, false));
+ EXPECT_EQ(kVideoFrameKey, frame_out->FrameType());
+}
+
+TEST_F(TestBasicJitterBuffer, DualPacketFrame) {
+ packet_->frameType = kVideoFrameKey;
+ packet_->isFirstPacket = true;
+ packet_->markerBit = false;
+
+ VCMEncodedFrame* frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+ EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(frame_in, *packet_));
+ VCMEncodedFrame* frame_out = DecodeCompleteFrame();
+ // Should not be complete.
+ EXPECT_TRUE(frame_out == NULL);
+
+ ++seq_num_;
+ packet_->isFirstPacket = false;
+ packet_->markerBit = true;
+ packet_->seqNum = seq_num_;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_FALSE(frame_in == NULL);
+
+ EXPECT_EQ(kCompleteSession, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ frame_out = DecodeCompleteFrame();
+ EXPECT_EQ(0, CheckOutFrame(frame_out, 2 * size_, false));
+
+ EXPECT_EQ(kVideoFrameKey, frame_out->FrameType());
+}
+
+TEST_F(TestBasicJitterBuffer, 100PacketKeyFrame) {
+ packet_->frameType = kVideoFrameKey;
+ packet_->isFirstPacket = true;
+ packet_->markerBit = false;
+ VCMEncodedFrame* frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ VCMEncodedFrame* frame_out = DecodeCompleteFrame();
+
+ // Frame should not be complete.
+ EXPECT_TRUE(frame_out == NULL);
+
+ // Insert 98 frames.
+ int loop = 0;
+ do {
+ seq_num_++;
+ packet_->isFirstPacket = false;
+ packet_->markerBit = false;
+ packet_->seqNum = seq_num_;
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_FALSE(frame_in == NULL);
+
+ EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(frame_in, *packet_));
+ loop++;
+ } while (loop < 98);
+
+ // Insert last packet.
+ ++seq_num_;
+ packet_->isFirstPacket = false;
+ packet_->markerBit = true;
+ packet_->seqNum = seq_num_;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_FALSE(frame_in == NULL);
+
+ EXPECT_EQ(kCompleteSession, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ frame_out = DecodeCompleteFrame();
+
+ EXPECT_EQ(0, CheckOutFrame(frame_out, 100 * size_, false));
+ EXPECT_EQ(kVideoFrameKey, frame_out->FrameType());
+}
+
+TEST_F(TestBasicJitterBuffer, 100PacketDeltaFrame) {
+ // Always start with a complete key frame.
+ packet_->frameType = kVideoFrameKey;
+ packet_->isFirstPacket = true;
+ packet_->markerBit = true;
+
+ VCMEncodedFrame* frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_EQ(kCompleteSession, jitter_buffer_->InsertPacket(frame_in, *packet_));
+ VCMEncodedFrame* frame_out = DecodeCompleteFrame();
+ EXPECT_FALSE(frame_out == NULL);
+
+ ++seq_num_;
+ packet_->seqNum = seq_num_;
+ packet_->markerBit = false;
+ packet_->frameType = kVideoFrameDelta;
+ packet_->timestamp += 33 * 90;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_FALSE(frame_in == NULL);
+
+ EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ frame_out = DecodeCompleteFrame();
+
+ // Frame should not be complete.
+ EXPECT_TRUE(frame_out == NULL);
+
+ packet_->isFirstPacket = false;
+ // Insert 98 frames.
+ int loop = 0;
+ do {
+ ++seq_num_;
+ packet_->seqNum = seq_num_;
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_FALSE(frame_in == NULL);
+ // Insert a packet into a frame.
+ EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(frame_in, *packet_));
+ loop++;
+ } while (loop < 98);
+
+ // Insert the last packet.
+ ++seq_num_;
+ packet_->isFirstPacket = false;
+ packet_->markerBit = true;
+ packet_->seqNum = seq_num_;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_FALSE(frame_in == NULL);
+
+ EXPECT_EQ(kCompleteSession, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ frame_out = DecodeCompleteFrame();
+
+ EXPECT_EQ(0, CheckOutFrame(frame_out, 100 * size_, false));
+ EXPECT_EQ(kVideoFrameDelta, frame_out->FrameType());
+}
+
+TEST_F(TestBasicJitterBuffer, PacketReorderingReverseOrder) {
+ // Insert the "first" packet last.
+ seq_num_ += 100;
+ packet_->frameType = kVideoFrameKey;
+ packet_->isFirstPacket = false;
+ packet_->markerBit = true;
+ packet_->seqNum = seq_num_;
+ packet_->timestamp = timestamp_;
+
+ VCMEncodedFrame* frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ VCMEncodedFrame* frame_out = DecodeCompleteFrame();
+
+ EXPECT_TRUE(frame_out == NULL);
+
+ // Insert 98 packets.
+ int loop = 0;
+ do {
+ seq_num_--;
+ packet_->isFirstPacket = false;
+ packet_->markerBit = false;
+ packet_->seqNum = seq_num_;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(frame_in, *packet_));
+ loop++;
+ } while (loop < 98);
+
+ // Insert the last packet.
+ seq_num_--;
+ packet_->isFirstPacket = true;
+ packet_->markerBit = false;
+ packet_->seqNum = seq_num_;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ EXPECT_EQ(kCompleteSession, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ frame_out = DecodeCompleteFrame();;
+
+ EXPECT_EQ(0, CheckOutFrame(frame_out, 100 * size_, false));
+
+ EXPECT_EQ(kVideoFrameKey, frame_out->FrameType());
+}
+
+TEST_F(TestBasicJitterBuffer, FrameReordering2Frames2PacketsEach) {
+ packet_->frameType = kVideoFrameDelta;
+ packet_->isFirstPacket = true;
+ packet_->markerBit = false;
+
+ VCMEncodedFrame* frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ VCMEncodedFrame* frame_out = DecodeCompleteFrame();
+
+ EXPECT_TRUE(frame_out == NULL);
+
+ seq_num_++;
+ packet_->isFirstPacket = false;
+ packet_->markerBit = true;
+ packet_->seqNum = seq_num_;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ EXPECT_EQ(kCompleteSession, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ // check that we fail to get frame since seqnum is not continuous
+ frame_out = DecodeCompleteFrame();
+ EXPECT_TRUE(frame_out == NULL);
+
+ seq_num_ -= 3;
+ timestamp_ -= 33*90;
+ packet_->frameType = kVideoFrameKey;
+ packet_->isFirstPacket = true;
+ packet_->markerBit = false;
+ packet_->seqNum = seq_num_;
+ packet_->timestamp = timestamp_;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ frame_out = DecodeCompleteFrame();
+
+ // It should not be complete.
+ EXPECT_TRUE(frame_out == NULL);
+
+ seq_num_++;
+ packet_->isFirstPacket = false;
+ packet_->markerBit = true;
+ packet_->seqNum = seq_num_;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ EXPECT_EQ(kCompleteSession, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ frame_out = DecodeCompleteFrame();
+
+ EXPECT_EQ(0, CheckOutFrame(frame_out, 2 * size_, false));
+
+ EXPECT_EQ(kVideoFrameKey, frame_out->FrameType());
+
+ jitter_buffer_->ReleaseFrame(frame_out);
+
+ frame_out = DecodeCompleteFrame();
+
+ EXPECT_EQ(0, CheckOutFrame(frame_out, 2 * size_, false));
+
+ EXPECT_EQ(kVideoFrameDelta, frame_out->FrameType());
+}
+
+TEST_F(TestBasicJitterBuffer, DuplicatePackets) {
+ packet_->frameType = kVideoFrameKey;
+ packet_->isFirstPacket = true;
+ packet_->markerBit = false;
+ packet_->seqNum = seq_num_;
+ packet_->timestamp = timestamp_;
+
+ VCMEncodedFrame* frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ VCMEncodedFrame* frame_out = DecodeCompleteFrame();
+
+ EXPECT_TRUE(frame_out == NULL);
+
+ packet_->isFirstPacket = false;
+ packet_->markerBit = true;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ // Insert a packet into a frame.
+ EXPECT_EQ(kDuplicatePacket, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ seq_num_++;
+ packet_->seqNum = seq_num_;
+
+ EXPECT_EQ(kCompleteSession, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ frame_out = DecodeCompleteFrame();
+
+ EXPECT_EQ(0, CheckOutFrame(frame_out, 2 * size_, false));
+
+ EXPECT_EQ(kVideoFrameKey, frame_out->FrameType());
+}
+
+TEST_F(TestBasicJitterBuffer, H264InsertStartCode) {
+ packet_->frameType = kVideoFrameKey;
+ packet_->isFirstPacket = true;
+ packet_->markerBit = false;
+ packet_->seqNum = seq_num_;
+ packet_->timestamp = timestamp_;
+ packet_->insertStartCode = true;
+
+ VCMEncodedFrame* frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ VCMEncodedFrame* frame_out = DecodeCompleteFrame();
+
+ // Frame should not be complete.
+ EXPECT_TRUE(frame_out == NULL);
+
+ seq_num_++;
+ packet_->isFirstPacket = false;
+ packet_->markerBit = true;
+ packet_->seqNum = seq_num_;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ EXPECT_EQ(kCompleteSession, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ frame_out = DecodeCompleteFrame();
+
+ EXPECT_EQ(0, CheckOutFrame(frame_out, size_ * 2 + 4 * 2, true));
+
+ EXPECT_EQ(kVideoFrameKey, frame_out->FrameType());
+}
+
+TEST_F(TestBasicJitterBuffer, PacketLoss) {
+ // Verify missing packets statistics and not decodable packets statistics.
+ // Insert 10 frames consisting of 4 packets and remove one from all of them.
+ // The last packet is an empty (non-media) packet.
+
+ // Select a start seqNum which triggers a difficult wrap situation
+ // The JB will only output (incomplete)frames if the next one has started
+ // to arrive. Start by inserting one frame (key).
+ jitter_buffer_->DecodeWithErrors(true);
+ seq_num_ = 0xffff - 4;
+ seq_num_++;
+ packet_->frameType = kVideoFrameKey;
+ packet_->isFirstPacket = true;
+ packet_->markerBit = false;
+ packet_->seqNum = seq_num_;
+ packet_->timestamp = timestamp_;
+ packet_->completeNALU = kNaluStart;
+ VCMEncodedFrame* frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+ EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ for (int i = 0; i < 11; ++i) {
+ webrtc::FrameType frametype = kVideoFrameDelta;
+ seq_num_++;
+ timestamp_ += 33*90;
+ packet_->frameType = frametype;
+ packet_->isFirstPacket = true;
+ packet_->markerBit = false;
+ packet_->seqNum = seq_num_;
+ packet_->timestamp = timestamp_;
+ packet_->completeNALU = kNaluStart;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ VCMEncodedFrame* frame_out = DecodeCompleteFrame();
+
+ // Should not be complete.
+ EXPECT_TRUE(frame_out == NULL);
+
+ seq_num_ += 2;
+ packet_->isFirstPacket = false;
+ packet_->markerBit = true;
+ packet_->seqNum = seq_num_;
+ packet_->completeNALU = kNaluEnd;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+
+ // Insert an empty (non-media) packet.
+ seq_num_++;
+ packet_->isFirstPacket = false;
+ packet_->markerBit = false;
+ packet_->seqNum = seq_num_;
+ packet_->completeNALU = kNaluEnd;
+ packet_->frameType = kFrameEmpty;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ frame_out = DecodeIncompleteFrame();
+
+ // One of the packets has been discarded by the jitter buffer.
+ // Last frame can't be extracted yet.
+ if (i < 10) {
+ EXPECT_EQ(0, CheckOutFrame(frame_out, size_, false));
+
+ if (i == 0) {
+ EXPECT_EQ(kVideoFrameKey, frame_out->FrameType());
+ } else {
+ EXPECT_EQ(frametype, frame_out->FrameType());
+ }
+ EXPECT_FALSE(frame_out->Complete());
+ EXPECT_FALSE(frame_out->MissingFrame());
+ }
+
+ jitter_buffer_->ReleaseFrame(frame_out);
+ }
+
+ EXPECT_EQ(10, jitter_buffer_->num_not_decodable_packets());
+
+ // Insert 3 old packets and verify that we have 3 discarded packets
+ // Match value to actual latest timestamp decoded.
+ timestamp_ -= 33 * 90;
+ packet_->timestamp = timestamp_ - 1000;
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in == NULL);
+
+ packet_->timestamp = timestamp_ - 500;
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in == NULL);
+
+ packet_->timestamp = timestamp_ - 100;
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in == NULL);
+
+ EXPECT_EQ(3, jitter_buffer_->num_discarded_packets());
+
+ jitter_buffer_->Flush();
+
+ // This statistic shouldn't be reset by a flush.
+ EXPECT_EQ(3, jitter_buffer_->num_discarded_packets());
+}
+
+TEST_F(TestBasicJitterBuffer, DeltaFrame100PacketsWithSeqNumWrap) {
+ seq_num_ = 0xfff0;
+ packet_->frameType = kVideoFrameKey;
+ packet_->isFirstPacket = true;
+ packet_->markerBit = false;
+ packet_->seqNum = seq_num_;
+ packet_->timestamp = timestamp_;
+
+ VCMEncodedFrame* frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ VCMEncodedFrame* frame_out = DecodeCompleteFrame();
+
+ EXPECT_TRUE(frame_out == NULL);
+
+ int loop = 0;
+ do {
+ seq_num_++;
+ packet_->isFirstPacket = false;
+ packet_->markerBit = false;
+ packet_->seqNum = seq_num_;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ frame_out = DecodeCompleteFrame();
+
+ EXPECT_TRUE(frame_out == NULL);
+
+ loop++;
+ } while (loop < 98);
+
+ seq_num_++;
+ packet_->isFirstPacket = false;
+ packet_->markerBit = true;
+ packet_->seqNum = seq_num_;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ EXPECT_EQ(kCompleteSession, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ frame_out = DecodeCompleteFrame();
+
+ EXPECT_EQ(0, CheckOutFrame(frame_out, 100 * size_, false));
+
+ EXPECT_EQ(kVideoFrameKey, frame_out->FrameType());
+}
+
+TEST_F(TestBasicJitterBuffer, PacketReorderingReverseWithNegSeqNumWrap) {
+ // Insert "first" packet last seqnum.
+ seq_num_ = 10;
+ packet_->frameType = kVideoFrameKey;
+ packet_->isFirstPacket = false;
+ packet_->markerBit = true;
+ packet_->seqNum = seq_num_;
+
+ VCMEncodedFrame* frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(frame_in, *packet_));
+ VCMEncodedFrame* frame_out = DecodeCompleteFrame();
+
+ // Should not be complete.
+ EXPECT_TRUE(frame_out == NULL);
+
+ // Insert 98 frames.
+ int loop = 0;
+ do {
+ seq_num_--;
+ packet_->isFirstPacket = false;
+ packet_->markerBit = false;
+ packet_->seqNum = seq_num_;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ frame_out = DecodeCompleteFrame();
+
+ EXPECT_TRUE(frame_out == NULL);
+
+ loop++;
+ } while (loop < 98);
+
+ // Insert last packet.
+ seq_num_--;
+ packet_->isFirstPacket = true;
+ packet_->markerBit = false;
+ packet_->seqNum = seq_num_;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ EXPECT_EQ(kCompleteSession, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ frame_out = DecodeCompleteFrame();
+ EXPECT_EQ(0, CheckOutFrame(frame_out, 100 * size_, false));
+ EXPECT_EQ(kVideoFrameKey, frame_out->FrameType());
+}
+
+TEST_F(TestBasicJitterBuffer, TestInsertOldFrame) {
+ // ------- -------
+ // | 2 | | 1 |
+ // ------- -------
+ // t = 3000 t = 2000
+ seq_num_ = 2;
+ timestamp_ = 3000;
+ packet_->frameType = kVideoFrameKey;
+ packet_->isFirstPacket = true;
+ packet_->markerBit = true;
+ packet_->timestamp = timestamp_;
+ packet_->seqNum = seq_num_;
+
+ VCMEncodedFrame* frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ EXPECT_EQ(kCompleteSession, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ VCMEncodedFrame* frame_out = DecodeCompleteFrame();
+ EXPECT_EQ(3000u, frame_out->TimeStamp());
+
+ EXPECT_EQ(0, CheckOutFrame(frame_out, size_, false));
+
+ EXPECT_EQ(kVideoFrameKey, frame_out->FrameType());
+
+ jitter_buffer_->ReleaseFrame(frame_out);
+
+ seq_num_--;
+ timestamp_ = 2000;
+ packet_->frameType = kVideoFrameDelta;
+ packet_->isFirstPacket = true;
+ packet_->markerBit = true;
+ packet_->seqNum = seq_num_;
+ packet_->timestamp = timestamp_;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ // Changed behavior, never insert packets into frames older than the
+ // last decoded frame.
+ EXPECT_TRUE(frame_in == NULL);
+}
+
+TEST_F(TestBasicJitterBuffer, TestInsertOldFrameWithSeqNumWrap) {
+ // ------- -------
+ // | 2 | | 1 |
+ // ------- -------
+ // t = 3000 t = 0xffffff00
+
+ seq_num_ = 2;
+ timestamp_ = 3000;
+ packet_->frameType = kVideoFrameKey;
+ packet_->isFirstPacket = true;
+ packet_->markerBit = true;
+ packet_->seqNum = seq_num_;
+ packet_->timestamp = timestamp_;
+
+ VCMEncodedFrame* frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ EXPECT_EQ(kCompleteSession, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ VCMEncodedFrame* frame_out = DecodeCompleteFrame();
+ EXPECT_EQ(timestamp_, frame_out->TimeStamp());
+
+ EXPECT_EQ(0, CheckOutFrame(frame_out, size_, false));
+
+ EXPECT_EQ(kVideoFrameKey, frame_out->FrameType());
+
+ jitter_buffer_->ReleaseFrame(frame_out);
+
+ seq_num_--;
+ timestamp_ = 0xffffff00;
+ packet_->frameType = kVideoFrameDelta;
+ packet_->isFirstPacket = true;
+ packet_->markerBit = true;
+ packet_->seqNum = seq_num_;
+ packet_->timestamp = timestamp_;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ // This timestamp is old.
+ EXPECT_TRUE(frame_in == NULL);
+}
+
+TEST_F(TestBasicJitterBuffer, TimestampWrap) {
+ // --------------- ---------------
+ // | 1 | 2 | | 3 | 4 |
+ // --------------- ---------------
+ // t = 0xffffff00 t = 33*90
+
+ timestamp_ = 0xffffff00;
+ packet_->frameType = kVideoFrameKey;
+ packet_->isFirstPacket = true;
+ packet_->markerBit = false;
+ packet_->seqNum = seq_num_;
+ packet_->timestamp = timestamp_;
+
+ VCMEncodedFrame* frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ VCMEncodedFrame* frame_out = DecodeCompleteFrame();
+
+ EXPECT_TRUE(frame_out == NULL);
+
+ seq_num_++;
+ packet_->isFirstPacket = false;
+ packet_->markerBit = true;
+ packet_->seqNum = seq_num_;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ EXPECT_EQ(kCompleteSession, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ frame_out = DecodeCompleteFrame();
+
+ EXPECT_EQ(0, CheckOutFrame(frame_out, 2 * size_, false));
+
+ jitter_buffer_->ReleaseFrame(frame_out);
+
+ seq_num_++;
+ timestamp_ += 33*90;
+ packet_->frameType = kVideoFrameDelta;
+ packet_->isFirstPacket = true;
+ packet_->markerBit = false;
+ packet_->seqNum = seq_num_;
+ packet_->timestamp = timestamp_;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ frame_out = DecodeCompleteFrame();
+
+ EXPECT_TRUE(frame_out == NULL);
+
+ seq_num_++;
+ packet_->isFirstPacket = false;
+ packet_->markerBit = true;
+ packet_->seqNum = seq_num_;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ EXPECT_EQ(kCompleteSession, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ frame_out = DecodeCompleteFrame();
+
+ EXPECT_EQ(0, CheckOutFrame(frame_out, 2 * size_, false));
+
+ EXPECT_EQ(kVideoFrameDelta, frame_out->FrameType());
+}
+
+TEST_F(TestBasicJitterBuffer, 2FrameWithTimestampWrap) {
+ // ------- -------
+ // | 1 | | 2 |
+ // ------- -------
+ // t = 0xffffff00 t = 2700
+
+ timestamp_ = 0xffffff00;
+ packet_->frameType = kVideoFrameKey;
+ packet_->isFirstPacket = true;
+ packet_->markerBit = true;
+ packet_->timestamp = timestamp_;
+
+ VCMEncodedFrame* frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ // Insert first frame (session will be complete).
+ EXPECT_EQ(kCompleteSession, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ // Insert next frame.
+ seq_num_++;
+ timestamp_ = 2700;
+ packet_->frameType = kVideoFrameDelta;
+ packet_->isFirstPacket = true;
+ packet_->markerBit = true;
+ packet_->seqNum = seq_num_;
+ packet_->timestamp = timestamp_;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ EXPECT_EQ(kCompleteSession, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ VCMEncodedFrame* frame_out = DecodeCompleteFrame();
+ EXPECT_EQ(0xffffff00, frame_out->TimeStamp());
+
+ EXPECT_EQ(0, CheckOutFrame(frame_out, size_, false));
+
+ EXPECT_EQ(kVideoFrameKey, frame_out->FrameType());
+
+ VCMEncodedFrame* frame_out2 = DecodeCompleteFrame();
+ EXPECT_EQ(2700u, frame_out2->TimeStamp());
+
+ EXPECT_EQ(0, CheckOutFrame(frame_out2, size_, false));
+
+ EXPECT_EQ(kVideoFrameDelta, frame_out2->FrameType());
+}
+
+TEST_F(TestBasicJitterBuffer, Insert2FramesReOrderedWithTimestampWrap) {
+ // ------- -------
+ // | 2 | | 1 |
+ // ------- -------
+ // t = 2700 t = 0xffffff00
+
+ seq_num_ = 2;
+ timestamp_ = 2700;
+ packet_->frameType = kVideoFrameDelta;
+ packet_->isFirstPacket = true;
+ packet_->markerBit = true;
+ packet_->seqNum = seq_num_;
+ packet_->timestamp = timestamp_;
+
+ VCMEncodedFrame* frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ EXPECT_EQ(kCompleteSession, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ // Insert second frame
+ seq_num_--;
+ timestamp_ = 0xffffff00;
+ packet_->frameType = kVideoFrameKey;
+ packet_->isFirstPacket = true;
+ packet_->markerBit = true;
+ packet_->seqNum = seq_num_;
+ packet_->timestamp = timestamp_;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ EXPECT_EQ(kCompleteSession, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ VCMEncodedFrame* frame_out = DecodeCompleteFrame();
+ EXPECT_EQ(0xffffff00, frame_out->TimeStamp());
+
+ EXPECT_EQ(0, CheckOutFrame(frame_out, size_, false));
+
+ EXPECT_EQ(kVideoFrameKey, frame_out->FrameType());
+
+ VCMEncodedFrame* frame_out2 = DecodeCompleteFrame();
+ EXPECT_EQ(2700u, frame_out2->TimeStamp());
+
+ EXPECT_EQ(0, CheckOutFrame(frame_out2, size_, false));
+
+ EXPECT_EQ(kVideoFrameDelta, frame_out2->FrameType());
+}
+
+TEST_F(TestBasicJitterBuffer, DeltaFrameWithMoreThanMaxNumberOfPackets) {
+ int loop = 0;
+ bool firstPacket = true;
+ VCMEncodedFrame* frame_in;
+ // Insert kMaxPacketsInJitterBuffer into frame.
+ do {
+ seq_num_++;
+ packet_->isFirstPacket = false;
+ packet_->markerBit = false;
+ packet_->seqNum = seq_num_;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ if (firstPacket) {
+ EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(frame_in, *packet_));
+ firstPacket = false;
+ } else {
+ EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(frame_in, *packet_));
+ }
+
+ loop++;
+ } while (loop < kMaxPacketsInSession);
+
+ // Max number of packets inserted.
+ // Insert one more packet.
+ seq_num_++;
+ packet_->isFirstPacket = false;
+ packet_->markerBit = true;
+ packet_->seqNum = seq_num_;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+ // Insert the packet -> frame recycled.
+ EXPECT_EQ(kSizeError, jitter_buffer_->InsertPacket(frame_in, *packet_));
+ EXPECT_TRUE(NULL == DecodeCompleteFrame());
+
+}
+
+TEST_F(TestBasicJitterBuffer, ExceedNumOfFrameWithSeqNumWrap) {
+ // TEST fill JB with more than max number of frame (50 delta frames +
+ // 51 key frames) with wrap in seq_num_
+ //
+ // --------------------------------------------------------------
+ // | 65485 | 65486 | 65487 | .... | 65535 | 0 | 1 | 2 | .....| 50 |
+ // --------------------------------------------------------------
+ // |<-----------delta frames------------->|<------key frames----->|
+
+ int loop = 0;
+ seq_num_ = 65485;
+ VCMEncodedFrame* ptrLastDeltaFrame = NULL;
+ VCMEncodedFrame* ptrFirstKeyFrame = NULL;
+ VCMEncodedFrame* frame_in;
+ // Insert MAX_NUMBER_OF_FRAMES frames.
+ do {
+ timestamp_ += 33*90;
+ seq_num_++;
+ packet_->isFirstPacket = true;
+ packet_->markerBit = true;
+ packet_->seqNum = seq_num_;
+ packet_->timestamp = timestamp_;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_TRUE(frame_in != NULL);
+
+ if (loop == 49) { // last delta
+ ptrLastDeltaFrame = frame_in;
+ }
+ if (loop == 50) { // first key
+ ptrFirstKeyFrame = frame_in;
+ packet_->frameType = kVideoFrameKey;
+ }
+
+ // Insert frame.
+ EXPECT_EQ(kCompleteSession,
+ jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ loop++;
+ } while (loop < kMaxNumberOfFrames);
+
+ // Max number of frames inserted.
+
+ // Insert one more frame.
+ timestamp_ += 33*90;
+ seq_num_++;
+ packet_->isFirstPacket = true;
+ packet_->markerBit = true;
+ packet_->seqNum = seq_num_;
+ packet_->timestamp = timestamp_;
+
+ // Now, no free frame - frames will be recycled until first key frame.
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ // Pointer to last inserted delta frame should be returned.
+ EXPECT_TRUE(frame_in != NULL && frame_in && ptrLastDeltaFrame);
+
+ EXPECT_EQ(kCompleteSession, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ VCMEncodedFrame* frame_out = DecodeCompleteFrame();;
+ EXPECT_EQ(ptrFirstKeyFrame, frame_out);
+
+ EXPECT_EQ(0, CheckOutFrame(frame_out, size_, false));
+
+ EXPECT_EQ(kVideoFrameKey, frame_out->FrameType());
+}
+
+TEST_F(TestBasicJitterBuffer, EmptyLastFrame) {
+ jitter_buffer_->DecodeWithErrors(true);
+ seq_num_ = 3;
+ // Insert one empty packet per frame, should never return the last timestamp
+ // inserted. Only return empty frames in the presence of subsequent frames.
+ int maxSize = 1000;
+ for (int i = 0; i < maxSize + 10; i++) {
+ timestamp_ += 33 * 90;
+ seq_num_++;
+ packet_->isFirstPacket = false;
+ packet_->markerBit = false;
+ packet_->seqNum = seq_num_;
+ packet_->timestamp = timestamp_;
+ packet_->frameType = kFrameEmpty;
+ VCMEncodedFrame* frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(frame_in, *packet_));
+ VCMEncodedFrame* testFrame = DecodeIncompleteFrame();
+ // Timestamp should never be the last TS inserted.
+ if (testFrame != NULL) {
+ EXPECT_TRUE(testFrame->TimeStamp() < timestamp_);
+ }
+ }
+}
+
+TEST_F(TestBasicJitterBuffer, H264IncompleteNalu) {
+ jitter_buffer_->SetNackMode(kNoNack, -1, -1);
+ jitter_buffer_->DecodeWithErrors(true);
+ seq_num_ ++;
+ timestamp_ += 33 * 90;
+ int insertedLength = 0;
+ packet_->seqNum = seq_num_;
+ packet_->timestamp = timestamp_;
+ packet_->frameType = kVideoFrameKey;
+ packet_->isFirstPacket = true;
+ packet_->completeNALU = kNaluStart;
+ packet_->markerBit = false;
+
+ VCMEncodedFrame* frame_in = jitter_buffer_->GetFrame(*packet_);
+
+ EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ seq_num_ += 2; // Skip one packet
+ packet_->seqNum = seq_num_;
+ packet_->frameType = kVideoFrameKey;
+ packet_->isFirstPacket = false;
+ packet_->completeNALU = kNaluIncomplete;
+ packet_->markerBit = false;
+
+ EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ seq_num_++;
+ packet_->seqNum = seq_num_;
+ packet_->frameType = kVideoFrameKey;
+ packet_->isFirstPacket = false;
+ packet_->completeNALU = kNaluEnd;
+ packet_->markerBit = false;
+
+ EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ seq_num_++;
+ packet_->seqNum = seq_num_;
+ packet_->completeNALU = kNaluComplete;
+ packet_->markerBit = true; // Last packet
+ EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(frame_in, *packet_));
+ // The JB will only output (incomplete) frames if a packet belonging to a
+ // subsequent frame was already inserted. Insert one packet of a subsequent
+ // frame. place high timestamp so the JB would always have a next frame
+ // (otherwise, for every inserted frame we need to take care of the next
+ // frame as well).
+ packet_->seqNum = 1;
+ packet_->timestamp = timestamp_ + 33 * 90 * 10;
+ packet_->frameType = kVideoFrameDelta;
+ packet_->isFirstPacket = false;
+ packet_->completeNALU = kNaluStart;
+ packet_->markerBit = false;
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ VCMEncodedFrame* frame_out = DecodeIncompleteFrame();
+
+ // We can decode everything from a NALU until a packet has been lost.
+ // Thus we can decode the first packet of the first NALU and the second NALU
+ // which consists of one packet.
+ EXPECT_EQ(0, CheckOutFrame(frame_out, packet_->sizeBytes * 2, false));
+ jitter_buffer_->ReleaseFrame(frame_out);
+
+ // Test reordered start frame + 1 lost.
+ seq_num_ += 2; // Re-order 1 frame.
+ timestamp_ += 33*90;
+ insertedLength = 0;
+
+ packet_->seqNum = seq_num_;
+ packet_->timestamp = timestamp_;
+ packet_->frameType = kVideoFrameKey;
+ packet_->isFirstPacket = false;
+ packet_->completeNALU = kNaluEnd;
+ packet_->markerBit = false;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(frame_in, *packet_));
+ insertedLength += packet_->sizeBytes; // This packet should be decoded.
+
+ seq_num_--;
+ packet_->seqNum = seq_num_;
+ packet_->timestamp = timestamp_;
+ packet_->frameType = kVideoFrameKey;
+ packet_->isFirstPacket = true;
+ packet_->completeNALU = kNaluStart;
+ packet_->markerBit = false;
+ EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(frame_in, *packet_));
+ insertedLength += packet_->sizeBytes; // This packet should be decoded.
+
+ seq_num_ += 3; // One packet drop
+ packet_->seqNum = seq_num_;
+ packet_->timestamp = timestamp_;
+ packet_->frameType = kVideoFrameKey;
+ packet_->isFirstPacket = false;
+ packet_->completeNALU = kNaluComplete;
+ packet_->markerBit = false;
+ EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(frame_in, *packet_));
+ insertedLength += packet_->sizeBytes; // This packet should be decoded.
+
+ seq_num_ += 1;
+ packet_->seqNum = seq_num_;
+ packet_->timestamp = timestamp_;
+ packet_->frameType = kVideoFrameKey;
+ packet_->isFirstPacket = false;
+ packet_->completeNALU = kNaluStart;
+ packet_->markerBit = false;
+ EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(frame_in, *packet_));
+ // This packet should be decoded since it's the beginning of a NAL.
+ insertedLength += packet_->sizeBytes;
+
+ seq_num_ += 2;
+ packet_->seqNum = seq_num_;
+ packet_->timestamp = timestamp_;
+ packet_->frameType = kVideoFrameKey;
+ packet_->isFirstPacket = false;
+ packet_->completeNALU = kNaluEnd;
+ packet_->markerBit = true;
+ EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(frame_in, *packet_));
+ // This packet should not be decoded because it is an incomplete NAL if it
+ // is the last.
+ frame_out = DecodeIncompleteFrame();
+ // Only last NALU is complete.
+ EXPECT_EQ(0, CheckOutFrame(frame_out, insertedLength, false));
+ jitter_buffer_->ReleaseFrame(frame_out);
+
+
+ // Test to insert empty packet.
+ seq_num_ += 1;
+ timestamp_ += 33 * 90;
+ VCMPacket emptypacket(data_, 0, seq_num_, timestamp_, true);
+ emptypacket.seqNum = seq_num_;
+ emptypacket.timestamp = timestamp_;
+ emptypacket.frameType = kVideoFrameKey;
+ emptypacket.isFirstPacket = true;
+ emptypacket.completeNALU = kNaluComplete;
+ emptypacket.markerBit = true;
+ frame_in = jitter_buffer_->GetFrame(emptypacket);
+ EXPECT_EQ(kCompleteSession,
+ jitter_buffer_->InsertPacket(frame_in, emptypacket));
+ // This packet should not be decoded because it is an incomplete NAL if it
+ // is the last.
+ insertedLength += 0;
+
+ // Will be sent to the decoder, as a packet belonging to a subsequent frame
+ // has arrived.
+ frame_out = DecodeIncompleteFrame();
+
+
+ // Test that a frame can include an empty packet.
+ seq_num_ += 1;
+ timestamp_ += 33 * 90;
+
+ packet_->seqNum = seq_num_;
+ packet_->timestamp = timestamp_;
+ packet_->frameType = kVideoFrameKey;
+ packet_->isFirstPacket = true;
+ packet_->completeNALU = kNaluComplete;
+ packet_->markerBit = false;
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ seq_num_ += 1;
+ emptypacket.seqNum = seq_num_;
+ emptypacket.timestamp = timestamp_;
+ emptypacket.frameType = kVideoFrameKey;
+ emptypacket.isFirstPacket = true;
+ emptypacket.completeNALU = kNaluComplete;
+ emptypacket.markerBit = true;
+ EXPECT_EQ(kCompleteSession,
+ jitter_buffer_->InsertPacket(frame_in, emptypacket));
+
+ frame_out = DecodeCompleteFrame();
+ // Only last NALU is complete
+ EXPECT_EQ(0, CheckOutFrame(frame_out, packet_->sizeBytes, false));
+}
+
+TEST_F(TestBasicJitterBuffer, NextFrameWhenIncomplete) {
+ // Test that a we cannot get incomplete frames from the JB if we haven't
+ // received the marker bit, unless we have received a packet from a later
+ // timestamp.
+ jitter_buffer_->DecodeWithErrors(true);
+ // Start with a complete key frame - insert and decode.
+ packet_->frameType = kVideoFrameKey;
+ packet_->isFirstPacket = true;
+ packet_->markerBit = true;
+ VCMEncodedFrame* frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_EQ(kCompleteSession, jitter_buffer_->InsertPacket(frame_in, *packet_));
+ VCMEncodedFrame* frame_out = DecodeCompleteFrame();
+ EXPECT_TRUE(frame_out != NULL);
+
+ packet_->seqNum += 2;
+ packet_->timestamp += 33 * 90;
+ packet_->frameType = kVideoFrameDelta;
+ packet_->isFirstPacket = false;
+ packet_->markerBit = false;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ frame_out = DecodeIncompleteFrame();
+ EXPECT_TRUE(frame_out == NULL);
+
+ packet_->seqNum += 2;
+ packet_->timestamp += 33 * 90;
+ packet_->isFirstPacket = true;
+
+ frame_in = jitter_buffer_->GetFrame(*packet_);
+ EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(frame_in, *packet_));
+
+ frame_out = DecodeIncompleteFrame();
+
+ EXPECT_EQ(0, CheckOutFrame(frame_out, packet_->sizeBytes, false));
+}
+
TEST_F(TestRunningJitterBuffer, Full) {
// Insert a key frame and decode it.
EXPECT_GE(InsertFrame(kVideoFrameKey), kNoError);
diff --git a/webrtc/modules/video_coding/main/test/jitter_buffer_test.cc b/webrtc/modules/video_coding/main/test/jitter_buffer_test.cc
deleted file mode 100644
index 9edbd2a..0000000
--- a/webrtc/modules/video_coding/main/test/jitter_buffer_test.cc
+++ /dev/null
@@ -1,1755 +0,0 @@
-/*
- * Copyright (c) 2012 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 "webrtc/modules/video_coding/main/test/jitter_estimate_test.h"
-
-#include <math.h>
-
-#include "webrtc/common_types.h"
-#include "webrtc/modules/video_coding/main/interface/video_coding.h"
-#include "webrtc/modules/video_coding/main/source/frame_buffer.h"
-#include "webrtc/modules/video_coding/main/source/inter_frame_delay.h"
-#include "webrtc/modules/video_coding/main/source/jitter_buffer.h"
-#include "webrtc/modules/video_coding/main/source/jitter_estimator.h"
-#include "webrtc/modules/video_coding/main/source/media_opt_util.h"
-#include "webrtc/modules/video_coding/main/source/packet.h"
-#include "webrtc/modules/video_coding/main/test/test_util.h"
-#include "webrtc/modules/video_coding/main/test/test_macros.h"
-#include "webrtc/system_wrappers/interface/clock.h"
-
-// TODO(holmer): Get rid of this to conform with style guide.
-using namespace webrtc;
-
-// TODO (Mikhal/Stefan): Update as gtest and separate to specific tests.
-
-int CheckOutFrame(VCMEncodedFrame* frameOut, unsigned int size, bool startCode)
-{
- if (frameOut == 0)
- {
- return -1;
- }
-
- const uint8_t* outData = frameOut->Buffer();
-
- unsigned int i = 0;
-
- if(startCode)
- {
- if (outData[0] != 0 || outData[1] != 0 || outData[2] != 0 ||
- outData[3] != 1)
- {
- return -2;
- }
- i+= 4;
- }
-
- // check the frame data
- int count = 3;
-
- // check the frame length
- if (frameOut->Length() != size)
- {
- return -3;
- }
-
- for(; i < size; i++)
- {
- if (outData[i] == 0 && outData[i + 1] == 0 && outData[i + 2] == 0x80)
- {
- i += 2;
- }
- else if(startCode && outData[i] == 0 && outData[i + 1] == 0)
- {
- if (outData[i] != 0 || outData[i + 1] != 0 ||
- outData[i + 2] != 0 || outData[i + 3] != 1)
- {
- return -3;
- }
- i += 3;
- }
- else
- {
- if (outData[i] != count)
- {
- return -4;
- }
- count++;
- if(count == 10)
- {
- count = 3;
- }
- }
- }
- return 0;
-}
-
-VCMEncodedFrame* DecodeCompleteFrame(uint32_t max_wait_time_ms) {
- uint32_t timestamp = 0;
- bool found_frame = jb.NextCompleteTimestamp(max_wait_time_ms, ×tamp);
- if (!found_frame)
- return NULL;
-
- return jb.ExtractAndSetDecode(timestamp);
-}
-
-VCMEncodedFrame* DecodeIncompleteFrame() {
- uint32_t timestamp = 0;
- bool found_frame =
- jb.MaybeGetIncompleteFrameTimestampForDecoding(×tamp);
- if (!found_frame)
- return NULL;
- return frame = jb.ExtractAndSetDecode(timestamp);
-}
-
-int JitterBufferTest(CmdArgs& args)
-{
- Clock* clock = Clock::GetRealTimeClock();
-
- // Start test
- uint16_t seqNum = 1234;
- uint32_t timeStamp = 0;
- int size = 1400;
- uint8_t data[1500];
- VCMPacket packet(data, size, seqNum, timeStamp, true);
-
- NullEventFactory event_factory;
- VCMJitterBuffer jb(clock, &event_factory, -1, -1, true);
-
- seqNum = 1234;
- timeStamp = 123*90;
- VCMEncodedFrame* frameOut=NULL;
- packet.timestamp = timeStamp;
- packet.seqNum = seqNum;
-
- // build a data vector with 0, 0, 0x80, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0x80, 3....
- data[0] = 0;
- data[1] = 0;
- data[2] = 0x80;
- int count = 3;
- for (unsigned int i = 3; i < sizeof(data) - 3; ++i)
- {
- data[i] = count;
- count++;
- if(count == 10)
- {
- data[i+1] = 0;
- data[i+2] = 0;
- data[i+3] = 0x80;
- count = 3;
- i += 3;
- }
- }
-
- // Not started
- TEST(0 == jb.GetFrame(packet));
- TEST(0 == DecodeCompleteFrame(10));
- TEST(0 == DecodeIncompleteFrame());
-
- // Start
- jb.Start();
-
- // Allow decoding with errors.
- jb.DecodeWithErrors(true);
-
- // Get frame to use for this timestamp
- VCMEncodedFrame* frameIn = jb.GetFrame(packet);
- TEST(frameIn != 0);
-
- // No packets inserted
- TEST(0 == DecodeCompleteFrame(10));
-
-
- //
- // TEST single packet frame
- //
- // --------
- // | 1234 |
- // --------
-
- // packet.frameType;
- // packet.dataPtr;
- // packet.sizeBytes;
- // packet.timestamp;
- // packet.seqNum;
- // packet.isFirstPacket;
- // packet.markerBit;
- //
- packet.frameType = kVideoFrameKey;
- packet.isFirstPacket = true;
- packet.markerBit = true;
-
- // Insert a packet into a frame.
- TEST(kFirstPacket == jb.InsertPacket(frameIn, packet));
-
- // Get the frame (always starts with a key frame).
- frameOut = DecodeCompleteFrame(10);
-
- TEST(CheckOutFrame(frameOut, size, false) == 0);
-
- // check the frame type
- TEST(frameOut->FrameType() == kVideoFrameKey);
-
- // Release frame (when done with decoding)
- jb.ReleaseFrame(frameOut);
-
- //printf("DONE delta frame 1 packet\n");
-
- //
- // TEST dual packet frame
- //
- // -----------------
- // | 1235 | 1236 |
- // -----------------
- //
-
- seqNum++;
- timeStamp += 33*90;
- 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 the frame
- frameOut = DecodeCompleteFrame(10);
-
- // it should not be complete
- TEST(frameOut == 0);
-
- seqNum++;
- packet.isFirstPacket = false;
- packet.markerBit = true;
- packet.seqNum = seqNum;
-
- frameIn = jb.GetFrame(packet);
- TEST(frameIn != 0);
-
- // Insert a packet into a frame
- TEST(kCompleteSession == jb.InsertPacket(frameIn, packet));
-
- // get the frame
- frameOut = DecodeCompleteFrame(10);
-
- TEST(CheckOutFrame(frameOut, size*2, false) == 0);
-
- // check the frame type
- TEST(frameOut->FrameType() == kVideoFrameDelta);
-
- // Release frame (when done with decoding)
- jb.ReleaseFrame(frameOut);
-
- //printf("DONE delta frame 2 packets\n");
-
-
- //
- // TEST 100 packets frame Key frame
- //
- // ----------------------------------
- // | 1237 | 1238 | .... | 1336 |
- // ----------------------------------
-
- // insert first packet
- timeStamp += 33*90;
- seqNum++;
- 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 the frame
- frameOut = DecodeCompleteFrame(10);
-
- // it should not be complete
- TEST(frameOut == 0);
-
- // insert 98 frames
- int loop = 0;
- do
- {
- seqNum++;
- 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(kCompleteSession == jb.InsertPacket(frameIn, packet));
-
- // get the frame
- frameOut = DecodeCompleteFrame(10);
-
- TEST(CheckOutFrame(frameOut, size*100, false) == 0);
-
- // check the frame type
- TEST(frameOut->FrameType() == kVideoFrameKey);
-
- // Release frame (when done with decoding)
- jb.ReleaseFrame(frameOut);
-
- //printf("DONE key frame 100 packets\n");
-
- //
- // TEST 100 packets frame Delta frame
- //
- // ----------------------------------
- // | 1337 | 1238 | .... | 1436 |
- // ----------------------------------
-
- // 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 the frame
- frameOut = DecodeCompleteFrame(10);
-
- // it should not be complete
- TEST(frameOut == 0);
-
- // insert 98 frames
- loop = 0;
- do
- {
- seqNum++;
- 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(kCompleteSession == jb.InsertPacket(frameIn, packet));
-
- // get the frame
- frameOut = DecodeCompleteFrame(10);
-
- TEST(CheckOutFrame(frameOut, size*100, false) == 0);
-
- // check the frame type
- TEST(frameOut->FrameType() == kVideoFrameDelta);
-
- // Release frame (when done with decoding)
- jb.ReleaseFrame(frameOut);
-
- //printf("DONE delta frame 100 packets\n");
-
- //
- // TEST packet re-ordering reverse order
- //
- // ----------------------------------
- // | 1437 | 1238 | .... | 1536 |
- // ----------------------------------
- // <----------
-
- // insert "first" packet last seqnum
- timeStamp += 33*90;
- seqNum += 100;
- packet.frameType = kVideoFrameDelta;
- packet.isFirstPacket = false;
- 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 the frame
- frameOut = DecodeCompleteFrame(10);
-
- // it should not be complete
- TEST(frameOut == 0);
-
- // insert 98 packets
- loop = 0;
- do
- {
- seqNum--;
- 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 = true;
- packet.markerBit = false;
- packet.seqNum = seqNum;
-
- frameIn = jb.GetFrame(packet);
- TEST(frameIn != 0);
-
- // Insert a packet into a frame
- TEST(kCompleteSession == jb.InsertPacket(frameIn, packet));
-
- // get the frame
- frameOut = DecodeCompleteFrame(10);
-
- TEST(CheckOutFrame(frameOut, size*100, false) == 0);
-
- // check the frame type
- TEST(frameOut->FrameType() == kVideoFrameDelta);
-
- // Release frame (when done with decoding)
- jb.ReleaseFrame(frameOut);
-
- //printf("DONE delta frame 100 packets reverse order\n");
-
- seqNum+= 100;
-
- //
- // TEST frame re-ordering 2 frames 2 packets each
- //
- // ----------------- -----------------
- // | 1539 | 1540 | | 1537 | 1538 |
- // ----------------- -----------------
-
- seqNum += 2;
- timeStamp += 2* 33 * 90;
- 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 the frame
- frameOut = DecodeCompleteFrame(10);
-
- // it should not be complete
- TEST(frameOut == 0);
-
- seqNum++;
- packet.isFirstPacket = false;
- packet.markerBit = true;
- packet.seqNum = seqNum;
-
- frameIn = jb.GetFrame(packet);
- TEST(frameIn != 0);
-
- // Insert a packet into a frame
- TEST(kCompleteSession == jb.InsertPacket(frameIn, packet));
-
- // check that we fail to get frame since seqnum is not continuous
- frameOut = DecodeCompleteFrame(10);
- TEST(frameOut == 0);
-
- seqNum -= 3;
- timeStamp -= 33*90;
- 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 the frame
- frameOut = jb.GetCompleteFrameForDecoding(10);
-
- // it should not be complete
- TEST(frameOut == 0);
-
- seqNum++;
- packet.isFirstPacket = false;
- packet.markerBit = true;
- packet.seqNum = seqNum;
-
- frameIn = jb.GetFrame(packet);
- TEST(frameIn != 0);
-
- // Insert a packet into a frame
- TEST(kCompleteSession == jb.InsertPacket(frameIn, packet));
-
- // get the frame
- frameOut = DecodeCompleteFrame(10);
-
- TEST(CheckOutFrame(frameOut, size*2, false) == 0);
-
- // check the frame type
- TEST(frameOut->FrameType() == kVideoFrameDelta);
-
- // Release frame (when done with decoding)
- jb.ReleaseFrame(frameOut);
-
- // get the frame
- frameOut = DecodeCompleteFrame(10);
-
- TEST(CheckOutFrame(frameOut, size*2, false) == 0);
-
- // check the frame type
- TEST(frameOut->FrameType() == kVideoFrameDelta);
-
- // Release frame (when done with decoding)
- jb.ReleaseFrame(frameOut);
-
- seqNum += 2;
- //printf("DONE frame re-ordering 2 frames 2 packets\n");
-
- // restore
- packet.dataPtr = data;
- packet.codec = kVideoCodecUnknown;
-
- //
- // TEST duplicate packets
- //
- // -----------------
- // | 1543 | 1543 |
- // -----------------
- //
-
- seqNum++;
- timeStamp += 2*33*90;
- 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 the frame
- frameOut = DecodeCompleteFrame(10);
-
- // it should not be complete
- TEST(frameOut == 0);
-
- packet.isFirstPacket = false;
- packet.markerBit = true;
-
- frameIn = jb.GetFrame(packet);
- TEST(frameIn != 0);
-
- // Insert a packet into a frame
- TEST(kDuplicatePacket == jb.InsertPacket(frameIn, packet));
-
- seqNum++;
- packet.seqNum = seqNum;
-
- TEST(kCompleteSession == jb.InsertPacket(frameIn, packet));
-
- // get the frame
- frameOut = DecodeCompleteFrame(10);
-
- TEST(CheckOutFrame(frameOut, size*2, false) == 0);
-
- // check the frame type
- TEST(frameOut->FrameType() == kVideoFrameDelta);
-
- // Release frame (when done with decoding)
- jb.ReleaseFrame(frameOut);
-
- //printf("DONE test duplicate packets\n");
-
- //
- // TEST H.264 insert start code
- //
- // -----------------
- // | 1544 | 1545 |
- // -----------------
- // insert start code, both packets
-
- seqNum++;
- timeStamp += 33 * 90;
- packet.frameType = kVideoFrameDelta;
- packet.isFirstPacket = true;
- packet.markerBit = false;
- packet.seqNum = seqNum;
- packet.timestamp = timeStamp;
- packet.insertStartCode = true;
-
- frameIn = jb.GetFrame(packet);
- TEST(frameIn != 0);
-
- // Insert a packet into a frame
- TEST(kFirstPacket == jb.InsertPacket(frameIn, packet));
-
- // get the frame
- frameOut = DecodeCompleteFrame(10);
-
- // it should not be complete
- TEST(frameOut == 0);
-
- seqNum++;
- packet.isFirstPacket = false;
- packet.markerBit = true;
- packet.seqNum = seqNum;
-
- frameIn = jb.GetFrame(packet);
- TEST(frameIn != 0);
-
- // Insert a packet into a frame
- TEST(kCompleteSession == jb.InsertPacket(frameIn, packet));
-
- // get the frame
- frameOut = DecodeCompleteFrame(10);
-
- TEST(CheckOutFrame(frameOut, size * 2 + 4 * 2, true) == 0);
-
- // check the frame type
- TEST(frameOut->FrameType() == kVideoFrameDelta);
-
- // Release frame (when done with decoding)
- jb.ReleaseFrame(frameOut);
-
- // reset
- packet.insertStartCode = false;
- //printf("DONE H.264 insert start code test 2 packets\n");
-
-
- jb.Flush();
-
- //
- // TEST packet loss. Verify missing packets statistics and not decodable
- // packets statistics.
- // Insert 10 frames consisting of 4 packets and remove one from all of them.
- // The last packet is an empty (non-media) packet
- //
-
- // Select a start seqNum which triggers a difficult wrap situation
- // The JB will only output (incomplete)frames if the next one has started
- // to arrive. Start by inserting one frame (key).
- seqNum = 0xffff - 4;
- seqNum++;
- timeStamp += 33*90;
- packet.frameType = kVideoFrameKey;
- packet.isFirstPacket = true;
- packet.markerBit = false;
- packet.seqNum = seqNum;
- packet.timestamp = timeStamp;
- packet.completeNALU = kNaluStart;
- frameIn = jb.GetFrame(packet);
- TEST(frameIn != 0);
- // Insert a packet into a frame
- TEST(kFirstPacket == jb.InsertPacket(frameIn, packet));
-
- for (int i = 0; i < 11; ++i) {
- webrtc::FrameType frametype = kVideoFrameDelta;
- seqNum++;
- timeStamp += 33*90;
- packet.frameType = frametype;
- packet.isFirstPacket = true;
- packet.markerBit = false;
- packet.seqNum = seqNum;
- packet.timestamp = timeStamp;
- packet.completeNALU = kNaluStart;
-
- frameIn = jb.GetFrame(packet);
- TEST(frameIn != 0);
-
- // Insert a packet into a frame
- TEST(kFirstPacket == jb.InsertPacket(frameIn, packet));
-
- // Get the frame
- frameOut = DecodeCompleteFrame(10);
-
- // Should not be complete
- TEST(frameOut == 0);
-
- seqNum += 2;
- packet.isFirstPacket = false;
- packet.markerBit = true;
- packet.seqNum = seqNum;
- packet.completeNALU = kNaluEnd;
-
- frameIn = jb.GetFrame(packet);
- TEST(frameIn != 0);
-
- // Insert a packet into a frame
- TEST(kIncomplete == jb.InsertPacket(frameIn, packet));
-
-
- // Insert an empty (non-media) packet
- seqNum++;
- packet.isFirstPacket = false;
- packet.markerBit = false;
- packet.seqNum = seqNum;
- packet.completeNALU = kNaluEnd;
- packet.frameType = kFrameEmpty;
-
- frameIn = jb.GetFrame(packet);
- TEST(frameIn != 0);
-
- // Insert a packet into a frame
- TEST(kIncomplete == jb.InsertPacket(frameIn, packet));
-
- // Get the frame
- frameOut = DecodeIncompleteFrame();
-
- // One of the packets has been discarded by the jitter buffer.
- // Last frame can't be extracted yet.
- if (i < 10)
- {
- TEST(CheckOutFrame(frameOut, size, false) == 0);
-
- // check the frame type
- if (i == 0)
- {
- TEST(frameOut->FrameType() == kVideoFrameKey);
- }
- else
- {
- TEST(frameOut->FrameType() == frametype);
- }
- TEST(frameOut->Complete() == false);
- TEST(frameOut->MissingFrame() == false);
- }
-
- // Release frame (when done with decoding)
- jb.ReleaseFrame(frameOut);
- }
-
- TEST(jb.num_not_decodable_packets() == 10);
-
- // Insert 3 old packets and verify that we have 3 discarded packets
- // Match value to actual latest timestamp decoded
- timeStamp -= 33 * 90;
- packet.timestamp = timeStamp - 1000;
- frameIn = jb.GetFrame(packet);
- TEST(frameIn == NULL);
-
- packet.timestamp = timeStamp - 500;
- frameIn = jb.GetFrame(packet);
- TEST(frameIn == NULL);
-
- packet.timestamp = timeStamp - 100;
- frameIn = jb.GetFrame(packet);
- TEST(frameIn == NULL);
-
- TEST(jb.num_discarded_packets() == 3);
-
- jb.Flush();
-
- // This statistic shouldn't be reset by a flush.
- TEST(jb.num_discarded_packets() == 3);
-
- //printf("DONE Statistics\n");
-
-
- // Temporarily do this to make the rest of the test work:
- timeStamp += 33*90;
- seqNum += 4;
-
-
- //
- // TEST delta frame 100 packets with seqNum wrap
- //
- // ---------------------------------------
- // | 65520 | 65521 | ... | 82 | 83 |
- // ---------------------------------------
- //
-
- jb.Flush();
-
- // insert first packet
- timeStamp += 33*90;
- seqNum = 0xfff0;
- 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 the frame
- frameOut = DecodeCompleteFrame(10);
-
- // it should not be complete
- TEST(frameOut == 0);
-
- // Insert 98 packets.
- loop = 0;
- do
- {
- seqNum++;
- 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));
-
- // get the frame
- frameOut = DecodeCompleteFrame(2);
-
- // it should not be complete
- 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(kCompleteSession == jb.InsertPacket(frameIn, packet));
-
- // get the frame
- frameOut = DecodeCompleteFrame(10);
-
- TEST(CheckOutFrame(frameOut, size*100, false) == 0);
-
- // check the frame type
- TEST(frameOut->FrameType() == kVideoFrameKey);
-
- // Release frame (when done with decoding)
- jb.ReleaseFrame(frameOut);
-
- //printf("DONE delta frame 100 packets with wrap in seqNum\n");
-
- //
- // TEST packet re-ordering reverse order with neg seqNum warp
- //
- // ----------------------------------------
- // | 65447 | 65448 | ... | 9 | 10 |
- // ----------------------------------------
- // <-------------
-
- // test flush
- jb.Flush();
-
- // insert "first" packet last seqnum
- timeStamp += 33*90;
- seqNum = 10;
- packet.frameType = kVideoFrameKey;
- packet.isFirstPacket = false;
- 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 the frame
- frameOut = DecodeIncompleteFrame();
-
- // it should not be complete
- TEST(frameOut == 0);
-
- // insert 98 frames
- loop = 0;
- do
- {
- seqNum--;
- 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));
-
- // get the frame
- frameOut = DecodeCompleteFrame(2);
-
- // it should not be complete
- TEST(frameOut == 0);
-
- loop++;
- } while (loop < 98);
-
- // insert last packet
- seqNum--;
- packet.isFirstPacket = true;
- packet.markerBit = false;
- packet.seqNum = seqNum;
-
- frameIn = jb.GetFrame(packet);
- TEST(frameIn != 0);
-
- // Insert a packet into a frame
- TEST(kCompleteSession == jb.InsertPacket(frameIn, packet));
-
- // get the frame
- frameOut = DecodeIncompleteFrame();
-
- TEST(CheckOutFrame(frameOut, size*100, false) == 0);
-
- // check the frame type
- TEST(frameOut->FrameType() == kVideoFrameDelta);
-
- // Release frame (when done with decoding)
- jb.ReleaseFrame(frameOut);
-
- //printf("DONE delta frame 100 packets reverse order with wrap in seqNum \n");
-
- // test flush
- jb.Flush();
-
- //
- // TEST packet re-ordering with seqNum wrap
- //
- // -----------------------
- // | 1 | 65535 | 0 |
- // -----------------------
-
- // insert "first" packet last seqnum
- timeStamp += 33*90;
- seqNum = 1;
- packet.frameType = kVideoFrameKey;
- packet.isFirstPacket = false;
- 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 the frame
- frameOut = DecodeCompleteFrame(10);
-
- // it should not be complete
- TEST(frameOut == 0);
-
- // insert last packet
- seqNum -= 2;
- packet.isFirstPacket = true;
- 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));
-
- // get the frame
- frameOut = DecodeIncompleteFrame();
-
- // it should not be complete
- TEST(frameOut == 0);
-
- seqNum++;
- packet.isFirstPacket = false;
- packet.markerBit = false;
- packet.seqNum = seqNum;
-
- frameIn = jb.GetFrame(packet);
- TEST(frameIn != 0);
-
- // Insert a packet into a frame
- TEST(kCompleteSession == jb.InsertPacket(frameIn, packet));
-
- // get the frame
- frameOut = DecodeIncompleteFrame();
-
- TEST(CheckOutFrame(frameOut, size*3, false) == 0);
-
- // check the frame type
- TEST(frameOut->FrameType() == kVideoFrameDelta);
-
- // Release frame (when done with decoding)
- jb.ReleaseFrame(frameOut);
-
- //printf("DONE delta frame 3 packets re-ordering with wrap in seqNum \n");
-
- // test flush
- jb.Flush();
-
- //
- // TEST insert old frame
- //
- // ------- -------
- // | 2 | | 1 |
- // ------- -------
- // t = 3000 t = 2000
-
- seqNum = 2;
- timeStamp = 3000;
- packet.frameType = kVideoFrameDelta;
- 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 the frame
- frameOut = DecodeCompleteFrame();
- TEST(3000 == frameOut->TimeStamp());
-
- TEST(CheckOutFrame(frameOut, size, false) == 0);
-
- // check the frame type
- TEST(frameOut->FrameType() == kVideoFrameDelta);
-
- jb.ReleaseFrame(frameOut);
-
- seqNum--;
- timeStamp = 2000;
- packet.frameType = kVideoFrameDelta;
- packet.isFirstPacket = true;
- packet.markerBit = true;
- packet.seqNum = seqNum;
- packet.timestamp = timeStamp;
-
- frameIn = jb.GetFrame(packet);
- // Changed behavior, never insert packets into frames older than the
- // last decoded frame.
- TEST(frameIn == 0);
-
- //printf("DONE insert old frame\n");
-
- jb.Flush();
-
- //
- // TEST insert old frame with wrap in timestamp
- //
- // ------- -------
- // | 2 | | 1 |
- // ------- -------
- // t = 3000 t = 0xffffff00
-
- seqNum = 2;
- timeStamp = 3000;
- packet.frameType = kVideoFrameDelta;
- 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 the frame
- frameOut = DecodeIncompleteFrame();
- TEST(timeStamp == frameOut->TimeStamp());
-
- TEST(CheckOutFrame(frameOut, size, false) == 0);
-
- // check the frame type
- TEST(frameOut->FrameType() == kVideoFrameDelta);
-
- jb.ReleaseFrame(frameOut);
-
- seqNum--;
- timeStamp = 0xffffff00;
- packet.frameType = kVideoFrameDelta;
- packet.isFirstPacket = true;
- packet.markerBit = true;
- packet.seqNum = seqNum;
- packet.timestamp = timeStamp;
-
- frameIn = jb.GetFrame(packet);
- // This timestamp is old
- TEST(frameIn == 0);
-
- jb.Flush();
-
- //
- // TEST wrap in timeStamp
- //
- // --------------- ---------------
- // | 1 | 2 | | 3 | 4 |
- // --------------- ---------------
- // t = 0xffffff00 t = 33*90
-
- seqNum = 1;
- timeStamp = 0xffffff00;
- 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 the frame
- frameOut = DecodeCompleteFrame(10);
-
- // it should not be complete
- TEST(frameOut == 0);
-
- seqNum++;
- packet.isFirstPacket = false;
- packet.markerBit = true;
- packet.seqNum = seqNum;
-
- frameIn = jb.GetFrame(packet);
- TEST(frameIn != 0);
-
- // Insert a packet into a frame
- TEST(kCompleteSession == jb.InsertPacket(frameIn, packet));
-
- frameOut = DecodeIncompleteFrame();
-
- TEST(CheckOutFrame(frameOut, size*2, false) == 0);
-
- jb.ReleaseFrame(frameOut);
-
- seqNum++;
- timeStamp += 33*90;
- 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 the frame
- frameOut = DecodeCompleteFrame(10);
-
- // it should not be complete
- TEST(frameOut == 0);
-
- seqNum++;
- packet.isFirstPacket = false;
- packet.markerBit = true;
- packet.seqNum = seqNum;
-
- frameIn = jb.GetFrame(packet);
- TEST(frameIn != 0);
-
- // Insert a packet into a frame
- TEST(kCompleteSession == jb.InsertPacket(frameIn, packet));
-
- // get the frame
- frameOut = DecodeIncompleteFrame();
-
- TEST(CheckOutFrame(frameOut, size*2, false) == 0);
-
- // check the frame type
- TEST(frameOut->FrameType() == kVideoFrameDelta);
-
- // Release frame (when done with decoding)
- jb.ReleaseFrame(frameOut);
-
- //printf("DONE time stamp wrap 2 frames 2 packets\n");
-
- jb.Flush();
-
- //
- // TEST insert 2 frames with wrap in timeStamp
- //
- // ------- -------
- // | 1 | | 2 |
- // ------- -------
- // t = 0xffffff00 t = 2700
-
- seqNum = 1;
- timeStamp = 0xffffff00;
- packet.frameType = kVideoFrameDelta;
- packet.isFirstPacket = true;
- packet.markerBit = true;
- packet.seqNum = seqNum;
- packet.timestamp = timeStamp;
-
- frameIn = jb.GetFrame(packet);
- TEST(frameIn != 0);
-
- // Insert first frame
- TEST(kFirstPacket == jb.InsertPacket(frameIn, packet));
-
- // Insert next frame
- seqNum++;
- timeStamp = 2700;
- packet.frameType = kVideoFrameDelta;
- 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 frame
- frameOut = jb.GetFrameForDecoding();
- TEST(0xffffff00 == frameOut->TimeStamp());
-
- TEST(CheckOutFrame(frameOut, size, false) == 0);
-
- // check the frame type
- TEST(frameOut->FrameType() == kVideoFrameDelta);
-
- // Get frame
- VCMEncodedFrame* frameOut2 = DecodeIncompleteFrame();
- TEST(2700 == frameOut2->TimeStamp());
-
- TEST(CheckOutFrame(frameOut2, size, false) == 0);
-
- // check the frame type
- TEST(frameOut2->FrameType() == kVideoFrameDelta);
-
- // Release frame (when done with decoding)
- jb.ReleaseFrame(frameOut);
- jb.ReleaseFrame(frameOut2);
-
- //printf("DONE insert 2 frames (1 packet) with wrap in timestamp\n");
-
- jb.Flush();
-
- //
- // TEST insert 2 frames re-ordered with wrap in timeStamp
- //
- // ------- -------
- // | 2 | | 1 |
- // ------- -------
- // t = 2700 t = 0xffffff00
-
- seqNum = 2;
- timeStamp = 2700;
- packet.frameType = kVideoFrameDelta;
- packet.isFirstPacket = true;
- packet.markerBit = true;
- packet.seqNum = seqNum;
- packet.timestamp = timeStamp;
-
- frameIn = jb.GetFrame(packet);
- TEST(frameIn != 0);
-
- // Insert first frame
- TEST(kFirstPacket == jb.InsertPacket(frameIn, packet));
-
- // Insert second frame
- seqNum--;
- timeStamp = 0xffffff00;
- packet.frameType = kVideoFrameDelta;
- 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 frame
- frameOut = jb.GetFrameForDecoding();
- TEST(0xffffff00 == frameOut->TimeStamp());
-
- TEST(CheckOutFrame(frameOut, size, false) == 0);
-
- // check the frame type
- TEST(frameOut->FrameType() == kVideoFrameDelta);
-
- // Get frame
- frameOut2 = DecodeIncompleteFrame();
- TEST(2700 == frameOut2->TimeStamp());
-
- TEST(CheckOutFrame(frameOut2, size, false) == 0);
-
- // check the frame type
- TEST(frameOut2->FrameType() == kVideoFrameDelta);
-
- // Release frame (when done with decoding)
- jb.ReleaseFrame(frameOut);
- jb.ReleaseFrame(frameOut2);
-
- //printf("DONE insert 2 frames (1 packet) re-ordered with wrap in timestamp\n");
-
- //
- // TEST delta frame with more than max number of packets
- //
-
- jb.Start();
-
- loop = 0;
- packet.timestamp += 33*90;
- bool firstPacket = true;
- // insert kMaxPacketsInJitterBuffer into frame
- do
- {
- seqNum++;
- packet.isFirstPacket = false;
- packet.markerBit = false;
- packet.seqNum = seqNum;
-
- frameIn = jb.GetFrame(packet);
- TEST(frameIn != 0);
-
- // Insert frame
- if (firstPacket)
- {
- TEST(kFirstPacket == jb.InsertPacket(frameIn, packet));
- firstPacket = false;
- }
- else
- {
- TEST(kIncomplete == jb.InsertPacket(frameIn, packet));
- }
-
- loop++;
- } while (loop < kMaxPacketsInSession);
-
- // Max number of packets inserted
-
- // Insert one more packet
- seqNum++;
- packet.isFirstPacket = false;
- packet.markerBit = true;
- packet.seqNum = seqNum;
-
- frameIn = jb.GetFrame(packet);
- TEST(frameIn != 0);
-
- // Insert the packet -> frame recycled
- TEST(kSizeError == jb.InsertPacket(frameIn, packet));
-
- TEST(0 == DecodeIncompleteFrame());
-
- //printf("DONE fill frame - packets > max number of packets\n");
-
- //
- // TEST fill JB with more than max number of frame (50 delta frames +
- // 51 key frames) with wrap in seqNum
- //
- // --------------------------------------------------------------
- // | 65485 | 65486 | 65487 | .... | 65535 | 0 | 1 | 2 | .....| 50 |
- // --------------------------------------------------------------
- // |<-----------delta frames------------->|<------key frames----->|
-
- jb.Flush();
-
- loop = 0;
- seqNum = 65485;
- VCMEncodedFrame* ptrLastDeltaFrame = NULL;
- VCMEncodedFrame* ptrFirstKeyFrame = NULL;
- // 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);
-
- if (loop == 49) // last delta
- {
- ptrLastDeltaFrame = frameIn;
- }
- if (loop == 50) // first key
- {
- ptrFirstKeyFrame = frameIn;
- packet.frameType = kVideoFrameKey;
- }
-
- // Insert frame
- TEST(kFirstPacket == jb.InsertPacket(frameIn, packet));
-
- 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;
- packet.timestamp = timeStamp;
-
- // Now, no free frame - frames will be recycled until first key frame
- frameIn = jb.GetFrame(packet);
- // ptr to last inserted delta frame should be returned
- TEST(frameIn != 0 && frameIn && ptrLastDeltaFrame);
-
- // Insert frame
- TEST(kFirstPacket == jb.InsertPacket(frameIn, packet));
-
- // get the first key frame
- frameOut = jb.GetFrameForDecoding();
- TEST(ptrFirstKeyFrame == frameOut);
-
- TEST(CheckOutFrame(frameOut, size, false) == 0);
-
- // check the frame type
- TEST(frameOut->FrameType() == kVideoFrameKey);
-
- // Release frame (when done with decoding)
- jb.ReleaseFrame(frameOut);
-
- jb.Flush();
-
- // printf("DONE fill JB - nr of delta + key frames (w/ wrap in seqNum) >
- // max nr of frames\n");
-
- // Testing that 1 empty packet inserted last will not be set for decoding
- seqNum = 3;
- // Insert one empty packet per frame, should never return the last timestamp
- // inserted. Only return empty frames in the presence of subsequent frames.
- int maxSize = 1000;
- for (int i = 0; i < maxSize + 10; i++)
- {
- timeStamp += 33 * 90;
- seqNum++;
- packet.isFirstPacket = false;
- packet.markerBit = false;
- packet.seqNum = seqNum;
- packet.timestamp = timeStamp;
- packet.frameType = kFrameEmpty;
- VCMEncodedFrame* testFrame = jb.MaybeGetIncompleteFrameForDecoding();
- // timestamp should bever be the last TS inserted
- if (testFrame != NULL)
- {
- TEST(testFrame->TimeStamp() < timeStamp);
- printf("Not null TS = %d\n",testFrame->TimeStamp());
- }
- }
-
- jb.Flush();
-
-
- // printf(DONE testing inserting empty packets to the JB)
-
-
- // H.264 tests
- // Test incomplete NALU frames
-
- jb.Flush();
- jb.SetNackMode(kNoNack, -1, -1);
- seqNum ++;
- timeStamp += 33 * 90;
- int insertedLength = 0;
- packet.seqNum = seqNum;
- packet.timestamp = timeStamp;
- packet.frameType = kVideoFrameKey;
- packet.isFirstPacket = true;
- packet.completeNALU = kNaluStart;
- packet.markerBit = false;
-
- frameIn = jb.GetFrame(packet);
-
- // Insert a packet into a frame
- TEST(kFirstPacket == jb.InsertPacket(frameIn, packet));
-
- seqNum += 2; // Skip one packet
- packet.seqNum = seqNum;
- packet.frameType = kVideoFrameKey;
- packet.isFirstPacket = false;
- packet.completeNALU = kNaluIncomplete;
- packet.markerBit = false;
-
- // Insert a packet into a frame
- TEST(kIncomplete == jb.InsertPacket(frameIn, packet));
-
- seqNum++;
- packet.seqNum = seqNum;
- packet.frameType = kVideoFrameKey;
- packet.isFirstPacket = false;
- packet.completeNALU = kNaluEnd;
- packet.markerBit = false;
-
- // Insert a packet into a frame
- TEST(kIncomplete == jb.InsertPacket(frameIn, packet));
-
- seqNum++;
- packet.seqNum = seqNum;
- packet.completeNALU = kNaluComplete;
- packet.markerBit = true; // Last packet
- TEST(kIncomplete == jb.InsertPacket(frameIn, packet));
-
-
- // The JB will only output (incomplete) frames if a packet belonging to a
- // subsequent frame was already inserted. Insert one packet of a subsequent
- // frame. place high timestamp so the JB would always have a next frame
- // (otherwise, for every inserted frame we need to take care of the next
- // frame as well).
- packet.seqNum = 1;
- packet.timestamp = timeStamp + 33 * 90 * 10;
- packet.frameType = kVideoFrameDelta;
- packet.isFirstPacket = false;
- packet.completeNALU = kNaluStart;
- packet.markerBit = false;
- frameIn = jb.GetFrame(packet);
- TEST(kFirstPacket == jb.InsertPacket(frameIn, packet));
-
- frameOut = jb.MaybeGetIncompleteFrameForDecoding();
-
- // We can decode everything from a NALU until a packet has been lost.
- // Thus we can decode the first packet of the first NALU and the second NALU
- // which consists of one packet.
- TEST(CheckOutFrame(frameOut, packet.sizeBytes * 2, false) == 0);
- jb.ReleaseFrame(frameOut);
-
- // Test reordered start frame + 1 lost
- seqNum += 2; // Reoreder 1 frame
- timeStamp += 33*90;
- insertedLength = 0;
-
- packet.seqNum = seqNum;
- packet.timestamp = timeStamp;
- packet.frameType = kVideoFrameKey;
- packet.isFirstPacket = false;
- packet.completeNALU = kNaluEnd;
- packet.markerBit = false;
-
- TEST(frameIn = jb.GetFrame(packet));
- TEST(kFirstPacket == jb.InsertPacket(frameIn, packet));
- insertedLength += packet.sizeBytes; // This packet should be decoded
-
- seqNum--;
- packet.seqNum = seqNum;
- packet.timestamp = timeStamp;
- packet.frameType = kVideoFrameKey;
- packet.isFirstPacket = true;
- packet.completeNALU = kNaluStart;
- packet.markerBit = false;
- TEST(kIncomplete == jb.InsertPacket(frameIn, packet));
- insertedLength += packet.sizeBytes; // This packet should be decoded
-
- seqNum += 3; // One packet drop
- packet.seqNum = seqNum;
- packet.timestamp = timeStamp;
- packet.frameType = kVideoFrameKey;
- packet.isFirstPacket = false;
- packet.completeNALU = kNaluComplete;
- packet.markerBit = false;
- TEST(kIncomplete == jb.InsertPacket(frameIn, packet));
- insertedLength += packet.sizeBytes; // This packet should be decoded
-
- seqNum += 1;
- packet.seqNum = seqNum;
- packet.timestamp = timeStamp;
- packet.frameType = kVideoFrameKey;
- packet.isFirstPacket = false;
- packet.completeNALU = kNaluStart;
- packet.markerBit = false;
- TEST(kIncomplete == jb.InsertPacket(frameIn, packet));
- // This packet should be decoded since it's the beginning of a NAL
- insertedLength += packet.sizeBytes;
-
- seqNum += 2;
- packet.seqNum = seqNum;
- packet.timestamp = timeStamp;
- packet.frameType = kVideoFrameKey;
- packet.isFirstPacket = false;
- packet.completeNALU = kNaluEnd;
- packet.markerBit = true;
- TEST(kIncomplete == jb.InsertPacket(frameIn, packet));
- // This packet should not be decoded because it is an incomplete NAL if it
- // is the last
-
- frameOut = jb.MaybeGetIncompleteFrameForDecoding();
- // Only last NALU is complete
- TEST(CheckOutFrame(frameOut, insertedLength, false) == 0);
- jb.ReleaseFrame(frameOut);
-
-
- // Test to insert empty packet
- seqNum += 1;
- timeStamp += 33 * 90;
- VCMPacket emptypacket(data, 0, seqNum, timeStamp, true);
- emptypacket.seqNum = seqNum;
- emptypacket.timestamp = timeStamp;
- emptypacket.frameType = kVideoFrameKey;
- emptypacket.isFirstPacket = true;
- emptypacket.completeNALU = kNaluComplete;
- emptypacket.markerBit = true;
- TEST(frameIn = jb.GetFrame(emptypacket));
- TEST(kFirstPacket == jb.InsertPacket(frameIn, emptypacket));
- // This packet should not be decoded because it is an incomplete NAL if it
- // is the last
- insertedLength += 0;
-
- // Will be sent to the decoder, as a packet belonging to a subsequent frame
- // has arrived.
- frameOut = jb.MaybeGetIncompleteFrameForDecoding();
-
-
- // Test that a frame can include an empty packet.
- seqNum += 1;
- timeStamp += 33 * 90;
-
- packet.seqNum = seqNum;
- packet.timestamp = timeStamp;
- packet.frameType = kVideoFrameKey;
- packet.isFirstPacket = true;
- packet.completeNALU = kNaluComplete;
- packet.markerBit = false;
- TEST(frameIn = jb.GetFrame(packet));
- TEST(kFirstPacket == jb.InsertPacket(frameIn, packet));
-
- seqNum += 1;
- emptypacket.seqNum = seqNum;
- emptypacket.timestamp = timeStamp;
- emptypacket.frameType = kVideoFrameKey;
- emptypacket.isFirstPacket = true;
- emptypacket.completeNALU = kNaluComplete;
- emptypacket.markerBit = true;
- TEST(kCompleteSession == jb.InsertPacket(frameIn, emptypacket));
-
- // get the frame
- frameOut = jb.GetFrameForDecoding();
- // Only last NALU is complete
- TEST(CheckOutFrame(frameOut, packet.sizeBytes, false) == 0);
-
- jb.ReleaseFrame(frameOut);
-
- jb.Flush();
-
- // Test that a we cannot get incomplete frames from the JB if we haven't
- // received the marker bit, unless we have received a packet from a later
- // timestamp.
-
- packet.seqNum += 2;
- packet.frameType = kVideoFrameDelta;
- packet.isFirstPacket = false;
- packet.markerBit = false;
-
- TEST(frameIn = jb.GetFrame(packet));
- TEST(kFirstPacket == jb.InsertPacket(frameIn, packet));
-
- frameOut = jb.MaybeGetIncompleteFrameForDecoding();
- TEST(frameOut == NULL);
-
- packet.seqNum += 2;
- packet.timestamp += 33 * 90;
-
- TEST(frameIn = jb.GetFrame(packet));
- TEST(kFirstPacket == jb.InsertPacket(frameIn, packet));
-
- frameOut = jb.MaybeGetIncompleteFrameForDecoding();
-
- TEST(frameOut != NULL);
- TEST(CheckOutFrame(frameOut, packet.sizeBytes, false) == 0);
- jb.ReleaseFrame(frameOut);
-
- jb.Stop();
-
- printf("DONE !!!\n");
-
- printf("\nVCM Jitter Buffer Test: \n\n%i tests completed\n",
- vcmMacrosTests);
- if (vcmMacrosErrors > 0)
- {
- printf("%i FAILED\n\n", vcmMacrosErrors);
- }
- else
- {
- printf("ALL PASSED\n\n");
- }
-
- return 0;
-
-}