14. x264_macroblock_encode函数-1

这个函数主要根据已经选定的模式来对宏块残差进行编码。

)如果是P_SKIP模式,那么调用x264_macroblock_encode_pskip函数

),那么调用pixel_avg;否则,调用mc_copy。pixel_avg位于mc.c文件中,是1/4搜索时需要临时插值函数。 

dst[x] = ( src1[x] + src2[x] + 1 ) >> 1;   //利用相邻半像素和两个像素取平均插值

mc_copy位于mc.c文件。

最后还要调用x264_macroblock_encode_skip函数,在这个函数中主要设置CBP值。

(2)如果是B_SKIP模式,先是调用x264_mb_mc函数完成运动补偿,然后调用x264_macroblock_encode_skip来进行CBP设置。

)接下来是帧内模式的编码,包括帧内I_16x16,帧内I_8x8和帧内I_4x4。在做每种模式的编码之前都要先计算预测帧。分别调用相应的预测函数 个块)和predict_4x4(16个块)。

A. 对于I_16x16,调用x264_mb_encode_i16x16进行编码,如果是无损编码h->mb.b_lossless被置上,则以4x4为单位,进行无损压缩的量化和扫描。若是有损压缩方式,先调用 h-> dctf. sub16x16_dct计算宏块残差(p_src-p_dst)并进行4x4大小的DCT变换。
仍然,h-> dctf. sub16x16_dct是一个函数指针,其最常设置的值是sub16x16_dct,位于dct.c文件中。

个8x8块进行调用分别调用sub8x8_dct来完成残差计算和DCT变换的。而sub8x8_dct则是调用4个sub4x4_dct分别对4个4x4块进行残差DCT变换计算的。具体到sub4x4_dct,是调用pixel_sub_wxh来计算得到残差,然后再进行DCT变换,采用264中经典的4x4DCT变换的算法。

个4x4块在for循环中进行处理:先拿出每个4x4块的DC系数(存放在一个数组dct4x4[0]中),然后对每个4x4块进行量化、扫描和反量化。分别由函数:x264_quant_4x4_trellis或quant_4x4、scan_zigzag_4x4和h->quantf.dequant_4x4完成。

接下来,对所有4x4块的在数组dct4x4 [0]中DCT系数进行:DCT变换、量化和扫描。分别由函数: h->dctf.dct4x4dc、quant_4x4_dc和scan_zigzag_4x4full完成。

然后,为了重建帧的需要,对DC系数进行反DCT变换、反量化(为什么不是先反量化后反变换,待解决)。分别由函数h->dctf.idct4x4dc和x264_mb_dequant_4x4_dc完成。对于直流系数,对每个4x4子块进行反DCT、反量化并加到预测宏块上得到重建的帧。由函数 h->dctf.add16x16_idct完成。

个8x8来分别进行。先调用predict_8x8函数来计算预测值,然后调用函数x264_mb_encode_i8x8进行编码。在该函数中,8x8DCT变换——h->dctf.sub8x8_dct8函数,量化—— x264_quant_8x8_trellis或quant_8x8函数、扫描——h->zigzagf.scan_8x8函数、反量化—— h->quantf.dequant_8x8函数和反DCT变换并加到预测宏块上——h->dctf.add8x8_idct8函数。

 

个4x4块分别进行。先h->predict_4x4[i_mode]进行帧内预测,得到预测帧。然后x264_mb_encode_i4x4编码。在x264_mb_encode_i4x4中,如果是无损压缩h->mb.b_lossless置位。调用sub_zigzag_4x4full计算残差,并扫描,返回。若是非无损编码,进行DCT、量化、Z字扫描、反量化、反IDCT并加到预测帧上。分别由函数:h->dctf.sub4x4_dct、 x264_quant_4x4_trellis或quant_4x4、scan_zigzag_4x4full、 h->quantf.dequant_4x4和h->dctf.add4x4_idct完成。

)如果是帧间模式编码,

(h->mb.i_type == P_L0)的16x16预测模式,根据h->mb.i_partition的类型(D_16x16、D_16x8、D_8x16),分别调用 x264_mb_mc_0xywh函数进行前向宏块运动补偿。x264_mb_mc_0xywh分别对亮度和色度进行运动补偿: h->mc.mc_luma和h->mc.mc_chroma函数。如果宏块类型(h->mb.i_type)为P_8x8或B_8x8。对4个8x8块,分别调用x264_mb_mc_8x8进行运动补偿。
其根据字块类型(h->mb.i_sub_partition[i8])分别进行运动补偿。D_L0_8x8、D_L0_8x4、D_L0_4x8 和D_L0_4x4类型,调用x264_mb_mc_0xywh进行前向宏块运动补偿。D_L1_8x8、D_L1_8x4、D_L1_4x8和 D_L1_4x4类型,调用x264_mb_mc_1xywh进行后向宏块运动补偿。D_BI_8x8、D_BI_8x4、D_BI_4x8和 D_BI_4x4类型,分别调用x264_mb_mc_01xywh进行宏块双向运动补偿。D_DIRECT_8x8类型,调用x264_mb_mc_direct8x8 进行直接模式8*8块运动补偿。x264_mb_mc_direct8x8函数根据不同的条件调用x264_mb_mc_0xywh、x264_mb_mc_1xywh和x264_mb_mc_01xywh函数。如果宏块类型(h->mb.i_type)为B_SKIP或B_DIRECT。调用直接模式8*8块运动补偿函数x264_mb_mc_direct8x8。如果宏块类型(h->mb.i_type)为其它B帧模式。先初始化参考列表。根据子块类型(h->mb.i_partition)
为,D_16x16、D_16x8、D_8x16和前向、后项、双向参考类型,分别调用x264_mb_mc_0xywh、 x264_mb_mc_1xywh和x264_mb_mc_01xywh函数。

个4x4块,分别进行残差计算和z字扫描,由函数个8x8块,分别调用x264_denoise_dct去噪、x264_quant_8x8_trellis或quant_8x8量化、字扫描。然后是反量化、将残差加到参考宏块上。由h->quantf.dequant_8x8和h->dctf.add8x8_idct8完成。然后对4个8x8块,分别调用x264_denoise_dct去噪、x264_quant_8x8_trellis或quant_8x8量化、scan_zigzag_8x8full Z字扫描。然后是反量化、将残差加到参考宏块上。由h->quantf.dequant_8x8和h->dctf.add8x8_idct8完成。

个4x4块进行去噪——x264_denoise_dct、量化x264_quant_4x4_trellis或 quant_4x4、Z字扫描——scan_zigzag_4x4full。然后是反量化——h->quantf.dequant_4x4和
反DCT并加到参考帧上——h->dctf.add8x8_idct。

D. 亮度编码完成后,进行色度编码。x264_mb_encode_8x8_chroma函数。对Cb和Cr分量分别进行。

个4x4块进行残差计算、Z字扫描和DC系数计算。

非无损编码,用h->dctf.sub8x8_dct对每个4x4块进行残差计算和DCT转换。之后对每个4x4块,先取2x2DC系数,量
化——quant_4x4_chroma、Z字扫描——h->zigzagf.scan_4x4ac。对2x2DC系数进行DCT变换、量化和Z字
扫描,分别由函数h->dctf.dct2x2dc、quant_2x2_dc和scan_zigzag_2x2_dc。接着是反DCT变换和反量
化,h->dctf.idct2x2dc与x264_mb_dequant_2x2_dc函数。h->quantf.dequant_4x4 对4x4块反量化,h->dctf.add8x8_idct对每个4x4块反DCT变换并且加到色度预测帧上。

E. 亮度和色度编码完成后。计算亮度和色度模式和非零的个数,确定h->mb.i_cbp_chroma和h->mb.cbp的值。

 

 

15. x264_macroblock_encode函数-2

下面是该函数的调用情况,在上面对这个函数的分析中,已经对其中的大部分的函数都有了一个相对比较详细的介绍,

 

16. x264_macroblock_write_cabac函数

在宏块编码结束后,就要将编码生成的内容写到码流中。如果支持CABAC编码,就调用x264_macroblock_write_cabac。如果是CAVLC编码,就调用x264_macroblock_write_cavlc。

先调用函数x264_cabac_mb_type来将宏块类型写入码流,然后根据宏块的类型进行码流的写入操作:

A. 如果是I_PCM类型,那么直接对亮度和色度调用函数bs_write来将数据写入码流,然后返回。

B. 如果是帧内类型,如果采用了8x8DCT变换并且不是I_16x16,那么就调用x264_cabac_mb_transform_size来将变换的尺寸写入码流,如果是I_8x8或I_4x4,需要将预测模式写入码流,然后是将色度预测模式写入码流。

C. 如果是帧间16x16, 16x8 和 8x16 ,则根据相应的类型,调用x264_cabac_mb_ref将参考帧写入码流,调用x264_cabac_mb_mvd将运动矢量差写入码流

D. 如果是帧间P_8x8模式,首先将每一个子块的模式写入码流x264_cabac_mb_sub_p_partition,然后将每一个块用到的参考帧写入码流x264_cabac_mb_ref,最后在函数x264_cabac_mb8x8_mvd中将每一个8x8块的mvd写入码流。

E. 如果是B_8x8模式,同样写入子块模式x264_cabac_mb_sub_b_partition,然后前后参考帧写入码流x264_cabac_mb_ref,最后调用x264_cabac_mb8x8_mvd将L0和L1上的参考帧写入码流。

F. 如果是除B_DIRECT之外所有其他模式,将参考帧和mvd写入码流。

 

接下来将亮度和色度CBP写入码流:x264_cabac_mb_cbp_luma和x264_cabac_mb_cbp_chroma。

然后将qp_delta写入码流x264_cabac_mb_qp_delta,
同时根据宏块类型将残差系数写入码流block_residual_write_cabac。

 

 

17.x264_macroblock_write_cavlc函数

首先,根据帧类型计算i_mb_i_offset的值。依据宏块类型(i_mb_type)写相应的数据到流中:

A. 如果宏块类型是I_PCM,就把16x16个亮度值、2x8x8个色度值直接写到码流中。

个4x4块和4个8x8块,先调用 x264_mb_predict_intra4x4_mode获取最可能的预测模式,然后比较当前的预测模式和最可能的预测模式,将判断结果写入码流中,
最后写入当前的预测模式值。

C. 如果宏块类型是I_16x16,将当前的预测模式写入码流。

D. 如果宏块类型是P_L0, 宏块子分区分别为D_16x16、D_16x8和D_8x16时,处理步骤相似,先将分区类型写入码流,然后预测运动向量(x264_mb_predict_mv)得到mvp,最后写入当前运动向量与mvp的差值(MVD)。

个子宏块类型,参考帧信息,调用cavlc_mb8x8_mvd计算 mvd。cavlc_mb8x8_mvd函数中根据不同的子分区类型(D_L0_8x8/D_L1_8x8/D_BI_8x8...)调用 cavlc_mb_mvd函数计算MVD并写入码流。cavlc_mb_mvd函数中也是计算mvp(x264_mb_predict_mv),算mvd 并写入码流中。

F. 如果宏块类型是非B_DIRECT——B帧的非直接模式,可能会双向参考。之后根据两个参考帧列表结合子分区类型(D_16x16、D_16x8、D_8x16),写入参考帧信息,计算mvp(x264_mb_predict_mv),计算mvd并写入码流中。

G. 如果宏块类型是B_DIRECT,就写个类型。

 

这样,在运动向量差写入完成后。写编码的块模式。写残差数据,分亮度残差数据和色度残差数据。

A. 如果类型是I_16x16,先计算qp-delta并写入码流,写亮度DC和AC系数(block_residual_write_cavlc)。

B. 如果不是I_16x16,且亮度和色度有一个不是零(h->mb.i_cbp_luma != 0 || h->mb.i_cbp_chroma != 0)。先计算qp-delta并写入码流,然后调用x264_macroblock_luma_write_cavlc进行亮度宏块编码。

 

对于色度残差数据的cavlc编码,先写入Cb,Cr的DC系数(block_residual_write_cavlc),后写入AC系数(block_residual_write_cavlc)。

这样就完成了熵编码。

 

 

 

 

 

x264阅读记录-3的更多相关文章

  1. x264阅读记录-2

    x264阅读记录-2 7. x264_encoder_encode函数-1 查看该函数代码(Encoder.c文件)可以发现,该函数中注释很详细,对编码的整个步骤展示的也相对比较清晰. 在查看具体的代 ...

  2. x264阅读记录-1

    x264阅读记录-1 采用x264版本是x264-snapshot-20060316-2245. 1. main函数 x264的main函数位于x264.c中,下面是main函数调用情况: (1)_s ...

  3. EventBus源码解析 源码阅读记录

    EventBus源码阅读记录 repo地址: greenrobot/EventBus EventBus的构造 双重加锁的单例. static volatile EventBus defaultInst ...

  4. Elasticsearch6.3.2启动过程源码阅读记录

    Elasticsearch6.3.2启动过程源码阅读记录 网上有很多关于es的源码分析,觉得自己技术深度还不够,所以这些文章只是看源码过程中的一个笔记,谈不上分析. 整个启动过程以类名.方法名,按顺序 ...

  5. 《Javascript高级程序设计》阅读记录(七):第七章

    <Javascript高级程序设计>中,2-7章中已经涵盖了大部分精华内容,所以摘录到博客中,方便随时回忆.本系列基本完成,之后的章节,可能看情况进行摘录. 这个系列以往文字地址: < ...

  6. 《Javascript高级程序设计》阅读记录(六):第六章 下

    这个系列以往文字地址: <Javascript高级程序设计>阅读记录(一):第二.三章 <Javascript高级程序设计>阅读记录(二):第四章 <Javascript ...

  7. 《Javascript高级程序设计》阅读记录(五):第六章 上

    这个系列以往文字地址: <Javascript高级程序设计>阅读记录(一):第二.三章 <Javascript高级程序设计>阅读记录(二):第四章 <Javascript ...

  8. 《Javascript高级程序设计》阅读记录(三):第五章 上

    这个系列以往文字地址: <Javascript高级程序设计>阅读记录(一):第二.三章 <Javascript高级程序设计>阅读记录(二):第四章 这个系列,我会把阅读< ...

  9. 《Javascript高级程序设计》阅读记录(一):第二、三章

    <Javascript高级程序设计>阅读记录(一) 这个系列,我会把阅读<Javascript高级程序设计>之后,感觉讲的比较深入,而且实际使用价值较大的内容记录下来,并且注释 ...

随机推荐

  1. 一起学Hadoop——Hadoop的前世今生

    Hadoop是什么? Hadoop是一个处理海量数据的开源框架.2002年Nutch项目面世,这是一个爬取网页工具和搜索引擎系统,和其他众多的工具一样,都遇到了在处理海量数据时效率低下,无法存储爬取网 ...

  2. python__int 部分内部功能介绍

    查看创建的对象的类型: age=18 print(type(age)) 结果: <class 'int'> x.bit_length():返回二进制的位数 Python中进制的转换: Py ...

  3. nginx限制单个IP的最大连接数量限制下载速度

    今天seafile服务因为测试在下载文件的时候,带宽占用过大,导致seafile客户端无法登陆的问题. 我们公司的seafile是通过nginx代理的8000端口,因此我这边通过修改nginx配置来解 ...

  4. form表单利用iframe高仿ajax

    html代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...

  5. BZOJ4237 稻草人 分治 单调栈

    原文链接https://www.cnblogs.com/zhouzhendong/p/8682572.html 题目传送门 - BZOJ4237 题意 平面上有$n(n\leq 2\times 10^ ...

  6. Python re模块, xpath 用法

    1.re正则的用法总结 (1). ^ 表示以哪个字符为开头      eg:  '^g' 表示以g开头的字符串      . 表示任意字符 '^g.d'  表示以g开头第二个为任意字符,第三个为b的字 ...

  7. Linux安装Tomcat-Nginx-FastDFS-Redis-Solr-集群——【第四集之安装Linux】

    1,确保Linux镜像的路径存在 2,启动 3,在真实机情况下,进入BIOS修改安装操作系统的路径[记住:虚拟机不需要这一步.] 如果是真实机安装Linux,默认是从硬盘中安装,而不是从光盘.这就需要 ...

  8. SpringBoot统一错误处理

    1.处理错误请求页面 import org.springframework.stereotype.Controller; import org.springframework.web.bind.ann ...

  9. 一张图解析FastAdmin中的表格列表的功能

    大图: 1.默认生成的CRUD是没有菜单名称和描述显示的,如果需要显示则可以在后台修改,权限管理->菜单规则,给对应菜单的添加上备注信息后即可显示,支持HTML 2.TAB过滤选项卡 在一键生成 ...

  10. HDU 5113

    HDU 5113类似四色定理的什么东西,大体就是dfs了,不过有两个坑点,这个题的逼格瞬间就上去了1.剪枝很神奇,任何一种颜色都不能超过剩下总格子数的一半,想想确实显然但是比赛的时候没有想到:2.测评 ...