avcodec_open2(st->codec, codec, options ? &options[i] : NULL);
|-- avctx->codec->init(avctx);
-->int X264_init(AVCodecContext *avctx)
|-- check_default_settings(avctx); // 使用默认设置"Default settings detected, using medium profile"
| ...
| if(x4->x264opts){ 对x264进行指定的参数设置;}
| ...
|-- x264_encoder_open(&x4->params);
|-- x264_sps_init( h->sps, h->param.i_sps_id, &h->param );
| x264_pps_init( h->pps, h->param.i_sps_id, &h->param, h->sps );
| 初始化帧内预测,MC, DCT, 扫描, 量化, deblock, 熵编码的函数指针;
| ...
|-- x264_encoder_headers(x4->enc, &nal, &nnal); //编码NAL头, SPS和PPS
|-- encode_nals(avctx, avctx->extradata, s, nal, nnal, 1);
transcode
|
V
output_packet
|
V
do_video_out
|
V
avcodec_encode_video
|
V
int X264_frame(AVCodecContext *ctx, // 编码参数
uint8_t *buf,int orig_bufsize, // 输出的编码后的比特流
void *data) // 要编码YUV帧
{
x264_picture_init( &x4->pic ); // 初始化
x264_encoder_encode(...);
|-- x264_frame_expand_border_lowres( frame ); //扩边
x264_slice_init( h, i_nal_type, i_global_qp ); // Create slice header
x264_slices_write( h );
|-- x264_slice_write()
|-- x264_slice_header_write( &h->out.bs, &h->sh, h->i_nal_ref_idc );
|-- x264_macroblock_analyse( x264_t *h )
|-- if( h->sh.i_type == SLICE_TYPE_I )
| 进行I4x4, I8x8, I16x16的SAD计算,得到最佳宏块模式;
| else if( h->sh.i_type == SLICE_TYPE_P )
| 进行Intra, inter P的SAD计算, 得到最佳宏块模式;
| else if( h->sh.i_type == SLICE_TYPE_B )
| 进行Intra, inter B的SAD计算, 得到最佳宏块模式;
|-- x264_macroblock_encode_internal( h, 1, 1 )
|-- if( h->mb.i_type == I_16x16 )
| x264_mb_encode_i16x16( h, p, i_qp );// I_16x16编码: 预测,计算残差,DCT,量化,扫描,反量化,idct
| else if( h->mb.i_type == I_8x8 )
| x264_mb_encode_i8x8( h, p, i, i_qp, i_mode, NULL, 1 );
| else if( h->mb.i_type == I_4x4 )
| 264_mb_encode_i4x4( h, p, i, i_qp, i_mode, 1 ); // 预测,计算残差值
| else /* Inter MB */
| 预测,计算残差值, dct, 量化,扫描, 反量化, idct ;
| ...
| if( chroma )
| x264_mb_encode_chroma( h, !IS_INTRA( h->mb.i_type ), h->mb.i_chroma_qp );
|-- 熵编码
}