在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,而致使相應模塊被誤編譯,但關聯庫和頭文件的搜索路徑未添加,從而會致使編譯錯誤。






相關文章
相關標籤/搜索