H.264 中很有用的一些概念

来源:百度文库 编辑:神马文学网 时间:2024/03/28 22:55:36

Q:PSNR

峰值信噪比

Q:是根据它来取qp是不是?

A:不是, 和QP没有直接关系, 但是QP的选择会影响到PSNR

Q: 如果不用率失真最优化, 为什么选择SATD+delta×r(mv,mode)作为模式选择的依据?为什么运动估计中,整象素搜索用SAD,而亚象素用SATD?为什么帧内模式选择要用SATD?

A: SAD即绝对误差和,仅反映残差时域差异,影响PSNR值,不能有效反映码流的大小。SATD即将残差经哈德曼变换的4×4块的预测残差绝对值总和,可以 将其看作简单的时频变换,其值在一定程度上可以反映生成码流的大小。因此,不用率失真最优化时,可将其作为模式选择的依据。一般帧内要对所有的模式进行检 测,帧内预测选用SATD的原因同上。

在做运动估计时,一般而言,离最优匹配点越远,匹配误差值SAD越大,这就是有名的单一平面 假设,现有的运动估计快速算法大都利用该特性。但是,转换后SATD值并不满足该条件,如果在整象素中运用SATD搜索,容易陷入局部最优点。而在亚象素 中,待搜索点不多,各点处的SAD差异相对不大,可以用SATD选择码流较少的匹配位置。

//----------------------------------------------------------------------------------------- 

Q:什么是SAD,SAE,SATD,SSD,SSE,MAD,MAE,MSD,MSE?

A

SAD(Sum of Absolute Difference)=SAE(Sum of Absolute Error)即绝对误差和

SATD(Sum of Absolute Transformed Difference)即hadamard变换后再绝对值求和

SSD(Sum of Squared Difference)=SSE(Sum of Squared Error)即差值的平方和

MAD(Mean Absolute Difference)=MAE(Mean Absolute Error)即平均绝对差值

MSD(Mean Squared Difference)=MSE(Mean Squared Error)即平均平方误差

--------------------------------------------------------------------------------

Q:下面代码的功能是什么?

if(pix & (~255))

{

pix1[x] = (-pix) >> 31;

}

else

{

pix1[x] = (unsigned char)pix;

}

A:

pix的定义是short型,pix1定义的是unsigned char型

这段代码可以这么理解(这段代码的功能):如果pix<0,那么pix1[x]=0,如果pix>255,那么pix1[x]=255,否则pix1[x]=pix;

Q:编解码是以什么为单位进行的?

A:在看编码解码的框图的时候,如果你以帧为输入单位来看,可能你会看不懂,所以应该以宏块为输入单位来看,因为编码解码都是以宏块为单位,逐个宏块编解码,然后组合为一帧图像的。这样你就能看明白了。所以个人认为编解码应该是以宏块为单位进行的。

Q:为何在cavlc编码的时候,第一个负数要加1?

A:如果拖尾小于3,说明第一个level的绝对值值肯定大于1。因此,level为正时,减1;为负时加1。可降低码流

Q: YCrCb 4:2:0是什么?像4:4:4和4:2:2一样表示 Y:Cr:Cb是4:2:0吗?

A: 不要让它骗了,我觉得它所表达意思应该是4:1:1,还有如果你看得是像http://www.cs.sfu.ca/CC/365/li /material/notes/Chap3/Chap3.4/Chap3.4.html 里面这样的对4:2:0的说明的烂图的话,可能看半天也不明白,建议看 里面相应的图。里面的说明也很详细:

4 : 2 :0 means that Cr and Cb each haveh alf the horizontal and vertical resolution of Y, as

shown. The term ‘4 : 2 : 0’ is rather confusing: the numbers do not actually have a sensible

interpretation and appear to have been chosen historically as a ‘code’ to identify this particular sampling pattern.

Q:H.264中,术语IDR的意思是什么,有什么用?

A:IDR-instantaneous decoding refresh (IDR)picture;

A coded picture in which all slices are I or SI slices that causes the decoding process to mark all reference pictures as "unused for reference" immediately after decoding the IDR picture. After the decoding of an IDR picture all following coded pictures in decoding order can be decoded without inter prediction from any picture decoded prior to the IDR picture. The first picture of each coded video sequence is an IDR picture.

也就是说,IDR的出现其实是相当于向解码器发出了一个清理reference buffer的信号吧,上面说前于这一帧的所有已编码帧不能为inter做参考帧了。

Q:CABAC中开始时各字符出现的概率是怎么得到的?

A:基于查表实现的

Q:我们可以从一幅图像的自相关函数图中得到不同图像之间的相似程度.在中点处的最顶点表示图像未经移动时的图像.当空域移动拷贝被从原始图像的任一个方向移除的时候,这个函数值就会急骤下降,就这说明了一个图像采样值的邻域内是高度相关的.

我想问一下,空域移动拷贝被从原始图像的任一个方向移除的时候,这是一个什么过程

A:空域移动就表示平移,求自相关函数就包含平移这个过程.你看一维的 R(t,delta)=E[X(t)*X(t+delta)] ,二维不过平移多个方向而已

Q:only the central decoder is standardized什么意思

A:意思是说264标准只定义了码流的格式 编码器实现是各公司自己的事,只要形成的码流符合标准就行 解码器必须按照这个格式来,这样任何符合标准的码流都可以解出来

Q:What is RVLC?

A:It is a VLC method which can be decoded from left to right and from right to left exclusively.

Q:RDO模型用来干什么?RQ模型又用来干什么?

A:RDO用来确定编码模式的,保证码率比特数和图像失真的最佳权衡点,而RQ是在上一层码率数一定的情况下用来确定下一层分配的比特数。RQ先于RDO进行。

Q:帧,场,图像的联系与区别是什么?

A:在分析标准时要分清帧(frame)、场(field)、图像(picture)很关键。

frame;逐行扫描图像

field:隔行扫描图像,偶数行成为顶场行,奇数行称为为底场行,所有顶场行称为顶场,同样所有底场行称为底场。

pictue:场和帧都可认为是图像

[注:SUPERPUMA语]

顶底场分别编码,对应位置的宏块叫做宏块对。顶场对已编码的顶/底场预测编码。底场一般对顶场预测编码

Q:如何在VC下编译JM

A:编码步骤:

打开tml.dsw,依次选择project->settings,在settings for那一栏中选中lencod,在右边的debug选项卡做如下填写:

Executable for debug session: 和tml.dsw同一文件夹,我填的是\JM\bin\lencod.exe,具体有什么讲究我没有研究,应该没很大关系。

Working directory:./bin

Program arguments:-f encoder.cfg decoder.cfg

Remote executable path and file name:可不填

然后,在vc中选择build->set active configurations,再选择lencod-Win32 debug.

下一步compile、build、execute,在这些之后,就完成了编码的工作。

解码步骤:

重复以上编码操作,不同之处是在settings for那一栏中选中ldecod,Executable for debug session填的路径和编码时应一样,Program arguments填decoder.cfg,build->set active configurations中选择ldecod-Win32 debug,其他不变。之后compile、build、execute,解码完成!

还有一点需要注意:编码的yuv图像要放在bin文件夹中!

Q:关于H264 ASIC设计的难点。

A:

1)怎样设计一个高效的Memory(SDRAM or DDR)系统是其中最大的挑战。MC最少的单元是4x4,因为在一行中只有4个Pixel,必然会导致memory miss rate的增加,从而降低memory BW的利用率。也许可以利用图像的空间相关性,设计一个类似于CACHE的结构。但CACHE的大小是一个值得探讨的问题。

2)怎样用相同的硬件结构来实现帧内预测和帧间预测。

3)怎样用一套硬件结构来同时实现mpeg2/4,WMV.因为核心的算法,例如DCT都不一样。

4)怎样降低熵解码的复杂度。

5)可以最多允许多少个reference Frame的问题。这对整个硬件构架没有任何影响。但直接影响成本,也就是片外要用多少M memory的问题。

A: IDR帧与I帧的区别Q:因为264采用了多帧预测,就有可能在display order下I帧后的P会参考I帧前的帧,这样在random access时如果只找I帧,随后的帧的参考帧可能unavailable,IDR就是这样一种特殊的I帧,把它定义为确保后面的P一定不参考其前面的 帧,可以放心地random access。

Q:对于帧间编码,在一个宏块内,可以同时存在的模式?

A:在同一宏块内,如果用模式16*8,那么宏块分为两块,均为16*8;8*16类似.如果用p8*8模式,对于8*4和4*8把一个8*8块分为两个块,对于4*4则分为4个.

Q:帧间预测时,MV,MVp,MVD分别是什么?

A:me得到的是mv ,预测得到的是mvp ,差值是mvd

MV:运动向量,参考帧中相对于当前帧的偏移

MVp:参考运动向量

MVD:两个向量间的差别

Q: I帧和P帧的概念比较好懂,B帧的概念有些模糊,只知道加了B帧图像质量会更好,请问对B帧该怎么理解?

A: B 帧在 MPEG-4 中有四种参考模式,如果是同时参考前后的画面压缩,则记录的是 和 (前画面 pixel 值 + 后画面 pixel 值)/2 的差值,也就是 和 「前后画面的平均」的差值。所以记录的差值个数和 P 帧一样,只有一个,没有增加。而因为 B 帧位于前后画面的中间,以「前后画面的平均」,也就是「前后画面的中间值」来作为预测数值(预测 B 帧的 pixel 数值为多少?如果有误差,再记录差值),这样这个预测数值会比单独使用前一个画面来预测,更接近目前真正的 B 帧的数值,可想而知,如此所需要记录的差值就会很小甚至可以根本不用记录,所以便可以省下很多的 bits,提高压缩率。

除了压缩率以外,B 帧对画质的影响也是有的,因为 B 帧这种参考前后画面的特性,等于有内插(interpolation)的效果,所以可以减少噪讯。

Golomb 用于运动矢量,模式类型,头信息等编码

CAVLC用于残差编码

CABAC都可以

Q:udp(user data packet protocol) 和 (rtp)real-time transport protocol有什么区别?

A:RTP是为了实时传输而在源数据上加了一些时间控制信息

UDP只是为了传输数据,udp的包可以加上rtp的头,成为一个rtp的数据包

rtp3984 拆分3种包:

单一NALU包

聚合包

分割包

经过测试发现,无线网络下,一包大小不能超过1400,只能传QCIF,QP35

Q:相对PAFF,MBAFF的作用大不大?

A:有优势,但不明显。只有当图像运动剧烈的时候,优势才会比较明显。

Q:

变换量化公式: |Zij|=(|Wij|.MF+f)>>qbits 中的f是什么?

A:

f是一个修正参数,对于帧内编码宏块f=(2^qbits)/3,对于帧间编码宏块f=(2^qbits)/6。

Q:

整数DCT变换之后,为什么还要对直流分量进行哈达玛变换??有什么意义?

A:

因为在帧内编码宏块中大多数的能量都集中在直流系数上,这种变换有利于进一步压缩4×4的亮度直流信号的相关性。

Q:white paper中给出帧内预测9种模式,vertical和horizontal容易理解,不知其他模式是依据怎样的算法来进行预测的。

A:标准P91-96给出了算法。

如8.3.1.2.8 Specification of Intra_4x4_Vertical_Left prediction mode中指出:

This Intra_4x4 prediction mode shall be used when Intra4x4PredMode[luma4x4BlkIdx] is equal to 7.

The values of the prediction samples pred4x4L(x,y),with x,y=0...3 are derived as follows:

For y=0 or y=2,

pred4x4L(x,y)=(p(x+(y>>1),-1)+p(x+(y>>1)+1,-1)+1)>>1;

Otherwise,

pred4x4L(x,y)=(p(x+(y>>1),-1)+2*p(x+(y>>1)+1,-1)+p(x+(y>>1)+2,-1)+2)>>1;

hehe,>>为无符号数右移操作。

Q:关于对除开拖尾系数以外的非零系数Level编码

A:

level的编码和AVS一样,查6个表,表也和AVS的一样

JM有算法,可以参看

writeSyntaxElement_Level_VLCN

函数。.

这个算法就是生成6个表的算法。

Q:h264在网络上以udp方式传输问题

在mpeg4标准中,都是通过rtp协议把视频帧分成一个个的包加上rtp头再发送,在h264中,是由nal直接分片成包的还是要通过rtp分呢?要不要加rtp头

Q:FMO的优处和劣处?

A:劣处是FMO模式打乱了原宏块顺序,降低了编码效率,增加了时延;

优处是增强了抗误码性能。

Q:block的类型包括几种?

A:在变换编码的阶段,根据block的类型有三种变换编码,

block的类型包括1、亮度的4*4直流系数组成的块;2、色度的2*2的直流系数组成的 块;3、其它类型的块(包括亮度的4*4交流系数组成的块(在DC系数的位置设为0);色度的4*4交流系数组成的块(在DC系数的位置设为0);采用 4*4帧内编码模式的4*4块;运动补偿的4*4的帧间预测块)

其中亮度4*4DC系数组成块和色度2*2的直流系数组成的块仅仅在16*16的帧内预测模式下会出现。

Q:在进行运动估计和运动补偿时,所用的块匹配快速算法有哪些?匹配准则又有哪几种?

A:块匹配快速算法有:正交搜索算法(OSA)、交叉搜索算法(CSA)、共轭方向搜索 (CDS)、三步搜索(TSS)、二维对数(TDL)和全搜索(FS)、钻石算法等等。匹配准则一般有:归一化互相关函数(NCCF)、均方误差 (MSE)、绝对误差和(SAD)等等。SAD最常用。

Q:jm各个版本之间的代码做了些什么改动,有没有说明这些的文档啊?

A:每个版本源代码的根目录下都有一个 change.txt 文件,里面详细记录了所有版本的更新。

补充:为何已经有了 JM 10.2,大家仍偏好用 8.6 呢 ?

风轻回答:针对对象不同,jm90以上全部是针对高保真的视频的。86基本上可以满足一般处理的所有要求。

Q: PicAFF和MbAFF的区别是什么?

A: PicAFF和MBAFF是决定压缩场的两种方式,PicAff(picture adaptive field frame)是在图像层来说的,此时帧被分成两个场,并且这两个场单独压缩,这两个场在分别分成16*16的宏块,然后对宏块进行编码,编码的时候对场中 的宏块单独编码,在某个场编码完后,才会编另一个场的码。

而MBAFF(MicroBlock Adaptive Filed/Frame)是在宏块层(16*32)上进行编码,它将该宏块层即可以按单独的场,也可以将两个场合并成一个进行编码,在分成两个单独的宏块 (16*16)编码的时候,是先编码一个场的宏块,再编码另一个场的宏块,这和PicAFF的区别就是对于整个图像来说各个场的宏块还是交叉编码的;在合 并成单独的一个宏块编码时,在一个宏块(16*16)内,即包括奇数场的元素,也包括偶数场的元素,即宏块对,同时同一幅图像值(就算是上一场)也不能做 参考。

Q:用h264设计的解码器是不是可以解任意编码器编的码?是根据档次设计解码器吗?

A:不可以解任意编码器编的码。也不是根据档次来设计编解码器。要根据具体的情况。

如果是按照H.264的标准来设计编解码器,便是通用的;若编解码器的设计有自己的特点,便不能成为通用的编解码器。

Q:在VC环境下是如何读入*.yuv序列的?

A:把*.yuv文件当作一般的文件读就可以了。

如下:

#include

#include

void main()

{

char *Y;

char *Cb;

char *Cr;

int width = 352, height = 288;

FILE *fp;

FILE *fy;

int i;

Y = (char*)malloc(width*height);

Cb = (char*)malloc(width*height/4);

Cr = (char*)malloc(width*height/4);

fp= fopen("input.yuv","rb");

if(fp == NULL)

printf("open input.yuv failed\n");

fy = fopen("output.yuv", "ab+");

if(fy == NULL)

printf("open output.yuv failed\n");

for(i = 0; i<1; i++)

{

//fseek(fp, i*width*height, 0);

if(0 == fread(Y, width*height, 1, fp))

printf("read error\n");

if(0 == fwrite(Y, width*height, 1, fy))

printf("write error\n");

fread(Cb, width*height/4, 1, fp);

fread(Cr, width*height/4, 1, fp);

fwrite(Cb, width*height/4, 1, fy);

fwrite(Cr, width*height/4, 1, fy);

}

fclose(fp);

fclose(fy);

free(Y);

free(Cb);

free(Cr);

}

Q:SODB,RBSP,EBSP的区别

A:SODB:最原始的编码数据,没有任何附加数据

RBSP:在SODB的基础上加了rbsp_stop_ont_bit(bit 值为1),并用0按字节补位对齐,字节对齐后,后面还有可能存在若干组16bits的0x0000(参考标准中的One or more cabac_zero_word 16-bit syntax elements equal to 0x0000 may be present in some RBSPs after the rbsp_trailing_bits( ) at the end of the RBSP.)

EBSP:在RBSP的基础上增加了防止伪起始码字节(0X03)

Q:码流的读取位置

A:当数据流存储在介质上时,此时读取用GetAnnexbNALU (nalu);

否则,数据流应该来自分组交换网络,此时读取用GetRTPNALU (nalu)

二者的区别:

码流格式为Byte stream format时,调用函数GetAnnexbNALU(nalu);此时码流中包含起始码前缀(start_code_prefix_one_3bytes),3 个字节,值为0x00 00 01。并可能包含连续若干字节的0(leading_zero_8bit),拖尾字节0。起始码前缀是为了表明码流的开始,与AVS相似。因为可能存在填 充bit 0,所以也可能包含有leading_zero_8bit,即起始码前缀的表现形式可能是0x00 00 00 01或其他值。但这些值必须包含0x00 00 01。对原始码流提取后,这些值均被丢弃。

如果码流是按RTP协议传输,则调用GetRTPNALU(nalu)。并对RTP包进行拆封。在H.264中,对RTP包头的各段的值进行了限制,这些被限制的值必须满足条件,否则认为出错。

A:MBAFF的问题

Q:帧模式下的MBAFF,每个宏块对由本帧的宏块组成。

场模式下的MBAFF,把两场组成一帧后,在按照帧的方式来组成宏块对。实际上是每个宏块对由顶场的一个宏块和底场的一个宏块组成。

Q;CAVLC,Exp-Golomb的区别

A:Exp-Golomb的前缀和后缀根据阶数K的不同,可能是对称,后缀比前缀的长度多1等情况。

负数的情况下,通过公式(–1)k+1 Ceil( k÷2 ),把解析出来的哥伦布码值还原为原始的语法元素值;正数也有相应的对应方法。

CAVLC的前缀和后缀可能对称,也可能不对称,(大多数情况下都是不对称的)而且后缀还可以不存在,后缀的长度也是根据上下文环境来判断的,后缀的取值是根据编码表查询的,

对于正数,编码后的后缀部分的最后1 bit一定是0(若存在后缀);对于负数,其一定是1(若存在后缀)。

CAVLC与Exp-Golomb的前缀的表现形式都是1,01,001,0001......

Q:CAVLC的过程

A:

编码

4×4的残差块通过Zig-Zag扫描,得到一系列字符,如:0,3,0,1,-1,-1,0,1,0......

由此序列推导出以下变量:TotalCoeffs(全部的非零系数,包括拖尾系 数),TotalZeros(最后一个非零系数前面的所有0的个数,方向为从左到右,比如上面的序列中,最后一个非零系数为 1),TrailingOnes(托尾系数的个数,并规定不能超过3个),然后通过NC值查表,把TotalCoeffs ,和TrailingOnes的组合进行编码,称为编码元素coeff_token。接下来,对每个拖尾系数的符合编码,0表示+,1表示负。再接下来, 对剩下的非零系数编码(此时拖尾系数已经被编码了,不再包括),编码方向为从右到左,比如上面的序列中,先编码1,再编码3。这些系数被编码后,是由 level_prefix和level_suffix两部分组成的。level_prefix的值通过查表得出,level_suffix是由若干个0组 成,0的个数由suffixLength决定。再接着对TotalZeros的值编码。然后对RunBefore(每个非零系数前零的个数)进行编码,这 个方向也是从右到左,并且最后一个(从左边数的第一个)非零系数前零的个数不需要编码,因为后面的编过后,剩下多少个0只有一个存放位置,就是最前面。

解码

由计算出的bit串长度读出相应的bits,通过查表得到TotalCoeffs和 TrailingOnes的值,此时无输出,接着读取拖尾系数的符合,由编码的顺序知,先读到的是最后一个拖尾系数。解码完拖尾系数并依次输出,接下来是 剩下的非零系数的值,通过查表解码并输出。然后解码TotalZeros,此时输出不变,仍为以前的解码值。接下来解码RunBefore,因为编码时是 从右往左编的,故第一个解码出来的RunBefore应该插到第一个解码出的拖尾系数的前面,即插入的方向也是从右到左,最后一步时,剩下的 RunBefore都插入到最前面。

Q:哪位能讲一下标准里面的坐标的问题,分不清到底指的是块,宏块,尤其是MBAFF时?比如第6章逆扫描时的这两个公式:y = yO + ( mbAddr % 2 ) * 16(帧),

y = yO + ( mbAddr % 2 ) (场)

A:这是计算像素坐标的计算公式,MBADDR时是以宏块对出现的,MBADDR是宏块对的号码,所以场模式下是不要乘16的,TOP FIELD和BOTTON FIELD的像素是独立计算的。表达可能不大准确,也可能有误,希望各位指点。

Q:为什么要在计算桢内DC预测模式时要+2,+4?

A:16*16和4*4的桢内DC预测模式中+2,+4的目的是为了四舍五入,使预测值更精确~~~

如(A+B+C+D)/4=190.1,那么约等于190

(A+B+C+D)/4=190.9,也是约等于190

这样误差就会大些

所以加上0.5后190.1=190.6,约等于190

而190.9+0.5后=191.4,约等于191

这样保证了精确性~~~

Q: 为什么量化系数的数组是取[6][4][4]呢?

A:设变量p为需要变换的系数,c(p) 为变换之后的系数,其变换如下:

|1 1 1 1| |p00 p01 p02 p03| |1 2 1 1| |aa ab/2 aa ab/2|

|2 1 -1 -2| |p10 p11 p12 p13| |1 1 -1 -2| * |ab/2 bb/4 ab/2 bb/4|

|1 -1 -1 1| |p20 p21 p22 p23| |1 -1 -1 2| |aa ab/2 aa ab/2|

|1 -2 2 -1| |p30 p31 p32 p33| |1 -2 1 -1| |ab/2 bb/4 ab/2 bb/4|

我们可以看到位于p00、p02、p20、p22位置的系数需要乘aa,p11、p13、 p31、p33的系数需要乘bb/4,其余的系数需要乘ab/2,这里a = 0.5,b = sqrt(0.4),c = 0.5。然而整数变换中的乘法运算可以与量化过程的除法运算糅合起来,这样就产生了你所提到的quant_coef[6][4][4]。第一个分量取6, 是因为量化阶每隔6就增加一倍,因此只需要记录下量化阶为0-5时的各个系数的大小,而后两个分量取4则是为了与整数变换的大小相匹配

Q: int cof[4][6][4][4]; //!< correction coefficients from predicted

这个变量是干什么用的啊?

A:这个变量用来存储解码并且逆量化之后的系数,其中cof[4][6]的内容如下:

|y0 y1 y4 y5 |

|y2 y3 y6 y7 |

|y8 y9 y12 y13|

|y10 y11 y14 y15|

|u0 u1 v0 v1 |

|u2 u3 v2 v3 |

Q:IDR picture指什么?

A:instantaneous decoder refresh picture,是一种只包含I-slices的picture. IDR picture之后的picture不使用IDR picture之前的picture作为运动估计的参考picture.

//------------------------------------------------------------------------------------------------------

PartitionMotionSearch函数里面static int bx0[5][4] = {{0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,2,0,0}, {0,2,0,2}},[5]是模式,[4]是子块的坐标 。0模式就是指skip或direct模式

ChromaResidualCoding (&dummy)中dummy是计算色度CBP的值,然后在亮度CBP上叠加,构成率失真函数的重要部分

--------------------------------------------------------------------------------

常用的测试序列选择:

Coastguard :为物体的相对运动和镜头移动

flower :为物体的剧烈运动和镜头的快速移动

garphone :为物体的快速转换

foreman :为物体转换和镜头移动

mobile&calendar :为物体的多种运动和镜头移动

--------------------------------------------------------------------------------

Q:为什么帧内预测要用未滤波的图像而不是滤波后的图像呢?

A:帧内预测只能用滤波前的值,因为帧内预测的时候边界滤波还不能进行,帧内预测所需要的象 素点的边界的滤波不能进行,因为需要等到当前宏块解完后才开始,但是你现在就在解当前宏块,所以为了避免预测和滤波的耦合 应该分开来单独做,prediction的时候保存一个line buffer就解决问题了

----这样的解释对吗?

Q:h->param.analyse.inter &= X264_ANALYSE_PSUB16x16|X264_ANALYSE_PSUB8x8|X264_ANALYSE_BSUB16x16|

X264_ANALYSE_I4x4|X264_ANALYSE_I8x8;

为什么这么做啊?

A:帧间要遍历所有模块,可以去掉一下选项,就是说,你可以不搜索一些模式,他默认是都要搜索的,比如你编码P帧的时候,不想搜索的那么精细,可以去掉ANALYSE_PSUB8x8

--------------------------------------------------------------------------------

Q:CQM_4IY,CQM_4IC,CQM_4PY,CQM_4PC,CQM_8IY,CQM_8PY的含义?

A:cqm_4iy->INTRA4X4_LUMA,cqm_4ic->INTRA4X4_CHROMA

cqm_4py->INTER4X4_LUMA,cqm_4ic->INTER4X4_CHROMA

cqm_4py->INTER8X8_LUMA,cqm_4ic->INTER8X8_CHROMA

Q:在x264的x264_cqm_init( x264_t *h )函数中:

for( i = 0; i < 16; i++ )

{

h->dequant4_mf[i_list][q][0] = def_dequant4[q] * h->pps->scaling_list[i_list];

h-> quant4_mf[i_list][q][0] = def_quant4[q] * 16 / h->pps->scaling_list[i_list];

}

第二个式子为什么*16?

A:你不要管这个16,这个16是约定成俗的,要和量化,凡量化一直考虑

Q:unquant4_mf[4][52][16]这个矩阵也是量化里面的,你看量化矩阵和反量化矩阵都是4维的,而这个是3维的

A:unquant4_mf[i_list][q],是0~15,是线性排列,quant4_mf[i_list][q%6][0],是[][]矩阵排列

Q:在上面的程序中量化和反量化矩阵为什么第三维只为0呢?

A:为0才对,因为本来定义[4][4],现在要线性访问16个成员,就必须[0]了

 

--------------------------------------------------------------------------------

Q:关于skip模式的问题

A:When a Skipped macroblock is signalled in the bitstream, no further data is sent for that macroblock. The decoder calculates a vector for the skipped macroblock and reconstructs the macroblock using motion-compensated prediction from the first reference picture in list 0.

p_skip 就是说只计算参考桢中的mv,传输的是0数据,直接把参考中的匹配宏块拿过来就行了,skip模式只传送mb_type,其他信息都是从参考桢中获取,在 解码端计算MV及恢复残差数据,MV不是从参考帧获得的,是在解码端计算,mv是根据周围的相邻块的mv进行计算,好像是取中间值,有点像MV在运动估计 时候的预测,是只传送mb_type,其他信息都可以计算出来 ,这就是skip。

To have a SKIP mode in H.264, a macroblock should meet following conditions all together [5]:

(i) the best motion compensation block size is 16x16,

(ii) reference frame is just one previous one,

(iii) motion vector is (0,0) or the same as its PMV, and(iv) its transform coefficients are all quantized to zero.

(iv) its transform coefficients are all quantized to zero

--------------------------------------------------------------------------------

 

FrameSkip,该参数是对原始YUV帧丢弃数,就是说每隔一帧(I或者P,不包括B)丢弃FrameSkip帧。

NumberBFrames,就是两个编码帧中间B帧的数目,该数必须小于FrameSkip

FramesToBeEncoded,总共要编码的帧数,不包括B帧.因为在编码过程中 b帧对其他帧并不产生影响,而且在实时编码中,如果负担过重;或带宽有限,可以有选择的丢弃b帧

IntraPeriod,每IntraPeriod帧(I/P帧)有一个I帧编码

如果你选择的frameskip>=1,numberbframes=0,intraperiod>1,序列类型:ipp...ipp...

如果你选择的frameskip>=1,numberbframes=1,intraperiod>1,序列类型:ipbpb...ipbpb...

如果你选择的frameskip>=2,numberbframes=2,intraperiod>1,序列类型:ipbbpbb...ipbbpbb...

--------------------------------------------------------------------------------

h264标准里为什么有PAFF和MBAFF两种编码模式,都是出于编码效率的考虑吗?

还是PAFF编码还考虑了逐行隔行显示的问题

--------------------------------------------------------------------------------

P_Skip的特别之处在于码流中不传输MVD数据,预测块的大小肯定史16*16。当下面四个条件满足任意一个时,当前宏块的MV预测值直接置为(0,0),不满足时当作普通P宏块处理

– mbAddrA is not available

– mbAddrB is not available

– refIdxL0A is equal to 0 and both components of mvL0A are equal to 0

– refIdxL0B is equal to 0 and both components of mvL0B are equal to 0

--------------------------------------------------------------------------------

 

#define SADFUNC(w, h, base) \

uint32_t \

T264_##base##_u_##w##x##h##_c(uint8_t* src, int32_t src_stride, uint8_t* data, int32_t dst_stride) \

{ \

return T264_##base##_u_c(src, src_stride, data, w, h, dst_stride); \

}

这种宏定义无论是在t264,x264或是jm代码中都比较常见

使用这样的宏定义后,函数名字可以根据宏定义进行改变,也就是说,函数名也有宏定义。

相邻两个##之间的内容用调用时的()内的相应的内容进行代替,例如:

SADFUNC(16, 16, sad)就用sad代替base,16代替x,16代替h

这样实际调用函数就为T264_sad_u_16x16(.........)了