ffmpeg configure 研究2:分析屏幕输出及文件输出的具体过程
author: hjjdebug
date: 2025年 02月 17日 星期一 16:57:55 CST
description: ffmpeg configure 研究2
分析屏幕输出及文件输出的具体过程
文章目录
- 0. 执行./configure 命令
- 1. sed: can't read 信息是从哪里来的 ?
- 1.1 find_filters_extern()
- 1.2 find_things_extern()
- 2. 屏幕输出信息的来源
- 2.1,查找 prefix 变量在哪里定义的?
- 2.2 函数名称: set_default
- 2.3, 查找其它变量的定义.
- 3 configure 中创建的文件具体创建过程是怎样的?
- 3.1 第一步,要找到变量定义.
- 3.2. 读懂函数代码.
- 3.3 函数名称: print_config
- 3.4 函数名称: cp_if_changed
- 3.5 函数名称: print_enabled_components
- 4 configure 对 Makefile 的影响
0. 执行./configure 命令
在家目录下创建目录t1, 把ffmpeg目录下的 configure 文件copy进去.
在 t1 目录下执行:
cd ~/t1
./configure
sed: can’t read ./libavfilter/allfilters.c: No such file or directory
sed: can’t read ./libavdevice/alldevices.c: No such file or directory
sed: can’t read ./libavdevice/alldevices.c: No such file or directory
sed: can’t read ./libavformat/allformats.c: No such file or directory
sed: can’t read ./libavformat/allformats.c: No such file or directory
sed: can’t read ./libavcodec/allcodecs.c: No such file or directory
sed: can’t read ./libavcodec/allcodecs.c: No such file or directory
sed: can’t read ./libavcodec/parsers.c: No such file or directory
sed: can’t read ./libavcodec/bitstream_filters.c: No such file or directory
sed: can’t read ./libavcodec/hwaccels.h: No such file or directory
sed: can’t read ./libavformat/protocols.c: No such file or directory
install prefix /usr/local
source path .
C compiler gcc
C library glibc
ARCH x86 (generic)
big-endian no
runtime cpu detection yes
standalone assembly yes
x86 assembler nasm
MMX enabled yes
…
运行./configure 后
会惊奇的发现在t1目录下生成了很多文件及目录.
$ tree
.
├── config.asm
├── config.h
├── configure # sh文件本身
├── doc
│ └── config.texi
├── ffbuild
│ ├── config.fate
│ ├── config.log
│ ├── config.mak
│ └── config.sh
├── libavcodec
│ ├── bsf_list.c
│ ├── codec_list.c
│ └── parser_list.c
├── libavdevice
│ ├── indev_list.c
│ └── outdev_list.c
├── libavfilter
│ └── filter_list.c
├── libavformat
│ ├── demuxer_list.c
│ ├── muxer_list.c
│ └── protocol_list.c
├── libavutil
│ └── avconfig.h
├── Makefile
└── tests
└── api
下面我们要阐明3个问题, 出错信息是从哪里来的? 屏幕打印信息从哪里来的? 输出文件是怎样生成的?
1. sed: can’t read 信息是从哪里来的 ?
对应 ./configure 3912 处代码
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)
这里我们看到是调用了2个函数:
1.1 find_filters_extern()
{file=$source_path/$1sed -n 's/^extern AVFilter ff_[avfsinkrc]\{2,5\}_\([[:alnum:]_]\{1,\}\);/\1_filter/p' $file
}
1.2 find_things_extern()
{thing=$1pattern=$2file=$source_path/$3out=${4:-$thing}sed -n "s/^[^#]*extern.*$pattern *ff_\([^ ]*\)_$thing;/\1_$out/p" "$file"
}
很简单,在控制台上执行一下sed命令就知道这些list 是什么内容了.
就是在指定的文件中查找pattern, 满足条件的行被替换内容后输出.保存到不同的变量中
由于t1目录只有一个configure 文件, 没有添加诸如 libavfilter/allfilters.c 文件,所以sed 报错了.
2. 屏幕输出信息的来源
对应 ./configure 7285 处代码. 嗯,bashdb 调试执行太慢了,不能用bashdb 调试了,
在3912设断点等一会能到达,在7285处设断点就慢的没法忍受了.只能放弃,你可以用bash -x -v ./configure 来记录执行的过程
echo “install prefix $prefix”
echo “source path $source_path”
echo “C compiler $cc”
echo “C library $libc_type”
…
2.1,查找 prefix 变量在哪里定义的?
有的变量定义是不太好找的. prefix 变量定义就是这样的.
在bash 中,变量的赋值是通过 a=b 方式进行的,如果是直接定义,可以通过字符串来查找.
但如果变量在函数中定义, 传进去的只是参数, 对参数的引用通过$i 或 $var 进行,则赋值就不能通过字符串直接查找了.
prefix在configure 代码中没有发现直接定义, 即没有prefix=xxx 形式的行.
在3755行 有 prefix_default=“/usr/local”, 与prefix 很接近.
在PATH_LIST 中有 prefix 字符串
由set_default P A T H L I S T , s e t d e f a u l t 函数引用了 PATH_LIST, set_default函数引用了 PATHLIST,setdefault函数引用了PATH_LIST变量,它设置了prefix变量, 具体过程参见函数
2.2 函数名称: set_default
输入参数: 列表
输出: 把列表作为变量名称,为其赋值.
描述: 把xxx_default变量的值送给xxx变量
set_default(){
for opt; do # 对传来的参数列表, 把其default值作为其值, 参数列表都是输出值
eval : ${$opt:=$${opt}_default}
done
}
当枚举到 $opt=prefix
则进行变量扩展后为
- eval : ‘KaTeX parse error: Expected '}', got 'EOF' at end of input: {prefix:=prefix_default}’
再执行一次 eval 命令完成赋值
赋值语句 x x x : = y y y , 当 {xxx:=yyy}, 当 xxx:=yyy,当xxx没有值或为空时,赋值给yyy, 2次扩展.
sh 脚本的难点是函数, 函数也等价于一个命令
configure 有7000多行代码, 包含180个函数, 知道了这180个函数的意思, 也就不怕configure 文件了.
关于具体的函数,以后会慢慢介绍几个关键函数.
2.3, 查找其它变量的定义.
先用grep 查找直接定义,
若找不到则可能是在函数中赋值的,如果代码不长运行较快可以用bashdb辅助查找,也可用bash -x -v输出log记录信息帮助查找
3 configure 中创建的文件具体创建过程是怎样的?
关注config.h 是怎样生成的, 顺便关注一下其它的文件
config.h
代码在7581-7628
向缓冲文件$TMPH 中打印头部信息
cat > $TMPH <<EOF
/* Automatically generated by configure - do not modify! */
#ifndef FFMPEG_CONFIG_H
#define FFMPEG_CONFIG_H
#define FFMPEG_CONFIGURATION "$(c_escape $FFMPEG_CONFIGURATION)"
#省略部分代码....
#define HAVE_MMX2 HAVE_MMXEXT
#define SWS_MAX_FILTER_SIZE $sws_max_filter_size
EOF#省略部分代码....
print_config ARCH_ "$config_files" $ARCH_LIST
print_config HAVE_ "$config_files" $HAVE_LIST
print_config CONFIG_ "$config_files" $CONFIG_LIST \$CONFIG_EXTRA \$ALL_COMPONENTS \
echo "#endif /* FFMPEG_CONFIG_H */" >> $TMPH
echo "endif # FFMPEG_CONFIG_MAK" >> ffbuild/config.makcp_if_changed $TMPH config.h
3.1 第一步,要找到变量定义.
config_files=“$TMPH ffbuild/config.mak doc/config.texi” 3个文件
ARCH_LIST=“aarch64
alpha
arm
avr32
avr32_ap
avr32_uc
bfin
ia64
m68k
mips
mips64
parisc
ppc
ppc64
s390
sh4
sparc
sparc64
tilegx
tilepro
tomi
x86
x86_32
x86_64”
ARCH_LIST 是24种cpu
3.2. 读懂函数代码.
3.3 函数名称: print_config
输入参数: $1, 前缀$2, 输出的文件名称列表$v, 是$@的枚举值, 则\${$v:-no}是其值,默认为no
输出参数: 无
描述. 对$@ 执行显示其配置值信息并通过awk 向文件列表中输出信息print_config(){pfx=$1files=$2 #文件列表shift 2map 'eval echo "$v \${$v:-no}"' "$@" |awk "BEGIN { split(\"$files\", files) } #把文件列表分割为文件{c = \"$pfx\" toupper(\$1); #c变量是前缀和第一列值(即枚举字符串)v = \$2; #v变量是 第2列值,它是yes 或者 no sub(/yes/, 1, v); # 将yes 或no 变成1和0sub(/no/, 0, v);for (f in files) { # 向文件列表中输出内容file = files[f];if (file ~ /\\.h\$/) { # .h 文件, 打印 #define xxx 1 形式printf(\"#define %s %d\\n\", c, v) >>file;} else if (file ~ /\\.asm\$/) { # .asm 文件, 打印 %%define xxx 1形式printf(\"%%define %s %d\\n\", c, v) >>file;} else if (file ~ /\\.mak\$/) { # .mak 文件, 打印xxx 或者!xxxn = -v ? \"\" : \"!\"; # 赋值n 为空或 ‘!'printf(\"%s%s=yes\\n\", n, c) >>file;} else if (file ~ /\\.texi\$/) { # .texi 文件, 打印pre@set xxx yes的形式pre = -v ? \"\" : \"@c \"; # 赋值pre为空或@c yesno = \$2;c2 = tolower(c);gsub(/_/, \"-\", c2);printf(\"%s@set %s %s\\n\", pre, c2, yesno) >>file;}}}"
}
3.4 函数名称: cp_if_changed
输入参数:$1,$2 两个文件名称
输出参数:无
函数功能: 比较2个文件$1,$2是否相同,相同给出提示 "$2 is nuchanged",返回, 不同则进行copy,不提示cp_if_changed(){ cmp -s "$1" "$2" && { test "$quiet" != "yes" && echo "$2 is unchanged"; } && returnmkdir -p "$(dirname $2)"cp -f "$1" "$2"
}
其中9个list 都是由如下命令生成
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
望文生义也可以猜到,例如它从$FILTER_LIST 参数中生成libavfilter/filter_list.c 文件,
使用AVFilter,filter_list 两个关键字
3.5 函数名称: print_enabled_components
输入参数: 第一参数输出文件名, 第二参数结构名称,第三参数一个格式参考关键字,其它为模块名称作为输出文件内容
输出参数: 无
描述: 从一堆信息中,合成一个输出文件, 用printf 打印的print_enabled_components(){file=$1 #输出文件struct_name=$2 #结构名称name=$3 #名称shift 3echo "static const $struct_name * const $name[] = {" > $TMPH # 定义结构名称,向临时文件copyfor c in $*; doif enabled $c; then # 如果变量是enabled , 对输出打印case $name in # 判断输出要求什么格式, 可以进行修饰, 重新赋值给cfilter_list)eval c=\$full_filter_name_${c%_filter};;indev_list)c=${c%_indev}_demuxer;;outdev_list)c=${c%_outdev}_muxer;;esacprintf " &ff_%s,\n" $c >> $TMPH # 打印变量fidoneif [ "$name" = "filter_list" ]; thenfor c in asrc_abuffer vsrc_buffer asink_abuffer vsink_buffer; doprintf " &ff_%s,\n" $c >> $TMPHdonefiecho " NULL };" >> $TMPHcp_if_changed $TMPH $file #跟输出文件不同则copy
}
4 configure 对 Makefile 的影响
Makefile 其时是没有改变的, 但Makefile 有
include ffbuild/config.mak
参考 print_config() 函数,
它同时向3个文件
config_files="$TMPH ffbuild/config.mak doc/config.texi" 打印信息.
其中$TMPH 就是config.h的缓冲文件,
相关文章:
ffmpeg configure 研究2:分析屏幕输出及文件输出的具体过程
author: hjjdebug date: 2025年 02月 17日 星期一 16:57:55 CST description: ffmpeg configure 研究2 分析屏幕输出及文件输出的具体过程 文章目录 0. 执行./configure 命令1. sed: cant read 信息是从哪里来的 ?1.1 find_filters_extern()1.2 find_things_extern() 2. 屏幕输…...
软件内有离线模型,效果也很实用......
今天给大家带来一款超实用的图片画质增强软件,完全不需要联网,随时随地都能用。 图片画质增强 一键增强画质 使用起来也超简单,完全不需要安装。 软件主要有两个功能:图片增强和视频增强。 在使用之前,先确定一下输出…...
Linux下ioctl的应用
文章目录 1、ioctl简介2、示例程序编写2.1、应用程序编写2.2、驱动程序编写 3、ioctl命令的构成4、测试 1、ioctl简介 ioctl(input/output control)是Linux中的一个系统调用,主要用于设备驱动程序与用户空间应用程序之间进行设备特定的输入/…...
如何通过 prometheus-operator 实现服务发现
在之前的章节中,我们讲解了如何编写一个自定义的 Exporter,以便将指标暴露给 Prometheus 进行抓取。现在,我们将进一步扩展这个内容,介绍如何使用 prometheus-operator 在 Kubernetes 集群中自动发现并监控这些暴露的指标。 部署应用 在 Kubernetes 集群中部署我们的自定…...
认识HTML的标签结构
一、HTML的基本概念 1.什么是HTML? ①HTML是描述网页的一种标记语言,也被称为超文本标记语言【并不是一种编程语言】 ②HTML包含了HTML标签和文本内容 ③HTML文档也称为web页面 2.HTML的标签 HTML的标签通常成对出现,HTML文档由标签和受…...
MySQL 之INDEX 索引(Index Index of MySQL)
MySQL 之INDEX 索引 1.4 INDEX 索引 1.4.1 索引介绍 索引:是排序的快速查找的特殊数据结构,定义作为查找条件的字段上,又称为键 key,索引通过存储引擎实现。 优点 大大加快数据的检索速度; 创建唯一性索引,保证数…...
基于flask+vue的租房信息可视化系统
✔️本项目利用 python 网络爬虫抓取某租房网站的租房信息,完成数据清洗和结构化,存储到数据库中,搭建web系统对各个市区的租金、房源信息进行展示,根据各种条件对租金进行预测。 1、数据概览 将爬取到的数据进行展示ÿ…...
开源Web主机控制面板ISPConfig配置DNS
ISPConfig 是一个开源的 Web 主机控制面板,特别适合用于构建虚拟主机环境。 它拥有强大的 DNS 管理功能,可以: 管理 DNS 区域 (主区域、辅助区域)。支持多种记录类型。DNSSEC 支持。远程 DNS 服务器管理。 ISPConfig 优点在于专为主机服务设…...
【Python项目】信息安全领域中语义搜索引擎系统
【Python项目】信息安全领域中语义搜索引擎系统 技术简介:采用Python技术、MYSQL数据库等实现。 系统简介:系统主要是围绕着语义搜索展开的,要将输入的文字在爬取数据时能够通过深层次的内涵理解,来更好的查找到与之相关的精准信息…...
网站搭建基本流程
需求分析: 实现网站搭建的过程:首先进行网站的需求性分析 网站可分为前台系统和后台系统,由不同的功能拆分为不同的模块 如下是一个电商网站可以拆分出的模块: 在编写代码前,我们要先对网站进行架构,通过…...
mysql 存储空间增大解决方案
一:查询数据库中表占比比较多的表 SELECT table_name AS "Tables", round(((data_length index_length) / 1024 / 1024), 2) AS "Size (MB)" FROM information_schema.tables WHERE table_schema "自己的数据库名"; …...
深入解析队列与广度优先搜索(BFS)的算法思想:原理、实现与应用
目录 1. 队列的基本概念 2. 广度优先搜索(BFS)的基本概念 3. 队列在BFS中的作用 4. BFS的实现细节 5. C实现BFS 6. BFS的应用场景 7. 复杂度分析 8. 总结 1. 队列的基本概念 队列(Queue)是一种先进先出(FIFO, …...
Swap to Gather-----
C - 烟销日出不见人 问题陈述 给定一个长度为 NN 的字符串 SS,由 0 和 1 组成。保证 SS 至少包含一个 1。 您可以执行以下操作任意次数(可能为零): 选择一个整数 ii (1≤i≤N−11≤i≤N−1),并交换 SS 的第 ii 个和…...
使用DeepSeek+本地知识库,尝试从0到1搭建高度定制化工作流(自动化篇)
7.5. 配图生成 目的:由于小红书发布文章要求图文格式,因此在生成文案的基础上,我们还需要生成图文搭配文案进行发布。 原实现思路: 起初我打算使用deepseek的文生图模型Janus进行本地部署生成,参考博客:De…...
Python 函数式编程全攻略:从理论到实战的深度解析
本文深入剖析 Python 函数式编程,详细讲解其概念、核心特性(迭代器、生成器等)、内置函数及相关模块(itertools、functools ),结合丰富示例与直观图表,助力读者全面掌握函数式编程技巧ÿ…...
Ollama 在 LangChain 中的使用
文章目录 一、langChain 介绍二、环境安装1.依赖库安装2.下载模型 三、基本使用示例1.使用 ChatPromptTemplate 进行对话2.流式输出3.工具调用4.多模态模型调用 四、进阶使用1.使用 ConversationChain 进行对话2.自定义提示模板3.构建一个简单的 RAG 问答系统 五、遇到问题与解…...
使用apt-rdepends制作软件离线deb安装包
使用apt-rdepends制作软件离线deb安装包 除基础软件外,还要获取软件依赖包。 依赖包工具安装 apt-get install apt-rdependsapt-rdepends工具使用 使用apt-rdepends工具,递归方式分析软件依赖,下载软件包本体,和依赖包。制作时…...
根据POD名称生成 三部曲:get、describe、log、exec
#!/bin/bash# 定义颜色变量 RED\033[0;31m GREEN\033[0;32m YELLOW\033[0;33m NC\033[0m # No Color# 检查是否传入 Pod 名称作为参数 if [ -z "$1" ]; then# 如果没有传参,则提示用户输入 Pod 名称echo -e "${YELLOW}Please enter the Pod name:${…...
SQL sever数据导入导出实验
1.创建数据库TCP-H (1)右键“数据库”,点击“新建数据库”即可 (2)用sql语言创建,此处以创建数据库DB_test为例,代码如下: use master;go--检查在当前服务器系统中的所有数据里面…...
python环境的yolov11.rknn物体检测
1.首先是我手里生成的一个yolo11的.rknn模型: 2.比对一下yolov5的模型: 2.1 yolov5模型的后期处理: outputs rknn.inference(inputs[img2], data_format[nhwc])np.save(./onnx_yolov5_0.npy, outputs[0])np.save(./onnx_yolov5_1.npy, outpu…...
音视频实时通信技术
音视频实时通信技术:连接世界的数字桥梁 在数字化时代,音视频实时通信技术已成为人们日常生活和工作中不可或缺的一部分。无论是远程办公、在线教育,还是社交娱乐,实时音视频传输让千里之外的交流变得如同面对面般自然。这项技术…...
如何搭建个人游戏串流服务器:Sunshine完整指南
如何搭建个人游戏串流服务器:Sunshine完整指南 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine Sunshine是一款开源的游戏串流服务器,能够将高性能电脑上的游…...
video-subtitle-extractor:本地AI字幕提取终极方案深度解析
video-subtitle-extractor:本地AI字幕提取终极方案深度解析 【免费下载链接】video-subtitle-extractor 视频硬字幕提取,生成srt文件。无需申请第三方API,本地实现文本识别。基于深度学习的视频字幕提取框架,包含字幕区域检测、字…...
NVMe 2.3协议学习
文章目录1 Controller Properties1.1 如何访问1.2 Controller 初始化流程1.3 CAP - Controller Capabilities (Offset 00h, 64-bit)X 面试场景问题1 为什么Properties Host必须通过BAR访问,不能通过DMA?2 如果Host按dword访问qword的CAP会怎样࿱…...
MySQL8四大事务隔离级别详解,彻底搞懂脏读、不可重复读、幻读
MySQL8四大事务隔离级别详解,彻底搞懂脏读、不可重复读、幻读 做后端开发久了,我相信大家都碰到过一类特别头疼的线上疑难问题: 代码逻辑反复核对没有问题,单元测试全部通过,测试环境稳得一批。可一旦上线生产&#…...
不止于安装:给你的Ubuntu 22.04 Fcitx5输入法换个皮肤,再装上维基百科词库
打造个性化Fcitx5输入环境:从皮肤更换到维基百科词库深度整合 在Ubuntu 22.04上完成Fcitx5基础安装后,真正的乐趣才刚刚开始。默认的灰白界面和基础词库虽然能用,但远未发挥这款现代输入法的全部潜力。本文将带你突破基础功能边界,…...
3分钟解锁Cursor Pro永久免费:终极破解工具完全指南
3分钟解锁Cursor Pro永久免费:终极破解工具完全指南 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reached your trial…...
SeuratWrappers终极指南:一站式解锁单细胞分析扩展工具集
SeuratWrappers终极指南:一站式解锁单细胞分析扩展工具集 【免费下载链接】seurat-wrappers Community-provided extensions to Seurat 项目地址: https://gitcode.com/gh_mirrors/se/seurat-wrappers 你是否在使用Seurat进行单细胞RNA测序分析时,…...
Windows热键冲突终极指南:Hotkey Detective一键定位占用程序
Windows热键冲突终极指南:Hotkey Detective一键定位占用程序 【免费下载链接】hotkey-detective A small program for investigating stolen key combinations under Windows 7 and later. 项目地址: https://gitcode.com/gh_mirrors/ho/hotkey-detective 你…...
[Al+」数智升级,品牌种草营销新范式
AI给各行各业带来的革新有目共睹。在营销工作中,这个命题亦尤为迫切。AI如何嵌入具体场景、解决日常问题?过去一年,千瓜持续投入「AI」产品战略升级,现已覆盖“达人、内容、品牌”三大维度,实现从选人选号、内容创作到…...
