compressSlice函数代码跟踪
西巴,上篇随便对付了一下关于GOP的函数,那接下来当然是对付Slice函数啦!
Void TEncSlice::compressSlice( TComPic* pcPic, const Bool bCompressEntireSlice, const Bool bFastDeltaQP )
{// if bCompressEntireSlice is true, then the entire slice (not slice segment) is compressed,// effectively disabling the slice-segment-mode.UInt startCtuTsAddr;UInt boundingCtuTsAddr;TComSlice* const pcSlice = pcPic->getSlice(getSliceIdx());pcSlice->setSliceSegmentBits(0);xDetermineStartAndBoundingCtuTsAddr ( startCtuTsAddr, boundingCtuTsAddr, pcPic );if (bCompressEntireSlice){boundingCtuTsAddr = pcSlice->getSliceCurEndCtuTsAddr();pcSlice->setSliceSegmentCurEndCtuTsAddr(boundingCtuTsAddr);}// initialize cost values - these are used by precompressSlice (they should be parameters).m_uiPicTotalBits = 0;m_dPicRdCost = 0; // NOTE: This is a write-only variable!m_uiPicDist = 0;m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST] );m_pcEntropyCoder->resetEntropy ( pcSlice );TEncBinCABAC* pRDSbacCoder = (TEncBinCABAC *) m_pppcRDSbacCoder[0][CI_CURR_BEST]->getEncBinIf();pRDSbacCoder->setBinCountingEnableFlag( false );pRDSbacCoder->setBinsCoded( 0 );TComBitCounter tempBitCounter;const UInt frameWidthInCtus = pcPic->getPicSym()->getFrameWidthInCtus();m_pcCuEncoder->setFastDeltaQp(bFastDeltaQP);//------------------------------------------------------------------------------// Weighted Prediction parameters estimation.//------------------------------------------------------------------------------// calculate AC/DC values for current pictureif( pcSlice->getPPS()->getUseWP() || pcSlice->getPPS()->getWPBiPred() ){xCalcACDCParamSlice(pcSlice);}const Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPred());if ( bWp_explicit ){//------------------------------------------------------------------------------// Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet.//------------------------------------------------------------------------------if ( pcSlice->getSliceMode()==FIXED_NUMBER_OF_BYTES || pcSlice->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES ){printf("Weighted Prediction is not supported with slice mode determined by max number of bins.\n"); exit(0);}xEstimateWPParamSlice( pcSlice );pcSlice->initWpScaling(pcSlice->getSPS());// check WP on/offxCheckWPEnable( pcSlice );}#if ADAPTIVE_QP_SELECTIONif( m_pcCfg->getUseAdaptQpSelect() && !(pcSlice->getDependentSliceSegmentFlag())){// TODO: this won't work with dependent slices: they do not have their own QP. Check fix to mask clause execution with && !(pcSlice->getDependentSliceSegmentFlag())m_pcTrQuant->clearSliceARLCnt(); // TODO: this looks wrong for multiple slices - the results of all but the last slice will be cleared before they are used (all slices compressed, and then all slices encoded)if(pcSlice->getSliceType()!=I_SLICE){Int qpBase = pcSlice->getSliceQpBase();pcSlice->setSliceQp(qpBase + m_pcTrQuant->getQpDelta(qpBase));}}
#endif// Adjust initial state if this is the start of a dependent slice.{const UInt ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap( startCtuTsAddr);const UInt currentTileIdx = pcPic->getPicSym()->getTileIdxMap(ctuRsAddr);const TComTile *pCurrentTile = pcPic->getPicSym()->getTComTile(currentTileIdx);const UInt firstCtuRsAddrOfTile = pCurrentTile->getFirstCtuRsAddr();if( pcSlice->getDependentSliceSegmentFlag() && ctuRsAddr != firstCtuRsAddrOfTile ){// This will only occur if dependent slice-segments (m_entropyCodingSyncContextState=true) are being used.if( pCurrentTile->getTileWidthInCtus() >= 2 || !m_pcCfg->getWaveFrontsynchro() ){m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( &m_lastSliceSegmentEndContextState );}}}// for every CTU in the slice segment (may terminate sooner if there is a byte limit on the slice-segment)for( UInt ctuTsAddr = startCtuTsAddr; ctuTsAddr < boundingCtuTsAddr; ++ctuTsAddr ){const UInt ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap(ctuTsAddr);// initialize CTU encoderTComDataCU* pCtu = pcPic->getCtu( ctuRsAddr );pCtu->initCtu( pcPic, ctuRsAddr );// update CABAC stateconst UInt firstCtuRsAddrOfTile = pcPic->getPicSym()->getTComTile(pcPic->getPicSym()->getTileIdxMap(ctuRsAddr))->getFirstCtuRsAddr();const UInt tileXPosInCtus = firstCtuRsAddrOfTile % frameWidthInCtus;const UInt ctuXPosInCtus = ctuRsAddr % frameWidthInCtus;if (ctuRsAddr == firstCtuRsAddrOfTile){m_pppcRDSbacCoder[0][CI_CURR_BEST]->resetEntropy(pcSlice);}else if ( ctuXPosInCtus == tileXPosInCtus && m_pcCfg->getWaveFrontsynchro()){// reset and then update contexts to the state at the end of the top-right CTU (if within current slice and tile).m_pppcRDSbacCoder[0][CI_CURR_BEST]->resetEntropy(pcSlice);// Sync if the Top-Right is available.TComDataCU *pCtuUp = pCtu->getCtuAbove();if ( pCtuUp && ((ctuRsAddr%frameWidthInCtus+1) < frameWidthInCtus) ){TComDataCU *pCtuTR = pcPic->getCtu( ctuRsAddr - frameWidthInCtus + 1 );if ( pCtu->CUIsFromSameSliceAndTile(pCtuTR) ){// Top-Right is available, we use it.m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( &m_entropyCodingSyncContextState );}}}// set go-on entropy coder (used for all trial encodings - the cu encoder and encoder search also have a copy of the same pointer)m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder );m_pcEntropyCoder->setBitstream( &tempBitCounter );tempBitCounter.resetBits();m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] ); // this copy is not strictly necessary here, but indicates that the GoOnSbacCoder// is reset to a known state before every decision process.((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);Double oldLambda = m_pcRdCost->getLambda();if ( m_pcCfg->getUseRateCtrl() ){Int estQP = pcSlice->getSliceQp();Double estLambda = -1.0;Double bpp = -1.0;if ( ( pcPic->getSlice( 0 )->getSliceType() == I_SLICE && m_pcCfg->getForceIntraQP() ) || !m_pcCfg->getLCULevelRC() ){estQP = pcSlice->getSliceQp();}else{bpp = m_pcRateCtrl->getRCPic()->getLCUTargetBpp(pcSlice->getSliceType());if ( pcPic->getSlice( 0 )->getSliceType() == I_SLICE){estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambdaAndQP(bpp, pcSlice->getSliceQp(), &estQP);}else{estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );estQP = m_pcRateCtrl->getRCPic()->getLCUEstQP ( estLambda, pcSlice->getSliceQp() );}estQP = Clip3( -pcSlice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, estQP );m_pcRdCost->setLambda(estLambda, pcSlice->getSPS()->getBitDepths());#if RDOQ_CHROMA_LAMBDA// set lambda for RDOQconst Double chromaLambda = estLambda / m_pcRdCost->getChromaWeight();const Double lambdaArray[MAX_NUM_COMPONENT] = { estLambda, chromaLambda, chromaLambda };m_pcTrQuant->setLambdas( lambdaArray );
#elsem_pcTrQuant->setLambda( estLambda );
#endif}m_pcRateCtrl->setRCQP( estQP );
#if ADAPTIVE_QP_SELECTIONpCtu->getSlice()->setSliceQpBase( estQP );
#endif}// run CTU trial encoderm_pcCuEncoder->compressCtu( pCtu );// All CTU decisions have now been made. Restore entropy coder to an initial stage, ready to make a true encode,// which will result in the state of the contexts being correct. It will also count up the number of bits coded,// which is used if there is a limit of the number of bytes per slice-segment.m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST] );m_pcEntropyCoder->setBitstream( &tempBitCounter );pRDSbacCoder->setBinCountingEnableFlag( true );m_pppcRDSbacCoder[0][CI_CURR_BEST]->resetBits();pRDSbacCoder->setBinsCoded( 0 );// encode CTU and calculate the true bit counters.m_pcCuEncoder->encodeCtu( pCtu );pRDSbacCoder->setBinCountingEnableFlag( false );const Int numberOfWrittenBits = m_pcEntropyCoder->getNumberOfWrittenBits();// Calculate if this CTU puts us over slice bit size.// cannot terminate if current slice/slice-segment would be 0 Ctu in size,const UInt validEndOfSliceCtuTsAddr = ctuTsAddr + (ctuTsAddr == startCtuTsAddr ? 1 : 0);// Set slice end parameterif(pcSlice->getSliceMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceBits()+numberOfWrittenBits > (pcSlice->getSliceArgument()<<3)){pcSlice->setSliceSegmentCurEndCtuTsAddr(validEndOfSliceCtuTsAddr);pcSlice->setSliceCurEndCtuTsAddr(validEndOfSliceCtuTsAddr);boundingCtuTsAddr=validEndOfSliceCtuTsAddr;}else if((!bCompressEntireSlice) && pcSlice->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+numberOfWrittenBits > (pcSlice->getSliceSegmentArgument()<<3)){pcSlice->setSliceSegmentCurEndCtuTsAddr(validEndOfSliceCtuTsAddr);boundingCtuTsAddr=validEndOfSliceCtuTsAddr;}if (boundingCtuTsAddr <= ctuTsAddr){break;}pcSlice->setSliceBits( (UInt)(pcSlice->getSliceBits() + numberOfWrittenBits) );pcSlice->setSliceSegmentBits(pcSlice->getSliceSegmentBits()+numberOfWrittenBits);// Store probabilities of second CTU in line into buffer - used only if wavefront-parallel-processing is enabled.if ( ctuXPosInCtus == tileXPosInCtus+1 && m_pcCfg->getWaveFrontsynchro()){m_entropyCodingSyncContextState.loadContexts(m_pppcRDSbacCoder[0][CI_CURR_BEST]);}if ( m_pcCfg->getUseRateCtrl() ){Int actualQP = g_RCInvalidQPValue;Double actualLambda = m_pcRdCost->getLambda();Int actualBits = pCtu->getTotalBits();Int numberOfEffectivePixels = 0;for ( Int idx = 0; idx < pcPic->getNumPartitionsInCtu(); idx++ ){if ( pCtu->getPredictionMode( idx ) != NUMBER_OF_PREDICTION_MODES && ( !pCtu->isSkipped( idx ) ) ){numberOfEffectivePixels = numberOfEffectivePixels + 16;break;}}if ( numberOfEffectivePixels == 0 ){actualQP = g_RCInvalidQPValue;}else{actualQP = pCtu->getQP( 0 );}m_pcRdCost->setLambda(oldLambda, pcSlice->getSPS()->getBitDepths());m_pcRateCtrl->getRCPic()->updateAfterCTU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda,pCtu->getSlice()->getSliceType() == I_SLICE ? 0 : m_pcCfg->getLCULevelRC() );}m_uiPicTotalBits += pCtu->getTotalBits();m_dPicRdCost += pCtu->getTotalCost();m_uiPicDist += pCtu->getTotalDistortion();}// store context state at the end of this slice-segment, in case the next slice is a dependent slice and continues using the CABAC contexts.if( pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag() ){m_lastSliceSegmentEndContextState.loadContexts( m_pppcRDSbacCoder[0][CI_CURR_BEST] );//ctx end of dep.slice}// stop use of temporary bit counter object.m_pppcRDSbacCoder[0][CI_CURR_BEST]->setBitstream(NULL);m_pcRDGoOnSbacCoder->setBitstream(NULL); // stop use of tempBitCounter.// TODO: optimise cabac_init during compress slice to improve multi-slice operation//if (pcSlice->getPPS()->getCabacInitPresentFlag() && !pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())//{// m_encCABACTableIdx = m_pcEntropyCoder->determineCabacInitIdx();//}//else//{// m_encCABACTableIdx = pcSlice->getSliceType();//}
}
compressSlice函数代码跟踪相关推荐
- HEVC编码框架和main函数代码跟踪解读
刚入学的时候导师安排的是看Hevc,虽然后面转头去做别的东西了,不过还是想着把自己学习的皮毛记录下来叭! 嗯,主要的框架图看到这篇文章写的很好,可以帮助我们进行代码跟踪 化简之后的图为: 代码我们从一 ...
- compressGOP函数代码跟踪
之前的学习中对encode函数进行了跟踪解读,在里面调用了compressGOP函数(代码太多了,看完得猴年马月,要人命,对付一下对付一下!),看到这个代码名字就联想到视频的编码过程了吧,视频先分成G ...
- 用Debug函数实现API函数的跟踪
用Debug函数实现API函数的跟踪 如果我们能自己编写一个类似调试器的功能,这个调试器需要实现我们对于跟踪监视工具的要求,即自动记录输入输出参数,自动让目标进程继续运行.下面我们就来介绍在不知道函数 ...
- 安卓代码跟踪方式学习笔记
一.代码跟踪的介绍&使用工具 代码跟踪常用于调试程序中,跟踪并了解程序的执行轨迹和执行逻辑.这样来说,对Java这样的高级语言来说,我们容易理解也容易调试.但是像一些低级语言,例如ASM.Sm ...
- ThinkPHP3.2 G函数代码及 使用方法
ThinkPHP3.2 G函数代码及 使用方法 代码: // 内存是否可调用 define('MEMORY_LIMIT_ON',function_exists('memory_get_usage')) ...
- php三个数字比较大小排序,php中常用的4种实现数字大小排序的冒泡选择等算法函数代码...
分别用冒泡排序法,快速排序法,选择排序法,插入排序法将下面数组中按照从小到大的顺序进行排序. 本站收录这篇文章php中常用的4种实现数字大小排序的冒泡选择等算法函数代码,详细解说文章中相关排序 冒泡 ...
- 2.函数(代码的整洁之道)
2.函数(代码的整洁之道) 目录 短小 只做一件事 每个函数一个抽象层次 switch语句 使用描述性的名称 函数参数 无副作用 分隔指令与询问 使用异常代替返回的错误码 别重复自己 结构化编程 如何 ...
- python转换函数使用_python进制转换函数代码的使用
python进制转换函数代码的使用 发布时间:2020-04-23 10:23:22 来源:亿速云 阅读:188 作者:小新 以上就是python进制转换函数代码的使用的详细内容了,看完之后是否有所收 ...
- python第一条入门程序_Python语言函数代码的执行流程
https://www.xin3721.com/eschool/pythonxin3721/ Python语言函数代码的执行流程,为了保证函数的定义先于其首次调用时执行,我们需要知道中语句的执行顺序. ...
最新文章
- 在Ubuntu 16.04.5 LTS上利用python 2.7版本的pillow库拼接近千张图片实录
- osm2pgsql windows “illegal option -W” error
- C++ 下使用curl 获取ftp文件
- 【风控建模】互联网金融-机器学习及评分卡构建
- Kubernetes 弹性伸缩全场景解析 (四)- 让核心组件充满弹性
- 寻找听过我讲座的大学生
- 如何确定Oracle是32 Bit(位)的还是64 Bit(位)的?
- 王者荣耀进不去服务器维护中,王者荣耀苹果版更新后进不去 王者荣耀iOS版服务器维护怎么办...
- GBDT 入门教程之原理、所解决的问题、应用场景讲解
- 第十九期:程序员节,女朋友偷偷送了我这个...
- 详解Nacos的高可用特性(转载)
- Java设计模式之单例(Singleton)模式解析
- 主键和外键举例_mysql 基础篇之主键和外键
- 用计算机处理文字,计算机文字 计算机文字与信息处理
- 老王的常用资源下载(全部附CSDN资源链接 12月19日 更新RetopoFlow3至3.00.2)
- CF 128A Statues
- 苹果自带计算机误删,苹果手机日历误删怎样恢复?恢复的小技巧
- 盘点2019年PHP高级开发工程师面试题及答案汇总
- 取消远程计算机控制,怎么脱离远程计算机控制?
- 简单游戏Roll_A_Ball开发笔记