之前的学习中对encode函数进行了跟踪解读,在里面调用了compressGOP函数(代码太多了,看完得猴年马月,要人命,对付一下对付一下!),看到这个代码名字就联想到视频的编码过程了吧,视频先分成GOP(两种形式的GOP),然后GOP又可以分成Slice和Tile(片和块),再往下就是CTU了,而CTU是由CU构成的,是不是就可以立即推视频编码压缩等等操作主要就是再CU之间啦!

Void TEncGOP::compressGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic,TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsInGOP,Bool isField, Bool isTff, const InputColourSpaceConversion snr_conversion, const Bool printFrameMSE )
{// TODO: Split this function up.TComPic*        pcPic = NULL;TComPicYuv*     pcPicYuvRecOut;TComSlice*      pcSlice;TComOutputBitstream  *pcBitstreamRedirect;pcBitstreamRedirect = new TComOutputBitstream;AccessUnit::iterator  itLocationToPushSliceHeaderNALU; // used to store location where NALU containing slice header is to be insertedxInitGOP( iPOCLast, iNumPicRcvd, isField );m_iNumPicCoded = 0;SEIMessages leadingSeiMessages;SEIMessages nestedSeiMessages;SEIMessages duInfoSeiMessages;SEIMessages trailingSeiMessages;std::deque<DUData> duData;SEIDecodingUnitInfo decodingUnitInfoSEI;EfficientFieldIRAPMapping effFieldIRAPMap;if (m_pcCfg->getEfficientFieldIRAPEnabled()){effFieldIRAPMap.initialize(isField, m_iGopSize, iPOCLast, iNumPicRcvd, m_iLastIDR, this, m_pcCfg);}//重设flag指明图片是否已被编码 reset flag indicating whether pictures have been encodedfor ( Int iGOPid=0; iGOPid < m_iGopSize; iGOPid++ ){m_pcCfg->setEncodedFlag(iGOPid, false);}for ( Int iGOPid=0; iGOPid < m_iGopSize; iGOPid++ ){if (m_pcCfg->getEfficientFieldIRAPEnabled()){iGOPid=effFieldIRAPMap.adjustGOPid(iGOPid);}//每一个slice的用时-- For time output for each sliceclock_t iBeforeTime = clock();UInt uiColDir = calculateCollocatedFromL1Flag(m_pcCfg, iGOPid, m_iGopSize);/// 初始化开始编码Initial to start encodingInt iTimeOffset;Int pocCurr;if(iPOCLast == 0) //第一帧或者顶场的情况case first frame or first top field{pocCurr=0;iTimeOffset = 1;}else if(iPOCLast == 1 && isField) //底场的情况,和第一帧一样,poc计算不正确,我们自行设置正确的值case first bottom field, just like the first frame, the poc computation is not right anymore, we set the right value{pocCurr = 1;iTimeOffset = 1;}else{pocCurr = iPOCLast - iNumPicRcvd + m_pcCfg->getGOPEntry(iGOPid).m_POC - ((isField && m_iGopSize>1) ? 1:0);iTimeOffset = m_pcCfg->getGOPEntry(iGOPid).m_POC;}if(pocCurr>=m_pcCfg->getFramesToBeEncoded())//获取待编码帧{if (m_pcCfg->getEfficientFieldIRAPEnabled()){iGOPid=effFieldIRAPMap.restoreGOPid(iGOPid);}continue;}if( getNalUnitType(pocCurr, m_iLastIDR, isField) == NAL_UNIT_CODED_SLICE_IDR_W_RADL || getNalUnitType(pocCurr, m_iLastIDR, isField) == NAL_UNIT_CODED_SLICE_IDR_N_LP ){m_iLastIDR = pocCurr;}// start a new access unit: create an entry in the list of output access unitsaccessUnitsInGOP.push_back(AccessUnit());AccessUnit& accessUnit = accessUnitsInGOP.back();xGetBuffer( rcListPic, rcListPicYuvRecOut, iNumPicRcvd, iTimeOffset, pcPic, pcPicYuvRecOut, pocCurr, isField );//片数据初始化  Slice data initializationpcPic->clearSliceBuffer();pcPic->allocateNewSlice();m_pcSliceEncoder->setSliceIdx(0);pcPic->setCurrSliceIdx(0);m_pcSliceEncoder->initEncSlice ( pcPic, iPOCLast, pocCurr, iGOPid, pcSlice, isField );//设置帧或场的编码Set Frame/Field codingpcSlice->getPic()->setField(isField);pcSlice->setLastIDR(m_iLastIDR);pcSlice->setSliceIdx(0);//设置默认的片层标志和序列参数集的层标志一样 set default slice level flag to the same as SPS level flagpcSlice->setLFCrossSliceBoundaryFlag(  pcSlice->getPPS()->getLoopFilterAcrossSlicesEnabledFlag()  );if(pcSlice->getSliceType()==B_SLICE&&m_pcCfg->getGOPEntry(iGOPid).m_sliceType=='P'){pcSlice->setSliceType(P_SLICE);}if(pcSlice->getSliceType()==B_SLICE&&m_pcCfg->getGOPEntry(iGOPid).m_sliceType=='I'){pcSlice->setSliceType(I_SLICE);}// 设置NAL单元的类型 Set the nal unit typepcSlice->setNalUnitType(getNalUnitType(pocCurr, m_iLastIDR, isField));if(pcSlice->getTemporalLayerNonReferenceFlag()){if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_TRAIL_R &&!(m_iGopSize == 1 && pcSlice->getSliceType() == I_SLICE))// Add this condition to avoid POC issues with encoder_intra_main.cfg configuration (see #1127 in bug tracker){pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TRAIL_N);}if(pcSlice->getNalUnitType()==NAL_UNIT_CODED_SLICE_RADL_R){pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_RADL_N);}if(pcSlice->getNalUnitType()==NAL_UNIT_CODED_SLICE_RASL_R){pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_RASL_N);}}if (m_pcCfg->getEfficientFieldIRAPEnabled()){if ( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP|| pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL|| pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_N_LP|| pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL|| pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP|| pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA )  /*(随机接入点Intra Random Access Point) IRAP picture,一种IRAP(intra random access point)帧,称为BLA(broken link access picture)帧,这种帧一般用做两段序列之间的连接。功能类似IDR帧,但可能之后会跟随RASL帧。*/{m_associatedIRAPType = pcSlice->getNalUnitType();m_associatedIRAPPOC = pocCurr;}pcSlice->setAssociatedIRAPType(m_associatedIRAPType);pcSlice->setAssociatedIRAPPOC(m_associatedIRAPPOC);}// Do decoding refresh marking if anypcSlice->decodingRefreshMarking(m_pocCRA, m_bRefreshPending, rcListPic, m_pcCfg->getEfficientFieldIRAPEnabled());m_pcEncTop->selectReferencePictureSet(pcSlice, pocCurr, iGOPid);if (!m_pcCfg->getEfficientFieldIRAPEnabled()){if ( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP|| pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL|| pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_N_LP|| pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL|| pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP|| pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA )  // IRAP picture{m_associatedIRAPType = pcSlice->getNalUnitType();m_associatedIRAPPOC = pocCurr;}pcSlice->setAssociatedIRAPType(m_associatedIRAPType);pcSlice->setAssociatedIRAPPOC(m_associatedIRAPPOC);}if ((pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPS(), false, m_iLastRecoveryPicPOC, m_pcCfg->getDecodingRefreshType() == 3) != 0) || (pcSlice->isIRAP()) || (m_pcCfg->getEfficientFieldIRAPEnabled() && isField && pcSlice->getAssociatedIRAPType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getAssociatedIRAPType() <= NAL_UNIT_CODED_SLICE_CRA && pcSlice->getAssociatedIRAPPOC() == pcSlice->getPOC()+1)){pcSlice->createExplicitReferencePictureSetFromReference(rcListPic, pcSlice->getRPS(), pcSlice->isIRAP(), m_iLastRecoveryPicPOC, m_pcCfg->getDecodingRefreshType() == 3, m_pcCfg->getEfficientFieldIRAPEnabled());}pcSlice->applyReferencePictureSet(rcListPic, pcSlice->getRPS());if(pcSlice->getTLayer() > 0 &&  !( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RADL_N     // Check if not a leading picture|| pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RADL_R|| pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_N|| pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_R )){if(pcSlice->isTemporalLayerSwitchingPoint(rcListPic) || pcSlice->getSPS()->getTemporalIdNestingFlag()){if(pcSlice->getTemporalLayerNonReferenceFlag()){pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TSA_N);}else{pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TSA_R);}}else if(pcSlice->isStepwiseTemporalLayerSwitchingPointCandidate(rcListPic)){Bool isSTSA=true;for(Int ii=iGOPid+1;(ii<m_pcCfg->getGOPSize() && isSTSA==true);ii++){Int lTid= m_pcCfg->getGOPEntry(ii).m_temporalId;if(lTid==pcSlice->getTLayer()){const TComReferencePictureSet* nRPS = pcSlice->getSPS()->getRPSList()->getReferencePictureSet(ii);for(Int jj=0;jj<nRPS->getNumberOfPictures();jj++){if(nRPS->getUsed(jj)){Int tPoc=m_pcCfg->getGOPEntry(ii).m_POC+nRPS->getDeltaPOC(jj);Int kk=0;for(kk=0;kk<m_pcCfg->getGOPSize();kk++){if(m_pcCfg->getGOPEntry(kk).m_POC==tPoc){break;}}Int tTid=m_pcCfg->getGOPEntry(kk).m_temporalId;if(tTid >= pcSlice->getTLayer()){isSTSA=false;break;}}}}}if(isSTSA==true){if(pcSlice->getTemporalLayerNonReferenceFlag()){pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_N);}else{pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_R);}}}}arrangeLongtermPicturesInRPS(pcSlice, rcListPic);TComRefPicListModification* refPicListModification = pcSlice->getRefPicListModification();refPicListModification->setRefPicListModificationFlagL0(0);refPicListModification->setRefPicListModificationFlagL1(0);pcSlice->setNumRefIdx(REF_PIC_LIST_0,min(m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive,pcSlice->getRPS()->getNumberOfPictures()));pcSlice->setNumRefIdx(REF_PIC_LIST_1,min(m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive,pcSlice->getRPS()->getNumberOfPictures()));//设置参考图像列表  Set reference listpcSlice->setRefPicList ( rcListPic );//片信息细化  Slice info. refinementif ( (pcSlice->getSliceType() == B_SLICE) && (pcSlice->getNumRefIdx(REF_PIC_LIST_1) == 0) ){pcSlice->setSliceType ( P_SLICE );}pcSlice->setEncCABACTableIdx(m_pcSliceEncoder->getEncCABACTableIdx());if (pcSlice->getSliceType() == B_SLICE){pcSlice->setColFromL0Flag(1-uiColDir);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);}else{pcSlice->setCheckLDC(true);}uiColDir = 1-uiColDir;//-------------------------------------------------------------pcSlice->setRefPOCList();pcSlice->setList1IdxToList0Idx();if (m_pcEncTop->getTMVPModeId() == 2){if (iGOPid == 0) // first picture in SOP (i.e. forward B){pcSlice->setEnableTMVPFlag(0);}else{// Note: pcSlice->getColFromL0Flag() is assumed to be always 0 and getcolRefIdx() is always 0.pcSlice->setEnableTMVPFlag(1);}}else if (m_pcEncTop->getTMVPModeId() == 1){pcSlice->setEnableTMVPFlag(1);}else{pcSlice->setEnableTMVPFlag(0);}///对于片的压缩 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());Double lambda            = 0.0;Int actualHeadBits       = 0;Int actualTotalBits      = 0;Int estimatedBits        = 0;Int tmpBitsBeforeWriting = 0;if ( m_pcCfg->getUseRateCtrl() ) // TODO: does this work with multiple slices and slice-segments?{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 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); // TODO: This only analyses the first slice segment - what about the others?if ( m_pcCfg->getIntraPeriod() != 1 )   //并不是改善所有的帧内编码分配bit 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;}//比特数小于200的话就等于200m_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()->getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, sliceQP );m_pcRateCtrl->getRCPic()->setPicEstQP( sliceQP );m_pcSliceEncoder->resetQP( pcPic, sliceQP, lambda );}UInt uiNumSliceSegments = 1;// 安排编码器,现在tile的数量已知  Allocate some coders, now the number of tiles are known.const Int numSubstreamsColumns = (pcSlice->getPPS()->getNumTileColumnsMinus1() + 1);const Int numSubstreamRows     = pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag() ? pcPic->getFrameHeightInCtus() : (pcSlice->getPPS()->getNumTileRowsMinus1() + 1);const Int numSubstreams        = numSubstreamRows * numSubstreamsColumns;std::vector<TComOutputBitstream> substreamsOut(numSubstreams);// now compress (trial encode) the various slice segments (slices, and dependent slices){const UInt numberOfCtusInFrame=pcPic->getPicSym()->getNumberOfCtusInFrame();pcSlice->setSliceCurStartCtuTsAddr( 0 );pcSlice->setSliceSegmentCurStartCtuTsAddr( 0 );for(UInt nextCtuTsAddr = 0; nextCtuTsAddr < numberOfCtusInFrame; ){m_pcSliceEncoder->precompressSlice( pcPic );m_pcSliceEncoder->compressSlice   ( pcPic, false, false );const UInt curSliceSegmentEnd = pcSlice->getSliceSegmentCurEndCtuTsAddr();if (curSliceSegmentEnd < numberOfCtusInFrame){const Bool bNextSegmentIsDependentSlice=curSliceSegmentEnd<pcSlice->getSliceCurEndCtuTsAddr();const UInt sliceBits=pcSlice->getSliceBits();pcPic->allocateNewSlice();//准备下一层 prepare for next slicepcPic->setCurrSliceIdx                    ( uiNumSliceSegments );m_pcSliceEncoder->setSliceIdx             ( uiNumSliceSegments   );pcSlice = pcPic->getSlice                 ( uiNumSliceSegments   );assert(pcSlice->getPPS()!=0);pcSlice->copySliceInfo                    ( pcPic->getSlice(uiNumSliceSegments-1)  );pcSlice->setSliceIdx                      ( uiNumSliceSegments   );if (bNextSegmentIsDependentSlice){pcSlice->setSliceBits(sliceBits);}else{pcSlice->setSliceCurStartCtuTsAddr      ( curSliceSegmentEnd );pcSlice->setSliceBits(0);}pcSlice->setDependentSliceSegmentFlag(bNextSegmentIsDependentSlice);pcSlice->setSliceSegmentCurStartCtuTsAddr ( curSliceSegmentEnd );// TODO: optimise cabac_init during compress slice to improve multi-slice operation// pcSlice->setEncCABACTableIdx(m_pcSliceEncoder->getEncCABACTableIdx());uiNumSliceSegments ++;}nextCtuTsAddr = curSliceSegmentEnd;}}duData.clear();pcSlice = pcPic->getSlice(0);//自适应样点补偿参数估计利用的是 SAO parameter estimation using non-deblocked pixels for CTU bottom and right boundary areasif( pcSlice->getSPS()->getUseSAO() && m_pcCfg->getSaoCtuBoundary() )//获取ctu边界{m_pcSAO->getPreDBFStatistics(pcPic);}//-- Loop filter环路滤波器Bool bLFCrossTileBoundary = pcSlice->getPPS()->getLoopFilterAcrossTilesEnabledFlag();m_pcLoopFilter->setCfg(bLFCrossTileBoundary);if ( m_pcCfg->getDeblockingFilterMetric() ){applyDeblockingFilterMetric(pcPic, uiNumSliceSegments);}m_pcLoopFilter->loopFilterPic( pcPic );/// File writing输出文件// Set entropy coder设置熵编码器m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder );if ( m_bSeqFirst ){// write various parameter sets写参数集actualTotalBits += xWriteParameterSets(accessUnit, pcSlice);// create prefix SEI messages at the beginning of the sequenceassert(leadingSeiMessages.empty());xCreateIRAPLeadingSEIMessages(leadingSeiMessages, pcSlice->getSPS(), pcSlice->getPPS());m_bSeqFirst = false;}// reset presence of BP SEI indicationm_bufferingPeriodSEIPresentInAU = false;// create prefix SEI associated with a picturexCreatePerPictureSEIMessages(iGOPid, leadingSeiMessages, nestedSeiMessages, pcSlice);/* use the main bitstream buffer for storing the marshalled picture */m_pcEntropyCoder->setBitstream(NULL);pcSlice = pcPic->getSlice(0);if (pcSlice->getSPS()->getUseSAO()){Bool sliceEnabled[MAX_NUM_COMPONENT];TComBitCounter tempBitCounter;tempBitCounter.resetBits();m_pcEncTop->getRDGoOnSbacCoder()->setBitstream(&tempBitCounter);m_pcSAO->initRDOCabacCoder(m_pcEncTop->getRDGoOnSbacCoder(), pcSlice);m_pcSAO->SAOProcess(pcPic, sliceEnabled, pcPic->getSlice(0)->getLambdas(), m_pcCfg->getTestSAODisableAtPictureLevel(), m_pcCfg->getSaoEncodingRate(), m_pcCfg->getSaoEncodingRateChroma(), m_pcCfg->getSaoCtuBoundary());m_pcSAO->PCMLFDisableProcess(pcPic);m_pcEncTop->getRDGoOnSbacCoder()->setBitstream(NULL);//assign SAO slice headerfor(Int s=0; s< uiNumSliceSegments; s++){pcPic->getSlice(s)->setSaoEnabledFlag(CHANNEL_TYPE_LUMA, sliceEnabled[COMPONENT_Y]);assert(sliceEnabled[COMPONENT_Cb] == sliceEnabled[COMPONENT_Cr]);pcPic->getSlice(s)->setSaoEnabledFlag(CHANNEL_TYPE_CHROMA, sliceEnabled[COMPONENT_Cb]);}}// pcSlice is currently slice 0.std::size_t binCountsInNalUnits   = 0; // For implementation of cabac_zero_word stuffing (section 7.4.3.10)std::size_t numBytesInVclNalUnits = 0; // For implementation of cabac_zero_word stuffing (section 7.4.3.10)for( UInt sliceSegmentStartCtuTsAddr = 0, sliceIdxCount=0; sliceSegmentStartCtuTsAddr < pcPic->getPicSym()->getNumberOfCtusInFrame(); sliceIdxCount++, sliceSegmentStartCtuTsAddr=pcSlice->getSliceSegmentCurEndCtuTsAddr() ){pcSlice = pcPic->getSlice(sliceIdxCount);if(sliceIdxCount > 0 && pcSlice->getSliceType()!= I_SLICE){pcSlice->checkColRefIdx(sliceIdxCount, pcPic);}pcPic->setCurrSliceIdx(sliceIdxCount);m_pcSliceEncoder->setSliceIdx(sliceIdxCount);pcSlice->setRPS(pcPic->getSlice(0)->getRPS());pcSlice->setRPSidx(pcPic->getSlice(0)->getRPSidx());for ( UInt ui = 0 ; ui < numSubstreams; ui++ ){substreamsOut[ui].clear();}m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder );m_pcEntropyCoder->resetEntropy      ( pcSlice );/* start slice NALunit */OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->getTLayer() );m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);pcSlice->setNoRaslOutputFlag(false);if (pcSlice->isIRAP()){if (pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_IDR_N_LP){pcSlice->setNoRaslOutputFlag(true);}//the inference for NoOutputPriorPicsFlag// KJS: This cannot happen at the encoderif (!m_bFirst && pcSlice->isIRAP() && pcSlice->getNoRaslOutputFlag()){if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA){pcSlice->setNoOutputPriorPicsFlag(true);}}}pcSlice->setEncCABACTableIdx(m_pcSliceEncoder->getEncCABACTableIdx());tmpBitsBeforeWriting = m_pcEntropyCoder->getNumberOfWrittenBits();m_pcEntropyCoder->encodeSliceHeader(pcSlice);actualHeadBits += ( m_pcEntropyCoder->getNumberOfWrittenBits() - tmpBitsBeforeWriting );pcSlice->setFinalized(true);pcSlice->clearSubstreamSizes(  );{UInt numBinsCoded = 0;m_pcSliceEncoder->encodeSlice(pcPic, &(substreamsOut[0]), numBinsCoded);binCountsInNalUnits+=numBinsCoded;}{// Construct the final bitstream by concatenating substreams.// The final bitstream is either nalu.m_Bitstream or pcBitstreamRedirect;// Complete the slice header info.m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder );m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);m_pcEntropyCoder->encodeTilesWPPEntryPoint( pcSlice );// Append substreams...TComOutputBitstream *pcOut = pcBitstreamRedirect;const Int numZeroSubstreamsAtStartOfSlice  = pcPic->getSubstreamForCtuAddr(pcSlice->getSliceSegmentCurStartCtuTsAddr(), false, pcSlice);const Int numSubstreamsToCode  = pcSlice->getNumberOfSubstreamSizes()+1;for ( UInt ui = 0 ; ui < numSubstreamsToCode; ui++ ){pcOut->addSubstream(&(substreamsOut[ui+numZeroSubstreamsAtStartOfSlice]));}}// If current NALU is the first NALU of slice (containing slice header) and more NALUs exist (due to multiple dependent slices) then buffer it.// If current NALU is the last NALU of slice and a NALU was buffered, then (a) Write current NALU (b) Update an write buffered NALU at approproate location in NALU list.Bool bNALUAlignedWrittenToList    = false; // used to ensure current NALU is not written more than once to the NALU list.xAttachSliceDataToNalUnit(nalu, pcBitstreamRedirect);accessUnit.push_back(new NALUnitEBSP(nalu));actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;numBytesInVclNalUnits += (std::size_t)(accessUnit.back()->m_nalUnitData.str().size());bNALUAlignedWrittenToList = true;if (!bNALUAlignedWrittenToList){nalu.m_Bitstream.writeAlignZero();accessUnit.push_back(new NALUnitEBSP(nalu));}if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() )|| ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) &&( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getSubPicCpbParamsPresentFlag() ) ){UInt numNalus = 0;UInt numRBSPBytes = 0;for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++){numRBSPBytes += UInt((*it)->m_nalUnitData.str().size());numNalus ++;}duData.push_back(DUData());duData.back().accumBitsDU = ( numRBSPBytes << 3 );duData.back().accumNalsDU = numNalus;}} // end iteration over slices// cabac_zero_words processingcabac_zero_word_padding(pcSlice, pcPic, binCountsInNalUnits, numBytesInVclNalUnits, accessUnit.back()->m_nalUnitData, m_pcCfg->getCabacZeroWordPaddingEnabled());pcPic->compressMotion();//-- For time output for each sliceDouble dEncTime = (Double)(clock()-iBeforeTime) / CLOCKS_PER_SEC;std::string digestStr;if (m_pcCfg->getDecodedPictureHashSEIEnabled()){SEIDecodedPictureHash *decodedPictureHashSei = new SEIDecodedPictureHash();m_seiEncoder.initDecodedPictureHashSEI(decodedPictureHashSei, pcPic, digestStr, pcSlice->getSPS()->getBitDepths());trailingSeiMessages.push_back(decodedPictureHashSei);}xWriteTrailingSEIMessages(trailingSeiMessages, accessUnit, pcSlice->getTLayer(), pcSlice->getSPS());m_pcCfg->setEncodedFlag(iGOPid, true);xCalculateAddPSNRs( isField, isTff, iGOPid, pcPic, accessUnit, rcListPic, dEncTime, snr_conversion, printFrameMSE );if (!digestStr.empty()){if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 1){printf(" [MD5:%s]", digestStr.c_str());}else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 2){printf(" [CRC:%s]", digestStr.c_str());}else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 3){printf(" [Checksum:%s]", digestStr.c_str());}}if ( m_pcCfg->getUseRateCtrl() ){Double avgQP     = m_pcRateCtrl->getRCPic()->calAverageQP();Double avgLambda = m_pcRateCtrl->getRCPic()->calAverageLambda();if ( avgLambda < 0.0 ){avgLambda = lambda;}m_pcRateCtrl->getRCPic()->updateAfterPicture( actualHeadBits, actualTotalBits, avgQP, avgLambda, pcSlice->getSliceType());m_pcRateCtrl->getRCPic()->addToPictureLsit( m_pcRateCtrl->getPicList() );m_pcRateCtrl->getRCSeq()->updateAfterPic( actualTotalBits );if ( pcSlice->getSliceType() != I_SLICE ){m_pcRateCtrl->getRCGOP()->updateAfterPicture( actualTotalBits );}else    // for intra picture, the estimated bits are used to update the current status in the GOP{m_pcRateCtrl->getRCGOP()->updateAfterPicture( estimatedBits );}}xCreatePictureTimingSEI(m_pcCfg->getEfficientFieldIRAPEnabled()?effFieldIRAPMap.GetIRAPGOPid():0, leadingSeiMessages, nestedSeiMessages, duInfoSeiMessages, pcSlice, isField, duData);if (m_pcCfg->getScalableNestingSEIEnabled()){xCreateScalableNestingSEI (leadingSeiMessages, nestedSeiMessages);}xWriteLeadingSEIMessages(leadingSeiMessages, duInfoSeiMessages, accessUnit, pcSlice->getTLayer(), pcSlice->getSPS(), duData);xWriteDuSEIMessages(duInfoSeiMessages, accessUnit, pcSlice->getTLayer(), pcSlice->getSPS(), duData);pcPic->getPicYuvRec()->copyToPic(pcPicYuvRecOut);pcPic->setReconMark   ( true );m_bFirst = false;m_iNumPicCoded++;m_totalCoded ++;/* logging: insert a newline at end of picture period */printf("\n");fflush(stdout);if (m_pcCfg->getEfficientFieldIRAPEnabled()){iGOPid=effFieldIRAPMap.restoreGOPid(iGOPid);}} // iGOPid-loopdelete pcBitstreamRedirect;assert ( (m_iNumPicCoded == iNumPicRcvd) );
}Void TEncGOP::printOutSummary(UInt uiNumAllPicCoded, Bool isField, const Bool printMSEBasedSNR, const Bool printSequenceMSE, const BitDepths &bitDepths)
{assert (uiNumAllPicCoded == m_gcAnalyzeAll.getNumPic());//--CFG_KDYconst Int rateMultiplier=(isField?2:1);m_gcAnalyzeAll.setFrmRate( m_pcCfg->getFrameRate()*rateMultiplier );m_gcAnalyzeI.setFrmRate( m_pcCfg->getFrameRate()*rateMultiplier );m_gcAnalyzeP.setFrmRate( m_pcCfg->getFrameRate()*rateMultiplier );m_gcAnalyzeB.setFrmRate( m_pcCfg->getFrameRate()*rateMultiplier );const ChromaFormat chFmt = m_pcCfg->getChromaFormatIdc();//-- allprintf( "\n\nSUMMARY --------------------------------------------------------\n" );m_gcAnalyzeAll.printOut('a', chFmt, printMSEBasedSNR, printSequenceMSE, bitDepths);printf( "\n\nI Slices--------------------------------------------------------\n" );m_gcAnalyzeI.printOut('i', chFmt, printMSEBasedSNR, printSequenceMSE, bitDepths);printf( "\n\nP Slices--------------------------------------------------------\n" );m_gcAnalyzeP.printOut('p', chFmt, printMSEBasedSNR, printSequenceMSE, bitDepths);printf( "\n\nB Slices--------------------------------------------------------\n" );m_gcAnalyzeB.printOut('b', chFmt, printMSEBasedSNR, printSequenceMSE, bitDepths);if (!m_pcCfg->getSummaryOutFilename().empty()){m_gcAnalyzeAll.printSummary(chFmt, printSequenceMSE, bitDepths, m_pcCfg->getSummaryOutFilename());}if (!m_pcCfg->getSummaryPicFilenameBase().empty()){m_gcAnalyzeI.printSummary(chFmt, printSequenceMSE, bitDepths, m_pcCfg->getSummaryPicFilenameBase()+"I.txt");m_gcAnalyzeP.printSummary(chFmt, printSequenceMSE, bitDepths, m_pcCfg->getSummaryPicFilenameBase()+"P.txt");m_gcAnalyzeB.printSummary(chFmt, printSequenceMSE, bitDepths, m_pcCfg->getSummaryPicFilenameBase()+"B.txt");}if(isField){//-- interlaced summarym_gcAnalyzeAll_in.setFrmRate( m_pcCfg->getFrameRate());m_gcAnalyzeAll_in.setBits(m_gcAnalyzeAll.getBits());// prior to the above statement, the interlace analyser does not contain the correct total number of bits.printf( "\n\nSUMMARY INTERLACED ---------------------------------------------\n" );m_gcAnalyzeAll_in.printOut('a', chFmt, printMSEBasedSNR, printSequenceMSE, bitDepths);if (!m_pcCfg->getSummaryOutFilename().empty()){m_gcAnalyzeAll_in.printSummary(chFmt, printSequenceMSE, bitDepths, m_pcCfg->getSummaryOutFilename());}}printf("\nRVM: %.3lf\n" , xCalculateRVM());
}Void TEncGOP::preLoopFilterPicAll( TComPic* pcPic, UInt64& ruiDist )
{Bool bCalcDist = false;m_pcLoopFilter->setCfg(m_pcCfg->getLFCrossTileBoundaryFlag());m_pcLoopFilter->loopFilterPic( pcPic );if (!bCalcDist){ruiDist = xFindDistortionFrame(pcPic->getPicYuvOrg(), pcPic->getPicYuvRec(), pcPic->getPicSym()->getSPS().getBitDepths());}
}

compressGOP函数代码跟踪相关推荐

  1. HEVC编码框架和main函数代码跟踪解读

    刚入学的时候导师安排的是看Hevc,虽然后面转头去做别的东西了,不过还是想着把自己学习的皮毛记录下来叭! 嗯,主要的框架图看到这篇文章写的很好,可以帮助我们进行代码跟踪 化简之后的图为: 代码我们从一 ...

  2. compressSlice函数代码跟踪

    西巴,上篇随便对付了一下关于GOP的函数,那接下来当然是对付Slice函数啦! Void TEncSlice::compressSlice( TComPic* pcPic, const Bool bC ...

  3. 用Debug函数实现API函数的跟踪

    用Debug函数实现API函数的跟踪 如果我们能自己编写一个类似调试器的功能,这个调试器需要实现我们对于跟踪监视工具的要求,即自动记录输入输出参数,自动让目标进程继续运行.下面我们就来介绍在不知道函数 ...

  4. 安卓代码跟踪方式学习笔记

    一.代码跟踪的介绍&使用工具 代码跟踪常用于调试程序中,跟踪并了解程序的执行轨迹和执行逻辑.这样来说,对Java这样的高级语言来说,我们容易理解也容易调试.但是像一些低级语言,例如ASM.Sm ...

  5. ThinkPHP3.2 G函数代码及 使用方法

    ThinkPHP3.2 G函数代码及 使用方法 代码: // 内存是否可调用 define('MEMORY_LIMIT_ON',function_exists('memory_get_usage')) ...

  6. php三个数字比较大小排序,php中常用的4种实现数字大小排序的冒泡选择等算法函数代码...

    分别用冒泡排序法,快速排序法,选择排序法,插入排序法将下面数组中按照从小到大的顺序进行排序. 本站收录这篇文章php中常用的4种实现数字大小排序的冒泡选择等算法函数代码,详细解说文章中相关排序 冒泡 ...

  7. 2.函数(代码的整洁之道)

    2.函数(代码的整洁之道) 目录 短小 只做一件事 每个函数一个抽象层次 switch语句 使用描述性的名称 函数参数 无副作用 分隔指令与询问 使用异常代替返回的错误码 别重复自己 结构化编程 如何 ...

  8. python转换函数使用_python进制转换函数代码的使用

    python进制转换函数代码的使用 发布时间:2020-04-23 10:23:22 来源:亿速云 阅读:188 作者:小新 以上就是python进制转换函数代码的使用的详细内容了,看完之后是否有所收 ...

  9. python第一条入门程序_Python语言函数代码的执行流程

    https://www.xin3721.com/eschool/pythonxin3721/ Python语言函数代码的执行流程,为了保证函数的定义先于其首次调用时执行,我们需要知道中语句的执行顺序. ...

最新文章

  1. VB调用C#写的WinForm.NET控件
  2. 02.iOS开发网络篇—HTTP协议
  3. php 支付加密,关于支付时rsa加密解密的函数
  4. 【转】刨根究底字符编码之十一——UTF-8编码方式与字节序标记BOM
  5. java中id name_关于DOM对象中的id与name的区别
  6. android p获取通话记录_Android 底层的进程间同步机制
  7. WPS多版本残留_软件分享猫 wps会员的获取
  8. 学生个人网页设计作品 学生个人网页模板 简单个人主页成品 个人网页制作 HTML学生个人网站作业设计
  9. C#练习题答案: 卡塔劳尔【难度:1级】--景越C#经典编程题库,1000道C#基础练习题等你来挑战
  10. 【电子知识摘要】合金电阻
  11. 深度Linux关闭搜狗后没法输入,在Deepin系统中搜狗输入法问题反馈和一些问题的解决方法...
  12. JavaEE简易聊天室(Netbeans:Servlet+Cookie+Session)
  13. 为什么我总是更新不了头像啊
  14. Java实现OPC UA Client直接与PLC通讯
  15. openlayers5之ol.proj坐标转换
  16. 上海-亚马逊AWS联合创新中心正式启用
  17. 【MATLAB】符号矩阵计算与化简
  18. 魔趣刷机(macos)实操(mi6)
  19. 大数据和AI 论文目录汇总
  20. 不同地图坐标系的经纬度转换方法

热门文章

  1. 逻辑回归 - 理论篇
  2. SpringBoot2+Netty+WebSocket(netty实现websocket,支持URL参数)
  3. Faster R-CNN文章详细解读
  4. SpringBoot请求报403 Forbidden
  5. 阿里内部信:构建“大中台、小前台”组织机制
  6. 通过无线网络实现两台计算机共享打印机共享,教你两招实现无线网络共享打印机...
  7. linux tomcat 无法关闭 :8005端口未启动
  8. Splitter Control for Dialog
  9. 安卓在GooglePlay上线后同时平板也能搜到
  10. python使用selenium模块实现火车票的自动购买