精华内容
下载资源
问答
  • 经过查阅许多牛人的博客,特别是要感谢博主minbiao880224...能够显示彩色图像LCU分割信息,也增加了一些新的代码(比如提取txt文档二进制数据,yuv文件420

         经过查阅许多牛人的博客,特别是要感谢博主minbiao880224(http://blog.csdn.net/minbiao880224/article/details/17685935),具体LCU分割信息提取参照该博主的文章,本文将博文中LCU显示MATLAB代码改写成了opencvC++代码,能够显示彩色图像LCU分割信息,也增加了一些新的代码(比如提取txt文档二进制数据,yuv文件420格式转换为Mat格式),希望对初学opencv mat类有一定帮助吧!

    #include "opencv2/opencv.hpp"
    #include <iostream>
    #include <fstream>
    
    using namespace std;
    using namespace cv;
    
    
    #define LCU_Size 64
    #define MaxNumPartition 256
    #define nWidth 1024
    #define nHeight 768
    #define FrameSize nWidth*nHeight*3/2
    #define NumLCU_Row  (nWidth + LCU_Size - 1) / LCU_Size
    #define NumLCU_Col  (nHeight + LCU_Size - 1) / LCU_Size
    #define Numdata  NumLCU_Row*NumLCU_Col*MaxNumPartition
    
    void DrawCUDepthLine(Mat rgbImg, int* DepthCTU, int uiPelX, int uiPelY, int uiSize_X, int  uiSize_Y, int uiNumPartition)
    {
    	int uiDepth = DepthCTU[0];
    	if (uiDepth == 0) { return; }
    	else
    	{
    		for (int i = 0; i < uiNumPartition; i++)
    		{
    			DepthCTU[i] -= 1;
    		}
    		Point p1, p2;
    		p1.x = uiPelX + uiSize_X / 2; p1.y = uiPelY;
    		p2.x = uiPelX + uiSize_X / 2; p2.y = uiPelY + uiSize_Y;
    		line(rgbImg, p1, p2, cv::Scalar(255, 0, 0), 1);
    		Point p3, p4;
    		p3.x = uiPelX; p3.y = uiPelY + uiSize_Y / 2;
    		p4.x = uiPelX + uiSize_X; p4.y = uiPelY + uiSize_Y / 2;
    		line(rgbImg, p3, p4, cv::Scalar(255, 0, 0), 1);
    		//further drawing
    		int uiNextSize_X = uiSize_X / 2;
    		int uiNextSize_Y = uiSize_Y / 2;
    		int uiNumPartitionNext = uiNumPartition / 4;
    
    		for (int iAbsPartY = 0; iAbsPartY < 2; iAbsPartY++)
    		{
    			for (int iAbsPartX = 0; iAbsPartX < 2; iAbsPartX++)
    			{
    
    				int uiNextPelX, uiNextPelY;
    				int  iAbsPartIndex = iAbsPartY * 2 + iAbsPartX;
    				int* iNextDepth = new int[uiNumPartitionNext];
    				for (int i = 0; i <uiNumPartitionNext; i++)
    				{
    					iNextDepth[i] = DepthCTU[i + iAbsPartIndex * uiNumPartitionNext];
    				}
    				uiNextPelX = uiPelX + iAbsPartX*uiNextSize_X;
    				uiNextPelY = uiPelY + iAbsPartY*uiNextSize_Y;
    				DrawCUDepthLine(rgbImg, iNextDepth, uiNextPelX, uiNextPelY, uiNextSize_X, uiNextSize_Y, uiNumPartitionNext);
    
    			}
    
    		}
    
    	}
    
    }
    
    
    int main()
    {
    
    	//读取txt文件分割深度数据存入arr数组中,每个分割深度数据代表4*4的块,一个LCU有256个分割深度数据
    	int length = 0;
    	ifstream t("BestDepth.txt", ios::in | ios::binary);
    	if (!t)
    	{
    		cout << "open error!" << endl;
    		return 1;
    	}
    	t.seekg(0, std::ios::end);    // go to the end  
    	length = t.tellg();           // report location (this is the length)  
    	cout << "length=" << length << endl;
    	t.seekg(0, std::ios::beg);    // go back to the beginning  
    	char* buffer = new char[length];    // allocate memory for a buffer of appropriate dimension  
    	t.read(buffer, length);
    	int* arr = new int[length];
    	for (int i = 0; i<length; i++)
    	{
    		arr[i] = (int)buffer[i];
    	}
    
    	//打开yuv文件
    	FILE *f;
    	if (!(f = fopen("balloons3.yuv", "rb")))
    	{
    		printf("file open error!");
    	}
    	//计算YUV视频帧数和文件大小
    	fseek(f, 0, SEEK_END);
    	int frame_count = 0;
    	long file_size = 0;
    	frame_count = (int)((int)ftell(f) / ((nWidth * nHeight * 3) / 2));  // ftell 用于求文件大小
    	printf("frame num is %d \n", frame_count);
    	printf("file length is   %d\n", ftell(f));
    	fseek(f, 0, SEEK_SET);//文件内位置定位到文件头
    
    
    	namedWindow("balloons", WINDOW_NORMAL);
    	int bufLen = nWidth*nHeight * 3 / 2;
    	unsigned char* pYuvBuf = new unsigned char[bufLen];
    	int pos = 0;
    	for (int n = 0; n < frame_count; n++)//对每一帧图像画LCU分割图,需要保留那一帧的LCU分割,只需修改frame_count值
    	{
    		fseek(f, pos, SEEK_SET);
    		//读取yuv420格式的文件,转换成cv::Mat格式
    		fread(pYuvBuf, bufLen*sizeof(unsigned char), 1, f);
    		Mat yuvImg;
    		yuvImg.create(nHeight * 3 / 2, nWidth, CV_8UC1);
    		memcpy(yuvImg.data, pYuvBuf, bufLen*sizeof(unsigned char));
    		Mat rgbImg;
    		cvtColor(yuvImg, rgbImg, CV_YUV2BGR_I420);
    
    		//在图像上画出LCU的分割情况
    		Point p1, p2;
    		for (int i = 1; i < nWidth / LCU_Size; i++)
    		{
    			p1.x = i*LCU_Size; p1.y = 0;
    			p2.x = i*LCU_Size; p2.y = nHeight;
    			line(rgbImg, p1, p2, cv::Scalar(0, 0, 255), 2);
    		}
    		for (int i = 1; i < nHeight / LCU_Size; i++)
    		{
    			p1.y = i*LCU_Size; p1.x = 0;
    			p2.y = i*LCU_Size; p2.x = nWidth;
    			line(rgbImg, p1, p2, cv::Scalar(0, 0, 255), 2);
    		}
    		int LCUData[MaxNumPartition];
    		for (int i = 0; i < NumLCU_Col; i++)
    		{
    			for (int j = 0; j < NumLCU_Row; j++)
    			{
    				int Idx = i*NumLCU_Row + j;
    				int uiPelX = j*LCU_Size;
    				int uiPelY = i*LCU_Size;
    
    				for (int k = 0; k <MaxNumPartition; k++)
    				{
    					LCUData[k] = arr[k + Idx*MaxNumPartition+ Numdata*n];
    				}
    				DrawCUDepthLine(rgbImg, LCUData, uiPelX, uiPelY, LCU_Size, LCU_Size, MaxNumPartition);
    			}
    		}
    		
    		imshow("balloons", rgbImg);
    		imwrite("plotLCU.jpg", rgbImg);
    		waitKey(30);
    		pos += FrameSize;
    	
    	}
    	waitKey(0);
    	destroyWindow("balloons");
    	delete[] pYuvBuf;
    	fclose(f);
    	system("pause");
    	return 0;
    }
    

    展开全文
  • 这次要做的是把模式保留下来,可以减少熵编码的比特数。这样就必须彻底的弄清楚CU的递归的划分也就是xcompressCU这个函数。这样才知道什么时候保存需要的模式,保存到哪里去,以什么形式存储,在熵编码的时候如何对...
    看过好几次CompressCU函数,都是一知半解。这次要做的是把模式保留下来,可以减少熵编码的比特数。这样就必须彻底的弄清楚CU的递归的划分也就是xcompressCU这个函数。这样才知道什么时候保存需要的模式,保存到哪里去,以什么形式存储,在熵编码的时候如何对PU的模式进行索引 
    
    1.xCompressCU 函数的调用
    在编码一个片的函数CompressSlice 函数中有这个几行代码

          // run CU encoder
          m_pcCuEncoder->compressCU( pcCU ); 就是一个LCU的编码,包括CU的划分,PU模式的决定,TU的划分
          m_pcCuEncoder->encodeCU( pcCU );  这里可以看出来pcCU是存储着需要编码的信息。
    2.进入这个函数
    Void TEncCu::compressCU( TComDataCU*& rpcCU )
    {
      // initialize CU data
      m_ppcBestCU[0]->initCU( rpcCU->getPic(), rpcCU->getAddr() ); 
    //这里的 m_ppcBestCU[0]和m_ppcTempCU[0]都是记录模式信息的,至于如何记录我们一点点的来看。由于是递归的划分CU,这里容易绕晕啊。
      m_ppcTempCU[0]->initCU( rpcCU->getPic(), rpcCU->getAddr() );

      // analysis of CU
      xCompressCU( m_ppcBestCU[0], m_ppcTempCU[0], 0 ); 这里进入xCompressCU函数,这里的第三个参数是 CU的分割深度。64x64的深度为0,以此类推,最小的CU为8x8深度为3。至于如何将最优的模式信息赋值到pcCU里,我们后面跟踪代码可以看到。
    这里首先要弄清一个概念,就是CU的划分是递归的
    第一步  CU的大小为64x64, 搜索最优的PU的划分得到最优的预测模式,进行TU的划分  
    第二步  CU的大小为32x32, 第一个CU(按之子扫描顺序) 同上
    第三步  CU的大小为16x16, 第一个CU  同上
    第四步  CU的大小为8x8,   以此进行第一个CU,第二个CU,第三个CU和第四个CU的PU和TU的划分和最优模式的选择。这里面完成每个CU后将这个的RD与前面进行累加。
    第五步  返回到CU为 16x16的CU,将其RD-COST 与第四部记录的四个8X8的CU的RD-cost进行比较。决定了这个16X16的最优的CU划分及最优的CU下的PU和CU的划分。
    第六步 CU的大小为 16X16,第二个CU。重复 第四步第五步,可以得到第二个最优的16x16的CU的划分和PU TU 的模式。 同时将改第二个CU的最优的RD-COST与5步得到的第一个16x16的CURD-COST进行累加。
    第七步 :同理完成第三个和第四个的16X16的CU的最优的划分和模式的选择,将其RD-COST累加。这样我们就得到了分割为16X16最佳的RD-cost。
    第八步 : 返回到第二步,比较第一个32X32CU的RD-cost 和 分割为4个16X16的CU的RD-cost,得了第一个32X32 CU的分割信息和最优的模式。
    第九步:同理完成第二个32x32,第三个32X32和第四个32X32的最优的划分和模式选择。通过记录和累加每一个32x32的RD-cost,与64x64的CU的RD-Cost进行比较。我们得到了最终的CU 的划分和每个CU的最优的PU的划分及PU的预测模式以及TU的划分。
    }
    3.xCompressCU( m_ppcBestCU[0], m_ppcTempCU[0], 0 )函数
    现在就按照2中的过程来看一看这函数的流程:
    首先进入该函数,CU的大小已经确定了为64x64,进行PU的划分和TU的划分
    PU的划分将按下列顺序进行尝试:
    帧间
    xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2Nx2N, bFMD )           skip 2NX2N
    xCheckRDCostMerge2Nx2N( rpcBestCU, rpcTempCU, &earlyDetectionSkipMode );  Merge 2NX2N
    xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2Nx2N, bFMD );   2NX2N  
    xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_NxN, bFMD  );   NXN  划分为4个PU
    xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_Nx2N, bFMD  );  Nx2N  划分为2个PU  
    xCheckRDCostInter      ( rpcBestCU, rpcTempCU, SIZE_2NxN, bFMD  );
    xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2NxnU, bFMD );
    xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2NxnD, bFMD );   4种非对称的划分
    xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_nLx2N, bFMD );
    这里在调用这个帧内RDcost函数时,rpcBestCU中始终存放的是当前CU下最优的PU的模式和划分信息的CU结构体。
    帧内:
    xCheckRDCostIntra( rpcBestCU, rpcTempCU, SIZE_2Nx2N );  2NX2N的划分。 PU为CU的大小。
    xCheckRDCostIntra( rpcBestCU, rpcTempCU, SIZE_NxN   );  当CU为最小的CU的时候,将尝试 分割为4个PU。
    在RD-cost的函数的最后有这样一个函数
    xCheckBestMode(rpcBestCU, rpcTempCU, uiDepth);

    接下来就该递归的分割LCU,下面看看分割的判断
      if( bSubBranch && bTrySplitDQP && uiDepth < g_uiMaxCUDepth - g_uiAddCUDepth ) 条件为真进行分割
        {
     UChar       uhNextDepth         = uiDepth+1;
          TComDataCU* pcSubBestPartCU     = m_ppcBestCU[uhNextDepth];
          TComDataCU* pcSubTempPartCU     = m_ppcTempCU[uhNextDepth];

          for ( UInt uiPartUnitIdx = 0; uiPartUnitIdx < 4; uiPartUnitIdx++ )
          {
          pcSubBestPartCU->initSubCU( rpcTempCU, uiPartUnitIdx, uhNextDepth, iQP );          
          pcSubTempPartCU->initSubCU( rpcTempCU, uiPartUnitIdx, uhNextDepth, iQP );  
          注意这里是用rpcTempCU对pcSubBestPartCU和pcSubTemPartC进行初始化,函数到此 rpcBestCU里面还是当前CU64x64大小最优的PU信息。
    接下来是递归的调用自己
    if ( rpcBestCU->isIntra(0) )
              {
                xCompressCU( pcSubBestPartCU, pcSubTempPartCU, uhNextDepth, SIZE_NONE );
          进入这个函数后,CU的大小为32X32 iPartUnitIdx 这里pcSubBestPartCU就和rpcBestCU一样始终放着当前最优的预测的信息。
              }
              else
              {
                xCompressCU( pcSubBestPartCU, pcSubTempPartCU, uhNextDepth, rpcBestCU->getPartitionSize(0) );
              }
     显然这里要做的是将4个最优的32X32CU的RD-cost累加。注意这里有一个语句是
     rpcTempCU->copyPartFrom( pcSubBestPartCU, uiPartUnitIdx, uhNextDepth ); 
    跟进去一看这个函数的几个代码就知道这个语句就是完成4个划分的最优的信息的累加,以便和为分割前的CU的最优的预测模式的RD-cost进行比较也就是m_ppcBestCU进行比较。
          }
        }  分割的循环
    完成了四个分割,即2中的过程2中的第九步。这里就 rpcTempCU存储的是CU的4个划分的信息。
    可以看见 xCheckBestMode( rpcBestCU, rpcTempCU, uiDepth);函数将未分割的CU和分割之后的4个CU进行比较来决定是否进行CU的划分。
    }

    但是奇怪的是如何和最开始CompressCU的参数pcCU的参数联系上。这里有个函数。在最后面
     rpcBestCU->copyToPic(uiDepth);  
    这个函数就是将得到的最优的PU的模式和预测信息,及CU的划分的信息赋值到pcCU中。
    进去看这个函数,
    TComDataCU*& rpcCU = m_pcPic->getCU( m_uiCUAddr );第一个语句中的rpcCU正好是CompressCU的参数。
    展开全文
  • 从十月份开始,接触HEVC已经将近两个月了,可是效果并不是很明显,这两天都在看代码,经过一段时间的折腾,加上分析学习HEVC_CJL兄弟的文章,终于对HEVC帧内预测编码有了一定的理解,现在主要把本人对于如何LCU如何...

        从十月份开始,接触HEVC已经将近两个月了,可是效果并不是很明显,这两天都在看代码,经过一段时间的折腾,加上分析学习HEVC_CJL兄弟的文章,终于对HEVC帧内预测编码有了一定的理解,现在主要把本人对于如何LCU如何进一步细分成CU的过程跟大家分享一下,好了,闲话少叙,下面进入主题:


    首先,对于四叉树的分割形式,大家想必都已经了解了,这里就不进行过多的赘述,下面是常见的四叉树结构示意图:

    接下来是代码部分:

    该过程主要由TEncCu::xCompressCU函数的递归实现

        // further split进一步进行CU的分割
        if( bSubBranch && bTrySplitDQP && uiDepth < g_uiMaxCUDepth - g_uiAddCUDepth )
        {
          UChar       uhNextDepth         = uiDepth+1;
          TComDataCU* pcSubBestPartCU     = m_ppcBestCU[uhNextDepth];
          TComDataCU* pcSubTempPartCU     = m_ppcTempCU[uhNextDepth];
    
          for ( UInt uiPartUnitIdx = 0; uiPartUnitIdx < 4; uiPartUnitIdx++ )//每次分成四个更小的CU
        {
            pcSubBestPartCU->initSubCU( rpcTempCU, uiPartUnitIdx, uhNextDepth, iQP );           // clear sub partition datas or init.
            pcSubTempPartCU->initSubCU( rpcTempCU, uiPartUnitIdx, uhNextDepth, iQP );           // clear sub partition datas or init.
    
            Bool bInSlice = pcSubBestPartCU->getSCUAddr()+pcSubBestPartCU->getTotalNumPart()>pcSlice->getDependentSliceCurStartCUAddr()&&pcSubBestPartCU->getSCUAddr()<pcSlice->getDependentSliceCurEndCUAddr();
            if(bInSlice && ( pcSubBestPartCU->getCUPelX() < pcSlice->getSPS()->getPicWidthInLumaSamples() ) && ( pcSubBestPartCU->getCUPelY() < pcSlice->getSPS()->getPicHeightInLumaSamples() ) )
            {
              if( m_bUseSBACRD )
              {
                if ( 0 == uiPartUnitIdx) //initialize RD with previous depth buffer
                {
                  m_pppcRDSbacCoder[uhNextDepth][CI_CURR_BEST]->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]);
                }
                else
                {
                  m_pppcRDSbacCoder[uhNextDepth][CI_CURR_BEST]->load(m_pppcRDSbacCoder[uhNextDepth][CI_NEXT_BEST]);
                }
              }
    
    #if AMP_ENC_SPEEDUP
              if ( rpcBestCU->isIntra(0) )
              {
                xCompressCU( pcSubBestPartCU, pcSubTempPartCU, uhNextDepth, SIZE_NONE );//递归函数
              }
              else
              {
                xCompressCU( pcSubBestPartCU, pcSubTempPartCU, uhNextDepth, rpcBestCU->getPartitionSize(0) );//递归函数
              }
    #else
              xCompressCU( pcSubBestPartCU, pcSubTempPartCU, uhNextDepth );         
    #endif
    
              rpcTempCU->copyPartFrom( pcSubBestPartCU, uiPartUnitIdx, uhNextDepth );         // Keep best part data to current temporary data.
              xCopyYuv2Tmp( pcSubBestPartCU->getTotalNumPart()*uiPartUnitIdx, uhNextDepth );
            }
            else if (bInSlice)
            {
              pcSubBestPartCU->copyToPic( uhNextDepth );
              rpcTempCU->copyPartFrom( pcSubBestPartCU, uiPartUnitIdx, uhNextDepth );
            }
          }


    既然已经知道,CU的分割是通过递归实现的,那么怎么确定哪个uiDepth的CU为rpcBestCU呢?

    上述递归函数结束后,然后再通过xCheckBestMode( rpcBestCU, rpcTempCU, uiDepth);判断决定是否选择本层CU还是下层CU.

    以下是编程实现输出一个LCU的分割模式:

      // We need to split, so don't try these modes.
      if(!bSliceEnd && !bSliceStart && bInsidePicture )
      {
        for (Int iQP=iMinQP; iQP<=iMaxQP; iQP++)
        {
          if (isAddLowestQP && (iQP == iMinQP))
          {
            iQP = lowestQP;
          }
          // variables for fast encoder decision
          bEarlySkip  = false;
          bTrySplit    = true;
          fRD_Skip    = MAX_DOUBLE;
    
          rpcTempCU->initEstData( uiDepth, iQP );
         //==输出分区深度信息depth==//
          cout<<"Depth:";
          for(Int i=0;i<=uiDepth;i++)
           cout<<"->";
           cout<<uiDepth<<endl;
    
          // do inter modes, SKIP and 2Nx2N
    打印输出的结构为:

    Depth:->0
    Depth:->->1
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->1
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->1
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->1
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->2
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3
    Depth:->->->->3


    如有错误,还望不吝赐教,特别感谢zhuix7788的指导。

    最终的LCU分割结果详见下一篇http://blog.csdn.net/yangxiao_xiang/article/details/8275181。






    展开全文
  • HEVC中LCU分割 划分查看

    热门讨论 2013-12-30 20:31:24
    相比于H.264,HEVC中特别采用了Coding ...为了查看编码过程中, LCU的最终划分,因此简单做了一个LCU分割划分的查看的代码。虽然做得比较粗糙,但是勉强能用。因为Matlab进行图片显示和操作比较容易,这里用了Matlab。
  • HEVC 中主要LCU分析函数xCompressCU说明

    千次阅读 2012-11-29 09:24:17
    所有LCU都是通过调用xCompressCU来实现其CU/PU划分. 然后通过其结果再调用 TEncCu::xencodeCU 函数来实现对所有CUs进行压缩编码.   xCompressCU大体可分为一下三块. Void TEncCu::xCompressCU() { //第...

     

    所有LCU都是通过调用xCompressCU来实现其CU/PU划分. 然后通过其结果再调用 TEncCu::xencodeCU 函数来实现对所有CUs进行压缩编码.

     

    xCompressCU大体可分为一下三块.

    Void TEncCu::xCompressCU()
    
    {      
    
         //第一块 for (Int iQP=iMinQP; iQP<=iMaxQP; iQP++)
    
    // do inter modes, SKIP and 2Nx2N
    
          if( rpcBestCU->getSlice()->getSliceType() != I_SLICE )
    
          {
    
            xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2Nx2N );
    
          xCheckRDCostMerge2Nx2N( rpcBestCU, rpcTempCU, &earlyDetectionSkipMode );
    
          }
    
         //第二块 for (Int iQP=iMinQP; iQP<=iMaxQP; iQP++)
    
          // do inter modes, NxN, 2NxN, and Nx2N
    
          if( rpcBestCU->getSlice()->getSliceType() != I_SLICE )
    
          {
    
          xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_NxN   );
    
          xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_Nx2N  );
    
          xCheckRDCostInter      ( rpcBestCU, rpcTempCU, SIZE_2NxN  );
    
          }
    
          //! Try AMP (SIZE_2NxnU, SIZE_2NxnD, SIZE_nLx2N, SIZE_nRx2N)  
    
          // do normal intra modes // speedup for inter frames
    
            {
    
            xCheckRDCostIntra( rpcBestCU, rpcTempCU, SIZE_2Nx2N );
    
            xCheckRDCostIntra( rpcBestCU, rpcTempCU, SIZE_NxN   );
    
            }       
    
            // test PCM
    
            xCheckIntraPCM (rpcBestCU, rpcTempCU);
    
          第三块//for (Int iQP=iMinQP; iQP<=iMaxQP; iQP++)
    
            // further split
    
          for ( UInt uiPartUnitIdx = 0; uiPartUnitIdx < 4; uiPartUnitIdx++ )
    
          {
    
              if ( rpcBestCU->isIntra(0) )
    
                xCompressCU( pcSubBestPartCU, pcSubTempPartCU, uhNextDepth, SIZE_NONE );
    
              else
    
                xCompressCU( pcSubBestPartCU, pcSubTempPartCU, uhNextDepth, rpcBestCU->getPartitionSize(0) );
    
          }
    
          //check是否使用split
    
          xCheckBestMode( rpcBestCU, rpcTempCU, uiDepth);
    
    }
    

    前2块实现对本层LCU的模式选择RDcost计算, 最后一块实现下层分割的计算,最后通过xCheckBestMode来比较是否选用分割!
     

     

     

    展开全文
  • 相比于H.264,HEVC中特别采用了Coding ...为了查看编码过程中, LCU的最终划分,因此简单做了一个LCU分割划分的查看的代码。虽然做得比较粗糙,但是勉强能用。因为Matlab进行图片显示和操作比较容易,这里用了Matlab。
  • LCU单元分割(续)

    千次阅读 2012-12-09 18:15:15
    上一篇文章对每个LCU进行遍历所有的CU分支,只是显示LCU的分割...因为一个LCU的最终分割是要经过预测和熵编码后才能通过率失真代价确定。所以,可以在m_pcCuEncoder->compressCU( pcCU );后查看pcCU->m_puhDepth对应的
  • 现在已经可以在下面这个函数下获得当前LCU的所有4X4块的深度信息,但是怎么获得当前LCU的上面一个LCU的信息,乃至左上角的信息呢??这个是很麻烦的问题,还待持续解决中。。。 // analysis of CU  xCompressCU( m...
  • HEVC 的最大编码单元为 LCU,即 64×64 的 CU,对一个 LCU 选择最佳 CU编码深度,需要遍历所有 64×64 到 8×8 的分割,一共 85 个 CU,通过计算率失真代价选择此 LCU 的最佳分割方式。对于每一个 CU,遍历帧内和帧...
  • 编码之Base64编码

    万次阅读 2019-10-01 09:22:46
    Base64编码是一种基于 64 个可打印字符来表示二进制数据的方法。目前 Base64 已经成为网络上常见的传输 8 位二进制字节代码的编码方式之一。 为什么会有 Base64 编码呢?因为有些网络传送渠道并不支持所有的字节,...
  • YUVviewerForHEVC 开发辅助工具 LCU查看器发布 --New Edit

    千次阅读 热门讨论 2013-01-09 16:52:37
    YUVviewerForHEVC 开发辅助工具 LCU查看器! 下载地址:(解决一些同学分辨率的问题!) 最新下载地址:; http://download.csdn.net/detail/feixiang_john/4978117  早期版本地址: ...
  • avs3编码器_avs3_源码

    2021-09-28 20:56:45
    AVS3离线编码器,支持帧级并行和lcu并行编码
  • HM编码器代码阅读(10)——片的编码

    千次阅读 2016-04-14 15:14:19
    这个函数主要是设置一些参数和初始化一些东西,然后对片中的每一个LCU调用initCU(初始化CU)和compressCU(对CU编码)和encodeCU(对CU进行熵编码,目的是选择最优参数)。 TEncSlice::compressSlice函数的详解: ...
  • YUVviewerForHEVC 开发辅助工具 LCU查看器! 下载地址:   http://download.csdn.net/detail/feixiang_john/4968921 或者 http://download.csdn.net/detail/feix
  • AV1编码标准-算法描述

    千次阅读 2020-10-15 22:35:22
    AV1编码标准 本文档介绍了相关编解码器中包含的编码工具的技术方面。...LCU: Largest coding unit OBMC: Overlapped Block Motion Compensation CDEF: Constrained Directional Enhancement Filter 块划分
  • 在离线模型训练中,用深度视频最大编码单元(LCU, largest coding unit)的最优划分深度作为标签,当前LCU的空域复杂度、空域相邻LCU的最优划分深度和彩色视频对应LCU的最优划分深度作为特征去构造MSVM模型。在编码时...
  • 【转载】LCU的划分

    千次阅读 2014-12-24 21:55:46
    以下是编程实现输出一个LCU的分割模式:   [cpp]   view plain copy //  We  need  to  split,  so  don't  try  these  modes.     if (!bSliceEnd  &&  !...
  • 入口函数TEncSlice::encodeSlice。 在处理完VPS,SPS,PPS和...(1)先初始化熵编码器,然后设置CABAC熵编码器为当前的熵编码器。 (2)然后就是加载各种熵编码器,各种初始化,各种加载上下文信息。 (3)遍历片中的每
  • HM编码器代码阅读(12)——CU编码

    万次阅读 2016-04-14 16:28:03
    xCompressCU是一个递归函数,对于每一个CU,该函数都会被调用,主要是计算当前CU编码之后代价,然后再计算当前CU的每一个子CU编码后的代价,和当前CU的编码代价相比较,用来决定是否对当前CU进行分割。 详细流程: ...
  • 浅析HEVC/H.265编码器中的熵编码

    千次阅读 2020-03-29 21:57:18
    为了实现目标,HEVC采用了一些全新的编码技术,比如:基于LCU(Largest Coding Unit)和四叉树(Quad Tree)的灵活编码结构[1]、大尺寸变换单元结构的选择[3]、改进的去方块滤波技术以及HEVC的并行化改进设计等。...
  • H.265/HEVC 中对LCU/CTU的大小限制

    千次阅读 2014-10-24 11:37:04
    当在配置文件中将LCU大小设定为8x8 ...下面是运行编码时的报错: 下面H.265官方ITU文档中Main Profile对 LCU的限制: 下面H.265官方ITU文档中Main 10 Profile对 LCU的限制:
  • 考虑到视频帧的纹理特性和编码中所采用的量化参数影响最优编码单元(CU)模式的选择,首先提取前一帧的平均分割层数和其最大编码单元(LCU)的最小分割层数来预测当前帧对应位置处LCU的最小分割层数,以跳过部分大块CU的...
  • 1、compressGOP对一整个图像组(GOP)进行编码,主要是遍历GOP中每一帧,对每一帧进行单独编码 2、每一帧又会被划分成若干slice(HM15中,每一帧对应一个slice),因此对每一帧的处理就转换成对每一片的处理。 3、...

空空如也

空空如也

1 2 3 4 5 ... 19
收藏数 369
精华内容 147
热门标签
关键字:

lcu编码