/** decode motion information for every PU block. * \param pcCU * \param uiAbsPartIdx * \param uiDepth * \param pcSubCU * \returns Void */ Void TDecEntropy::decodePUWise( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, TComDataCU* pcSubCU ) { PartSize ePartSize = pcCU->getPartitionSize( uiAbsPartIdx ); UInt uiNumPU = ( ePartSize == SIZE_2Nx2N ? 1 : ( ePartSize == SIZE_NxN ? 4 : 2 ) ); UInt uiPUOffset = ( g_auiPUOffset[UInt( ePartSize )] << ( ( pcCU->getSlice()->getSPS()->getMaxCUDepth() - uiDepth ) << 1 ) ) >> 4; #if H_3D_IV_MERGE TComMvField cMvFieldNeighbours[MRG_MAX_NUM_CANDS_MEM << 1]; // double length for mv of both lists UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS_MEM]; #else TComMvField cMvFieldNeighbours[MRG_MAX_NUM_CANDS << 1]; // double length for mv of both lists UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS]; #endif #if H_3D_SPIVMP Bool bSPIVMPFlag[MRG_MAX_NUM_CANDS_MEM]; TComMvField* pcMvFieldSP; UChar* puhInterDirSP; pcMvFieldSP = new TComMvField[pcCU->getPic()->getPicSym()->getNumPartition()*2]; puhInterDirSP = new UChar[pcCU->getPic()->getPicSym()->getNumPartition()]; #endif for ( UInt ui = 0; ui < pcCU->getSlice()->getMaxNumMergeCand(); ui++ ) { uhInterDirNeighbours[ui] = 0; } Int numValidMergeCand = 0; Bool isMerged = false; pcSubCU->copyInterPredInfoFrom( pcCU, uiAbsPartIdx, REF_PIC_LIST_0 ); pcSubCU->copyInterPredInfoFrom( pcCU, uiAbsPartIdx, REF_PIC_LIST_1 ); #if H_3D_IV_MERGE pcSubCU->copyDVInfoFrom( pcCU, uiAbsPartIdx); #endif for ( UInt uiPartIdx = 0, uiSubPartIdx = uiAbsPartIdx; uiPartIdx < uiNumPU; uiPartIdx++, uiSubPartIdx += uiPUOffset ) { #if H_MV_ENC_DEC_TRAC DTRACE_PU_S("=========== prediction_unit ===========\n") // ToDo: //DTRACE_PU("x0", uiLPelX) //DTRACE_PU("x1", uiTPelY) #endif decodeMergeFlag( pcCU, uiSubPartIdx, uiDepth, uiPartIdx ); if ( pcCU->getMergeFlag( uiSubPartIdx ) ) { decodeMergeIndex( pcCU, uiPartIdx, uiSubPartIdx, uiDepth ); UInt uiMergeIndex = pcCU->getMergeIndex(uiSubPartIdx); #if H_3D_IC decodeICFlag( pcCU, uiAbsPartIdx, uiDepth ); #endif #if H_3D_ARP decodeARPW ( pcCU, uiAbsPartIdx, uiDepth ); #endif if ( pcCU->getSlice()->getPPS()->getLog2ParallelMergeLevelMinus2() && ePartSize != SIZE_2Nx2N && pcSubCU->getWidth( 0 ) <= 8 ) { pcSubCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uiDepth ); if ( !isMerged ) { #if H_3D_VSP Int vspFlag[MRG_MAX_NUM_CANDS_MEM]; memset(vspFlag, 0, sizeof(Int)*MRG_MAX_NUM_CANDS_MEM); InheritedVSPDisInfo inheritedVSPDisInfo[MRG_MAX_NUM_CANDS_MEM]; #if H_3D_SPIVMP memset(bSPIVMPFlag, false, sizeof(Bool)*MRG_MAX_NUM_CANDS_MEM); #endif pcSubCU->initAvailableFlags(); pcSubCU->getInterMergeCandidates( 0, 0, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand); pcSubCU->xGetInterMergeCandidates( 0, 0, cMvFieldNeighbours, uhInterDirNeighbours, vspFlag, inheritedVSPDisInfo #if H_3D_SPIVMP , bSPIVMPFlag, pcMvFieldSP, puhInterDirSP #endif , numValidMergeCand ); pcCU->setVSPFlagSubParts( vspFlag[uiMergeIndex], uiSubPartIdx, uiPartIdx, uiDepth ); if(vspFlag[uiMergeIndex]) { pcCU->setDvInfoSubParts(inheritedVSPDisInfo[uiMergeIndex].m_acDvInfo, uiSubPartIdx, uiPartIdx, uiDepth); } #else #if H_3D pcSubCU->initAvailableFlags(); pcSubCU->getInterMergeCandidates( 0, 0, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand); pcSubCU->xGetInterMergeCandidates( 0, 0, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand ); #else pcSubCU->getInterMergeCandidates( 0, 0, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand ); #endif #endif isMerged = true; } pcSubCU->setPartSizeSubParts( ePartSize, 0, uiDepth ); } else { uiMergeIndex = pcCU->getMergeIndex(uiSubPartIdx); #if H_3D_VSP Int vspFlag[MRG_MAX_NUM_CANDS_MEM]; memset(vspFlag, 0, sizeof(Int)*MRG_MAX_NUM_CANDS_MEM); InheritedVSPDisInfo inheritedVSPDisInfo[MRG_MAX_NUM_CANDS_MEM]; #if H_3D_SPIVMP memset(bSPIVMPFlag, false, sizeof(Bool)*MRG_MAX_NUM_CANDS_MEM); #endif pcSubCU->initAvailableFlags(); pcSubCU->getInterMergeCandidates( uiSubPartIdx-uiAbsPartIdx, uiPartIdx, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand, uiMergeIndex ); pcSubCU->xGetInterMergeCandidates( uiSubPartIdx-uiAbsPartIdx, uiPartIdx, cMvFieldNeighbours, uhInterDirNeighbours, vspFlag, inheritedVSPDisInfo #if H_3D_SPIVMP , bSPIVMPFlag, pcMvFieldSP, puhInterDirSP #endif ,numValidMergeCand, uiMergeIndex ); pcCU->setVSPFlagSubParts( vspFlag[uiMergeIndex], uiSubPartIdx, uiPartIdx, uiDepth ); if(vspFlag[uiMergeIndex]) { pcCU->setDvInfoSubParts(inheritedVSPDisInfo[uiMergeIndex].m_acDvInfo, uiSubPartIdx, uiPartIdx, uiDepth); } #else #if H_3D pcSubCU->initAvailableFlags(); pcSubCU->getInterMergeCandidates( uiSubPartIdx-uiAbsPartIdx, uiPartIdx, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand, uiMergeIndex ); pcSubCU->xGetInterMergeCandidates( uiSubPartIdx-uiAbsPartIdx, uiPartIdx, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand, uiMergeIndex ); #else pcSubCU->getInterMergeCandidates( uiSubPartIdx-uiAbsPartIdx, uiPartIdx, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand, uiMergeIndex ); #endif #endif } pcCU->setInterDirSubParts( uhInterDirNeighbours[uiMergeIndex], uiSubPartIdx, uiPartIdx, uiDepth ); TComMv cTmpMv( 0, 0 ); for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ ) { if ( pcCU->getSlice()->getNumRefIdx( RefPicList( uiRefListIdx ) ) > 0 ) { pcCU->setMVPIdxSubParts( 0, RefPicList( uiRefListIdx ), uiSubPartIdx, uiPartIdx, uiDepth); pcCU->setMVPNumSubParts( 0, RefPicList( uiRefListIdx ), uiSubPartIdx, uiPartIdx, uiDepth); pcCU->getCUMvField( RefPicList( uiRefListIdx ) )->setAllMvd( cTmpMv, ePartSize, uiSubPartIdx, uiDepth, uiPartIdx ); pcCU->getCUMvField( RefPicList( uiRefListIdx ) )->setAllMvField( cMvFieldNeighbours[ 2*uiMergeIndex + uiRefListIdx ], ePartSize, uiSubPartIdx, uiDepth, uiPartIdx ); } } #if H_3D_SPIVMP pcCU->setSPIVMPFlagSubParts(bSPIVMPFlag[uiMergeIndex], uiSubPartIdx, uiPartIdx, uiDepth ); if (bSPIVMPFlag[uiMergeIndex] != 0) { Int iWidth, iHeight; UInt uiIdx; pcCU->getPartIndexAndSize( uiPartIdx, uiIdx, iWidth, iHeight, uiSubPartIdx, true ); UInt uiSPAddr; Int iNumSPInOneLine, iNumSP, iSPWidth, iSPHeight; pcCU->getSPPara(iWidth, iHeight, iNumSP, iNumSPInOneLine, iSPWidth, iSPHeight); for (Int iPartitionIdx = 0; iPartitionIdx < iNumSP; iPartitionIdx++) { pcCU->getSPAbsPartIdx(uiSubPartIdx, iSPWidth, iSPHeight, iPartitionIdx, iNumSPInOneLine, uiSPAddr); pcCU->setInterDirSP(puhInterDirSP[iPartitionIdx], uiSPAddr, iSPWidth, iSPHeight); pcCU->getCUMvField( REF_PIC_LIST_0 )->setMvFieldSP(pcCU, uiSPAddr, pcMvFieldSP[2*iPartitionIdx], iSPWidth, iSPHeight); pcCU->getCUMvField( REF_PIC_LIST_1 )->setMvFieldSP(pcCU, uiSPAddr, pcMvFieldSP[2*iPartitionIdx + 1], iSPWidth, iSPHeight); } } #endif } else { decodeInterDirPU( pcCU, uiSubPartIdx, uiDepth, uiPartIdx ); for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ ) { if ( pcCU->getSlice()->getNumRefIdx( RefPicList( uiRefListIdx ) ) > 0 ) { decodeRefFrmIdxPU( pcCU, uiSubPartIdx, uiDepth, uiPartIdx, RefPicList( uiRefListIdx ) ); decodeMvdPU ( pcCU, uiSubPartIdx, uiDepth, uiPartIdx, RefPicList( uiRefListIdx ) ); decodeMVPIdxPU ( pcSubCU, uiSubPartIdx-uiAbsPartIdx, uiDepth, uiPartIdx, RefPicList( uiRefListIdx ) ); } } #if H_3D_IC decodeICFlag( pcCU, uiAbsPartIdx, uiDepth ); #endif #if H_3D_ARP decodeARPW ( pcCU, uiAbsPartIdx, uiDepth ); #endif } #if H_3D_VSP if ( (pcCU->getInterDir(uiSubPartIdx) == 3) && pcSubCU->isBipredRestriction(uiPartIdx) && (pcCU->getVSPFlag(uiSubPartIdx) == false)) #else if ( (pcCU->getInterDir(uiSubPartIdx) == 3) && pcSubCU->isBipredRestriction(uiPartIdx) ) #endif { pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMv( TComMv(0,0), ePartSize, uiSubPartIdx, uiDepth, uiPartIdx); pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllRefIdx( -1, ePartSize, uiSubPartIdx, uiDepth, uiPartIdx); pcCU->setInterDirSubParts( 1, uiSubPartIdx, uiPartIdx, uiDepth); } } #if H_3D_SPIVMP delete[] pcMvFieldSP; delete[] puhInterDirSP; #endif return; }
Void TDecGop::filterPicture(TComPic*& rpcPic) { TComSlice* pcSlice = rpcPic->getSlice(rpcPic->getCurrSliceIdx()); //-- For time output for each slice long iBeforeTime = clock(); // deblocking filter Bool bLFCrossTileBoundary = pcSlice->getPPS()->getLoopFilterAcrossTilesEnabledFlag(); m_pcLoopFilter->setCfg(bLFCrossTileBoundary); m_pcLoopFilter->loopFilterPic( rpcPic ); if(pcSlice->getSPS()->getUseSAO()) { m_sliceStartCUAddress.push_back(rpcPic->getNumCUsInFrame()* rpcPic->getNumPartInCU()); rpcPic->createNonDBFilterInfo(m_sliceStartCUAddress, 0, &m_LFCrossSliceBoundaryFlag, rpcPic->getPicSym()->getNumTiles(), bLFCrossTileBoundary); } if( pcSlice->getSPS()->getUseSAO() ) { { SAOParam *saoParam = rpcPic->getPicSym()->getSaoParam(); saoParam->bSaoFlag[0] = pcSlice->getSaoEnabledFlag(); saoParam->bSaoFlag[1] = pcSlice->getSaoEnabledFlagChroma(); m_pcSAO->setSaoLcuBasedOptimization(1); m_pcSAO->createPicSaoInfo(rpcPic); m_pcSAO->SAOProcess(saoParam); m_pcSAO->PCMLFDisableProcess(rpcPic); m_pcSAO->destroyPicSaoInfo(); } } if(pcSlice->getSPS()->getUseSAO()) { rpcPic->destroyNonDBFilterInfo(); } #if H_3D rpcPic->compressMotion(2); #endif #if !H_3D rpcPic->compressMotion(); #endif Char c = (pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B'); if (!pcSlice->isReferenced()) c += 32; //-- For time output for each slice #if H_MV printf("\nLayer %2d POC %4d TId: %1d ( %c-SLICE, QP%3d ) ", pcSlice->getLayerId(), pcSlice->getPOC(), pcSlice->getTLayer(), c, pcSlice->getSliceQp() ); #else printf("\nPOC %4d TId: %1d ( %c-SLICE, QP%3d ) ", pcSlice->getPOC(), pcSlice->getTLayer(), c, pcSlice->getSliceQp() ); #endif m_dDecTime += (Double)(clock()-iBeforeTime) / CLOCKS_PER_SEC; printf ("[DT %6.3f] ", m_dDecTime ); m_dDecTime = 0; for (Int iRefList = 0; iRefList < 2; iRefList++) { printf ("[L%d ", iRefList); for (Int iRefIndex = 0; iRefIndex < pcSlice->getNumRefIdx(RefPicList(iRefList)); iRefIndex++) { #if H_MV if( pcSlice->getLayerId() != pcSlice->getRefLayerId( RefPicList(iRefList), iRefIndex ) ) { printf( "V%d ", pcSlice->getRefLayerId( RefPicList(iRefList), iRefIndex ) ); } else { #endif printf ("%d ", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex)); #if H_MV } #endif } printf ("] "); } if (m_decodedPictureHashSEIEnabled) { SEIMessages pictureHashes = getSeisByType(rpcPic->getSEIs(), SEI::DECODED_PICTURE_HASH ); const SEIDecodedPictureHash *hash = ( pictureHashes.size() > 0 ) ? (SEIDecodedPictureHash*) *(pictureHashes.begin()) : NULL; if (pictureHashes.size() > 1) { printf ("Warning: Got multiple decoded picture hash SEI messages. Using first."); } calcAndPrintHashStatus(*rpcPic->getPicYuvRec(), hash); } rpcPic->setOutputMark(true); rpcPic->setReconMark(true); m_sliceStartCUAddress.clear(); m_LFCrossSliceBoundaryFlag.clear(); }
Bool TDecTop::decode(InputNALUnit& nalu, Int& iSkipFrame, Int& iPOCLastDisplay) { TComPic*& pcPic = m_pcPic; #if E045_SLICE_COMMON_INFO_SHARING static TComPPS* pcNewPPS = NULL; #endif // Initialize entropy decoder m_cEntropyDecoder.setEntropyDecoder (&m_cCavlcDecoder); m_cEntropyDecoder.setBitstream (nalu.m_Bitstream); switch (nalu.m_UnitType) { case NAL_UNIT_SPS: m_cEntropyDecoder.decodeSPS( &m_cSPS ); #if ENABLE_ANAYSIS_OUTPUT TSysuAnalyzerOutput::getInstance()->writeOutSps( &m_cSPS ); #endif #if AMP for (Int i = 0; i < m_cSPS.getMaxCUDepth() - 1; i++) { // m_cSPS.setAMPAcc( i, m_cSPS.getUseAMP() ); m_cSPS.setAMPAcc( i, 1 ); } for (Int i = m_cSPS.getMaxCUDepth() - 1; i < m_cSPS.getMaxCUDepth(); i++) { m_cSPS.setAMPAcc( i, 0 ); } #endif // create ALF temporary buffer m_cAdaptiveLoopFilter.create( m_cSPS.getWidth(), m_cSPS.getHeight(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth ); #if MTK_SAO m_cSAO.create( m_cSPS.getWidth(), m_cSPS.getHeight(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth ); #endif #if PARALLEL_MERGED_DEBLK m_cLoopFilter.create( m_cSPS.getWidth(), m_cSPS.getHeight(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth ); #else m_cLoopFilter. create( g_uiMaxCUDepth ); #endif #if E045_SLICE_COMMON_INFO_SHARING createPPSBuffer(); #endif m_uiValidPS |= 1; return false; case NAL_UNIT_PPS: #if E045_SLICE_COMMON_INFO_SHARING pcNewPPS = getNewPPSBuffer(); #if SUB_LCU_DQP pcNewPPS->setSPS(&m_cSPS); #endif m_cEntropyDecoder.decodePPS( pcNewPPS ); if(pcNewPPS->getSharedPPSInfoEnabled()) { if(m_cSPS.getUseALF()) { m_cEntropyDecoder.decodeAlfParam( pcNewPPS->getSharedAlfParam()); } } signalNewPPSAvailable(); #else #if SUB_LCU_DQP m_cPPS.setSPS(&m_cSPS); #endif m_cEntropyDecoder.decodePPS( &m_cPPS ); #endif m_uiValidPS |= 2; return false; case NAL_UNIT_SEI: m_SEIs = new SEImessages; m_cEntropyDecoder.decodeSEI(*m_SEIs); return false; case NAL_UNIT_CODED_SLICE: case NAL_UNIT_CODED_SLICE_IDR: case NAL_UNIT_CODED_SLICE_CDR: { // make sure we already received both parameter sets assert( 3 == m_uiValidPS ); if (m_bFirstSliceInPicture) { m_apcSlicePilot->initSlice(); m_uiSliceIdx = 0; m_uiLastSliceIdx = 0; #if E045_SLICE_COMMON_INFO_SHARING if(hasNewPPS()) { m_pcPPS = pcNewPPS; updatePPSBuffer(); } #endif } m_apcSlicePilot->setSliceIdx(m_uiSliceIdx); // Read slice header m_apcSlicePilot->setSPS( &m_cSPS ); #if E045_SLICE_COMMON_INFO_SHARING m_apcSlicePilot->setPPS( m_pcPPS ); #else m_apcSlicePilot->setPPS( &m_cPPS ); #endif m_apcSlicePilot->setSliceIdx(m_uiSliceIdx); if (!m_bFirstSliceInPicture) { memcpy(m_apcSlicePilot, pcPic->getPicSym()->getSlice(m_uiSliceIdx-1), sizeof(TComSlice)); } m_apcSlicePilot->setNalUnitType(nalu.m_UnitType); m_apcSlicePilot->setReferenced(nalu.m_RefIDC != NAL_REF_IDC_PRIORITY_LOWEST); m_cEntropyDecoder.decodeSliceHeader (m_apcSlicePilot); if ( m_apcSlicePilot->getSymbolMode() ) { Int numBitsForByteAlignment = nalu.m_Bitstream->getNumBitsUntilByteAligned(); if ( numBitsForByteAlignment > 0 ) { UInt bitsForByteAlignment; nalu.m_Bitstream->read( numBitsForByteAlignment, bitsForByteAlignment ); assert( bitsForByteAlignment == ( ( 1 << numBitsForByteAlignment ) - 1 ) ); } } m_apcSlicePilot->setTLayerInfo(nalu.m_TemporalID); if (m_apcSlicePilot->isNextSlice() && m_apcSlicePilot->getPOC()!=m_uiPrevPOC && !m_bFirstSliceInSequence) { m_uiPrevPOC = m_apcSlicePilot->getPOC(); return true; } if (m_apcSlicePilot->isNextSlice()) m_uiPrevPOC = m_apcSlicePilot->getPOC(); m_bFirstSliceInSequence = false; if (m_apcSlicePilot->isNextSlice()) { // Skip pictures due to random access if (isRandomAccessSkipPicture(iSkipFrame, iPOCLastDisplay)) { return false; } } if (m_bFirstSliceInPicture) { // Buffer initialize for prediction. m_cPrediction.initTempBuff(); // Get a new picture buffer xGetNewPicBuffer (m_apcSlicePilot, pcPic); /* transfer any SEI messages that have been received to the picture */ pcPic->setSEIs(m_SEIs); m_SEIs = NULL; // 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( m_apcSlicePilot, m_apcSlicePilot->getSPS()->getWidth(), m_apcSlicePilot->getSPS()->getHeight(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth ); } // Set picture slice pointer TComSlice* pcSlice = m_apcSlicePilot; Bool bNextSlice = pcSlice->isNextSlice(); 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) { // Do decoding refresh marking if any pcSlice->decodingRefreshMarking(m_uiPOCCDR, m_bRefreshPending, m_cListPic); // Set reference list pcSlice->setRefPicList( m_cListPic ); // HierP + GPB case if ( m_cSPS.getUseLDC() && pcSlice->isInterB() ) { if(pcSlice->getRefPicListCombinationFlag() && (pcSlice->getNumRefIdx(REF_PIC_LIST_0) > pcSlice->getNumRefIdx(REF_PIC_LIST_1))) { for (Int iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_1); iRefIdx++) { pcSlice->setRefPic(pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx), REF_PIC_LIST_1, iRefIdx); } } else { 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); } } } // 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 TMVP_ONE_LIST_CHECK if (pcSlice->isInterB()) { 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; } } 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); } #endif //--------------- pcSlice->setRefPOCList(); if(!pcSlice->getRefPicListModificationFlagLC()) { pcSlice->generateCombinedList(); } pcSlice->setNoBackPredFlag( false ); if ( pcSlice->getSliceType() == B_SLICE && !pcSlice->getRefPicListCombinationFlag()) { if ( pcSlice->getNumRefIdx(RefPicList( 0 ) ) == pcSlice->getNumRefIdx(RefPicList( 1 ) ) ) { pcSlice->setNoBackPredFlag( true ); int i; for ( i=0; i < pcSlice->getNumRefIdx(RefPicList( 1 ) ); i++ ) { if ( pcSlice->getRefPOC(RefPicList(1), i) != pcSlice->getRefPOC(RefPicList(0), i) ) { pcSlice->setNoBackPredFlag( false ); break; } } } } } pcPic->setCurrSliceIdx(m_uiSliceIdx); // Decode a picture #if REF_SETTING_FOR_LD m_cGopDecoder.decompressGop(nalu.m_Bitstream, pcPic, false, m_cListPic ); #else m_cGopDecoder.decompressGop(nalu.m_Bitstream, pcPic, false); #endif m_bFirstSliceInPicture = false; m_uiSliceIdx++; } break; default: assert (1); } return false; }
Void TDecGop::decompressSlice(TComInputBitstream* pcBitstream, TComPic*& rpcPic) { TComSlice* pcSlice = rpcPic->getSlice(rpcPic->getCurrSliceIdx()); // Table of extracted substreams. // These must be deallocated AND their internal fifos, too. TComInputBitstream **ppcSubstreams = NULL; //-- For time output for each slice long iBeforeTime = clock(); UInt uiStartCUAddr = pcSlice->getSliceSegmentCurStartCUAddr(); UInt uiSliceStartCuAddr = pcSlice->getSliceCurStartCUAddr(); if(uiSliceStartCuAddr == uiStartCUAddr) { m_sliceStartCUAddress.push_back(uiSliceStartCuAddr); } m_pcSbacDecoder->init( (TDecBinIf*)m_pcBinCABAC ); m_pcEntropyDecoder->setEntropyDecoder (m_pcSbacDecoder); UInt uiNumSubstreams = pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag() ? pcSlice->getNumEntryPointOffsets()+1 : pcSlice->getPPS()->getNumSubstreams(); // init each couple {EntropyDecoder, Substream} UInt *puiSubstreamSizes = pcSlice->getSubstreamSizes(); ppcSubstreams = new TComInputBitstream*[uiNumSubstreams]; m_pcSbacDecoders = new TDecSbac[uiNumSubstreams]; m_pcBinCABACs = new TDecBinCABAC[uiNumSubstreams]; for ( UInt ui = 0 ; ui < uiNumSubstreams ; ui++ ) { m_pcSbacDecoders[ui].init(&m_pcBinCABACs[ui]); ppcSubstreams[ui] = pcBitstream->extractSubstream(ui+1 < uiNumSubstreams ? puiSubstreamSizes[ui] : pcBitstream->getNumBitsLeft()); } for ( UInt ui = 0 ; ui+1 < uiNumSubstreams; ui++ ) { m_pcEntropyDecoder->setEntropyDecoder ( &m_pcSbacDecoders[uiNumSubstreams - 1 - ui] ); m_pcEntropyDecoder->setBitstream ( ppcSubstreams [uiNumSubstreams - 1 - ui] ); m_pcEntropyDecoder->resetEntropy (pcSlice); } m_pcEntropyDecoder->setEntropyDecoder ( m_pcSbacDecoder ); m_pcEntropyDecoder->setBitstream ( ppcSubstreams[0] ); m_pcEntropyDecoder->resetEntropy (pcSlice); if(uiSliceStartCuAddr == uiStartCUAddr) { m_LFCrossSliceBoundaryFlag.push_back( pcSlice->getLFCrossSliceBoundaryFlag()); } #if H_3D_NBDV if(pcSlice->getViewIndex() && !pcSlice->getIsDepth()) //Notes from QC: this condition shall be changed once the configuration is completed, e.g. in pcSlice->getSPS()->getMultiviewMvPredMode() || ARP in prev. HTM. Remove this comment once it is done. { Int iColPoc = pcSlice->getRefPOC(RefPicList(1-pcSlice->getColFromL0Flag()), pcSlice->getColRefIdx()); rpcPic->setNumDdvCandPics(rpcPic->getDisCandRefPictures(iColPoc)); } if(pcSlice->getViewIndex() && !pcSlice->getIsDepth() && !pcSlice->isIntra()) //Notes from QC: this condition shall be changed once the configuration is completed, e.g. in pcSlice->getSPS()->getMultiviewMvPredMode() || ARP in prev. HTM. Remove this comment once it is done. { rpcPic->checkTemporalIVRef(); } if(pcSlice->getIsDepth()) { rpcPic->checkTextureRef(); } #endif #if H_3D pcSlice->setDepthToDisparityLUTs(); #endif m_pcSbacDecoders[0].load(m_pcSbacDecoder); m_pcSliceDecoder->decompressSlice( ppcSubstreams, rpcPic, m_pcSbacDecoder, m_pcSbacDecoders); m_pcEntropyDecoder->setBitstream( ppcSubstreams[uiNumSubstreams-1] ); // deallocate all created substreams, including internal buffers. for (UInt ui = 0; ui < uiNumSubstreams; ui++) { ppcSubstreams[ui]->deleteFifo(); delete ppcSubstreams[ui]; } delete[] ppcSubstreams; delete[] m_pcSbacDecoders; m_pcSbacDecoders = NULL; delete[] m_pcBinCABACs; m_pcBinCABACs = NULL; m_dDecTime += (Double)(clock()-iBeforeTime) / CLOCKS_PER_SEC; }
/** decode motion information for every PU block. * \param pcCU * \param uiAbsPartIdx * \param uiDepth * \param pcSubCU * \returns Void */ Void TDecEntropy::decodePUWise( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, TComDataCU* pcSubCU ) { PartSize ePartSize = pcCU->getPartitionSize( uiAbsPartIdx ); UInt uiNumPU = ( ePartSize == SIZE_2Nx2N ? 1 : ( ePartSize == SIZE_NxN ? 4 : 2 ) ); UInt uiPUOffset = ( g_auiPUOffset[UInt( ePartSize )] << ( ( pcCU->getSlice()->getSPS()->getMaxCUDepth() - uiDepth ) << 1 ) ) >> 4; TComMvField cMvFieldNeighbours[MRG_MAX_NUM_CANDS << 1]; // double length for mv of both lists UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS]; for ( UInt ui = 0; ui < MRG_MAX_NUM_CANDS; ui++ ) { uhInterDirNeighbours[ui] = 0; } Int numValidMergeCand = 0; bool isMerged = false; pcSubCU->copyInterPredInfoFrom( pcCU, uiAbsPartIdx, REF_PIC_LIST_0 ); pcSubCU->copyInterPredInfoFrom( pcCU, uiAbsPartIdx, REF_PIC_LIST_1 ); for ( UInt uiPartIdx = 0, uiSubPartIdx = uiAbsPartIdx; uiPartIdx < uiNumPU; uiPartIdx++, uiSubPartIdx += uiPUOffset ) { decodeMergeFlag( pcCU, uiSubPartIdx, uiDepth, uiPartIdx ); if ( pcCU->getMergeFlag( uiSubPartIdx ) ) { decodeMergeIndex( pcCU, uiPartIdx, uiSubPartIdx, ePartSize, uhInterDirNeighbours, cMvFieldNeighbours, uiDepth ); UInt uiMergeIndex = pcCU->getMergeIndex(uiSubPartIdx); if ( pcCU->getSlice()->getPPS()->getLog2ParallelMergeLevelMinus2() && ePartSize != SIZE_2Nx2N && pcSubCU->getWidth( 0 ) <= 8 ) { pcSubCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uiDepth ); if ( !isMerged ) { pcSubCU->getInterMergeCandidates( 0, 0, uiDepth, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand ); isMerged = true; } pcSubCU->setPartSizeSubParts( ePartSize, 0, uiDepth ); } else { uiMergeIndex = pcCU->getMergeIndex(uiSubPartIdx); pcSubCU->getInterMergeCandidates( uiSubPartIdx-uiAbsPartIdx, uiPartIdx, uiDepth, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand, uiMergeIndex ); } pcCU->setInterDirSubParts( uhInterDirNeighbours[uiMergeIndex], uiSubPartIdx, uiPartIdx, uiDepth ); TComMv cTmpMv( 0, 0 ); for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ ) { if ( pcCU->getSlice()->getNumRefIdx( RefPicList( uiRefListIdx ) ) > 0 ) { pcCU->setMVPIdxSubParts( 0, RefPicList( uiRefListIdx ), uiSubPartIdx, uiPartIdx, uiDepth); pcCU->setMVPNumSubParts( 0, RefPicList( uiRefListIdx ), uiSubPartIdx, uiPartIdx, uiDepth); pcCU->getCUMvField( RefPicList( uiRefListIdx ) )->setAllMvd( cTmpMv, ePartSize, uiSubPartIdx, uiDepth, uiPartIdx ); pcCU->getCUMvField( RefPicList( uiRefListIdx ) )->setAllMvField( cMvFieldNeighbours[ 2*uiMergeIndex + uiRefListIdx ], ePartSize, uiSubPartIdx, uiDepth, uiPartIdx ); } } } else { decodeInterDirPU( pcCU, uiSubPartIdx, uiDepth, uiPartIdx ); for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ ) { if ( pcCU->getSlice()->getNumRefIdx( RefPicList( uiRefListIdx ) ) > 0 ) { decodeRefFrmIdxPU( pcCU, uiSubPartIdx, uiDepth, uiPartIdx, RefPicList( uiRefListIdx ) ); decodeMvdPU ( pcCU, uiSubPartIdx, uiDepth, uiPartIdx, RefPicList( uiRefListIdx ) ); decodeMVPIdxPU ( pcSubCU, uiSubPartIdx-uiAbsPartIdx, uiDepth, uiPartIdx, RefPicList( uiRefListIdx ) ); } } } if ( (pcCU->getInterDir(uiSubPartIdx) == 3) && pcSubCU->isBipredRestriction(uiPartIdx) ) { pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMv( TComMv(0,0), ePartSize, uiSubPartIdx, uiDepth, uiPartIdx); pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllRefIdx( -1, ePartSize, uiSubPartIdx, uiDepth, uiPartIdx); pcCU->setInterDirSubParts( 1, uiSubPartIdx, uiPartIdx, uiDepth); } } return; }