diff --git a/src/modules/video_coding/main/source/jitter_buffer_unittest.cc b/src/modules/video_coding/main/source/jitter_buffer_unittest.cc index 408a621ea..6e48ea7b0 100644 --- a/src/modules/video_coding/main/source/jitter_buffer_unittest.cc +++ b/src/modules/video_coding/main/source/jitter_buffer_unittest.cc @@ -10,6 +10,8 @@ #include +#include + #include "gtest/gtest.h" #include "modules/video_coding/main/source/jitter_buffer.h" #include "modules/video_coding/main/source/media_opt_util.h" @@ -22,57 +24,116 @@ class StreamGenerator { public: StreamGenerator(uint16_t start_seq_num, uint32_t start_timestamp, int64_t current_time) - : sequence_number_(start_seq_num), + : packets_(), + sequence_number_(start_seq_num), timestamp_(start_timestamp), - start_time_(current_time), - num_packets_(0), - type_(kVideoFrameKey), - first_packet_(true) {} + start_time_(current_time) {} - 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_); // Move the sequence number counter if all packets from the previous frame // wasn't collected. - sequence_number_ += num_packets_; - num_packets_ = num_packets; - type_ = type; - first_packet_ = true; + sequence_number_ += packets_.size(); + packets_.clear(); + for (int i = 0; i < num_media_packets; ++i) { + 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) { - if (num_packets_ == 0) { + static VCMPacket GeneratePacket(uint16_t sequence_number, + 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::iterator it = GetPacketIterator(index); + if (it == packets_.end()) return false; - } - --num_packets_; - if (packet) { - 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; + if (packet) + *packet = (*it); + packets_.erase(it); return true; } + bool GetPacket(VCMPacket* packet, int index) { + std::list::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 { - return num_packets_; + return packets_.size(); } private: + std::list::iterator GetPacketIterator(int index) { + std::list::iterator it = packets_.begin(); + for (int i = 0; i < index; ++i) { + ++it; + if (it == packets_.end()) break; + } + return it; + } + + std::list packets_; uint16_t sequence_number_; uint32_t timestamp_; int64_t start_time_; - int num_packets_; - FrameType type_; - bool first_packet_; DISALLOW_COPY_AND_ASSIGN(StreamGenerator); }; @@ -99,11 +160,25 @@ class TestRunningJitterBuffer : public ::testing::Test { delete clock_; } - VCMFrameBufferEnum InsertNextPacket() { + VCMFrameBufferEnum InsertPacketAndPop(int index) { VCMPacket packet; - packet.dataPtr = data_buffer_; 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); if (!packet_available) return kStateError; // Return here to avoid crashes below. @@ -112,31 +187,47 @@ class TestRunningJitterBuffer : public ::testing::Test { } 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()); - EXPECT_EQ(kFirstPacket, InsertNextPacket()); + EXPECT_EQ(kFirstPacket, InsertPacketAndPop(0)); clock_->IncrementDebugClock(kDefaultFramePeriodMs); } - void InsertFrames(int num_frames) { + void InsertFrames(int num_frames, FrameType frame_type) { for (int i = 0; i < num_frames; ++i) { - InsertFrame(kVideoFrameDelta); + InsertFrame(frame_type); } } void DropFrame(int num_packets) { - stream_generator->GenerateFrame(kVideoFrameDelta, num_packets, + stream_generator->GenerateFrame(kVideoFrameDelta, num_packets, 0, clock_->MillisecondTimestamp()); 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_; StreamGenerator* stream_generator; FakeTickTime* clock_; uint8_t data_buffer_[kDataBufferSize]; }; -class TestNack : public TestRunningJitterBuffer { +class TestJitterBufferNack : public TestRunningJitterBuffer { protected: virtual void 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. InsertFrame(kVideoFrameKey); - EXPECT_TRUE(jitter_buffer_->GetCompleteFrameForDecoding(0) != NULL); + EXPECT_TRUE(DecodeCompleteFrame()); DropFrame(1); // Fill the jitter buffer. - InsertFrames(kMaxNumberOfFrames); + InsertFrames(kMaxNumberOfFrames, kVideoFrameDelta); // 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. // Since none is found it will have to wait until the next key frame before // decoding. 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. InsertFrame(kVideoFrameKey); - EXPECT_TRUE(jitter_buffer_->GetCompleteFrameForDecoding(0) != NULL); + EXPECT_TRUE(DecodeCompleteFrame()); // Generate and drop |kNackHistoryLength| packets to fill the NACK list. DropFrame(kNackHistoryLength); // Insert a frame which should trigger a recycle until the next key frame. InsertFrame(kVideoFrameDelta); - EXPECT_TRUE(jitter_buffer_->GetCompleteFrameForDecoding(0) == NULL); + EXPECT_FALSE(DecodeCompleteFrame()); uint16_t nack_list_length = kNackHistoryLength; bool extended; @@ -182,11 +292,11 @@ TEST_F(TestNack, TestNackListFull) { EXPECT_TRUE(nack_list_length == 0xffff && nack_list == NULL); InsertFrame(kVideoFrameDelta); - EXPECT_TRUE(jitter_buffer_->GetCompleteFrameForDecoding(0) == NULL); - EXPECT_TRUE(jitter_buffer_->GetFrameForDecoding() == NULL); + EXPECT_FALSE(DecodeCompleteFrame()); + EXPECT_FALSE(DecodeFrame()); } -TEST_F(TestNack, TestNackBeforeDecode) { +TEST_F(TestJitterBufferNack, TestNackBeforeDecode) { DropFrame(10); // Insert a frame and try to generate a NACK list. Shouldn't get one. InsertFrame(kVideoFrameDelta); @@ -195,44 +305,72 @@ TEST_F(TestNack, TestNackBeforeDecode) { uint16_t* list = jitter_buffer_->GetNackList(nack_list_size, extended); // No list generated, and a key frame request is signaled. 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()); InsertFrame(kVideoFrameKey); - EXPECT_TRUE(jitter_buffer_->GetCompleteFrameForDecoding(0) != NULL); + EXPECT_TRUE(DecodeFrame()); // ---------------------------------------------------------------- // | 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_->IncrementDebugClock(kDefaultFramePeriodMs); - EXPECT_EQ(kFirstPacket, InsertNextPacket()); + EXPECT_EQ(kFirstPacket, InsertPacketAndPop(0)); // Verify that the frame is incomplete. - EXPECT_TRUE(jitter_buffer_->GetCompleteFrameForDecoding(0) == NULL); - int i = 2; + EXPECT_FALSE(DecodeCompleteFrame()); while (stream_generator->PacketsRemaining() > 1) { - if (i % 10 != 0) - EXPECT_EQ(kIncomplete, InsertNextPacket()); + if (stream_generator->NextSequenceNumber() % 10 != 0) + EXPECT_EQ(kIncomplete, InsertPacketAndPop(0)); else stream_generator->NextPacket(NULL); // Drop packet - ++i; } - EXPECT_EQ(kIncomplete, InsertNextPacket()); + EXPECT_EQ(kIncomplete, InsertPacketAndPop(0)); EXPECT_EQ(0, stream_generator->PacketsRemaining()); - EXPECT_TRUE(jitter_buffer_->GetCompleteFrameForDecoding(0) == NULL); - EXPECT_TRUE(jitter_buffer_->GetFrameForDecoding() == NULL); + EXPECT_FALSE(DecodeCompleteFrame()); + EXPECT_FALSE(DecodeFrame()); 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 = 9; 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]); } +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 diff --git a/src/modules/video_coding/main/test/jitter_buffer_test.cc b/src/modules/video_coding/main/test/jitter_buffer_test.cc index f397195c3..e75e9cea9 100644 --- a/src/modules/video_coding/main/test/jitter_buffer_test.cc +++ b/src/modules/video_coding/main/test/jitter_buffer_test.cc @@ -1292,6 +1292,8 @@ int JitterBufferTest(CmdArgs& args) // check the frame type TEST(frameOut->FrameType() == kVideoFrameDelta); + jb.ReleaseFrame(frameOut); + seqNum--; timeStamp = 2000; packet.frameType = kVideoFrameDelta; @@ -1344,6 +1346,8 @@ int JitterBufferTest(CmdArgs& args) // check the frame type TEST(frameOut->FrameType() == kVideoFrameDelta); + jb.ReleaseFrame(frameOut); + seqNum--; timeStamp = 0xffffff00; packet.frameType = kVideoFrameDelta; @@ -1407,6 +1411,8 @@ int JitterBufferTest(CmdArgs& args) TEST(CheckOutFrame(frameOut, size*2, false) == 0); + jb.ReleaseFrame(frameOut); + seqNum++; timeStamp += 33*90; 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"); - // - // 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 // @@ -1889,52 +1671,6 @@ int JitterBufferTest(CmdArgs& args) //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 + // 51 key frames) with wrap in seqNum @@ -1948,7 +1684,7 @@ int JitterBufferTest(CmdArgs& args) loop = 0; seqNum = 65485; - timeStampStart = timeStamp + 33*90; + WebRtc_UWord32 timeStampStart = timeStamp + 33*90; WebRtc_UWord32 timeStampFirstKey = 0; VCMEncodedFrame* ptrLastDeltaFrame = 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) > // 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 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. - maxSize = 1000; + int maxSize = 1000; for (int i = 0; i < maxSize + 10; i++) { timeStamp += 33 * 90; @@ -2127,7 +1781,7 @@ int JitterBufferTest(CmdArgs& args) packet.seqNum = seqNum; packet.timestamp = timeStamp; packet.frameType = kFrameEmpty; - testFrame = jb.GetFrameForDecoding(); + VCMEncodedFrame* testFrame = jb.GetFrameForDecoding(); // timestamp should bever be the last TS inserted if (testFrame != NULL) { @@ -2325,6 +1979,8 @@ int JitterBufferTest(CmdArgs& args) // Only last NALU is complete TEST(CheckOutFrame(frameOut, packet.sizeBytes, false) == 0); + jb.ReleaseFrame(frameOut); + jb.Flush(); // Three reordered H263 packets with bits. @@ -2366,6 +2022,7 @@ int JitterBufferTest(CmdArgs& args) TEST(frameOut != NULL); const WebRtc_UWord8* buf = frameOut->Buffer(); TEST(buf[packet.sizeBytes - 1] == (startByte | endByte)); + jb.ReleaseFrame(frameOut); // First packet lost, second packet with bits. // The JB only outputs frame if the next one arrives: @@ -2392,6 +2049,7 @@ int JitterBufferTest(CmdArgs& args) frameOut = jb.GetFrameForDecoding(); TEST(frameOut != NULL); TEST(frameOut->Length() == 0); + jb.ReleaseFrame(frameOut); data[0] = oldData1; data[packet.sizeBytes - 1] = oldData2; @@ -2425,6 +2083,7 @@ int JitterBufferTest(CmdArgs& args) TEST(frameOut != NULL); TEST(CheckOutFrame(frameOut, packet.sizeBytes, false) == 0); + jb.ReleaseFrame(frameOut); jb.Stop();