cdc943e2d5
Review URL: http://webrtc-codereview.appspot.com/59001 git-svn-id: http://webrtc.googlecode.com/svn/trunk@142 4adac7df-926f-26a2-2b94-8c16560cd09d
2253 lines
59 KiB
C++
2253 lines
59 KiB
C++
/*
|
|
* Copyright (c) 2011 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 "common_types.h"
|
|
#include "jitter_buffer.h"
|
|
#include "jitter_estimator.h"
|
|
#include "inter_frame_delay.h"
|
|
#include "packet.h"
|
|
#include "tick_time.h"
|
|
#include "../source/event.h"
|
|
#include "frame_buffer.h"
|
|
#include "jitter_estimate_test.h"
|
|
#include "test_macros.h"
|
|
#include "test_util.h"
|
|
#include <stdio.h>
|
|
#include <math.h>
|
|
|
|
using namespace webrtc;
|
|
|
|
void CheckOutFrame(VCMEncodedFrame* frameOut, int size, bool startCode)
|
|
{
|
|
TEST(frameOut != 0);
|
|
|
|
const WebRtc_UWord8* outData = frameOut->Buffer();
|
|
|
|
int i = 0;
|
|
|
|
if(startCode)
|
|
{
|
|
TEST(outData[0] == 0);
|
|
TEST(outData[1] == 0);
|
|
TEST(outData[2] == 0);
|
|
TEST(outData[3] == 1);
|
|
i+= 4;
|
|
}
|
|
|
|
// check the frame data
|
|
int count = 3;
|
|
int layer = 0;
|
|
|
|
// check the frame length
|
|
TEST(frameOut->Length() == size);
|
|
|
|
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)
|
|
{
|
|
TEST(outData[i] == 0);
|
|
TEST(outData[i+1] == 0);
|
|
TEST(outData[i+2] == 0);
|
|
TEST(outData[i+3] == 1);
|
|
i += 3;
|
|
}
|
|
else
|
|
{
|
|
if (outData[i] != count)
|
|
{
|
|
int a=0;
|
|
}
|
|
TEST(outData[i] == count);
|
|
count++;
|
|
if(count == 10)
|
|
{
|
|
count = 3;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
int JitterBufferTest(CmdArgs& args)
|
|
{
|
|
// Don't run these tests with debug time
|
|
#if defined(TICK_TIME_DEBUG) || defined(EVENT_DEBUG)
|
|
return -1;
|
|
#endif
|
|
|
|
// Start test
|
|
WebRtc_UWord16 seqNum = 1234;
|
|
WebRtc_UWord32 timeStamp = 0;
|
|
int size = 1400;
|
|
WebRtc_UWord8 data[1500];
|
|
VCMPacket packet(data, size, seqNum, timeStamp, true);
|
|
|
|
VCMFrameListTimestampOrderAsc frameList;
|
|
VCMFrameBuffer* fb = NULL;
|
|
for (int i=0; i < 100; i++)
|
|
{
|
|
fb = new VCMFrameBuffer();
|
|
fb->SetState(kStateEmpty);
|
|
packet.timestamp = 0xfffffff0 + i;
|
|
packet.seqNum = seqNum;
|
|
packet.payloadType = 126;
|
|
seqNum++;
|
|
fb->InsertPacket(packet, VCMTickTime::MillisecondTimestamp());
|
|
TEST(frameList.Insert(fb) == 0);
|
|
}
|
|
VCMFrameListItem* item = NULL;
|
|
WebRtc_UWord32 prevTimestamp = 0;
|
|
int i = 0;
|
|
for (i=0; !frameList.Empty(); i++)
|
|
{
|
|
item = frameList.First();
|
|
fb = static_cast<VCMFrameBuffer*>(item->GetItem());
|
|
TEST(i > 0 || fb->TimeStamp() == 0xfffffff0); // Frame 0 has no prev
|
|
TEST(prevTimestamp - fb->TimeStamp() == -1 || i == 0);
|
|
prevTimestamp = fb->TimeStamp();
|
|
frameList.Erase(item);
|
|
delete fb;
|
|
}
|
|
TEST(i == 100);
|
|
|
|
//printf("DONE timestamp ordered frame list\n");
|
|
|
|
VCMJitterBuffer jb;
|
|
|
|
seqNum = 1234;
|
|
timeStamp = 123*90;
|
|
VCMFrameBufferEnum retVal(kNoError);
|
|
FrameType incomingFrameType(kVideoFrameKey);
|
|
VCMEncodedFrame* frameOut=NULL;
|
|
WebRtc_Word64 renderTimeMs = 0;
|
|
WebRtc_UWord8 payloadType = 0;
|
|
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(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;
|
|
}
|
|
}
|
|
|
|
// Test out of range inputs
|
|
TEST(kSizeError == jb.InsertPacket(0, packet));
|
|
jb.ReleaseFrame(0);
|
|
|
|
// Not started
|
|
TEST(0 == jb.GetFrame(packet));
|
|
TEST(-1 == jb.GetNextTimeStamp(10, incomingFrameType, renderTimeMs));
|
|
TEST(0 == jb.GetCompleteFrameForDecoding(10));
|
|
TEST(0 == jb.GetFrameForDecoding());
|
|
|
|
// Start
|
|
jb.Start();
|
|
|
|
// Get frame to use for this timestamp
|
|
VCMEncodedFrame* frameIn = jb.GetFrame(packet);
|
|
TEST(frameIn != 0);
|
|
|
|
// No packets inserted
|
|
TEST(0 == jb.GetCompleteFrameForDecoding(10));
|
|
|
|
|
|
//
|
|
// TEST single packet frame
|
|
//
|
|
// --------
|
|
// | 1234 |
|
|
// --------
|
|
|
|
// packet.frameType;
|
|
// packet.dataPtr;
|
|
// packet.sizeBytes;
|
|
// packet.timestamp;
|
|
// packet.seqNum;
|
|
// packet.isFirstPacket;
|
|
// packet.markerBit;
|
|
//
|
|
packet.frameType = kVideoFrameDelta;
|
|
packet.isFirstPacket = true;
|
|
packet.markerBit = true;
|
|
|
|
// 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);
|
|
|
|
CheckOutFrame(frameOut, size, false);
|
|
|
|
// check the frame type
|
|
TEST(frameOut->FrameType() == kVideoFrameDelta);
|
|
|
|
// 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 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);
|
|
|
|
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 = jb.GetCompleteFrameForDecoding(10);
|
|
|
|
CheckOutFrame(frameOut, size*2, false);
|
|
|
|
// 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 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 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 = jb.GetCompleteFrameForDecoding(10);
|
|
|
|
CheckOutFrame(frameOut, size*100, false);
|
|
|
|
// 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 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 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 = jb.GetCompleteFrameForDecoding(10);
|
|
|
|
CheckOutFrame(frameOut, size*100, false);
|
|
|
|
// 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 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--;
|
|
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 = jb.GetCompleteFrameForDecoding(10);
|
|
|
|
CheckOutFrame(frameOut, size*100, false);
|
|
|
|
// 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 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);
|
|
|
|
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 = jb.GetCompleteFrameForDecoding(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 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);
|
|
|
|
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 = jb.GetCompleteFrameForDecoding(10);
|
|
|
|
CheckOutFrame(frameOut, size*2, false);
|
|
|
|
// check the frame type
|
|
TEST(frameOut->FrameType() == kVideoFrameDelta);
|
|
|
|
// Release frame (when done with decoding)
|
|
jb.ReleaseFrame(frameOut);
|
|
|
|
// get the frame
|
|
frameOut = jb.GetCompleteFrameForDecoding(10);
|
|
|
|
CheckOutFrame(frameOut, size*2, false);
|
|
|
|
// 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");
|
|
|
|
//
|
|
// TEST H.263 bits
|
|
//
|
|
// -----------------
|
|
// | 1541 | 1542 |
|
|
// -----------------
|
|
// sBits
|
|
|
|
seqNum++;
|
|
timeStamp += 2*33*90;
|
|
packet.frameType = kVideoFrameDelta;
|
|
packet.isFirstPacket = true;
|
|
packet.markerBit = false;
|
|
packet.seqNum = seqNum;
|
|
packet.timestamp = timeStamp;
|
|
packet.bits = false;
|
|
packet.codec = kVideoCodecH263;
|
|
|
|
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);
|
|
|
|
seqNum++;
|
|
packet.isFirstPacket = false;
|
|
packet.markerBit = true;
|
|
packet.seqNum = seqNum;
|
|
packet.bits = true;
|
|
packet.dataPtr = &(data[9]);
|
|
|
|
frameIn = jb.GetFrame(packet);
|
|
TEST(frameIn != 0);
|
|
|
|
// Insert a packet into a frame
|
|
TEST(kCompleteSession == jb.InsertPacket(frameIn, packet));
|
|
|
|
TEST(timeStamp == jb.GetNextTimeStamp(10, incomingFrameType, renderTimeMs));
|
|
|
|
// get the frame
|
|
frameOut = jb.GetCompleteFrameForDecoding(10);
|
|
|
|
CheckOutFrame(frameOut, (size*2)-1, false);
|
|
|
|
// check the frame type
|
|
TEST(frameOut->FrameType() == kVideoFrameDelta);
|
|
|
|
// Release frame (when done with decoding)
|
|
jb.ReleaseFrame(frameOut);
|
|
|
|
// restore
|
|
packet.dataPtr = data;
|
|
packet.bits = false;
|
|
packet.codec = kVideoCodecUnknown;
|
|
//printf("DONE H.263 frame 2 packets with bits\n");
|
|
|
|
//
|
|
// TEST duplicate packets
|
|
//
|
|
// -----------------
|
|
// | 1543 | 1543 |
|
|
// -----------------
|
|
//
|
|
|
|
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 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);
|
|
|
|
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 = jb.GetCompleteFrameForDecoding(10);
|
|
|
|
CheckOutFrame(frameOut, size*2, false);
|
|
|
|
// 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 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);
|
|
|
|
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 = jb.GetCompleteFrameForDecoding(10);
|
|
|
|
CheckOutFrame(frameOut, size*2+4*2, true);
|
|
|
|
// 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");
|
|
|
|
|
|
// Temporarily do this to make the rest of the test work:
|
|
timeStamp += 33*90;
|
|
seqNum += 4;
|
|
|
|
//
|
|
// TEST statistics
|
|
//
|
|
WebRtc_UWord32 numDeltaFrames = 0;
|
|
WebRtc_UWord32 numKeyFrames = 0;
|
|
TEST(jb.GetFrameStatistics(numDeltaFrames, numKeyFrames) == 0);
|
|
|
|
TEST(numDeltaFrames == 9);
|
|
TEST(numKeyFrames == 1);
|
|
|
|
WebRtc_UWord32 frameRate;
|
|
WebRtc_UWord32 bitRate;
|
|
TEST(jb.GetUpdate(frameRate, bitRate) == 0);
|
|
|
|
// these depend on CPU speed works on a T61
|
|
TEST(frameRate > 30);
|
|
TEST(bitRate > 10000000);
|
|
|
|
//printf("DONE Statistics\n");
|
|
|
|
//
|
|
// TEST delta frame 100 packets with seqNum wrap
|
|
//
|
|
// ---------------------------------------
|
|
// | 65520 | 65521 | ... | 82 | 83 |
|
|
// ---------------------------------------
|
|
//
|
|
|
|
// test flush
|
|
jb.Flush();
|
|
|
|
// insert first packet
|
|
timeStamp += 33*90;
|
|
seqNum = 0xfff0;
|
|
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++;
|
|
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 packet notification
|
|
TEST(timeStamp == jb.GetNextTimeStamp(2, incomingFrameType, renderTimeMs));
|
|
|
|
// check incoming frame type
|
|
TEST(incomingFrameType == kVideoFrameDelta);
|
|
|
|
// get the frame
|
|
frameOut = jb.GetCompleteFrameForDecoding(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 = jb.GetCompleteFrameForDecoding(10);
|
|
|
|
CheckOutFrame(frameOut, size*100, false);
|
|
|
|
// check the frame type
|
|
TEST(frameOut->FrameType() == kVideoFrameDelta);
|
|
|
|
// 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 = 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 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 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 packet notification
|
|
TEST(timeStamp == jb.GetNextTimeStamp(2, incomingFrameType, renderTimeMs));
|
|
|
|
// check incoming frame type
|
|
TEST(incomingFrameType == kVideoFrameDelta);
|
|
|
|
// get the frame
|
|
frameOut = jb.GetCompleteFrameForDecoding(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 = jb.GetCompleteFrameForDecoding(10);
|
|
|
|
CheckOutFrame(frameOut, size*100, false);
|
|
|
|
// 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 = 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 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 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 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);
|
|
|
|
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 = jb.GetCompleteFrameForDecoding(10);
|
|
|
|
CheckOutFrame(frameOut, size*3, false);
|
|
|
|
// 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 packet notification
|
|
TEST(3000 == jb.GetNextTimeStamp(10, incomingFrameType, renderTimeMs));
|
|
TEST(kVideoFrameDelta == incomingFrameType);
|
|
|
|
// Get the frame
|
|
frameOut = jb.GetCompleteFrameForDecoding(10);
|
|
TEST(3000 == frameOut->TimeStamp());
|
|
|
|
CheckOutFrame(frameOut, size, false);
|
|
|
|
// check the frame type
|
|
TEST(frameOut->FrameType() == kVideoFrameDelta);
|
|
|
|
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 packet notification
|
|
TEST(timeStamp == jb.GetNextTimeStamp(10, incomingFrameType, renderTimeMs));
|
|
TEST(kVideoFrameDelta == incomingFrameType);
|
|
|
|
// Get the frame
|
|
frameOut = jb.GetCompleteFrameForDecoding(10);
|
|
TEST(timeStamp == frameOut->TimeStamp());
|
|
|
|
CheckOutFrame(frameOut, size, false);
|
|
|
|
// check the frame type
|
|
TEST(frameOut->FrameType() == kVideoFrameDelta);
|
|
|
|
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 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);
|
|
|
|
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 = jb.GetCompleteFrameForDecoding(10);
|
|
|
|
CheckOutFrame(frameOut, size*2, false);
|
|
|
|
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 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);
|
|
|
|
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 = jb.GetCompleteFrameForDecoding(10);
|
|
|
|
CheckOutFrame(frameOut, size*2, false);
|
|
|
|
// 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));
|
|
|
|
// Get packet notification
|
|
TEST(0xffffff00 == jb.GetNextTimeStamp(10, incomingFrameType, renderTimeMs));
|
|
TEST(kVideoFrameDelta == incomingFrameType);
|
|
|
|
// 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 packet notification
|
|
TEST(0xffffff00 == jb.GetNextTimeStamp(10, incomingFrameType, renderTimeMs));
|
|
TEST(kVideoFrameDelta == incomingFrameType);
|
|
|
|
// Get frame
|
|
frameOut = jb.GetCompleteFrameForDecoding(10);
|
|
TEST(0xffffff00 == frameOut->TimeStamp());
|
|
|
|
CheckOutFrame(frameOut, size, false);
|
|
|
|
// check the frame type
|
|
TEST(frameOut->FrameType() == kVideoFrameDelta);
|
|
|
|
// Get packet notification
|
|
TEST(2700 == jb.GetNextTimeStamp(0, incomingFrameType, renderTimeMs));
|
|
TEST(kVideoFrameDelta == incomingFrameType);
|
|
|
|
// Get frame
|
|
VCMEncodedFrame* frameOut2 = jb.GetCompleteFrameForDecoding(10);
|
|
TEST(2700 == frameOut2->TimeStamp());
|
|
|
|
CheckOutFrame(frameOut2, size, false);
|
|
|
|
// 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));
|
|
|
|
// Get packet notification
|
|
TEST(2700 == jb.GetNextTimeStamp(10, incomingFrameType, renderTimeMs));
|
|
TEST(kVideoFrameDelta == incomingFrameType);
|
|
|
|
// 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 packet notification
|
|
TEST(0xffffff00 == jb.GetNextTimeStamp(10, incomingFrameType, renderTimeMs));
|
|
TEST(kVideoFrameDelta == incomingFrameType);
|
|
|
|
// Get frame
|
|
frameOut = jb.GetCompleteFrameForDecoding(10);
|
|
TEST(0xffffff00 == frameOut->TimeStamp());
|
|
|
|
CheckOutFrame(frameOut, size, false);
|
|
|
|
// check the frame type
|
|
TEST(frameOut->FrameType() == kVideoFrameDelta);
|
|
|
|
// get packet notification
|
|
TEST(2700 == jb.GetNextTimeStamp(0, incomingFrameType, renderTimeMs));
|
|
TEST(kVideoFrameDelta == incomingFrameType);
|
|
|
|
// Get frame
|
|
frameOut2 = jb.GetCompleteFrameForDecoding(10);
|
|
TEST(2700 == frameOut2->TimeStamp());
|
|
|
|
CheckOutFrame(frameOut2, size, false);
|
|
|
|
// 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 NACK
|
|
//
|
|
// ---------------------------------------------------------------------------------------------
|
|
// | 3 | 4 | 5 | 6 | 7 | 9 | x | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | x | 21 |.....| 102 |
|
|
// ---------------------------------------------------------------------------------------------
|
|
jb.SetNackMode(kNackInfinite);
|
|
|
|
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);
|
|
|
|
CheckOutFrame(frameOut, size, false);
|
|
|
|
// 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
|
|
//
|
|
|
|
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));
|
|
}
|
|
|
|
// get packet notification
|
|
TEST(packet.timestamp == jb.GetNextTimeStamp(10, incomingFrameType, renderTimeMs));
|
|
|
|
// check incoming frame type
|
|
TEST(incomingFrameType == kVideoFrameDelta);
|
|
|
|
loop++;
|
|
} while (loop < kMaxPacketsInJitterBuffer);
|
|
|
|
// 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));
|
|
|
|
// should fail
|
|
TEST(-1 == jb.GetNextTimeStamp(10, incomingFrameType, renderTimeMs));
|
|
TEST(0 == jb.GetCompleteFrameForDecoding(10));
|
|
|
|
//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
|
|
//
|
|
// --------------------------------------------------------------
|
|
// | 65485 | 65486 | 65487 | .... | 65535 | 0 | 1 | 2 | .....| 50 |
|
|
// --------------------------------------------------------------
|
|
// |<-----------delta frames------------->|<------key frames----->|
|
|
|
|
jb.Flush();
|
|
|
|
loop = 0;
|
|
seqNum = 65485;
|
|
timeStampStart = timeStamp + 33*90;
|
|
WebRtc_UWord32 timeStampFirstKey = 0;
|
|
VCMEncodedFrame* ptrLastDeltaFrame;
|
|
VCMEncodedFrame* ptrFirstKeyFrame;
|
|
// 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;
|
|
timeStampFirstKey = packet.timestamp;
|
|
}
|
|
|
|
// Insert frame
|
|
TEST(kFirstPacket == jb.InsertPacket(frameIn, packet));
|
|
|
|
// Get packet notification, should be first inserted frame
|
|
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;
|
|
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));
|
|
|
|
// First inserted key frame should be oldest in buffer
|
|
TEST(timeStampFirstKey == jb.GetNextTimeStamp(10, incomingFrameType,
|
|
renderTimeMs));
|
|
|
|
// check incoming frame type
|
|
TEST(incomingFrameType == kVideoFrameKey);
|
|
|
|
// get the first key frame
|
|
frameOut = jb.GetCompleteFrameForDecoding(10);
|
|
TEST(ptrFirstKeyFrame == frameOut);
|
|
|
|
CheckOutFrame(frameOut, size, false);
|
|
|
|
// 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");
|
|
|
|
// 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(kFirstPacket == 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(kFirstPacket == 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);
|
|
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);
|
|
|
|
|
|
// printf(DONE testing inserting empty packets to the JB)
|
|
|
|
|
|
// H.264 tests
|
|
//Test incomplete NALU frames
|
|
|
|
jb.Flush();
|
|
jb.SetNackMode(kNoNack);
|
|
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));
|
|
|
|
|
|
// get packet notification
|
|
TEST(timeStamp == jb.GetNextTimeStamp(10, incomingFrameType, renderTimeMs));
|
|
frameOut = jb.GetFrameForDecoding();
|
|
|
|
// 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.
|
|
CheckOutFrame(frameOut, packet.sizeBytes * 2, false);
|
|
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
|
|
insertedLength+=0;
|
|
|
|
frameOut = jb.GetFrameForDecoding();
|
|
// Only last NALU is complete
|
|
CheckOutFrame(frameOut, insertedLength, false);
|
|
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;
|
|
|
|
TEST(-1 == jb.GetNextTimeStamp(10, incomingFrameType, renderTimeMs));
|
|
TEST(NULL==jb.GetFrameForDecoding());
|
|
|
|
|
|
// 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.GetCompleteFrameForDecoding(10);
|
|
// Only last NALU is complete
|
|
CheckOutFrame(frameOut, packet.sizeBytes, false);
|
|
jb.Flush();
|
|
|
|
// Three reordered H263 packets with bits.
|
|
|
|
packet.codec = kVideoCodecH263;
|
|
packet.frameType = kVideoFrameDelta;
|
|
packet.isFirstPacket = false;
|
|
packet.markerBit = false;
|
|
packet.bits = true;
|
|
packet.seqNum += 1;
|
|
WebRtc_UWord8 oldData1 = data[0];
|
|
WebRtc_UWord8 oldData2 = data[packet.sizeBytes - 1];
|
|
unsigned char startByte = 0x07;
|
|
unsigned char endByte = 0xF8;
|
|
data[0] = startByte;
|
|
TEST(frameIn = jb.GetFrame(packet));
|
|
TEST(kFirstPacket == jb.InsertPacket(frameIn, packet));
|
|
frameOut = jb.GetFrameForDecoding();
|
|
TEST(frameOut == NULL);
|
|
|
|
packet.seqNum -= 1;
|
|
packet.isFirstPacket = true;
|
|
packet.bits = false;
|
|
data[0] = oldData1;
|
|
data[packet.sizeBytes - 1] = endByte;
|
|
TEST(frameIn = jb.GetFrame(packet));
|
|
TEST(kIncomplete == jb.InsertPacket(frameIn, packet));
|
|
frameOut = jb.GetFrameForDecoding();
|
|
TEST(frameOut == NULL);
|
|
|
|
packet.seqNum += 2;
|
|
packet.isFirstPacket = false;
|
|
packet.markerBit = true;
|
|
data[packet.sizeBytes - 1] = oldData2;
|
|
TEST(frameIn = jb.GetFrame(packet));
|
|
TEST(kCompleteSession == jb.InsertPacket(frameIn, packet));
|
|
frameOut = jb.GetFrameForDecoding();
|
|
TEST(frameOut != NULL);
|
|
//CheckOutFrame(frameOut, packet.sizeBytes * 3 - 1, false);
|
|
const WebRtc_UWord8* buf = frameOut->Buffer();
|
|
TEST(buf[packet.sizeBytes - 1] == (startByte | endByte));
|
|
|
|
// First packet lost, second packet with bits.
|
|
|
|
packet.frameType = kVideoFrameDelta;
|
|
packet.isFirstPacket = false;
|
|
packet.markerBit = true;
|
|
packet.bits = true;
|
|
packet.seqNum += 2;
|
|
packet.timestamp += 33*90;
|
|
data[0] = 0x07;
|
|
data[packet.sizeBytes - 1] = 0xF8;
|
|
//unsigned char startByte = packet.dataPtr[0];
|
|
//unsigned char endByte = packet.dataPtr[packet.sizeBytes-1];
|
|
TEST(frameIn = jb.GetFrame(packet));
|
|
TEST(kFirstPacket == jb.InsertPacket(frameIn, packet));
|
|
frameOut = jb.GetFrameForDecoding();
|
|
TEST(frameOut != NULL);
|
|
TEST(frameOut->Length() == 0);
|
|
|
|
data[0] = oldData1;
|
|
data[packet.sizeBytes - 1] = oldData2;
|
|
packet.codec = kVideoCodecUnknown;
|
|
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.bits = false;
|
|
packet.frameType = kVideoFrameDelta;
|
|
packet.isFirstPacket = false;
|
|
packet.markerBit = false;
|
|
|
|
TEST(frameIn = jb.GetFrame(packet));
|
|
TEST(kFirstPacket == jb.InsertPacket(frameIn, packet));
|
|
|
|
frameOut = jb.GetFrameForDecoding();
|
|
TEST(frameOut == NULL);
|
|
|
|
packet.seqNum += 2;
|
|
packet.timestamp += 33*90;
|
|
|
|
TEST(frameIn = jb.GetFrame(packet));
|
|
TEST(kFirstPacket == jb.InsertPacket(frameIn, packet));
|
|
|
|
frameOut = jb.GetFrameForDecoding();
|
|
|
|
TEST(frameOut != NULL);
|
|
CheckOutFrame(frameOut, packet.sizeBytes, false);
|
|
|
|
jb.Flush();
|
|
|
|
// Test that a we can get incomplete frames from the JB if we have received
|
|
// the marker bit.
|
|
packet.seqNum +=2;
|
|
packet.frameType = kVideoFrameDelta;
|
|
packet.isFirstPacket = false;
|
|
packet.markerBit = true;
|
|
|
|
TEST(frameIn = jb.GetFrame(packet));
|
|
TEST(kFirstPacket == jb.InsertPacket(frameIn, packet));
|
|
|
|
frameOut = jb.GetFrameForDecoding();
|
|
TEST(frameOut != NULL);
|
|
|
|
// ---
|
|
jb.Stop();
|
|
|
|
printf("DONE !!!\n");
|
|
EventWrapper* waitEvent = EventWrapper::Create();
|
|
waitEvent->Wait(5000);
|
|
|
|
return 0;
|
|
|
|
}
|