FFmpeg与libx264 x264接口源代码简单分析

源代码位于“libavcodec/libx264.c”中。正是有了这部分代码,使得FFmpeg可以调用libx264编码H.264视频。
 从图中可以看出,libx264对应的 AVCodec结构体ff_libx264_encoder 中设定编码器初始化函数是X264_init(), 编码 一帧数据的函数是X264_frame(),编码器关闭函数是X264_close()。
X264_init()调用了如下函数:
[libx264 API] x264_param_default():设置默认参数。
[libx264 API] x264_param_default_preset():设置默认preset。
convert_pix_fmt():将FFmpeg像素格式转换为libx264像素格式。
[libx264 API] x264_param_apply_profile():设置Profile。
[libx264 API] x264_encoder_open():打开编码器。
[libx264 API] x264_encoder_headers():需要全局头的时候,输出头信息。
X264_frame()调用了如下函数:
[libx264 API] x264_encoder_encode():编码一帧数据。
[libx264 API] x264_encoder_delayed_frames():输出编码器中缓存的数据。
encode_nals():将编码后得到的x264_nal_t 转换为AVPacket
X264_close()调用了如下函数:
[libx264 API] x264_encoder_close():关闭编码器。
  1. //libx264对应的AVCodec结构体  
  2. AVCodec ff_libx264_encoder = {  
  3.     .name             = "libx264",  
  4.     .long_name        = NULL_IF_CONFIG_SMALL("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),  
  5.     .type             = AVMEDIA_TYPE_VIDEO,  
  6.     .id               = AV_CODEC_ID_H264,  
  7.     .priv_data_size   = sizeof(X264Context),  
  8.     .init             = X264_init,  
  9.     .encode2          = X264_frame,  
  10.     .close            = X264_close,  
  11.     .capabilities     = CODEC_CAP_DELAY | CODEC_CAP_AUTO_THREADS,  
  12.     .priv_class       = &x264_class,  
  13.     .defaults         = x264_defaults,  
  14.     .init_static_data = X264_init_static,  
  15. };  
priv_class指向一个x264_class静态结构体,该结构体是 libx264对应的 AVClass ,定义如下:
  1. static const AVClass x264_class = {  
  2.     .class_name = "libx264",  
  3.     .item_name  = av_default_item_name,  
  4.     .option     = options,//选项  
  5.     .version    = LIBAVUTIL_VERSION_INT,  
  6. };  
option指向一个options[]静态数组,其中包含了libx264支持的 AVOption选项
  1. //FFmpeg针对libx264提供的可以通过AVOption设置的选项  
x264opts:x264 options
x264-params: Override  the x264 configuration using a :-separated list of key=value parameters
X264_init:
主要将各种选项值传递给libx264。这些选项有两个来源:AVCodecContext和X264Context。
AVCodecContext中包含了编码器的一些通用选项,而X264Context包含了一些libx264特有的选项。
X264Context *x4 = avctx->priv_data;  
//把AVCodecContext的值(主要是编码时候的一些通用选项)映射到x264_param_t   :
  1. if (avctx->gop_size >= 0)  
  2.         x4->params.i_keyint_max         = avctx->gop_size;  
//把X264Context中的信息(主要是针对于libx264的一些选项)映射到x264_param_t   
  1. if(x4->x264opts){  
  2.         const char *p= x4->x264opts;  
  3.         while(p){  
  4.             char param[256]={0}, val[256]={0};  
  5.             if(sscanf(p, "%255[^:=]=%255[^:]", param, val) == 1){  
  6.                 OPT_STR(param, "1");  
  7.             }else  
  8.                 OPT_STR(param, val);  
  9.             p= strchr(p, ':');  
  10.             p+=!!p;  
  11.         }  
  12.     }  
  13.   
  14.     if (x4->x264_params) {  
  15.         AVDictionary *dict    = NULL;  
  16.         AVDictionaryEntry *en = NULL;  
  17.   
  18.         if (!av_dict_parse_string(&dict, x4->x264_params, "="":", 0)) {  
  19.             while ((en = av_dict_get(dict, "", en, AV_DICT_IGNORE_SUFFIX))) {  
  20.                 if (x264_param_parse(&x4->params, en->key, en->value) < 0)  
  21.                     av_log(avctx, AV_LOG_WARNING,  
  22.                            "Error parsing option '%s = %s'.\n",  
  23.                             en->key, en->value);  
  24.             }  
  25.   
  26.             av_dict_free(&dict);  
  27.         }  
  28.     }  
X264_frame:
 AVFrame --> x264_picture_t --> x264_nal_t --> AVPacket   
调用encode_nals()将x264_nal_t转换成了AVPacket( 可能有多个NALU, 作用就是将 多个 x264_nal_t合并为一个AVPacket 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值