1. if( p_set_outfile_param( opt->hout, param ) ) // p_set_outfile_param = set_param_bsf 判断输出文件
{
fprintf( stderr, "can't set outfile param\n" );
p_close_infile( opt->hin );
p_close_outfile( opt->hout );
return -1;
}
p_set_outfile_param = set_param_bsf , 在muxers.c中,函数原型为:
int set_param_bsf( hnd_t handle, x264_param_t *p_param )
{
return 0;
}
2. x264_picture_alloc( &pic, X264_CSP_I420, param->i_width, param->i_height );
//构造一个图像帧的初始化空间,在common.c中,函数原型为:
void x264_picture_alloc( x264_picture_t *pic, int i_csp, int i_width, int i_height )
{
pic->i_type = X264_TYPE_AUTO;
pic->i_qpplus1 = 0;
pic->img.i_csp = i_csp;
switch( i_csp & X264_CSP_MASK )
{
case X264_CSP_I420:
case X264_CSP_YV12:
pic->img.i_plane = 3;
pic->img.plane[0] = x264_malloc( 3 * i_width * i_height / 2 );
pic->img.plane[1] = pic->img.plane[0] + i_width * i_height;
pic->img.plane[2] = pic->img.plane[1] + i_width * i_height / 4;
pic->img.i_stride[0] = i_width;
pic->img.i_stride[1] = i_width / 2;
pic->img.i_stride[2] = i_width / 2;
break;
case X264_CSP_I422:
...
}
}
3. i_start = x264_mdate(); //用于编码用时的计算,设定起始时间,在 mdate.c中,函数原型为:
int64_t x264_mdate( void )
{
#if !(defined(_MSC_VER) || defined(__MINGW32__))
struct timeval tv_date;
gettimeofday( &tv_date, NULL );
return( (int64_t) tv_date.tv_sec * 1000000 + (int64_t) tv_date.tv_usec );
#else
struct _timeb tb;
_ftime(&tb);
return ((int64_t)tb.time * (1000) + (int64_t)tb.millitm) * (1000);
#endif
}
4. 进入编码帧 /* Encode frames */
for( i_frame = 0, i_file = 0, i_progress = 0;
b_ctrl_c == 0 && (i_frame < i_frame_total || i_frame_total == 0); )
{
if( p_read_frame( &pic, opt->hin, i_frame + opt->i_seek ) )//读取
break;
//p_read_frame() 按照h->hin提供的输入文件的地址,读入图像的内容到&pic提供的存储区的首地址
pic.i_pts = (int64_t)i_frame * param->i_fps_den;
i_file += Encode_frame( h, opt->hout, &pic );//编码并保存,
//Encode_frame( h, opt->hout, &pic )实现编码,是x264的核心部分
i_frame++;
/* update status line (up to 1000 times per input file) */
if( opt->b_progress && param->i_log_level < X264_LOG_DEBUG &&
( i_frame_total ? i_frame * 1000 / i_frame_total > i_progress
: i_frame % 10 == 0 ) )
{
int64_t i_elapsed = x264_mdate() - i_start;
double fps = i_elapsed > 0 ? i_frame * 1000000. / i_elapsed : 0;
if( i_frame_total )
{
int eta = i_elapsed * (i_frame_total - i_frame) / ((int64_t)i_frame * 1000000);
i_progress = i_frame * 1000 / i_frame_total;
fprintf( stderr, "encoded frames: %d/%d (%.1f%%), %.2f fps, eta %d:%02d:%02d \r",
i_frame, i_frame_total, (float)i_progress / 10, fps,
eta/3600, (eta/60)%60, eta%60 );
}
else
fprintf( stderr, "encoded frames: %d, %.2f fps \r", i_frame, fps );
fflush( stderr ); // needed in windows
}
}
注1: //在本文环境下,p_read_frame=read_frame_yuv,read_frame_yuv()定义在muxers.c中,原型为:
int read_frame_yuv( x264_picture_t *p_pic, hnd_t handle, int i_frame )
{
yuv_input_t *h = handle;
if( i_frame != h->next_frame )
if( fseek( h->fh, (uint64_t)i_frame * h->width * h->height * 3 / 2, SEEK_SET ) )
return -1;
if( fread( p_pic->img.plane[0], 1, h->width * h->height, h->fh ) <= 0
|| fread( p_pic->img.plane[1], 1, h->width * h->height / 4, h->fh ) <= 0
|| fread( p_pic->img.plane[2], 1, h->width * h->height / 4, h->fh ) <= 0 )
return -1;
h->next_frame = i_frame+1;
return 0;
}
从文件中分别读取288*352(亮度信息),144*176(Cr),144*176(Cb)的数据放入p_pic->img.plane[0],p_pic->img.plane[1],p_pic->img.plane[2],如果成功则继续执行一下程序;如果不成功则打断程序,返回-1.
注2: i_file += Encode_frame( h, opt->hout, &pic );//编码并保存,
//Encode_frame( h, opt->hout, &pic )实现编码,是x264的核心部分,在X264.c中,
//这个函数主要是调用了 x264_encoder_encode( h, &nal, &i_nal, pic, &pic_out ) 来实现编码。
// 原型为:
static int Encode_frame( x264_t *h, hnd_t hout, x264_picture_t *pic )
{
x264_picture_t pic_out;
x264_nal_t *nal;
int i_nal, i;
int i_file = 0;
/* Do not force any parameters */
if( pic )
{
pic->i_type = X264_TYPE_AUTO;
pic->i_qpplus1 = 0;
}
if( x264_encoder_encode( h, &nal, &i_nal, pic, &pic_out ) < 0 )
{
fprintf( stderr, "x264_encoder_encode failed\n" );
}
for( i = 0; i < i_nal; i++ )
{
int i_size;
int i_data;
i_data = DATA_MAX;
if( ( i_size = x264_nal_encode( data, &i_data, 1, &nal[i] ) ) > 0 )
{
i_file += p_write_nalu( hout, data, i_size );
}
else if( i_size < 0 )
{
fprintf( stderr, "need to increase buffer size (size=%d)\n", -i_size );
}
}
if (i_nal)
p_set_eop( hout, &pic_out );
return i_file;
}
评论