ffmpeg的mpeg2编码I帧代码解读(四)

下面解释一个block的编码以及编码码表
 
1.首先编码的是DC系数,在函数encode_dc里面进行。由于DC系数的码表有两个,分别针对Y帧和(Cr,Cb)帧。编码的时候,编码的是非负的系数,但是原始的DC系数有正有负,因此需要做一个映射。这一个映射,在encode_dc里面,首先就用
if(((unsigned) (diff+255)) >= 511)
分成了两部分,表示正负数的映射。而码表的选择,是根据component变量来选择的。整个编码过程和标准完全一样。但是代码中diff为正和为负的情况,表面上采用了不同的编码方法,但是实质上是完全一样的。
mpeg1_lum_dc_uni的初始化在ff_mpeg1_encode_init里面完成,查看这个初始化过程,其实就是一个编码过程。
 
2.对于其他系数的编码,根据标准,存在两种不同的情况:
a.(level,run)较小的情况,直接进行查表
b.(level,run)较大的情况,进行所谓的换码编码,首先是写入一个Escape code,然后在加上level和run
因此,首先需要判断(level,run)是否足够大,代码中用
if (alevel <= mpeg1_max_level[0][run])
来解决这个问题。mpeg1_max_level这个矩阵的构成在ff_mpeg1_encode_init函数中,通过调用init_rl函数来实现,至于这个具体怎么初始化的,很容易看懂的(如果这个都看不懂,那ffmpeg代码也就不要想看懂了)
 
3.在一个block的最后,需要编码end of block,也是通过查表
 
4.现在解释码表,所有要用到的vlc的码表存放在文件mpeg12data.c里面,
mpeg1_vlc就是标准中的码表B-14
mpeg2_vlc就是标准中的码表B-15
两个码表,第一列表示码字,第二列表示码字长度,对照标准上面的码表,很容易发现这两个数组的构成方法(具体是什么,看一下就知道了,很容易的)
看懂了这里,也就很容易看懂在mpeg12enc.c里面对于其他系数的编码了
 
最后要说的是,ffmpeg的代码写的非常的晦涩,写得非常的不对称,比如encode_dc就是这样的,码表的初始化也比较混乱,因而看起来很费劲

posted on 2009-09-16 17:37  vincenzo.lai  阅读(2866)  评论(3编辑  收藏  举报

导航