随笔分类 - H.264/JM

摘要:在H.264中衡量失真(distortion)的方法 主要有:SAD,SATD和SSD三种方法,即:这三种失真计算方法使用的场合是不一样的.(1)SAD/SATD主要用于在帧间预测中, 进行运动搜索的时候,计算块匹配之间的代价的时候,在进行模式选择的时候, 使用的是SAD, 或者SATD(2) SSD 计算的失真比较精确, 主要是在真正的编码过程中所使用的. 在进行模式选择的时候, 如何使用RDO的话, 也要计算SSD(3)对于整象素点的 MV 搜索,Distortion 采用 SAD,对于亚(分数)象素点的 MV 搜索,Distortion 采用 SATD。H.264编码后码流的生成 H.. 阅读全文
posted @ 2012-07-31 15:12 Mr.Rico 阅读 (1278) | 评论 (0) 编辑
摘要:关于JM93的compute_colocated函数1、为什么用到RSD这个宏?#define RSD(x) ((x&2) ? (x|1) : (x&(~1)))关于这个宏的使用协议中是否有相应的说明?2、storable_picture结构体中ref_idx, re_pic_id, ref_id有什么区别? int*** ref_idx; //!moving_block[i][j] = !((!p->is_long_term &&((p->ref_idx[LIST_0][i][j] == 0) && (abs(p->mv[LI 阅读全文
posted @ 2012-07-31 15:09 Mr.Rico 阅读 (575) | 评论 (0) 编辑
摘要:JM8.6中的运动搜索:BlockSAD数组的理解,SetupLargrBlocks函数理解整象素搜索主要包括3个函数SetupFastFullPelSearch,SetMotionVectorPredictor,SetupLargerBlocks, 都位于文件mv_search.c中间。int *****BlockSAD; //!max_num_references+1][8][16][ max_pos] BlockSAD用于根据4x4块来计算其他大块的SAD值从对BlockSAD进行分配空间的函数可以看出: InitializeFastFullIntegerSearch 通过对函数void 阅读全文
posted @ 2012-07-31 15:06 Mr.Rico 阅读 (433) | 评论 (0) 编辑
摘要:这是网上的一篇文章, 我重新读了一下, 然后做了一些整理 1.为什么要进行变换 空间图像数据通常是很难压缩的:相邻的采样点具有很强的相关性(相互关联的),而且能量一般平均分布在一幅图像中,从而要想丢掉某些数据和降低数据精度而不明显影响图像质量,就要选择合适的变换,方法,使图像易于被压缩。适合压缩的变换方法要有这样几个性质: (1).可以聚集图像的能量(将能量集中到少数有意义的数值上),如下图: 举个例子说明, 左图是变换前的数据, 右图是变换后的数据: 可以看出,经变换后,数据的能量基本上集中到左上方(低频信号)了,而变换后的数据完全可以通过反变换还原成原来的数据。为了达到压缩文件... 阅读全文
posted @ 2012-07-31 14:27 Mr.Rico 阅读 (8264) | 评论 (2) 编辑
摘要:2011年4月20日15:16:43 JM8.6中对数据分割的一点解释 分析currslice->partarr[partmap[SE_MVD]] (关于数据分割的实现) Currslice指当前slice Partarr是一个datapartition数组 Partmap :const int* partmap = assignse2partition[input->partition_mode]; Int * assignse2partition[2] ; Static int assignse2partition_nodp[SE_MAX_ELEMENTS] = { 0, 0, 阅读全文
posted @ 2012-07-31 14:16 Mr.Rico 阅读 (789) | 评论 (0) 编辑
摘要:2011-9-6 10:16:12find_sad_16x16是一个比较重要的函数, 下面是其被调用过程: 在find_sad_16x16中有一个/4和/2的问题, 这其实就牵扯到hadamard变换的问题.在H.264乐园论坛上给出的解释如下:hadamard 变换本身就有一个 /2 的操作,因此每次变换都要对所有系数进行 /2。而 find_sad_16x16 函数执行了两次 hadamard 变换:首先对 256 个系数进行一次,其次对所有 DC 系数再做一次,因此对DC 系数应该 /4,而对 AC 系数应该 /2。find_sad_16x16 函数中的:M4[ i ][j]=M0[0. 阅读全文
posted @ 2012-07-31 13:33 Mr.Rico 阅读 (2301) | 评论 (1) 编辑
摘要:H.264编码器框架图 H.264解码器框架图 H264encflow1_v2.jpg:JM6.1 H264encflow2_v2:JM6.1 H264deblock_V2:JM6.1 H.264中运动估计和运动搜索:JM6.1 H.264中的亚像素预测 JM13.2 流程图:编码与解码流程 1/4像素插值:红色的是整像素,蓝色是1/2像素(半像素),黄色是1/4像素 JM中的函数流程 阅读全文
posted @ 2012-07-31 13:06 Mr.Rico 阅读 (2117) | 评论 (0) 编辑
摘要:JM86中多参考帧相关问题关于jm86中MAX_LIST_SIZE值的选取我们知道在参考图像队列中listX[ i ][ j ], 这边的i的取值范围是0~5,而且0~5所代表的含义论坛上已经有人说过。即如下:istXsize[6];奇数为参考帧列表 list0 中参考帧的个数;偶数为参考帧列表 list1 中参考帧的个数。0、1用于帧图像或者场图像,2、3用于MBAFF帧图像中顶宏块,4、5用于MBAFF帧图像中底宏块所有涉及帧间参考的大小为6的数组都可以这样类推。例如listX[6],它的解释就是:奇数为参考帧列表 list0;偶数为参考帧列表 list1。0、1用于帧图像或者场图像,2、 阅读全文
posted @ 2012-07-31 12:39 Mr.Rico 阅读 (1921) | 评论 (1) 编辑
摘要:2011年9月5日13:47:04帧内预测之Intra16x16中的4种模式选择在JM8.6中对应的函数是Intra16x16_Mode_Decision, 该函数包括3部分: intrapred_luma_16x16:计算4种模式的预测值 find_sad_16x16: 计算SATD值作为代价,从而得到最优的模式 dct_luma_16x16:对于所选出的最优模式进行DCT变换/量化和反DCT变换和量化下面对这三个函数进行详细分析一下:(1)intrapred_luma_16x16 这个函数其实很简单, 都是对应着标准来写的. Intra16x16有vertical,... 阅读全文
posted @ 2012-07-31 11:07 Mr.Rico 阅读 (2930) | 评论 (0) 编辑
摘要:Raw Byte Sequence Packet (RBSP)String Of Data Bits (SODB)POC:Picture Order CountSequence parameter set (SPS)Picture parameter set (PPS)DPB 解码图像缓冲区decoder picture bufferIDR图像 立即刷新图像 一个序列的第一个图像,IDR图像都是I帧图像PAFF means "Picture Adaptive Field Frame", MBAFF means "MacroBlock Adaptive Field 阅读全文
posted @ 2012-07-28 14:59 Mr.Rico 阅读 (3215) | 评论 (0) 编辑
摘要:1. jm8.6中所涉及的几项关于比特分布的地方: 序列参数集SPS: parset.c文件中的GernateSPS... 具体宏块编码中的比特分布: #if TRACE snprintf(currSE->tracestring, TRACESTRING_SIZE, "Intra mode = %3d %d",currSE->value1,currSE->context); #endif 还有很相关的一个是和比特计数相关的: bitCount[BITS_COEFF_Y_MB]+=currSE->len; rate += currSE->l... 阅读全文
posted @ 2012-07-28 14:54 Mr.Rico 阅读 (1931) | 评论 (0) 编辑
摘要:帧、场编码的个人理解一、概述原始视频帧(最原始的视频数据)根据编码的需要,以不同的方式进行扫描产生两种视频帧:连续或隔行视频帧,隔行视频帧包括顶场和底场,连续(遂行)扫描的视频帧与隔行扫描视频帧有着不同的特性和编码特征,产生了所谓的帧编码和场编码。一般情况下,遂行帧进行帧编码,隔行帧可在帧编码和场编码间选取。 在帧编码中,参考为帧图像,采用帧运动补偿,两个场是联合编码;在场编码中,参考为场图像,两个场是分别编码,采用场运动补偿。二、视频序列帧、场编码方式1.固定帧编码(全帧)----视频序列的全部帧始终采用帧编码方式。 2.固定场编码(全场) 视频序列中帧被分成两个场独立编码。编码规则:(1. 阅读全文
posted @ 2012-07-28 14:18 Mr.Rico 阅读 (2432) | 评论 (0) 编辑
摘要:1、H.264新特性学习阶段 首先,我们学习的weigand的那篇关于H.264 overview的经典文献,这篇文献对H.264的新特性大部分都有讲到。之后,我们共开展三次会议来分组深入地学习H.264的各个新特性。 帧间编码小组主讲的内容有:高精度运动估计,分析了H.264的半象素点插值预测和1/4象素点插值预测,同时还分析了H.263的半象素点的插值预测以作比较。多参考帧和7种宏块模式,分析它们的基本原理,并列举了一些快速算法。B帧,讲解了B帧的新特性,同时详细讲述了B帧独有的两种宏块模式direct mode和multihypothesis mode。 帧内编码小组主讲的内容有:... 阅读全文
posted @ 2012-07-28 14:15 Mr.Rico 阅读 (3596) | 评论 (0) 编辑
摘要:<<H.264 中 4x4 块的快速帧内预测算法>>作者:王启文,黄东军目前,对帧内预测的研究已取得很多成果,如快速三步法 [1]。该算法利用相邻预测方向的相关性,选择性地计算帧内方向预测模式,以达到减少率失真优化计算量的目的,但它对编码时间的节约效果不理想。文献[2]利用子块边缘的变化方向从预选模式中选取最可能的预测方向,该算法采用边缘梯度直方图法,在几种最可能的预测方向中选取最佳预测方向,在视频场景较复杂的情况下,其视频压缩效果不佳。文献[3]对文献[2]算法进行改进,但对预测正确率的提高效果不明显。文献[4]提出自适应阈值快速算法,利用邻块相关性为当前块的率失真设 阅读全文
posted @ 2012-07-28 13:52 Mr.Rico 阅读 (1473) | 评论 (0) 编辑
摘要:2011年8月18日 09时31分13秒SODB到RBSP的转换:对SODB的最后填充rbsp_trailing_bits就得到RBSP,而这个rbsp_trailing_bits是第一个比特为1,接下来是0,直到字节对齐。比如SODB的最后几个比特是1001,这时rbsp_trailing_bits即为:1000SODB 到RBSP到转换代码如下:void SODBtoRBSP(Bitstream*currStream){ currStream->byte_buf <<= 1; //左移1bit currStream->byte_buf |= 1; //在尾部填一个& 阅读全文
posted @ 2012-07-28 11:16 Mr.Rico 阅读 (5077) | 评论 (0) 编辑
摘要:writeSyntaxElement_NumCoeffTrailingOnes里有lentab[3][4][17] codtab[3][4][17]编码非零系数数目 (NumCoeff)和拖尾系数数目(TrailingOnes)writeSyntaxElement_NumCoeffTrailingOnesChromaDC里有lentab[4][5] codtab[4][5]与上面的函数功能一样, 只是这儿特别针对Chroma DC(色度直流系数)writeSyntaxElement_TotalZeros里有lentab[TOTRUN_NUM(15)][16] codtab[TOTRUN_NUM 阅读全文
posted @ 2012-07-28 09:23 Mr.Rico 阅读 (2476) | 评论 (0) 编辑
摘要:首先,写一些关于-f和-d命令的使用情况吧。在jm代码内部,默认的设置文件是encoder.cfg,这个文件需要在工作目录下,程序才找得到。如果在工作目录下有这个cfg文件,选用-d xxxx.cfg或-f xxxx.cfg时的效果是一样的。如果工作目录下没有这个encoder.cfg文件,选用-d xxxx.cfg会达到效果,但是-f xxxx.cfg 却不能达到效果。我看了一下代码主要原因是程序在测试是否为-f命令之前要对一个配置文件进行解析,如果默认的配置文件不存在,程序在解析配置默认文件 (encoder.cfg)时出错,直接退出了 配置文件的理解:Files输入/输出文件配置 这.. 阅读全文
posted @ 2012-07-27 22:52 Mr.Rico 阅读 (1691) | 评论 (0) 编辑
摘要:在JM代码中共有3个方法进行RDCost的计算,主要为:RDCost_for_4x4IntraBlocks, RDCost_for_4x4IntraBlocks被调用的函数 可以发现, RDCost_for_4x4IntraBlocks只被一个函数直接调用, 从调用流程我们就可精确的知道RDCost_for_4x4IntraBlocks的用处:帧内模式I4MB在RDO方式下的计算函数, 主要是计算一个4x4块的RDO代价RDCost_for_8x8blocks, 该函数一个宏块的4个8x8块在亚宏块模式下进行模式选择的时候, 计算其RDO代价, 根据求得的代价对当前的... 阅读全文
posted @ 2012-07-27 21:27 Mr.Rico 阅读 (1477) | 评论 (0) 编辑
摘要:JM8.6中关于PSNR(峰值信噪比), img->quad的解释:在JM代码中,多次遇到img->quad这个东西,而在官方代码中只给出了一句说明: 我开始看了好几遍都没有看懂,然后看到后面有snr,所以想应该和snr有关吧.然后再代码中寻找snr,发现jm代码中有一个函数,然后就往下看,忽然发现这儿 在老毕的书上有 我们可以对比上面的公式发现,令n=8,我们可以得出代码中的65025=(2^8-1)=255^2,所以主要是MSE的计算,而MSE是均方误差,所以可以推断出diff_y应该是误差的平方,我们看看diff_y的计算, 联系一下quad的含义,我突然感觉有些明白原代码注 阅读全文
posted @ 2012-07-27 18:58 Mr.Rico 阅读 (879) | 评论 (0) 编辑
摘要:关于 int ****cofAC变量的理解 对cofAC, cofAC8x8, cofDC, cofAC4x4, cofAC4x4intern的探讨 我要在这儿解释一下红框内的一些变量的含义:我在JM86的代码中搜索了一下,发现cofAC4x4intern使用的地方没有几处: 再看,我觉得貌似cofAC4x4intern没有什么用处, 只是为了通过get_memACcoeff来对cofAC4x4进行分配内存空间,可能懒得再写一个单独为cofAC4x4分配空间的函数了吧。对于cofAC4x4这个容易理解了,就是一个4x4小块的AC系数cofDC是包括色度块在内的6个8x8大小块(亮... 阅读全文
posted @ 2012-07-27 18:57 Mr.Rico 阅读 (820) | 评论 (1) 编辑
摘要:JM8.6中的关于写比特流的问题 通过上面的对比, 我们可以发现store_coding_state函数和reset_coding_state函数基本上完全一致, 对于cs_mb, store_coding_state函数将img->currentslice变量中的一些需要保存的量存储在cs_mb中, 然后等到进行编码完成后, 要恢复现场, 利用reset_coding_state函数将cs_mb中保存的相关量恢复到变量img->currentslice中, 便于下面的利用.从上面的截图我们也可以看出, 对于非CABAC编码的状况, 主要是保存的bitstream 而对于CABAC 阅读全文
posted @ 2012-07-27 17:04 Mr.Rico 阅读 (432) | 评论 (0) 编辑
摘要:JM8.6中encode_one_macroblock函数的运作流程[宏块代价函数的使用或帧间帧内模式选择流程]在JM中最重要, 最核心的一个函数就是encode_one_macroblock, 这个函数是整个编码器的核心, 其实, 通过读源码,可以发现, encode_one_macroblock中的大部分工作是在进行模式的选择, 下面我们跟着代码走一下, 看看具体的流程: (我们假设帧间帧内同时都允许)1. 帧间三种帧间宏块级模式( 16×16, 16×8,8×16) 循环, 进行择优 同时将min_cost初始化为最大值, 将best_mode初始化为1(1 阅读全文
posted @ 2012-07-27 17:02 Mr.Rico 阅读 (1317) | 评论 (2) 编辑
摘要:JM8.6中的运动估计BlockMotionSearch函数对不同帧间模式block type (1-16x16 ... 7-4x4)进行运动搜索.从该函数中,我们可以发现,有一个局部变量,通过下面的语句将img->pred_mv与pred_mv联系了起来, 这样其实通过调用函数SetMotionVectorPredictor来计算运动矢量的预测值(MVpred), 代码中向SetMotionVectorPredictor函数传递了pred_mv这个整型指针(指向img->pred_mv具体要保存的地方), 这样在函数SetMotionVectorPredictor中求出运动矢量的 阅读全文
posted @ 2012-07-27 17:02 Mr.Rico 阅读 (605) | 评论 (0) 编辑
摘要:JM8.6中enc_frame_picture, enc_pictures的理解 在frame_picture函数中有这么一句: 同样在field_picture中有这么一句: 从上面我们似乎可以看出一点东西, enc_picture就是指的图像, 这个图像的含义比较广, 包括了frame_picture, top_picture和bottom_picture. 所以我们看到在代码中有将enc_frame_picture, enc_top_picture和enc_bottom_picture分别赋值给enc_picture. 我们猜想, 因为在frame_picture() 和field_pi 阅读全文
posted @ 2012-07-27 17:00 Mr.Rico 阅读 (522) | 评论 (0) 编辑
摘要:JM8.6代码文件结构总结一下, JM8.6中比较重要的源代码文件[block.c]用于处理一个块 void intrapred_luma (int img_x, int img_y, int *left_available, int *up_available, int *all_available)void intrapred_luma_16x16 ()int dct_luma_16x16 (int new_intra_mode)int dct_luma (int block_x, int block_y, int *coeff_cost, int old_intra_mode)in... 阅读全文
posted @ 2012-07-27 16:57 Mr.Rico 阅读 (1816) | 评论 (0) 编辑
摘要:2011年5月2日16:31:18img->mb_ximg->block_ximg->pix_ximg->opix_xin the function init_frame, we got this: it is obvious that here , the function just initialize the variables.在函数set_MB_parameters中完成了对img中几个变量的赋值如: 阅读全文
posted @ 2012-07-27 16:43 Mr.Rico 阅读 (465) | 评论 (0) 编辑
摘要:2011年4月24日9:30:25JM8.6中重要结构体说明[global.h文件]下面是一些枚举类型的定义数据分区方式:PAR_DP_TYPE[PAR_DP_1(不使用数据分区), PAR_DP_3(使用ABC3数据分区)]输出文件的类型:PAR_OF_TYPE[PAR_OF_ANNEXB, PAR_OF_RTP] 编码的方式: CodingType [FRAME_CODING, FIELD_CODING, ADAPTIVE_CODING]句法元素的类型: SE_type[SE_HEADER, SE_PTYPE, SE_MBTYPE, SE_REFFRAME, SE_INTR... 阅读全文
posted @ 2012-07-27 16:33 Mr.Rico 阅读 (1489) | 评论 (0) 编辑
摘要:2011年4月23日22:22:12H.264编码后码流的生成 H.264 比较全的编码框架 2011年4月23日22:23:35H.264中的PB帧编码 在针对连续动态图像编码时,将连续若干幅图像分成P,B,I三种类型,P帧由在它前面的P帧或者I帧预测而来,它比较与它前面的P帧或者I帧之间的相同信 息或数据,也即考虑运动的特性进行帧间压缩。P帧法是根据本帧与相邻的前一帧(I帧或P帧)的不同点来压缩本帧数据。采取P帧和I帧联合压缩的方法可达到 更高的压缩且无明显的压缩痕迹。在H.264编码中,I帧是内部编码帧,不需要参考其它帧,P帧需要前向的I帧作为参考,B是双向预测帧,需... 阅读全文
posted @ 2012-07-27 16:30 Mr.Rico 阅读 (6324) | 评论 (2) 编辑
摘要:2011年4月22日19:49:49题目: JM8.6中帧内帧间模式的选择在JM8.6中帧内与帧间模式的选择是其中非常重要的一部分, 模式选择的过程其实涵盖了H.264编码中的大部分内容. 从代码看来, 这一部分其实和码率控制中的代价函数计算是重叠在一起的, 在进行代价函数的计算过程中也就实现了模式的选择, 代价计算完毕, 最优模式也就选择完毕. 1. 下面, 我们先回顾一下H.264中的帧内预测算法: 2. H.264中的帧间模式选择算法: 在帧间模式选中, 要进行的一个重要的过程就是运动估计(运动搜索)3. 代价函数在上面我们也提到过, 帧内帧间模式的选择其实和代价的计算是重... 阅读全文
posted @ 2012-07-27 16:13 Mr.Rico 阅读 (3699) | 评论 (1) 编辑
摘要:下面是在阅读JM8.6的过程中,对encode_one_macroblock的注释。/*! ************************************************************************************* * \brief * Mode Decision for a macroblock * //+++该函数的作用是编码一个宏块(包括帧间、帧内、帧内预测的方式)。 * NOTE:从上面程序段中可以看出JM8.5中对种宏块模式是采用全部遍历的方式,所以导致的计算复杂度很高。 **************************... 阅读全文
posted @ 2011-04-04 17:06 Mr.Rico 阅读 (3155) | 评论 (0) 编辑