📄 picencoder.cpp
字号:
RNOK( m_pcNalUnitEncoder->closeNalUnit( uiPPSBits ) );
m_uiWrittenBytes += ( ( uiPPSBits >> 3 ) + 4 );
m_adMVCSeqBits[0] += uiPPSBits; //SEI
//===== init pic encoder with parameter sets =====
RNOK( xInitParameterSets() );
}
//===== set status =====
rbMoreSets = ! m_bInitParameterSets;
return Err::m_nOK;
}
// ying {{ new configuration file
ErrVal
PicEncoder::xInitFrameSpecSpecial() // for 12 and 15 only
{
UInt uiFrameNumInGOP=1;
UInt auiPredListSize[2];
if(m_uiGOPSize==12)
{
m_acFrameSpecification[12].init('I',uiFrameNumInGOP++,12,0);
m_acFrameSpecification[ 6].init('B',uiFrameNumInGOP++, 6,1);
m_acFrameSpecification[ 3].init('B',uiFrameNumInGOP++, 3,2);
m_acFrameSpecification[ 9].init('B',uiFrameNumInGOP++, 9,2);
m_acFrameSpecification[ 2].init('B',uiFrameNumInGOP++, 2,3);
m_acFrameSpecification[ 5].init('B',uiFrameNumInGOP++, 5,3);
m_acFrameSpecification[ 8].init('B',uiFrameNumInGOP++, 8,3);
m_acFrameSpecification[11].init('B',uiFrameNumInGOP++,11,3);
m_acFrameSpecification[ 1].init('b',uiFrameNumInGOP , 1,4);
m_acFrameSpecification[ 4].init('b',uiFrameNumInGOP , 4,4);
m_acFrameSpecification[ 7].init('b',uiFrameNumInGOP , 7,4);
m_acFrameSpecification[10].init('b',uiFrameNumInGOP ,10,4);
m_acFrameSpecification[12].updateAnchor(m_pcCodingParameter->getIntraPeriod());
}
else if (m_uiGOPSize==15)
{
m_acFrameSpecification[15].init('I',uiFrameNumInGOP++,15,0);
m_acFrameSpecification[ 8].init('B',uiFrameNumInGOP++, 8,1);
m_acFrameSpecification[ 4].init('B',uiFrameNumInGOP++, 4,2);
m_acFrameSpecification[12].init('B',uiFrameNumInGOP++,12,2);
m_acFrameSpecification[ 2].init('B',uiFrameNumInGOP++, 2,3);
m_acFrameSpecification[ 6].init('B',uiFrameNumInGOP++, 6,3);
m_acFrameSpecification[10].init('B',uiFrameNumInGOP++,10,3);
m_acFrameSpecification[14].init('B',uiFrameNumInGOP++,14,3);
m_acFrameSpecification[ 1].init('b',uiFrameNumInGOP , 1,4);
m_acFrameSpecification[ 3].init('b',uiFrameNumInGOP , 3,4);
m_acFrameSpecification[ 5].init('b',uiFrameNumInGOP , 5,4);
m_acFrameSpecification[ 7].init('b',uiFrameNumInGOP , 7,4);
m_acFrameSpecification[ 9].init('b',uiFrameNumInGOP , 9,4);
m_acFrameSpecification[11].init('b',uiFrameNumInGOP ,11,4);
m_acFrameSpecification[13].init('b',uiFrameNumInGOP ,13,4);
m_acFrameSpecification[15].updateAnchor(m_pcCodingParameter->getIntraPeriod());
}
//put the code together
for(UInt uiFrame = 1 ; uiFrame <= m_uiGOPSize; uiFrame++ )
{
xGetListSizesSpecial( m_acFrameSpecification[uiFrame].getTemporalLayer(), uiFrame, auiPredListSize);
m_acFrameSpecification[uiFrame].setNumRefIdxActive( LIST_0, auiPredListSize[0]);
m_acFrameSpecification[uiFrame].setNumRefIdxActive( LIST_1, auiPredListSize[1]);
SliceType eSliceType = ( auiPredListSize[1] ? B_SLICE : auiPredListSize[0] ? P_SLICE : I_SLICE );
m_acFrameSpecification[uiFrame].setSliceType(eSliceType);
}
return Err::m_nOK;
}
ErrVal
PicEncoder::xInitFrameSpecHierarchical()
{
UInt uiFrameNumInGOP=1;
UInt uiTemporalLevel;
UInt auiPredListSize[2];
for( uiTemporalLevel = 0; uiTemporalLevel <= m_uiMaxTL; uiTemporalLevel++ )
{
UInt uiStep = ( 1 << ( m_uiMaxTL - uiTemporalLevel ) );
for( UInt uiFrameId = uiStep; uiFrameId <= m_uiGOPSize; uiFrameId += ( uiStep << 1 ) )
{
UChar ucType;
if(uiTemporalLevel==0) ucType = 'I';
else if(uiTemporalLevel==m_uiMaxTL) ucType = 'b';
else ucType = 'B';
m_acFrameSpecification[uiFrameId].init(ucType, uiFrameNumInGOP, uiFrameId, uiTemporalLevel );
if (m_acFrameSpecification[uiFrameId].getNalRefIdc()) uiFrameNumInGOP++;
if (uiTemporalLevel==0) m_acFrameSpecification[uiFrameId].updateAnchor(m_pcCodingParameter->getIntraPeriod());
//put the code together
xGetListSizes ( uiTemporalLevel, uiFrameId, auiPredListSize);
m_acFrameSpecification[uiFrameId].setNumRefIdxActive( LIST_0, auiPredListSize[0]);
m_acFrameSpecification[uiFrameId].setNumRefIdxActive( LIST_1, auiPredListSize[1]);
SliceType eSliceType = ( auiPredListSize[1] ? B_SLICE : auiPredListSize[0] ? P_SLICE : I_SLICE );
m_acFrameSpecification[uiFrameId].setSliceType(eSliceType);
}
}
return Err::m_nOK;
}
ErrVal
PicEncoder::xInitFrameSpec()
{
m_uiGOPSizeReal = m_pcCodingParameter->getGOPSize();
m_uiTotalFrames = m_pcCodingParameter->getTotalFrames();
m_uiMaxTL = m_pcCodingParameter->getDecompositionStages();
m_uiMaxNumRefFrames = m_pcCodingParameter->getNumRefFrames();
m_pcSPSMVCExt = &m_pcCodingParameter->SpsMVC;
m_uiFrameDelay = (UInt) m_pcCodingParameter->getMaximumDelay();
m_uiMaxFrameNum = (1 << m_pcCodingParameter->getLog2MaxFrameNum());
m_uiAnchorFrameNumber = 0;
m_CurrentViewId = m_pcCodingParameter->getCurentViewId();
// m_ViewLevel = m_pcCodingParameter->getViewLevel(); JVT-W035
m_bAVCFlag = m_pcCodingParameter->getAVCFlag();
m_SvcMvcFlag = (m_pcCodingParameter->getMVCmode()!=0 );
m_bInterPridPicsFirst = m_pcCodingParameter->getInterPredPicsFirst()!=0; // JVT-V043 encoder
// with some assumption, can be modified later
m_uiAnchorNumFwdViewRef = m_pcSPSMVCExt->getNumAnchorRefsForListX(getViewId(), LIST_0);
m_uiAnchorNumBwdViewRef = m_pcSPSMVCExt->getNumAnchorRefsForListX(getViewId(), LIST_1);
m_uiNonAncNumFwdViewRef = m_pcSPSMVCExt->getNumNonAnchorRefsForListX(getViewId(), LIST_0);
m_uiNonAncNumBwdViewRef = m_pcSPSMVCExt->getNumNonAnchorRefsForListX(getViewId(), LIST_1);
m_vFramePeriod = m_pcCodingParameter->getIntraPeriod();
//m_bCompleteGOP = m_uiTotalFrames< (m_uiGOPSize +1) ? false : true ;
m_bSpecialGOP = false;
UInt uiFrameNumInGOP=0;
// UInt uiTemporalLevel;
// UInt auiPredListSize[2];
if(m_uiTotalFrames< (m_uiGOPSizeReal +1) ) m_uiGOPSize = m_uiTotalFrames -1;
else m_uiGOPSize= m_uiGOPSizeReal;
m_acFrameSpecification[uiFrameNumInGOP++].init('A', 0, 0, 0);
// complete GOP 12 (15)
if( (m_uiGOPSizeReal==12 || m_uiGOPSizeReal==15) && m_uiGOPSize == m_uiGOPSizeReal)
{
m_bSpecialGOP = true;
m_uiGOPSizeReal = m_uiGOPSize;
RNOK(xInitFrameSpecSpecial());
}
else
{
RNOK(xInitFrameSpecHierarchical());
}
m_uiMinTempLevelLastGOP =0; // to save dpb a fix here March 20
for(UInt uiFrame = 0 ; uiFrame <= m_uiGOPSize; uiFrame++ )
{
RNOK( xInitReordering( uiFrame ) );
}
m_cFrameSpecification.copy( m_acFrameSpecification[0] );
m_uiProcessingPocInGOP =0;
return Err::m_nOK;
}
ErrVal
PicEncoder::xGetNextFrameSpecSpecial()
{
return Err::m_nOK;
}
ErrVal
PicEncoder::xGetNextFrameSpec()
{
if( m_uiProcessingPocInGOP ==0 )
// the key picture is coded
{
// for GOPSize 12 and 15 when the GOP is complete
if(m_bSpecialGOP && m_uiGOPSizeReal == m_uiGOPSize)
{
m_uiProcessingPocInGOP=m_uiGOPSizeReal;
m_cFrameSpecification.copy( m_acFrameSpecification[m_uiProcessingPocInGOP] );
return Err::m_nOK;
}
// for all other cases: GOPSize is 2^n or the uncompleted GOP
for(UInt templevel=0; templevel<=m_uiMaxTL; templevel++)
{
UInt uiStartNumTL = 1<<(m_uiMaxTL-templevel);
if( uiStartNumTL <=m_uiGOPSize)
{
m_uiProcessingPocInGOP = uiStartNumTL;
m_cFrameSpecification.copy( m_acFrameSpecification[m_uiProcessingPocInGOP] );
return Err::m_nOK;
}
}
}
//at the end of a complete GOP for hierarchical B
if( m_uiProcessingPocInGOP == (1<<m_uiMaxTL) -1 && m_uiProcessingPocInGOP!=m_uiGOPSize)
{
// others
xUpdateFrameSepNextGOP();
m_uiProcessingPocInGOP=0;
return xGetNextFrameSpec();
}
//at the end of a complete special GOP
if(m_bSpecialGOP && m_acFrameSpecification [m_uiProcessingPocInGOP].getTemporalLayer()==m_uiMaxTL && m_uiProcessingPocInGOP + 2 >=m_uiGOPSizeReal )
{
// others
xUpdateFrameSepNextGOP();
m_uiProcessingPocInGOP=0;
return xGetNextFrameSpec();
}
// other cases
// for hierarchical B and the uncompleted GOP /////////////////////////
if(!m_bSpecialGOP || m_uiGOPSizeReal > m_uiGOPSize )
{
UInt uiStep = ( 1 << ( m_uiMaxTL - m_acFrameSpecification[m_uiProcessingPocInGOP].getTemporalLayer() ) );
UInt uiNextFrameIdInGOP = (uiStep<<1)+m_uiProcessingPocInGOP;
if (uiNextFrameIdInGOP>m_uiGOPSize || (uiNextFrameIdInGOP == (1 <<m_uiMaxTL) ))
{
m_uiProcessingPocInGOP = (uiStep >>1);
}
else
{
m_uiProcessingPocInGOP = uiNextFrameIdInGOP;
}
}
// for hierarchical B and the uncompleted GOP /////////////////////////
else // for the completed special GOP
{
Bool bFindInSameTL=false;
UInt uiCurrTL =m_acFrameSpecification[m_uiProcessingPocInGOP].getTemporalLayer();
for(UInt uiPocInGOP= m_uiProcessingPocInGOP+1; uiPocInGOP< m_uiGOPSize; uiPocInGOP++)
if( m_acFrameSpecification[uiPocInGOP].getTemporalLayer() == uiCurrTL)
{
m_uiProcessingPocInGOP = uiPocInGOP;
bFindInSameTL=true;
break;
}
if(!bFindInSameTL)
for(UInt i=0; i< m_uiGOPSize; i++)
if( m_acFrameSpecification[i].getTemporalLayer() == uiCurrTL+1)
{
m_uiProcessingPocInGOP =i; break;
}
}
m_cFrameSpecification.copy( m_acFrameSpecification[m_uiProcessingPocInGOP] );
return Err::m_nOK;
}
ErrVal
PicEncoder::xUpdateFrameSepNextGOPFinish()
{
UInt uiFrameNumStart = m_acFrameSpecification[1].getFrameNum();
// bug fix
// assume that the [1] frame is the highest temporal level frame and always has the
// lagest frame_num of the previous GOP. Or we can search the largets frame_num
UInt uiContFrameNumStart = m_acFrameSpecification[m_uiGOPSize].getContFrameNumber();
m_uiGOPSize=m_uiTotalFrames-m_uiAnchorFrameNumber-1;
if ( m_uiGOPSize==0) return Err::m_nOK;
UInt uiTemporalLevel;
UInt auiPredListSize[2];
m_uiMinTempLevelLastGOP = m_uiMaxTL; // to save dpb
for( uiTemporalLevel = 0; uiTemporalLevel <= m_uiMaxTL; uiTemporalLevel++ )
{
UInt uiStep = ( 1 << ( m_uiMaxTL - uiTemporalLevel ) );
for( UInt uiFrameId = uiStep; uiFrameId <= m_uiGOPSize; uiFrameId += ( uiStep << 1 ) )
{
UChar ucType;
if(uiTemporalLevel==0) ucType = 'I';
else if(uiTemporalLevel==m_uiMaxTL) ucType = 'b';
else ucType = 'B';
m_acFrameSpecification[uiFrameId].init(ucType, uiFrameNumStart, uiFrameId, uiTemporalLevel );
m_acFrameSpecification[uiFrameId].updateNumbers(0, uiContFrameNumStart, m_uiMaxFrameNum);
// update frame_num and framenumcon
if (m_acFrameSpecification[uiFrameId].getNalRefIdc()) uiFrameNumStart++;
if (uiTemporalLevel==0) m_acFrameSpecification[uiFrameId].updateAnchor(m_pcCodingParameter->getIntraPeriod());
//put the code together
xGetListSizes ( uiTemporalLevel, uiFrameId, auiPredListSize);
m_acFrameSpecification[uiFrameId].setNumRefIdxActive( LIST_0, auiPredListSize[0]);
m_acFrameSpecification[uiFrameId].setNumRefIdxActive( LIST_1, auiPredListSize[1]);
SliceType eSliceType = ( auiPredListSize[1] ? B_SLICE : auiPredListSize[0] ? P_SLICE : I_SLICE );
m_acFrameSpecification[uiFrameId].setSliceType(eSliceType);
if (uiTemporalLevel< m_uiMinTempLevelLastGOP ) m_uiMinTempLevelLastGOP = uiTemporalLevel; // to save dpb
}
}
for(UInt uiFrame = 1 ; uiFrame <= m_uiGOPSize; uiFrame++ )
{
RNOK( xInitReordering( uiFrame ) );
}
m_uiAnchorFrameNumber = m_uiTotalFrames -1;
return Err::m_nOK;
}
ErrVal
PicEncoder::xUpdateFrameSepNextGOP()
{
m_uiAnchorFrameNumber+=m_uiGOPSize;
m_acFrameSpecification[0].copy(m_acFrameSpecification[m_uiGOPSize]);
if( m_uiAnchorFrameNumber+1>=m_uiTotalFrames ) // bug fix 30 Dec 2006
//end coding
{
return Err::m_nOK;
}
if( m_uiAnchorFrameNumber+m_uiGOPSize+1 > m_uiTotalFrames)
//reach the uncomplete GOP
{
return xUpdateFrameSepNextGOPFinish();
}
// usually periodic GOP
UInt uiFrameNumGap = m_uiGOPSize>1 ? m_uiGOPSize/2: m_uiGOPSize ; // works only for hierarchical
// update for special GOP
if(m_bSpecialGOP) uiFrameNumGap = 1 << (m_uiMaxTL-1);
UInt auiPredListSize[2];
const UInt uiMaxFrameNumber = m_uiMaxFrameNum;
// m_uiFrameNum + = uiFrameNumGap;
// if ( m_uiFrameNum >
for(UInt i=1; i<=m_uiGOPSize; i++)
m_acFrameSpecification[i].updateNumbers( uiFrameNumGap, m_uiGOPSize, uiMaxFrameNumber );
m_acFrameSpecification[m_uiGOPSize].updateAnchor(m_pcCodingParameter->getIntraPeriod());
//put the code together
if (!m_bSpecialGOP )
xGetListSizes ( 0, m_uiGOPSize, auiPredListSize);
else
xGetListSizesSpecial( 0, m_uiGOPSize, auiPredListSize);
m_acFrameSpecification[m_uiGOPSize].setNumRefIdxActive( LIST_0, auiPredListSize[0]);
m_acFrameSpecification[m_uiGOPSize].setNumRefIdxActive( LIST_1, auiPredListSize[1]);
for(UInt uiFrame = 1 ; uiFrame <= m_uiGOPSize; uiFrame++ )
{
RNOK( xInitReordering( uiFrame ) );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -