HEVC码率控制(二):从compressGOP()到compressSlice()
来源:互联网 发布:大数据和云计算的关系 编辑:程序博客网 时间:2024/06/01 22:52
compressGOP()函数要点:
- 根据iGOPid逐次递增,对一个GOP内的picture依次编码
- 根据picture level对当前picture进行码率分配
- 实际中一个Pic就是一个Slice,因此关于slice的循环只执行一次(默认)
- 根据已经编过的picture,来得到当前picture的lambda
- 得到当前picture的lambda后,对该picture下每一个CTU进行码率分配
- 一个picture编完,码流写好了,根据实际编码所用的比特,更新对应level下的lambda参数
compressGOP(){ ... for(Int iGOPid=0;iGOPid<m_iGopSize;iGOPid++) //GOP内picture循环 { m_pcSliceEncoder->initEncSlice(); //当前Slice编码参数QP、lambda的默认设置,会在码率控制中进一步被修改 ... if(m_pcCfg->getUseRateCtrl()) { m_pcRateCtrl->initRCPic(frameLevel);//根据frame level进行比特分配 ... lambda=m_pcRateCtrl->getRCPic()->estimatePicLambda();//确定当前picture的lambda sliceQP = m_pcRateCtrl->getRCPic()->estimatePicQP( lambda,.. );//QP由lambda计算 ... } for(UInt nextCtuTsAddr = 0; nextCtuTsAddr < numberOfCtusInFrame; ) //这个循环只执行了一次 { ... m_pcSliceEncoder->compressSlice(); ... } ... //编完一帧,开始熵编码,写码流等等 ... if(m_pcCfg->getUseRateCtrl()) { ... updataAfterPicture(); //编完一帧,更新当前picture level对应的lambda参数值(alpha和beta) ... } }//iGOPid loop}
- estimatePicLambda()函数中,在得到lambda之后,对一个picture内所有LCU进行比特分配:
Double TEncRCPic::estimatePicLambda( ){ Double alpha = m_encRCSeq->getPicPara( m_frameLevel ).m_alpha; Double beta = m_encRCSeq->getPicPara( m_frameLevel ).m_beta; //alpha和beta从数组中对应level处取,这两个值在编完前一个相同level的帧后,被设置 Double bpp = (Double)m_targetBits/(Double)m_numberOfPixel; Double estLambda; if (eSliceType == I_SLICE) { estLambda = calculateLambdaIntra(alpha, beta, pow(m_totalCostIntra/(Double)m_numberOfPixel, BETA1), bpp); } else { estLambda = alpha * pow( bpp, beta ); } Double lastLevelLambda = -1.0; Double lastPicLambda = -1.0; Double lastValidLambda = -1.0; //对estLambda进行Clip操作 m_estPicLambda = estLambda; //TEncRCPic::m_estPicLambda Double totalWeight = 0.0; // initial BU bit allocation weight for ( Int i=0; i<m_numberOfLCU; i++ ) { Double alphaLCU, betaLCU; if ( m_encRCSeq->getUseLCUSeparateModel() ) { alphaLCU = m_encRCSeq->getLCUPara( m_frameLevel, i ).m_alpha; betaLCU = m_encRCSeq->getLCUPara( m_frameLevel, i ).m_beta; } else { alphaLCU = m_encRCSeq->getPicPara( m_frameLevel ).m_alpha; betaLCU = m_encRCSeq->getPicPara( m_frameLevel ).m_beta; } m_LCUs[i].m_bitWeight = m_LCUs[i].m_numberOfPixel * pow( estLambda/alphaLCU, 1.0/betaLCU ); if ( m_LCUs[i].m_bitWeight < 0.01 ) { m_LCUs[i].m_bitWeight = 0.01; } totalWeight += m_LCUs[i].m_bitWeight; } for ( Int i=0; i<m_numberOfLCU; i++ ) { Double BUTargetBits = m_targetBits * m_LCUs[i].m_bitWeight / totalWeight; m_LCUs[i].m_bitWeight = BUTargetBits; } return estLambda;}
m_bitWeight即使每一个CTU对应的比特分配权重
- 跟新picture level 的alpha和beta函数updateAfterPicture():
void TEncRCPic::updateAfterPicture(){ //计算inputLambda //计算calLambda alpha += m_encRCSeq->getAlphaUpdate() * ( log( inputLambda ) - log( calLambda ) ) * alpha; Double lnbpp = log( picActualBpp ); lnbpp = Clip3( -5.0, -0.1, lnbpp ); //按照码率控制算法,跟新alpha和beta TRCParameter rcPara; rcPara.m_alpha = alpha; rcPara.m_beta = beta; m_encRCSeq->setPicPara( m_frameLevel, rcPara ); //将更新后的alpha和beta保存在数组中}
compressSlice()函数
- 按照CTU的先后顺序循环遍历编码
- 编完一个CTU之后,要更新参数
void TEncSlice::compressSlice(){ ... xDetermineStartAndBoundingCtuTsAddr ( startCtuTsAddr, boundingCtuTsAddr, pcPic ); ... for( UInt ctuTsAddr = startCtuTsAddr; ctuTsAddr < boundingCtuTsAddr; ++ctuTsAddr ) //对一个Slice内所有CTU开始循环编码 { ... if ( m_pcCfg->getUseRateCtrl() ) { Int estQP = pcSlice->getSliceQp(); Double estLambda = -1.0; Double bpp = -1.0; //根据LCU的m_bitWeight这个成员计算当前LCU的比特,再除以LCU内Pixel总数,得到bpp。而m_bitWeight这个成员是得到Pic的lambda之后被赋值。 estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambdaAndQP(bpp, pcSlice->getSliceQp(), &estQP); ... m_pcRdCost->setLambda(estLambda, pcSlice->getSPS()->getBitDepths()); } m_pcCuEncoder->compressCtu(pCtu); ... if(m_pcCfg->getUseRateCtrl()) { ... updateAfterCTU(); ... } //将CTU的编码结果累加到Picture的统计量之中 m_uiPicTotalBits+=pCtu->getTotalBits(); m_dPicRdcost+=PCtu->getTotalCost(); m_uiPicDist+=PCtu->getTotalDistortion; }}
0 0
- HEVC码率控制(二):从compressGOP()到compressSlice()
- HEVC代码追踪(五):compressSlice
- HEVC代码追踪(三):encode->compressGOP
- HEVC代码追踪(四):compressGOP框架
- HEVC码率控制代码追踪(二)
- HEVC compressGOP 接口
- HEVC码率控制
- HEVC中的码率控制(RC)
- HEVC代码学习34:compressSlice函数
- HEVC码率控制代码追踪(一)(HEVC code tracing-Rate control)
- compressSlice
- HEVC码率控制代码追踪(三)
- HEVC码率控制介绍(R-Lamda)
- compressGOP
- HEVC码率控制浅析——HM代码阅读之二
- HEVC码率控制浅析——HM代码阅读之二
- HEVC码率控制提案总结
- 3D-HEVC码率控制
- 细节成就未来(结构化数组)
- python菜鸟
- 【从零开始学习MySql数据库】(1)建表与简单查询
- 英文歌曲初恋《heartbeats》 心跳
- Linux下磁盘的挂载与卸载
- HEVC码率控制(二):从compressGOP()到compressSlice()
- Android----按钮单击事件的四种写法
- centos7 网卡名字改为eth0
- 代码中适配
- HDU 1083 二分图匹配
- UVA.232 Crossword Answers
- numpy基本使用方法示例
- winform窗体上的超链接怎么跳转到网页?
- bLue的文件查找器