您的位置:首页 > 编程语言

HEVC代码追踪(四。二)

2014-11-26 11:11 155 查看
/////////////////////////////////////////////////////////////////////////////////////////////////// Compress a slice
//  Slice compression
if (m_pcCfg->getUseASR())
{
m_pcSliceEncoder->setSearchRange(pcSlice);
}

Bool bGPBcheck=false;
if ( pcSlice->getSliceType() == B_SLICE)
{
if ( pcSlice->getNumRefIdx(RefPicList( 0 ) ) == pcSlice->getNumRefIdx(RefPicList( 1 ) ) )
{
bGPBcheck=true;
Int i;
for ( i=0; i < pcSlice->getNumRefIdx(RefPicList( 1 ) ); i++ )
{
if ( pcSlice->getRefPOC(RefPicList(1), i) != pcSlice->getRefPOC(RefPicList(0), i) )
{
bGPBcheck=false;
break;
}
}
}
}
if(bGPBcheck)
{
pcSlice->setMvdL1ZeroFlag(true);
}
else
{
pcSlice->setMvdL1ZeroFlag(false);
}
pcPic->getSlice(pcSlice->getSliceIdx())->setMvdL1ZeroFlag(pcSlice->getMvdL1ZeroFlag());
码率控制:对每一幅picture需要用到的相关参数进行初始化
Double lambda            = 0.0;
Int actualHeadBits       = 0;
Int actualTotalBits      = 0;
Int estimatedBits        = 0;
Int tmpBitsBeforeWriting = 0;
if ( m_pcCfg->getUseRateCtrl() )
{
Int frameLevel = m_pcRateCtrl->getRCSeq()->getGOPID2Level( iGOPid );
if ( pcPic->getSlice(0)->getSliceType() == I_SLICE )
{
frameLevel = 0;
}
m_pcRateCtrl->initRCPic( frameLevel );
estimatedBits = m_pcRateCtrl->getRCPic()->getTargetBits();

Int sliceQP = m_pcCfg->getInitialQP();
if ( ( pcSlice->getPOC() == 0 && m_pcCfg->getInitialQP() > 0 ) || ( frameLevel == 0 && m_pcCfg->getForceIntraQP() ) ) // QP is specified
{
Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)NumberBFrames );
Double dQPFactor     = 0.57*dLambda_scale;
Int    SHIFT_QP      = 12;
Int    bitdepth_luma_qp_scale = 0;
Double qp_temp = (Double) sliceQP + bitdepth_luma_qp_scale - SHIFT_QP;
lambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
}
else if ( frameLevel == 0 )   // intra case, but use the model
{
m_pcSliceEncoder->calCostSliceI(pcPic);
if ( m_pcCfg->getIntraPeriod() != 1 )   // do not refine allocated bits for all intra case
{
Int bits = m_pcRateCtrl->getRCSeq()->getLeftAverageBits();
bits = m_pcRateCtrl->getRCPic()->getRefineBitsForIntra( bits );
if ( bits < 200 )
{
bits = 200;
}
m_pcRateCtrl->getRCPic()->setTargetBits( bits );
}

list<TEncRCPic*> listPreviousPicture = m_pcRateCtrl->getPicList();
m_pcRateCtrl->getRCPic()->getLCUInitTargetBits();
lambda  = m_pcRateCtrl->getRCPic()->estimatePicLambda( listPreviousPicture, pcSlice->getSliceType());
sliceQP = m_pcRateCtrl->getRCPic()->estimatePicQP( lambda, listPreviousPicture );
}
else    // normal case
{
list<TEncRCPic*> listPreviousPicture = m_pcRateCtrl->getPicList();
lambda  = m_pcRateCtrl->getRCPic()->estimatePicLambda( listPreviousPicture, pcSlice->getSliceType());
sliceQP = m_pcRateCtrl->getRCPic()->estimatePicQP( lambda, listPreviousPicture );
}

sliceQP = Clip3( -pcSlice->getSPS()->getQpBDOffsetY(), MAX_QP, sliceQP );
m_pcRateCtrl->getRCPic()->setPicEstQP( sliceQP );

m_pcSliceEncoder->resetQP( pcPic, sliceQP, lambda );
}


/*Slice Compression部分*/
UInt uiNumSlices = 1;

UInt uiInternalAddress = pcPic->getNumPartInCU()-4;//CU内部Zscan顺序
UInt uiExternalAddress = pcPic->getPicSym()->getNumberOfCUsInFrame()-1;//CU相对于整帧图像的位置
UInt uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];//CU的绝对位置
UInt uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
while(uiPosX>=uiWidth||uiPosY>=uiHeight)
{
uiInternalAddress--;
uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
}
uiInternalAddress++;
if(uiInternalAddress==pcPic->getNumPartInCU())
{
uiInternalAddress = 0;
uiExternalAddress++;
}
UInt uiRealEndAddress = uiExternalAddress*pcPic->getNumPartInCU()+uiInternalAddress;

Int  p, j;
UInt uiEncCUAddr;

pcPic->getPicSym()->initTiles(pcSlice->getPPS());

// Allocate some coders, now we know how many tiles there are.
Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();

//generate the Coding Order Map and Inverse Coding Order Map
for(p=0, uiEncCUAddr=0; p<pcPic->getPicSym()->getNumberOfCUsInFrame(); p++, uiEncCUAddr = pcPic->getPicSym()->xCalculateNxtCUAddr(uiEncCUAddr))
{
pcPic->getPicSym()->setCUOrderMap(p, uiEncCUAddr);
pcPic->getPicSym()->setInverseCUOrderMap(uiEncCUAddr, p);
}
pcPic->getPicSym()->setCUOrderMap(pcPic->getPicSym()->getNumberOfCUsInFrame(), pcPic->getPicSym()->getNumberOfCUsInFrame());
pcPic->getPicSym()->setInverseCUOrderMap(pcPic->getPicSym()->getNumberOfCUsInFrame(), pcPic->getPicSym()->getNumberOfCUsInFrame());

// Allocate some coders, now we know how many tiles there are.
m_pcEncTop->createWPPCoders(iNumSubstreams);
pcSbacCoders = m_pcEncTop->getSbacCoders();
pcSubstreamsOut = new TComOutputBitstream[iNumSubstreams];

UInt startCUAddrSliceIdx = 0; // used to index "m_uiStoredStartCUAddrForEncodingSlice" containing locations of slice boundaries
UInt startCUAddrSlice    = 0; // used to keep track of current slice's starting CU addr.
pcSlice->setSliceCurStartCUAddr( startCUAddrSlice ); // Setting "start CU addr" for current slice
m_storedStartCUAddrForEncodingSlice.clear();

UInt startCUAddrSliceSegmentIdx = 0; // used to index "m_uiStoredStartCUAddrForEntropyEncodingSlice" containing locations of slice boundaries
UInt startCUAddrSliceSegment    = 0; // used to keep track of current Dependent slice's starting CU addr.
pcSlice->setSliceSegmentCurStartCUAddr( startCUAddrSliceSegment ); // Setting "start CU addr" for current Dependent slice

m_storedStartCUAddrForEncodingSliceSegment.clear();
UInt nextCUAddr = 0;
m_storedStartCUAddrForEncodingSlice.push_back (nextCUAddr);
startCUAddrSliceIdx++;
m_storedStartCUAddrForEncodingSliceSegment.push_back(nextCUAddr);
startCUAddrSliceSegmentIdx++;


while(nextCUAddr<uiRealEndAddress) // determine slice boundaries
{
pcSlice->setNextSlice       ( false );
pcSlice->setNextSliceSegment( false );
assert(pcPic->getNumAllocatedSlice() == startCUAddrSliceIdx);
m_pcSliceEncoder->precompressSlice( pcPic );
m_pcSliceEncoder->compressSlice   ( pcPic );

Bool bNoBinBitConstraintViolated = (!pcSlice->isNextSlice() && !pcSlice->isNextSliceSegment());
if (pcSlice->isNextSlice() || (bNoBinBitConstraintViolated && m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU))
{
startCUAddrSlice = pcSlice->getSliceCurEndCUAddr();
// Reconstruction slice
m_storedStartCUAddrForEncodingSlice.push_back(startCUAddrSlice);
startCUAddrSliceIdx++;
// Dependent slice
if (startCUAddrSliceSegmentIdx>0 && m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx-1] != startCUAddrSlice)
{
m_storedStartCUAddrForEncodingSliceSegment.push_back(startCUAddrSlice);
startCUAddrSliceSegmentIdx++;
}

if (startCUAddrSlice < uiRealEndAddress)
{
pcPic->allocateNewSlice();
pcPic->setCurrSliceIdx                  ( startCUAddrSliceIdx-1 );
m_pcSliceEncoder->setSliceIdx           ( startCUAddrSliceIdx-1 );
pcSlice = pcPic->getSlice               ( startCUAddrSliceIdx-1 );
pcSlice->copySliceInfo                  ( pcPic->getSlice(0)      );
pcSlice->setSliceIdx                    ( startCUAddrSliceIdx-1 );
pcSlice->setSliceCurStartCUAddr         ( startCUAddrSlice      );
pcSlice->setSliceSegmentCurStartCUAddr  ( startCUAddrSlice      );
pcSlice->setSliceBits(0);
uiNumSlices ++;
}
}
else if (pcSlice->isNextSliceSegment() || (bNoBinBitConstraintViolated && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU))
{
startCUAddrSliceSegment                                                     = pcSlice->getSliceSegmentCurEndCUAddr();
m_storedStartCUAddrForEncodingSliceSegment.push_back(startCUAddrSliceSegment);
startCUAddrSliceSegmentIdx++;
pcSlice->setSliceSegmentCurStartCUAddr( startCUAddrSliceSegment );
}
else
{
startCUAddrSlice                                                            = pcSlice->getSliceCurEndCUAddr();
startCUAddrSliceSegment                                                     = pcSlice->getSliceSegmentCurEndCUAddr();
}

nextCUAddr = (startCUAddrSlice > startCUAddrSliceSegment) ? startCUAddrSlice : startCUAddrSliceSegment;
}
m_storedStartCUAddrForEncodingSlice.push_back( pcSlice->getSliceCurEndCUAddr());
startCUAddrSliceIdx++;
m_storedStartCUAddrForEncodingSliceSegment.push_back(pcSlice->getSliceCurEndCUAddr());
startCUAddrSliceSegmentIdx++;

pcSlice = pcPic->getSlice(0);

// SAO parameter estimation using non-deblocked pixels for LCU bottom and right boundary areas
if( pcSlice->getSPS()->getUseSAO() && m_pcCfg->getSaoLcuBoundary() )
{
m_pcSAO->getPreDBFStatistics(pcPic);
}
//-- Loop filter
Bool bLFCrossTileBoundary = pcSlice->getPPS()->getLoopFilterAcrossTilesEnabledFlag();
m_pcLoopFilter->setCfg(bLFCrossTileBoundary);
if ( m_pcCfg->getDeblockingFilterMetric() )
{
dblMetric(pcPic, uiNumSlices);
}
m_pcLoopFilter->loopFilterPic( pcPic );


/////////////////////////////////////////////////////////////////////////////////////////////////// File writing
// Set entropy coder
m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice );

/* write various header sets. */
if ( m_bSeqFirst )
{
OutputNALUnit nalu(NAL_UNIT_VPS);
m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
m_pcEntropyCoder->encodeVPS(m_pcEncTop->getVPS());
writeRBSPTrailingBits(nalu.m_Bitstream);
accessUnit.push_back(new NALUnitEBSP(nalu));
actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;

nalu = NALUnit(NAL_UNIT_SPS);
m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
if (m_bSeqFirst)
{
pcSlice->getSPS()->setNumLongTermRefPicSPS(m_numLongTermRefPicSPS);
for (Int k = 0; k < m_numLongTermRefPicSPS; k++)
{
pcSlice->getSPS()->setLtRefPicPocLsbSps(k, m_ltRefPicPocLsbSps[k]);
pcSlice->getSPS()->setUsedByCurrPicLtSPSFlag(k, m_ltRefPicUsedByCurrPicFlag[k]);
}
}
if( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() )
{
UInt maxCU = m_pcCfg->getSliceArgument() >> ( pcSlice->getSPS()->getMaxCUDepth() << 1);
UInt numDU = ( m_pcCfg->getSliceMode() == 1 ) ? ( pcPic->getNumCUsInFrame() / maxCU ) : ( 0 );
if( pcPic->getNumCUsInFrame() % maxCU != 0 || numDU == 0 )
{
numDU ++;
}
pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->setNumDU( numDU );
pcSlice->getSPS()->setHrdParameters( m_pcCfg->getFrameRate(), numDU, m_pcCfg->getTargetBitrate(), ( m_pcCfg->getIntraPeriod() > 0 ) );
}
if( m_pcCfg->getBufferingPeriodSEIEnabled() || m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() )
{
pcSlice->getSPS()->getVuiParameters()->setHrdParametersPresentFlag( true );
}
m_pcEntropyCoder->encodeSPS(pcSlice->getSPS());
writeRBSPTrailingBits(nalu.m_Bitstream);
accessUnit.push_back(new NALUnitEBSP(nalu));
actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;

nalu = NALUnit(NAL_UNIT_PPS);
m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
m_pcEntropyCoder->encodePPS(pcSlice->getPPS());
writeRBSPTrailingBits(nalu.m_Bitstream);
accessUnit.push_back(new NALUnitEBSP(nalu));
actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;

xCreateLeadingSEIMessages(accessUnit, pcSlice->getSPS());

m_bSeqFirst = false;
}

if (writeSOP) // write SOP description SEI (if enabled) at the beginning of GOP
{
Int SOPcurrPOC = pocCurr;

OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);

SEISOPDescription SOPDescriptionSEI;
SOPDescriptionSEI.m_sopSeqParameterSetId = pcSlice->getSPS()->getSPSId();

UInt i = 0;
UInt prevEntryId = iGOPid;
for (j = iGOPid; j < m_iGopSize; j++)
{
Int deltaPOC = m_pcCfg->getGOPEntry(j).m_POC - m_pcCfg->getGOPEntry(prevEntryId).m_POC;
if ((SOPcurrPOC + deltaPOC) < m_pcCfg->getFramesToBeEncoded())
{
SOPcurrPOC += deltaPOC;
SOPDescriptionSEI.m_sopDescVclNaluType[i] = getNalUnitType(SOPcurrPOC, m_iLastIDR, isField);
SOPDescriptionSEI.m_sopDescTemporalId[i] = m_pcCfg->getGOPEntry(j).m_temporalId;
SOPDescriptionSEI.m_sopDescStRpsIdx[i] = m_pcEncTop->getReferencePictureSetIdxForSOP(pcSlice, SOPcurrPOC, j);
SOPDescriptionSEI.m_sopDescPocDelta[i] = deltaPOC;

prevEntryId = j;
i++;
}
}

SOPDescriptionSEI.m_numPicsInSopMinus1 = i - 1;

m_seiWriter.writeSEImessage( nalu.m_Bitstream, SOPDescriptionSEI, pcSlice->getSPS());
writeRBSPTrailingBits(nalu.m_Bitstream);
accessUnit.push_back(new NALUnitEBSP(nalu));

writeSOP = false;
}

if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&
( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() )
|| ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) )
{
if( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getSubPicCpbParamsPresentFlag() )
{
UInt numDU = pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNumDU();
pictureTimingSEI.m_numDecodingUnitsMinus1     = ( numDU - 1 );
pictureTimingSEI.m_duCommonCpbRemovalDelayFlag = false;

if( pictureTimingSEI.m_numNalusInDuMinus1 == NULL )
{
pictureTimingSEI.m_numNalusInDuMinus1       = new UInt[ numDU ];
}
if( pictureTimingSEI.m_duCpbRemovalDelayMinus1  == NULL )
{
pictureTimingSEI.m_duCpbRemovalDelayMinus1  = new UInt[ numDU ];
}
if( accumBitsDU == NULL )
{
accumBitsDU                                  = new UInt[ numDU ];
}
if( accumNalsDU == NULL )
{
accumNalsDU                                  = new UInt[ numDU ];
}
}
pictureTimingSEI.m_auCpbRemovalDelay = std::min<Int>(std::max<Int>(1, m_totalCoded - m_lastBPSEI), static_cast<Int>(pow(2, static_cast<double>(pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getCpbRemovalDelayLengthMinus1()+1)))); // Syntax element signalled as minus, hence the .
pictureTimingSEI.m_picDpbOutputDelay = pcSlice->getSPS()->getNumReorderPics(pcSlice->getSPS()->getMaxTLayers()-1) + pcSlice->getPOC() - m_totalCoded;
#if EFFICIENT_FIELD_IRAP
if(IRAPGOPid > 0 && IRAPGOPid < m_iGopSize)
{
// if pictures have been swapped there is likely one more picture delay on their tid. Very rough approximation
pictureTimingSEI.m_picDpbOutputDelay ++;
}
#endif
Int factor = pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getTickDivisorMinus2() + 2;
pictureTimingSEI.m_picDpbOutputDuDelay = factor * pictureTimingSEI.m_picDpbOutputDelay;
if( m_pcCfg->getDecodingUnitInfoSEIEnabled() )
{
picSptDpbOutputDuDelay = factor * pictureTimingSEI.m_picDpbOutputDelay;
}
}

if( ( m_pcCfg->getBufferingPeriodSEIEnabled() ) && ( pcSlice->getSliceType() == I_SLICE ) &&
( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&
( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() )
|| ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) )
{
OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);

SEIBufferingPeriod sei_buffering_period;

UInt uiInitialCpbRemovalDelay = (90000/2);                      // 0.5 sec
sei_buffering_period.m_initialCpbRemovalDelay      [0][0]     = uiInitialCpbRemovalDelay;
sei_buffering_period.m_initialCpbRemovalDelayOffset[0][0]     = uiInitialCpbRemovalDelay;
sei_buffering_period.m_initialCpbRemovalDelay      [0][1]     = uiInitialCpbRemovalDelay;
sei_buffering_period.m_initialCpbRemovalDelayOffset[0][1]     = uiInitialCpbRemovalDelay;

Double dTmp = (Double)pcSlice->getSPS()->getVuiParameters()->getTimingInfo()->getNumUnitsInTick() / (Double)pcSlice->getSPS()->getVuiParameters()->getTimingInfo()->getTimeScale();

UInt uiTmp = (UInt)( dTmp * 90000.0 );
uiInitialCpbRemovalDelay -= uiTmp;
uiInitialCpbRemovalDelay -= uiTmp / ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getTickDivisorMinus2() + 2 );
sei_buffering_period.m_initialAltCpbRemovalDelay      [0][0]  = uiInitialCpbRemovalDelay;
sei_buffering_period.m_initialAltCpbRemovalDelayOffset[0][0]  = uiInitialCpbRemovalDelay;
sei_buffering_period.m_initialAltCpbRemovalDelay      [0][1]  = uiInitialCpbRemovalDelay;
sei_buffering_period.m_initialAltCpbRemovalDelayOffset[0][1]  = uiInitialCpbRemovalDelay;

sei_buffering_period.m_rapCpbParamsPresentFlag              = 0;
//for the concatenation, it can be set to one during splicing.
sei_buffering_period.m_concatenationFlag = 0;
//since the temporal layer HRD is not ready, we assumed it is fixed
sei_buffering_period.m_auCpbRemovalDelayDelta = 1;
sei_buffering_period.m_cpbDelayOffset = 0;
sei_buffering_period.m_dpbDelayOffset = 0;

m_seiWriter.writeSEImessage( nalu.m_Bitstream, sei_buffering_period, pcSlice->getSPS());
writeRBSPTrailingBits(nalu.m_Bitstream);
{
UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
UInt offsetPosition = m_activeParameterSetSEIPresentInAU;   // Insert BP SEI after APS SEI
AccessUnit::iterator it;
for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
{
it++;
}
accessUnit.insert(it, new NALUnitEBSP(nalu));
m_bufferingPeriodSEIPresentInAU = true;
}

if (m_pcCfg->getScalableNestingSEIEnabled())
{
OutputNALUnit naluTmp(NAL_UNIT_PREFIX_SEI);
m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
m_pcEntropyCoder->setBitstream(&naluTmp.m_Bitstream);
scalableNestingSEI.m_nestedSEIs.clear();
scalableNestingSEI.m_nestedSEIs.push_back(&sei_buffering_period);
m_seiWriter.writeSEImessage( naluTmp.m_Bitstream, scalableNestingSEI, pcSlice->getSPS());
writeRBSPTrailingBits(naluTmp.m_Bitstream);
UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
UInt offsetPosition = m_activeParameterSetSEIPresentInAU + m_bufferingPeriodSEIPresentInAU + m_pictureTimingSEIPresentInAU;   // Insert BP SEI after non-nested APS, BP and PT SEIs
AccessUnit::iterator it;
for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
{
it++;
}
accessUnit.insert(it, new NALUnitEBSP(naluTmp));
m_nestedBufferingPeriodSEIPresentInAU = true;
}

m_lastBPSEI = m_totalCoded;
m_cpbRemovalDelay = 0;
}
m_cpbRemovalDelay ++;
if( ( m_pcEncTop->getRecoveryPointSEIEnabled() ) && ( pcSlice->getSliceType() == I_SLICE ) )
{
if( m_pcEncTop->getGradualDecodingRefreshInfoEnabled() && !pcSlice->getRapPicFlag() )
{
// Gradual decoding refresh SEI
OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);

SEIGradualDecodingRefreshInfo seiGradualDecodingRefreshInfo;
seiGradualDecodingRefreshInfo.m_gdrForegroundFlag = true; // Indicating all "foreground"

m_seiWriter.writeSEImessage( nalu.m_Bitstream, seiGradualDecodingRefreshInfo, pcSlice->getSPS() );
writeRBSPTrailingBits(nalu.m_Bitstream);
accessUnit.push_back(new NALUnitEBSP(nalu));
}
// Recovery point SEI
OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);

SEIRecoveryPoint sei_recovery_point;
sei_recovery_point.m_recoveryPocCnt    = 0;
sei_recovery_point.m_exactMatchingFlag = ( pcSlice->getPOC() == 0 ) ? (true) : (false);
sei_recovery_point.m_brokenLinkFlag    = false;
#if ALLOW_RECOVERY_POINT_AS_RAP
if(m_pcCfg->getDecodingRefreshType() == 3)
{
m_iLastRecoveryPicPOC = pocCurr;
}
#endif

m_seiWriter.writeSEImessage( nalu.m_Bitstream, sei_recovery_point, pcSlice->getSPS() );
writeRBSPTrailingBits(nalu.m_Bitstream);
accessUnit.push_back(new NALUnitEBSP(nalu));
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: