原文转自:http://blog.163.com/huangchao198311@126/blog/static/1370282702010014112311995/

I帧只存在帧内编码,没有帧间运动估计,不用参考其他的帧,所以I帧具有同步作用,.付出的代价就是效率稍差,不过也十分必要的。

I帧帧内编码分为亮度编码和色度编码,需要完成预测,计算RD代价,来判别宏块分块模式.

I帧亮度度分块模式分为16X16,8X8,4X4三种模式,色度分块模式只有一种8X8模式,每种分块模式,又有不同的

预测方式,在JM模型中,需要对这些模式进行RD代价计算,选择其中最小值作为最优模式。

下面对涉及分块模式的数据进行说明:

const int mb_mode_table[9] = {0, 1, 2, 3, P8x8, I16MB, I4MB, I8MB, IPCM}; // DO NOT CHANGE ORDER !!!

0:16X16 Direct模式,在B帧中有效

1:Inter16X16,在帧间有效

2:Inter16X8,在帧间有效

3:Inter8X16,在帧间有效

P8X8:帧间有效

I16MB:Intra16X16帧内有效

I4MB:Intra有效

I8MB:Intra有效

IPCM:Intra有效,不要预测,直接对RAW数据编码.

其中P8X8模式和下面的数据又有关系:

const int b8_mode_table[6] = {0, 4, 5, 6, 7};         // DO NOT CHANGE ORDER !!!

上面的5种模式都归入P8X8模式,叫做亚宏块级,在码流TRACE文件有一个语法元素叫做b8mode,说的就是这个。

0:8X8 Direct模式,在B帧中有效。

4:Inter8X8,在帧间有效

5:Inter8X4,在帧间有效

6:Inter4X8,在帧间有效

7:Inter4X4,在帧间有效

下面举个例子,TRACE文件里面:

@45800 mb_type (B_SLICE) ( 7, 4) =   8                            0000 ( 22)

@45804 8x8 mode/pdir( 0) =   4/0                                   000 ( 1)

@45807 8x8 mode/pdir( 1) =   6/1                                  0000 ( 7)

@45811 8x8 mode/pdir( 2) =   4/0                                    00 ( 1)

@45813 8x8 mode/pdir( 3) =   5/1                               0000000 ( 6)

意思就是位置(7,4)宏块是P8X8分块,

其中第一个8X8块是8X8,list0预测,第二个8X8块,是两个4X8块,list1方向预测,第3个是8X8,list0预测,第四个是两个8X4,list1预测,

这个好象有点跑题了,因为b8mode不是I帧分块模式,是P,B帧中分块模式。

以上基本包括了264帧内,帧间要用到的所有分块模式.

下面开始分析帧内预测流程:

色度预测(计算所有可能的预测模式的预测值)---->亮度预测(所有的分块模式,要对3种分块)---->计算每种模式的RD值(包括各种预测方式)--->获得最优。

下面可是一步一步进行说明:

1:色度预测

色度预测基于8X8块预测,8X8预测有4种预测模式,包括水平,垂直,DC预测,平坦预测。

对色度帧内预测,必须要提到几个表格:

一个表格是:

static int block_pos[3][4][4]= //[yuv][b8][b4]

{

{ {0, 1, 2, 3},{0, 0, 0, 0},{0, 0, 0, 0},{0, 0, 0, 0}},

{ {0, 1, 2, 3},{2, 3, 2, 3},{0, 0, 0, 0},{0, 0, 0, 0}},

{ {0, 1, 2, 3},{1, 1, 3, 3},{2, 3, 2, 3},{3, 3, 3, 3}}

};

其中yuv就是YUV采样比例,yuv = YUV format -1,因此YUV420,yuv值等于0,b8为宏块色度8X8块序号,YUV420,8X8块只有一个,b8为0,

b4有0,1,2,3,因此,很容易看明白上面的表格.

第二个表格是

const unsigned char subblk_offset_x[3][8][4] = //[yuv][b8][b4]

{

{ {0, 4, 0, 4},

{0, 4, 0, 4},

{0, 0, 0, 0},

{0, 0, 0, 0},

{0, 0, 0, 0},

{0, 0, 0, 0},

{0, 0, 0, 0},

{0, 0, 0, 0}, },

{ {0, 4, 0, 4},

{0, 4, 0, 4},

{0, 4, 0, 4},

{0, 4, 0, 4},

{0, 0, 0, 0},

{0, 0, 0, 0},

{0, 0, 0, 0},

{0, 0, 0, 0}, },

{ {0, 4, 0, 4},

{8,12, 8,12},

{0, 4, 0, 4},

{8,12, 8,12},

{0, 4, 0, 4},

{8,12, 8,12},

{0, 4, 0, 4},

{8,12, 8,12} }

};

const unsigned char subblk_offset_y[3][8][4] =//[yuv][b8][b4]

{ { {0, 0, 4, 4},

{0, 0, 4, 4},

{0, 0, 0, 0},

{0, 0, 0, 0},

{0, 0, 0, 0},

{0, 0, 0, 0},

{0, 0, 0, 0},

{0, 0, 0, 0}, },

{ {0, 0, 4, 4},

{8, 8,12,12},

{0, 0, 4, 4},

{8, 8,12,12},

{0, 0, 0, 0},

{0, 0, 0, 0},

{0, 0, 0, 0},

{0, 0, 0, 0} },

{ {0, 0, 4, 4},

{0, 0, 4, 4},

{8, 8,12,12},

{8, 8,12,12},

{0, 0, 4, 4},

{0, 0, 4, 4},

{8, 8,12,12},

{8, 8,12,12} }

};

这两个表格和上面的那个block_pos含义差不多,但是对U,V两个分量都包括进去了,这个含义是帧内坐标偏移,不是上面序号的意思

色度帧内预测要用到临块A,B,C宏块情况做出判断,色度块预测.

由于写这篇文章的时候,是边对照代码,边写的,所以是思路有些不对,有点写文章中倒叙的方式

ImageParameters结构里面有一个成员mprr_c[2][4][16][16];//[uv][DC_PRED_8/HOR_PRED_8/VERT_PRED_8/PLANE_8][16][16]这个成员,

放置了各种模式下的预测值,问为什么要16X16呢,而不是8X8,当YUV444模式时,当然是16X16了,这个是预留得

1:DC预测,DC预测又是以4X4块为基本单位,对A,B,C块的象素取平均值,假如没有A,B,C块的时候,取128了

2:垂直预测,假如B宏块存在,直接把B宏块最下边的象素Copy

3:水平预测,假如A宏块存在,直接把A宏块最右边的象素Copy

4:平坦模式,需要A,B,C同时存在,平坦模式的预测象素值算法比较复杂,这里不讲了.

预测完了色度值,暂时保存在mprr_c数组里面,等待后面使用,

2:对亮度的预测和代价值的计算都在函数compute_mode_RD_cost中,该函数又用RDCost_for_macroblocks来完成主要计算

该函数说明如下:

int RDCost_for_macroblocks (double   lambda,       // <-- lagrange multiplier,拉格朗日因子

int      mode,         // <-- modus (0-COPY/DIRECT, 1-16x16, 2-16x8, 3-8x16, 4-8x8(+), 5-Intra4x4, 6-Intra16x16)

// mode 9种分块模式.

double* min_rdcost,   // <-> minimum rate-distortion cost

double* min_rate,     // --> bitrate of mode which has minimum rate-distortion cost.

int i16mode )          //16X16预测模式,仅对帧间16X16有效。

该函数对mode取不同值选择不同的模式决策函数

I4MB-------------Mode_Decision_for_Intra4x4Macroblock

I16MB------------Intra16x16_Mode_Decision

I8MB-------------Mode_Decision_for_new_Intra8x8Macroblock

下面对I4MB进行分析

I4MB又调用Mode_Decision_for_8x8IntraBlocks函数,故名思义,该函数对8X8块进行模式选择,

该函数又调用Mode_Decision_for_4x4IntraBlocks,该函数完成4X4帧内预测,残差计算,参差DCT,Zig排序,量化,RL编码,IDCT,反量化,

存储重建象素,便于以后使用.

二。264编一个I帧多麻烦---JM 9.7中I帧编码分析

编码一帧,首先当然得知道从哪儿开始编,自打有了容错这种东西之后,FMO(Flexible macroblock ordering)就成了选择编码块的

第一步了.当然,最平常的编码方法中,一帧就是一个slice,一个slice从一帧的第一个宏块开始算,所以得到一帧的最左上角的宏块

地址,I帧编码开始.

在初始化编码参数的时候,大都都是在configure文件中设置好的编码参数,比如说在Intra中4x4的某个方向的预测是不是被禁止的

,8x8是可选的,还是说压根儿就不用等等.这些都被初始化到enc_mb->valid[]这个诡异的小东西里面了,所以说如果要做单个block

mode的时候,对里面的数据一定是要非常小心的.

对于一个I帧来说,编码总是先把一帧的U,V部分先进行Intra prediction,然后才考虑在Chroma最优之后,Luma的最优解.之后通过计

算编码这一帧来说最小的RD cost的mode来得到当前luma分量的编码方法.

核心函数:rdopt.c: int RDCost_for_macroblocks(.....)

在该函数中,对于不同种的分块模式以及当前的编码status来分析,涉及到Intra coding的有I4MB,I8MB,I16MB以及IPCM(IPCM是个

关于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的比值不划算,所以编码的一个中心的思想还是很重要的,就是复杂的不见得最优,数学理论与实验科学还

是有一些区别的.这也为继续的研究给出来一个启示,多想想简单而出新的想法,不要把一切都归给数学,警示.

JM模型I帧帧内预测流程相关推荐

  1. H.266/VVC帧内预测总结

    一.帧内预测基本原理 帧内预测技术是利用同一帧中相邻像素的相关性,利用当前块相邻区域的重建像素预测当前块中像素的技术,如下图所示,当前CU可以利用相邻A.B.C.D和E位置处的重建像素来预测当前CU中 ...

  2. 【HEVC代码阅读】帧内预测

    HEVC的帧内预测的架构分为三个步骤: ①构建参考像素数组:②生成预测像素:③后处理操作. HEVC标准将这三个步骤进行了精密设计,以求达到较高的编码效率,同时降低编码和解码端的运算要求.HEVC标准 ...

  3. 音视频开发(四十九)H.264 帧内预测

    目录 编码流程和数据格式回顾 4 × 4亮度块的9中预测模式 16 × 16亮度块的4种预测模式 8 × 8 色度块的4种预测模式 JM代码 一.编码流程和数据格式回顾 我们先看下下图来回顾下编码流程 ...

  4. 音视频开发之旅(58) -H.264 帧内预测

    目录 编码流程和数据格式回顾 4 × 4亮度块的9中预测模式 16 × 16亮度块的4种预测模式 8 × 8 色度块的4种预测模式 JM代码 资料 收获 一.编码流程和数据格式回顾 我们先看下下图来回 ...

  5. HM编码器代码阅读(38)——帧内预测(五)帧内预测之正式的预测操作

    正式的预测操作 在前面的操作中,我们已经得到了模式候选列表,但是我们的目的是要得到一个最优的模式,因此我们还需要对这个列表中的模式进行遍历,对于每一个模式,进行预测操作,为了计算率失真代价还必须进行变 ...

  6. HEVC学习-帧内预测-亮度分量预测主函数

    QP的详解:https://blog.csdn.net/liangjiubujiu/article/details/80569391 代码部分:https://blog.csdn.net/HEVC_C ...

  7. HEVC算法和体系结构:预测编码之帧内预测

    预测编码之帧内预测(Intra-Picture Prediction) 预测编码(Prediction Coding)是视频编码的核心技术之一,指利用已编码的一个或几个样本值,根据某种模型或方法,对当 ...

  8. H.264学习笔记2——帧内预测

    帧内预测:根据经过反量化和反变换(没有进行去块效应)之后的同一条带内的块进行预测. A.4x4亮度块预测: 用到的像素和预测方向如图: a~f是4x4块中要预测的像素值,A~Q是临块中解码后的参考值. ...

  9. H.264系列文章(三)——帧内预测

    H.264 White Paper学习笔记(二)帧内预测 为什么要有帧内预测?因为一般来说,对于一幅图像,相邻的两个像素的亮度和色度值之间经常是比较接近的,也就是颜色是逐渐变化的,不会一下子突变成完全 ...

最新文章

  1. U盘安装Linux CentOS 6.5 64位操作系统(来自互联网)
  2. DropdownList 赋初始值问题
  3. POJ 1187 陨石的秘密 (线性DP)
  4. OpenCV训练SVM模型并预测的完整过程
  5. deeplung代码实现测试是卡住情况说明
  6. wpf绑定 dictionary 给定关键字不再字典中_为什么要在 JavaScript 中学习函数式编程?...
  7. my97Date如何多选日期且无重复日期
  8. 《机器学习》周志华--第5章神经网络。 笔记+习题
  9. 基于vb的mysql管理系统代码_VB ACCESS高校财务管理系统[论文 源代码 可执行程序]...
  10. 开元酒店在中国的签约及在营酒店规模正式超过600家
  11. JS中的List转Map
  12. 用户管理和用户组管理
  13. 微信小程序_文档_04_框架_视图层_WXS_WXSS
  14. 总线宽度为32bit,时钟频率为200MHz,若总线上每5个时钟周期传送一个32bit的字,则该总线的带宽为 (4) MB/S。...
  15. asp.net 鲜花销售系统1058毕业设计
  16. 酷派s6、Coolpad 9190l_C00 无log信息输出解决方法
  17. 微服架构基础设施环境平台搭建 -(四)在Kubernetes集群基础上搭建Kubesphere平台
  18. 文件服务器均衡负载,文件服务器均衡负载
  19. 例说STM32F7高速缓存——Cache一致性问题(一)
  20. Axie Infinity 是一个受神奇宝贝启发的宇宙,任何人都可以通过熟练的游戏玩法和对生态系统的贡献来赚取代币

热门文章

  1. Tableau 桑基图
  2. 如何让计算机显示器满屏,电脑显示器满屏条纹的解决方法
  3. python字典中删除键值对的del语句与pop方法
  4. 毕业设计:基于汇编实现的欢乐QQ堂小游戏 附完整代码
  5. 【按键精灵学习记录】以DOTA2人机为例
  6. PPT处理福音!Aspose.Slides最新版实现自主的跨平台3D引擎
  7. JVM 启动参数规则:-、-X、-XX、-D表示什么意思?
  8. 圆周率用计算机能算出来不,圆周率到底能不能算尽?人类拿超级计算机算了,结果不敢相信!...
  9. Etcd——大厂面试问题集合
  10. design pattern Builder 建造者设计模式