当前位置: 首页 > news >正文

ffmpeg 中config 文件一些理解

依赖检查

config中看到最多的是:

...
nvenc_deps="ffnvcodec"
nvenc_deps_any="libdl LoadLibrary"
nvenc_encoder_deps="nvenc"
...
h264_crystalhd_decoder_select="crystalhd h264_mp4toannexb_bsf h264_parser"
h264_cuvid_decoder_deps="cuvid"
h264_cuvid_decoder_select="h264_mp4toannexb_bsf"
h264_mediacodec_decoder_deps="mediacodec"
h264_mediacodec_decoder_select="h264_mp4toannexb_bsf h264_parser"
h264_mf_encoder_deps="mediafoundation"
h264_mmal_decoder_deps="mmal"
h264_nvenc_encoder_deps="nvenc"
h264_nvenc_encoder_select="atsc_a53"
...

这个主要用来做依赖检查,比如上面的nvenc_deps="ffnvcodec"表示:
nvenc这个模块依赖ffnvcodec,其余以此类推。

依赖类型:

_deps:必须全部满足的依赖(如 flv_decoder 依赖 h264_decoder)。
_deps_any:只需满足任意一个的依赖。
_conflict:不能同时存在的冲突依赖。
_select:强制启用的依赖(如 flv_decoder 强制启用 h264_parser)。
_suggest:建议启用的可选依赖。
_if 和 _if_any:条件启用的依赖。

依赖检查函数

核心检查在下边:

  • 首先我们看到list列表是从相关的allxxx.c文件中获取到的,然后添加到对应的list中
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
"
PARSER_LIST=$(find_things_extern parser AVCodecParser libavcodec/parsers.c)
BSF_LIST=$(find_things_extern bsf AVBitStreamFilter libavcodec/bitstream_filters.c)
HWACCEL_LIST=$(find_things_extern hwaccel AVHWAccel libavcodec/hwaccels.h)
PROTOCOL_LIST=$(find_things_extern protocol URLProtocol libavformat/protocols.c)
...
AVCODEC_COMPONENTS_LIST="$BSF_LIST$DECODER_LIST$ENCODER_LIST$HWACCEL_LIST$PARSER_LIST
"
...check_deps $CONFIG_LIST       \$CONFIG_EXTRA      \$HAVE_LIST         \$ALL_COMPONENTS    \
# The cfg loop is very hot (several thousands iterations), and in bash also
# potentialy quite slow. Try to abort the iterations early, preferably without
# calling functions. 70%+ of the time cfg is already done or without deps.
check_deps(){for cfg; do# 避免重复检查或检测循环依赖eval [ x\$${cfg}_checking = xdone ] && continueeval [ x\$${cfg}_checking = xinprogress ] && die "Circular dependency for $cfg."# 获取组件的各种依赖配置eval "dep_all=\$${cfg}_depsdep_any=\$${cfg}_deps_anydep_con=\$${cfg}_conflictdep_sel=\$${cfg}_selectdep_sgs=\$${cfg}_suggestdep_ifa=\$${cfg}_ifdep_ifn=\$${cfg}_if_any"# most of the time here $cfg has no deps - avoid costly no-op workif [ "$dep_all$dep_any$dep_con$dep_sel$dep_sgs$dep_ifa$dep_ifn" ]; theneval ${cfg}_checking=inprogress# 递归检查当前组件的所有依赖#递归策略:先检查当前组件的所有依赖项(如 A 依赖 B,则先检查 B 的依赖),确保依赖链上的所有组件状态都被确定。set -- $cfg "$dep_all" "$dep_any" "$dep_con" "$dep_sel" "$dep_sgs" "$dep_ifa" "$dep_ifn"check_deps $dep_all $dep_any $dep_con $dep_sel $dep_sgs $dep_ifa $dep_ifncfg=$1; dep_all=$2; dep_any=$3; dep_con=$4; dep_sel=$5 dep_sgs=$6; dep_ifa=$7; dep_ifn=$8# 条件启用:若 dep_ifa 中所有项都启用,则弱启用当前组件[ -n "$dep_ifa" ] && { enabled_all $dep_ifa && enable_weak $cfg; }[ -n "$dep_ifn" ] && { enabled_any $dep_ifn && enable_weak $cfg; }# 弱启用(enable_weak):仅在其他条件允许时启用,否则保持禁用。# 必须依赖:所有 _deps 必须满足enabled_all  $dep_all || { disable_with_reason $cfg "not all dependencies are satisfied: $dep_all"; }# 可选依赖:_deps_any 中至少满足一个enabled_any  $dep_any || { disable_with_reason $cfg "not any dependency is satisfied: $dep_any"; }# 冲突检查:_conflict 中所有项必须禁用disabled_all $dep_con || { disable_with_reason $cfg "some conflicting dependencies are unsatisfied: $dep_con"; }# 强制依赖:_select 中所有项必须启用disabled_any $dep_sel && { disable_with_reason $cfg "some selected dependency is unsatisfied: $dep_sel"; }# 若当前组件启用,则递归启用 _select 和 _suggest 中的依赖enabled $cfg && enable_deep_weak $dep_sel $dep_sgs# 收集额外库依赖for dep in $dep_all $dep_any $dep_sel $dep_sgs; do# filter out library deps, these do not belong in extralibsis_in $dep $LIBRARY_LIST && continueenabled $dep && eval append ${cfg}_extralibs ${dep}_extralibsdonefieval ${cfg}_checking=donedone
}

依赖关系示例

以 FLV 解码器(flv_decoder)为例,假设其依赖配置如下:

flv_decoder_deps="h264_decoder aac_decoder"
flv_decoder_select="h264_parser"
flv_decoder_suggest="zlib"

必须依赖:h264_decoder 和 aac_decoder 必须同时启用。
强制启用:若 flv_decoder 启用,则 h264_parser 也会被强制启用。
建议依赖:zlib 可选,若可用则更好(如用于压缩数据)。

函数调用流程
初始化:配置脚本通过 enabled 等函数设置初始组件状态(如用户通过 --enable-xxx 指定)。
调用 check_deps:传入所有组件名,开始递归检查。
递归验证:从叶子节点(无依赖的组件)开始,逐层向上验证依赖关系。
状态传播:根据依赖结果,启用或禁用组件,并记录原因(如 “缺少 xyz 依赖”)。

命令参数–enable-xxx

这个处理在config :--enable-*=*|--disable-*=*)中处理。

–enable-?:匹配以 --enable- 开头,后跟至少一个字符的参数(如 --enable-libx264)。
–disable-?
:匹配以 --disable- 开头,后跟至少一个字符的参数(如 --disable-debug)

for opt dooptval="${opt#*=}"case "$opt" in--extra-ldflags=*)add_ldflags $optval;;...--enable-?*|--disable-?*)# 使用 sed 命令将参数转换为 shell 变量赋值语句:# --enable-libx264 → action=enable option=libx264# --disable-debug → action=disable option=debug# 通过 eval 执行转换后的语句,将 action 和 option 设为当前 shell 变量。eval $(echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g')# 判断是否在$COMPONENT_LIST中if is_in $option $COMPONENT_LIST; thentest $action = disable && action=unseteval $action \$$(toupper ${option%s})_LISTelif is_in $option $CMDLINE_SELECT; then$action $optionelsedie_unknown $optfi;;...--help|-h) show_help;;--quiet|-q) quiet=yes;;--fatal-warnings) enable fatal_warnings;;--libfuzzer=*)libfuzzer_path="$optval";;*)optname="${opt%%=*}"optname="${optname#--}"optname=$(echo "$optname" | sed 's/-/_/g')if is_in $optname $CMDLINE_SET; theneval $optname='$optval'elif is_in $optname $CMDLINE_APPEND; thenappend $optname "$optval"elsedie_unknown $optfi;;esac
done

组件列表处理分开解析:

if is_in $option $COMPONENT_LIST; thentest $action = disable && action=unseteval $action \$$(toupper ${option%s})_LIST

COMPONENT_LIST:包含 FFmpeg 中可独立配置的组件类型(如 encoders, decoders, filters 等)。

COMPONENT_LIST="$AVCODEC_COMPONENTS$AVDEVICE_COMPONENTS$AVFILTER_COMPONENTS$AVFORMAT_COMPONENTS
"

逻辑:
若 option 是组件类型(如 encoders),则:
若为 disable 操作,将其转换为 unset(从列表中移除)。
通过 eval 动态操作对应的大写组件列表变量:
例如 --enable-encoders → enable ENCODERS_LIST
例如 --disable-decoders → unset DECODERS_LIST

常规选项处理

elif is_in $option $CMDLINE_SELECT; then$action $option

CMDLINE_SELECT:包含可直接通过命令行启用 / 禁用的选项列表(如 debug, shared, static 等)。
逻辑:直接执行 action(enable 或 disable)操作对应的选项

示例说明

示例 1:启用所有编码器

--enable-encoders

转换为 action=enable option=encoders
由于 encoders 在 COMPONENT_LIST 中,执行 enable ENCODERS_LIST
最终启用所有编码器(通过修改 ENCODERS_LIST 变量)

示例 2:禁用调试模式

--disable-debug

转换为 action=disable option=debug
由于 debug 在 CMDLINE_SELECT 中,执行 disable debug
最终禁用调试模式(通过设置 enable_debug=no)

示例 3:启用 libx264 支持

--enable-libx264

转换为 action=enable option=libx264
由于 libx264 在 CMDLINE_SELECT 中,执行 enable libx264
最终启用 libx264 外部库支持

命令参数—enable-=|–disable-=)

-enable-=
匹配以 --enable- 开头,后跟任意字符串,再以 = 连接另一个任意字符串的参数.
案例:

    --enable-decoder=libx264 \--enable-decoder=libx265 \

config 中处理代码:

        --enable-*=*|--disable-*=*)# ${opt%%=*}:提取参数等号前的部分(如 --enable-encoder → --enable-encoder)。# sed 替换:将 --enable-encoder 转换为 action=enable thing=encoder,并通过 eval 设置为变量。eval $(echo "${opt%%=*}" | sed 's/--/action=/;s/-/ thing=/')# ${thing}s:将组件类型转为复数形式(如 encoder → encoders)is_in "${thing}s" $COMPONENT_LIST || die_unknown "$opt"# 态获取组件列表:将组件类型转为大写并添加 _LIST 后缀(如 encoder → ENCODERS_LIST)。# 示例:thing=encoder → list=$ENCODERS_LIST,获取所有编码器列表。eval list=\$$(toupper $thing)_LIST# 将逗号分隔的多个组件名转为正则表达式(如 h264,mp3 → h264_encoder|mp3_encoder)。# 添加 _${thing} 后缀以匹配内部组件命名(如 h264 → h264_encoder)。name=$(echo "${optval}" | sed "s/,/_${thing}|/g")_${thing}#filter 函数:从 $list 中筛选出匹配 $name 的组件。# 示例:若 name=h264_encoder,则从 ENCODERS_LIST 中筛选出 h264_encoderlist=$(filter "$name" $list)# 空检查:若未找到匹配组件,发出警告。# 依赖检查:若启用组件,先检查其依赖是否满足(warn_if_gets_disabled)。# 执行操作:调用 enable 或 disable 函数处理筛选出的组件。[ "$list" = "" ] && warn "Option $opt did not match anything"test $action = enable && warn_if_gets_disabled $list$action $list;;

示例说明

--enable-encoder=h264

参数解析:
action=enable
thing=encoder
list=$ENCODERS_LIST(所有编码器列表)
name=h264_encoder
执行结果:
从 ENCODERS_LIST 中筛选出 h264_encoder。
执行 enable h264_encoder,启用 H.264 编码器。

--disable-filter=scale,transpose

参数解析:
action=disable
thing=filter
list=$FILTERS_LIST(所有滤镜列表)
name=scale_filter|transpose_filter
执行结果:
从 FILTERS_LIST 中筛选出 scale_filter 和 transpose_filter。
执行 disable scale_filter transpose_filter,禁用这两个滤镜。

http://www.dtcms.com/a/270383.html

相关文章:

  • Flutter基础(前端教程②-卡片列表)
  • study_WebView介绍
  • MYSQL进阶知识
  • 在keil中使用stlink下载程序报错Invalid ROM Table
  • Day07_C语言IO进程线程(重难点)
  • TensorFlow 和PyTorch的全方位对比和选择建议
  • Latex几种常用的花体
  • [2-02-02].第04节:环境搭建 - Linux搭建ES集群环境
  • [RPA] 影刀RPA基本知识
  • Kafka多组消费:同一Topic,不同Group ID
  • NV298NV312美光固态闪存NW639NW640
  • 基于mysqlfrm工具解析mysql数据结构文件frm表结构和数据库版本信息
  • 【Nginx】Nginx代理WebSocket
  • 扣子Coze远程连接数据库插件
  • C语言基础(1)
  • 【C++】AVL树底层思想 and 大厂面试
  • Python 的内置函数 slice
  • 为什么elementui的<el-table-column label=“名称“ prop=“name“ label不用写成:label
  • RS-232协议与RS485协议详解
  • [Backlog] 命令行界面CLI vs Web界面及服务端
  • 快手电商要投入多少钱?快手电商入驻条件和费用
  • 分布式无线工业数据采集终端应用场景简析
  • POI报表
  • Paimon本地表查询引擎LocalTableQuery详解
  • Mybits-plus 表关联查询,嵌套查询,子查询示例演示
  • 使用策略模式 + 自动注册机制来构建旅游点评系统的搜索模块
  • 音频被动降噪技术
  • Spring AI:ETL Pipeline
  • STM32-USART
  • 图像噪点消除:用 OpenCV 实现多种滤波方法