bug fix for a crash in the jitter buffer, patch from pljones
This commit is contained in:
parent
911692c5fa
commit
08c16748a8
4 changed files with 510 additions and 498 deletions
16
llcon.pro
16
llcon.pro
|
@ -163,14 +163,14 @@ DISTFILES += AUTHORS \
|
||||||
NEWS \
|
NEWS \
|
||||||
README \
|
README \
|
||||||
TODO \
|
TODO \
|
||||||
libs\celt\AUTHORS \
|
libs/celt/AUTHORS \
|
||||||
libs\celt\ChangeLog \
|
libs/celt/ChangeLog \
|
||||||
libs\celt\COPYING \
|
libs/celt/COPYING \
|
||||||
libs\celt\INSTALL \
|
libs/celt/INSTALL \
|
||||||
libs\celt\NEWS \
|
libs/celt/NEWS \
|
||||||
libs\celt\README \
|
libs/celt/README \
|
||||||
libs\celt\README_LLCON \
|
libs/celt/README_LLCON \
|
||||||
libs\celt\TODO \
|
libs/celt/TODO \
|
||||||
src/res/CLEDBlack.png \
|
src/res/CLEDBlack.png \
|
||||||
src/res/CLEDBlackSmall.png \
|
src/res/CLEDBlackSmall.png \
|
||||||
src/res/CLEDDisabledSmall.png \
|
src/res/CLEDDisabledSmall.png \
|
||||||
|
|
|
@ -206,10 +206,9 @@ bool CNetBufWithStats::Get ( CVector<uint8_t>& vecbyData )
|
||||||
const double dInitState =
|
const double dInitState =
|
||||||
ErrorRateStatistic[NUM_STAT_SIMULATION_BUFFERS - 1].InitializationState();
|
ErrorRateStatistic[NUM_STAT_SIMULATION_BUFFERS - 1].InitializationState();
|
||||||
|
|
||||||
if ( dInitState < 0.2 )
|
if ( dInitState < 0.1 )
|
||||||
{
|
{
|
||||||
if ( ( dInitState > 0.1 ) &&
|
if ( ErrorRateStatistic[NUM_STAT_SIMULATION_BUFFERS - 1].GetAverage() > ERROR_RATE_BOUND )
|
||||||
( ErrorRateStatistic[NUM_STAT_SIMULATION_BUFFERS - 1].GetAverage() > ERROR_RATE_BOUND ) )
|
|
||||||
{
|
{
|
||||||
for ( int i = 0; i < NUM_STAT_SIMULATION_BUFFERS; i++ )
|
for ( int i = 0; i < NUM_STAT_SIMULATION_BUFFERS; i++ )
|
||||||
{
|
{
|
||||||
|
|
968
src/buffer.h
968
src/buffer.h
|
@ -1,483 +1,485 @@
|
||||||
/******************************************************************************\
|
/******************************************************************************\
|
||||||
* Copyright (c) 2004-2011
|
* Copyright (c) 2004-2011
|
||||||
*
|
*
|
||||||
* Author(s):
|
* Author(s):
|
||||||
* Volker Fischer
|
* Volker Fischer
|
||||||
*
|
*
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it under
|
* This program is free software; you can redistribute it and/or modify it under
|
||||||
* the terms of the GNU General Public License as published by the Free Software
|
* the terms of the GNU General Public License as published by the Free Software
|
||||||
* Foundation; either version 2 of the License, or (at your option) any later
|
* Foundation; either version 2 of the License, or (at your option) any later
|
||||||
* version.
|
* version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
* details.
|
* details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along with
|
* You should have received a copy of the GNU General Public License along with
|
||||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*
|
*
|
||||||
\******************************************************************************/
|
\******************************************************************************/
|
||||||
|
|
||||||
#if !defined ( BUFFER_H__3B123453_4344_BB23945IUHF1912__INCLUDED_ )
|
#if !defined ( BUFFER_H__3B123453_4344_BB23945IUHF1912__INCLUDED_ )
|
||||||
#define BUFFER_H__3B123453_4344_BB23945IUHF1912__INCLUDED_
|
#define BUFFER_H__3B123453_4344_BB23945IUHF1912__INCLUDED_
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
|
||||||
|
|
||||||
/* Definitions ****************************************************************/
|
/* Definitions ****************************************************************/
|
||||||
// each regular buffer access lead to a count for put and get, assuming 2.66 ms
|
// each regular buffer access lead to a count for put and get, assuming 2.66 ms
|
||||||
// blocks we have 15 s / 2.66 ms * 2 = approx. 11000
|
// blocks we have 15 s / 2.66 ms * 2 = approx. 11000
|
||||||
#define MAX_STATISTIC_COUNT 11000
|
#define MAX_STATISTIC_COUNT 11000
|
||||||
|
|
||||||
// definition of the error bound
|
// definition of the error bound
|
||||||
#define ERROR_RATE_BOUND 0.002
|
#define ERROR_RATE_BOUND 0.002
|
||||||
|
|
||||||
// number of simulation network jitter buffers for evaluating the statistic
|
// number of simulation network jitter buffers for evaluating the statistic
|
||||||
#define NUM_STAT_SIMULATION_BUFFERS 13
|
#define NUM_STAT_SIMULATION_BUFFERS 13
|
||||||
|
|
||||||
|
|
||||||
/* Classes ********************************************************************/
|
/* Classes ********************************************************************/
|
||||||
// Buffer base class -----------------------------------------------------------
|
// Buffer base class -----------------------------------------------------------
|
||||||
template<class TData> class CBufferBase
|
template<class TData> class CBufferBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CBufferBase ( const bool bNIsSim = false ) :
|
CBufferBase ( const bool bNIsSim = false ) :
|
||||||
bIsSimulation ( bNIsSim ), bIsInitialized ( false ) {}
|
bIsSimulation ( bNIsSim ), bIsInitialized ( false ) {}
|
||||||
|
|
||||||
void SetIsSimulation ( const bool bNIsSim ) { bIsSimulation = bNIsSim; }
|
void SetIsSimulation ( const bool bNIsSim ) { bIsSimulation = bNIsSim; }
|
||||||
|
|
||||||
virtual void Init ( const int iNewMemSize,
|
virtual void Init ( const int iNewMemSize,
|
||||||
const bool bPreserve = false )
|
const bool bPreserve = false )
|
||||||
{
|
{
|
||||||
// in simulation mode the size is not changed during operation -> we do
|
// in simulation mode the size is not changed during operation -> we do
|
||||||
// not have to implement special code for this case
|
// not have to implement special code for this case
|
||||||
// only enter the "preserve" branch, if object was already initialized
|
// only enter the "preserve" branch, if object was already initialized
|
||||||
if ( bPreserve && ( !bIsSimulation ) && bIsInitialized )
|
if ( bPreserve && ( !bIsSimulation ) && bIsInitialized )
|
||||||
{
|
{
|
||||||
// copy old data in new vector using get pointer as zero per
|
// copy old data in new vector using get pointer as zero per
|
||||||
// definition
|
// definition
|
||||||
|
|
||||||
int iCurPos;
|
int iCurPos;
|
||||||
|
|
||||||
// copy current data in temporary vector
|
// copy current data in temporary vector
|
||||||
CVector<TData> vecTempMemory ( vecMemory );
|
CVector<TData> vecTempMemory ( vecMemory );
|
||||||
|
|
||||||
// resize actual buffer memory
|
// resize actual buffer memory
|
||||||
vecMemory.Init ( iNewMemSize );
|
vecMemory.Init ( iNewMemSize );
|
||||||
|
|
||||||
// get maximum number of data to be copied
|
// get maximum number of data to be copied
|
||||||
int iCopyLen = GetAvailData();
|
int iCopyLen = GetAvailData();
|
||||||
if ( iCopyLen > iNewMemSize )
|
if ( iCopyLen > iNewMemSize )
|
||||||
{
|
{
|
||||||
iCopyLen = iNewMemSize;
|
iCopyLen = iNewMemSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set correct buffer state
|
// set correct buffer state
|
||||||
if ( iCopyLen >= iNewMemSize )
|
if ( iCopyLen == iNewMemSize )
|
||||||
{
|
{
|
||||||
eBufState = CBufferBase<TData>::BS_FULL;
|
eBufState = CBufferBase<TData>::BS_FULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( iCopyLen == 0 )
|
if ( iCopyLen == 0 )
|
||||||
{
|
{
|
||||||
eBufState = CBufferBase<TData>::BS_EMPTY;
|
eBufState = CBufferBase<TData>::BS_EMPTY;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
eBufState = CBufferBase<TData>::BS_OK;
|
eBufState = CBufferBase<TData>::BS_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( iGetPos < iPutPos )
|
if ( iGetPos < iPutPos )
|
||||||
{
|
{
|
||||||
// "get" position is before "put" position -> no wrap around
|
// "get" position is before "put" position -> no wrap around
|
||||||
for ( iCurPos = 0; iCurPos < iCopyLen; iCurPos++ )
|
for ( iCurPos = 0; iCurPos < iCopyLen; iCurPos++ )
|
||||||
{
|
{
|
||||||
vecMemory[iCurPos] = vecTempMemory[iGetPos + iCurPos];
|
vecMemory[iCurPos] = vecTempMemory[iGetPos + iCurPos];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// update put pointer
|
else
|
||||||
if ( eBufState == CBufferBase<TData>::BS_FULL )
|
{
|
||||||
{
|
// "put" position is before "get" position -> wrap around
|
||||||
iPutPos = 0;
|
bool bEnoughSpaceForSecondPart = true;
|
||||||
}
|
int iFirstPartLen = iMemSize - iGetPos;
|
||||||
else
|
|
||||||
{
|
// check that first copy length is not larger then new memory
|
||||||
iPutPos -= iGetPos;
|
if ( iFirstPartLen >= iCopyLen )
|
||||||
}
|
{
|
||||||
}
|
iFirstPartLen = iCopyLen;
|
||||||
else
|
bEnoughSpaceForSecondPart = false;
|
||||||
{
|
}
|
||||||
// "put" position is before "get" position -> wrap around
|
|
||||||
bool bEnoughSpaceForSecondPart = true;
|
for ( iCurPos = 0; iCurPos < iFirstPartLen; iCurPos++ )
|
||||||
int iFirstPartLen = iMemSize - iGetPos;
|
{
|
||||||
|
vecMemory[iCurPos] = vecTempMemory[iGetPos + iCurPos];
|
||||||
// check that first copy length is not larger then new memory
|
}
|
||||||
if ( iFirstPartLen > iCopyLen )
|
|
||||||
{
|
if ( bEnoughSpaceForSecondPart )
|
||||||
iFirstPartLen = iCopyLen;
|
{
|
||||||
bEnoughSpaceForSecondPart = false;
|
// calculate remaining copy length
|
||||||
}
|
const int iRemainingCopyLen = iCopyLen - iFirstPartLen;
|
||||||
|
|
||||||
for ( iCurPos = 0; iCurPos < iFirstPartLen; iCurPos++ )
|
// perform copying of second part
|
||||||
{
|
for ( iCurPos = 0; iCurPos < iRemainingCopyLen; iCurPos++ )
|
||||||
vecMemory[iCurPos] = vecTempMemory[iGetPos + iCurPos];
|
{
|
||||||
}
|
vecMemory[iCurPos + iFirstPartLen] =
|
||||||
|
vecTempMemory[iCurPos];
|
||||||
if ( bEnoughSpaceForSecondPart )
|
}
|
||||||
{
|
}
|
||||||
// calculate remaining copy length
|
}
|
||||||
const int iRemainingCopyLen = iCopyLen - iFirstPartLen;
|
|
||||||
|
// update put pointer
|
||||||
// perform copying of second part
|
if ( eBufState == CBufferBase<TData>::BS_FULL )
|
||||||
for ( iCurPos = 0; iCurPos < iRemainingCopyLen; iCurPos++ )
|
{
|
||||||
{
|
iPutPos = 0;
|
||||||
vecMemory[iCurPos + iFirstPartLen] =
|
}
|
||||||
vecTempMemory[iCurPos];
|
else
|
||||||
}
|
{
|
||||||
}
|
iPutPos = iCopyLen;
|
||||||
|
}
|
||||||
// update put pointer
|
|
||||||
if ( eBufState == CBufferBase<TData>::BS_FULL )
|
// update get position -> zero per definition
|
||||||
{
|
iGetPos = 0;
|
||||||
iPutPos = 0;
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
// allocate memory for actual data buffer
|
||||||
iPutPos += iFirstPartLen;
|
if ( !bIsSimulation )
|
||||||
}
|
{
|
||||||
}
|
vecMemory.Init ( iNewMemSize );
|
||||||
|
}
|
||||||
// update get position -> zero per definition
|
|
||||||
iGetPos = 0;
|
// init buffer pointers and buffer state (empty buffer)
|
||||||
}
|
iGetPos = 0;
|
||||||
else
|
iPutPos = 0;
|
||||||
{
|
eBufState = CBufferBase<TData>::BS_EMPTY;
|
||||||
// allocate memory for actual data buffer
|
}
|
||||||
if ( !bIsSimulation )
|
|
||||||
{
|
// store total memory size value
|
||||||
vecMemory.Init ( iNewMemSize );
|
iMemSize = iNewMemSize;
|
||||||
}
|
|
||||||
|
// set initialized flag
|
||||||
// init buffer pointers and buffer state (empty buffer)
|
bIsInitialized = true;
|
||||||
iGetPos = 0;
|
}
|
||||||
iPutPos = 0;
|
|
||||||
eBufState = CBufferBase<TData>::BS_EMPTY;
|
virtual bool Put ( const CVector<TData>& vecData,
|
||||||
}
|
const int iInSize )
|
||||||
|
{
|
||||||
// store total memory size value
|
if ( bIsSimulation )
|
||||||
iMemSize = iNewMemSize;
|
{
|
||||||
|
// in this simulation only the buffer pointers and the buffer state
|
||||||
// set initialized flag
|
// is updated, no actual data is transferred
|
||||||
bIsInitialized = true;
|
iPutPos += iInSize;
|
||||||
}
|
if ( iPutPos >= iMemSize )
|
||||||
|
{
|
||||||
virtual bool Put ( const CVector<TData>& vecData,
|
iPutPos -= iMemSize;
|
||||||
const int iInSize )
|
}
|
||||||
{
|
}
|
||||||
if ( bIsSimulation )
|
else
|
||||||
{
|
{
|
||||||
// in this simulation only the buffer pointers and the buffer state
|
// copy new data in internal buffer
|
||||||
// is updated, no actual data is transferred
|
int iCurPos = 0;
|
||||||
iPutPos += iInSize;
|
if ( iPutPos + iInSize > iMemSize )
|
||||||
if ( iPutPos >= iMemSize )
|
{
|
||||||
{
|
// remaining space size for second block
|
||||||
iPutPos -= iMemSize;
|
const int iRemSpace = iPutPos + iInSize - iMemSize;
|
||||||
}
|
|
||||||
}
|
// data must be written in two steps because of wrap around
|
||||||
else
|
while ( iPutPos < iMemSize )
|
||||||
{
|
{
|
||||||
// copy new data in internal buffer
|
vecMemory[iPutPos++] = vecData[iCurPos++];
|
||||||
int iCurPos = 0;
|
}
|
||||||
if ( iPutPos + iInSize > iMemSize )
|
|
||||||
{
|
for ( iPutPos = 0; iPutPos < iRemSpace; iPutPos++ )
|
||||||
// remaining space size for second block
|
{
|
||||||
const int iRemSpace = iPutPos + iInSize - iMemSize;
|
vecMemory[iPutPos] = vecData[iCurPos++];
|
||||||
|
}
|
||||||
// data must be written in two steps because of wrap around
|
}
|
||||||
while ( iPutPos < iMemSize )
|
else
|
||||||
{
|
{
|
||||||
vecMemory[iPutPos++] = vecData[iCurPos++];
|
// data can be written in one step
|
||||||
}
|
const int iEnd = iPutPos + iInSize;
|
||||||
|
while ( iPutPos < iEnd )
|
||||||
for ( iPutPos = 0; iPutPos < iRemSpace; iPutPos++ )
|
{
|
||||||
{
|
vecMemory[iPutPos++] = vecData[iCurPos++];
|
||||||
vecMemory[iPutPos] = vecData[iCurPos++];
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
// take care about wrap around of put pointer
|
||||||
// data can be written in one step
|
if ( iPutPos == iMemSize )
|
||||||
const int iEnd = iPutPos + iInSize;
|
{
|
||||||
while ( iPutPos < iEnd )
|
iPutPos = 0;
|
||||||
{
|
}
|
||||||
vecMemory[iPutPos++] = vecData[iCurPos++];
|
|
||||||
}
|
// set buffer state flag
|
||||||
}
|
if ( iPutPos == iGetPos )
|
||||||
}
|
{
|
||||||
|
eBufState = CBufferBase<TData>::BS_FULL;
|
||||||
// set buffer state flag
|
}
|
||||||
if ( iPutPos == iGetPos )
|
else
|
||||||
{
|
{
|
||||||
eBufState = CBufferBase<TData>::BS_FULL;
|
eBufState = CBufferBase<TData>::BS_OK;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
return true; // no error check in base class, alyways return ok
|
||||||
eBufState = CBufferBase<TData>::BS_OK;
|
}
|
||||||
}
|
|
||||||
|
virtual bool Get ( CVector<TData>& vecData )
|
||||||
return true; // no error check in base class, alyways return ok
|
{
|
||||||
}
|
// get size of data to be get from the buffer
|
||||||
|
const int iInSize = vecData.Size();
|
||||||
virtual bool Get ( CVector<TData>& vecData )
|
|
||||||
{
|
if ( bIsSimulation )
|
||||||
// get size of data to be get from the buffer
|
{
|
||||||
const int iInSize = vecData.Size();
|
// in this simulation only the buffer pointers and the buffer state
|
||||||
|
// is updated, no actual data is transferred
|
||||||
if ( bIsSimulation )
|
iGetPos += iInSize;
|
||||||
{
|
if ( iGetPos >= iMemSize )
|
||||||
// in this simulation only the buffer pointers and the buffer state
|
{
|
||||||
// is updated, no actual data is transferred
|
iGetPos -= iMemSize;
|
||||||
iGetPos += iInSize;
|
}
|
||||||
if ( iGetPos >= iMemSize )
|
}
|
||||||
{
|
else
|
||||||
iGetPos -= iMemSize;
|
{
|
||||||
}
|
// copy data from internal buffer in output buffer
|
||||||
}
|
int iCurPos = 0;
|
||||||
else
|
if ( iGetPos + iInSize > iMemSize )
|
||||||
{
|
{
|
||||||
// copy data from internal buffer in output buffer
|
// remaining data size for second block
|
||||||
int iCurPos = 0;
|
const int iRemData = iGetPos + iInSize - iMemSize;
|
||||||
if ( iGetPos + iInSize > iMemSize )
|
|
||||||
{
|
// data must be read in two steps because of wrap around
|
||||||
// remaining data size for second block
|
while ( iGetPos < iMemSize )
|
||||||
const int iRemData = iGetPos + iInSize - iMemSize;
|
{
|
||||||
|
vecData[iCurPos++] = vecMemory[iGetPos++];
|
||||||
// data must be read in two steps because of wrap around
|
}
|
||||||
while ( iGetPos < iMemSize )
|
|
||||||
{
|
for ( iGetPos = 0; iGetPos < iRemData; iGetPos++ )
|
||||||
vecData[iCurPos++] = vecMemory[iGetPos++];
|
{
|
||||||
}
|
vecData[iCurPos++] = vecMemory[iGetPos];
|
||||||
|
}
|
||||||
for ( iGetPos = 0; iGetPos < iRemData; iGetPos++ )
|
}
|
||||||
{
|
else
|
||||||
vecData[iCurPos++] = vecMemory[iGetPos];
|
{
|
||||||
}
|
// data can be read in one step
|
||||||
}
|
const int iEnd = iGetPos + iInSize;
|
||||||
else
|
while ( iGetPos < iEnd )
|
||||||
{
|
{
|
||||||
// data can be read in one step
|
vecData[iCurPos++] = vecMemory[iGetPos++];
|
||||||
const int iEnd = iGetPos + iInSize;
|
}
|
||||||
while ( iGetPos < iEnd )
|
}
|
||||||
{
|
}
|
||||||
vecData[iCurPos++] = vecMemory[iGetPos++];
|
|
||||||
}
|
// take care about wrap around of get pointer
|
||||||
}
|
if ( iGetPos == iMemSize )
|
||||||
}
|
{
|
||||||
|
iGetPos = 0;
|
||||||
// set buffer state flag
|
}
|
||||||
if ( iPutPos == iGetPos )
|
|
||||||
{
|
// set buffer state flag
|
||||||
eBufState = CBufferBase<TData>::BS_EMPTY;
|
if ( iPutPos == iGetPos )
|
||||||
}
|
{
|
||||||
else
|
eBufState = CBufferBase<TData>::BS_EMPTY;
|
||||||
{
|
}
|
||||||
eBufState = CBufferBase<TData>::BS_OK;
|
else
|
||||||
}
|
{
|
||||||
|
eBufState = CBufferBase<TData>::BS_OK;
|
||||||
return true; // no error check in base class, alyways return ok
|
}
|
||||||
}
|
|
||||||
|
return true; // no error check in base class, alyways return ok
|
||||||
virtual int GetAvailSpace() const
|
}
|
||||||
{
|
|
||||||
// calculate available space in buffer
|
virtual int GetAvailSpace() const
|
||||||
int iAvSpace = iGetPos - iPutPos;
|
{
|
||||||
|
// calculate available space in buffer
|
||||||
// check for special case and wrap around
|
int iAvSpace = iGetPos - iPutPos;
|
||||||
if ( iAvSpace < 0 )
|
|
||||||
{
|
// check for special case and wrap around
|
||||||
iAvSpace += iMemSize; // wrap around
|
if ( iAvSpace < 0 )
|
||||||
}
|
{
|
||||||
else
|
iAvSpace += iMemSize; // wrap around
|
||||||
{
|
}
|
||||||
if ( ( iAvSpace == 0 ) && ( eBufState == BS_EMPTY ) )
|
else
|
||||||
{
|
{
|
||||||
iAvSpace = iMemSize;
|
if ( ( iAvSpace == 0 ) && ( eBufState == BS_EMPTY ) )
|
||||||
}
|
{
|
||||||
}
|
iAvSpace = iMemSize;
|
||||||
|
}
|
||||||
return iAvSpace;
|
}
|
||||||
}
|
|
||||||
|
return iAvSpace;
|
||||||
virtual int GetAvailData() const
|
}
|
||||||
{
|
|
||||||
// calculate available data in buffer
|
virtual int GetAvailData() const
|
||||||
int iAvData = iPutPos - iGetPos;
|
{
|
||||||
|
// calculate available data in buffer
|
||||||
// check for special case and wrap around
|
int iAvData = iPutPos - iGetPos;
|
||||||
if ( iAvData < 0 )
|
|
||||||
{
|
// check for special case and wrap around
|
||||||
iAvData += iMemSize; // wrap around
|
if ( iAvData < 0 )
|
||||||
}
|
{
|
||||||
else
|
iAvData += iMemSize; // wrap around
|
||||||
{
|
}
|
||||||
if ( ( iAvData == 0 ) && ( eBufState == BS_FULL ) )
|
else
|
||||||
{
|
{
|
||||||
iAvData = iMemSize;
|
if ( ( iAvData == 0 ) && ( eBufState == BS_FULL ) )
|
||||||
}
|
{
|
||||||
}
|
iAvData = iMemSize;
|
||||||
|
}
|
||||||
return iAvData;
|
}
|
||||||
}
|
|
||||||
|
return iAvData;
|
||||||
protected:
|
}
|
||||||
enum EBufState { BS_OK, BS_FULL, BS_EMPTY };
|
|
||||||
|
protected:
|
||||||
virtual void Clear()
|
enum EBufState { BS_OK, BS_FULL, BS_EMPTY };
|
||||||
{
|
|
||||||
// clear memory
|
virtual void Clear()
|
||||||
if ( !bIsSimulation )
|
{
|
||||||
{
|
// clear memory
|
||||||
vecMemory.Reset ( 0 );
|
if ( !bIsSimulation )
|
||||||
}
|
{
|
||||||
|
vecMemory.Reset ( 0 );
|
||||||
// init buffer pointers and buffer state (empty buffer)
|
}
|
||||||
iGetPos = 0;
|
|
||||||
iPutPos = 0;
|
// init buffer pointers and buffer state (empty buffer)
|
||||||
eBufState = CBufferBase<TData>::BS_EMPTY;
|
iGetPos = 0;
|
||||||
}
|
iPutPos = 0;
|
||||||
|
eBufState = CBufferBase<TData>::BS_EMPTY;
|
||||||
CVector<TData> vecMemory;
|
}
|
||||||
int iMemSize;
|
|
||||||
int iGetPos;
|
CVector<TData> vecMemory;
|
||||||
int iPutPos;
|
int iMemSize;
|
||||||
EBufState eBufState;
|
int iGetPos;
|
||||||
bool bIsSimulation;
|
int iPutPos;
|
||||||
bool bIsInitialized;
|
EBufState eBufState;
|
||||||
};
|
bool bIsSimulation;
|
||||||
|
bool bIsInitialized;
|
||||||
|
};
|
||||||
// Network buffer (jitter buffer) ----------------------------------------------
|
|
||||||
class CNetBuf : public CBufferBase<uint8_t>
|
|
||||||
{
|
// Network buffer (jitter buffer) ----------------------------------------------
|
||||||
public:
|
class CNetBuf : public CBufferBase<uint8_t>
|
||||||
CNetBuf ( const bool bNewIsSim = false ) :
|
{
|
||||||
CBufferBase<uint8_t> ( bNewIsSim ) {}
|
public:
|
||||||
|
CNetBuf ( const bool bNewIsSim = false ) :
|
||||||
virtual void Init ( const int iNewBlockSize,
|
CBufferBase<uint8_t> ( bNewIsSim ) {}
|
||||||
const int iNewNumBlocks,
|
|
||||||
const bool bPreserve = false );
|
virtual void Init ( const int iNewBlockSize,
|
||||||
|
const int iNewNumBlocks,
|
||||||
int GetSize() { return iMemSize / iBlockSize; }
|
const bool bPreserve = false );
|
||||||
|
|
||||||
virtual bool Put ( const CVector<uint8_t>& vecbyData, const int iInSize );
|
int GetSize() { return iMemSize / iBlockSize; }
|
||||||
virtual bool Get ( CVector<uint8_t>& vecbyData );
|
|
||||||
|
virtual bool Put ( const CVector<uint8_t>& vecbyData, const int iInSize );
|
||||||
protected:
|
virtual bool Get ( CVector<uint8_t>& vecbyData );
|
||||||
int iBlockSize;
|
|
||||||
int iNumInvalidElements;
|
protected:
|
||||||
};
|
int iBlockSize;
|
||||||
|
int iNumInvalidElements;
|
||||||
|
};
|
||||||
// Network buffer (jitter buffer) with statistic calculations ------------------
|
|
||||||
class CNetBufWithStats : public CNetBuf
|
|
||||||
{
|
// Network buffer (jitter buffer) with statistic calculations ------------------
|
||||||
public:
|
class CNetBufWithStats : public CNetBuf
|
||||||
CNetBufWithStats();
|
{
|
||||||
|
public:
|
||||||
virtual void Init ( const int iNewBlockSize,
|
CNetBufWithStats();
|
||||||
const int iNewNumBlocks,
|
|
||||||
const bool bPreserve = false );
|
virtual void Init ( const int iNewBlockSize,
|
||||||
|
const int iNewNumBlocks,
|
||||||
virtual bool Put ( const CVector<uint8_t>& vecbyData, const int iInSize );
|
const bool bPreserve = false );
|
||||||
virtual bool Get ( CVector<uint8_t>& vecbyData );
|
|
||||||
|
virtual bool Put ( const CVector<uint8_t>& vecbyData, const int iInSize );
|
||||||
int GetAutoSetting() { return iCurAutoBufferSizeSetting; }
|
virtual bool Get ( CVector<uint8_t>& vecbyData );
|
||||||
|
|
||||||
// TEST
|
int GetAutoSetting() { return iCurAutoBufferSizeSetting; }
|
||||||
void StoreAllSimAverages();
|
|
||||||
|
// TEST
|
||||||
protected:
|
void StoreAllSimAverages();
|
||||||
void UpdateAutoSetting();
|
|
||||||
|
protected:
|
||||||
// statistic (do not use the vector class since the classes do not have
|
void UpdateAutoSetting();
|
||||||
// appropriate copy constructor/operator)
|
|
||||||
CErrorRate ErrorRateStatistic[NUM_STAT_SIMULATION_BUFFERS];
|
// statistic (do not use the vector class since the classes do not have
|
||||||
CNetBuf SimulationBuffer[NUM_STAT_SIMULATION_BUFFERS];
|
// appropriate copy constructor/operator)
|
||||||
int viBufSizesForSim[NUM_STAT_SIMULATION_BUFFERS];
|
CErrorRate ErrorRateStatistic[NUM_STAT_SIMULATION_BUFFERS];
|
||||||
|
CNetBuf SimulationBuffer[NUM_STAT_SIMULATION_BUFFERS];
|
||||||
double dCurIIRFilterResult;
|
int viBufSizesForSim[NUM_STAT_SIMULATION_BUFFERS];
|
||||||
int iCurDecidedResult;
|
|
||||||
int iInitCounter;
|
double dCurIIRFilterResult;
|
||||||
int iCurAutoBufferSizeSetting;
|
int iCurDecidedResult;
|
||||||
};
|
int iInitCounter;
|
||||||
|
int iCurAutoBufferSizeSetting;
|
||||||
|
};
|
||||||
// Conversion buffer (very simple buffer) --------------------------------------
|
|
||||||
// For this very simple buffer no wrap around mechanism is implemented. We
|
|
||||||
// assume here, that the applied buffers are an integer fraction of the total
|
// Conversion buffer (very simple buffer) --------------------------------------
|
||||||
// buffer size.
|
// For this very simple buffer no wrap around mechanism is implemented. We
|
||||||
template<class TData> class CConvBuf
|
// assume here, that the applied buffers are an integer fraction of the total
|
||||||
{
|
// buffer size.
|
||||||
public:
|
template<class TData> class CConvBuf
|
||||||
CConvBuf() { Init ( 0 ); }
|
{
|
||||||
|
public:
|
||||||
void Init ( const int iNewMemSize )
|
CConvBuf() { Init ( 0 ); }
|
||||||
{
|
|
||||||
// set memory size
|
void Init ( const int iNewMemSize )
|
||||||
iMemSize = iNewMemSize;
|
{
|
||||||
|
// set memory size
|
||||||
// allocate and clear memory for actual data buffer
|
iMemSize = iNewMemSize;
|
||||||
vecsMemory.Init ( iMemSize );
|
|
||||||
|
// allocate and clear memory for actual data buffer
|
||||||
iPutPos = 0;
|
vecsMemory.Init ( iMemSize );
|
||||||
}
|
|
||||||
|
iPutPos = 0;
|
||||||
int GetSize() const { return iMemSize; }
|
}
|
||||||
|
|
||||||
bool Put ( const CVector<TData>& vecsData )
|
int GetSize() const { return iMemSize; }
|
||||||
{
|
|
||||||
const int iVecSize = vecsData.Size();
|
bool Put ( const CVector<TData>& vecsData )
|
||||||
|
{
|
||||||
// copy new data in internal buffer
|
const int iVecSize = vecsData.Size();
|
||||||
int iCurPos = 0;
|
|
||||||
const int iEnd = iPutPos + iVecSize;
|
// copy new data in internal buffer
|
||||||
|
int iCurPos = 0;
|
||||||
// first check for buffer overrun
|
const int iEnd = iPutPos + iVecSize;
|
||||||
if ( iEnd <= iMemSize )
|
|
||||||
{
|
// first check for buffer overrun
|
||||||
// actual copy operation
|
if ( iEnd <= iMemSize )
|
||||||
while ( iPutPos < iEnd )
|
{
|
||||||
{
|
// actual copy operation
|
||||||
vecsMemory[iPutPos++] = vecsData[iCurPos++];
|
while ( iPutPos < iEnd )
|
||||||
}
|
{
|
||||||
|
vecsMemory[iPutPos++] = vecsData[iCurPos++];
|
||||||
// return "buffer is ready for readout" flag
|
}
|
||||||
return ( iEnd == iMemSize );
|
|
||||||
}
|
// return "buffer is ready for readout" flag
|
||||||
else
|
return ( iEnd == iMemSize );
|
||||||
{
|
}
|
||||||
// buffer overrun or not initialized, return "not ready"
|
else
|
||||||
return false;
|
{
|
||||||
}
|
// buffer overrun or not initialized, return "not ready"
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
CVector<TData> Get()
|
}
|
||||||
{
|
|
||||||
iPutPos = 0;
|
CVector<TData> Get()
|
||||||
return vecsMemory;
|
{
|
||||||
}
|
iPutPos = 0;
|
||||||
|
return vecsMemory;
|
||||||
protected:
|
}
|
||||||
CVector<TData> vecsMemory;
|
|
||||||
int iMemSize;
|
protected:
|
||||||
int iPutPos;
|
CVector<TData> vecsMemory;
|
||||||
};
|
int iMemSize;
|
||||||
|
int iPutPos;
|
||||||
#endif /* !defined ( BUFFER_H__3B123453_4344_BB23945IUHF1912__INCLUDED_ ) */
|
};
|
||||||
|
|
||||||
|
#endif /* !defined ( BUFFER_H__3B123453_4344_BB23945IUHF1912__INCLUDED_ ) */
|
||||||
|
|
19
src/util.h
19
src/util.h
|
@ -155,8 +155,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typename std::vector<TData>::iterator pData;
|
typename std::vector<TData>::iterator pData;
|
||||||
int iVectorSize;
|
int iVectorSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -172,7 +172,7 @@ template<class TData> void CVector<TData>::Init ( const int iNewSize )
|
||||||
pData = this->begin();
|
pData = this->begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class TData> void CVector<TData>::Init ( const int iNewSize,
|
template<class TData> void CVector<TData>::Init ( const int iNewSize,
|
||||||
const TData tIniVal )
|
const TData tIniVal )
|
||||||
{
|
{
|
||||||
// call actual init routine
|
// call actual init routine
|
||||||
|
@ -271,6 +271,7 @@ public:
|
||||||
|
|
||||||
inline double GetAverage()
|
inline double GetAverage()
|
||||||
{
|
{
|
||||||
|
// make sure we do not divide by zero
|
||||||
if ( this->iNorm == 0 )
|
if ( this->iNorm == 0 )
|
||||||
{
|
{
|
||||||
return dNoDataResult;
|
return dNoDataResult;
|
||||||
|
@ -282,7 +283,17 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
double InitializationState() const
|
double InitializationState() const
|
||||||
{ return static_cast<double> ( this->iNorm ) / this->iVectorSize; }
|
{
|
||||||
|
// make sure we do not divide by zero
|
||||||
|
if ( this->iVectorSize != 0 )
|
||||||
|
{
|
||||||
|
return static_cast<double> ( this->iNorm ) / this->iVectorSize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int iCurIdx;
|
int iCurIdx;
|
||||||
|
|
Loading…
Reference in a new issue