mpeg2解码过程,标准解读part1

(零)总体框图:

894-412663aa220fedcc

(一)高层语法结构

重构场图将成对相伴而形成重构帧。

如果progressive_sequence==1,则重构帧将以帧周期为时间间隔从解码过程输出。

如果progressive_sequence==0,则重构帧将被分成一个重构场的序列,在解码过程输出端以有规律的长周期为时间间隔而出现。如果一个帧图的repeat_frist_field==1,则这个帧的第一场将在第二场后被重复。

(二)变长码解码

用cc指代颜色分量,他与下表中所述的块号相关。于是,对于Y分量,cc为0,对Cb分量cc为1,对于Cr分量cc为2。

894-412663aa25159e27

比如,在块号为7的时候,对4:2:2,cc的值为2。

1.内部块中的DC系数

DC系数的编码分为两种情况,一种是内部块的第一个系数,一种是非内部块的第一个系数

1)内部块的第一个系数

DC系数有两个码表,根据cc的值(0或者非0)来选择码表。

在ffmpeg的代码中,mpeg12enc.c里面,encode_dc函数,表明了如何对DC进行编码。ffmpeg的DC的码表用数mpeg1_lum_dc_uni和数组mpeg1_chr_dc_uni保存。这两个数组,即保存了编码码字的长度,也保存了编码码字的code,方法是,数组的每一个元素的第8个比特表示码字长度,剩余的比特表示了码字code。因此在encode_dc这个函数的putbits要将码表的第八位析出来作为码字长度,将码表向右移八位表示编码的码字code。

编码仍旧按照前缀+INFO的方法,前缀包含了INFO长度的信息,因此,在解码的时候,首先读出前缀,就可以知道INFO的长度,从而解码出DC系数。

下面两个表表明了DC的编码前缀或INFO长度的对应关系

894-412663aa47a80309

编码的时候,由于编码的DC系数是当前DC系数与前一帧的DC系数的差值diff,这个diff的范围是[-255, 255],因而首先将difference做一个映射,映射为非负的整数,方法如下:

if (difference >= 0)

    diff = difference;

else

    diff = (difference - 1) + 512;

接下来计算diff的位宽,得到dct_dc_size_luminance或者dct_dc_size_chrominace,然后根据上面两个码表,查出前缀,最后,按照前缀+INFO的方式将编码后的数据写到比特流中。这里的INFO就是diff。

ffmpeg代码中码表的初始化在函数ff_mpeg1_encode_init里面完成。

2)非内部块的第一个系数

当DC的绝对值为1的时候,编码码字为1x,x表示DC的符号,-1时x为1,1时x为0。码字长度为2。

当DC的绝对值不为1的时候,把它按照其他系数来处理进行编码。

2.其他系数

mpeg2宏块内的编码思想是:由于一个宏块中绝大部分系数都是0,zig-zag扫描过后出现的情况是:level1, 0, 0, ... , 0, level2, 0, ..., 0, level3, ..., ..., leveln, 0, ..., 0。其中levelx表示非零的系数,每一个非零系数后面跟了若干个0(0的个数可能为0),这个0的长度被称作run(游程),统计出(level,run)对,然后对每一对(run,level)查表编码。

而其中的码表总共有两个,选择方式如下:

894-412663aa95aa4994

一些(run,level)对,没有相应的变长码与之对应,是因为他们在统计学上很少出现,于是采用换码编码,用定长编码对他们进行编码,具体做法是:在换码VLC的后面跟一个6bit定长码表示run,在跟12bit定长码表示signed_level。

posted on 2009-09-04 16:33  vincenzo.lai  阅读(2438)  评论(0编辑  收藏  举报

导航