在看ffmpeg自带example中的encoder_video.c的源码,遇到的第一个ffmpeg函数就是avcodec_find_encoder_by_name,最后跳转到av_codec_iterate函数,函数内部code_list的AVCodec数组,搜索整个目录发现只有在libavcodec/allcodes.c中定义为:
1 2 3 4 5 6 7 8 9 #if CONFIG_OSSFUZZ AVCodec * codec_list[] = { NULL , NULL , NULL }; #else #include "libavcodec/codec_list.c" #endif
显然是走到else分支,但是codec_list.c文件却没有找到。最后发现竟然是在./configure的时候生成的。 在configure文件中,搜到如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 ... find_things_extern(){ thing=$1 pattern=$2 file=$source_path/$3 out=${4:-$thing} sed -n "s/^[^#]*extern.*$pattern *ff_\([^ ]*\)_$thing;/\1_$out/p" "$file" } find_filters_extern(){ file=$source_path/$1 sed -n 's/^extern AVFilter ff_[avfsinkrc]\{2,5\}_\([[:alnum:]_]\{1,\}\);/\1_filter/p' $file } FILTER_LIST=$(find_filters_extern libavfilter/allfilters.c) OUTDEV_LIST=$(find_things_extern muxer AVOutputFormat libavdevice/alldevices.c outdev) INDEV_LIST=$(find_things_extern demuxer AVInputFormat libavdevice/alldevices.c indev) MUXER_LIST=$(find_things_extern muxer AVOutputFormat libavformat/allformats.c) DEMUXER_LIST=$(find_things_extern demuxer AVInputFormat libavformat/allformats.c) ENCODER_LIST=$(find_things_extern encoder AVCodec libavcodec/allcodecs.c) DECODER_LIST=$(find_things_extern decoder AVCodec libavcodec/allcodecs.c) CODEC_LIST=" $ENCODER_LIST $DECODER_LIST " ... # generate the lists of enabled components print_enabled_components(){ file=$1 struct_name=$2 name=$3 shift 3 echo "static const $struct_name * const $name[] = {" > $TMPH for c in $*; do if enabled $c; then case $name in filter_list) eval c=\$full_filter_name_${c%_filter} ;; indev_list) c=${c%_indev}_demuxer ;; outdev_list) c=${c%_outdev}_muxer ;; esac printf " &ff_%s,\n" $c >> $TMPH fi done if [ "$name" = "filter_list" ]; then for c in asrc_abuffer vsrc_buffer asink_abuffer vsink_buffer; do printf " &ff_%s,\n" $c >> $TMPH done fi echo " NULL };" >> $TMPH cp_if_changed $TMPH $file } print_enabled_components libavfilter/filter_list.c AVFilter filter_list $FILTER_LIST print_enabled_components libavcodec/codec_list.c AVCodec codec_list $CODEC_LIST print_enabled_components libavcodec/parser_list.c AVCodecParser parser_list $PARSER_LIST print_enabled_components libavcodec/bsf_list.c AVBitStreamFilter bitstream_filters $BSF_LIST print_enabled_components libavformat/demuxer_list.c AVInputFormat demuxer_list $DEMUXER_LIST print_enabled_components libavformat/muxer_list.c AVOutputFormat muxer_list $MUXER_LIST print_enabled_components libavdevice/indev_list.c AVInputFormat indev_list $INDEV_LIST print_enabled_components libavdevice/outdev_list.c AVOutputFormat outdev_list $OUTDEV_LIST print_enabled_components libavformat/protocol_list.c URLProtocol url_protocols $PROTOCOL_LIST
看到以上代码,舒了一口气,codec_list.c终于找到了。正则表达式去查找libavcodec/allcodecs.c中声明的encoder和decoder,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 ... extern AVCodec ff_a64multi_encoder;extern AVCodec ff_a64multi5_encoder;extern AVCodec ff_aasc_decoder;extern AVCodec ff_aic_decoder;extern AVCodec ff_alias_pix_encoder;extern AVCodec ff_alias_pix_decoder;extern AVCodec ff_agm_decoder;extern AVCodec ff_amv_encoder;extern AVCodec ff_amv_decoder;extern AVCodec ff_anm_decoder;extern AVCodec ff_ansi_decoder;extern AVCodec ff_apng_encoder;extern AVCodec ff_apng_decoder;extern AVCodec ff_arbc_decoder;extern AVCodec ff_argo_decoder;extern AVCodec ff_asv1_encoder;extern AVCodec ff_asv1_decoder;extern AVCodec ff_asv2_encoder;extern AVCodec ff_asv2_decoder;extern AVCodec ff_aura_decoder;extern AVCodec ff_aura2_decoder;extern AVCodec ff_avrp_encoder;extern AVCodec ff_avrp_decoder;extern AVCodec ff_avrn_decoder;extern AVCodec ff_avs_decoder;extern AVCodec ff_avui_encoder;extern AVCodec ff_avui_decoder;extern AVCodec ff_ayuv_encoder;extern AVCodec ff_ayuv_decoder;extern AVCodec ff_bethsoftvid_decoder;extern AVCodec ff_bfi_decoder;extern AVCodec ff_bink_decoder;extern AVCodec ff_bitpacked_decoder;extern AVCodec ff_bmp_encoder;...
题外话插一句:对我而言,开源项目认真看了的项目是tensorflow lite,MACE和MNN,最近才开始认真阅读ffmpeg的源码,但给我带来的冲击远比其他开源项目大,感慨c原来也可以这么玩。