📄 filebitstreamreaderagent.cpp
字号:
double CEBCOTRateAllocator::OptimizeBitstreamLayer(int nLayerNumber, double fMaxSThresh, int nMaxBytes, int nPrevBytes)
{
double fSlopeThresh;
//在估计该层的Slope之前,应先保存packetencoder的状态;
m_pPktEncoder->Save();
double fMinSlope;
//根据m_pnRDSlopesRates所包含的单纯的码块压缩码流信息,进行slope的估计;
int sidx;
for (sidx=RD_SUMMARY_SIZE-1;sidx>0;sidx--)
{
if (m_pnRDSlopesRates[sidx]>=nMaxBytes)
break;
}
fMinSlope=GetSlopeFromSIndex(sidx);
if (fMinSlope>=fMaxSThresh)
{
sidx--;
if (sidx<0)
fMinSlope=0;
else
{
fMinSlope=GetSlopeFromSIndex(sidx);
}
}
fSlopeThresh=(fMinSlope+fMaxSThresh)/2;
if (fSlopeThresh<=fMinSlope)
fSlopeThresh=fMaxSThresh;
int nActualBytes;
int nTileNums,nComNums;
nTileNums=m_pCodedImgBlkData->GetTileNums();
nComNums=m_pCodedImgBlkData->GetImgComNums();
int nTileNumber,nComNumber;
int r;
int nPrecIndex;
bool bPktEncoder=false;
bool bSOPUsed,bEPHUsed;
int nPrecNums;
// int s,startSIdx,endSIdx;
do
{
nActualBytes=nPrevBytes;
for (nTileNumber=0;nTileNumber<nTileNums;nTileNumber++)
for (nComNumber=0;nComNumber<nComNums;nComNumber++)
{
bSOPUsed=pEncoderSpec->pSOPUsed->GetTileDef(nTileNumber);
bEPHUsed=pEncoderSpec->pEPHUsed->GetTileDef(nTileNumber);
for (r=0;r<m_pnMrl[nTileNumber][nComNumber];r++)
{
nPrecNums=m_pPrecNums[nTileNumber][nComNumber][r].m_nX*m_pPrecNums[nTileNumber][nComNumber][r].m_nY;
for (nPrecIndex=0;nPrecIndex<nPrecNums;nPrecIndex++)
{
FindTruncIndex(nLayerNumber,nTileNumber,nComNumber,r,nPrecIndex,fSlopeThresh);
bPktEncoder=m_pPktEncoder->EncodePacket(nLayerNumber+1,nComNumber,nTileNumber,r,nPrecIndex,m_pBlkRateDistStats[nTileNumber][nComNumber][r],m_pnTruncIndex[nTileNumber][nLayerNumber][nComNumber][r]);
nActualBytes+=m_pPktEncoder->GetCurPktBodyLenth();
nActualBytes+=m_pPktEncoder->GetCurPktHeaderBuf()->GetValidBLenth();
if (bSOPUsed)
nActualBytes+=CMarkers::SOP_LENGTH;
if (bEPHUsed)
nActualBytes+=CMarkers::EPH_LENGTH;
}
}
}
if (nActualBytes>nMaxBytes)
{
fMinSlope=fSlopeThresh;
}
else
{
fMaxSThresh=fSlopeThresh;
}
fSlopeThresh=(fMinSlope+fMaxSThresh)/2;
m_pPktEncoder->Restore();
}while((fSlopeThresh<fMaxSThresh*(1.0-FLOAT_REL_PRECISION))&&(fSlopeThresh<(fMaxSThresh-FLOAT_ABS_PRECISION)));
if (fSlopeThresh<=FLOAT_ABS_PRECISION)
fSlopeThresh=0;
else
fSlopeThresh=fMaxSThresh;
return fSlopeThresh;
}
void CEBCOTRateAllocator::FindTruncIndex(int nLayerNumber, int nTileNumber, int nComNumber, int r, int nPrecIndex, double fSThresh)
{
int startSIdx,endSIdx,s;
startSIdx=1;
endSIdx=3;
if (r==0)
{
startSIdx=0;
endSIdx=0;
}
int *pnCBlkInPrec=0;
int nBlkInPrecNums;
int nBlkNumber,nBlkIdx;
CBlkRateDistStats *pBlkRateDistStats=0;
int n;
for (s=startSIdx;s<=endSIdx;s++)
{
pnCBlkInPrec=m_pPktEncoder->GetBlkInPrec(nTileNumber,nComNumber,r,s,nPrecIndex);
if (pnCBlkInPrec)
{
nBlkInPrecNums=pnCBlkInPrec[0];
for (nBlkIdx=3;nBlkIdx<(nBlkInPrecNums+3);nBlkIdx++)
{
nBlkNumber=pnCBlkInPrec[nBlkIdx];
pBlkRateDistStats=m_pBlkRateDistStats[nTileNumber][nComNumber][r][s][nBlkNumber];
for (n=0;n<pBlkRateDistStats->m_nVldTrunc;n++)
{
if (pBlkRateDistStats->m_pTruncSlopes[n]<fSThresh)
break;
}
m_pnTruncIndex[nTileNumber][nLayerNumber][nComNumber][r][s][nBlkNumber]=n-1;
}
}
delete []pnCBlkInPrec;
pnCBlkInPrec=0;
}
}
double CEBCOTRateAllocator::EstimateLayerThreshold(int nTargetBytes, CEBCOTLayer &LastLayer)
{
double fSlopeThresh;
double flog_sl1,flog_sl2;
double flog_len1,flog_len2;
double flog_isl;
double flog_ilen;
double flog_lab;
int nSIdx;
double flog_off;
double flthresh;
int nlab=LastLayer.m_nActualBytes;
int tlen;
flthresh=LastLayer.m_fRDThreshold;
if (flthresh>m_fMaxSlope)
flthresh=m_fMaxSlope;
if (flthresh<FLOAT_ABS_PRECISION)
return 0;
nSIdx=GetLimitedSIndexFromSlope(flthresh);
if (nSIdx>=RD_SUMMARY_SIZE-1)
nSIdx=RD_SUMMARY_SIZE-2;
if (m_pnRDSlopesRates[nSIdx+1]==0)
{
flog_len1=log((m_pnRDSlopesRates[nSIdx]<<1)+1);
flog_len2=log(m_pnRDSlopesRates[nSIdx]+1);
flog_lab=log(nlab+m_pnRDSlopesRates[nSIdx]+1);
}
else
{
flog_len1=log(m_pnRDSlopesRates[nSIdx]);
flog_len2=log(m_pnRDSlopesRates[nSIdx+1]);
flog_lab=log(nlab);
}
flog_sl1=log(GetSlopeFromSIndex(nSIdx));
flog_sl2=log(GetSlopeFromSIndex(nSIdx+1));
flog_isl=log(flthresh);
flog_ilen=flog_len1+(flog_isl-flog_sl1)*(flog_len1-flog_len2)/(flog_sl1-flog_sl2);
flog_off=flog_lab-flog_ilen;
tlen=(int)(nTargetBytes/exp(flog_off));
for (nSIdx=RD_SUMMARY_SIZE-1;nSIdx>0;nSIdx--)
{
if (m_pnRDSlopesRates[nSIdx]>=tlen)
break;
}
nSIdx++;
if (nSIdx>=RD_SUMMARY_SIZE)
nSIdx=RD_SUMMARY_SIZE-1;
if (nSIdx<=0)
nSIdx=1;
if (m_pnRDSlopesRates[nSIdx]==0)
{
flog_len1=log(m_pnRDSlopesRates[nSIdx-1]+1);
flog_len2=log((m_pnRDSlopesRates[nSIdx-1]<<1)+1);
flog_lab=log(tlen+m_pnRDSlopesRates[nSIdx-1]+1);
}
else
{
flog_len1=log(m_pnRDSlopesRates[nSIdx]);
flog_len2=log(m_pnRDSlopesRates[nSIdx-1]);
flog_lab=log(tlen);
}
flog_sl1=log(GetSlopeFromSIndex(nSIdx));
flog_sl2=log(GetSlopeFromSIndex(nSIdx-1));
flog_isl=flog_sl1+(flog_ilen-flog_len1)*(flog_sl1-flog_sl2)/(flog_len1-flog_len2);
fSlopeThresh=exp(flog_isl);
if (fSlopeThresh>flthresh)
fSlopeThresh=flthresh;
if (fSlopeThresh<FLOAT_ABS_PRECISION)
fSlopeThresh=0;
return fSlopeThresh;
}
void CEBCOTRateAllocator::BuildandWriteLayers()
{
int nMaxBytes,nActualBytes,nPakcetBytes=0;
int nLayerNumber;
double fRDThresh=m_fMaxSlope;
int nTileNums,nComNums;
nTileNums=m_pCodedImgBlkData->GetTileNums();
nComNums=m_pCodedImgBlkData->GetImgComNums();
int *pnTileLength=new int[nTileNums];
int nTileNumber,nComNumber;
for (nTileNumber=0;nTileNumber<nTileNums;nTileNumber++)
{
pnTileLength[nTileNumber]=0;
}
bool bSOPUsed,bEPHUsed;
int r;
int startSIdx,endSIdx;
int nPrecIndex,nPrecNums;
int ntmp=0;
bool bPktEncoder;
nActualBytes=0;
/*-------------------------------------------------
* 估计每一层的截断点门限和每一层的字节数 *
--------------------------------------------------*/
for (nLayerNumber=0;nLayerNumber<m_nLayerNums;nLayerNumber++)
{
nMaxBytes=m_pEBCOTLayer[nLayerNumber].m_nMaxBytes;
if (m_pEBCOTLayer[nLayerNumber].m_bOptimize)
fRDThresh=OptimizeBitstreamLayer(nLayerNumber,fRDThresh,nMaxBytes,nActualBytes);
else
fRDThresh=EstimateLayerThreshold(nMaxBytes,m_pEBCOTLayer[nLayerNumber-1]);
for (nTileNumber=0;nTileNumber<nTileNums;nTileNumber++)
{
if (nLayerNumber==0)
{
CHeaderEncoder *pp=m_pHeadEncoder;
m_pHeadEncoder->Reset();
m_pHeadEncoder->WriteTilePartHeader(0,nTileNumber);
pnTileLength[nTileNumber]+=m_pHeadEncoder->GetBufferLength();
}
for (nComNumber=0;nComNumber<nComNums;nComNumber++)
{
bSOPUsed=pEncoderSpec->pSOPUsed->GetTileComVal(nTileNumber,nComNumber);
bEPHUsed=pEncoderSpec->pEPHUsed->GetTileComVal(nTileNumber,nComNumber);
for (r=0;r<m_pnMrl[nTileNumber][nComNumber];r++)
{
nPrecNums=m_pPrecNums[nTileNumber][nComNumber][r].m_nX*m_pPrecNums[nTileNumber][nComNumber][r].m_nY;
startSIdx=1;
endSIdx=3;
if (r==0)
{
startSIdx=0;
endSIdx=0;
}
for (nPrecIndex=0;nPrecIndex<nPrecNums;nPrecIndex++)
{
FindTruncIndex(nLayerNumber,nTileNumber,nComNumber,r,nPrecIndex,fRDThresh);
bPktEncoder=m_pPktEncoder->EncodePacket(nLayerNumber+1,nComNumber,nTileNumber,r,nPrecIndex,m_pBlkRateDistStats[nTileNumber][nComNumber][r],m_pnTruncIndex[nTileNumber][nLayerNumber][nComNumber][r]);
ntmp=m_pPktEncoder->GetCurPktBodyLenth();
ntmp+=m_pPktEncoder->GetCurPktHeaderBuf()->GetValidBLenth();
if (bSOPUsed)
ntmp+=CMarkers::SOP_LENGTH;
if (bEPHUsed)
ntmp+=CMarkers::EPH_LENGTH;
nActualBytes+=ntmp;
pnTileLength[nTileNumber]+=ntmp;
}
}
}
}
m_pEBCOTLayer[nLayerNumber].m_fRDThreshold=fRDThresh;
m_pEBCOTLayer[nLayerNumber].m_nActualBytes=nActualBytes;
}
/*-----------------------------------------------------------
* 根据上面所得到的每一层的截断点以及编码参数progression, *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -