SmartAudio/package/allwinner/liballwinner_tina/liballwinner/LIBRARY/PLAYER/bitrateEstimater.cpp

200 lines
5.2 KiB
C++
Executable File

#include <string.h>
#include <stdint.h>
#include "bitrateEstimater.h"
#include "log.h"
BitrateEstimater* BitrateEstimaterCreate(void)
{
BitrateEstimater* be;
be = (BitrateEstimater*)malloc(sizeof(BitrateEstimater));
if(be == NULL)
{
loge("malloc memory fail.");
return NULL;
}
memset(be, 0, sizeof(BitrateEstimater));
pthread_mutex_init(&be->mutex, NULL);
return be;
}
void BitrateEstimaterDestroy(BitrateEstimater* be)
{
pthread_mutex_destroy(&be->mutex);
free(be);
return;
}
void BitrateEstimaterUpdate(BitrateEstimater* be, int64_t nPts, int nFrameLen)
{
int tmpWritePos;
pthread_mutex_lock(&be->mutex);
if(nPts == -1)
{
if(be->nValidNodeCnt == 0)
{
pthread_mutex_unlock(&be->mutex);
return;
}
tmpWritePos = be->nWritePos;
if(tmpWritePos == 0)
tmpWritePos = BITRATE_ARRAY_SIZE-1;
else
tmpWritePos--;
be->nodes[tmpWritePos].nFrameLen += nFrameLen;
pthread_mutex_unlock(&be->mutex);
return;
}
be->nodes[be->nWritePos].nFramePts = nPts;
be->nodes[be->nWritePos].nFrameLen = nFrameLen;
be->nWritePos++;
if(be->nWritePos >= BITRATE_ARRAY_SIZE)
be->nWritePos = 0;
if(be->nValidNodeCnt < BITRATE_ARRAY_SIZE)
be->nValidNodeCnt++;
tmpWritePos = be->nWritePos;
if(tmpWritePos < be->nWritePosLastEstimate)
tmpWritePos += BITRATE_ARRAY_SIZE;
if(tmpWritePos >= (be->nWritePosLastEstimate+BITRATE_ESTIMATE_INTERVAL))
{
int i;
int j;
int nStartPos;
int nRunLen;
int64_t nByteRate;
int64_t nTotalSize;
int64_t nFirstPts;
int64_t nLastPts;
int64_t nDuration;
int frameLenArr[BITRATE_ARRAY_SIZE];
int64_t ptsArr[BITRATE_ARRAY_SIZE+1];
nStartPos = be->nWritePos - be->nValidNodeCnt;
if(nStartPos < 0)
nStartPos += BITRATE_ARRAY_SIZE;
for(i=0; i<be->nValidNodeCnt; i++)
{
frameLenArr[i] = be->nodes[nStartPos].nFrameLen;
ptsArr[i] = be->nodes[nStartPos].nFramePts;
nStartPos++;
if(nStartPos >= BITRATE_ARRAY_SIZE)
nStartPos = 0;
}
//* find the longest pts continue frame run length.
for(i=0; i<be->nValidNodeCnt-1; i++)
{
if(ptsArr[i] > (ptsArr[i+1]+PTS_DISCONTINUE_INTERVAL) ||
(ptsArr[i]+PTS_DISCONTINUE_INTERVAL) < ptsArr[i+1])
{
logv("pts jump at %d, pts[%d] = %lld, pts[%d] = %lld", i, i, ptsArr[i], i+1, ptsArr[i+1]);
break;
}
}
if(i == be->nValidNodeCnt-1)
{
//* pts normal mode.
nFirstPts = ptsArr[0];
nLastPts = ptsArr[be->nValidNodeCnt-1];
nDuration = nLastPts - nFirstPts;
if(nDuration <= 0)
{
// logw("bitrate estimater get an invalid duration %lld", nDuration);
be->nWritePosLastEstimate = be->nWritePos;
pthread_mutex_unlock(&be->mutex);
return;
}
nTotalSize = 0;
for(j=0; j<be->nValidNodeCnt; j++)
nTotalSize += frameLenArr[j];
nByteRate = nTotalSize*1000000/nDuration;
be->nBitrate = (int)(nByteRate*8);
}
else
{
//* pts loop back mode.
j = 0;
nStartPos = 0;
nRunLen = 0;
ptsArr[be->nValidNodeCnt] = -1;
for(i=0; i<be->nValidNodeCnt; i++)
{
if(ptsArr[i] > (ptsArr[i+1] + PTS_DISCONTINUE_INTERVAL) ||
(ptsArr[i] + PTS_DISCONTINUE_INTERVAL) < ptsArr[i+1])
{
if(i - nStartPos > nRunLen)
{
j = nStartPos;
nRunLen = i - nStartPos;
}
nStartPos = i+1;
}
}
if(nRunLen > 0)
{
nFirstPts = ptsArr[j];
nLastPts = ptsArr[j+nRunLen];
nDuration = nLastPts - nFirstPts;
if(nDuration <= 0)
{
logw("bitrate estimater get an invalid duration %lld", nDuration);
be->nWritePosLastEstimate = be->nWritePos;
pthread_mutex_unlock(&be->mutex);
return;
}
nTotalSize = 0;
for(i=0; i<=nRunLen; i++)
nTotalSize += frameLenArr[j+i];
nByteRate = nTotalSize*1000000/nDuration;
be->nBitrate = (int)(nByteRate*8);
}
}
be->nWritePosLastEstimate = be->nWritePos;
}
pthread_mutex_unlock(&be->mutex);
return;
}
int BitrateEstimaterGetBitrate(BitrateEstimater* be)
{
return be->nBitrate;
}
void BitrateEstimaterReset(BitrateEstimater* be)
{
pthread_mutex_lock(&be->mutex);
be->nBitrate = 0;
be->nWritePos = 0;
be->nValidNodeCnt = 0;
be->nWritePosLastEstimate = 0;
pthread_mutex_unlock(&be->mutex);
return;
}