正式的预测操作

在前面的操作中,我们已经得到了模式候选列表,但是我们的目的是要得到一个最优的模式,因此我们还需要对这个列表中的模式进行遍历,对于每一个模式,进行预测操作,为了计算率失真代价还必须进行变换量化,根据率失真代价来选取最优的预测模式。得到最优的预测模式的同时,我们也得到了变换系数(因为预测之后我们还进行了变换量化操作)。

执行正式的预测操作的相关代码在estIntraPredQT中,主要的功能是遍历模式候选列表中的所有模式,对每一个模式进行预测(顺带变换量化),选出最优的预测模式

     // 遍历候选集中的模式for( UInt uiMode = 0; uiMode < numModesForFullRD; uiMode++ ){// set luma prediction modeUInt uiOrgMode = uiRdModeList[uiMode];pcCU->setLumaIntraDirSubParts ( uiOrgMode, uiPartOffset, uiDepth + uiInitTrDepth );// set context models// 设置上下文模型m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );// determine residual for partitionUInt   uiPUDistY = 0;UInt   uiPUDistC = 0;Double dPUCost   = 0.0;
#if HHI_RQT_INTRA_SPEEDUP// 通过多候选模式进行预测、变换、量化等操作来计算代价// 注意倒数第二个参数bCheckFirst是true,表示会继续按照四叉树的方式向下划分xRecurIntraCodingQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiPUDistY, uiPUDistC, true, dPUCost );// 重要函数end
#elsexRecurIntraCodingQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiPUDistY, uiPUDistC, dPUCost );
#endif// check r-d cost// 从候选列表中选取最优的模式if( dPUCost < dBestPUCost ){
#if HHI_RQT_INTRA_SPEEDUP_MODuiSecondBestMode  = uiBestPUMode;dSecondBestPUCost = dBestPUCost;
#endifuiBestPUMode  = uiOrgMode;uiBestPUDistY = uiPUDistY;uiBestPUDistC = uiPUDistC;dBestPUCost   = dPUCost;xSetIntraResultQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcRecoYuv );UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth(0) + uiInitTrDepth ) << 1 );::memcpy( m_puhQTTempTrIdx,  pcCU->getTransformIdx()       + uiPartOffset, uiQPartNum * sizeof( UChar ) );::memcpy( m_puhQTTempCbf[0], pcCU->getCbf( TEXT_LUMA     ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );::memcpy( m_puhQTTempCbf[1], pcCU->getCbf( TEXT_CHROMA_U ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );::memcpy( m_puhQTTempCbf[2], pcCU->getCbf( TEXT_CHROMA_V ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );::memcpy( m_puhQTTempTransformSkipFlag[0], pcCU->getTransformSkip(TEXT_LUMA)     + uiPartOffset, uiQPartNum * sizeof( UChar ) );::memcpy( m_puhQTTempTransformSkipFlag[1], pcCU->getTransformSkip(TEXT_CHROMA_U) + uiPartOffset, uiQPartNum * sizeof( UChar ) );::memcpy( m_puhQTTempTransformSkipFlag[2], pcCU->getTransformSkip(TEXT_CHROMA_V) + uiPartOffset, uiQPartNum * sizeof( UChar ) );}
#if HHI_RQT_INTRA_SPEEDUP_MODelse if( dPUCost < dSecondBestPUCost ){uiSecondBestMode  = uiOrgMode;dSecondBestPUCost = dPUCost;}
#endif} // Mode loop

正式预测操作的入口函数

入口函数是xRecurIntraCodingQT,它的流程如下:

一、检测bCheckFull标识是否为true,如果是true,那么进行下面操作:
    1、检查TransformSkip标识是否为true,如果是true(表示将会跳过变换步骤),进行下面操作
        (1)进行两次遍历,每一次遍历都调用xIntraCodingLumaBlk、xIntraCodingChromaBlk对三个分量进行预测、计算残差(没有变换步骤)、量化
        (2)选取两次遍历中更优的模式
    2、如果TransformSkip是false,那么进行下面操作:
        (1)调用xIntraCodingLumaBlk、xIntraCodingChromaBlk对三个分量进行预测、变换、量化
二、检查bCheckSplit表示是否为true,如果为true,那么对子PU进行递归处理

/*
** 正式的预测操作(顺便进行了变换量化)
** 为了清晰易懂,把不太相关的代码删除,只保留了清晰的架构
*/
Void TEncSearch::xRecurIntraCodingQT( TComDataCU*  pcCU, UInt         uiTrDepth,UInt         uiAbsPartIdx, Bool         bLumaOnly,TComYuv*     pcOrgYuv, TComYuv*     pcPredYuv, TComYuv*     pcResiYuv, UInt&        ruiDistY,UInt&        ruiDistC,
#if HHI_RQT_INTRA_SPEEDUPBool         bCheckFirst,
#endifDouble&      dRDCost )
{// 删除不太重要的代码******Bool    bCheckFull    = ( uiLog2TrSize  <= pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() );Bool    bCheckSplit   = ( uiLog2TrSize  >  pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) );// 删除不太重要的代码******Bool noSplitIntraMaxTuSize = bCheckFull;if(m_pcEncCfg->getRDpenalty() && ! isIntraSlice){// in addition don't check split if TU size is less or equal to 16x16 TU size for non-intra slicenoSplitIntraMaxTuSize = ( uiLog2TrSize  <= min(maxTuSize,4) );// if maximum RD-penalty don't check TU size 32x32 if(m_pcEncCfg->getRDpenalty()==2){bCheckFull    = ( uiLog2TrSize  <= min(maxTuSize,4));}}if( bCheckFirst && noSplitIntraMaxTuSize ){bCheckSplit = false;}// 删除不太重要的代码******Bool    checkTransformSkip  = pcCU->getSlice()->getPPS()->getUseTransformSkip();UInt    widthTransformSkip  = pcCU->getWidth ( 0 ) >> uiTrDepth;UInt    heightTransformSkip = pcCU->getHeight( 0 ) >> uiTrDepth;// 删除不太重要的代码******checkTransformSkip         &= (widthTransformSkip == 4 && heightTransformSkip == 4);checkTransformSkip         &= (!pcCU->getCUTransquantBypass(0));if ( m_pcEncCfg->getUseTransformSkipFast() ){checkTransformSkip       &= (pcCU->getPartitionSize(uiAbsPartIdx)==SIZE_NxN);}if( bCheckFull ){// skip模式为真if(checkTransformSkip == true){// 删除不太重要的代码******// 遍历两次也是为了选取最优的模式,modeId能够决定xIntraCodingLumaBlk的最后一个参数,该参数控制了预测像素如何生成for(Int modeId = firstCheckId; modeId < 2; modeId ++){// 删除不太重要的代码******// 亮度块的预测、变换和量化xIntraCodingLumaBlk( pcCU, uiTrDepth, uiAbsPartIdx, pcOrgYuv, pcPredYuv, pcResiYuv, singleDistYTmp,default0Save1Load2); singleCbfYTmp = pcCU->getCbf( uiAbsPartIdx, TEXT_LUMA, uiTrDepth );//----- code chroma blocks with given intra prediction mode and store Cbf-----if( !bLumaOnly ){// 删除不太重要的代码******// 色度块的预测、变换和量化xIntraCodingChromaBlk ( pcCU, uiTrDepth, uiAbsPartIdx, pcOrgYuv, pcPredYuv, pcResiYuv, singleDistCTmp, 0, default0Save1Load2); xIntraCodingChromaBlk ( pcCU, uiTrDepth, uiAbsPartIdx, pcOrgYuv, pcPredYuv, pcResiYuv, singleDistCTmp, 1, default0Save1Load2); // 删除不太重要的代码******}// 删除不太重要的代码******// 代价更新if(singleCostTmp < dSingleCost){dSingleCost   = singleCostTmp;uiSingleDistY = singleDistYTmp;uiSingleDistC = singleDistCTmp;uiSingleCbfY  = singleCbfYTmp;uiSingleCbfU  = singleCbfUTmp;uiSingleCbfV  = singleCbfVTmp;bestModeId    = modeId;if(bestModeId == firstCheckId){xStoreIntraResultQT(pcCU, uiTrDepth, uiAbsPartIdx,bLumaOnly );m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiFullDepth ][ CI_TEMP_BEST ] );}}// 删除不太重要的代码******}// 删除不太重要的代码******}else{// 删除不太重要的代码******xIntraCodingLumaBlk( pcCU, uiTrDepth, uiAbsPartIdx, pcOrgYuv, pcPredYuv, pcResiYuv, uiSingleDistY ); // 删除不太重要的代码******if( !bLumaOnly ){// 删除不太重要的代码******xIntraCodingChromaBlk ( pcCU, uiTrDepth, uiAbsPartIdx, pcOrgYuv, pcPredYuv, pcResiYuv, uiSingleDistC, 0 ); xIntraCodingChromaBlk ( pcCU, uiTrDepth, uiAbsPartIdx, pcOrgYuv, pcPredYuv, pcResiYuv, uiSingleDistC, 1 ); // 删除不太重要的代码******}// 删除不太重要的代码******}}// 当前块是否向下继续划分为4个子块,如果是,那么就递归处理if( bCheckSplit ){// 删除不太重要的代码******for( UInt uiPart = 0; uiPart < 4; uiPart++, uiAbsPartIdxSub += uiQPartsDiv ){
#if HHI_RQT_INTRA_SPEEDUP// 递归调用xRecurIntraCodingQT( pcCU, uiTrDepth + 1, uiAbsPartIdxSub, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiSplitDistY, uiSplitDistC, bCheckFirst, dSplitCost );
#elsexRecurIntraCodingQT( pcCU, uiTrDepth + 1, uiAbsPartIdxSub, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiSplitDistY, uiSplitDistC, dSplitCost );
#endif// 删除不太重要的代码******}// 删除不太重要的代码******//----- determine rate and r-d cost -----UInt uiSplitBits = xGetIntraBitsQT( pcCU, uiTrDepth, uiAbsPartIdx, true, !bLumaOnly, false );dSplitCost       = m_pcRdCost->calcRdCost( uiSplitBits, uiSplitDistY + uiSplitDistC );//===== compare and set best =====if( dSplitCost < dSingleCost ){//--- update cost ---ruiDistY += uiSplitDistY;ruiDistC += uiSplitDistC;dRDCost  += dSplitCost;return;}// 删除不太重要的代码******//--- set reconstruction for next intra prediction blocks ---// 到这里是像素块的重建操作,这里把相关的代码删了}ruiDistY += uiSingleDistY;ruiDistC += uiSingleDistC;dRDCost  += dSingleCost;
}

对某个分量进行预测(顺带变换量化)

流程很简单:

1、先进行预测,得到预测像素

2、计算残差

3、对残差进行变换、量化

4、进行反变换、反量化

5、重建像素块

/*
** 帧内预测的一整套流程:预测+变换量化+反变换反量化+重建像素
** 被xRecurIntraCodingQT调用
*/
Void TEncSearch::xIntraCodingLumaBlk( TComDataCU* pcCU,UInt        uiTrDepth,UInt        uiAbsPartIdx,TComYuv*    pcOrgYuv, TComYuv*    pcPredYuv, TComYuv*    pcResiYuv, UInt&       ruiDist,Int        default0Save1Load2 )
{// 获取亮度块的预测模式UInt    uiLumaPredMode    = pcCU     ->getLumaIntraDir     ( uiAbsPartIdx );// 获取深度UInt    uiFullDepth       = pcCU     ->getDepth   ( 0 )  + uiTrDepth;// 获取宽高UInt    uiWidth           = pcCU     ->getWidth   ( 0 ) >> uiTrDepth;UInt    uiHeight          = pcCU     ->getHeight  ( 0 ) >> uiTrDepth;// 获取偏移UInt    uiStride          = pcOrgYuv ->getStride  ();// 原始的像素地址Pel*    piOrg             = pcOrgYuv ->getLumaAddr( uiAbsPartIdx );// 预测的像素地址Pel*    piPred            = pcPredYuv->getLumaAddr( uiAbsPartIdx );// 残差的像素地址Pel*    piResi            = pcResiYuv->getLumaAddr( uiAbsPartIdx );// 重建的像素地址Pel*    piReco            = pcPredYuv->getLumaAddr( uiAbsPartIdx );UInt    uiLog2TrSize      = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiFullDepth ] + 2;UInt    uiQTLayer         = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;UInt    uiNumCoeffPerInc  = pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() >> ( pcCU->getSlice()->getSPS()->getMaxCUDepth() << 1 );// 系数(实际是一个int数组)TCoeff* pcCoeff           = m_ppcQTTempCoeffY[ uiQTLayer ] + uiNumCoeffPerInc * uiAbsPartIdx;#if ADAPTIVE_QP_SELECTIONInt*    pcArlCoeff        = m_ppcQTTempArlCoeffY[ uiQTLayer ] + uiNumCoeffPerInc * uiAbsPartIdx;
#endifPel*    piRecQt           = m_pcQTTempTComYuv[ uiQTLayer ].getLumaAddr( uiAbsPartIdx );UInt    uiRecQtStride     = m_pcQTTempTComYuv[ uiQTLayer ].getStride  ();// Z扫描的顺序UInt    uiZOrder          = pcCU->getZorderIdxInCU() + uiAbsPartIdx;Pel*    piRecIPred        = pcCU->getPic()->getPicYuvRec()->getLumaAddr( pcCU->getAddr(), uiZOrder );UInt    uiRecIPredStride  = pcCU->getPic()->getPicYuvRec()->getStride  ();Bool    useTransformSkip  = pcCU->getTransformSkip(uiAbsPartIdx, TEXT_LUMA);//===== init availability pattern =====// 上方是否有效Bool  bAboveAvail = false;// 左侧是否有效Bool  bLeftAvail  = false;// default0Save1Load2参数控制了预测像素的生成方式if(default0Save1Load2 != 2){pcCU->getPattern()->initPattern   ( pcCU, uiTrDepth, uiAbsPartIdx );pcCU->getPattern()->initAdiPattern( pcCU, uiAbsPartIdx, uiTrDepth, m_piYuvExt, m_iYuvExtStride, m_iYuvExtHeight, bAboveAvail, bLeftAvail );// 预测操作predIntraLumaAng( pcCU->getPattern(), uiLumaPredMode, piPred, uiStride, uiWidth, uiHeight, bAboveAvail, bLeftAvail );// save prediction // 保存预测信息if(default0Save1Load2 == 1){Pel*  pPred   = piPred;Pel*  pPredBuf = m_pSharedPredTransformSkip[0];Int k = 0;for( UInt uiY = 0; uiY < uiHeight; uiY++ ){for( UInt uiX = 0; uiX < uiWidth; uiX++ ){pPredBuf[ k ++ ] = pPred[ uiX ];}pPred += uiStride;}}}else {// load prediction// 直接计算预测值!Pel*  pPred   = piPred;Pel*  pPredBuf = m_pSharedPredTransformSkip[0];Int k = 0;for( UInt uiY = 0; uiY < uiHeight; uiY++ ){for( UInt uiX = 0; uiX < uiWidth; uiX++ ){pPred[ uiX ] = pPredBuf[ k ++ ];}pPred += uiStride;}}//===== get residual signal ====={// get residual// 计算残差Pel*  pOrg    = piOrg;Pel*  pPred   = piPred;Pel*  pResi   = piResi;for( UInt uiY = 0; uiY < uiHeight; uiY++ ){for( UInt uiX = 0; uiX < uiWidth; uiX++ ){// 此处计算残差数据pResi[ uiX ] = pOrg[ uiX ] - pPred[ uiX ];}pOrg  += uiStride;pResi += uiStride;pPred += uiStride;}}// 变换和量化//===== transform and quantization =====//--- init rate estimation arrays for RDOQ ---// 是否跳过变换操作if( useTransformSkip? m_pcEncCfg->getUseRDOQTS():m_pcEncCfg->getUseRDOQ()){// 比特数估计m_pcEntropyCoder->estimateBit( m_pcTrQuant->m_pcEstBitsSbac, uiWidth, uiWidth, TEXT_LUMA );}//--- transform and quantization ---UInt uiAbsSum = 0;pcCU       ->setTrIdxSubParts ( uiTrDepth, uiAbsPartIdx, uiFullDepth );m_pcTrQuant->setQPforQuant    ( pcCU->getQP( 0 ), TEXT_LUMA, pcCU->getSlice()->getSPS()->getQpBDOffsetY(), 0 );#if RDOQ_CHROMA_LAMBDA m_pcTrQuant->selectLambda     (TEXT_LUMA);
#endif// 变换(连同量化一起)m_pcTrQuant->transformNxN     ( pcCU, piResi, uiStride, pcCoeff,
#if ADAPTIVE_QP_SELECTIONpcArlCoeff,
#endifuiWidth, uiHeight, uiAbsSum, TEXT_LUMA, uiAbsPartIdx,useTransformSkip );//--- set coded block flag ---pcCU->setCbfSubParts          ( ( uiAbsSum ? 1 : 0 ) << uiTrDepth, TEXT_LUMA, uiAbsPartIdx, uiFullDepth );//--- inverse transform ---// uiAbsSum表示变换系数的绝对值只和if( uiAbsSum ){Int scalingListType = 0 + g_eTTable[(Int)TEXT_LUMA];assert(scalingListType < SCALING_LIST_NUM);// 反变换m_pcTrQuant->invtransformNxN( pcCU->getCUTransquantBypass(uiAbsPartIdx), TEXT_LUMA,pcCU->getLumaIntraDir( uiAbsPartIdx ), piResi, uiStride, pcCoeff, uiWidth, uiHeight, scalingListType, useTransformSkip );}else{Pel* pResi = piResi;memset( pcCoeff, 0, sizeof( TCoeff ) * uiWidth * uiHeight );for( UInt uiY = 0; uiY < uiHeight; uiY++ ){memset( pResi, 0, sizeof( Pel ) * uiWidth );pResi += uiStride;}}// 图像重建//===== reconstruction ====={Pel* pPred      = piPred;Pel* pResi      = piResi;Pel* pReco      = piReco;Pel* pRecQt     = piRecQt;Pel* pRecIPred  = piRecIPred;for( UInt uiY = 0; uiY < uiHeight; uiY++ ){for( UInt uiX = 0; uiX < uiWidth; uiX++ ){pReco    [ uiX ] = ClipY( pPred[ uiX ] + pResi[ uiX ] );pRecQt   [ uiX ] = pReco[ uiX ];pRecIPred[ uiX ] = pReco[ uiX ];}pPred     += uiStride;pResi     += uiStride;pReco     += uiStride;pRecQt    += uiRecQtStride;pRecIPred += uiRecIPredStride;}}//===== update distortion =====// 失真代价更新!ruiDist += m_pcRdCost->getDistPart(g_bitDepthY, piReco, uiStride, piOrg, uiStride, uiWidth, uiHeight );
}

预测函数

流程也很简单:

1、判断模式属于哪一类:planar模式、水平类型的模式、垂直类型的模式、DC模式

2、根据模式来调用不同的函数,进行预测

// 亮度块的帧内预测
Void TComPrediction::predIntraLumaAng(TComPattern* pcTComPattern, UInt uiDirMode, Pel* piPred, UInt uiStride, Int iWidth, Int iHeight, Bool bAbove, Bool bLeft )
{Pel *pDst = piPred;Int *ptrSrc;assert( g_aucConvertToBit[ iWidth ] >= 0 ); //   4x  4assert( g_aucConvertToBit[ iWidth ] <= 5 ); // 128x128assert( iWidth == iHeight  );// 获取数据的指针ptrSrc = pcTComPattern->getPredictorPtr( uiDirMode, g_aucConvertToBit[ iWidth ] + 2, m_piYuvExt );// get starting pixel in block// 获取块中的开始像素Int sw = 2 * iWidth + 1; // 9// Create the prediction// 如果指定了planar模式if ( uiDirMode == PLANAR_IDX ){// planar预测模式xPredIntraPlanar( ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight );}else{// 没有指定planar模式// 区分水平或者垂直模式进行预测if ( (iWidth > 16) || (iHeight > 16) ){xPredIntraAng(g_bitDepthY, ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight, uiDirMode, bAbove, bLeft, false );}else{xPredIntraAng(g_bitDepthY, ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight, uiDirMode, bAbove, bLeft, true );// 观察是否为DC模式if( (uiDirMode == DC_IDX ) && bAbove && bLeft ){// 对DC模式进行滤波xDCPredFiltering( ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight);}}}
}

预测的实现细节

下面这些函数基本都是某个公式的实现,详细信息请参考标准

planar模式:xPredIntraPlanar

DC模式和其他模式:xPredIntraAng

变换和量化

处理变换和量化的函数是transformNxN,这个函数等讲解变换量化的时候再细讲

HM编码器代码阅读(38)——帧内预测(五)帧内预测之正式的预测操作相关推荐

  1. HM编码器代码阅读(30)——帧间预测之AMVP模式(五)运动估计

    运动估计 通过 点击打开链接 介绍的方法得到MVP之后,可以根据该MVP确定运动估计的搜索起点,然后进行运动估计 xMotionEstimation就是进行运动估计的入口函数     1.先进行一些初 ...

  2. HM编码器代码阅读(16)——帧间预测之AMVP模式(四)预测MV的获取

    帧间预测的原理 AMVP的原理 帧间预测的实质就是为当前的PU在参考帧中寻找一块最相似块(相似度的判断准则有SAD等方法).但是参考图像通常都比较大,我们直接去搜索的话就太费时了,应该使用某种方法在参 ...

  3. HM编码器代码阅读(13)——帧间预测之AMVP模式(一)总体流程

    帧间预测的原理 AMVP的原理 帧间预测的实质就是为当前的PU在参考帧中寻找一块最相似块(相似度的判断准则有SAD等方法).但是参考图像通常都比较大,我们直接去搜索的话就太费时了,应该使用某种方法在参 ...

  4. HM编码器代码阅读(14)——帧间预测之AMVP模式(二)predInterSearch函数

    简介     predInterSearch主要的工作是ME(运动估计)和MC(运动补偿).     函数中有一个bTestNormalMC变量,它表示是否进行正常的MC过程,正常的MC过程就是进行M ...

  5. HM编码器代码阅读(14)——帧间预測之AMVP模式(二)predInterSearch函数

    简单介绍     predInterSearch基本的工作是ME(运动预计)和MC(运动补偿).     函数中有一个bTestNormalMC变量.它表示是否进行正常的MC过程,正常的MC过程就是进 ...

  6. HM编码器代码阅读(32)——帧间预测之AMVP/Merge模式(七)encodeResAndCalcRdInterCU函数:残差计算、变换量化

    encodeResAndCalcRdInterCU 原理和细节 经过运动估计.运动补偿,我们得到了MV以及参考块,那么接下来是计算残差.计算MVD,然后对系数进行变换.量化. encodeResAnd ...

  7. HM编码器代码阅读(31)——帧间预测之AMVP/Merge模式(六)运动补偿

    运动补偿 原理 说实话一直很难理解运动补偿中"补偿"二字的意思,在参考了 http://blog.csdn.net/hevc_cjl/article/details/8457642 ...

  8. HM编码器代码阅读(15)——帧间预测之AMVP模式(三)xGetBlkBits函数

    GetBlkBits函数的主要功能是计算使用某种PU划分模式的时候,该种模式占用的比特数 Void TEncSearch::xGetBlkBits( PartSize eCUMode, Bool bP ...

  9. HM编码器代码阅读(20)——与变换量化有关的其他知识

    与变换量化有关的其他知识 变换 哈达玛变换 哈达玛变换是广义傅立叶变换的一种,它的变换矩阵Hm是一个2^m x 2^m的矩阵. 哈达玛变换及其矩阵有下面的几个特性: 1.hadamard矩阵元素都是正 ...

最新文章

  1. 使用JDBC进行MySQL 5.1的数据连接、查询、修改等操作练习。
  2. 在JavaScript中深度克隆对象的最有效方法是什么?
  3. 如何在WIN7上添加磁盘
  4. 频谱仪使用方法图解_钳形电流表使用方法图解
  5. qt单步调试linux程序,用Qt 调用GDB调试 Arm程序 详细步骤----可单步执行每一行
  6. CAS单点登录详细流程
  7. springboot整合es启动报错的问题
  8. 第57条:将局部变量的作用域最小化
  9. Apache 软件基金会:顶级项目仍使用老旧软件,补丁作用被削弱
  10. 网络协议收发数据问题
  11. Python 爬虫抓站 记录
  12. 调用微信内置浏览器实现微信打开的网页上的图片能点击打开的效果
  13. win7桌面不显示我的计算机名,win7系统桌面没有显示我的电脑图标的操作技巧
  14. AD20/Altium designer——如何从立创EDA获取元器件封装库原理图库PCB库
  15. ORB-SLAM3相对于ORB-SLAM2有哪些优势?
  16. JVM: GC过程总结(minor GC 和 Full GC)
  17. AutoFac在WinForm中的使用
  18. 2022年流动式起重机司机考试题库模拟考试平台操作
  19. 《矩阵论》学习笔记(五):第五章 特征值的估计及对称矩阵的极性
  20. 一文读懂NFT的发展历史、进展及未来趋势

热门文章

  1. java视频 坦克大战制作
  2. 网红自习室APP社交功能太多,遭用户吐槽
  3. python编程入门软件_python编程入门
  4. 树形控件(CTreeCtrl)简介(转)
  5. Android开发太卷了!技术总监出来求职,竟然都找不到工作……
  6. c语言s10 是什么意思啊,S10中单数据曝光 究竟谁C一目了然
  7. Linux常用基础命令之二(cat,head,tail,chmod,chown,echo,df,du)
  8. 秦嘉哲:11.9黄金晚间行情实时分析及美盘多空操作建议
  9. 风格化渲染之油画渲染:Customizing Painterly Rendering Styles Using Stroke Processes——论文阅读和个人理解
  10. 如何从ST官网下载ST库