x264阅读笔记之 X264_frame

来源:百度文库 编辑:神马文学网 时间:2024/04/23 22:22:54
ffmpeg中,libavcodec\libx264.c 文件,X264_frame 函数,用以对一帧图像或者延迟的数据进行压缩编码。
static int X264_frame(AVCodecContext *ctx, uint8_t *buf,
int bufsize, void *data)
{
X264Context *x4 = ctx->priv_data;
AVFrame *frame = data;
x264_nal_t *nal;
int nnal, i;
x264_picture_t pic_out;
// 将 ffmpeg 的 AVFrame 转换为 x264 的 x264_picture_t 类型
x4->pic.img.i_csp   = X264_CSP_I420;  //Csp: color space parameter 色 彩空间参数 X264只支持I420
x4->pic.img.i_plane = 3;              //i_Plane 代表色彩空间的个数。一般为3,YUV
if (frame) {  // frame==NULL 意味着,avcodec_encode_video 调用 X264_frame 时,实际传入参数 AVFrame *pict 的值为NULL。即 X264_frame 是对delayed frame进行处理。
for (i = 0; i < 3; i++) {
x4->pic.img.plane[i]    = frame->data[i];    //原来有这种对应关系
x4->pic.img.i_stride[i] = frame->linesize[i];//原来有这种对应关系
}
x4->pic.i_pts  = frame->pts;       //pts居然是由外传入的。这么说在ffmpeg中,应该有生成pts的地方,可在 video_encode_example 中并没有
x4->pic.i_type = X264_TYPE_AUTO;
}
do {            //*pi_nal(即此处的nnal) is the number of NAL units outputted in pp_nal(即此处的nal)
if (x264_encoder_encode(x4->enc, &nal, &nnal, frame? &x4->pic: NULL, &pic_out) < 0) //pic_out是干嘛的?主要是最终是进入到了x4->out_pic
return -1;
bufsize = encode_nals(ctx, buf, bufsize, nal, nnal, 0);
if (bufsize < 0)
return -1;
} while (!bufsize && !frame && x264_encoder_delayed_frames(x4->enc));
//与函数开始处相对,这是将 x264 的 x264_picture_t 类型,转换为 ffmpeg 的 AVFrame 类型。
/* FIXME: libx264 now provides DTS, but AVFrame doesn't have a field for it. */
x4->out_pic.pts = pic_out.i_pts;
switch (pic_out.i_type) {
case X264_TYPE_IDR:
case X264_TYPE_I:
x4->out_pic.pict_type = FF_I_TYPE;
break;
case X264_TYPE_P:
x4->out_pic.pict_type = FF_P_TYPE;
break;
case X264_TYPE_B:
case X264_TYPE_BREF:
x4->out_pic.pict_type = FF_B_TYPE;
break;
}
x4->out_pic.key_frame = pic_out.b_keyframe; /* x264中的注释: Out: whether this frame is a keyframe.  Important when using modes that result in
* SEI recovery points being used instead of IDR frames. */
x4->out_pic.quality   = (pic_out.i_qpplus1 - 1) * FF_QP2LAMBDA;
return bufsize;
}
=================================
X264Context 结构,是ffmpeg代码中的定义:
typedef struct X264Context {
x264_param_t    params;
x264_t         *enc;
x264_picture_t  pic;
uint8_t        *sei;
int             sei_size;
AVFrame         out_pic;
} X264Context;
其中的:x264_param_t、x264_t、x264_picture_t 三种数据结构,都是 x264 代码中的定义。
其中的 AVFrame         out_pic; 目前还没有搞明白到底是用来做什么的?因为在 api_example.c中并没有使用到这个域中的数据。
x264_encoder_encode 函数的最后一个参数 pic_out,主要是在 x264_encoder_frame_end 中修改各成员内容的。
这个数据的流出是在 x4->out_pic,但是在 api_example 中 调用了 avcodec_encode_video 但并没有使用 out_pic 。