• 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'. ",  
    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 
  • 相关阅读:
    v-if与v-show的区别
    vue 初始化项目
    element-ui的el-table中添加递增序号
    根据下拉框中选择的列在下面表格中显示对应的列
    element-ui中el-input需要改变placeholder的字体颜色
    根据不同路由,使对应的菜单高亮显示
    中间文字,两边横线的css3伪元素的使用
    关于正则表达式进行自定义校验
    对输入的表单内容自定义校验
    vue实现登录之后长时间未操作,退出登录
  • 原文地址:https://www.cnblogs.com/elesos/p/6025647.html
Copyright © 2020-2023  润新知