X264阅读笔记3

来源:互联网 发布:沁人缘淘宝网 编辑:程序博客网 时间:2024/04/29 20:09
分析代码x264-snapshot-20061010-2245


一、某个宏块编码结束后 x264_macroblock_encode  encoder.c
1、宏块编码结束后,就要将编码生成的内容写到码流中。如果支持CABAC编码,就调用x264_macroblock_write_cabac。
如果是CAVLC编码,就调用x264_macroblock_write_cavlc。调用之前要计算跳过编码的帧个数,并且要写到码流中去。
2、主要分析下x264_macroblock_write_cavlc。根据帧类型计算i_mb_i_offset的值。依据宏块类型(i_mb_type)写相应的数据到流中。
3、如果宏块类型是I_PCM,就把16x16个亮度值、2x8x8个色度值直接写到码流中。
4、如果宏块类型是I_4x4或I_8x8,先写入是否是8x8模式。然后对16个4x4块和4个8x8块,先调用x264_mb_predict_intra4x4_mode获取最可能的预测模式,然后比较当前的预测模式和最可能的预测模式,将判断结果写入码流中,最后写入当前的预测模式值。
5、如果宏块类型是I_16x16,将当前的预测模式写入码流。
6、如果宏块类型是P_L0,宏块子分区分别为D_16x16、D_16x8和D_8x16时,处理步骤相似,先将分区类型写入码流,然后预测运动向量(x264_mb_predict_mv)得到mvp,最后写入当前运动向量与mvp的差值(MVD)。
7、如果宏块类型是P_8x8或B_8x8时,过程类似。先写入类型,接着写入4个子宏块类型,参考帧信息,调用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并写入码流中。
8、如果宏块类型是非B_DIRECT——B帧的非直接模式,可能会双向参考。之后根据两个参考帧列表结合子分区类型(D_16x16、D_16x8、D_8x16),写入参考帧信息,计算mvp(x264_mb_predict_mv),计算mvd并写入码流中。
9、如果宏块类型是B_DIRECT,就写个类型。
10、运动向量差写入完成后。写编码的块模式。写残差数据,分亮度残差数据和色度残差数据。如果类型是I_16x16,先计算qp-delta并写入码流,写亮度DC和AC系数(block_residual_write_cavlc)。
11、如果不是I_16x16,且亮度和色度有一个不是零(h->mb.i_cbp_luma != 0 || h->mb.i_cbp_chroma != 0)。先计算qp-delta并写入码流,然后调用x264_macroblock_luma_write_cavlc进行亮度宏块编码。
12、色度残差数据的cavlc编码。写入Cb,Cr的DC系数(block_residual_write_cavlc),后写入AC系数(block_residual_write_cavlc)。
13、熵编码结束后。x264_macroblock_cache_save函数保存已编码的信息,为了下一次的编码做参考。然后统计编码状态数据,如果使用了动态qp值,用x264_ratecontrol_mb进行qp调整。bs_rbsp_trailing,写入编码结尾数据。x264_nal_end结束NALU。
14、至此整个x264_slices_write函数结束。如果P帧编码出错,就重新编码成I帧。设置码流特征信息,设置码流输出。码流控制更新(x264_ratecontrol_end),更新参考帧(x264_reference_update),重置缓冲区(x264_frame_put),计算编码状态信息。
15、当前帧编码结束后,要进行nalu打包了。根据编码时确定的nalu个数,用x264_nal_encode进行打包。
16、如果还有B帧需要编码,就调用Encode_frame进行编码。之后就是释放空间(x264_picture_clean),关闭编码器(x264_encoder_close)。
17、编码的流程结束。
原创粉丝点击