📄 fgssubbandencoder.cpp
字号:
UInt ui;
RNOK( m_cMbDataCtrlEL .initSlice ( *m_pcSliceHeader, PRE_PROCESS, false, NULL ) );
RNOK( m_pcCurrMbDataCtrl->initSlice ( *m_pcSliceHeader, PRE_PROCESS, false, NULL ) );
m_pcSliceHeader->setSliceType( m_eSliceType );
if(!uiFracNb)
{
RNOK( m_pcSymbolWriter ->startSlice( *m_pcSliceHeader ) );
}
else
{
RNOK( m_pcSymbolWriter ->startFragment() );
}
AOT( m_pcSymbolWriter == 0);
m_pcSliceHeader->setSliceType( F_SLICE );
rbCorrupted = false;
Int iLastQP = m_pcSliceHeader->getPicQp();
UInt uiBitsLast = m_pcSymbolWriter->getNumberOfWrittenBits();
Bool bCheck = ( uiMaxBits != 0 );
//FIX_FRAG_CAVLC
if( uiFracNb )
{
RNOK( m_pcSymbolWriter->setFirstBits(m_ucLastByte, m_uiLastBitPos));
}
//~FIX_FRAG_CAVLC
//positions vector for luma (and chromaAC) and chroma DC
for(ui = 0; ui < 4; ui++)
{
m_auiScanPosVectChromaDC[ui] = ui;
}
if(m_pcSliceHeader->getFGSCodingMode() == false)
{
//grouping size mode
UInt uiGroupingSize = m_pcSliceHeader->getGroupingSize();
ui = 0;
m_auiScanPosVectLuma[ui] = uiGroupingSize-1;
while( m_auiScanPosVectLuma[ui] < 15)
{
ui++;
m_auiScanPosVectLuma[ui] = m_auiScanPosVectLuma[ui-1]+uiGroupingSize;
}
}
else
{
//vector specified
ui = 0;
m_auiScanPosVectLuma[ui] = m_pcSliceHeader->getPosVect(ui);
while( m_auiScanPosVectLuma[ui] != 15)
{
ui++;
m_auiScanPosVectLuma[ui] = m_auiScanPosVectLuma[ui-1] + m_pcSliceHeader->getPosVect(ui);
}
}
try
{
{
UInt uiScanPos;
UInt iStartCycle = 0, iCycle = 0;
UInt iLastBitsLuma = 0;
UInt iLastBitsChroma = 0;
UInt iBitsLuma = 0;
UInt iBitsChroma = 0;
UInt iLumaScanIdx = 0;
UInt iChromaDCScanIdx = 0;
UInt iChromaACScanIdx = 1;
UInt uiPass;
UInt uiPassStart;
m_uiFirstMbInSlice = m_pcSliceHeader->getFirstMbInSlice();
UInt uiLastMbInSlice = m_pcSliceHeader->getLastMbInSlice();
//--ICU/ETRI FMO Implementation : start
UInt uiFirstMbY = (UInt) ( m_uiFirstMbInSlice / m_uiWidthInMB );
UInt uiFirstMbX = m_uiFirstMbInSlice % m_uiWidthInMB;
UInt uiLastMbY = (UInt) ( ( uiLastMbInSlice+1) / m_uiWidthInMB );
UInt uiLastMbX = ( uiLastMbInSlice+1) % m_uiWidthInMB;
if(!uiFracNb) //FIX_FRAG_CAVLC
{
// Pre-scan frame to find VLC positions
UInt auiEobShift[16];
UInt auiHighMagHist[16];
UInt auiBestCodeTabMap[16];
UInt* pauiHistLuma = new UInt[16*16*16];
UInt* pauiHistChroma = new UInt[16*16*16];
::memset(pauiHistLuma , 0x00, 16*16*16*sizeof(UInt));
::memset(pauiHistChroma, 0x00, 16*16*16*sizeof(UInt));
::memset(auiHighMagHist, 0x00, 16*sizeof(UInt));
for(UInt uiMbAddress=m_uiFirstMbInSlice ;uiMbAddress<=uiLastMbInSlice ;)
{
UInt uiMbYIdx = uiMbAddress / m_uiWidthInMB;
UInt uiMbXIdx = uiMbAddress % m_uiWidthInMB;
{
//===== LUMA =====
for( UInt uiB8YIdx = 2 * uiMbYIdx; uiB8YIdx < 2 * uiMbYIdx + 2; uiB8YIdx++ )
for( UInt uiB8XIdx = 2 * uiMbXIdx; uiB8XIdx < 2 * uiMbXIdx + 2; uiB8XIdx++ )
{
for( UInt uiBlockYIdx = 2 * uiB8YIdx; uiBlockYIdx < 2 * uiB8YIdx + 2; uiBlockYIdx++ )
for( UInt uiBlockXIdx = 2 * uiB8XIdx; uiBlockXIdx < 2 * uiB8XIdx + 2; uiBlockXIdx++ )
{
RNOK( xVLCParseLuma( uiBlockYIdx, uiBlockXIdx, pauiHistLuma, auiHighMagHist ) );
} // 4x4 block iteration
} // 8x8 block iteration
// ===== CHROMA AC =====
for( UInt uiPlane = 0; uiPlane < 2; uiPlane ++ )
for( UInt uiB8YIdx = 2 * uiMbYIdx; uiB8YIdx < 2 * uiMbYIdx + 2; uiB8YIdx++ )
for( UInt uiB8XIdx = 2 * uiMbXIdx; uiB8XIdx < 2 * uiMbXIdx + 2; uiB8XIdx++ ) {
RNOK( xVLCParseChromaAC( uiPlane, uiB8YIdx, uiB8XIdx, pauiHistChroma ) );
}
} // macroblock iteration
//--ICU/ETRI FMO Implementation
uiMbAddress = m_pcSliceHeader->getFMO()->getNextMBNr(uiMbAddress );
}
RNOK( m_cMbDataCtrlEL .initSlice ( *m_pcSliceHeader, PRE_PROCESS, false, NULL ) );
RNOK( m_pcCurrMbDataCtrl->initSlice ( *m_pcSliceHeader, PRE_PROCESS, false, NULL ) );
// Tally over base pos to find EOB shift
for (uiScanPos=0; uiScanPos<16; uiScanPos++)
{
auiEobShift[uiScanPos] = 0;
for (UInt uiHpos=1; uiHpos<16; uiHpos++) {
UInt uiTotal = 0;
for (UInt uiBase=0; uiBase<16; uiBase++)
uiTotal += pauiHistLuma[(uiScanPos*16+uiBase)*16+uiHpos];
if (uiTotal < auiHighMagHist[uiScanPos])
break;
if (uiScanPos > 0 && auiEobShift[uiScanPos] == auiEobShift[uiScanPos-1])
break;
auiEobShift[uiScanPos]++;
}
}
// 'Outlier' removal
if (auiEobShift[0] > auiEobShift[1] + 8)
auiEobShift[0] = 15;
RNOK( m_pcSymbolWriter->RQencodeEobOffsets_Luma( auiEobShift ) );
{
UInt uiTempCodeLenCycleBase[][16] = {
{1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16}, // unary 0
{2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9}, // flat 2 1
{2, 2, 2, 4, 4, 4, 6, 6, 6, 8, 8, 8,10,10,10,11}, // flat 3 2
{1, 3, 3, 3, 5, 5, 5, 7, 7, 7, 9, 9, 9,11,11,11}, // S3 cutoff 0 3
{1, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,9, 9, 9}}; //
UInt *pauiHistLumaNoBase = new UInt[16*16];
UInt uiTotalNumCodeTable = 5;
UInt uiTotalRunCost = 0;
UInt uiCycle=0;
// tally histogram without LEBL index
memset(pauiHistLumaNoBase, 0, sizeof(UInt)*16*16);
for(uiCycle = 0; uiCycle < 16; uiCycle++)
{
for(ui = 0; ui < 16; ui++)
for(UInt uiBase = 0; uiBase < 16; uiBase++)
{
pauiHistLumaNoBase[uiCycle*16+ui] += pauiHistLuma[(uiCycle*16+uiBase)*16+ui];
}
}
{
uiCycle = 0;
UInt uiBestTable;
UInt uiCost[5], uiBestCost;
UInt uiTableIdx;
// find the cost of using each table
for(uiTableIdx = 0; uiTableIdx < uiTotalNumCodeTable; uiTableIdx++)
{
UInt *uiTable = uiTempCodeLenCycleBase[uiTableIdx];
uiCost[uiTableIdx] = 0;
for(ui = 1; ui < 16; ui++)
{
UInt uiCodeLen = uiTable[ui-1];
uiCost[uiTableIdx] += pauiHistLumaNoBase[ui]*uiCodeLen;
}
}
// find the best table with lowest cost
uiBestTable = 0;
uiBestCost = uiCost[0];
for(uiTableIdx = 1; uiTableIdx < uiTotalNumCodeTable; uiTableIdx++)
{
if(uiCost[uiTableIdx] < uiBestCost)
{
uiBestTable = uiTableIdx;
uiBestCost = uiCost[uiTableIdx];
}
}
auiBestCodeTabMap[uiCycle] = uiBestTable;
uiTotalRunCost += uiBestCost;
}
for(uiCycle = 1; uiCycle < 16; uiCycle++)
{
UInt uiBestTable;
UInt uiCost[5], uiBestCost;
UInt uiTableIdx;
// find the cost of using each table
for( uiTableIdx = 0; uiTableIdx < uiTotalNumCodeTable; uiTableIdx++)
{
UInt *uiTable = uiTempCodeLenCycleBase[uiTableIdx];
uiCost[uiTableIdx] = 0;
for(ui = 0; ui < 16; ui++)
{
UInt uiSymbol;
if(ui == 0)
{
uiSymbol = auiEobShift[uiCycle];
}
else
{
uiSymbol = (ui <= auiEobShift[uiCycle])? ui-1:ui;
}
UInt uiCodeLen = uiTable[uiSymbol];
uiCost[uiTableIdx] += pauiHistLumaNoBase[(uiCycle*16)+ui]*uiCodeLen;
}
}
// find the best table with lowest cost
uiBestTable = 0;
uiBestCost = uiCost[0];
for(uiTableIdx = 1; uiTableIdx < uiTotalNumCodeTable; uiTableIdx++)
{
if(uiCost[uiTableIdx] < uiBestCost)
{
uiBestTable = uiTableIdx;
uiBestCost = uiCost[uiTableIdx];
}
}
auiBestCodeTabMap[uiCycle] = uiBestTable;
uiTotalRunCost += uiBestCost;
}
delete pauiHistLumaNoBase;
}
// Tally over base pos to find EOB shift
for (uiScanPos=0; uiScanPos<16; uiScanPos++) {
auiEobShift[uiScanPos] = 0;
UInt uiEobTotal = 0;
for (UInt uiBase=0; uiBase<16; uiBase++)
uiEobTotal += pauiHistChroma[(uiScanPos*16+uiBase)*16];
for (UInt uiHpos=1; uiHpos<16; uiHpos++) {
UInt uiTotal = 0;
for (int uiBase=0; uiBase<16; uiBase++)
uiTotal += pauiHistChroma[(uiScanPos*16+uiBase)*16+uiHpos];
if (uiTotal < uiEobTotal)
break;
if (uiScanPos > 0 && auiEobShift[uiScanPos] == auiEobShift[uiScanPos-1])
break;
auiEobShift[uiScanPos]++;
}
}
// 'Outlier' removal
if (auiEobShift[0] > auiEobShift[1] + 8)
auiEobShift[0] = 15;
RNOK( m_pcSymbolWriter->RQencodeEobOffsets_Chroma( auiEobShift ) );
RNOK( m_pcSymbolWriter->RQencodeBestCodeTableMap( auiBestCodeTabMap, 16 ) );
delete pauiHistLuma;
delete pauiHistChroma;
} //FIX_FRAG_CAVLC
UInt uiLumaCbpBitCount = 0;
UInt uiLumaCbpNextMbX = uiFirstMbX;
UInt uiLumaCbpNextMbY = uiFirstMbY;
UInt uiLumaCbpNext8x8Idx = 0;
UInt uiChromaCbpBitCount = 0;
UInt uiChromaCbpNextMbX = uiFirstMbX;
UInt uiChromaCbpNextMbY = uiFirstMbY;
if( ! m_pcSliceHeader->getPPS().getEntropyCodingModeFlag() && !uiFracNb)
{
xEncodeLumaCbpVlcStart(
uiLumaCbpNextMbX, uiLumaCbpNextMbY, uiLumaCbpNext8x8Idx,
uiLastMbX, uiLastMbY, uiLumaCbpBitCount);
xEncodeChromaCbpVlcStart(uiFirstMbX, uiFirstMbY, uiChromaCbpBitCount);
}
while (iLumaScanIdx < 16 || iChromaDCScanIdx < 4 || iChromaACScanIdx < 16) {
UInt bAllowChromaDC = (iCycle == 0) || ((iCycle >= iStartCycle) && ((iCycle-iStartCycle) % 2 == 0));
UInt bAllowChromaAC = (iCycle > 0) && ((iCycle == iStartCycle) || ((iCycle >= iStartCycle) && ((iCycle-iStartCycle) % 3 == 1)));
//if(!uiFracNb) bCheck = true;
//m_uiMaxBits = 10000;
if(!uiFracNb)
{
// start values for loops
m_uiMbYIdx = uiFirstMbY;
m_uiMbXIdx = ( m_uiMbYIdx == uiFirstMbY ? uiFirstMbX : 0 );
m_uiB8YIdx = 2*m_uiMbYIdx;
m_uiB8XIdx = 2*m_uiMbXIdx;
m_uiBlockYIdx = 2*m_uiB8YIdx;
m_uiBlockXIdx = 2*m_uiB8XIdx;
m_uiPlane = 0;
m_uiFGSPart = 0;
uiPassStart = 0;
}
else
{
if(bRestore)
{
bCheck = false;
// restore status
UInt uiUnused;
xRestoreFGSState(iLumaScanIdx, iChromaDCScanIdx, iChromaACScanIdx, iStartCycle, iCycle, uiPassStart, bAllowChromaDC, bAllowChromaAC, uiUnused, uiUnused, uiUnused, uiUnused, uiUnused, uiUnused, iLastBitsLuma, /*uiBitsLast*/uiUnused, uiUnused, uiUnused, iLastQP);
// restore the cbp-related coding states
uiLumaCbpNextMbX = m_uiLumaCbpNextMbX;
uiLumaCbpNextMbY = m_uiLumaCbpNextMbY;
uiLumaCbpNext8x8Idx = m_uiLumaCbpNext8x8Idx;
uiChromaCbpNextMbX = m_uiChromaCbpNextMbX;
uiChromaCbpNextMbY = m_uiChromaCbpNextMbY;
bRestore = false;
}
else
{
uiPassStart = 0;
}
}
uiPass = uiPassStart;
UInt uiMaxPosLuma;
UInt uiMaxPosChromaAC;
UInt uiMaxPosChromaDC;
if( iLumaScanIdx == 16 )
uiMaxPosLuma = 16;
else {
for( ui=0; m_auiScanPosVectLuma[ui]<iLumaScanIdx; ui++ ) ;
uiMaxPosLuma = m_auiScanPosVectLuma[ui];
}
if( iChromaACScanIdx == 16 )
uiMaxPosChromaAC = 16;
else {
for( ui=0; 1+m_auiScanPosVectLuma[ui]<iChromaACScanIdx; ui++ ) ;
uiMaxPosChromaAC = 1+m_auiScanPosVectLuma[ui];
}
if( iChromaDCScanIdx == 16 )
uiMaxPosChromaDC = 16;
else {
for( ui=0; m_auiScanPosVectChromaDC[ui]<iChromaDCScanIdx; ui++ ) ;
uiMaxPosChromaDC = m_auiScanPosVectChromaDC[ui];
}
for(UInt uiMbAddress=m_uiFirstMbInSlice ;uiMbAddress<=uiLastMbInSlice;)
{
UInt uiMbYIdx = uiMbAddress / m_uiWidthInMB;
UInt uiMbXIdx = uiMbAddress % m_uiWidthInMB;
{
if( ! m_pcSliceHeader->getPPS().getEntropyCodingModeFlag() )
{
Bool bFirstPassPrescan = bFirstPass;
UInt uiB8YInit, uiB8XInit, uiBlockYInit, uiBlockXInit;
uiB8YInit = m_uiB8YIdx;
uiB8XInit = m_uiB8XIdx;
uiBlockYInit = 2*uiB8YInit;
uiBlockXInit = 2*uiB8XInit;
if(!bFirstPassPrescan) {
uiB8YInit = 2*uiMbYIdx;
uiB8XInit = 2*uiMbXIdx;
}
/* refinement coefficients pre-scan */
//===== LUMA =====
if( (m_uiFGSPart == 0) || (!bFirstPassPrescan) ){
for( UInt uiB8YIdx = uiB8YInit; uiB8YIdx < 2 * uiMbYIdx + 2; uiB8YIdx++ ) {
for( UInt uiB8XIdx = uiB8XInit; uiB8XIdx < 2 * uiMbXIdx + 2; uiB8XIdx++ ){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -