博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
x264编码过程分析(一)概述
阅读量:3918 次
发布时间:2019-05-23

本文共 3194 字,大约阅读时间需要 10 分钟。

在这里插入图片描述
这里只摘录个人觉得梗概的部分,详细跳转雷神
在这里插入图片描述
x264编码主要分4部分:
1、x264_encoder_open()用于打开编码器,其中初始化了libx264编码所需要的各种变量。它调用了下面的函数:

x264_validate_parameters():检查输入参数(例如输入图像的宽高是否为正数)。

x264_sps_init():根据输入参数生成H.264码流的SPS信息。
x264_pps_init():根据输入参数生成H.264码流的PPS信息。
x264_predict_16x16_init():初始化Intra16x16帧内预测汇编函数。
x264_predict_4x4_init():初始化Intra4x4帧内预测汇编函数。
x264_pixel_init():初始化像素值计算相关的汇编函数(包括SAD、SATD、SSD等)。
x264_dct_init():初始化DCT变换和DCT反变换相关的汇编函数。
x264_mc_init():初始化运动补偿相关的汇编函数。
x264_quant_init():初始化量化和反量化相关的汇编函数。
x264_deblock_init():初始化去块效应滤波器相关的汇编函数。
x264_lookahead_init():初始化Lookahead相关的变量。
x264_ratecontrol_new():初始化码率控制相关的变量。

在这里插入图片描述

在这里插入图片描述

2、x264_encoder_headers()输出SPS/PPS/SEI这些H.264码流的头信息。它调用了下面的函数:

x264_sps_write():输出SPS

x264_pps_write():输出PPS
x264_sei_version_write():输出SEI//x264_param2string将参数变成string再write
//为了使之在文件中是nalu的形式 要再前后进行x264_nal_start() x264_nal_end()

3、x264_encoder_encode()编码一帧YUV为H.264码流。它调用了下面的函数:

1、x264_frame_pop_unused():获取1个x264_frame_t类型结构体fenc。//如果frames.unused[]队列不为空,就调用x264_frame_pop()从unused[]队列取1个现成的;//否则就调用x264_frame_new()创建一个新的编码帧or重建帧。	//	调用x264_frame_internal_csp()将多种(i_csp=)外部colorspace转换成3中内部colorspace:X264_CSP_NV12(对应YUV420),X264_CSP_NV16(对应YUV422),X264_CSP_I444(对应YUV444)2、x264_frame_copy_picture()将外部结构体的pic_in(x264_picture_t类型)的数据拷贝给内部结构体的fenc(x264_frame_t类型)。//简单地将x264_picture_t中字段的值赋值给了x264_frame_t。3、x264_lookahead_put_frame():将fenc放入lookahead.next.list[]队列,等待确定帧类型。4、x264_lookahead_get_frames():分析Lookahead模块中一个帧的帧类型。分析后的帧保存在frames.current[]中。//调用x264_slicetype_decide→调用x264_slicetype_analyse  以及x264_slicetype_frame/slice/mb_cost计算开销。//经过一些列分析之后,最终确定了帧类型信息,并且将帧放入frames.current[]队列。	//(1)如果frames[1]通过scenecut()判断为场景切换,设置为I帧,并且直接返回。	//(2)如果i_bframe为0,即不使用B帧,则将所有帧都设置为P帧。	//(3)如果i_bframe不为0,即使用B帧,则需要进行比较复杂的帧开销计算。这时候需要调用一帧图像开销的计算函数x264_slicetype_frame_cost()。5、x264_frame_shift():从frames.current[]队列头部取出1帧list[0]用于编码。6、x264_reference_update():更新参考帧队列frames.reference[]。//将重建帧fdec加入参考帧队列//如果重建帧fdec是不被参考的B帧,则直接返回;如果fdec是被参考的帧,则会调用x264_frame_push()将该帧加入frames.reference[]队列的尾部。//如果frames.reference[]已经满了,则会调用x264_frame_shift()和x264_frame_push_unused()将frames.reference[]队列头部的帧移动到frames.unused[]队列。最后函数还会调用x264_frame_pop_unused()获取一个新的重建帧fdec。7、x264_reference_reset():如果为IDR帧,调用该函数清空参考帧列表。//x264_reference_reset()中调用x264_frame_pop()和x264_frame_push_unused()将frames.reference[]队列中的帧移动到frames.unused[]队列中。8、x264_reference_hierarchy_reset():如果是I(非IDR帧)、P帧、B帧(可做为参考帧),调用该函数。9、x264_reference_build_list():创建参考帧列表list0和list1。10、根据选项做一些配置:		a)如果b_aud不为0,输出AUD类型NALU		b)在当前帧是关键帧的情况下,如果b_repeat_headers不为0,调用x264_sps_write()和x264_pps_write()输出SPS和PPS。		c)输出一些特殊的SEI信息,用于适配各种解码器。11、x264_ratecontrol_start():开启码率控制。12、x264_slice_init():创建 Slice Header。//调用x264_slice_header_init()完成了Slice Header “通用”的初始化工作,然后根据帧类型的不同,做了一些特殊参数的设置13、x264_slices_write():编码数据(最关键的步骤)。//其中调用了x264_slice_write()完成了编码的工作(注意“x264_slices_write对应帧”和“x264_slice_write对应slice”名字差了一个“s”)。14、x264_encoder_frame_end():编码结束后做一些后续处理,//例如记录一些统计信息。其中调用了x264_frame_push_unused()将fenc重新放回frames.unused[]队列,并且调用x264_ratecontrol_end()关闭码率控制。

在这里插入图片描述

4、x264_encoder_close()用于关闭解码器,同时输出一些统计信息。

//输出使用了libx264中输出日志的API函数

它调用了下面的函数:

x264_lookahead_delete():释放Lookahead相关的变量。
x264_ratecontrol_summary():汇总码率控制信息。
x264_ratecontrol_delete():关闭码率控制。

转载地址:http://rfhrn.baihongyu.com/

你可能感兴趣的文章
剑指 Offer 48. 最长不含重复字符的子字符串
查看>>
剑指 Offer 49. 丑数
查看>>
剑指 Offer 50. 第一个只出现一次的字符
查看>>
模式23.解释器模式-Java
查看>>
模式22.享元模式-Java
查看>>
剑指 Offer 52. 两个链表的第一个公共节点
查看>>
剑指 Offer 53 - I. 在排序数组中查找数字 I
查看>>
剑指 Offer 53 - II. 0~n-1中缺失的数字
查看>>
剑指 Offer 54. 二叉搜索树的第k大节点
查看>>
剑指 Offer 55 - I. 二叉树的深度
查看>>
剑指 Offer 55 - II. 平衡二叉树
查看>>
剑指 Offer 56 - I. 数组中数字出现的次数
查看>>
模式24.访问者模式-Java
查看>>
剑指 Offer 56 - II. 数组中数字出现的次数 II
查看>>
剑指 Offer 57. 和为s的两个数字
查看>>
剑指 Offer 57 - II. 和为s的连续正数序列
查看>>
剑指 Offer 58 - I. 翻转单词顺序
查看>>
剑指 Offer 58 - II. 左旋转字符串
查看>>
剑指 Offer 59 - I. 滑动窗口的最大值
查看>>
剑指 Offer 59 - II. 队列的最大值
查看>>