欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

x264编码过程分析(二)核心函数x264_slice_write()

程序员文章站 2022-07-06 22:55:11
...

x264编码过程分析(二)核心函数x264_slice_write()

1)调用x264_nal_start()开始输出一个NALU。
//x264_macroblock_thread_init()设定了宏块编码数据指针p_fenc[0],p_fenc[1],p_fenc[2]在fenc_buf[]中的位置,
//以及宏块重建数据指针p_fdec[0],p_fdec[1],p_fdec[2] 在fdec_buf[]中的位置2x264_macroblock_thread_init():初始化宏块重建像素数据缓存fdec_buf[]和编码像素数据缓存fenc_buf[]。

(3)调用x264_slice_header_write()输出 Slice Header。

(4)进入一个循环,该循环每执行一遍编码一个宏块:
	a) 每处理一行宏块,调用一次x264_fdec_filter_row()执行滤波模块。
	//(1)环路滤波(去块效应滤波)。通过调用x264_frame_deblock_row()实现。
	//(2)半像素内插。通过调用x264_frame_filter()实现。
			//经过汇编半像素内插函数处理之后,得到的水平半像素内差点存储在x264_frame_t的filtered[][1]中,
			//垂直半像素内差点存储在x264_frame_t的filtered[][2]中,
			//对角线半像素内差点存储在x264_frame_t的filtered[][3]中
			//(整像素点存储在x264_frame_t的filtered[][0]中)。

	//(3)视频质量SSIM和PSNR计算。PSNR在这里只计算了SSD,通过调用x264_pixel_ssd_wxh()实现;SSIM的计算则是通过x264_pixel_ssim_wxh()实现。

	b) 调用x264_macroblock_cache_load()将要编码的宏块的周围的宏块的信息读进来。
	//(1)加载Intra4x4帧内预测模式intra4x4_pred_mode[]和DCT非零系数non_zero_count[]缓存Cache的宏块周边信息。加载顺序为:上->左->左上。
	//(2)加载宏块重建像素p_fdec[]的周边像素,以及宏块编码像素p_fenc[]。对于p_fdec[]来说,在本函数中直接加载当前宏块左边的像素;调用函数x264_macroblock_load_pic_pointers()加载当前宏块上面的像素。对于p_fenc[]来说,调用x264_macroblock_load_pic_pointers()从图像上拷贝数据。
					//x264_macroblock_load_pic_pointers()用于给宏块重建像素p_fdec[]和宏块编码像素p_fenc[]加载数据,并且加载图像的半像素数据。
					//(1)加载编码宏块mb.pic.p_fenc[]的像素数据,以及重建宏块mb.pic.p_fenc[]上边的像素数据。
					//(2)加载参考帧的半像素数据(除了整像素外,还包含了:H,V,C三组半像素数据点)。
	//(3)加载参考帧序号ref[]和运动矢量mv[]缓存Cache的宏块周边信息。加载顺序为:左上->上->左。
	//(4)加载其它信息。

	c) 调用x264_macroblock_analyse()用于分析宏块的编码模式。
		//对于帧内宏块来说,主要分析使用Intra16x16合适还是使用Intra4x4合适;
		//对于帧间宏块来说,主要分析它的划分模式,并且进行运动估计。
	d) 调用x264_macroblock_encode()执行宏块编码模块。
		//两个工作:编码(DCT变换和量化)和重建(DCT反变换和反量化)。
	e) 调用x264_macroblock_write_cabac()/x264_macroblock_write_cavlc()执行熵编码模块。
	f) 调用x264_macroblock_cache_save()保存当前宏块的信息。
	g) 调用x264_ratecontrol_mb()执行码率控制。
	h) 准备处理下一个宏块。

(5)调用x264_nal_end()结束输出一个NALU。

相关标签: H264