一、函数入口main x264.c
1、调用x264_param_default 设置默认的编码参数。
2、调用Parse 转换 命令行参数
3、进入Encode函数,开始编码
二、Encode x264.c
1、p_get_frame_total获取要编的总数
2、x264_encoder_open创建x264编码器,配置参数
3、p_set_outfile_param设置输出文件参数
4、x264_picture_alloc分配原始图像的内存空间
5、for 循环编码每一帧
6、Encode_frame 编码一帧图像,并nal打包
7、编完剩余的B帧
8、x264_picture_clean释放分配的图像空间
9、x264_encoder_close关闭编码器
10、p_close_infile和p_close_outfile关闭输入和输出文件。
三、Encode_frame x264.c
1、x264_encoder_encode编一帧图像
2、for循环,用x264_nal_encode打nal包,用p_write_nalu写出nal码流。
四、x264_encoder_encode Encoder.c
1、x264_frame_get 申请空间,fenc指向新空间
2、x264_frame_copy_picture 将图像数据从pic_in 拷贝到fenc
3、如果图像的宽高不是16对齐,用x264_frame_expand_border_mod16对数据进行扩展
4、x264_frame_put 将fenc放到next指针数组中
5、当使用低分辨率图像时,用x264_frame_init_lowres作处理
6、if(h->frames.current[0]==NULL)分支表示填充获取B帧编码图像数据,后面再说
7、从current中获取编码图像拷贝到fenc中,用x264_frame_get
8、do_encode 开始编码
9、根据要编码的帧类型设置nal的类型和slice条带的类型。如果是IDR,要用x264_reference_reset重置参考帧。
10、计算poc、帧号、帧类型、当前帧是否作为参考帧等
11、x264_reference_build_list构建参帧链表,list0和list1
12、用x264_ratecontrol_start开始码率控制,用x264_ratecontrol_qp获取当前帧的qp值
13、如果是B帧,用x264_macroblock_bipred_init初始化双向预测
14、x264_slice_init初始化条带头信息
15、用bs_init初始化输出bit流信息
16、写AUD nal、SEI nal、SPS nal和PPS nal信息。
17、调用x264_slices_write开始宏块编码
五、x264_slices_write Encoder.c
1、用单线程编码,调用x264_slice_write编码
2、用x264_nal_start开始写nal,用x264_slice_header_write写条带头信息到码流中
3、如果使用cabac,要初始化cabac环境。调用x264_cabac_context_init和x264_cabac_encode_init。
4、for对每个宏块进行编码。
5、先计算当前宏块的索引,i_mb_y和i_mb_x。
6、x264_macroblock_cache_load获取当前宏块左侧和上侧相邻宏块的数据
7、x264_macroblock_analyse决定当前宏块的最佳编码模式。I帧用9种4x4模式和4种16x16模式。P帧用帧内预测的4x4模式和16x16模式,或用帧间16x16、16x8,8x16,8x8,
8x4,4x8,4x4。选择能生成最小SAD值的模式为当前宏块的编码模式。
8、x264_mb_analyse_init初始化分析参数
9、I帧调用x264_mb_analyse_intra决定帧内模式、P帧和B帧要复杂
10、先看P帧预测。P帧预测中含有I帧的帧内预测。先判断P帧是否可以SKIP,用编码。如果是跳过用x264_macroblock_probe_pskip。
11、x264_mb_analyse_load_costs分配运动向量空间。x264_mb_analyse_inter_p16x16分析帧间16x16模式。模式代价值analysis.l0.me16x16.cost。
12、if判断是否使用了16x16子块模式。如用了,调用x264_mb_analyse_inter_p8x8_mixed_ref和x264_mb_analyse_inter_p8x8对帧间8x8模式进行预测。模式代价值analysis.l0.i_cost8x8。
13、如果上述8x8模式的代价小于16x16模式的值,对8x8模式进一步分成4x4模式。当然要配置了8x8的子块模式。4个8x8块,对4个4x4块进行模式选择,调用x264_mb_analyse_inter_p4x4完成,得到analysis.l0.i_cost4x4[i]4个4x4块的代价和。如果4x4模式的代价analysis.l0.i_cost4x4[i]比8x8模式代价analysis.l0.me8x8[i].cost小,
再对8x8模式划分成8x4和4x8模式,用x264_mb_analyse_inter_p8x4和x264_mb_analyse_inter_p4x8完成。
今天到这来,下次继续16x8和8x16模式的分析。