ffmpeg configure 研究1-命令行参数的分析


author: hjjdebug

date: 2025年 02月 14日 星期五 17:16:12 CST

description: ffmpeg configure 研究1

./configure 命令行参数的分析


文章目录

    • [1 configure 对命令行参数的分析,在4019行](#1 configure 对命令行参数的分析,在4019行)
      • [1.1 函数名称: is_in](#1.1 函数名称: is_in)
      • [1.2. 函数名称: enable](#1.2. 函数名称: enable)
      • [1.3. 函数名称: set_all](#1.3. 函数名称: set_all)
    • [2 执行退出判断的关键代码:](#2 执行退出判断的关键代码:)
      • [2.1. 函数名称: map](#2.1. 函数名称: map)
      • [2.2 函数名称: die_license_disabled](#2.2 函数名称: die_license_disabled)
      • [2.3 函数名称 enabled()](#2.3 函数名称 enabled())
    • [3. 小测试代码](#3. 小测试代码)
    • [4.执行结果 ./1.sh](#4.执行结果 ./1.sh)
    • 5.小结:
      • [小结1: 命令行参数分析过程概括.](#小结1: 命令行参数分析过程概括.)
      • [小结2: bash脚本的本质是什么?](#小结2: bash脚本的本质是什么?)

详细分析了 ffmpeg 下执行
./configure --enable-libx264
libx264 is gpl and --enable-gpl is not specified.
程序退出的过程

如果说在命令行上有 --enable-libx264 而没有 --enable-gpl 就退出,

用c 写也就寥寥几句,

libx264_enable=false,gpl_enable=fale;

for(int i=0;i<argc;i++)

{

if(strcmp(arg[i],"--enable-libx264")0) libx264_enable=true;
if(strcmp(arg[i],"--enable-gpl")0) gpl_enable=true;
}
if(libx264_enabletrue && gpl_enablefalse) exit(1)

如果用bash 又应该怎么写呢?

如果只是实现上边的功能,bash 也可以写的很简单, 但在configure 文件中就不是那样写了.

而是有一个复杂的架构,

为什么?因为它要支持一些复杂的功能.

所以该博客就是来了解这个简单的功能是如何在复杂的架构上实现的.

让我们能窥斑见豹. 别被它庞大的架构吓唬注了.

这些是bash编程最基本的东西, 就从此开始吧.

1 configure 对命令行参数的分析,在4019行

for opt do

因为 opt 后面没有 in 参数, 实际上就是 in " @ " , 代码处于顶层 , @",代码处于顶层, @",代码处于顶层,@就是命令行参数,此时

$opt = --enable-libx264

case 语句会匹配到4087行

--enable-?|--disable-? )

eval ( e c h o " (echo " (echo"opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g')

if is_in option COMPONENT_LIST; then

test $action = disable && action=unset

eval action (toupper {option%s})_LIST

elif is_in option CMDLINE_SELECT; then

action option

else

die_unknown $opt

fi

bash 在每次执行命令前要进行8大变换. 其是也是很简单的.

大括号扩展 {} , 把形如 {1...5} 扩展为 1 2 3 4 5

波浪线扩展 ~ , 把~扩展为你的家目录

变量扩展 , 简单方式就是 {} , 简单方式就是 ,简单方式就是var样式, 就是变量引用和变量替换

算术扩展 $(()) , 数学运算在这里进行

命令替换 $()或 ``, 这里可以调用命令,先执行命令

分词分割 IFS , 按照空格,tab,回车来分割成单词

路径扩展 * ? [] , 把*展开匹配任意字符,?匹配0或1个字符,[]匹配指定字符

引号去除 , 去除其中的双引号,单引号

把该行信息都收拾一遍叫扫描,然后再交给bash去执行命令,

eval ( e c h o " (echo " (echo"opt" | sed 's/--/action=/;s/-/ option=/;s/-//g')
eval 语句会进行2次扫描. 即扩展了一遍还要再扩展一遍,所以有$$(...)之类的写法
执行第一遍扫描,进行变量扩展
eval $(echo --enable-libx264 | sed 's/--/action=/;s/-/ option=/;s/-/
/g')

,进行命令替换

eval action=enable option=libx264

运行eval命令,执行第二遍扫描,(此例第一遍已经扩展干净了,第二遍没有要改变的.)

action=enable option=libx264

这条语句交给bash执行,就是定义了2个变量,并赋值.

elif is_in option CMDLINE_SELECT; then

$action o p t i o n l i b x 264 在 option libx264 在 optionlibx264在CMDLINE_SELECT 中被发现,会执行 enable libx264 函数


1.1 函数名称: is_in

输入参数: 列表

输出参数:

返回值: 0(成功), 1(失败,假)

描述: 把第一个参数作为值, 依次与后续参数做比较,如果想等,返回成功,全部不成功,返回失败.


is_in(){

value=$1 # 第一个参数为value

shift

for var in KaTeX parse error: Expected 'EOF', got '#' at position 7: *; do #̲ 后续参数与value相比

$var = KaTeX parse error: Expected 'EOF', got '\&' at position 9: value \] \&̲\& return 0 # 相同...value被扩展为libx264, $CMDLINE_SELECT 被扩展为一堆字符串, 其中包含libx264, 所以其返回为成功. $action $option 被扩展为: enable libx264 *** ** * ** *** #### 1.2. 函数名称: enable 输入参数: 列表 输出参数: 无 返回值: 无 描述: 把参数都做为变量,其值设置为"yes" *** ** * ** *** enable(){ set_all yes $\* } 执行结果, 把libx264 设置为了 yes, 等价与 libx264=yes *** ** * ** *** #### 1.3. 函数名称: set_all 输入参数: 列表 输出参数: 无 返回值: 无 描述: 把第一个参数作为value, 其余的参数都作为变量用$value赋值 *** ** * ** *** set_all(){ value=$1 # 第一个参数为value, shift # 移除第一个参数 for var in $\*; do eval v a r = var= var=value # 其余参数都设置为$value done } 注意: 调试时打印pr value 是没有意义的, pr $value才是对变量的引用. ### 2 执行退出判断的关键代码: map "die_license_disabled gpl" $EXTERNAL_LIBRARY_GPL_LIST $EXTERNAL_LIBRARY_GPLV3_LIST $EXTERNAL_LIBRARY_GPL_LIST 变量在1721行有定义,包括libx264,libx265及其它模块 该语句功能. 检查一系列模块,如果enable 了模块而没有enable gpl, 就退出. *** ** * ** *** #### 2.1. 函数名称: map 输入参数: 列表 输出参数: 无 描述: 把第一个参数作为命令, 后续参数依次作为$v参数,来执行第一条命令 *** ** * ** *** map(){ m=$1 # 把die_license_disabled gpl 赋值给m shift for v; do eval $m; done # 把后面的参数依次送给v, 执行 $m,即执行die_license_disabled gpl 函数 } *** ** * ** *** #### 2.2 函数名称: die_license_disabled 输入参数: 函数调用参数 1 , 全局参数 1, 全局参数 1,全局参数v 输出参数: 无 功能描述: 判断第1个参数(对应"gpl","nonfree")是否enabled,如果已经enabled,则正常退出; 否则判断$v 参数是否 enabled, 如果为真则打印错误信息并退出(die 函数) 注意: 不满足条件时会退出程序. *** ** * ** *** die_license_disabled() { enabled $1 \|\| { enabled KaTeX parse error: Expected 'EOF', got '\&' at position 3: v \&̲\& die "v is $1 and --enable-$1 is not specified."; } } 命令可以作为map 的第一个参数. 该命令接受的参数是$1 和 $v *** ** * ** *** #### 2.3 函数名称 enabled() 输入参数: 一个参数 输出参数: 无 返回值: 0或1 描述: 对参数$1 判断其值是否是"yes" *** ** * ** *** enabled(){ test "${1#!}" = "$1" \&\& op="=" \|\| op="!=" # 该句设置op为等号或不等号 eval test "x$${1#!}" $op "xyes" # 运行test返回真值或假值. } ${1#!}是$1变量去除从开始到!止部分,$1无!则不会去除任何东西. ### 3. 小测试代码 为了对enabled() 函数,die() 及颜色设置有更深入理解,我写了如下测试函数 $ cat 1.sh #!/bin/bash enabled(){ test "${1#!}" = "$1" && op="=" || op="!=" # 根据第一个参数是否首字符为!为op赋值=或者!= eval test "x\$${1#!}" $op "xyes" # 测试变量的值是否为yes } if test -t 1 && which tput >/dev/null 2>&1; then ncolors=$(tput colors) if test -n "$ncolors" && test $ncolors -ge 8; then bold_color=$(tput bold) warn_color=$(tput setaf 3) # 设置前景色为黄(3) error_color=$(tput setaf 1) # 设置前景色为红(1) , set attr foregroud reset_color=$(tput sgr0) # 恢复颜色, set groud 0 fi # 72 used instead of 80 since that's the default of pr ncols=$(tput cols) fi : ${ncols:=72} # :就是空操作, 退出总是成功 ${var:=}, 如果ncols 没有值,就给72,否则保持不变 logfile="1.log" log(){ echo "$@" >> $logfile } die(){ log "$@" echo "$error_color$bold_color$@$reset_color" # 设置红色,加重的颜色,显示$@ 然后颜色再恢复 } abc=yes enabled abc && echo "abc enabled" || echo "abc not enabled" enabled abb && echo "abb enabled" || echo "abb not enabled" die "I hope this is red" ### 4.执行结果 $ ./1.sh abc enabled abb not enabled I hope this is red ### 5.小结: #### 小结1: 命令行参数分析过程概括. 对于 --enable-libx64 参数而言,它是一个动词-名词的结构,首先用sed将它分为2部分. 把动词作为函数,把名字作为参数执行函数, 实现把名词作为变量进行赋值. 命令行参数分析完后, 对变量进行数值判断,不满足条件则退出程序. #### 小结2: bash脚本的本质是什么? bash脚本命令. 就是一个命令的集合体. 命令就是你在控制台下与机器交互输入的命令 你在命令行下所做的操作, 用bash脚本都可以完成. 命令是带参数的. 参数是可以用变量来存储的. 参数经过8大扩展再传递给命令 引入变量和函数可以简化人机的接口,使少敲几个字符就给计算机说明白了. 函数也是由命令集合来构成,支持参数传递,为完成特定功能而编写. 变量和函数的灵活性也增加了代码的复杂性. 所以bash脚本就是不断的执行预定的命令. 不用你在控制台下手敲了. 常在bash下工作的人, 用脚本编程简化维护等工作也是很自然的了.

相关推荐
喵手13 小时前
Java实现视频格式转换的完整指南:从FFmpeg到纯Java方案!
java·开发语言·ffmpeg
钰爱&13 小时前
【Qt】ffmpeg编码—存储(H264)
c++·qt·ffmpeg
yunteng52113 小时前
音视频(二)ffmpeg编译及推流
ffmpeg·音视频·h264·媒体推流
DogDaoDao19 小时前
从零开始:Windows 系统中 PowerShell 配置 FFmpeg 的详细步骤
windows·ffmpeg·音视频·ffplay·powershell·视频直播·ffprobe
m晴朗2 天前
ffmpeg(1)-图片相关知识
ffmpeg·yuv·rgb·像素
邪恶的贝利亚2 天前
学习ffmpeg-从了解开始
学习·ffmpeg
xiao--xin3 天前
使用ProcessBuilder执行FFmpeg命令,进程一直处于阻塞状态,一直没有返回执行结果
java·笔记·ffmpeg·个人开发·缓冲区·进程阻塞
音视频牛哥3 天前
nginx-rtmp-module之ngx_rtmp_live_module.c代码详解
运维·c语言·nginx·ffmpeg·大牛直播sdk·nginx rtmp代码·nginx rtmp服务器
肥肥呀呀呀4 天前
Flutter视频播放优化
ffmpeg·音视频
CrabKA4 天前
FFmpeg开发学习:音视频封装
学习·ffmpeg·音视频