HEVC代码追踪(十四):解码之xDecodeSlice

来源:互联网 发布:腾讯数据实验室 编辑:程序博客网 时间:2024/06/06 10:50


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!\n");  }  // 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; i<pcPic->getPicSym()->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;}






0 0
原创粉丝点击