1.概述
Mpeg1是上世纪90年代提出来的视频标准,比较古老了。其特性包括:
- 视频压缩编码,压缩后码率在 1.5Mbps,可用于视频传输和视频存储;编码前必须将视频图像转换成逐行扫描图像。
- 录像机的正放、图像冻结快进、快退和慢放功能以及随机存储功能。
Mpeg1使用了一系列的编码技术提升压缩率,包括: - 1) 使用基于块的运动补偿减少空间冗余;
- 2) 使用DCT变换后量化,减少空间相关性,并丢弃部分不重要的高频信息;
- 3) 对mv和DCT参数信息使用变长编码
2.码流结构
如图所示,Mpeg1码流结构可以分为以下几层:
- 码流由一个序列头和多个GOP组成,并以endcode结尾;
- GOP是一组可以单独解码的图像,是mpeg1码流实现随机播放的基本单元;GOP内第一个编码帧是I帧;
- Piture层:Mpeg1标准只支持YUV420格式,一帧图像包含三个分量:Y、Cb、Cr,Y亮度分量宽高需要是偶数,CbCr色度分量宽高是Y分量的一半;支持4中帧类型:I帧、P帧、B帧、D帧;
- Slice层:slice是防止误差扩散的基本单元,一帧图像由多个slice构成,相邻slice不能重叠也不能出现空隙;
- Mb层:一个宏块包含例一个16x16亮度块(4个亮度block)和两个8x8的色度块(2个色度block)
- Block层:8x8的亮度或色度块
3.解码流程
Mpeg1/2标准解码整个流程如下图所示。
- 按照码流语法结构,通过VLC解码出DC/AC参数;
- 解码出来的参数是游程编码(run-level),因此需要经过反扫描恢复参数;
- 参数矩阵经反量化、反变换后得到残差数据;
- 如果是P、B宏块需要通过运动补偿重建该宏块数据;如果是I宏块,则反变换后的数据为该宏块重建数据;
以上解码流程的基本单元是8x8大小的block。
解码过程按照宏块类型可分为4种:帧内编码宏块、P帧中的预测编码宏块、B帧中的预测编码宏块、Skip宏块;
3.1 帧内编码宏块
I帧中所有宏块都以帧内编码方式,P帧和B帧中也可能存在帧内编码宏块(由macroblock_type语法决定)。Mpeg标准没有帧内预测,由于DCT变换后DC参数数值较大,直接编码会占用较多数据量,因此帧内编码使用DC预测减少码率。
帧内编码宏块解码步骤如下:
- 1) 根据block中语法元素dct_dc_differential和dct_coeff_next可以得到dct系数矩阵dct_zz[];
- 2) Dct_zz[] 乘上量化参数和加权矩阵可得到重建后的dct系数矩阵dct_reconn[m][n];
- 3) 每个颜色通道的8x8 block的DC系数由上一block的DC预测得到,因此dct_reconn[0][0] += dct_dc_y_past;
- 4) 对dct_reconn进行反变换得到该宏块重建数据
3.2 P帧中的预测编码宏块
MPEG1标准预测编码支持半像素精度,对于半像素的预测宏块是通过线性插值实现。
P帧中的预测编码宏块解码主要可分为两个部分:一是重建宏块的前向运动矢量以及预测宏块;二是存放在码流中的block DCT参数经过反量化、反变换并与预测宏块叠加;
计算步骤如下:
- 1) 重建mv,由于相邻块的mv存在相关性,因此可以使用前一块的mv做预测以减少编码数据。解码过程中需要结合宏块头信息中的语法元素以及前一相邻块的mv计算得到当前宏块mv;
- 2) 重建预测宏块,使用上一个解码的I帧或P帧作为参考帧,结合mv,计算得到当前宏块预测像素值。如果是全像素精度,可以直接从参考图中找到对应像素值;如果是半像素精度,则需要对相邻像素求平均值。
- 3) 根据block中语法元素解析得到dct参数,经IDCT后得到残差值,加上预测宏块像素值则得到该解码宏块重建像素值;
3.3 B帧中的预测编码宏块
B帧中的预测宏块解码过程可分为以下四个步骤:
- 1) 重建前向mv和前向预测宏块,该步骤类似于P帧的预测宏块重建。
需要注意以下几点:
a) 用于预测的前一个block mv只能在以下两种情况下重置:slice中的第一个宏块或上一个解码宏块为帧内编码宏块。
b) 如果当前宏块没有前向mv,则使用上一个宏块 - 2) 重建后向mv和后向预测宏块,重建过程与上一步骤类似;
- 3) 根据前向和后向预测宏块计算预测像素值。如果只有前向或后向预测宏块信息,则使用单一方向做预测;如果两者都存在,则最终预测像素值为二者平均值;
- 4) 根据block中语法元素解析得到dct参数,经IDCT后得到残差值,加上预测宏块像素值则得到该解码宏块重建像素值;
3.4 skipped宏块
Skipped宏块是指码流中没有编码数据的宏块,这类宏块既没有mv信息也没有DCT参数。这些宏块由宏块头信息中的macroblock_address_increment来表示,当macroblock_address_increment的值大于1时,可以认为当前宏块与上一宏块间存在skipped宏块。
- I帧中,所有宏块都编码,不存在skipped宏块;
- P帧中,skipped宏块表示该宏块mv为0,并且没有DCT参数;P帧内skipped宏块重建值直接拷贝参考帧对应位置的像素值;
- B帧中,skipped宏块mb_type(主要用来确定该宏块的预测方式,前向参考、后向参考还是双向参考)与上一宏块一样,并且mv残差为0,没有DCT参数。在B帧中skipped宏块不能紧跟在帧内编码宏块之后。因此B帧内skipped宏块重建需要考虑三种情况:如果是前向参考,则直接拷贝前向参考帧对应位置像素数据;如果是后向参考,则直接拷贝后向参考帧对应位置像素数据;如果是双向参考,则为前向、后向参考像素值的均值。
3.5 参考帧管理
mpeg1参考帧最多只有2个,为之前解码两个的I或P帧。
假设一段码流显示顺序如下:
1 2 3 4 5 6 7
I B B P B B P
其解码顺序如下:
I P B B P B B
当前解码帧 | 前向参考帧Last_pic | 后向参考帧Next_pic | |
---|---|---|---|
解码1I帧 | 1 | 0 | 1 |
解码4P帧 | 4 | 1 | 4 |
解码2B帧 | 2 | 1 | 4 |
解码3B帧 | 3 | 1 | 4 |
解码7P帧 | 7 | 4 | 7 |
解码5B帧 | 5 | 4 | 7 |
解码6B帧 | 6 | 4 | 7 |
如上表所示,参考帧管理基本原则是:
- 当前解码为I帧或P帧前更新参考帧;
- 更新方法是前向参考帧等于后向参考帧,后向参考帧等于当前帧;当解码P帧时,只使用前向参考帧;当解码B帧时,使用2个参考帧。