JM模型I帧帧内预测流程











关于H.264中DCT变换问题


以前写的一篇文章,现在放上来。解码器现在作到Huffman解码了。  


 窗外的烟花声音渐渐沉寂,开始工作了.

 H.264标准DCT8X8变换问题,据流媒体MPEG4/H264版面斑竹,X264/MPEG4开发小组成员的chenm001讲已经废弃,所有


ABT(自适应块尺寸变换)部分,都从标准中拿掉.但是我从JM97测试模型中依然开始看到,这一部分还在工作,码流依然输出

了相关的DCT8X8 flag信息,所谓ABT(adaptive block
transform),就是讲在DCT变换的时候,选择4X4,8X8,16X16是可以自适应

的,自动选择其最合理的方式,听起来的挺好的事情,任何好的东西都是要付出代价的,天下没有掉下的馅饼。自适应是要

付出计算代价的。H.264
80%以上(对不起,没有数据参考,纯属个人估计)的DCT变换是基于4X4的,对I16MB模式下用16X16

变换.其实DCT8X8变换是很多压缩标准使用的变换方式,比如JPEG.

 DCT8X8模式是JM的一个可选项.哪些项可以启用8X8DCT呢?

我们看JM对此决策:

       if ((mode >= 1 &&
mode <= 3) && currMB->luma_transform_size_8x8_flag ==
0)

        {

          //try with
8x8 transform size

          }

        //=========== try
DIRECT-MODE with 8x8 transform ===========

        else if (mode == 0
&& bslice &&
active_sps->direct_8x8_inference_flag &&
currMB->luma_transform_size_8x8_flag == 0)

        {

          //try with
8x8 transform size

          
continue;

        }

        //=========== try
mb_type P8x8 for mode 4 with 4x4/8x8 transform ===========

        else if ((mode == P8x8)
&& (enc_mb.valid[4]) &&
(currMB->luma_transform_size_8x8_flag == 0))

        {

          //check 8x8
partition for transform size 8x8

        }

可以看得出来当我们帧间预测的时候,模式为16X8,8X16,16X16,P8X8,I8MB时候,我们都要需要测试计算DCT8X8的RD大小.


为何其他的尺寸不做DCT8X8,比如I4MB,这是理所当然的,我们作DCT是为了块数据的去相关性,我们对I4MB是做4X4预测的


我们却对四个4X4的block合并一起作DCT8X8,数据之间的相关性不大,可以想象效果不会好.这里要指出,对宏块作I8MB子块预测


也是新加入标准的,据我对JM的了解,I8MB也和I4MB一样,有9种预测模式.值的注意的是,I8MB和其它的帧内子块有所不同,由于


DCT8X8变换尺寸比较大,大尺寸变换虽然去相关效果不错,但是会尺寸比较严重的块效应,尤其两块之间的边缘会形成比较大的梯度

所以在预测之前,I8MB子预测要做低通滤波,人工去除两块之间变换后引入的高频噪声,这样块边界看起来比较平滑。



诡异的东西,回头再说)

对于I16MB来说:
首先进行16x16块的Intra prediction.当然这是整个块的预测了,所以不涉及到ABT的问题,直接用DC,水平,垂直,Plane四种mode进
行编码,就可以得到四个mode的预测结果.
得到预测结果之后,我们用orignal的数据减去我们预测的数据,得到的就是residual,不同的mode得到的residual的值是不同的,结
果就是他们所含的能量是不同的,它的结果是编码所消耗的码字是不同的,于是乎结果就是不同的.多少年来,做编码的人们为了这么
几个bits费劲脑力,为了省bits,对比结果的这么些个功还是得做的.比较的内容就是他们各自的sad(sum of absolute difference)
,SAD最小的那个mode被称为I16MB分块方式中最佳的编码模式.

预测结束之后,我们就使用这个编码模式,对residual进行DCT与Quantization,结果直接送给熵编码器进行处理,这样一个I16MB编码
完毕.


对于I4MB来说:
将16x16的宏块先分成4个8x8的子块,再把各个子块各分成4个4x4的子块,对每一个4x4的块进行intra prediction,当然4x4的块进行
预测有9个mode,是根据它们可能的纹理走向进行预测的,最符合纹理方向的mode得到的residual比较小,才会被选为是最佳编码的
mode.用最佳的mode得到的最佳intra prediction的值求得相应的residual,计算各自的RD.方法大同小异,计算DCT,送给Quantization,
结果送给熵编码器,编码收工.

这样一直等到16个4x4的块编码完成算是完事.

对于I8MB来说:
把一个16x16的宏块分成4个8x8的子块,对于每一个子块都进行8x8的prediction.计算的结果,算得residual,将每一个residual利用
Hadamard变换求得SATD,比较大小,小的那个为最佳的预测mode.保留最佳residual,进行8x8的dct变换,将变换系数保留,编码结束.



这样一直进行操作,使得整个帧都被编码,这时I帧编码结束.写出MB Layer数据,写出Macroblock编码数据,I帧编码结束.

可以看到对于I帧编码很容易想到更复杂的算法,比如说在一个宏块里面使用多种子块方法等,但是这样的做法可能会使得cbp的bits
数过多,使得bitrate与PSNR的比值不划算,所以编码的一个中心的思想还是很重要的,就是复杂的不见得最优,数学理论与实验科学还
是有一些区别的.这也为继续的研究给出来一个启示,多想想简单而出新的想法,不要把一切都归给数学,警示.





导读:





本文转自

http://intozgc.zhuaxia.com/pre_channel/4971106 

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭