bug fix in server, added simulation mode in buffer base class, added deactivated test code for simulation buffer statistics, avoid audio drop outs when the jitter buffer size is changed
This commit is contained in:
parent
1a99b76365
commit
56f528b13e
11 changed files with 326 additions and 128 deletions
|
@ -29,17 +29,21 @@
|
||||||
|
|
||||||
|
|
||||||
/* Network buffer implementation **********************************************/
|
/* Network buffer implementation **********************************************/
|
||||||
void CNetBuf::Init ( const int iNewBlockSize,
|
void CNetBuf::Init ( const int iNewBlockSize,
|
||||||
const int iNewNumBlocks )
|
const int iNewNumBlocks,
|
||||||
|
const bool bPreserve )
|
||||||
{
|
{
|
||||||
// store block size value
|
// store block size value
|
||||||
iBlockSize = iNewBlockSize;
|
iBlockSize = iNewBlockSize;
|
||||||
|
|
||||||
// total size -> size of one block times the number of blocks
|
// total size -> size of one block times the number of blocks
|
||||||
CBufferBase<uint8_t>::Init ( iNewBlockSize * iNewNumBlocks );
|
CBufferBase<uint8_t>::Init ( iNewBlockSize * iNewNumBlocks, bPreserve );
|
||||||
|
|
||||||
// use the "get" flag to make sure the buffer is cleared
|
// use the "get" flag to make sure the buffer is cleared
|
||||||
Clear ( CT_GET );
|
if ( !bPreserve )
|
||||||
|
{
|
||||||
|
Clear ( CT_GET );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CNetBuf::Put ( const CVector<uint8_t>& vecbyData,
|
bool CNetBuf::Put ( const CVector<uint8_t>& vecbyData,
|
||||||
|
@ -180,7 +184,10 @@ void CNetBuf::Clear ( const EClearType eClearType )
|
||||||
if ( eClearType == CT_GET )
|
if ( eClearType == CT_GET )
|
||||||
{
|
{
|
||||||
// clear buffer since we had a buffer underrun
|
// clear buffer since we had a buffer underrun
|
||||||
vecMemory.Reset ( 0 );
|
if ( !bIsSimulation )
|
||||||
|
{
|
||||||
|
vecMemory.Reset ( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
// reset buffer pointers so that they are at maximum distance after
|
// reset buffer pointers so that they are at maximum distance after
|
||||||
// the get operation (assign new fill level value to the get pointer)
|
// the get operation (assign new fill level value to the get pointer)
|
||||||
|
@ -233,14 +240,48 @@ void CNetBuf::Clear ( const EClearType eClearType )
|
||||||
|
|
||||||
|
|
||||||
/* Network buffer with statistic calculations implementation ******************/
|
/* Network buffer with statistic calculations implementation ******************/
|
||||||
|
/*
|
||||||
|
CNetBufWithStats::CNetBufWithStats() :
|
||||||
|
CNetBuf ( false ) // base class init: no simulation mode
|
||||||
|
{
|
||||||
|
// define the sizes of the simulation buffers,
|
||||||
|
// must be NUM_STAT_SIMULATION_BUFFERS elements!
|
||||||
|
viBufSizesForSim[0] = 2;
|
||||||
|
viBufSizesForSim[1] = 3;
|
||||||
|
viBufSizesForSim[2] = 4;
|
||||||
|
viBufSizesForSim[3] = 5;
|
||||||
|
viBufSizesForSim[4] = 6;
|
||||||
|
viBufSizesForSim[5] = 7;
|
||||||
|
viBufSizesForSim[6] = 8;
|
||||||
|
viBufSizesForSim[7] = 10;
|
||||||
|
viBufSizesForSim[8] = 12;
|
||||||
|
|
||||||
|
// set all simulation buffers in simulation mode
|
||||||
|
for ( int i = 0; i < NUM_STAT_SIMULATION_BUFFERS; i++ )
|
||||||
|
{
|
||||||
|
SimulationBuffer[i].SetIsSimulation ( true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CNetBufWithStats::Init ( const int iNewBlockSize,
|
void CNetBufWithStats::Init ( const int iNewBlockSize,
|
||||||
const int iNewNumBlocks )
|
const int iNewNumBlocks,
|
||||||
|
const bool bPreserve )
|
||||||
{
|
{
|
||||||
// call base class Init
|
// call base class Init
|
||||||
CNetBuf::Init ( iNewBlockSize, iNewNumBlocks );
|
CNetBuf::Init ( iNewBlockSize, iNewNumBlocks, bPreserve );
|
||||||
|
|
||||||
// init statistic
|
// inits for statistics calculation
|
||||||
ErrorRateStatistic.Init ( MAX_STATISTIC_COUNT );
|
if ( !bPreserve )
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < NUM_STAT_SIMULATION_BUFFERS; i++ )
|
||||||
|
{
|
||||||
|
// init simulation buffers with the correct size
|
||||||
|
SimulationBuffer[i].Init ( iNewBlockSize, viBufSizesForSim[i] );
|
||||||
|
|
||||||
|
// init statistics
|
||||||
|
ErrorRateStatistic[i].Init ( MAX_STATISTIC_COUNT );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CNetBufWithStats::Put ( const CVector<uint8_t>& vecbyData,
|
bool CNetBufWithStats::Put ( const CVector<uint8_t>& vecbyData,
|
||||||
|
@ -249,8 +290,12 @@ bool CNetBufWithStats::Put ( const CVector<uint8_t>& vecbyData,
|
||||||
// call base class Put
|
// call base class Put
|
||||||
const bool bPutOK = CNetBuf::Put ( vecbyData, iInSize );
|
const bool bPutOK = CNetBuf::Put ( vecbyData, iInSize );
|
||||||
|
|
||||||
// update statistic
|
// update statistics calculations
|
||||||
ErrorRateStatistic.Update ( !bPutOK );
|
for ( int i = 0; i < NUM_STAT_SIMULATION_BUFFERS; i++ )
|
||||||
|
{
|
||||||
|
ErrorRateStatistic[i].Update (
|
||||||
|
!SimulationBuffer[i].Put ( vecbyData, iInSize ) );
|
||||||
|
}
|
||||||
|
|
||||||
return bPutOK;
|
return bPutOK;
|
||||||
}
|
}
|
||||||
|
@ -260,8 +305,31 @@ bool CNetBufWithStats::Get ( CVector<uint8_t>& vecbyData )
|
||||||
// call base class Get
|
// call base class Get
|
||||||
const bool bGetOK = CNetBuf::Get ( vecbyData );
|
const bool bGetOK = CNetBuf::Get ( vecbyData );
|
||||||
|
|
||||||
// update statistic
|
// update statistics calculations
|
||||||
ErrorRateStatistic.Update ( !bGetOK );
|
for ( int i = 0; i < NUM_STAT_SIMULATION_BUFFERS; i++ )
|
||||||
|
{
|
||||||
|
ErrorRateStatistic[i].Update (
|
||||||
|
!SimulationBuffer[i].Get ( vecbyData ) );
|
||||||
|
}
|
||||||
|
|
||||||
return bGetOK;
|
return bGetOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TEST for debugging
|
||||||
|
void CNetBufWithStats::StoreAllSimAverages()
|
||||||
|
{
|
||||||
|
FILE* pFile = fopen ( "c:\\temp\\test.dat", "w" );
|
||||||
|
|
||||||
|
for ( int i = 0; i < NUM_STAT_SIMULATION_BUFFERS - 1; i++ )
|
||||||
|
{
|
||||||
|
fprintf ( pFile, "%e, ", ErrorRateStatistic[i].GetAverage() );
|
||||||
|
}
|
||||||
|
fprintf ( pFile, "%e", ErrorRateStatistic[NUM_STAT_SIMULATION_BUFFERS - 1].GetAverage() );
|
||||||
|
|
||||||
|
fprintf ( pFile, "\n" );
|
||||||
|
fclose ( pFile );
|
||||||
|
|
||||||
|
// scilab:
|
||||||
|
// close;x=read('c:/temp/test.dat',-1,9);plot2d( [2, 3, 4, 5, 6, 7, 8, 10, 12], x, style=-1 , logflag = 'nl');plot2d([2 12],[1 1]*0.01);plot2d([2 12],[1 1]*0.005);x
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
314
src/buffer.h
314
src/buffer.h
|
@ -34,54 +34,188 @@
|
||||||
// blocks we have 30 s / 2.33 ms * 2 = 25714
|
// blocks we have 30 s / 2.33 ms * 2 = 25714
|
||||||
#define MAX_STATISTIC_COUNT 25714
|
#define MAX_STATISTIC_COUNT 25714
|
||||||
|
|
||||||
|
// number of simulation network jitter buffers for evaluating the statistic
|
||||||
|
#define NUM_STAT_SIMULATION_BUFFERS 9
|
||||||
|
|
||||||
|
|
||||||
/* Classes ********************************************************************/
|
/* Classes ********************************************************************/
|
||||||
// Buffer base class -----------------------------------------------------------
|
// Buffer base class -----------------------------------------------------------
|
||||||
template<class TData> class CBufferBase
|
template<class TData> class CBufferBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void Init ( const int iNewMemSize )
|
CBufferBase ( const bool bNIsSim = false ) :
|
||||||
|
bIsSimulation ( bNIsSim ), bIsInitialized ( false ) {}
|
||||||
|
|
||||||
|
void SetIsSimulation ( const bool bNIsSim ) { bIsSimulation = bNIsSim; }
|
||||||
|
|
||||||
|
virtual void Init ( const int iNewMemSize,
|
||||||
|
const bool bPreserve = false )
|
||||||
{
|
{
|
||||||
|
// in simulation mode the size is not changed during operation -> we do
|
||||||
|
// not have to implement special code for this case
|
||||||
|
// only enter the "preserve" branch, if object was already initialized
|
||||||
|
if ( bPreserve && ( !bIsSimulation ) && bIsInitialized )
|
||||||
|
{
|
||||||
|
// copy old data in new vector using get pointer as zero per
|
||||||
|
// definition
|
||||||
|
|
||||||
|
int iCurPos;
|
||||||
|
|
||||||
|
// copy current data in temporary vector
|
||||||
|
CVector<TData> vecTempMemory ( vecMemory );
|
||||||
|
|
||||||
|
// resize actual buffer memory
|
||||||
|
vecMemory.Init ( iNewMemSize );
|
||||||
|
|
||||||
|
// get maximum number of data to be copied
|
||||||
|
int iCopyLen = GetAvailData();
|
||||||
|
if ( iCopyLen > iNewMemSize )
|
||||||
|
{
|
||||||
|
iCopyLen = iNewMemSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set correct buffer state
|
||||||
|
if ( iCopyLen >= iNewMemSize )
|
||||||
|
{
|
||||||
|
eBufState = CBufferBase<TData>::BS_FULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( iCopyLen == 0 )
|
||||||
|
{
|
||||||
|
eBufState = CBufferBase<TData>::BS_EMPTY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
eBufState = CBufferBase<TData>::BS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( iGetPos < iPutPos )
|
||||||
|
{
|
||||||
|
// "get" position is before "put" position -> no wrap around
|
||||||
|
for ( iCurPos = 0; iCurPos < iCopyLen; iCurPos++ )
|
||||||
|
{
|
||||||
|
vecMemory[iCurPos] = vecTempMemory[iGetPos + iCurPos];
|
||||||
|
}
|
||||||
|
|
||||||
|
// update put pointer
|
||||||
|
if ( eBufState == CBufferBase<TData>::BS_FULL )
|
||||||
|
{
|
||||||
|
iPutPos = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iPutPos -= iGetPos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// "put" position is before "get" position -> wrap around
|
||||||
|
bool bEnoughSpaceForSecondPart = true;
|
||||||
|
int iFirstPartLen = iMemSize - iGetPos;
|
||||||
|
|
||||||
|
// check that first copy length is not larger then new memory
|
||||||
|
if ( iFirstPartLen > iCopyLen )
|
||||||
|
{
|
||||||
|
iFirstPartLen = iCopyLen;
|
||||||
|
bEnoughSpaceForSecondPart = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( iCurPos = 0; iCurPos < iFirstPartLen; iCurPos++ )
|
||||||
|
{
|
||||||
|
vecMemory[iCurPos] = vecTempMemory[iGetPos + iCurPos];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( bEnoughSpaceForSecondPart )
|
||||||
|
{
|
||||||
|
// calculate remaining copy length
|
||||||
|
const int iRemainingCopyLen = iCopyLen - iFirstPartLen;
|
||||||
|
|
||||||
|
// perform copying of second part
|
||||||
|
for ( iCurPos = 0; iCurPos < iRemainingCopyLen; iCurPos++ )
|
||||||
|
{
|
||||||
|
vecMemory[iCurPos + iFirstPartLen] =
|
||||||
|
vecTempMemory[iCurPos];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update put pointer
|
||||||
|
if ( eBufState == CBufferBase<TData>::BS_FULL )
|
||||||
|
{
|
||||||
|
iPutPos = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iPutPos += iFirstPartLen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update get position -> zero per definition
|
||||||
|
iGetPos = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// allocate memory for actual data buffer
|
||||||
|
if ( !bIsSimulation )
|
||||||
|
{
|
||||||
|
vecMemory.Init ( iNewMemSize );
|
||||||
|
}
|
||||||
|
|
||||||
|
// init buffer pointers and buffer state (empty buffer)
|
||||||
|
iGetPos = 0;
|
||||||
|
iPutPos = 0;
|
||||||
|
eBufState = CBufferBase<TData>::BS_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
// store total memory size value
|
// store total memory size value
|
||||||
iMemSize = iNewMemSize;
|
iMemSize = iNewMemSize;
|
||||||
|
|
||||||
// allocate memory for actual data buffer
|
// set initialized flag
|
||||||
vecMemory.Init ( iNewMemSize );
|
bIsInitialized = true;
|
||||||
|
|
||||||
// init buffer pointers and buffer state (empty buffer)
|
|
||||||
iGetPos = 0;
|
|
||||||
iPutPos = 0;
|
|
||||||
eBufState = CBufferBase<TData>::BS_EMPTY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool Put ( const CVector<TData>& vecData,
|
virtual bool Put ( const CVector<TData>& vecData,
|
||||||
const int iInSize )
|
const int iInSize )
|
||||||
{
|
{
|
||||||
// copy new data in internal buffer
|
if ( bIsSimulation )
|
||||||
int iCurPos = 0;
|
|
||||||
if ( iPutPos + iInSize > iMemSize )
|
|
||||||
{
|
{
|
||||||
// remaining space size for second block
|
// in this simulation only the buffer pointers and the buffer state
|
||||||
const int iRemSpace = iPutPos + iInSize - iMemSize;
|
// is updated, no actual data is transferred
|
||||||
|
iPutPos += iInSize;
|
||||||
// data must be written in two steps because of wrap around
|
if ( iPutPos >= iMemSize )
|
||||||
while ( iPutPos < iMemSize )
|
|
||||||
{
|
{
|
||||||
vecMemory[iPutPos++] = vecData[iCurPos++];
|
iPutPos -= iMemSize;
|
||||||
}
|
|
||||||
|
|
||||||
for ( iPutPos = 0; iPutPos < iRemSpace; iPutPos++ )
|
|
||||||
{
|
|
||||||
vecMemory[iPutPos] = vecData[iCurPos++];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// data can be written in one step
|
// copy new data in internal buffer
|
||||||
const int iEnd = iPutPos + iInSize;
|
int iCurPos = 0;
|
||||||
while ( iPutPos < iEnd )
|
if ( iPutPos + iInSize > iMemSize )
|
||||||
{
|
{
|
||||||
vecMemory[iPutPos++] = vecData[iCurPos++];
|
// remaining space size for second block
|
||||||
|
const int iRemSpace = iPutPos + iInSize - iMemSize;
|
||||||
|
|
||||||
|
// data must be written in two steps because of wrap around
|
||||||
|
while ( iPutPos < iMemSize )
|
||||||
|
{
|
||||||
|
vecMemory[iPutPos++] = vecData[iCurPos++];
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( iPutPos = 0; iPutPos < iRemSpace; iPutPos++ )
|
||||||
|
{
|
||||||
|
vecMemory[iPutPos] = vecData[iCurPos++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// data can be written in one step
|
||||||
|
const int iEnd = iPutPos + iInSize;
|
||||||
|
while ( iPutPos < iEnd )
|
||||||
|
{
|
||||||
|
vecMemory[iPutPos++] = vecData[iCurPos++];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,31 +237,44 @@ public:
|
||||||
// get size of data to be get from the buffer
|
// get size of data to be get from the buffer
|
||||||
const int iInSize = vecData.Size();
|
const int iInSize = vecData.Size();
|
||||||
|
|
||||||
// copy data from internal buffer in output buffer
|
if ( bIsSimulation )
|
||||||
int iCurPos = 0;
|
|
||||||
if ( iGetPos + iInSize > iMemSize )
|
|
||||||
{
|
{
|
||||||
// remaining data size for second block
|
// in this simulation only the buffer pointers and the buffer state
|
||||||
const int iRemData = iGetPos + iInSize - iMemSize;
|
// is updated, no actual data is transferred
|
||||||
|
iGetPos += iInSize;
|
||||||
// data must be read in two steps because of wrap around
|
if ( iGetPos >= iMemSize )
|
||||||
while ( iGetPos < iMemSize )
|
|
||||||
{
|
{
|
||||||
vecData[iCurPos++] = vecMemory[iGetPos++];
|
iGetPos -= iMemSize;
|
||||||
}
|
|
||||||
|
|
||||||
for ( iGetPos = 0; iGetPos < iRemData; iGetPos++ )
|
|
||||||
{
|
|
||||||
vecData[iCurPos++] = vecMemory[iGetPos];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// data can be read in one step
|
// copy data from internal buffer in output buffer
|
||||||
const int iEnd = iGetPos + iInSize;
|
int iCurPos = 0;
|
||||||
while ( iGetPos < iEnd )
|
if ( iGetPos + iInSize > iMemSize )
|
||||||
{
|
{
|
||||||
vecData[iCurPos++] = vecMemory[iGetPos++];
|
// remaining data size for second block
|
||||||
|
const int iRemData = iGetPos + iInSize - iMemSize;
|
||||||
|
|
||||||
|
// data must be read in two steps because of wrap around
|
||||||
|
while ( iGetPos < iMemSize )
|
||||||
|
{
|
||||||
|
vecData[iCurPos++] = vecMemory[iGetPos++];
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( iGetPos = 0; iGetPos < iRemData; iGetPos++ )
|
||||||
|
{
|
||||||
|
vecData[iCurPos++] = vecMemory[iGetPos];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// data can be read in one step
|
||||||
|
const int iEnd = iGetPos + iInSize;
|
||||||
|
while ( iGetPos < iEnd )
|
||||||
|
{
|
||||||
|
vecData[iCurPos++] = vecMemory[iGetPos++];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,52 +336,13 @@ public:
|
||||||
protected:
|
protected:
|
||||||
enum EBufState { BS_OK, BS_FULL, BS_EMPTY };
|
enum EBufState { BS_OK, BS_FULL, BS_EMPTY };
|
||||||
|
|
||||||
void PutSimulation ( const int iInSize )
|
|
||||||
{
|
|
||||||
// in this simulation only the buffer pointers and the buffer state
|
|
||||||
// is updated, no actual data is transferred
|
|
||||||
iPutPos += iInSize;
|
|
||||||
if ( iPutPos >= iMemSize )
|
|
||||||
{
|
|
||||||
iPutPos -= iMemSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set buffer state flag
|
|
||||||
if ( iPutPos == iGetPos )
|
|
||||||
{
|
|
||||||
eBufState = CBufferBase<TData>::BS_FULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
eBufState = CBufferBase<TData>::BS_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetSimulation ( const int iInSize )
|
|
||||||
{
|
|
||||||
// in this simulation only the buffer pointers and the buffer state
|
|
||||||
// is updated, no actual data is transferred
|
|
||||||
iGetPos += iInSize;
|
|
||||||
if ( iGetPos >= iMemSize )
|
|
||||||
{
|
|
||||||
iGetPos -= iMemSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set buffer state flag
|
|
||||||
if ( iPutPos == iGetPos )
|
|
||||||
{
|
|
||||||
eBufState = CBufferBase<TData>::BS_EMPTY;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
eBufState = CBufferBase<TData>::BS_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CVector<TData> vecMemory;
|
CVector<TData> vecMemory;
|
||||||
int iMemSize;
|
int iMemSize;
|
||||||
int iGetPos, iPutPos;
|
int iGetPos;
|
||||||
|
int iPutPos;
|
||||||
EBufState eBufState;
|
EBufState eBufState;
|
||||||
|
bool bIsSimulation;
|
||||||
|
bool bIsInitialized;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -242,7 +350,13 @@ protected:
|
||||||
class CNetBuf : public CBufferBase<uint8_t>
|
class CNetBuf : public CBufferBase<uint8_t>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void Init ( const int iNewBlockSize, const int iNewNumBlocks );
|
CNetBuf ( const bool bNewIsSim = false ) :
|
||||||
|
CBufferBase<uint8_t> ( bNewIsSim ) {}
|
||||||
|
|
||||||
|
virtual void Init ( const int iNewBlockSize,
|
||||||
|
const int iNewNumBlocks,
|
||||||
|
const bool bPreserve = false );
|
||||||
|
|
||||||
int GetSize() { return iMemSize / iBlockSize; }
|
int GetSize() { return iMemSize / iBlockSize; }
|
||||||
|
|
||||||
virtual bool Put ( const CVector<uint8_t>& vecbyData, const int iInSize );
|
virtual bool Put ( const CVector<uint8_t>& vecbyData, const int iInSize );
|
||||||
|
@ -258,21 +372,37 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
// This is a test class which provides statistic for a certain number of
|
||||||
|
// simulation buffers -> was intended to improve the auto jitter buffer
|
||||||
|
// setting but we stick to the old auto mechanism because of some draw backs
|
||||||
|
// of the simulated jitter buffers like that if burst errors occur, we would
|
||||||
|
// have to exclude it to not to effect the error rate too much and others...
|
||||||
|
|
||||||
// Network buffer (jitter buffer) with statistic calculations ------------------
|
// Network buffer (jitter buffer) with statistic calculations ------------------
|
||||||
class CNetBufWithStats : public CNetBuf
|
class CNetBufWithStats : public CNetBuf
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void Init ( const int iNewBlockSize, const int iNewNumBlocks );
|
CNetBufWithStats();
|
||||||
|
|
||||||
|
virtual void Init ( const int iNewBlockSize,
|
||||||
|
const int iNewNumBlocks,
|
||||||
|
const bool bPreserve = false );
|
||||||
|
|
||||||
virtual bool Put ( const CVector<uint8_t>& vecbyData, const int iInSize );
|
virtual bool Put ( const CVector<uint8_t>& vecbyData, const int iInSize );
|
||||||
virtual bool Get ( CVector<uint8_t>& vecbyData );
|
virtual bool Get ( CVector<uint8_t>& vecbyData );
|
||||||
|
|
||||||
double GetErrorRate() { return ErrorRateStatistic.GetAverage(); }
|
// TEST
|
||||||
|
void StoreAllSimAverages();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// statistic
|
// statistic (do not use the vector class since the classes do not have
|
||||||
CErrorRate ErrorRateStatistic;
|
// appropriate copy constructor/operator)
|
||||||
|
CErrorRate ErrorRateStatistic[NUM_STAT_SIMULATION_BUFFERS];
|
||||||
|
CNetBuf SimulationBuffer[NUM_STAT_SIMULATION_BUFFERS];
|
||||||
|
int viBufSizesForSim[NUM_STAT_SIMULATION_BUFFERS];
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
// Conversion buffer (very simple buffer) --------------------------------------
|
// Conversion buffer (very simple buffer) --------------------------------------
|
||||||
|
|
|
@ -163,7 +163,8 @@ void CChannel::SetAudioStreamProperties ( const int iNewNetwFrameSize,
|
||||||
CreateNetTranspPropsMessFromCurrentSettings();
|
CreateNetTranspPropsMessFromCurrentSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CChannel::SetSockBufNumFrames ( const int iNewNumFrames )
|
bool CChannel::SetSockBufNumFrames ( const int iNewNumFrames,
|
||||||
|
const bool bPreserve )
|
||||||
{
|
{
|
||||||
QMutexLocker locker ( &Mutex ); // this operation must be done with mutex
|
QMutexLocker locker ( &Mutex ); // this operation must be done with mutex
|
||||||
|
|
||||||
|
@ -176,7 +177,7 @@ bool CChannel::SetSockBufNumFrames ( const int iNewNumFrames )
|
||||||
|
|
||||||
// the network block size is a multiple of the minimum network
|
// the network block size is a multiple of the minimum network
|
||||||
// block size
|
// block size
|
||||||
SockBuf.Init ( iNetwFrameSize, iNewNumFrames );
|
SockBuf.Init ( iNetwFrameSize, iNewNumFrames, bPreserve );
|
||||||
|
|
||||||
return false; // -> no error
|
return false; // -> no error
|
||||||
}
|
}
|
||||||
|
@ -259,7 +260,7 @@ void CChannel::OnSendProtMessage ( CVector<uint8_t> vecMessage )
|
||||||
|
|
||||||
void CChannel::OnJittBufSizeChange ( int iNewJitBufSize )
|
void CChannel::OnJittBufSizeChange ( int iNewJitBufSize )
|
||||||
{
|
{
|
||||||
SetSockBufNumFrames ( iNewJitBufSize );
|
SetSockBufNumFrames ( iNewJitBufSize, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
void CChannel::OnChangeChanGain ( int iChanID, double dNewGain )
|
void CChannel::OnChangeChanGain ( int iChanID, double dNewGain )
|
||||||
|
|
|
@ -91,7 +91,8 @@ public:
|
||||||
void SetRemoteChanGain ( const int iId, const double dGain )
|
void SetRemoteChanGain ( const int iId, const double dGain )
|
||||||
{ Protocol.CreateChanGainMes ( iId, dGain ); }
|
{ Protocol.CreateChanGainMes ( iId, dGain ); }
|
||||||
|
|
||||||
bool SetSockBufNumFrames ( const int iNewNumFrames );
|
bool SetSockBufNumFrames ( const int iNewNumFrames,
|
||||||
|
const bool bPreserve = false );
|
||||||
int GetSockBufNumFrames() const { return iCurSockBufNumFrames; }
|
int GetSockBufNumFrames() const { return iCurSockBufNumFrames; }
|
||||||
|
|
||||||
int GetUploadRateKbps();
|
int GetUploadRateKbps();
|
||||||
|
@ -106,8 +107,6 @@ public:
|
||||||
int GetNetwFrameSize() const { return iNetwFrameSize; }
|
int GetNetwFrameSize() const { return iNetwFrameSize; }
|
||||||
int GetNumAudioChannels() const { return iNumAudioChannels; }
|
int GetNumAudioChannels() const { return iNumAudioChannels; }
|
||||||
|
|
||||||
double GetJitterBufferErrorRate() { return SockBuf.GetErrorRate(); }
|
|
||||||
|
|
||||||
// network protocol interface
|
// network protocol interface
|
||||||
void CreateJitBufMes ( const int iJitBufSize )
|
void CreateJitBufMes ( const int iJitBufSize )
|
||||||
{
|
{
|
||||||
|
@ -143,7 +142,7 @@ protected:
|
||||||
CVector<double> vecdGains;
|
CVector<double> vecdGains;
|
||||||
|
|
||||||
// network jitter-buffer
|
// network jitter-buffer
|
||||||
CNetBufWithStats SockBuf;
|
CNetBuf SockBuf;
|
||||||
int iCurSockBufNumFrames;
|
int iCurSockBufNumFrames;
|
||||||
|
|
||||||
CCycleTimeVariance CycleTimeVariance;
|
CCycleTimeVariance CycleTimeVariance;
|
||||||
|
|
|
@ -421,11 +421,11 @@ void CClient::Stop()
|
||||||
// stop audio interface
|
// stop audio interface
|
||||||
Sound.Stop();
|
Sound.Stop();
|
||||||
|
|
||||||
// wait for approx. 300 ms to make sure no audio packet is still in the
|
// wait for approx. 100 ms to make sure no audio packet is still in the
|
||||||
// network queue causing the channel to be reconnected right after having
|
// network queue causing the channel to be reconnected right after having
|
||||||
// received the disconnect message (seems not to gain much, disconnect is
|
// received the disconnect message (seems not to gain much, disconnect is
|
||||||
// still not working reliably)
|
// still not working reliably)
|
||||||
QTime dieTime = QTime::currentTime().addMSecs ( 300 );
|
QTime dieTime = QTime::currentTime().addMSecs ( 100 );
|
||||||
while ( QTime::currentTime() < dieTime )
|
while ( QTime::currentTime() < dieTime )
|
||||||
{
|
{
|
||||||
QCoreApplication::processEvents ( QEventLoop::AllEvents, 100 );
|
QCoreApplication::processEvents ( QEventLoop::AllEvents, 100 );
|
||||||
|
|
|
@ -134,13 +134,14 @@ public:
|
||||||
|
|
||||||
void SetDoAutoSockBufSize ( const bool bValue ) { bDoAutoSockBufSize = bValue; }
|
void SetDoAutoSockBufSize ( const bool bValue ) { bDoAutoSockBufSize = bValue; }
|
||||||
bool GetDoAutoSockBufSize() const { return bDoAutoSockBufSize; }
|
bool GetDoAutoSockBufSize() const { return bDoAutoSockBufSize; }
|
||||||
void SetSockBufNumFrames ( const int iNumBlocks )
|
void SetSockBufNumFrames ( const int iNumBlocks,
|
||||||
|
const bool bPreserve = false )
|
||||||
{
|
{
|
||||||
// only change parameter if new parameter is different from current one
|
// only change parameter if new parameter is different from current one
|
||||||
if ( Channel.GetSockBufNumFrames() != iNumBlocks )
|
if ( Channel.GetSockBufNumFrames() != iNumBlocks )
|
||||||
{
|
{
|
||||||
// set the new socket size (number of frames)
|
// set the new socket size (number of frames)
|
||||||
if ( !Channel.SetSockBufNumFrames ( iNumBlocks ) )
|
if ( !Channel.SetSockBufNumFrames ( iNumBlocks, bPreserve ) )
|
||||||
{
|
{
|
||||||
// if setting of socket buffer size was successful,
|
// if setting of socket buffer size was successful,
|
||||||
// tell the server that size has changed
|
// tell the server that size has changed
|
||||||
|
|
|
@ -546,7 +546,7 @@ void CClientSettingsDlg::OnDriverSetupClicked()
|
||||||
|
|
||||||
void CClientSettingsDlg::OnNetBufValueChanged ( int value )
|
void CClientSettingsDlg::OnNetBufValueChanged ( int value )
|
||||||
{
|
{
|
||||||
pClient->SetSockBufNumFrames ( value );
|
pClient->SetSockBufNumFrames ( value, true );
|
||||||
UpdateJitterBufferFrame();
|
UpdateJitterBufferFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -957,7 +957,7 @@ void CLlconClientDlg::customEvent ( QEvent* Event )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MS_SET_JIT_BUF_SIZE:
|
case MS_SET_JIT_BUF_SIZE:
|
||||||
pClient->SetSockBufNumFrames ( iStatus );
|
pClient->SetSockBufNumFrames ( iStatus, true );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -225,8 +225,6 @@ CServer::CServer ( const int iNewNumChan,
|
||||||
vstrChatColors[4] = "maroon";
|
vstrChatColors[4] = "maroon";
|
||||||
vstrChatColors[5] = "coral";
|
vstrChatColors[5] = "coral";
|
||||||
|
|
||||||
vecsSendData.Init ( SYSTEM_FRAME_SIZE_SAMPLES );
|
|
||||||
|
|
||||||
// init moving average buffer for response time evaluation
|
// init moving average buffer for response time evaluation
|
||||||
CycleTimeVariance.Init ( SYSTEM_FRAME_SIZE_SAMPLES,
|
CycleTimeVariance.Init ( SYSTEM_FRAME_SIZE_SAMPLES,
|
||||||
SYSTEM_SAMPLE_RATE_HZ, TIME_MOV_AV_RESPONSE_SECONDS );
|
SYSTEM_SAMPLE_RATE_HZ, TIME_MOV_AV_RESPONSE_SECONDS );
|
||||||
|
@ -598,10 +596,10 @@ void CServer::OnTimer()
|
||||||
|
|
||||||
// generate a sparate mix for each channel
|
// generate a sparate mix for each channel
|
||||||
// actual processing of audio data -> mix
|
// actual processing of audio data -> mix
|
||||||
vecsSendData = ProcessData ( i,
|
CVector<short> vecsSendData ( ProcessData ( i,
|
||||||
vecvecsData,
|
vecvecsData,
|
||||||
vecvecdGains[i],
|
vecvecdGains[i],
|
||||||
vecNumAudioChannels );
|
vecNumAudioChannels ) );
|
||||||
|
|
||||||
// get current number of CELT coded bytes
|
// get current number of CELT coded bytes
|
||||||
const int iCeltNumCodedBytes =
|
const int iCeltNumCodedBytes =
|
||||||
|
|
|
@ -228,7 +228,6 @@ protected:
|
||||||
QString strServerNameWithPort;
|
QString strServerNameWithPort;
|
||||||
|
|
||||||
CHighPrecisionTimer HighPrecisionTimer;
|
CHighPrecisionTimer HighPrecisionTimer;
|
||||||
CVector<short> vecsSendData;
|
|
||||||
|
|
||||||
// server list
|
// server list
|
||||||
CServerListManager ServerListManager;
|
CServerListManager ServerListManager;
|
||||||
|
|
|
@ -467,9 +467,11 @@ bool LlconNetwUtil::ParseNetworkAddress ( QString strAddress,
|
||||||
/******************************************************************************\
|
/******************************************************************************\
|
||||||
* Global Functions Implementation *
|
* Global Functions Implementation *
|
||||||
\******************************************************************************/
|
\******************************************************************************/
|
||||||
void DebugError ( const QString& pchErDescr, const QString& pchPar1Descr,
|
void DebugError ( const QString& pchErDescr,
|
||||||
const double dPar1, const QString& pchPar2Descr,
|
const QString& pchPar1Descr,
|
||||||
const double dPar2 )
|
const double dPar1,
|
||||||
|
const QString& pchPar2Descr,
|
||||||
|
const double dPar2 )
|
||||||
{
|
{
|
||||||
QFile File ( "DebugError.dat" );
|
QFile File ( "DebugError.dat" );
|
||||||
if ( File.open ( QIODevice::Append ) )
|
if ( File.open ( QIODevice::Append ) )
|
||||||
|
|
Loading…
Reference in a new issue