x264_encoder_encode
int x264_encoder_encode( x264_t *h,x264_nal_t **pp_nal, int *pi_nal,x264_picture_t* pic_in,x264_picture_t *pic_out )
函数功能说明:
多线程h->param.i_threads > 1的情况先跳过。
●判断上一帧重构fdec是否做参考帧,如果是参考帧,放到reference队列里,然后从
unused队列里分配一帧给fdec。如果上一重构帧不是参考帧(比如B帧),直接返回。
对应的函数为x264_reference_update()。
●从unused队列里取出一帧给fenc,然后将输入的YUV数据复制到fenc的缓冲区里。
●图像宽度和高度不为16的倍数时进行扩边
●h->frames.i_input记录图像的输入顺序。将fenc指针放到next队列里
●对进入待编码队列的帧进行下采样,由参数h->frames.b_have_lowres控制。
对应函数为x264_frame_init_lowres()
●编码的延迟帧数为h->frames.i_delay + 1 - h->param.i_threads。单线程时延迟帧数为
h->frames.i_delay。当h->frames.i_input > h->frames.i_delay进行编码,否则返回。也就是说当编码第一帧时,next队列里缓存了(h->frames.i_delay + 1)帧数据。
●当h->frames.current[0]为空时,需要对next队列里的帧进行重排序,将排序后的当前编
码帧指针放到current队列里。重排序的方法是调用x264_slicetype_decide()产生next队列里各帧的帧类型,然后将next队列里的非B帧先压到current队列里,然后将next 队列里的B帧压到current队列里。
注意:当h->frames.current[0]不为空时,表明h->frames.current[0]里的帧的顺序已经经过了重排序,不需要再更改。
●将current[0]指针pop到fenc里,开始编码。
●根据h->fenc->i_type对nal单元的类型进行初始化。
●初始化h->fenc->i_poc,然后根据当前帧的h->fenc->i_poc队参考帧队列进行排序,生成
新的h->fref0和h->fref1。
●初始化以下数据。
x264_ratecontrol_start()
x264_macroblock_bipred_init()
x264_slice_init()
bs_init()
●当i_nal_type是NAL_SLICE_IDR时,编序列头SPS和图像头PPS。
●编多组块。对应函数是x264_slices_write()。这个函数里面包括编码的各个模块,也是
最耗时的部分。
●如果P帧编得不好,重新编码,编成I帧。
●统计编码时间、psnr、mb类型比例、释放编码分配的空间。
对应函数是x264_encoder_frame_end()。