📄 h264avcdecoder.cpp
字号:
for( uiLayer = 0; uiLayer < MAX_LAYERS; uiLayer ++ )
for( uiQualityLevel = 0; uiQualityLevel < MAX_QUALITY_LEVELS; uiQualityLevel ++)
{
m_uiNumberOfFragment[uiLayer][uiQualityLevel] = 0;
}
}
Void H264AVCDecoder::getDecodedResolution(UInt &uiLayerId)
{
UInt uiSPSId = 0;
UInt uiX = 0;
UInt uiY = 0;
UInt uiMBX = 0;
UInt uiMBY = 0;
SequenceParameterSet *rcSPS;
uiSPSId = 0;
uiMBX = 0;
uiMBY = 0;
UInt uiSPS = 0;
while(uiSPS < m_uiNumberOfSPS)
{
if(m_pcParameterSetMng->isValidSPS(uiSPSId))
{
m_pcParameterSetMng->get(rcSPS,uiSPSId);
uiX = rcSPS->getFrameWidthInMbs();
uiY = rcSPS->getFrameHeightInMbs();
if(uiX >= uiMBX && uiY >= uiMBY) //FIX_FRAG_CAVLC
{
uiMBX = uiX;
uiMBY = uiY;
uiLayerId = rcSPS->getLayerId();
}
uiSPS++;
}
uiSPSId++;
}
}
//~JVT-P031
//TMM_EC{{
Bool
H264AVCDecoder::checkSEIForErrorConceal()
{
Bool ret = true;
//UInt i = 0;
if ( m_bNotSupport)
{
return false;
}
if ( m_uiNumLayers > 2 || m_uiNumLayers == 0 )
{
return false;
}
return ret;
}
ErrVal
H264AVCDecoder::checkSliceGap( BinDataAccessor* pcBinDataAccessor,
MyList<BinData*>& cVirtualSliceList )
{
static Bool bFinished=false;//TMM_EC
Bool bEos;
NalUnitType eNalUnitType;
SliceHeader* pcSliceHeader = NULL;
Int slicePoc;
ROT( NULL == pcBinDataAccessor );
bEos = ( NULL == pcBinDataAccessor->data() ) || ( 0 == pcBinDataAccessor->size() );
slicePoc = 0;
UInt frame_num;
UInt uiLayerId;
UInt uiPocLsb;
UInt uiMaxFrameNum;
UInt uiMaxPocLsb;
//TMM_EC {{
if ( bEos && !bFinished)
{
bFinished = true;
goto bEOS;
}
//TMM_EC }}
if( ! bEos )
{
UInt uiNumBytesRemoved; //FIX_FRAG_CAVLC
//bug-fix suffix shenqiu{{
//RNOK( m_pcNalUnitParser->initNalUnit( pcBinDataAccessor, NULL, uiNumBytesRemoved, true, false, true ) );
RNOK( m_pcNalUnitParser->initNalUnit( pcBinDataAccessor, uiNumBytesRemoved, true, false, true ) );
//bug-fix suffix shenqiu}}
//prefix unit{{
if(m_pcNalUnitParser->getNalUnitType() == NAL_UNIT_PREFIX)
{
return Err::m_nOK;
}
//prefix unit}}
if ( m_pcNalUnitParser->getQualityLevel() != 0)
{
BinData *pcBinData = new BinData;
pcBinData->set( new UChar[pcBinDataAccessor->size()], pcBinDataAccessor->size());
memcpy( pcBinData->data(), pcBinDataAccessor->data(), pcBinDataAccessor->size());
cVirtualSliceList.pushBack( pcBinData);
//*///xk
return Err::m_nERR;
}
if ( ( m_pcNalUnitParser->getNalUnitType() == NAL_UNIT_CODED_SLICE_SCALABLE
|| m_pcNalUnitParser->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_SCALABLE )
&& m_pcNalUnitParser->getLayerId() == 0)
{
return Err::m_nERR;
}
if ( !checkSEIForErrorConceal())
{
return Err::m_nInvalidParameter;
}
eNalUnitType = m_pcNalUnitParser->getNalUnitType();
if( eNalUnitType != NAL_UNIT_CODED_SLICE &&
// eNalUnitType != NAL_UNIT_CODED_SLICE_IDR &&
eNalUnitType != NAL_UNIT_CODED_SLICE_SCALABLE &&
// eNalUnitType != NAL_UNIT_CODED_SLICE_IDR_SCALABLE &&
eNalUnitType != NAL_UNIT_END_OF_STREAM &&
1)
{
if(eNalUnitType==NAL_UNIT_CODED_SLICE_IDR||eNalUnitType==NAL_UNIT_CODED_SLICE_IDR_SCALABLE)
{
RNOK( m_pcSliceReader->readSliceHeader( m_pcNalUnitParser,
pcSliceHeader,
m_uiFirstFragmentNumMbsInSlice,
m_bFirstFragmentFGSCompSep
) );
if(pcSliceHeader->getFrameNum()==0)
m_uiMaxLayerId=pcSliceHeader->getLayerId()>m_uiMaxLayerId ? pcSliceHeader->getLayerId(): m_uiMaxLayerId;
}
return Err::m_nOK;
}
else
{
if ( eNalUnitType != NAL_UNIT_END_OF_STREAM)
{
// read the slice header
RNOK( m_pcSliceReader->readSliceHeader( m_pcNalUnitParser,
pcSliceHeader,
m_uiFirstFragmentNumMbsInSlice,
m_bFirstFragmentFGSCompSep
) );
if(pcSliceHeader->getFrameNum()==0)
m_uiMaxLayerId=pcSliceHeader->getLayerId()>m_uiMaxLayerId ? pcSliceHeader->getLayerId(): m_uiMaxLayerId;
calculatePoc( eNalUnitType, *pcSliceHeader, slicePoc );
// if(pcSliceHeader->getFrameNum()==1&&m_uiMaxLayerId!=(m_uiNumLayers-1))
// m_bNotSupport=true;
if ( pcSliceHeader->getFrameNum() == 1 && pcSliceHeader->getLayerId() == m_uiNumLayers-1)
{
if ( pcSliceHeader->getPicOrderCntLsb() != m_uiMaxGopSize)
{
m_bNotSupport = true;
}
if ( pcSliceHeader->getFirstMbInSlice() != 0)
{
m_bNotSupport = true;
}
if ( pcSliceHeader->getFrameNum() == 1)
{
UInt i=pcSliceHeader->getPicOrderCntLsb();
while ( i % 2 == 0)
{
i /= 2;
}
if ( i!= 1)
{
m_bNotSupport = true;
}
}
}
// F slices are also ignored
if( pcSliceHeader->getSliceType() == F_SLICE || pcSliceHeader->getFrameNum() == 1 && pcSliceHeader->getLayerId() < m_uiMaxLayerId)
// if( pcSliceHeader->getSliceType() == F_SLICE)
{
if( pcSliceHeader != NULL )
delete pcSliceHeader;
return Err::m_nOK;
}
// detection the gap of slice
frame_num = pcSliceHeader->getFrameNum();
uiLayerId = pcSliceHeader->getLayerId();
uiPocLsb = pcSliceHeader->getPicOrderCntLsb();
// uiGopSize = pcSliceHeader->getSPS().getNumRefFrames() + 1; //??
UInt uiGopSize = m_uiGopSize[uiLayerId];
if ( frame_num == 1 &&m_uiMaxLayerId==uiLayerId&& uiPocLsb > uiGopSize)
{
m_bNotSupport = true;
if( pcSliceHeader != NULL )
delete pcSliceHeader;
return Err::m_nOK;
}
uiMaxFrameNum = 1 << pcSliceHeader->getSPS().getLog2MaxFrameNum();
uiMaxPocLsb = 1 << pcSliceHeader->getSPS().getLog2MaxPicOrderCntLsb();
}
else
{
bEOS://xk
SliceHeader *pcSH;
if ( m_pcVeryFirstSliceHeader == NULL)
{
pcSH = m_apcMCTFDecoder[m_uiNextLayerId]->m_pcVeryFirstSliceHeader;
}
else
{
pcSH = m_pcVeryFirstSliceHeader;
}
uiMaxFrameNum = 1 << pcSH->getSPS().getLog2MaxFrameNum();
uiMaxPocLsb = 1 << pcSH->getSPS().getLog2MaxPicOrderCntLsb();
uiLayerId = m_uiNextLayerId;
UInt uiGopSize = 1 << m_uiDecompositionStages[uiLayerId];
// uiGopSize = m_uiGopSize[uiLayerId];
if ( m_uiFrameIdx[uiLayerId] % uiGopSize != 1)
{
frame_num = m_pauiFrameNumInGOP[uiLayerId][m_uiGopSize[uiLayerId]-1] % uiMaxFrameNum;
uiPocLsb = m_pauiPocInGOP[uiLayerId][m_uiGopSize[uiLayerId]-1] % uiMaxPocLsb;
}
else
{
frame_num = m_pauiFrameNumInGOP[uiLayerId][0] % uiMaxFrameNum;
uiPocLsb = m_pauiPocInGOP[uiLayerId][0] % uiMaxPocLsb;
}
// if ( m_uiFrameIdx[uiLayerId] % uiGopSize == 1)
{
frame_num -= (uiGopSize >> 1);
//xk
if ( uiGopSize == 1)
frame_num -= 1;
uiPocLsb -= m_uiMaxGopSize;
}
}
}
if ( frame_num != m_uiNextFrameNum || uiLayerId != m_uiNextLayerId || uiPocLsb != (m_uiNextPoc % uiMaxPocLsb))
{
// judge if the uncompleted GOP
UInt uiFrameIdx = 0;
UInt uiGopSize = 1 << m_uiDecompositionStages[uiLayerId];
// UInt uiGopSize = m_uiGopSize[uiLayerId];
for ( ;uiFrameIdx < uiGopSize; uiFrameIdx++)
{
if ( m_pauiPocInGOP[uiLayerId][uiFrameIdx] % uiMaxPocLsb == uiPocLsb)
break;
}
if ( ( m_pauiFrameNumInGOP[uiLayerId][uiFrameIdx] % uiMaxFrameNum ) == frame_num || (uiPocLsb-1) / m_uiMaxGopSize != ((m_uiNextPoc-1) % uiMaxPocLsb) / m_uiMaxGopSize)
{
if ( m_uiNextLayerId == 0 && m_baseMode == 1)
{
BinData *pcBinData = new BinData;
pcBinData->set( new UChar[11], 11);
// *(pcBinData->data()+0) = NAL_UNIT_VIRTUAL_BASELAYER;
*(pcBinData->data()+0) = NAL_UNIT_CODED_SLICE;
*(Int*)(pcBinData->data()+1) = 0xdeadface;
*(Short*)(pcBinData->data()+5) = (Short) m_uiNextFrameNum;
*(Short*)(pcBinData->data()+7) = (Short) m_uiNextPoc;
*(pcBinData->data()+9) = (UChar) m_uiNextTempLevel;
*(pcBinData->data()+pcBinData->size()-1) = 0;
cVirtualSliceList.pushFront( pcBinData);
}
else
{
BinData *pcBinData = new BinData;
pcBinData->set( new UChar[11], 11);
// *(pcBinData->data()+0) = NAL_UNIT_VIRTUAL_ENHANCELAYER;
*(pcBinData->data()+0) = NAL_UNIT_CODED_SLICE_SCALABLE;
*(Int*)(pcBinData->data()+1) = 0xdeadface;
*(Short*)(pcBinData->data()+5) = (Short)m_uiNextFrameNum;
*(Short*)(pcBinData->data()+7) = (Short)m_uiNextPoc;
*(pcBinData->data()+9) = (UChar) m_uiNextTempLevel;
*(pcBinData->data()+pcBinData->size()-1) = 0;
cVirtualSliceList.pushFront( pcBinData);
m_uiNumOfNALInAU++; //TMM_EC
}
}
else
{
// uncomplete GOP structure
// calculate the gop size of the layer current packet belongs to
if ( uiPocLsb % ( 2<<(m_uiMaxDecompositionStages-m_uiDecompositionStages[uiLayerId])) != 0)
{
m_uiGopSize[uiLayerId] = (((frame_num-1) % (uiGopSize>>1))<< 1) + 1;
}
else
{
UInt uiFrameDiff = ( m_pauiFrameNumInGOP[uiLayerId][uiFrameIdx] % uiMaxFrameNum) - frame_num;
UInt uiTL = m_uiDecompositionStages[uiLayerId];
UInt uiTmp = uiPocLsb >> (m_uiMaxDecompositionStages - m_uiDecompositionStages[uiLayerId]);
while( uiTmp % 2 == 0)
{
uiTmp >>=1;
uiTL--;
}
UInt ui = 0;
for ( ui=m_uiGopSize[uiLayerId]&(-2); ui>0; ui-=2)
{
UInt uiTempLevel = m_uiDecompositionStages[uiLayerId];
uiTmp = ui;
while( uiTmp % 2 == 0)
{
uiTmp >>=1;
uiTempLevel--;
}
if ( uiTL <= uiTempLevel)
{
continue;
}
uiFrameDiff--;
if ( uiFrameDiff == 0)
{
break;
}
}
m_uiGopSize[uiLayerId] = ui - 1;
}
// calculate the gop size of other layers
UInt ui=0;
for ( ui=0; ui<uiLayerId; ui++)
{
m_uiGopSize[ui] = m_uiGopSize[uiLayerId] >> (m_uiDecompositionStages[uiLayerId] - m_uiDecompositionStages[ui]);
}
for ( ui=uiLayerId+1; ui<m_uiNumLayers; ui++)
{
m_uiGopSize[ui] = ( m_uiGopSize[uiLayerId] << (m_uiDecompositionStages[ui] - m_uiDecompositionStages[uiLayerId])) + ((1<<(m_uiDecompositionStages[ui] - m_uiDecompositionStages[uiLayerId])) -1);
}
// calculate the correct frame_num and poc of every packet in this uncompleted gop each layer
m_uiFrameIdx[m_uiNextLayerId]--;
for ( ui=0; ui<m_uiNumLayers; ui++)
{
uiFrameIdx = 0;
UInt uiFrameNum = m_pauiFrameNumInGOP[ui][0];
UInt uiPoc = ( m_uiNextPoc - 1 ) & -(1<<m_uiMaxDecompositionStages);
if ( ui == 0 || m_uiFrameIdx[ui] % (1<<m_uiDecompositionStages[ui]) != 0)
uiFrameNum -= ( 1 << ( m_uiDecompositionStages[ui] - 1 ) );
UInt uiDecompositionStagesSub = m_uiMaxDecompositionStages - m_uiDecompositionStages[ui];
for( UInt uiTemporalLevel = 0; uiTemporalLevel <= m_uiDecompositionStages[ui]; uiTemporalLevel++ )
{
UInt uiStep = ( 1 << ( m_uiDecompositionStages[ui] - uiTemporalLevel ) );
for( UInt uiFrameId = uiStep; uiFrameId <= m_uiGopSize[ui]; uiFrameId += ( uiStep << 1 ) )
{
m_pauiPocInGOP[ui][uiFrameIdx] = (uiFrameId << uiDecompositionStagesSub ) + uiPoc;
m_pauiFrameNumInGOP[ui][uiFrameIdx] = uiFrameNum;
m_pauiTempLevelInGOP[ui][uiFrameIdx] = uiTemporalLevel;
uiFrameIdx++;
if ( uiFrameId % 2 == 0)
uiFrameNum++;
}
}
for ( uiFrameIdx=0; uiFrameIdx<m_uiFrameIdx[ui] % (1<<m_uiDecompositionStages[ui]); uiFrameIdx++)
{
m_pauiPocInGOP[ui][uiFrameIdx] += m_uiMaxGopSize;
m_pauiFrameNumInGOP[ui][uiFrameIdx] += (1<<(m_uiDecompositionStages[ui]-1));
}
}
do
{
if (m_uiFrameIdx[m_uiNextLayerId] % m_uiMaxGopSize < m_uiGopSize[m_uiNextLayerId])
break;
m_uiNextLayerId = (m_uiNextLayerId + 1) % m_uiNumLayers;
}
while( true);
if (m_uiFrameIdx[m_uiNextLayerId] % m_uiMaxGopSize < m_uiGopSize[m_uiNextLayerId])
{
uiMaxFrameNum = 1 << pcSliceHeader->getSPS().getLog2MaxFrameNum();
m_uiNextFrameNum = m_pauiFrameNumInGOP[m_uiNextLayerId][m_uiFrameIdx[m_uiNextLayerId] % uiGopSize] % uiMaxFrameNum;
m_uiNextPoc = m_pauiPocInGOP[m_uiNextLayerId][m_uiFrameIdx[m_uiNextLayerId] % uiGopSize];
m_uiNextTempLevel = m_pauiTempLevelInGOP[m_uiNextLayerId][m_uiFrameIdx[m_uiNextLayerId] % uiGopSize];
// TMM_EC
if ( uiGopSize == 1)
m_pauiFrameNumInGOP[m_uiNextLayerId][m_uiFrameIdx[m_uiNextLayerId] % uiGopSize] += 1 ;
else
m_pauiFrameNumInGOP[m_uiNextLayerId][m_uiFrameIdx[m_uiNextLayerId] % uiGopSize] += 1 << ( m_uiDecompositionStages[m_uiNextLayerId] - 1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -