-
CompressCU函数:LCU的编码,包括CU的划分,PU模式的决定,TU的划分
2014-12-21 11:08:40这次要做的是把模式保留下来,可以减少熵编码的比特数。这样就必须彻底的弄清楚CU的递归的划分也就是xcompressCU这个函数。这样才知道什么时候保存需要的模式,保存到哪里去,以什么形式存储,在熵编码的时候如何对...看过好几次CompressCU函数,都是一知半解。这次要做的是把模式保留下来,可以减少熵编码的比特数。这样就必须彻底的弄清楚CU的递归的划分也就是xcompressCU这个函数。这样才知道什么时候保存需要的模式,保存到哪里去,以什么形式存储,在熵编码的时候如何对PU的模式进行索引。
1.xCompressCU 函数的调用在编码一个片的函数CompressSlice 函数中有这个几行代码// run CU encoderm_pcCuEncoder->compressCU( pcCU ); 就是一个LCU的编码,包括CU的划分,PU模式的决定,TU的划分m_pcCuEncoder->encodeCU( pcCU ); 这里可以看出来pcCU是存储着需要编码的信息。2.进入这个函数Void TEncCu::compressCU( TComDataCU*& rpcCU ){// initialize CU datam_ppcBestCU[0]->initCU( rpcCU->getPic(), rpcCU->getAddr() );//这里的 m_ppcBestCU[0]和m_ppcTempCU[0]都是记录模式信息的,至于如何记录我们一点点的来看。由于是递归的划分CU,这里容易绕晕啊。m_ppcTempCU[0]->initCU( rpcCU->getPic(), rpcCU->getAddr() );// analysis of CUxCompressCU( 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 2NX2NxCheckRDCostMerge2Nx2N( rpcBestCU, rpcTempCU, &earlyDetectionSkipMode ); Merge 2NX2NxCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2Nx2N, bFMD ); 2NX2NxCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_NxN, bFMD ); NXN 划分为4个PUxCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_Nx2N, bFMD ); Nx2N 划分为2个PUxCheckRDCostInter ( 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帧内预测编码之LCU四叉树结构分块
2014-10-18 22:10:29从十月份开始,接触HEVC已经将近两个月了,可是效果并不是很明显,这两天都在看代码,经过一段时间的折腾,加上分析学习HEVC_CJL兄弟的文章,终于对HEVC帧内预测编码有了一定的理解,现在主要把本人对于如何LCU如何...原文地址:http://blog.csdn.net/yangxiao_xiang/article/details/8270723
从十月份开始,接触HEVC已经将近两个月了,可是效果并不是很明显,这两天都在看代码,经过一段时间的折腾,加上分析学习HEVC_CJL兄弟的文章,终于对HEVC帧内预测编码有了一定的理解,现在主要把本人对于如何LCU如何进一步细分成CU的过程跟大家分享一下,好了,闲话少叙,下面进入主题:
首先,对于四叉树的分割形式,大家想必都已经了解了,这里就不进行过多的赘述,下面是常见的四叉树结构示意图:接下来是代码部分:
该过程主要由TEncCu::xCompressCU函数的递归实现。
既然已经知道,CU的分割是通过递归实现的,那么怎么确定哪个uiDepth的CU为rpcBestCU呢?// 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 ); } }
上述递归函数结束后,然后再通过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/3D-HEVC视频编码中LCU分割信息提取及保留
2016-12-09 13:16:10经过查阅许多牛人的博客,特别是要感谢博主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; }
-
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来比较是否选用分割!
-
HEVC的LCU分割划分查看代码
2013-12-30 20:15:33相比于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 模式选择过程分析(CTU的深度选择及CU的分割)
2019-10-31 20:08:27HEVC 的最大编码单元为 LCU,即 64×64 的 CU,对一个 LCU 选择最佳 CU编码深度,需要遍历所有 64×64 到 8×8 的分割,一共 85 个 CU,通过计算率失真代价选择此 LCU 的最佳分割方式。对于每一个 CU,遍历帧内和帧... -
HM编码器代码阅读(10)——片的编码
2016-04-14 15:14:19这个函数主要是设置一些参数和初始化一些东西,然后对片中的每一个LCU调用initCU(初始化CU)和compressCU(对CU编码)和encodeCU(对CU进行熵编码,目的是选择最优参数)。 TEncSlice::compressSlice函数的详解: ... -
浅析HEVC/H.265编码器中的熵编码
2020-03-29 21:57:18为了实现目标,HEVC采用了一些全新的编码技术,比如:基于LCU(Largest Coding Unit)和四叉树(Quad Tree)的灵活编码结构[1]、大尺寸变换单元结构的选择[3]、改进的去方块滤波技术以及HEVC的并行化改进设计等。... -
基于多类支持向量机的3D-HEVC深度视频帧内编码快速算法
2021-01-14 16:56:21在离线模型训练中,用深度视频最大编码单元(LCU, largest coding unit)的最优划分深度作为标签,当前LCU的空域复杂度、空域相邻LCU的最优划分深度和彩色视频对应LCU的最优划分深度作为特征去构造MSVM模型。在编码时... -
AV1编码标准-算法描述
2020-10-15 22:35:22AV1编码标准 本文档介绍了相关编解码器中包含的编码工具的技术方面。...LCU: Largest coding unit OBMC: Overlapped Block Motion Compensation CDEF: Constrained Directional Enhancement Filter 块划分 -
研究论文-纹理图的3D-HEVC深度图编码单元快速划分算法.pdf
2019-08-07 15:26:18为了降低3D-HEVC编码标准中深度图的帧内预测编码复杂度和编码时间,使用概率统计分析纹理图的最大编码单元(LCU)划分分布与深度映射图的LCU划分分布之间的相关性,提出一种快速算法,通过判断纹理图中LCU的划分深度,跳过... -
HEVC编码块CU递归划分
2019-08-09 21:27:40#HEVC编码块CU的划分 在HEVC中CU的大小包括:64x64、32x32、16x16、8x8。对于一个LCU(最大的CU64x64)可以向下深度为4的划分为子CU,深度为0代表LCU不划分(64x64)、深度为1代表LCU向下四叉树划分一次(32x32)、... -
HEVC—编码树结构
2014-12-25 21:41:42HEVC中有CU,TU,PU概念就不多说了...在编码配置文档之中可以配置初始的LCU的大小也就是初始根节点CTU的大小 假设这里为64*64 在确定是否进行劈分的过程中利用一个CU_split_flag进行标识,同时结合四叉树的深度信息。获 -
HEVC码率控制介绍(R-Lamda)
2019-02-24 21:16:08转自:HEVC码率控制介绍(R-Lamda) ...第一类:K0103码率控制算法主要是在P/B帧上提出的,I帧没有做,体现在I帧中LCU编码时用的还是帧层的QP,而帧层的QP是由配置文件(即*.cfg中QP: 32 # Quantization par... -
HM编码器代码阅读(11)——CU的初始化
2016-04-14 15:32:43入口函数TComDataCU::initCU 主要流程: (1)计算当前LCU在图像中的像素地址 (2)计算LCU可以被分成多少个4x4的CU (3)把片的起始CU的地址存储起来 ...// 编码单元初始化 Void TComDataCU::initCU( TC -
使用opencl实现编码算法中运动搜索模块速度对比
2015-10-14 15:36:08使用opencl来实现编码算法中运动搜索模块! 下面测试数据时在GTX570上的测试结果: LCU为32x32, 100帧720P, CPU上纯C算法使用搜索时间是67s, GPU上是0.915s LCU为16x16, CPU 是76.8s, GPU上是1.6s LCU... -
java 通用编码解决方案
2018-03-26 14:32:48package com.lcu.web.filter; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Map; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax... -
HTM-16.2代码(1)——编码端一些函数的说明
2017-01-03 11:05:11(1)片编码器的初始化——initEncSlice 主要是设置和计算一些参数,为片的编码做准备 ...主要是设置一些参数和初始化一些东西,然后对片中的每一个LCU调用initCtu(初始化CU)和compressCtu(对CU编码)和e... -
视频编码中码率控制的上手实际操作
2019-12-05 21:08:10在VVC或则HEVC中进行码率控制的具体操作码率控制的主要步骤编码结构中rate control介绍和设置码率控制的具体操作 码率控制的主要步骤 码率控制的研究主要有两个步骤:一、目标比特的分配,将比特数分配到各个级别... -
HEVC函数入门(16)——Slice编码
2017-08-01 22:05:07这篇文章很多东西还没搞懂,所以先转载放在这。 入口函数TEncSlice::...这个函数主要是设置一些参数和初始化一些东西,然后对片中的每一个LCU调用initCU(初始化CU)和compressCU(对CU编码)和encodeCU(对CU进行熵 -
HM编码器代码阅读(8)——其他的一些重要的变量和数据结构的说明
2016-04-13 17:06:04TComDataCU:LCU 及其子 CU 的数据结构,存储了一个 LCU 所有的相关信息,里面重要的数据结构包括: m_uiCUAddr:一个 LCU 在 slice 中的位置 m_uiAbsIdxInLCU:当前 CU 在 LCU 中的位置,位置用 Z 扫描顺序 m_... -
----- PrintStream_都市游侠_新浪博客 http://blog.sina.com.cn/s/blog_6c1fe98c01012lcu.html
2014-05-13 09:38:51PrintStream,它可以将Java的基本资料型态等资料,直接转换为系统预设编码下对应的字元,再输出至OutputStream中,而这边要介绍的 PrintWriter其功能上与PrintStream类似,除了接受OutputStream之外,它还可以接受...
-
朱老师C++课程第3部分-3.6智能指针与STL查漏补缺
-
在高密度软件定义的WiFi网络中实现负载平衡
-
项目管理工具与方法
-
【Python-随到随学】 FLask第一周
-
Galera 高可用 MySQL 集群(PXC v5.6 + Ngin
-
2009年下半年 信息系统管理工程师 上午试卷 综合知识 软考真题【含答案和答案解析】
-
二叉树搜索树(无左旋右旋)C 迭代寻找插入
-
2019年下半年 信息系统监理师 上午试卷 综合知识 软考真题【含答案和答案解析】
-
沿RF锁相辅助的光纤环路链路上任意中间点的精确时延感测和工作台频率分配
-
深入剖析 ConcurrentHashMap
-
聊聊分布式事务,再说说解决方案
-
智能停车场云平台(附vue+SpringBoot前后端项目源码)
-
JMETER 性能测试基础课程
-
2016年下半年 信息系统监理师 上午试卷 综合知识 软考真题【含答案和答案解析】
-
电影记录-源码
-
2012年下半年 信息系统监理师 上午试卷 综合知识 软考真题【含答案和答案解析】
-
docker 20.10.3 配置国内源
-
用nodejs抓取-源码
-
Liunx 优化思路与实操步骤
-
设计需求分析方法与过程