Fast CU Depth Decision Algorithm for HEVC Intra Coding

2024-02-12 09:32

本文主要是介绍Fast CU Depth Decision Algorithm for HEVC Intra Coding,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


转自:http://blog.csdn.net/beechina/article/details/25430737

在HEVC 参考代码中,一个CTU块通过xcompressCU()函数进行CU递归得到最优的CU深度。

递归的过程可如下图(from:Fast CU Splitting and Pruning for Suboptimal CU Partitioning in HEVC Intra Coding)所示。图中每一个方框表示一个CU块,方框内的数字表示xcompressCU()函数的执行顺序。显而易见,如果能在做xcompressCU()函数之前,将CU的递归深度确定下,显然可以减小HEVC编码器的复杂度。




针对帧内编码器,已经有很多文献提出了提前确定CU递归深度的方法。这里介绍了"Fast CU Size Decision and Mode Decision Algorithm for HEVC Intra Coding"中Section II.A部分的具体实现。在这篇文献中,周边块的CTU depth size用来给当前块深度进行预测。具体的细节可以去查看该文献。

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Void TEncCu::compressCU( TComDataCU*& rpcCU )  
  2. {  
  3.   // initialize CU data  
  4.   m_ppcBestCU[0]->initCU( rpcCU->getPic(), rpcCU->getAddr() );  
  5.   m_ppcTempCU[0]->initCU( rpcCU->getPic(), rpcCU->getAddr() );  
  6.   
  7.   memset( m_preAnalyzeDepth,       0, rpcCU->getTotalNumPart() );  
  8.   memset( m_preAnaDepthDetermined, 0, rpcCU->getTotalNumPart() );  
  9.   memset( m_preAnaDepthRange     , 0, rpcCU->getTotalNumPart() );  
  10.   
  11.   // Neighboring CTUs.  
  12.   TComDataCU* t_pcCULeft      = rpcCU->getCULeft();  
  13.   TComDataCU* t_pcCUAbove     = rpcCU->getCUAbove();  
  14.   TComDataCU* t_pcCUAboveLeft = rpcCU->getCUAboveLeft();  
  15.   TComDataCU* t_pcCUAboveRight= rpcCU->getCUAboveRight();  
  16.   UInt DepthLeft       = 0;       // Max Depth of LeftCTU.  
  17.   UInt DepthAbove      = 0;       // Max Depth of AboveCTU.  
  18.   UInt DepthAboveLeft  = 0;  
  19.   UInt DepthAboveRight = 0;  
  20.   
  21.   UInt picWidth  = rpcCU->getSlice()->getSPS()->getPicWidthInLumaSamples();  
  22.   UInt picHeight = rpcCU->getSlice()->getSPS()->getPicHeightInLumaSamples();  
  23.   UInt uiLPelX   = rpcCU->getCUPelX();  
  24.   UInt uiRPelX   = uiLPelX + rpcCU->getWidth(0)  - 1;  
  25.   UInt uiTPelY   = rpcCU->getCUPelY();  
  26.   UInt uiBPelY   = uiTPelY + rpcCU->getHeight(0) - 1;  
  27.     
  28.   UChar    tDepth;  
  29.   
  30.   m_insidePicture= (uiRPelX<picWidth) && (uiBPelY<picHeight);  
  31.   // Considering Border CTUs.  
  32.   if ( t_pcCULeft!=NULL ) //获取左边CTU块最大的depth信息  
  33.   {  
  34.       for ( Int i=0; i<256; i++ )  
  35.       {  
  36.           tDepth    = t_pcCULeft->getDepth(i);  
  37.           if ( tDepth>DepthLeft )  
  38.           {  
  39.               DepthLeft = (UInt)tDepth;  
  40.           }  
  41.       }  
  42.   }  
  43.   else  
  44.       DepthLeft = 2; //如果是NULL,直接赋值2(16X16)  
  45.   
  46.   if ( t_pcCUAbove!=NULL )  
  47.   {  
  48.       for ( Int i=0; i<256; i++ )  
  49.       {  
  50.           tDepth    = t_pcCUAbove->getDepth(i);  
  51.           if ( tDepth>DepthAbove )  
  52.           {  
  53.               DepthAbove = (UInt)tDepth;  
  54.           }  
  55.       }  
  56.   }  
  57.   else  
  58.       DepthAbove = 2;  
  59.   
  60.   if ( t_pcCUAboveLeft!=NULL )  
  61.   {  
  62.       DepthAboveLeft = t_pcCUAboveLeft->getDepth(g_auiRasterToZscan[16*15+15]);  
  63.   }  
  64.   else  
  65.       DepthAboveLeft = 2;  
  66.   
  67.   if ( t_pcCUAboveRight!=NULL )  
  68.   {  
  69.       DepthAboveRight = t_pcCUAboveRight->getDepth(g_auiRasterToZscan[16*15]);  
  70.   }  
  71.   else  
  72.       DepthAboveRight = 2;  
  73.     
  74.   Double DepthPre = 0.3*DepthLeft+0.3*DepthAbove+0.2*DepthAboveLeft+0.2*DepthAboveRight; // 论文中Prediction Depth Type  
  75.   if ( DepthPre<=0.5 ) // 依据论文中的公式给出最小的depth level和最大的depth level  
  76.   {  
  77.       memset( m_preAnaDepthDetermined, 1, 256 );  
  78.       memset( m_preAnaDepthRange,      2, 256 );  
  79.       memset( m_preAnalyzeDepth,       0, 256 );  
  80.   }  
  81.   else if ( DepthPre<=1.5 )  
  82.   {  
  83.       memset( m_preAnaDepthDetermined, 1, 256 );  
  84.       memset( m_preAnaDepthRange,      3, 256 );  
  85.       memset( m_preAnalyzeDepth,       0, 256 );  
  86.   }  
  87.   else  
  88.   {  
  89.       memset( m_preAnaDepthDetermined, 1, 256 );  
  90.       memset( m_preAnaDepthRange,      3, 256 );  
  91.       memset( m_preAnalyzeDepth,       1, 256 );  
  92.   }  
  93.   
  94.   DEBUG_STRING_NEW(sDebug)  
  95.   
  96.   xCompressCU( m_ppcBestCU[0], m_ppcTempCU[0], 0 DEBUG_STRING_PASS_INTO(sDebug) );  
  97.   DEBUG_STRING_OUTPUT(std::cout, sDebug)  
  98.   // Double Check.  
  99.   UInt MaxDepthSize=0;  
  100.   // UInt CTUPelX, CTUPelY;  
  101.   if ( m_insidePicture )  
  102.   {  
  103.       for ( Int i=0; i<256; i++ )  
  104.       {  
  105.           // Decisioned.  
  106.           tDepth    = m_ppcBestCU[0]->getDepth(i);  
  107.   
  108.           UChar cuDepth         = m_preAnalyzeDepth[i];  
  109.           UChar cuPreDetermined = m_preAnaDepthDetermined[i];  
  110.           UChar cuRange         = m_preAnaDepthRange[i];  
  111.   
  112.           if ( tDepth<cuDepth && tDepth>=cuDepth+cuRange )  
  113.           {  
  114.               assert(0);  
  115.           }  
  116.       }  
  117.   }  
  118.   
  119. #if ADAPTIVE_QP_SELECTION  
  120.   if( m_pcEncCfg->getUseAdaptQpSelect() )  
  121.   {  
  122.     if(rpcCU->getSlice()->getSliceType()!=I_SLICE) //IIII  
  123.     {  
  124.       xLcuCollectARLStats( rpcCU);  
  125.     }  
  126.   }  
  127. #endif  
  128. }  

在xcompressCU函数中加入相关条件跳转。

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. // If slice start or slice end is within this cu...  
  2.  TComSlice * pcSlice = rpcTempCU->getPic()->getSlice(rpcTempCU->getPic()->getCurrSliceIdx());  
  3.  Bool bSliceStart = pcSlice->getSliceSegmentCurStartCUAddr()>rpcTempCU->getSCUAddr()&&pcSlice->getSliceSegmentCurStartCUAddr()<rpcTempCU->getSCUAddr()+rpcTempCU->getTotalNumPart();  
  4.  Bool bSliceEnd = (pcSlice->getSliceSegmentCurEndCUAddr()>rpcTempCU->getSCUAddr()&&pcSlice->getSliceSegmentCurEndCUAddr()<rpcTempCU->getSCUAddr()+rpcTempCU->getTotalNumPart());  
  5.  Bool bInsidePicture = ( uiRPelX < rpcBestCU->getSlice()->getSPS()->getPicWidthInLumaSamples() ) && ( uiBPelY < rpcBestCU->getSlice()->getSPS()->getPicHeightInLumaSamples() );  
  6.  // Fast CU decision Process.  
  7.  // When Current depth is not in the PreAnalyzedDepth Range, it just skips the PU/TU Decision process.  
  8.  // Added by xfHuang.  
  9.  Bool t_enCUSkip=false;  
  10.  if ( m_insidePicture )  
  11.  {  
  12.   // Split Analysis For CU32X32 And CU16X16.  
  13.   
  14.   if ( checkCurDepthInPreAnaRange( rpcBestCU, uiDepth ) == false ) //如果当前的depth level不在预测的depth level之内,后面直接将cost赋值成最大,不进行后面的预测操作。  
  15.   {  
  16.       t_enCUSkip = true;  
  17.       rpcBestCU->getTotalCost() = MAX_DOUBLE/16;  
  18.       rpcBestCU->getTotalDistortion() = MAX_UINT>>3;  
  19.       rpcBestCU->getTotalBits() = MAX_UINT>>3;  
  20.       // avoid assert disable.  
  21.       if ( uiDepth==3 )  
  22.       {  
  23.           rpcBestCU->setPartitionSize ( 0, SIZE_2Nx2N );        
  24.           rpcBestCU->setPredictionMode( 0, MODE_INTRA );   
  25.       }  
  26.   }  
  27.  }  
  28.    
  29.  // We need to split, so don't try these modes.  
  30.  if(!bSliceEnd && !bSliceStart && bInsidePicture )  
  31.  {  
  32. if( t_enCUSkip==false )  
  33. {  
  34.    for (Int iQP=iMinQP; iQP<=iMaxQP; iQP++)  
  35.    {  
  36.      const Bool bIsLosslessMode = isAddLowestQP && (iQP == iMinQP);  
  37.   
  38.      if (bIsLosslessMode)  
  39.      {  
  40.        iQP = lowestQP;  
  41.      }  
  42.   
  43.      rpcTempCU->initEstData( uiDepth, iQP, bIsLosslessMode );  

其中checkCurDepthInPreAnaRange函数如下:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Bool TEncCu::checkCurDepthInPreAnaRange( TComDataCU*& pCU, UInt uidepth )  
  2. {  
  3.     UChar cuDepth         = m_preAnalyzeDepth[pCU->getZorderIdxInCU()];  
  4.     UChar cuPreDetermined = m_preAnaDepthDetermined[pCU->getZorderIdxInCU()];  
  5.     UChar cuRange         = m_preAnaDepthRange[pCU->getZorderIdxInCU()];  
  6.     assert(cuDepth+cuRange<=5);  
  7.     if ( /*cuPreDetermined &&*/ uidepth>=cuDepth && uidepth<cuDepth+cuRange )  
  8.     {  
  9.         return true;  
  10.     }  
  11.     else  
  12.     {  
  13.         return false;  
  14.     }  
  15. }  

以上是一种基于周边CTU块信息来进行CU深度优化的一种方法。这个方法对于大部分来说只是不做64X64这一层depth,因此性能损失很小,平均大概在0.2%左右。时间可以节省10%左右。

[转载请注明作者和出处]

这篇关于Fast CU Depth Decision Algorithm for HEVC Intra Coding的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/702279

相关文章

【CSS in Depth 2 精译_023】第四章概述 + 4.1 Flexbox 布局的基本原理

当前内容所在位置(可进入专栏查看其他译好的章节内容) 第一章 层叠、优先级与继承(已完结) 1.1 层叠1.2 继承1.3 特殊值1.4 简写属性1.5 CSS 渐进式增强技术1.6 本章小结 第二章 相对单位(已完结) 2.1 相对单位的威力2.2 em 与 rem2.3 告别像素思维2.4 视口的相对单位2.5 无单位的数值与行高2.6 自定义属性2.7 本章小结 第三章 文档流与盒模型(已

【CSS in Depth 2 精译_024】4.2 弹性子元素的大小

当前内容所在位置(可进入专栏查看其他译好的章节内容) 第一章 层叠、优先级与继承(已完结) 1.1 层叠1.2 继承1.3 特殊值1.4 简写属性1.5 CSS 渐进式增强技术1.6 本章小结 第二章 相对单位(已完结) 2.1 相对单位的威力2.2 em 与 rem2.3 告别像素思维2.4 视口的相对单位2.5 无单位的数值与行高2.6 自定义属性2.7 本章小结 第三章 文档流与盒模型(已

每天一道面试题(2):fail-safe 机制与 fail-fast 机制分别有什么作用?

当谈论Java集合的 fail-fast 和 fail-safe 机制时,涉及的是在集合被并发修改时的行为和处理方式。这些机制对保证程序的正确性和稳定性非常重要,尤其是在多线程环境中。 1. Fail-Fast 机制 定义: Fail-fast 机制的核心是在检测到集合在遍历过程中被修改时,立即抛出 ConcurrentModificationException 异常,从而中断迭代操作。这种

【tensorflow 使用错误】tensorflow2.0 过程中出现 Error : Failed to get convolution algorithm

如果在使用 tensorflow 过程中出现 Error : Failed to get convolution algorithm ,这是因为显卡内存被耗尽了。 解决办法: 在代码的开头加入如下两句,动态分配显存 physical_device = tf.config.experimental.list_physical_devices("GPU")tf.config.experiment

UVa 11992 Fast Matrix Operations 线段树

UVa 11992 Fast Matrix Operations 题目大意:有一个r行c列的全0矩阵,支持三种操作: 1 x1 y1 x2 y2 v 子矩阵(x1,y1,x2,y2)的所有元素增加v(v > 0)。 2 x1 y1 x2 y2 v 子矩阵(x1,y1,x2,y2)的所有元素设为v(v > 0)。 3 x1 y1 x2 y2    查询子矩阵(x1,y1,x2,y2

【算法:二分查找】java算法二分查找,如何通过二分查找找到重复元素的第一个,coding

二分查找算法,是基于有序的结果集进行查询的 二分查找的时间复杂度是O(logN) 写一段二分查询的代码: public static void main(String[] args) {int[] data = new int[]{1, 2, 3, 3, 5, 5, 6, 8, 9, 9, 10};int queryData = 5;int index = queryDataIndex(qu

【HDU】4965 Fast Matrix Calculation 矩阵快速幂

传送门:【HDU】4965 Fast Matrix Calculation 题目分析:因为比赛的时候写的太匆忙。。写的不堪入目,所以赛后重写了一次,顺便就贴一下了。 因为A*B=C,所以C^(N*N-1) = A*B*A*B*A*...*B*A*B,因为满足结合律所以变成A*( (B*A)^(N*N-2) )*B,因为中间得到的矩阵最大不超过K(K<=6),所以可以对中间的矩阵快速幂,然

Fast Image Cache

https://github.com/path/FastImageCache   Fast Image Cache is an efficient, persistent, and—above all—fast way to store and retrieve images in your iOS application. Part of any good iOS applica

阅读笔记(四)NoSQL的选择指引《NoSQL database systems: a survey and decision guidance》

一. 前言   《NoSQL database systems: a survey and decision guidance》是一篇很好的综述类论文,详细的论述了NoSQL的特点和各种不同NoSQL数据库的选择依据。   传统的关系型数据库(relational database management systems ,RDBMSs)可以在保证一致性、可靠性、稳定性的前提下提供强有力的数据存储

NCBI-get-GCFIDs_fast.py

import requestsimport osimport redef download_genome_first(gcf_id):# 构建FTP下载路径base_url = "https://ftp.ncbi.nlm.nih.gov/genomes/all/GCF/"# 提取GCF号的数字部分并按三位分割parts = gcf_id.split('_')[1] # 提取数字部分path_