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. ELK+Redis+Nginx服务数据存储以及Nginx日志的收集

    PS:此片文章是承接上篇ELK部署文档,再次便不详细说明了 [安装Redis] [root@Redis ~]# wget  http://download.redis.io/releases/redi ...

  2. Codeforces Gym100783H 最短路 其他

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF-Gym100783H.html 题目传送门 - CF-Gym100783H 题意 给定一个 $n$ 个节点 ...

  3. sql语句表示不等于

    <> != 后面均不带引号“”

  4. 电信项目java补充类

    一.DecimalFormat 1.概述 public class DecimalFormat extends NumberFormat DecimalFormat是格式为十进制数的NumberFor ...

  5. Philosopher’s Walk(递归)

    In Programming Land, there are several pathways called Philosopher’s Walks for philosophers to have ...

  6. Nowcoder contest 370H Rinne Loves Dynamic Graph【分层图最短路】

    <题目链接> 题目大意:Rinne 学到了一个新的奇妙的东西叫做动态图,这里的动态图的定义是边权可以随着操作而变动的图.当我们在这个图上经过一条边的时候,这个图上所有边的边权都会发生变动. ...

  7. P2158 [SDOI2008]仪仗队

    P2158 [SDOI2008]仪仗队图是关于y=x对称的,横纵坐标一定是互质的否则在之前就被扫过了,所以就可以用欧拉函数再*2就完了. #include<iostream> #inclu ...

  8. 20172328《程序设计与数据结构》实验三 敏捷开发与XP实践报告

    20172328<程序设计与数据结构>实验三 敏捷开发与XP实践报告 课程:<程序设计与数据结构> 班级: 1723 姓名: 李馨雨 学号:20172328 实验教师:王志强 ...

  9. spring mvc简单介绍xml版

    spring mvc介绍:其实spring mvc就是基于servlet实现的,只不过他讲请求处理的流程分配的更细致而已. spring mvc核心理念的4个组件: 1.DispatcherServl ...

  10. dhcp搭建

    DHCP服务搭建 动态主机配置协议 dhcp曾用名 bootp 应用规模:终端超过五台,建议使用DHCP分配的信息:IP地址,NETMASK掩码,GATEWAY网关,DNS1DNS服务器,DNS2,D ...