HEVC代码追踪(十四):解码之xDecodeSlice
2019-04-15 16:44发布
生成海报
Bool TDecTop::decode(InputNALUnit& nalu, Int& iSkipFrame, Int& iPOCLastDisplay)
{
// Initialize entropy decoder
m_cEntropyDecoder.setEntropyDecoder (&m_cCavlcDecoder);
m_cEntropyDecoder.setBitstream (nalu.m_Bitstream);
switch (nalu.m_nalUnitType)
{
case NAL_UNIT_VPS:
xDecodeVPS();
return false;
case NAL_UNIT_SPS:
xDecodeSPS();
return false;
case NAL_UNIT_PPS:
xDecodePPS();
return false;
case NAL_UNIT_PREFIX_SEI:
case NAL_UNIT_SUFFIX_SEI:
xDecodeSEI( nalu.m_Bitstream, nalu.m_nalUnitType );
return false;
case NAL_UNIT_CODED_SLICE_TRAIL_R:
case NAL_UNIT_CODED_SLICE_TRAIL_N:
case NAL_UNIT_CODED_SLICE_TSA_R:
case NAL_UNIT_CODED_SLICE_TSA_N:
case NAL_UNIT_CODED_SLICE_STSA_R:
case NAL_UNIT_CODED_SLICE_STSA_N:
case NAL_UNIT_CODED_SLICE_BLA_W_LP:
case NAL_UNIT_CODED_SLICE_BLA_W_RADL:
case NAL_UNIT_CODED_SLICE_BLA_N_LP:
case NAL_UNIT_CODED_SLICE_IDR_W_RADL:
case NAL_UNIT_CODED_SLICE_IDR_N_LP:
case NAL_UNIT_CODED_SLICE_CRA:
case NAL_UNIT_CODED_SLICE_RADL_N:
case NAL_UNIT_CODED_SLICE_RADL_R:
case NAL_UNIT_CODED_SLICE_RASL_N:
case NAL_UNIT_CODED_SLICE_RASL_R:
return xDecodeSlice(nalu, iSkipFrame, iPOCLastDisplay);
break;
case NAL_UNIT_EOS:
m_associatedIRAPType = NAL_UNIT_INVALID;
m_pocCRA = 0;
m_pocRandomAccess = MAX_INT;
m_prevPOC = MAX_INT;
m_bFirstSliceInPicture = true;
m_bFirstSliceInSequence = true;
m_prevSliceSkipped = false;
m_skippedPOC = 0;
return false;
case NAL_UNIT_ACCESS_UNIT_DELIMITER:
// TODO: process AU delimiter
return false;
case NAL_UNIT_EOB:
return false;
case NAL_UNIT_FILLER_DATA:
return false;
case NAL_UNIT_RESERVED_VCL_N10:
case NAL_UNIT_RESERVED_VCL_R11:
case NAL_UNIT_RESERVED_VCL_N12:
case NAL_UNIT_RESERVED_VCL_R13:
case NAL_UNIT_RESERVED_VCL_N14:
case NAL_UNIT_RESERVED_VCL_R15:
case NAL_UNIT_RESERVED_IRAP_VCL22:
case NAL_UNIT_RESERVED_IRAP_VCL23:
case NAL_UNIT_RESERVED_VCL24:
case NAL_UNIT_RESERVED_VCL25:
case NAL_UNIT_RESERVED_VCL26:
case NAL_UNIT_RESERVED_VCL27:
case NAL_UNIT_RESERVED_VCL28:
case NAL_UNIT_RESERVED_VCL29:
case NAL_UNIT_RESERVED_VCL30:
case NAL_UNIT_RESERVED_VCL31:
case NAL_UNIT_RESERVED_NVCL41:
case NAL_UNIT_RESERVED_NVCL42:
case NAL_UNIT_RESERVED_NVCL43:
case NAL_UNIT_RESERVED_NVCL44:
case NAL_UNIT_RESERVED_NVCL45:
case NAL_UNIT_RESERVED_NVCL46:
case NAL_UNIT_RESERVED_NVCL47:
case NAL_UNIT_UNSPECIFIED_48:
case NAL_UNIT_UNSPECIFIED_49:
case NAL_UNIT_UNSPECIFIED_50:
case NAL_UNIT_UNSPECIFIED_51:
case NAL_UNIT_UNSPECIFIED_52:
case NAL_UNIT_UNSPECIFIED_53:
case NAL_UNIT_UNSPECIFIED_54:
case NAL_UNIT_UNSPECIFIED_55:
case NAL_UNIT_UNSPECIFIED_56:
case NAL_UNIT_UNSPECIFIED_57:
case NAL_UNIT_UNSPECIFIED_58:
case NAL_UNIT_UNSPECIFIED_59:
case NAL_UNIT_UNSPECIFIED_60:
case NAL_UNIT_UNSPECIFIED_61:
case NAL_UNIT_UNSPECIFIED_62:
case NAL_UNIT_UNSPECIFIED_63:
default:
assert (0);
}
return false;
}
Bool TDecTop::xDecodeSlice(InputNALUnit &nalu, Int &iSkipFrame, Int iPOCLastDisplay )
{
TComPic*& pcPic = m_pcPic;
m_apcSlicePilot->initSlice();
if (m_bFirstSliceInPicture)
{
m_uiSliceIdx = 0;
}
else
{
m_apcSlicePilot->copySliceInfo( pcPic->getPicSym()->getSlice(m_uiSliceIdx-1) );
}
m_apcSlicePilot->setSliceIdx(m_uiSliceIdx);
m_apcSlicePilot->setNalUnitType(nalu.m_nalUnitType);
Bool nonReferenceFlag = (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_TRAIL_N ||
m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_TSA_N ||
m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_STSA_N ||
m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_RADL_N ||
m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_N);
m_apcSlicePilot->setTemporalLayerNonReferenceFlag(nonReferenceFlag);
m_apcSlicePilot->setReferenced(true); // Putting this as true ensures that picture is referenced the first time it is in an RPS
m_apcSlicePilot->setTLayerInfo(nalu.m_temporalId);
m_cEntropyDecoder.decodeSliceHeader (m_apcSlicePilot, &m_parameterSetManagerDecoder);
// set POC for dependent slices in skipped pictures
if(m_apcSlicePilot->getDependentSliceSegmentFlag() && m_prevSliceSkipped)
{
m_apcSlicePilot->setPOC(m_skippedPOC);
}
m_apcSlicePilot->setAssociatedIRAPPOC(m_pocCRA);
m_apcSlicePilot->setAssociatedIRAPType(m_associatedIRAPType);
#if SETTING_NO_OUT_PIC_PRIOR
//For inference of NoOutputOfPriorPicsFlag
if (m_apcSlicePilot->getRapPicFlag())
{
if ((m_apcSlicePilot->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && m_apcSlicePilot->getNalUnitType() <= NAL_UNIT_CODED_SLICE_IDR_N_LP) ||
(m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA && m_bFirstSliceInSequence) ||
(m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA && m_apcSlicePilot->getHandleCraAsBlaFlag()))
{
m_apcSlicePilot->setNoRaslOutputFlag(true);
}
//the inference for NoOutputPriorPicsFlag
if (!m_bFirstSliceInBitstream && m_apcSlicePilot->getRapPicFlag() && m_apcSlicePilot->getNoRaslOutputFlag())
{
if (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA)
{
m_apcSlicePilot->setNoOutputPriorPicsFlag(true);
}
}
else
{
m_apcSlicePilot->setNoOutputPriorPicsFlag(false);
}
if(m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA)
{
m_craNoRaslOutputFlag = m_apcSlicePilot->getNoRaslOutputFlag();
}
}
if (m_apcSlicePilot->getRapPicFlag() && m_apcSlicePilot->getNoOutputPriorPicsFlag())
{
m_lastPOCNoOutputPriorPics = m_apcSlicePilot->getPOC();
m_isNoOutputPriorPics = true;
}
else
{
m_isNoOutputPriorPics = false;
}
//For inference of PicOutputFlag
if (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_N || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_R)
{
if ( m_craNoRaslOutputFlag )
{
m_apcSlicePilot->setPicOutputFlag(false);
}
}
#endif
#if FIX_POC_CRA_NORASL_OUTPUT
if (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA && m_craNoRaslOutputFlag) //Reset POC MSB when CRA has NoRaslOutputFlag equal to 1
{
Int iMaxPOClsb = 1 << m_apcSlicePilot->getSPS()->getBitsForPOC();
m_apcSlicePilot->setPOC( m_apcSlicePilot->getPOC() & (iMaxPOClsb - 1) );
}
#endif
// Skip pictures due to random access
if (isRandomAccessSkipPicture(iSkipFrame, iPOCLastDisplay))
{
m_prevSliceSkipped = true;
m_skippedPOC = m_apcSlicePilot->getPOC();
return false;
}
// Skip TFD pictures associated with BLA/BLANT pictures
if (isSkipPictureForBLA(iPOCLastDisplay))
{
m_prevSliceSkipped = true;
m_skippedPOC = m_apcSlicePilot->getPOC();
return false;
}
// clear previous slice skipped flag
m_prevSliceSkipped = false;
//we should only get a different poc for a new picture (with CTU address==0)
if (m_apcSlicePilot->isNextSlice() && m_apcSlicePilot->getPOC()!=m_prevPOC && !m_bFirstSliceInSequence && (m_apcSlicePilot->getSliceCurStartCUAddr()!=0))
{
printf ("Warning, the first slice of a picture might have been lost!
");
}
// exit when a new picture is found
if (m_apcSlicePilot->isNextSlice() && (m_apcSlicePilot->getSliceCurStartCUAddr() == 0 && !m_bFirstSliceInPicture) && !m_bFirstSliceInSequence )
{
if (m_prevPOC >= m_pocRandomAccess)
{
m_prevPOC = m_apcSlicePilot->getPOC();
return true;
}
m_prevPOC = m_apcSlicePilot->getPOC();
}
// actual decoding starts here
xActivateParameterSets();
if (m_apcSlicePilot->isNextSlice())
{
m_prevPOC = m_apcSlicePilot->getPOC();
}
m_bFirstSliceInSequence = false;
#if SETTING_NO_OUT_PIC_PRIOR
m_bFirstSliceInBitstream = false;
#endif
//detect lost reference picture and insert copy of earlier frame.
Int lostPoc;
while((lostPoc=m_apcSlicePilot->checkThatAllRefPicsAreAvailable(m_cListPic, m_apcSlicePilot->getRPS(), true, m_pocRandomAccess)) > 0)
{
xCreateLostPicture(lostPoc-1);
}
if (m_bFirstSliceInPicture)
{
// Buffer initialize for prediction.
m_cPrediction.initTempBuff();
m_apcSlicePilot->applyReferencePictureSet(m_cListPic, m_apcSlicePilot->getRPS());
// Get a new picture buffer
xGetNewPicBuffer (m_apcSlicePilot, pcPic);
Bool isField = false;
Bool isTff = false;
if(!m_SEIs.empty())
{
// Check if any new Picture Timing SEI has arrived
SEIMessages pictureTimingSEIs = extractSeisByType (m_SEIs, SEI::PICTURE_TIMING);
if (pictureTimingSEIs.size()>0)
{
SEIPictureTiming* pictureTiming = (SEIPictureTiming*) *(pictureTimingSEIs.begin());
isField = (pictureTiming->m_picStruct == 1) || (pictureTiming->m_picStruct == 2);
isTff = (pictureTiming->m_picStruct == 1);
}
}
//Set Field/Frame coding mode
m_pcPic->setField(isField);
m_pcPic->setTopField(isTff);
// transfer any SEI messages that have been received to the picture
pcPic->setSEIs(m_SEIs);
m_SEIs.clear();
// Recursive structure
m_cCuDecoder.create ( g_uiMaxCUDepth, g_uiMaxCUWidth, g_uiMaxCUHeight );
m_cCuDecoder.init ( &m_cEntropyDecoder, &m_cTrQuant, &m_cPrediction );
m_cTrQuant.init ( g_uiMaxCUWidth, g_uiMaxCUHeight, m_apcSlicePilot->getSPS()->getMaxTrSize());
m_cSliceDecoder.create();
}
else
{
// Check if any new SEI has arrived
if(!m_SEIs.empty())
{
// Currently only decoding Unit SEI message occurring between VCL NALUs copied
SEIMessages &picSEI = pcPic->getSEIs();
SEIMessages decodingUnitInfos = extractSeisByType (m_SEIs, SEI::DECODING_UNIT_INFO);
picSEI.insert(picSEI.end(), decodingUnitInfos.begin(), decodingUnitInfos.end());
deleteSEIs(m_SEIs);
}
}
// Set picture slice pointer
TComSlice* pcSlice = m_apcSlicePilot;
Bool bNextSlice = pcSlice->isNextSlice();
UInt i;
pcPic->getPicSym()->initTiles(pcSlice->getPPS());
//generate the Coding Order Map and Inverse Coding Order Map
UInt uiEncCUAddr;
for(i=0, uiEncCUAddr=0; igetPicSym()->getNumberOfCUsInFrame(); i++, uiEncCUAddr = pcPic->getPicSym()->xCalculateNxtCUAddr(uiEncCUAddr))
{
pcPic->getPicSym()->setCUOrderMap(i, uiEncCUAddr);
pcPic->getPicSym()->setInverseCUOrderMap(uiEncCUAddr, i);
}
pcPic->getPicSym()->setCUOrderMap(pcPic->getPicSym()->getNumberOfCUsInFrame(), pcPic->getPicSym()->getNumberOfCUsInFrame());
pcPic->getPicSym()->setInverseCUOrderMap(pcPic->getPicSym()->getNumberOfCUsInFrame(), pcPic->getPicSym()->getNumberOfCUsInFrame());
//convert the start and end CU addresses of the slice and dependent slice into encoding order
pcSlice->setSliceSegmentCurStartCUAddr( pcPic->getPicSym()->getPicSCUEncOrder(pcSlice->getSliceSegmentCurStartCUAddr()) );
pcSlice->setSliceSegmentCurEndCUAddr( pcPic->getPicSym()->getPicSCUEncOrder(pcSlice->getSliceSegmentCurEndCUAddr()) );
if(pcSlice->isNextSlice())
{
pcSlice->setSliceCurStartCUAddr(pcPic->getPicSym()->getPicSCUEncOrder(pcSlice->getSliceCurStartCUAddr()));
pcSlice->setSliceCurEndCUAddr(pcPic->getPicSym()->getPicSCUEncOrder(pcSlice->getSliceCurEndCUAddr()));
}
if (m_bFirstSliceInPicture)
{
if(pcPic->getNumAllocatedSlice() != 1)
{
pcPic->clearSliceBuffer();
}
}
else
{
pcPic->allocateNewSlice();
}
assert(pcPic->getNumAllocatedSlice() == (m_uiSliceIdx + 1));
m_apcSlicePilot = pcPic->getPicSym()->getSlice(m_uiSliceIdx);
pcPic->getPicSym()->setSlice(pcSlice, m_uiSliceIdx);
pcPic->setTLayer(nalu.m_temporalId);
if (bNextSlice)
{
pcSlice->checkCRA(pcSlice->getRPS(), m_pocCRA, m_associatedIRAPType, m_cListPic );
// Set reference list
pcSlice->setRefPicList( m_cListPic, true );
// For generalized B
// note: maybe not existed case (always L0 is copied to L1 if L1 is empty)
if (pcSlice->isInterB() && pcSlice->getNumRefIdx(REF_PIC_LIST_1) == 0)
{
Int iNumRefIdx = pcSlice->getNumRefIdx(REF_PIC_LIST_0);
pcSlice->setNumRefIdx ( REF_PIC_LIST_1, iNumRefIdx );
for (Int iRefIdx = 0; iRefIdx < iNumRefIdx; iRefIdx++)
{
pcSlice->setRefPic(pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx), REF_PIC_LIST_1, iRefIdx);
}
}
if (!pcSlice->isIntra())
{
Bool bLowDelay = true;
Int iCurrPOC = pcSlice->getPOC();
Int iRefIdx = 0;
for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_0) && bLowDelay; iRefIdx++)
{
if ( pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx)->getPOC() > iCurrPOC )
{
bLowDelay = false;
}
}
if (pcSlice->isInterB())
{
for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_1) && bLowDelay; iRefIdx++)
{
if ( pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx)->getPOC() > iCurrPOC )
{
bLowDelay = false;
}
}
}
pcSlice->setCheckLDC(bLowDelay);
}
//---------------
pcSlice->setRefPOCList();
}
pcPic->setCurrSliceIdx(m_uiSliceIdx);
if(pcSlice->getSPS()->getScalingListFlag())
{
pcSlice->setScalingList ( pcSlice->getSPS()->getScalingList() );
if(pcSlice->getPPS()->getScalingListPresentFlag())
{
pcSlice->setScalingList ( pcSlice->getPPS()->getScalingList() );
}
if(!pcSlice->getPPS()->getScalingListPresentFlag() && !pcSlice->getSPS()->getScalingListPresentFlag())
{
pcSlice->setDefaultScalingList();
}
m_cTrQuant.setScalingListDec(pcSlice->getScalingList());
m_cTrQuant.setUseScalingList(true);
}
else
{
m_cTrQuant.setFlatScalingList();
m_cTrQuant.setUseScalingList(false);
}
// Decode a picture
m_cGopDecoder.decompressSlice(nalu.m_Bitstream, pcPic);
m_bFirstSliceInPicture = false;
m_uiSliceIdx++;
return false;
}
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮