X264学习笔记
(1)cli_opt_t的这个_t代表结构图可能是type的意思。同时还有很多i_ b_等作为前缀的变量,其中的I_表示int类型的变量 b表示bool类型的。依次类推。
typedef struct {
int b_progress;
int i_seek;
hnd_t hin;
hnd_t hout;
FILE *qpfile;
} cli_opt_t;
此结构体是记录一些与编码关系较小的设置信息的opt=option。结构体内部的变量都可以通过读取main()的参数获得。也就是argv。
b_progress表示一个bool类型的变量,看参数帮助 也就是x264--help你会知道,他是用来控制是否显示编码进度的一个东西。取值为0,1.
I_seek 整数类型 表示开始从哪一帧编码。因为不一定从这个文件的第一帧开始编码,这是可以控制的。
Hnd_t(hnd=handle)是一个空指针, void *在C语言里空指针是有几个特性的,他是一个一般化指针,可以指向任何一种类型,但却不能解引用,需要解引用的时候,需要进行强制转换。采用空指针的策略,应该是为了声明变量的简便和统一。
Hin 指向输入yuv文件的指针。
Hout 指向编码过后生成的文件的指针
Qpfile 是一个指向文件类型的指针,他是文本文件,其每一行的格式是framenum frametype QP
用于强制指定某些帧或者全部帧的帧类型和QP(quant param量化参数)的值
(2)PTW32_STATIC_LIB//定义静态链接库,线程方面的一些相关的东东
(3)SIGINT是信号名称或代码(Ctrl-C会产生这个信号)
signal( SIGINT, SigIntHandler)就是当键入Ctrl-C的时候,当前执行程序调用SigIntHandler,执行完后再返回原来执行的地方接着往下走
(4)进入编码函数: static int Encode( x264_param_t *param, cli_opt_t *opt )
(a)x264_picture_t和x264_frame_t的区别.前者是说明一个视频序列中每帧的特点.后者存放每帧实际的象素值.注意区分
(b)Log参数,不需要打印编码信息时直接注释掉就行
pX264Param->i_log_level = X264_LOG_DEBUG
(c)poc和frame的区别
/****************************************************************************
* x264_encoder_encode:
* XXX: i_poc : is the poc of the current given picture
* i_frame : is the number of the frame being coded
* ex: type frame poc
* I 0 2*0
* P 1 2*3
* B 2 2*1
* B 3 2*2
* P 4 2*6
* B 5 2*4
* B 6 2*5
****************************************************************************/
假设一个视频序列如下:I B B P B B P
我们编码按 I P B B P B B的顺序,就是frame的编好编码;
而我们视频序列的播放序号是按POC的序号进行播放
(d)nal类型:int i_nal_type有以下几种:
enum nal_unit_type_e
{
NAL_UNKNOWN = 0,
NAL_SLICE = 1,//片,不分区,非IDR的片
NAL_SLICE_DPA = 2,
NAL_SLICE_DPB = 3,
NAL_SLICE_DPC = 4,
NAL_SLICE_IDR = 5, //I 帧/* ref_idc != 0 */
NAL_SEI = 6, //增强信息/* ref_idc == 0 */
NAL_SPS = 7,//序列参数集
NAL_PPS = 8,//图形参数集
NAL_AUD = 9,
/* ref_idc == 0 for 6,9,10,11,12 */
};
(e)x264_encoder_encode:
编码时,维持着三个队列:frame_next队列(临时缓存,帧类型没确定,待编码的帧队列),frame_current队列(按编码顺序排放,已经确定了帧的类型,正在编码的帧队列)和frame_unused队列(空白队列,将要编码的帧放入该队列)。
1.x264_reference_update:(更新参考帧队列,若为B帧则不更新)将上一个参考帧放入参考帧队列,并从空闲队列中取出一帧作为当前参考工作帧;
2.x264_frame_pop_unused:(获取一帧的空间fenc,用来存放待编码的帧)若unused队列不为空,则将取出的帧放入unused队列(x264_frame_pop),否则,分配一帧空间(x264_frame_new);
3. x264_frame_copy_picture:将该帧图像拷贝到fenc中
4.判断是否需要进行边界扩展(x264_frame_expand_border_mod16),不能被16整除的都需要进行扩展。
5.将fenc放入frame_next中(x264_frame_push)
6.如果用到半精度亮度块,需要进行1/2像素扩展(x264_frame_init_lowres)
7.若frame.current[0]==NULL(当前队列中没有帧需要编码)
I.若frame.next[0]==NULL,结束编码(x264_encoder_frame_end)
II. 判断帧类型(x264_slicetype_decide)
III.将帧类型确定的帧重新排列存放在frame.current队列中
8. 调整当前队列中帧的顺序,开始编码
9.对编码之后的nal封装成NAL单元(x264_nal_encode);
10.将NALU单元写入输出文件(p_write_nalu)
浙公网安备 33010602011771号