blob: 788af4dac0524390e60ecd4e9ca175b95c3cbbb2 [file] [log] [blame]
/* ------------------------------------------------------------------
* Copyright (C) 1998-2009 PacketVideo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied.
* See the License for the specific language governing permissions
* and limitations under the License.
* -------------------------------------------------------------------
*/
#ifndef PVMF_JITTER_BUFFER_H_INCLUDED
#define PVMF_JITTER_BUFFER_H_INCLUDED
#ifndef OSCL_BASE_H_INCLUDED
#include "oscl_base.h"
#endif
#ifndef OSCL_VECTOR_H_INCLUDED
#include "oscl_vector.h"
#endif
#ifndef OSCL_STRING_CONTAINERS_H_INCLUDED
#include "oscl_string_containers.h"
#endif
#ifndef OSCL_MEM_MEMPOOL_H_INCLUDED
#include "oscl_mem_mempool.h"
#endif
#ifndef PVLOGGER_H_INCLUDED
#include "pvlogger.h"
#endif
#ifndef PVMF_TIMESTAMP_H_INCLUDED
#include "pvmf_timestamp.h"
#endif
#ifndef PVMF_MEDIA_DATA_H_INCLUDED
#include "pvmf_media_data.h"
#endif
#ifndef PVMF_MEDIA_FRAG_GROUP_H_INCLUDED
#include "pvmf_media_frag_group.h"
#endif
#ifndef PVMF_SM_TUNABLES_H_INCLUDED
#include "pvmf_sm_tunables.h"
#endif
#ifndef __MEDIA_CLOCK_CONVERTER_H
#include "media_clock_converter.h"
#endif
#ifndef PVMF_MEDIA_MSG_FORMAT_IDS_H_INCLUDED
#include "pvmf_media_msg_format_ids.h"
#endif
#ifndef PVMF_EVENT_HANDLING_H_INCLUDED
#include "pvmf_event_handling.h"
#endif
#ifndef PVMF_JITTER_BUFFER_COMMON_TYPES_H_INCLUDED
#include "pvmf_jitter_buffer_common_types.h"
#endif
#ifndef PVMF_MEDIA_CLOCK_H_INCLUDED
#include "pvmf_media_clock.h"
#endif
#ifndef PVMF_JITTER_BUFFER_COMMON_INTERNAL_H
#include "pvmf_jitter_buffer_common_internal.h"
#endif
#ifndef OSCL_DLL_H_INCLUDED
#include "oscl_dll.h"
#endif
#ifndef PVMF_JB_EVENT_NOTIFIER_H
#include "pvmf_jb_event_notifier.h"
#endif
#ifndef PVMF_FORMAT_TYPE_H_INCLUDED
#include "pvmf_format_type.h"
#endif
class PVMFSMSharedBufferAllocWithReSize;
class PVMFJitterBufferStats
{
public:
PVMFJitterBufferStats()
{
ResetStats();
}
void ResetStats()
{
totalNumPacketsReceived = 0;
totalNumPacketsRegistered = 0;
totalPacketsLost = 0;
totalNumPacketsRetrieved = 0;
//Timestamp info
maxTimeStampRegistered = 0;
maxTimeStampRetrieved = 0;
//Occupancy related
maxOccupancy = 0;
currentOccupancy = 0;
totalNumBytesRecvd = 0;
packetSizeInBytesLeftInBuffer = 0;
//Seq num info
maxSeqNumReceived = 0;
maxSeqNumRegistered = 0;
lastRegisteredSeqNum = 0;
lastRetrievedSeqNum = 0;
seqNumBase = 0;
maxTimeStampRetrievedWithoutRTPOffset = 0;
ssrc = 0;
}
//Packet info
uint32 totalNumPacketsReceived;
uint32 totalNumPacketsRegistered;
uint32 totalPacketsLost;
uint32 totalNumPacketsRetrieved;
//Timestamp info
PVMFTimestamp maxTimeStampRegistered;
PVMFTimestamp maxTimeStampRetrieved;
//Occupancy related
uint32 maxOccupancy;
uint32 currentOccupancy;
uint32 totalNumBytesRecvd;
uint32 packetSizeInBytesLeftInBuffer;
//Seq num info
uint32 maxSeqNumReceived;
uint32 maxSeqNumRegistered;
uint32 lastRegisteredSeqNum;
uint32 lastRetrievedSeqNum;
uint32 seqNumBase;
PVMFTimestamp maxTimeStampRetrievedWithoutRTPOffset;
uint32 ssrc;
};
class MediaCommandMsgHolder
{
public:
MediaCommandMsgHolder()
{
iPreceedingMediaMsgSeqNumber = 0xFFFFFFFF;
};
MediaCommandMsgHolder(const MediaCommandMsgHolder& a)
{
iPreceedingMediaMsgSeqNumber = a.iPreceedingMediaMsgSeqNumber;
iCmdMsg = a.iCmdMsg ;
}
MediaCommandMsgHolder& operator=(const MediaCommandMsgHolder& a)
{
if (&a != this)
{
iPreceedingMediaMsgSeqNumber = a.iPreceedingMediaMsgSeqNumber;
iCmdMsg = a.iCmdMsg ;
}
return (*this);
}
uint32 iPreceedingMediaMsgSeqNumber;
PVMFSharedMediaMsgPtr iCmdMsg;
};
typedef enum
{
PVMF_JITTER_BUFFER_ADD_ELEM_ERROR,
PVMF_JITTER_BUFFER_ADD_ELEM_PACKET_OVERWRITE,
PVMF_JITTER_BUFFER_ADD_ELEM_SUCCESS
} PVMFJitterBufferAddElemStatus;
template<class Alloc>
class PVMFDynamicCircularArray
{
public:
PVMFDynamicCircularArray()
{
iNumElems = 0;
iArraySize = 0;
iMaxSeqNumAdded = 0;
iLastRetrievedSeqNum = 0;
iLastRetrievedTS = 0;
iReadOffset = 0;
iFirstSeqNumAdded = 0;
ipLogger = PVLogger::GetLoggerObject("PVMFDynamicCircularArray");
ipDataPathLoggerIn = PVLogger::GetLoggerObject("datapath.sourcenode.jitterbuffer.in");
ipDataPathLoggerOut = PVLogger::GetLoggerObject("datapath.sourcenode.jitterbuffer.out");
}
PVMFDynamicCircularArray(uint32 n)
{
iNumElems = 0;
iArraySize = n;
iMaxSeqNumAdded = 0;
iLastRetrievedSeqNum = 0;
iLastRetrievedTS = 0;
iReadOffset = 0;
iFirstSeqNumAdded = 0;
iMediaPtrVec.reserve(iArraySize);
InitVector(iArraySize);
ipLogger = PVLogger::GetLoggerObject("PVMFDynamicCircularArray");
ipDataPathLoggerIn = PVLogger::GetLoggerObject("datapath.sourcenode.jitterbuffer.in");
ipDataPathLoggerOut = PVLogger::GetLoggerObject("datapath.sourcenode.jitterbuffer.out");
}
virtual ~PVMFDynamicCircularArray()
{
if (!iMediaPtrVec.empty())
{
typedef typename Oscl_Vector<PVMFSharedMediaDataPtr, Alloc>::iterator iterator_type;
iterator_type it;
for (it = iMediaPtrVec.begin(); it != iMediaPtrVec.end(); it++)
{
if (it->GetRep() != NULL)
{
it->Unbind();
}
}
}
}
void Clear()
{
PVMF_JB_LOGINFO((0, "PVMFDynamicCircularArray::Clear - Cleared Jitter Buffer"));
typedef typename Oscl_Vector<PVMFSharedMediaDataPtr, Alloc>::iterator iterator_type;
iterator_type it;
for (it = iMediaPtrVec.begin(); it != iMediaPtrVec.end(); it++)
{
if (it->GetRep() != NULL)
{
it->Unbind();
}
}
iNumElems = 0;
iMediaPtrVec.clear();
InitVector(iArraySize);
iMaxSeqNumAdded = 0;
iLastRetrievedSeqNum = 0;
iLastRetrievedTS = 0;
iReadOffset = 0;
iFirstSeqNumAdded = 0;
iJitterBufferStats.currentOccupancy = 0;
iJitterBufferStats.packetSizeInBytesLeftInBuffer = 0;
}
void ResetJitterBufferStats()
{
iJitterBufferStats.ResetStats();
}
uint32 getNumElements()
{
return iNumElems;
}
uint32 getArraySize()
{
return iArraySize;
}
void growCircularArray(uint32 newSize)
{
if (newSize > iArraySize)
{
/*
* This transfers the existing contents
* as well
*/
iMediaPtrVec.reserve(newSize);
/* Initialize the new space */
InitVector((newSize - iArraySize));
iArraySize = newSize;
}
}
void setFirstSeqNumAdded(uint32 aFirstSeqNumAdded)
{
iFirstSeqNumAdded = aFirstSeqNumAdded;
}
//validations on timestamp and seqnum has to be done by the user of the dynamic circular array.
PVMFJitterBufferAddElemStatus addElement(PVMFSharedMediaDataPtr& elem, uint32 aSeqNumBase)
{
PVMFJitterBufferAddElemStatus oRet = PVMF_JITTER_BUFFER_ADD_ELEM_SUCCESS;
iJitterBufferStats.totalNumPacketsReceived++;
iJitterBufferStats.ssrc = elem->getStreamID();
uint32 seqNum = elem->getSeqNum();
/* Get packet size */
uint32 size = 0;
uint32 numFragments = elem->getNumFragments();
for (uint32 i = 0; i < numFragments; i++)
{
OsclRefCounterMemFrag memFragIn;
elem->getMediaFragment(i, memFragIn);
size += memFragIn.getMemFrag().len;
}
iJitterBufferStats.totalNumBytesRecvd += size;
iJitterBufferStats.packetSizeInBytesLeftInBuffer += size;
//Assumptions:
//- Validations based on ts and SeqNum are performed by the calling code,
//- By the time the code flows at this point we had already resetted the
// maxSeqNumRegistered to rolled over value in the derived implementation
if (seqNum > iJitterBufferStats.maxSeqNumRegistered)
{
iJitterBufferStats.maxSeqNumReceived = seqNum;
}
uint32 offset = (seqNum - aSeqNumBase) % iArraySize;
PVMFSharedMediaDataPtr currElem = iMediaPtrVec[offset];
if (currElem.GetRep() == NULL)
{
/* Register Packet */
iMediaPtrVec[offset] = elem;
iNumElems++;
iJitterBufferStats.totalNumPacketsRegistered++;
iJitterBufferStats.lastRegisteredSeqNum = seqNum;
if (seqNum > iJitterBufferStats.maxSeqNumRegistered)
{
iJitterBufferStats.maxSeqNumRegistered = seqNum;
iJitterBufferStats.maxTimeStampRegistered = elem->getTimestamp();
}
iJitterBufferStats.currentOccupancy = iNumElems;
PVMF_JB_LOGDATATRAFFIC_IN((0, "AddElement seqNum %d iNumElems %d", seqNum, iNumElems));
return (oRet);
}
else if (currElem->getSeqNum() != seqNum)
{
PVMF_JB_LOGDATATRAFFIC_IN((0, "[0x%x] JB OW: iReadOffset=%d, iNumElemsLeft=%d, iLastRetrievedSeqNum=%d, old seqNum=%d, new seqNum=%d",
this,
iReadOffset,
iNumElems,
iLastRetrievedSeqNum,
seqNum,
currElem->getSeqNum()));
/* Overwrite existing data */
currElem.Unbind();
/* Register Packet */
iMediaPtrVec[offset] = elem;
iJitterBufferStats.totalNumPacketsRegistered++;
iJitterBufferStats.lastRegisteredSeqNum = seqNum;
if (seqNum > iJitterBufferStats.maxSeqNumRegistered)
{
iJitterBufferStats.maxSeqNumRegistered = seqNum;
iJitterBufferStats.maxTimeStampRegistered = elem->getTimestamp();
}
iJitterBufferStats.currentOccupancy = iNumElems;
oRet = PVMF_JITTER_BUFFER_ADD_ELEM_PACKET_OVERWRITE;
return (oRet);
}
else
{
PVMF_JB_LOGDATATRAFFIC_IN((0, "[0x%x]Duplicate packet iNumElems %d", this, iNumElems));
}
/* Duplicate Packet - Ignore */
return (oRet);
}
PVMFSharedMediaDataPtr retrieveElement()
{
PVMFSharedMediaDataPtr dataPkt;
uint32 count = 0;
while (dataPkt.GetRep() == NULL)
{
/* No data */
if (count > iArraySize)
{
dataPkt.Unbind();
return dataPkt;
}
/* Wrap around */
if (iReadOffset >= iArraySize)
{
iReadOffset = 0;
}
dataPkt = iMediaPtrVec[iReadOffset];
if (dataPkt.GetRep() == NULL)
{
PVMF_JB_LOGDATATRAFFIC_IN_E((0, "[0x%x] Hole in Jb at index %u", this, iReadOffset));
}
iReadOffset++;
count++;
}
iNumElems--;
/* Mark the retrieved element location as free */
PVMFSharedMediaDataPtr retElem = iMediaPtrVec[iReadOffset-1];
retElem.Unbind();
iMediaPtrVec[iReadOffset-1] = retElem;
iLastRetrievedSeqNum = (int32)(dataPkt.GetRep()->getSeqNum());
/* Check and register packet loss */
iJitterBufferStats.totalPacketsLost += (count - 1);
iJitterBufferStats.maxTimeStampRetrieved = dataPkt->getTimestamp();
iJitterBufferStats.currentOccupancy = iNumElems;
iJitterBufferStats.totalNumPacketsRetrieved++;
iJitterBufferStats.lastRetrievedSeqNum = iLastRetrievedSeqNum;
/* Get packet size */
uint32 size = 0;
uint32 numFragments = dataPkt->getNumFragments();
for (uint32 i = 0; i < numFragments; i++)
{
OsclRefCounterMemFrag memFragIn;
dataPkt->getMediaFragment(i, memFragIn);
size += memFragIn.getMemFrag().len;
}
iJitterBufferStats.packetSizeInBytesLeftInBuffer -= size;
PVMF_JB_LOGDATATRAFFIC_OUT((0, "[0x%x]PVMFDynamicCircularArray::retrieveElement: iReadOffset=%d, iNumElemsLeft=%d, SeqNum=%d",
this,
iReadOffset,
iNumElems,
iLastRetrievedSeqNum));
return (dataPkt);
}
PVMFJitterBufferStats& getStats()
{
return iJitterBufferStats;
}
PVMFJitterBufferStats* getStatsPtr()
{
return &iJitterBufferStats;
}
void peekNextElementTimeStamp(PVMFTimestamp& aTS,
uint32& aSeqNum)
{
PVMFSharedMediaDataPtr dataPkt;
uint32 peekOffset = iReadOffset;
uint32 count = 0;
while (dataPkt.GetRep() == NULL)
{
if (count > iNumElems)
{
aTS = 0xFFFFFFFF;
}
if (peekOffset >= iArraySize)
{
peekOffset = 0;
}
dataPkt = iMediaPtrVec[peekOffset];
peekOffset++;
count++;
}
aTS = dataPkt.GetRep()->getTimestamp();
aSeqNum = dataPkt.GetRep()->getSeqNum();
return;
}
void peekMaxElementTimeStamp(PVMFTimestamp& aTS,
uint32& aSeqNum)
{
aTS = iJitterBufferStats.maxTimeStampRegistered;
aSeqNum = iJitterBufferStats.maxSeqNumRegistered;
return;
}
bool CheckCurrentReadPosition()
{
uint32 offset = iReadOffset;
if (offset >= iArraySize)
{
offset = 0;
}
PVMFSharedMediaDataPtr dataPkt =
iMediaPtrVec[offset];
if (dataPkt.GetRep() == NULL)
{
return false;
}
return true;
}
bool CheckSpaceAvailability(uint32 aNumElements = 1)
{
if ((iArraySize - iNumElems) > aNumElements)
{
return true;
}
return false;
}
void setSeqNumBase(uint32 aSeqNum)
{
iJitterBufferStats.seqNumBase = aSeqNum;
}
//setRTPInfoParams replaced by setSeqNumBase
PVMFSharedMediaDataPtr getElementAt(uint32 aIndex)
{
if (aIndex > iArraySize) OSCL_LEAVE(OsclErrArgument);
return (iMediaPtrVec[aIndex]);
}
void AddElementAt(PVMFSharedMediaDataPtr aMediaPtr,
uint32 aIndex)
{
if (aIndex > iArraySize) OSCL_LEAVE(OsclErrArgument);
iMediaPtrVec[aIndex] = aMediaPtr;
}
void PurgeElementsWithSeqNumsLessThan(uint32 aSeqNum, uint32 aPrevSeqNumBaseOut)
{
PVMF_JB_LOGINFO((0, "PVMFDynamicCircularArray::PurgeElementsWithSeqNumsLessThan SeqNum %d aPrevSeqNumBaseOut %d", aSeqNum, aPrevSeqNumBaseOut));
if (!iMediaPtrVec.empty())
{
if (aSeqNum < iLastRetrievedSeqNum)
{
typedef typename Oscl_Vector<PVMFSharedMediaDataPtr, Alloc>::iterator iterator_type;
iterator_type it;
for (it = iMediaPtrVec.begin(); it != iMediaPtrVec.end(); it++)
{
if (it->GetRep() != NULL)
{
/* Get packet size */
uint32 size = 0;
uint32 numFragments = it->GetRep()->getNumFragments();
for (uint32 i = 0; i < numFragments; i++)
{
OsclRefCounterMemFrag memFragIn;
it->GetRep()->getMediaFragment(i, memFragIn);
size += memFragIn.getMemFrag().len;
}
iJitterBufferStats.packetSizeInBytesLeftInBuffer -= size;
it->Unbind();
}
}
iNumElems = 0;
/* If after purging all elements, we want to determine the TS of the previous element
* (with DeterminePrevTimeStampPeek()), it will give as false information if the
* seqnum has wrapped around. So because of that, we set aPrevSeqNumBaseOut to be smaller
* than the current seqnum (RIO-4021).
*/
aPrevSeqNumBaseOut = aSeqNum - 1;
}
else if (aSeqNum > iLastRetrievedSeqNum)
{
/*
* Start from last retrieved seq num and offset it by
* first seq number added
* This guarantees that we deallocate in the allocation
* sequence.
*/
uint32 startoffset = ((iLastRetrievedSeqNum - iFirstSeqNumAdded) + 1) % iArraySize;
PVMF_JB_LOGDATATRAFFIC_OUT((0, "[0x%x]PVMFDynamicCircularArray::PurgeElementsWithSeqNumsLessThan: SeqNum=%d, StartOffset=%d, iArraySize=%d",
this,
aSeqNum,
startoffset,
iArraySize));
for (uint32 i = 0; i < aSeqNum - (iLastRetrievedSeqNum + 1); i++)
{
uint32 offset = (startoffset + i) % iArraySize;
/* Mark the retrieved element location as free */
PVMFSharedMediaDataPtr elem = iMediaPtrVec[offset];
if (elem.GetRep() != NULL)
{
if (elem->getSeqNum() < aSeqNum)
{
/* Get packet size */
uint32 size = 0;
uint32 numFragments = elem->getNumFragments();
for (uint32 i = 0; i < numFragments; i++)
{
OsclRefCounterMemFrag memFragIn;
elem->getMediaFragment(i, memFragIn);
size += memFragIn.getMemFrag().len;
}
iJitterBufferStats.packetSizeInBytesLeftInBuffer -= size;
elem.Unbind();
iMediaPtrVec[offset] = elem;
iNumElems--;
}
}
}
}
}
/* To prevent us from registering any old packets */
iLastRetrievedSeqNum = aSeqNum - 1;
iJitterBufferStats.lastRetrievedSeqNum = iLastRetrievedSeqNum;
iJitterBufferStats.currentOccupancy = iNumElems;
SetReadOffset(aSeqNum);
}
void PurgeElementsWithTimestampLessThan(PVMFTimestamp aTS)
{
if (!iMediaPtrVec.empty())
{
while (iNumElems > 0)
{
/* Wrap around */
if (iReadOffset >= iArraySize)
{
iReadOffset = 0;
}
PVMFSharedMediaDataPtr dataPkt = iMediaPtrVec[iReadOffset];
if (dataPkt.GetRep() != NULL)
{
PVMF_JB_LOGDATATRAFFIC_IN((0, "[0x%x]JB Purge:ReadOffset=%d, NumElemsLeft=%d, lastRetrievedSeqNum=%d, seqNum=%d",
this,
iReadOffset,
iNumElems,
iLastRetrievedSeqNum,
dataPkt->getSeqNum()));
PVMFTimestamp tmpTS = dataPkt.GetRep()->getTimestamp();
if (tmpTS >= aTS)
break;
/* Get packet size */
uint32 size = 0;
uint32 numFragments = dataPkt->getNumFragments();
for (uint32 i = 0; i < numFragments; i++)
{
OsclRefCounterMemFrag memFragIn;
dataPkt->getMediaFragment(i, memFragIn);
size += memFragIn.getMemFrag().len;
}
iJitterBufferStats.packetSizeInBytesLeftInBuffer -= size;
(iMediaPtrVec[iReadOffset]).Unbind();
iNumElems--;
}
iReadOffset++;
}
}
/* To prevent us from registering any old packets */
iLastRetrievedTS = aTS;
iJitterBufferStats.currentOccupancy = iNumElems;
}
void SetReadOffset(uint32 aSeqNum)
{
iReadOffset = (aSeqNum - iFirstSeqNumAdded) % iArraySize;
}
private:
void InitVector(uint32 size)
{
for (uint32 i = 0; i < size; i++)
{
PVMFSharedMediaDataPtr sharedMediaPtr;
iMediaPtrVec.push_back(sharedMediaPtr);
}
}
uint32 iNumElems;
uint32 iArraySize;
uint32 iReadOffset;
uint32 iLastRetrievedSeqNum;
PVMFTimestamp iLastRetrievedTS;
uint32 iMaxSeqNumAdded;
uint32 iFirstSeqNumAdded;
PVMFJitterBufferStats iJitterBufferStats;
Oscl_Vector<PVMFSharedMediaDataPtr, Alloc> iMediaPtrVec;
PVLogger* ipLogger;
PVLogger* ipDataPathLoggerIn;
PVLogger* ipDataPathLoggerOut;
};
class PVMFJitterBufferObserver
{
public:
virtual ~PVMFJitterBufferObserver() {}
virtual void JitterBufferFreeSpaceAvailable(OsclAny* aContext) = 0;
virtual void ProcessJBInfoEvent(PVMFAsyncEvent& aEvent) = 0;
virtual void PacketReadyToBeRetrieved(OsclAny* aContext) = 0;
virtual void EndOfStreamSignalled(OsclAny* aContext) = 0;
};
class PVMFJitterBuffer
{
public:
virtual ~PVMFJitterBuffer() {}
/**
This API will be called when Streaming will be started, i.e. when
we are attempting to set up the transport for communication with the server
(firewall packet xchange) So, the jitter buffer should be in a state to
start accepting the *valid* packets from the server.
This API will start/initialize the estimation of the server clock
aka estimated server clock.
Can Leave: No
*/
virtual void StreamingSessionStarted() = 0;
/**
This API will be called when Streaming will be paused, i.e. we expect the server to stop
sending the data. Because of async nature of the SDK, there may be possibility of receiving
some data from the server. So, Jb will continue to accept any valid data.
Can Leave: No
*/
virtual void StreamingSessionPaused() = 0;
/**
This API will be called when Streaming session is considered terminated (from server/client),
Jb will not accept any packet from the server after this call and will flush itself.
Can Leave: No
*/
virtual void StreamingSessionStopped() = 0;
/**
To have smooth playback, jitter buffer needs to have sufficient amount of data ahead of the
current playback position. As data flows out of the jitter buffer, the occupancy of the jitter
buffer will decrease. To order to have sufficient data in it, jitter buffer will go into
rebuffering once differnce between the estimated server clock and playback clock becomes
less than *RebufferingThreshold*. The value of this "RebufferingThreshold" is
initialized/modified by this API.
params:
aRebufferingThresholdInMilliSeconds:[in] uint32
Can Leave: No
Constraint:
This value ought to be less than "Delay/Duration" specified by "SetDurationInMilliSeconds" API
*/
virtual void SetRebufferingThresholdInMilliSeconds(uint32 aRebufferingThresholdInMilliSeconds) = 0;
/**
To have smooth playback, before letting any data out of it, jitter buffer accumulates sufficient
amount of data ahead of the current playback position.
The amoount of data that Jb should acculate is discated by this API.
"aDuration" specifies the amount of data(in millisec) Jb should accumuate before letting any data out of it.
params:
aDuration:[in] uint32
Can Leave: No
Constraint:
This value ought to be more than "RebufferingThreshold" specified by "SetRebufferingThresholdInMilliSeconds" API
*/
virtual void SetDurationInMilliSeconds(uint32 aDuration) = 0;
/**
This API will reset any EOS flag signalled by the user of the JB.
This will reinitialize the streaming segment.
Jitter buffer will go into transition state and will remian in that state unless
SetPlayRange API is called on it.
Jitter buffer will neither accept nor let out any packet out of it.
Can Leave: No
Constraint: N/A
*/
virtual void PrepareForRepositioning() = 0;
/**
Provides the observer with the mime type of the data that is persisted in JB.
*/
virtual const char* GetMimeType() const = 0;
/**
Will let the observer of JB the current state of the JB.
Can Leave: No
Constraint: N/A
*/
virtual PVMFJitterBufferDataState GetState() const = 0;
/**
This API will set the state of the Jitter buffer.
Param(s):[in] aState
Can Leave: No
Constraint: N/A
*/
virtual void SetJitterBufferState(PVMFJitterBufferDataState aState) = 0;
/**
Jitter buffer maintains the pointers to the chunks of the data retrieved from the server.
The chunks of memory that are used to persist the data retrieved from the server are allocated
by the allocator created in some other component (in socket node for RTSP and the HTTP streaming)
Jitter buffer need to know the occupancy of the memory pool for saving itself from overflowing.
SetJitterBufferChunkAllocator provides jitter buffer the access to the allocator that allocates
chunks for persisting the media.
Param(s):[in] aDataBufferAllocator
Can Leave: No
Constraint: N/A
*/
virtual void SetJitterBufferChunkAllocator(OsclMemPoolResizableAllocator* aDataBufferAllocator) = 0;
/**
This API provides the info about the memory pool that is allocated for persisting the media
from the server.
Param(s):[in] uint32 aSize - Size of memory pool
[in] uint32 aResizeSize - If Jb needed to be extented, this will specify the mempool
chunk that will be added up to the existing mempool.
[in] uint32 aMaxNumResizes - Specifies the max number of times memory chunks of size
"aResizeSize" can be appended to the mempool.
[in] uint32 aExpectedNumberOfBlocksPerBuffer - Specifies the estimated max number of chunks
of media that are expected to be in the Jitter buffer at
any instant of time.
Can Leave: No
Constraint: N/A
*/
virtual void SetJitterBufferMemPoolInfo(uint32 aSize,
uint32 aResizeSize,
uint32 aMaxNumResizes,
uint32 aExpectedNumberOfBlocksPerBuffer) = 0;
/**
This API provides the let the observer of JB know about the memory pool stats that is allocated
for persisting the media received from the server.
Param(s):[out] uint32 aSize - Size of memory pool
[out] uint32 aResizeSize - If Jb needed to be extented, this will specify the mempool
chunk that will be added up to the existing mempool.
[out] uint32 aMaxNumResizes - Specifies the max number of times memory chunks of size
"aResizeSize" can be appended to the mempool.
[out] uint32 aExpectedNumberOfBlocksPerBuffer - Specifies the estimated max number of chunks
of media that are expected to be in the Jitter buffer at
any instant of time.
Can Leave: No
Constraint: N/A
*/
virtual void GetJitterBufferMemPoolInfo(uint32& aSize,
uint32& aResizeSize,
uint32& aMaxNumResizes,
uint32& aExpectedNumberOfBlocksPerBuffer) const = 0;
/**
Registers the packet with the jitter buffer.
If inplace processing is false, then each fragment in the media msg is treated as a separate packet
and is internally wrapped in separate media msg by this functions and persisted in the jitter buffer.
This method may fail with the return value PVMF_JITTER_BUFFER_ADD_PKT_INSUFFICIENT_MEMORY
In this case, the user of the jitter buffer is expected to make async call NotifyFreeSpaceAvailable
call with the jitter buffer and wait for JitterBufferFreeSpaceAvailable callback before
requesting to register the packet again.
Param(s):[in] PVMFSharedMediaMsgPtr& aMsg - Media msg to be registered with the JB
Can Leave: No
Constraint: N/A
*/
virtual PVMFJitterBufferRegisterMediaMsgStatus RegisterMediaMsg(PVMFSharedMediaMsgPtr& aMsg) = 0;
/**
Specifies the initialization of new streaming segement.
*/
virtual bool QueueBOSCommand(uint32 aStreamId) = 0;
/**
Specifies the termination of the streaming.
Param(s):[out] PVMFSharedMediaMsgPtr& aMsg - Cmd Msg signifying EOS
[out] aCmdPacket: aMsg is considered to be valid if aCmdPacket is true
Can Leave: No
Constraint: N/A
*/
virtual PVMFStatus GenerateAndSendEOSCommand(PVMFSharedMediaMsgPtr& aMediaOutMsg, bool& aCmdPacket) = 0;
/**
Specifies if sufficient amount of data is available with the jitter buffer.
Delay is considered to be established:
- If estimated server clock is ahead of playback clock by duration specified by
"SetDurationInMilliSeconds"
- or, EOS is signalled by the user of the JB
- and JB is not in *transition* state.
Param(s):[out] uint32& aClockDiff - Difference between the estimated server clock and client playback clock
Can Leave: No
Constraint: N/A
*/
virtual bool IsDelayEstablished(uint32& aClockDiff) = 0;
/**
This API will provide the user of the Jitter buffer with the media msg from the Jitter buffer.
The packet retrieved from Jb can be
- media packet
- command packet
Param(s):[out] PVMFSharedMediaMsgPtr& aMediaMsgPtr - Media data retrieved from the jitter buffer
[out] bool& aCmdPacket - retrieved pkt from Jb is command packet
Can Leave: No
Constraint: N/A
Return value:PVMFStatus [PVMFSuccess/PVMFErrNotReady]
PVMFSuccess: If it is possible to retieve the media msg from the JB
PVMFErrNotReady: If packet cannot be retrieved from the Jb as of now.
User is Jb is expected to requet a callback via NotifyCanRetrievePacket API to get notification
about the readiness of JB to send out the packet.
*/
virtual PVMFStatus RetrievePacket(PVMFSharedMediaMsgPtr& aMediaMsgPtr, bool& aCmdPacket) = 0;
virtual PVMFStatus SetInputPacketHeaderPreparsed(bool aPreParsed) = 0;
/**
Request the JB to signal when user can retrieve the packet from it.
*/
virtual void NotifyCanRetrievePacket() = 0;
/**
Cancel the previously made request(if any) with the jitter buffer.
*/
virtual void CancelNotifyCanRetrievePacket() = 0;
/**
Returns the PVMFJitterBufferStats structure.
*/
virtual PVMFJitterBufferStats& getJitterBufferStats() = 0;
/**
Cleans up the jitter buffer. All the data in the Jb is considered invalid and
*/
virtual void FlushJitterBuffer() = 0;
/**
*/
virtual void ResetJitterBuffer() = 0;
/**
This function returns the mts of the next packet that is expected to be retrieved
from the jitter buffer.
*/
virtual PVMFTimestamp peekNextElementTimeStamp() = 0;
/**
*/
virtual PVMFTimestamp peekMaxElementTimeStamp() = 0;
/**
Returns true if there is no media in the JB to be retrieved.
else returns false
*/
virtual bool IsEmpty() = 0;
/**
Signals that EOS is received, and no media data is expected anymore.
*/
virtual void SetEOS(bool aVal) = 0;
/**
Checks if EOS is received.
*/
virtual bool GetEOS() = 0;
/**
This function is used to specify the play range, i.e. session params for the
current streaming segment
*/
virtual void SetPlayRange(int32 aStartTimeInMS, bool aPlayAfterSeek, bool aStopTimeAvailable = false, int32 aStopTimeInMS = 0) = 0;
/**
*/
virtual void PurgeElementsWithSeqNumsLessThan(uint32 aSeqNum, uint32 aPlayerClockMS) = 0;
/**
*/
virtual void PurgeElementsWithTimestampLessThan(PVMFTimestamp aTS) = 0;
/**
Sets the mode of processing the input packets.
If "aInPlaceProcessing" boolean if set to true means that media msg wrappers
that carry the RTP packets from upstream node can be reused.
If "aInPlaceProcessing" boolean if set to false, then inside "RegisterPacket"
We allocate a new media msg wrapper and transfer the memory fragments from "inputDataPacket"
to "dataPacket".
If there are multiple media packets in "inputDataPacket" then we have to allocate new
media msg wrappers for each one of these. So "aInPlaceProcessing" cannot be true if
downstream node packs multiple media packets in a single media msg.
*/
virtual void SetInPlaceProcessingMode(bool aInPlaceProcessingMode) = 0;
/**
*/
virtual bool addMediaCommand(PVMFSharedMediaMsgPtr& aMediaCmd) = 0;
/**
*/
virtual void SetAdjustedTSInMS(PVMFTimestamp aAdjustedTS) = 0;
/**
*/
virtual void SetBroadCastSession() = 0;
/**
This function is only implemented for RTSP based streaming to set the source identifier.
*/
virtual void setSSRC(uint32 aSSRC) = 0;
/**
This function is only implemented for RTSP based streaming to get the source identifier.
*/
virtual uint32 GetSSRC() const = 0;
/**
This function is specific to the RTSP based streaming.
This is used to set the RTP info.
RTP info is genreally obtained in response to the play request sent to the 3GPP server
*/
/**
*/
virtual void AdjustRTPTimeStamp() = 0;
virtual void setRTPInfoParams(PVMFRTPInfoParams rtpInfoParams, bool oPlayAfterASeek) = 0;
virtual PVMFRTPInfoParams& GetRTPInfoParams() = 0;
/**
This functiosn is RTSP streaming specific and is used to detrmine the interarriavl jitter
*/
virtual uint32 getInterArrivalJitter() = 0;
/**
*/
virtual bool GetRTPTimeStampOffset(uint32& aTimeStampOffset) = 0;
/**
*/
virtual void SetRTPTimeStampOffset(uint32 newTSBase) = 0;
/**
*/
virtual PVMFSharedMediaDataPtr& GetFirstDataPacket(void) = 0;
/**
*/
virtual bool NotifyFreeSpaceAvailable() = 0;
virtual void SetTrackConfig(OsclRefCounterMemFrag& aConfig) = 0;
virtual void SetMediaClockConverter(MediaClockConverter* aConverter) = 0;
virtual void SetTimeScale(uint32 aTimeScale) = 0;
virtual uint32 GetTimeScale() const = 0;
virtual void SetEarlyDecodingTimeInMilliSeconds(uint32 duration) = 0;
virtual void SetBurstThreshold(float burstThreshold) = 0;
};
///////////////////////////////////////////////////////////////////////////////
// Contains implementation of functions common to all streaming types
///////////////////////////////////////////////////////////////////////////////
typedef enum
{
PVMF_JB_ERR_INSUFFICIENT_MEM_TO_PACKETIZE,
PVMF_JB_ERR_INVALID_CONFIGURATION,
PVMF_JB_ERR_CORRUPT_HDR,
PVMF_JB_ERR_TRUNCATED_HDR,
PVMF_JB_ERR_UNEXPECTED_PKT,
PVMF_JB_ERR_LATE_PACKET,
PVMF_JB_ERR_NO_PACKET,
PVMF_JB_PACKET_PARSING_SUCCESS
} PVMFJBPacketParsingAndStatUpdationStatus;
class PVMFJitterBufferImpl : public PVMFJitterBuffer
, public OsclMemPoolFixedChunkAllocatorObserver
, public PVMFJBEventNotifierObserver
{
public:
OSCL_IMPORT_REF virtual ~PVMFJitterBufferImpl();
OSCL_IMPORT_REF virtual void StreamingSessionStarted();
OSCL_IMPORT_REF virtual void StreamingSessionPaused();
OSCL_IMPORT_REF virtual void StreamingSessionStopped();
OSCL_IMPORT_REF virtual void SetRebufferingThresholdInMilliSeconds(uint32 aRebufferingThresholdInMilliSeconds);
OSCL_IMPORT_REF virtual void SetDurationInMilliSeconds(uint32 aDuration);
OSCL_IMPORT_REF void PrepareForRepositioning();
OSCL_IMPORT_REF PVMFJitterBufferDataState GetState() const;
OSCL_IMPORT_REF virtual void SetJitterBufferState(PVMFJitterBufferDataState aState);
OSCL_IMPORT_REF virtual void SetJitterBufferChunkAllocator(OsclMemPoolResizableAllocator* aDataBufferAllocator);
OSCL_IMPORT_REF virtual const char* GetMimeType() const;
OSCL_IMPORT_REF virtual PVMFJitterBufferRegisterMediaMsgStatus RegisterMediaMsg(PVMFSharedMediaMsgPtr& msg);
OSCL_IMPORT_REF bool QueueBOSCommand(uint32 aStreamId);
OSCL_IMPORT_REF void SetInPlaceProcessingMode(bool aInPlaceProcessingMode);
OSCL_IMPORT_REF PVMFStatus GenerateAndSendEOSCommand(PVMFSharedMediaMsgPtr& aMediaOutMsg, bool& aCmdPacket);
OSCL_IMPORT_REF virtual void NotifyCanRetrievePacket();
OSCL_IMPORT_REF virtual void CancelNotifyCanRetrievePacket();
OSCL_IMPORT_REF virtual PVMFStatus RetrievePacket(PVMFSharedMediaMsgPtr& aMediaMsgPtr, bool& aCmdPacket);
OSCL_IMPORT_REF virtual PVMFStatus SetInputPacketHeaderPreparsed(bool aPreParsed);
OSCL_IMPORT_REF virtual PVMFJitterBufferStats& getJitterBufferStats();
OSCL_IMPORT_REF virtual PVMFTimestamp peekNextElementTimeStamp();
OSCL_IMPORT_REF virtual PVMFTimestamp peekMaxElementTimeStamp();
OSCL_IMPORT_REF bool IsEmpty();
OSCL_IMPORT_REF void SetEOS(bool aVal);
OSCL_IMPORT_REF bool GetEOS();
OSCL_IMPORT_REF void SetPlayRange(int32 aStartTimeInMS, bool aPlayAfterSeek, bool aStopTimeAvailable = false, int32 aStopTimeInMS = 0);
OSCL_IMPORT_REF bool CheckForHighWaterMark();
OSCL_IMPORT_REF bool CheckForLowWaterMark();
OSCL_IMPORT_REF bool CheckNumElements();
OSCL_IMPORT_REF bool addMediaCommand(PVMFSharedMediaMsgPtr& aMediaCmd);
OSCL_IMPORT_REF virtual bool GetPendingCommand(PVMFSharedMediaMsgPtr& aCmdMsg);
OSCL_IMPORT_REF virtual bool HasPendingCommand();
OSCL_IMPORT_REF void SetAdjustedTSInMS(PVMFTimestamp aAdjustedTSInMS);
OSCL_IMPORT_REF virtual void SetBroadCastSession();
OSCL_IMPORT_REF virtual PVMFRTPInfoParams& GetRTPInfoParams();
OSCL_IMPORT_REF bool GetRTPTimeStampOffset(uint32& aTimeStampOffset);
OSCL_IMPORT_REF bool NotifyFreeSpaceAvailable();
OSCL_IMPORT_REF void freechunkavailable(OsclAny*);
OSCL_IMPORT_REF virtual void FlushJitterBuffer();
OSCL_IMPORT_REF virtual void ResetJitterBuffer();
OSCL_IMPORT_REF bool CheckSpaceAvailability(PVMFSharedMediaMsgPtr& aMsg);
OSCL_IMPORT_REF bool CheckSpaceAvailability();
OSCL_IMPORT_REF void setSSRC(uint32 aSSRC);
OSCL_IMPORT_REF uint32 GetSSRC() const;
OSCL_IMPORT_REF virtual void SetJitterBufferMemPoolInfo(uint32 aSize,
uint32 aResizeSize,
uint32 aMaxNumResizes,
uint32 aExpectedNumberOfBlocksPerBuffer);
OSCL_IMPORT_REF void GetJitterBufferMemPoolInfo(uint32& aSize, uint32& aResizeSize, uint32& aMaxNumResizes, uint32& aExpectedNumberOfBlocksPerBuffer) const;
OSCL_IMPORT_REF virtual void SetTrackConfig(OsclRefCounterMemFrag& aConfig);
OSCL_IMPORT_REF virtual void SetMediaClockConverter(MediaClockConverter* aConverter);
OSCL_IMPORT_REF virtual void SetTimeScale(uint32 aTimeScale);
OSCL_IMPORT_REF virtual uint32 GetTimeScale() const ;
OSCL_IMPORT_REF bool IsDelayEstablished(uint32& aClockDiff);
protected:
OSCL_IMPORT_REF void LogClientAndEstimatedServerClock(PVLogger*& aLogger);
OSCL_IMPORT_REF bool RequestEventCallBack(JB_NOTIFY_CALLBACK aEventType, uint32 aDelay = 0, OsclAny* aContext = NULL);
OSCL_IMPORT_REF void CancelEventCallBack(JB_NOTIFY_CALLBACK aEventType, OsclAny* aContext = NULL);
OSCL_IMPORT_REF bool IsCallbackPending(JB_NOTIFY_CALLBACK aEventType, OsclAny* aContext);
OSCL_IMPORT_REF void ProcessCallback(CLOCK_NOTIFICATION_INTF_TYPE aClockNotificationInterfaceType, uint32 aCallBkId, const OsclAny* aContext, PVMFStatus aStatus);
OSCL_IMPORT_REF PVMFJitterBufferImpl(const PVMFJitterBufferConstructParams& aJBCreationData);
typedef enum
{
STREAMINGSTATE_UNKNOWN,
STREAMINGSTATE_STARTED,
STREAMINGSTATE_PAUSED,
STREAMINGSTATE_STOPPED
}StreamingState;
virtual bool IsSeqTsValidForPkt(uint32 aSeqNum, uint32 aTs, PVMFJitterBufferStats& jbStats) = 0;
OSCL_IMPORT_REF virtual uint32 GetNumOfPackets(PVMFSharedMediaMsgPtr& aMsg) const;
OSCL_IMPORT_REF virtual void ReportJBInfoEvent(PVMFAsyncEvent& aEvent);
OSCL_IMPORT_REF virtual PVMFSharedMediaDataPtr RetrievePacketPayload();
OSCL_IMPORT_REF void Construct();
OSCL_IMPORT_REF bool Allocate(OsclSharedPtr<PVMFMediaDataImpl>& mediaDataOut);
OSCL_IMPORT_REF bool CreateMediaData(PVMFSharedMediaDataPtr& dataPacket, OsclSharedPtr<PVMFMediaDataImpl>& mediaDataOut);
//pure virtuals to be overridden by the derived implementation
virtual PVMFJBPacketParsingAndStatUpdationStatus ParsePacketHeaderAndUpdateJBStats(PVMFSharedMediaDataPtr& inDataPacket,
PVMFSharedMediaDataPtr& outDataPacket,
uint32 aFragIndex = 0) = 0;
virtual void EOSCmdReceived() = 0;
virtual void DeterminePrevTimeStampPeek(uint32 aSeqNum,
PVMFTimestamp& aPrevTS) = 0;
virtual void ComputeMaxAdjustedRTPTS() = 0;
virtual void CheckForRTPTimeAndRTPSeqNumberBase() = 0;
virtual bool CanRetrievePacket(PVMFSharedMediaMsgPtr& aMediaOutMsg, bool& aCmdPacket) = 0;
virtual bool CanRetrievePacket() = 0;
virtual void DeterminePrevTimeStamp(uint32 aSeqNum) = 0;
OSCL_IMPORT_REF virtual PVMFStatus PerformFlowControl(bool aIncomingMedia);
uint32 iSeqNum;
class JitterBufferMemPoolInfo
{
public:
JitterBufferMemPoolInfo(): iSize(0), iResizeSize(0), iMaxNumResizes(0), iExpectedNumberOfBlocksPerBuffer(0) {}
void Init(uint32 aSize = 0, uint32 aExpectedNumberOfBlocksPerBuffer = 0, uint32 aResizeSize = 0, uint32 aMaxNumResizes = 0)
{
iSize = aSize;
iResizeSize = aResizeSize;
iMaxNumResizes = aMaxNumResizes;
iExpectedNumberOfBlocksPerBuffer = aExpectedNumberOfBlocksPerBuffer;
}
uint32 iSize;
uint32 iResizeSize;
uint32 iMaxNumResizes;
uint32 iExpectedNumberOfBlocksPerBuffer;
};
JitterBufferMemPoolInfo iJitterBufferMemPoolInfo;
PVMFSharedMediaDataPtr firstDataPacket;
Oscl_Vector<PVMFSharedMediaDataPtr, OsclMemAllocator> iFirstDataPackets;
StreamingState iStreamingState;
bool iPlayingAfterSeek;
bool iReportCanRetrievePacket;
bool iInPlaceProcessing;
bool iOnePacketPerFragment;
bool iOnePacketPerMediaMsg;
uint32 iLastPacketOutTs;
bool iOverflowFlag;
/* Media Command related */
Oscl_Vector<MediaCommandMsgHolder, OsclMemAllocator> iMediaCmdVec;
//Allocators [Will be created only when PVMFJitterBufferImpl::iInPlaceProcessing == false]
PVMFMediaFragGroupCombinedAlloc<OsclMemPoolFixedChunkAllocator>* iMediaDataGroupAlloc;
OsclMemPoolFixedChunkAllocator* iMediaDataImplMemPool;
OsclMemPoolFixedChunkAllocator* iMediaMsgMemPool;
int32 iStartTimeInMS;
int32 iStopTimeInMS;
bool iPlayStopTimeAvailable;
bool iBroadCastSession;
PVMFTimestamp iMaxAdjustedRTPTS;
bool iSessionDurationExpired;
uint32 iDurationInMilliSeconds;
uint32 iRebufferingThresholdInMilliSeconds;
uint64 iMonotonicTimeStamp;
uint32 iFirstSeqNum;
typedef PVMFDynamicCircularArray<OsclMemAllocator> PVMFDynamicCircularArrayType;
PVMFDynamicCircularArrayType* iJitterBuffer;
Oscl_Vector<PVMFRTPInfoParams, OsclMemAllocator> iRTPInfoParamsVec;
bool iEOSSignalled;
bool iEOSSent;
uint32 iStreamID;
PVMFTimestamp iMaxAdjustedTS; //[iMaxAdjustedRTPTS]
PVMFTimestamp iPrevAdjustedTS;//[iPrevAdjustedRTPTS]
PVMFMediaClock& irEstimatedServerClock;
PVMFMediaClock& irClientPlayBackClock;
PVMFJBEventNotifier& irJBEventNotifier;
OSCL_HeapString<OsclMemAllocator> irMimeType;
bool& irDelayEstablished;
uint32& irJitterDelayPercent;
PVMFJitterBufferDataState& irDataState;
bool iInProcessingMode;
bool iHeaderPreParsed;
uint32 iRTPTimeScale;
PVMFTimestamp iPrevTSOut;
MediaClockConverter iEstServClockMediaClockConvertor;
PVMFJitterBufferObserver* const iObserver;
OsclAny* const iObserverContext;
bool seqNumLock;
uint32 iInterArrivalJitter;
bool oFirstPacket;
OsclRefCounterMemFrag iTrackConfig;
uint32 iTimeScale;
MediaClockConverter* ipMediaClockConverter;
uint32 SSRCLock;
bool oSSRCFromSetUpResponseAvailable;
uint32 SSRCFromSetUpResponse;
uint32 iPrevSeqNumBaseOut;
PVMFTimestamp seqLockTimeStamp;
PVMFTimestamp iPrevAdjustedRTPTS;
PVMFTimestamp iPrevTSIn;
uint32 iPrevSeqNumBaseIn;
OsclMemPoolResizableAllocator* iBufferAlloc;
uint32 prevMinPercentOccupancy;
uint32 consecutiveLowBufferCount;
uint32 iNumUnderFlow;
bool iMonitorReBufferingCallBkPending;
bool iWaitForOOOPacketCallBkPending;
bool iJitterBufferDurationCallBkPending;
uint32 iWaitForOOOPacketCallBkId;
uint32 iMonitorReBufferingCallBkId;
uint32 iJitterBufferDurationCallBkId;
PVLogger* ipLogger;
PVLogger* ipClockLoggerSessionDuration;
PVLogger* ipDataPathLogger;
PVLogger* ipMaxRTPTsLogger;
PVLogger* ipDataPathLoggerIn;
PVLogger* ipDataPathLoggerOut;
PVLogger* ipClockLogger;
PVLogger* ipClockLoggerRebuff;
PVLogger* ipDataPathLoggerFlowCtrl;
PVLogger* ipJBEventsClockLogger;
PVLogger* ipRTCPDataPathLoggerIn;
PVLogger* ipRTCPDataPathLoggerOut;
private:
void CreateAllocators();
void DestroyAllocators();
PVMFJitterBufferRegisterMediaMsgStatus AddPacket(PVMFSharedMediaDataPtr& aDataPacket);
OSCL_IMPORT_REF virtual PVMFJitterBufferRegisterMediaMsgStatus RegisterCmdPacket(PVMFSharedMediaMsgPtr& aMediaCmd);
OSCL_IMPORT_REF virtual bool CanRegisterMediaMsg();
PVMFJitterBufferRegisterMediaMsgStatus RegisterDataPacket(PVMFSharedMediaDataPtr& aDataPacket);
void ResetParams(bool aReleaseMemory = true);
void HandleEvent_MonitorReBuffering(const OsclAny* aContext);
void HandleEvent_NotifyWaitForOOOPacketComplete(const OsclAny* aContext);
void HandleEvent_JitterBufferBufferingDurationComplete();
};
#endif