Void TDecTop::xActivateParameterSets() { if (m_bFirstSliceInPicture) { const TComPPS *pps = m_parameterSetManager.getPPS(m_apcSlicePilot->getPPSId()); // this is a temporary PPS object. Do not store this value assert (pps != 0); const TComSPS *sps = m_parameterSetManager.getSPS(pps->getSPSId()); // this is a temporary SPS object. Do not store this value assert (sps != 0); m_parameterSetManager.clearSPSChangedFlag(sps->getSPSId()); m_parameterSetManager.clearPPSChangedFlag(pps->getPPSId()); if (false == m_parameterSetManager.activatePPS(m_apcSlicePilot->getPPSId(),m_apcSlicePilot->isIRAP())) { printf ("Parameter set activation failed!"); assert (0); } // TODO: remove the use of the following globals: for (UInt channel = 0; channel < MAX_NUM_CHANNEL_TYPE; channel++) { g_bitDepth[channel] = sps->getBitDepth(ChannelType(channel)); g_maxTrDynamicRange[channel] = (sps->getUseExtendedPrecision()) ? std::max<Int>(15, (g_bitDepth[channel] + 6)) : 15; } g_uiMaxCUWidth = sps->getMaxCUWidth(); g_uiMaxCUHeight = sps->getMaxCUHeight(); g_uiMaxCUDepth = sps->getMaxCUDepth(); g_uiAddCUDepth = max (0, sps->getLog2MinCodingBlockSize() - (Int)sps->getQuadtreeTULog2MinSize() + (Int)getMaxCUDepthOffset(sps->getChromaFormatIdc(), sps->getQuadtreeTULog2MinSize())); // Get a new picture buffer. This will also set up m_pcPic, and therefore give us a SPS and PPS pointer that we can use. xGetNewPicBuffer (*(sps), *(pps), m_pcPic, m_apcSlicePilot->getTLayer()); m_apcSlicePilot->applyReferencePictureSet(m_cListPic, m_apcSlicePilot->getRPS()); // make the slice-pilot a real slice, and set up the slice-pilot for the next slice assert(m_pcPic->getNumAllocatedSlice() == (m_uiSliceIdx + 1)); m_apcSlicePilot = m_pcPic->getPicSym()->swapSliceObject(m_apcSlicePilot, m_uiSliceIdx); // we now have a real slice: TComSlice *pSlice = m_pcPic->getSlice(m_uiSliceIdx); // Update the PPS and SPS pointers with the ones of the picture. pps=pSlice->getPPS(); sps=pSlice->getSPS(); // Initialise the various objects for the new set of settings m_cSAO.create( sps->getPicWidthInLumaSamples(), sps->getPicHeightInLumaSamples(), sps->getChromaFormatIdc(), sps->getMaxCUWidth(), sps->getMaxCUHeight(), sps->getMaxCUDepth(), pps->getSaoOffsetBitShift(CHANNEL_TYPE_LUMA), pps->getSaoOffsetBitShift(CHANNEL_TYPE_CHROMA) ); m_cLoopFilter.create( sps->getMaxCUDepth() ); m_cPrediction.initTempBuff(sps->getChromaFormatIdc()); Bool isField = false; Bool isTopField = 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) || (pictureTiming->m_picStruct == 9) || (pictureTiming->m_picStruct == 10) || (pictureTiming->m_picStruct == 11) || (pictureTiming->m_picStruct == 12); isTopField = (pictureTiming->m_picStruct == 1) || (pictureTiming->m_picStruct == 9) || (pictureTiming->m_picStruct == 11); } } //Set Field/Frame coding mode m_pcPic->setField(isField); m_pcPic->setTopField(isTopField); // transfer any SEI messages that have been received to the picture m_pcPic->setSEIs(m_SEIs); m_SEIs.clear(); // Recursive structure m_cCuDecoder.create ( sps->getMaxCUDepth(), sps->getMaxCUWidth(), sps->getMaxCUHeight(), sps->getChromaFormatIdc() ); m_cCuDecoder.init ( &m_cEntropyDecoder, &m_cTrQuant, &m_cPrediction ); m_cTrQuant.init ( sps->getMaxTrSize() ); m_cSliceDecoder.create(); } else { // make the slice-pilot a real slice, and set up the slice-pilot for the next slice m_pcPic->allocateNewSlice(); assert(m_pcPic->getNumAllocatedSlice() == (m_uiSliceIdx + 1)); m_apcSlicePilot = m_pcPic->getPicSym()->swapSliceObject(m_apcSlicePilot, m_uiSliceIdx); TComSlice *pSlice = m_pcPic->getSlice(m_uiSliceIdx); // we now have a real slice. const TComSPS *sps = pSlice->getSPS(); const TComPPS *pps = pSlice->getPPS(); // check that the current active PPS has not changed... if (m_parameterSetManager.getSPSChangedFlag(sps->getSPSId()) ) { printf("Error - a new SPS has been decoded while processing a picture\n"); exit(1); } if (m_parameterSetManager.getPPSChangedFlag(pps->getPPSId()) ) { printf("Error - a new PPS has been decoded while processing a picture\n"); exit(1); } // Check if any new SEI has arrived if(!m_SEIs.empty()) { // Currently only decoding Unit SEI message occurring between VCL NALUs copied SEIMessages &picSEI = m_pcPic->getSEIs(); SEIMessages decodingUnitInfos = extractSeisByType (m_SEIs, SEI::DECODING_UNIT_INFO); picSEI.insert(picSEI.end(), decodingUnitInfos.begin(), decodingUnitInfos.end()); deleteSEIs(m_SEIs); } } }
Void TDecTop::xActivateParameterSets() { if (m_bFirstSliceInPicture) { const TComPPS *pps = m_parameterSetManager.getPPS(m_apcSlicePilot->getPPSId()); // this is a temporary PPS object. Do not store this value assert (pps != 0); const TComSPS *sps = m_parameterSetManager.getSPS(pps->getSPSId()); // this is a temporary SPS object. Do not store this value assert (sps != 0); m_parameterSetManager.clearSPSChangedFlag(sps->getSPSId()); m_parameterSetManager.clearPPSChangedFlag(pps->getPPSId()); if (false == m_parameterSetManager.activatePPS(m_apcSlicePilot->getPPSId(),m_apcSlicePilot->isIRAP())) { printf ("Parameter set activation failed!"); assert (0); } xParsePrefixSEImessages(); #if RExt__HIGH_BIT_DEPTH_SUPPORT==0 if (sps->getSpsRangeExtension().getExtendedPrecisionProcessingFlag() || sps->getBitDepth(CHANNEL_TYPE_LUMA)>12 || sps->getBitDepth(CHANNEL_TYPE_CHROMA)>12 ) { printf("High bit depth support must be enabled at compile-time in order to decode this bitstream\n"); assert (0); exit(1); } #endif // NOTE: globals were set up here originally. You can now use: // g_uiMaxCUDepth = sps->getMaxTotalCUDepth(); // g_uiAddCUDepth = sps->getMaxTotalCUDepth() - sps->getLog2DiffMaxMinCodingBlockSize() // Get a new picture buffer. This will also set up m_pcPic, and therefore give us a SPS and PPS pointer that we can use. xGetNewPicBuffer (*(sps), *(pps), m_pcPic, m_apcSlicePilot->getTLayer()); m_apcSlicePilot->applyReferencePictureSet(m_cListPic, m_apcSlicePilot->getRPS()); // make the slice-pilot a real slice, and set up the slice-pilot for the next slice assert(m_pcPic->getNumAllocatedSlice() == (m_uiSliceIdx + 1)); m_apcSlicePilot = m_pcPic->getPicSym()->swapSliceObject(m_apcSlicePilot, m_uiSliceIdx); // we now have a real slice: TComSlice *pSlice = m_pcPic->getSlice(m_uiSliceIdx); // Update the PPS and SPS pointers with the ones of the picture. pps=pSlice->getPPS(); sps=pSlice->getSPS(); // Initialise the various objects for the new set of settings m_cSAO.create( sps->getPicWidthInLumaSamples(), sps->getPicHeightInLumaSamples(), sps->getChromaFormatIdc(), sps->getMaxCUWidth(), sps->getMaxCUHeight(), sps->getMaxTotalCUDepth(), pps->getPpsRangeExtension().getLog2SaoOffsetScale(CHANNEL_TYPE_LUMA), pps->getPpsRangeExtension().getLog2SaoOffsetScale(CHANNEL_TYPE_CHROMA) ); m_cLoopFilter.create( sps->getMaxTotalCUDepth() ); m_cPrediction.initTempBuff(sps->getChromaFormatIdc()); Bool isField = false; Bool isTopField = false; if(!m_SEIs.empty()) { // Check if any new Picture Timing SEI has arrived SEIMessages pictureTimingSEIs = getSeisByType(m_SEIs, SEI::PICTURE_TIMING); if (pictureTimingSEIs.size()>0) { SEIPictureTiming* pictureTiming = (SEIPictureTiming*) *(pictureTimingSEIs.begin()); isField = (pictureTiming->m_picStruct == 1) || (pictureTiming->m_picStruct == 2) || (pictureTiming->m_picStruct == 9) || (pictureTiming->m_picStruct == 10) || (pictureTiming->m_picStruct == 11) || (pictureTiming->m_picStruct == 12); isTopField = (pictureTiming->m_picStruct == 1) || (pictureTiming->m_picStruct == 9) || (pictureTiming->m_picStruct == 11); } } //Set Field/Frame coding mode m_pcPic->setField(isField); m_pcPic->setTopField(isTopField); // transfer any SEI messages that have been received to the picture m_pcPic->setSEIs(m_SEIs); m_SEIs.clear(); // Recursive structure m_cCuDecoder.create ( sps->getMaxTotalCUDepth(), sps->getMaxCUWidth(), sps->getMaxCUHeight(), sps->getChromaFormatIdc() ); m_cCuDecoder.init ( &m_cEntropyDecoder, &m_cTrQuant, &m_cPrediction ); m_cTrQuant.init ( sps->getMaxTrSize() ); m_cSliceDecoder.create(); } else { // make the slice-pilot a real slice, and set up the slice-pilot for the next slice m_pcPic->allocateNewSlice(); assert(m_pcPic->getNumAllocatedSlice() == (m_uiSliceIdx + 1)); m_apcSlicePilot = m_pcPic->getPicSym()->swapSliceObject(m_apcSlicePilot, m_uiSliceIdx); TComSlice *pSlice = m_pcPic->getSlice(m_uiSliceIdx); // we now have a real slice. const TComSPS *sps = pSlice->getSPS(); const TComPPS *pps = pSlice->getPPS(); // check that the current active PPS has not changed... if (m_parameterSetManager.getSPSChangedFlag(sps->getSPSId()) ) { printf("Error - a new SPS has been decoded while processing a picture\n"); exit(1); } if (m_parameterSetManager.getPPSChangedFlag(pps->getPPSId()) ) { printf("Error - a new PPS has been decoded while processing a picture\n"); exit(1); } xParsePrefixSEImessages(); // Check if any new SEI has arrived if(!m_SEIs.empty()) { // Currently only decoding Unit SEI message occurring between VCL NALUs copied SEIMessages &picSEI = m_pcPic->getSEIs(); SEIMessages decodingUnitInfos = extractSeisByType (m_SEIs, SEI::DECODING_UNIT_INFO); picSEI.insert(picSEI.end(), decodingUnitInfos.begin(), decodingUnitInfos.end()); deleteSEIs(m_SEIs); } } }