📄 picencoder.cpp
字号:
{
Int iDiff = *iter - uiCurrReorderNr;
AOF( iDiff );
if( iDiff < 0 )
{
Int iVal = -iDiff - 1;
rcRplrBuffer.set( uiCount++, Rplr( RPLR_NEG, iVal) );
bNeg = true;
iSum += iVal;
}
else
{
Int iVal = iDiff - 1;
rcRplrBuffer.set( uiCount++, Rplr( RPLR_POS, iVal) );
bPos = true;
iSum += iVal;
}
uiCurrReorderNr = *iter;
}
rcRplrBuffer.set( uiCount++, Rplr( RPLR_END ) );
rcRplrBuffer.setRefPicListReorderingFlag( true );
//force temporal RPLR for MVC slices only
if( iSum == 0 && ( bPos == ! bNeg ) && m_bAVCFlag ) // purvin
//&& !m_bForceReOrderingCommands )
{
rcRplrBuffer.clear();
rcRplrBuffer.setRefPicListReorderingFlag( false );
}
return Err::m_nOK;
}
ErrVal
PicEncoder::xGetFrameNumList( FrameSpec& rcFrameSpec, UIntList& rcFrameNumList, ListIdx eLstIdx, UInt uiCurrBasePos )
{
rcFrameNumList.clear();
const UInt uiLevel = rcFrameSpec.getTemporalLayer();
const UInt uiMaxSize = rcFrameSpec.getNumRefIdxActive( eLstIdx );
ROF( uiMaxSize );
// for list1;
if( eLstIdx == LIST_1 )
{
for( Int i = (Int)uiCurrBasePos+1; i <= (Int)m_uiGOPSize; i++ )
{
if( m_acFrameSpecification[i].getTemporalLayer()< uiLevel && m_acFrameSpecification[i].getNalRefIdc()>0)
{
rcFrameNumList.push_back( m_acFrameSpecification[i].getFrameNum() );
if( rcFrameNumList.size() == uiMaxSize )
{
break;
}
}
}
if(rcFrameNumList.size() < uiMaxSize) // maybe not required
{
for( Int i = uiCurrBasePos-1; i >= 0; i-- )
{
if( m_acFrameSpecification[i].getTemporalLayer() < uiLevel && m_acFrameSpecification[i].getNalRefIdc()>0)
{
rcFrameNumList.push_back( m_acFrameSpecification[i].getFrameNum());
if( rcFrameNumList.size() == uiMaxSize )
{
break;
}
}
}
}
}
else // for list0
{
for( Int i = uiCurrBasePos-1; i >= 0; i-- )
{
if( m_acFrameSpecification[i].getTemporalLayer()< uiLevel && m_acFrameSpecification[i].getNalRefIdc()>0)
{
rcFrameNumList.push_back( m_acFrameSpecification[i].getFrameNum() );
if( rcFrameNumList.size() == uiMaxSize )
{
break;
}
}
}
if(rcFrameNumList.size() < uiMaxSize) // maybe not required
{
for( Int i = (Int)uiCurrBasePos+1; i <= (Int)m_uiGOPSize; i++ )
{
if( m_acFrameSpecification[i].getTemporalLayer() < uiLevel && m_acFrameSpecification[i].getNalRefIdc()>0)
{
rcFrameNumList.push_back( m_acFrameSpecification[i].getFrameNum() );
if( rcFrameNumList.size() == uiMaxSize )
{
break;
}
}
}
}
}
ROF( rcFrameNumList.size() == uiMaxSize );
return Err::m_nOK;
}
ErrVal
PicEncoder::xSetRplrAndMmco( FrameSpec& rcFrameSpec )
{
// clear L1 rplr buffer
rcFrameSpec.getRplrBuffer(LIST_1)->setRefPicListReorderingFlag( false );
rcFrameSpec.getRplrBuffer(LIST_1)->clear();
// clear mmco buffer
rcFrameSpec.getMmcoBuffer()->clear();
rcFrameSpec.setAdaptiveRefPicBufferingFlag( false );
UInt uiCurrFrameNr = rcFrameSpec.getFrameNum(); // should be mode by MaxFrameNum
// do it later
const UInt uiMaxFrameNumber = m_uiMaxFrameNum;
// leave if idr
if( rcFrameSpec.isIdrNalUnit())
{
m_cLPFrameNumList.clear();
m_cLPFrameNumList.push_front( uiCurrFrameNr );
return Err::m_nOK;
}
// generate rplr commands
AOT( m_cLPFrameNumList.size() < rcFrameSpec.getNumRefIdxActive( LIST_0 ) );
UIntList cTempList;
UIntList::iterator iter = m_cLPFrameNumList.begin();
for( UInt n = 0; n < rcFrameSpec.getNumRefIdxActive( LIST_0 ); n++ )
{
cTempList.push_back( *iter++ );
}
xSetRplr( *rcFrameSpec.getRplrBuffer(LIST_0), cTempList, uiCurrFrameNr );
// calculate number of mmco commands
const Int iDiffA = m_cLPFrameNumList.front() - uiCurrFrameNr;
UInt uiDiffA = ( uiMaxFrameNumber - iDiffA ) % uiMaxFrameNumber;
// generate mmco commands for inter b frames
UInt uiPos = 0;
while( --uiDiffA )
{
rcFrameSpec.getMmcoBuffer()->set( uiPos++, Mmco( MMCO_SHORT_TERM_UNUSED, uiDiffA-1 ) );
}
// generate mmco command for high-pass frame
UInt uiNeedLowPassBefore = max( 1, rcFrameSpec.getNumRefIdxActive( LIST_0 ) );
if( m_cLPFrameNumList.size() > uiNeedLowPassBefore )
{
const Int iDiffB = m_cLPFrameNumList.popBack() - uiCurrFrameNr;
UInt uiDiffB = ( uiMaxFrameNumber - iDiffB ) % uiMaxFrameNumber;
rcFrameSpec.getMmcoBuffer()->set( uiPos++, Mmco( MMCO_SHORT_TERM_UNUSED, uiDiffB-1 ) );
}
// end of command list
if ( uiPos )
{
rcFrameSpec.getMmcoBuffer()->set( uiPos, Mmco( MMCO_END) );
rcFrameSpec.setAdaptiveRefPicBufferingFlag( true );
}
else
rcFrameSpec.setAdaptiveRefPicBufferingFlag( false );
// insert frame_num
m_cLPFrameNumList.push_front( uiCurrFrameNr );
return Err::m_nOK;
}
ErrVal
PicEncoder::xInitReordering ( UInt uiFrameIdInGOP )
{
FrameSpec * pcFrameSpec=&m_acFrameSpecification[uiFrameIdInGOP];
// JVT-V043
//===== set RPLR and MMCO =====
if( pcFrameSpec->getTemporalLayer() == m_uiMinTempLevelLastGOP && pcFrameSpec->getNalRefIdc()>0 ) // change 0 to m_uiMinTempLevelLastGOP
{
//===== low-pass frames =====
RNOK( xSetRplrAndMmco( *pcFrameSpec ) );
m_uiMinTempLevelLastGOP = 0; // change back
}
else
{
UIntList cFrameNumList;
pcFrameSpec->getMmcoBuffer()->clear();
pcFrameSpec->setAdaptiveRefPicBufferingFlag( false );
if( pcFrameSpec->getSliceType() == B_SLICE )
{
// RefPicList0
if ( m_pcSPSMVCExt->getNumRefsForListX(m_CurrentViewId, LIST_0, pcFrameSpec->isAnchor() ) > 0 )
{
RNOK( xGetFrameNumList( *pcFrameSpec, cFrameNumList, LIST_0, uiFrameIdInGOP ) );
RNOK( xSetRplr ( *pcFrameSpec->getRplrBuffer(LIST_0), cFrameNumList, pcFrameSpec->getFrameNum()) );
}
else
{
pcFrameSpec->getRplrBuffer( LIST_0 )->clear();
pcFrameSpec->getRplrBuffer( LIST_0 )->setRefPicListReorderingFlag( false );
}
// RefPicList1
if ( m_pcSPSMVCExt->getNumRefsForListX(m_CurrentViewId, LIST_1, pcFrameSpec->isAnchor()) > 0 )
{
RNOK( xGetFrameNumList( *pcFrameSpec, cFrameNumList, LIST_1, uiFrameIdInGOP ) );
RNOK( xSetRplr ( *pcFrameSpec->getRplrBuffer(LIST_1), cFrameNumList, pcFrameSpec->getFrameNum() ) );
}
else
{
pcFrameSpec->getRplrBuffer( LIST_1 )->clear();
pcFrameSpec->getRplrBuffer( LIST_1 )->setRefPicListReorderingFlag( false );
}
}
else if ( pcFrameSpec->getSliceType() == P_SLICE )
{
// ROF( pcFrameSpec->getSliceType() == P_SLICE );
// bug fix for num_ref_active_minus1 equal to 0.
RNOK( xGetFrameNumList( *pcFrameSpec, cFrameNumList, LIST_0, uiFrameIdInGOP ) );
RNOK( xSetRplr ( *pcFrameSpec->getRplrBuffer(LIST_0), cFrameNumList, pcFrameSpec->getFrameNum() ) );
pcFrameSpec->getRplrBuffer( LIST_1 )->clear();
pcFrameSpec->getRplrBuffer( LIST_1 )->setRefPicListReorderingFlag( false );
}
else
{
pcFrameSpec->getRplrBuffer( LIST_0 )->clear();
pcFrameSpec->getRplrBuffer( LIST_0 )->setRefPicListReorderingFlag( false );
pcFrameSpec->getRplrBuffer( LIST_1 )->clear();
pcFrameSpec->getRplrBuffer( LIST_1 )->setRefPicListReorderingFlag( false );
}
}
return Err::m_nOK;
}
ErrVal
PicEncoder::xGetListSizesSpecial ( UInt uiTemporalLevel,
UInt uiFrameIdInGOP,
UInt auiPredListSize[2])
{
// do not consider the delay as input
auiPredListSize[0] = 0;
auiPredListSize[1] = 0;
Int iPocInGOP;
for( iPocInGOP = (Int) (uiFrameIdInGOP-1); iPocInGOP>= 0 ; iPocInGOP-- )
{
if(m_acFrameSpecification[iPocInGOP].getTemporalLayer()<uiTemporalLevel && m_acFrameSpecification[iPocInGOP].getNalRefIdc())
{
auiPredListSize[0]++;
}
}
for( iPocInGOP = (Int) uiFrameIdInGOP+1; iPocInGOP<= (Int) m_uiGOPSize; iPocInGOP++ )
{
if(m_acFrameSpecification[iPocInGOP].getTemporalLayer()<uiTemporalLevel && m_acFrameSpecification[iPocInGOP].getNalRefIdc())
{
auiPredListSize[1]++;
}
}
UInt uiMaxNumActiveList0 = m_uiMaxNumRefFrames - min(m_uiMaxNumRefFrames, m_uiNonAncNumFwdViewRef);
UInt uiMaxNumActiveList1 = m_uiMaxNumRefFrames - min(m_uiMaxNumRefFrames, m_uiNonAncNumBwdViewRef);
// for anchor pictures these values shall be 0 anyway
auiPredListSize[0] = min( uiMaxNumActiveList0, auiPredListSize[0] );
auiPredListSize[1] = min( uiMaxNumActiveList1, auiPredListSize[1] );
return Err::m_nOK;
}
ErrVal
PicEncoder::xGetListSizes ( UInt uiTemporalLevel,
UInt uiFrameIdInGOP,
UInt auiPredListSize[2])
{
//----- get delay decomposition stages -----
UInt uiDelayDecompositionStages = 0;
for( ; m_uiFrameDelay >> uiDelayDecompositionStages; uiDelayDecompositionStages++ );
uiDelayDecompositionStages = min( m_uiMaxTL, uiDelayDecompositionStages );
//----- loop over prediction and update steps -----
for( UInt uiLevel = uiTemporalLevel; uiLevel <= m_uiMaxTL; uiLevel++ )
{
//----- get parameters base GOP size and cut-off frame id -----
UInt uiBaseLevel = m_uiMaxTL - uiLevel;
UInt uiFrameIdLevel = uiFrameIdInGOP >> uiBaseLevel;
UInt uiBaseGOPSize = ( 1 << uiDelayDecompositionStages ) >> min( uiBaseLevel, uiDelayDecompositionStages );
UInt uiCutOffFrame = max( 0, Int( uiBaseGOPSize - ( m_uiFrameDelay >> uiBaseLevel ) - 1 ) );
if( uiLevel == uiTemporalLevel )
{
//=========== PREDICTION LIST SIZES ==========
auiPredListSize[0] = ( uiFrameIdLevel + 1 ) >> 1;
UInt uiFrameIdWrap = ( uiFrameIdLevel % uiBaseGOPSize );
if( uiFrameIdWrap > uiCutOffFrame )
{
auiPredListSize[1] = ( uiBaseGOPSize - uiFrameIdWrap + 1 ) >> 1;
}
else
{
auiPredListSize[1] = ( uiCutOffFrame - uiFrameIdWrap + 1 ) >> 1;
}
UInt uiMaxNumActiveList0 = m_uiMaxNumRefFrames - min(m_uiMaxNumRefFrames, m_uiNonAncNumFwdViewRef);
UInt uiMaxNumActiveList1 = m_uiMaxNumRefFrames - min(m_uiMaxNumRefFrames, m_uiNonAncNumBwdViewRef);
// for anchor pictures these values shall be 0 anyway
auiPredListSize[0] = min( uiMaxNumActiveList0, auiPredListSize[0] );
auiPredListSize[1] = min( uiMaxNumActiveList1, auiPredListSize[1] );
//----- take into account actual GOP size -----
{
UInt uiMaxL1Size = ( ( m_uiGOPSize >> uiBaseLevel ) + 1 - uiFrameIdLevel ) >> 1;
auiPredListSize[1] = min( uiMaxL1Size, auiPredListSize[1] );
}
}
}
UInt uiCurrFrame = ( m_uiAnchorFrameNumber) + uiFrameIdInGOP;
UInt uiIntraPeriod = m_vFramePeriod;
if( ( uiCurrFrame % uiIntraPeriod ) == 0 )
{
auiPredListSize[0] = 0;
auiPredListSize[1] = 0;
}
return Err::m_nOK;
}
ErrVal
PicEncoder::xInitReorderingInterView (SliceHeader*& rpcSliceHeader)
{
SliceType eSliceType = rpcSliceHeader->getSliceType();
SpsMvcExtension * pcSPSMVC = m_pcSPS->getSpsMVC();
UInt uiCurrViewId = rpcSliceHeader->getViewId();
Bool bAnchor = rpcSliceHeader->getAnchorPicFlag();
UInt uiMaxLists = ( eSliceType == B_SLICE ? 2 : eSliceType == P_SLICE ? 1 : 0 );
Bool bInterPredFirst = m_bInterPridPicsFirst;
UInt uiIdentifier = 0;
UInt uiCommand = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -