zoukankan      html  css  js  c++  java
  • 在ffmpeg中添加编解码器

    本文基于ffmpeg-2.2,添加基于QSV(Intel Media SDK / Quick Sync Video)的系列编解码器qsvavc_enc、qsvavc_dec、qsvmpeg2_dec、 qsvvc1_dec,通过一个命令行参数--enable-qsv打开和关闭。

    1. 在libavcodec目录添加相应的代码实现

    可参考hevc.c, libx265.c。如qsvdec.c,qsvenc.c。
    文件名可以随意起,实现中注意下面红字标出的地方需注意。
    ff_qsvavc_decoder/ff_qsvavc_encoder是全局变量,在libavcodec/allcodecs.c中调用REGISTER_ENCDEC宏注册编解码器时会引用此全局变量,因此要保值一致。
    .name项影响到ffmpeg命令行参数-vcodec的名称。

    AVCodec ff_qsvavc_decoder = {
        .name           = "qsvavc",
        .long_name      = NULL_IF_CONFIG_SMALL("H.264 / AVC Decoder via Intel Media SDK / Quick Sync Video (QSV)"),
        .type           = AVMEDIA_TYPE_VIDEO,
        .id             = AV_CODEC_ID_H264,
        .priv_data_size = sizeof(qsvContext),
        .init           = qsv_decode_init_avc,
        .close          = qsv_decode_close,
        .decode         = qsv_decode_frame,
        .flush          = qsv_decode_flush,
        .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_TRUNCATED,
    };

    2. 在libavcodec/allcodecs.c中添加编解码器的注册
    REGISTER_ENCODER(QSVAVC,            qsvavc);
    REGISTER_DECODER(QSVAVC,            qsvavc);
    REGISTER_DECODER(QSVMPEG2,          qsvmpeg2);
    REGISTER_DECODER(QSVVC1,            qsvvc1);

    allcodecs.c定义了REGISTER_ENCDEC,REGISTER_DECODER,REGISTER_ENCODER三个宏,用于注册编码解码器,仅编码器,仅解码器。
    查看REGISTER_DECODER的宏定义可以看到,先引用全局的ff_xxx_decoder变量,然后调用avcodec_register()函数添加到解码器列表中。

    #define REGISTER_DECODER(X, x)                                          
        {                                                                  
            extern AVCodec ff_##x##_decoder;                                
            if (CONFIG_##X##_DECODER)                                      
                avcodec_register(&ff_##x##_decoder);                        
        }

    3. 在libavcodec/Makefile中添加目标文件
    将.c文件名替换为.o
    OBJS-$(CONFIG_QSV)              += qsvdec.o
    OBJS-$(CONFIG_QSV)              += qsvenc.o
    OBJS-$(CONFIG_QSVAVC_DECODER)              += qsvdec.o
    OBJS-$(CONFIG_QSVAVC_ENCODER)              += qsvenc.o
    $(CONFIG_XXX)在./configure时生成的config.mak中定义

    4. 修改configure文件,使编解码器可以在./configure时禁用和启用
    这个步骤是网上一些文章中没有的。

    搜索show_help()函数,添加./configure --help时的帮助显示,非必须。
    --enable-qsv           enable codecs via Intel Media SDK

    在EXTERNAL_LIBRARY_LIST变量中添加qsv,否则./configure --enable-qsv会提示没有这个选项。另外,./configure会根据此生成config.h的#define CONFIG_QSV 1和config.mak的CONFIG_QSV=yes。

    添加依赖关系,将qsvavc_decoder/qsvavc_encoder和--enable-qsv的配置项关联起来。
    可以搜索“libx264_encoder_deps”,在后面添加。
    qsvavc_decoder_deps="qsv"
    qsvavc_encoder_deps="qsv"
    qsvmpeg2_decoder_deps="qsv"
    qsvvc1_decoder_deps="qsv"

    添加依赖库的检查。可以搜索“enabled libx264”在后面添加。
    enabled qsv             && { check_lib mfxvideo.h MFXInit -lmfxhw64 -lva -lva-drm ||
                                   die "ERROR: Intel Media SDK not found"; }

    5. configure时相关宏定义和环境变量的生成
    config.h
    #define CONFIG_QSV 1
    #define CONFIG_QSVAVC_DECODER 1
    #define CONFIG_QSVMPEG2_DECODER 1
    #define CONFIG_QSVVC1_DECODER 1
    #define CONFIG_BINTEXT_DECODER 1

    config.mak
    CONFIG_QSV=yes
    CONFIG_QSVAVC_DECODER=yes
    CONFIG_QSVMPEG2_DECODER=yes
    CONFIG_QSVVC1_DECODER=yes
    CONFIG_BINTEXT_DECODER=yes

    $ALL_COMPONENTS -> $DECODER_LIST -> find_things() 通过sed提取allcodecs.c中的编码解码器,添加到$ALL_COMPONENTS列表中。

    configure -> check_deps() $ALL_COMPONENTS 默认为yes -> do_check_deps()根据qsvavc_decoder_deps的依赖关系检测,disable不符合依赖关系的。qsvavc_decoder的依赖设置为qsvavc_decoder_deps="qsv",configure时不添加--enable-qsv参数,qsvavc_decoder的值先设置为yes,do_check_deps()时检测不满足依赖关系,将qsvavc_decoder的值改为no。

    configure -> print_config() 读取$ALL_COMPONENTS每项的值,在config.h或config.mak中生成相应的宏定义或环境变量。如qsvavc_decoder项的值为no,生成#define CONFIG_QSVAVC_DECODER 0,config.mak中的CONFIG_QSVAVC_DECODER=yes被注掉。
    map 'eval echo "$v ${$v:-no}"' "$@"

    如果qsvavc_decoder_deps="qsv"没有被正确添加,会生成#define CONFIG_QSVAVC_DECODER 1和CONFIG_QSVAVC_DECODER=yes,而导致相应模块被误编译,但关联库和头文件的搜索路径未添加,从而会导致编译错误。








  • 相关阅读:
    web框架开发-Django模型层(1)之ORM简介和单表操作
    web框架开发-模板层
    生产者-消费者模式
    不变模式
    SynchronousQueue
    ThreadLocal
    锁的优化以及Java虚拟机对锁优化所做的努力
    随机数据结构:跳表(SkipList)
    数据共享通道:BlockingQueue
    CopyOnWriteArrayList
  • 原文地址:https://www.cnblogs.com/techsunny/p/3806316.html
Copyright © 2011-2022 走看看