在FFmpeg源码下增加自定义程序

为了了解FFmpeg解码的细节,使用avcodec_send_packet和avcodec_receive_frame组合,写了一个简单的例子,解码video生成yuv文件,比起用FFmpeg跟踪代码要简单很多。

但是问题是在FFmpeg下编译的ffmpeg/ffplay都可以直接跟踪调试,自己编译的因为连接的系统的动态库,所以不能跟踪到代码里面。

所以参考tools/enum_options程序,在FFmpeg源码目录新增一个目录,修改Makefile相关代码,就可以编译生成类似ffmpeg/ffplay的可执行文件,放在vscode里面非常方便的展台调试。

STEP 1:增加decode目录

decode/
├── decode3.c
└── Makefile

如果是直接编译,链接系统库,没法gdb调试FFmpeg源码,试了下make tools/enum_options可以生成enum_options程序,并且gdb可以调试FFmpeg源码,所以参考tools/Makefile,decode/Makefile如下:

STEP 2:Makefile

DECODE = decode3OUTDIRS += decodeclean::$(RM) $(CLEANSUFFIXES:%=decode/%)

STEP 3:添加到FFmpeg/Makefile

将这个Makefile还要加入到FFmpeg/Makefile里面,下面是diff文件,为了知道每个变量的内容,增加了info打印:

--- a/Makefile
+++ b/Makefile
@@ -39,13 +39,29 @@ SKIPHEADERS = compat/w32pthreads.h# first so "all" becomes default targetall: all-yes+# decode3
+include $(SRC_PATH)/tools/Makefile
+include $(SRC_PATH)/decode/Makefileinclude $(SRC_PATH)/ffbuild/common.makFF_EXTRALIBS := $(FFEXTRALIBS)FF_DEP_LIBS  := $(DEP_LIBS)FF_STATIC_DEP_LIBS := $(STATIC_DEP_LIBS)+$(info debug - info FF_EXTRALIBS: $(FF_EXTRALIBS))
+$(info debug - info FF_DEP_LIBS: $(FF_DEP_LIBS))
+$(info debug - info DEP_LIBS: $(DEP_LIBS))
+$(info debug - info LD_O: $(LD_O))
+$(info debug - info LDFLAGS: $(LDFLAGS))
+$(info debug - info LDEXEFLAGS: $(LDEXEFLAGS))
+$(info debug - info EXTRALIBS: $(EXTRALIBS))
+$(info debug - info ELIBS: $(ELIBS))
+$(info debug - info LD: $(LD))
+$(info debug - info EXESUF: $(EXESUF))
+$(info debug - info DECODE: $(DECODE))
+$(info debug - info LIBFUZZER_PATH: $(LIBFUZZER_PATH))
+$(TOOLS): %$(EXESUF): %.o$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(EXTRALIBS-$(*F)) $(EXTRALIBS) $(ELIBS)@@ -64,6 +80,8 @@ tools/target_dem_fuzzer$(EXESUF): tools/target_dem_fuzzer.o $(FF_DEP_LIBS)tools/target_io_dem_fuzzer$(EXESUF): tools/target_io_dem_fuzzer.o $(FF_DEP_LIBS)$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)+decode/decode3$(EXESUF): decode/decode3.o $(FF_DEP_LIBS)
+       $(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)tools/enum_options$(EXESUF): ELIBS = $(FF_EXTRALIBS)tools/enum_options$(EXESUF): $(FF_DEP_LIBS)

STEP 4:编译

这样编译就可以生成decode3,奇怪的是得先make decode,然后再make decode3

$ make decode
debug - info FF_EXTRALIBS: -lavdevice -lavfilter -lavformat -lavcodec -lpostproc -lswresample -lswscale -lavutil  -lm -latomic -lxcb -lxcb-shm -lxcb-shape -lxcb-xfixes -lasound -lSDL2 -lsndio -lXv -lX11 -lXext -pthread -lm -latomic -lva -lm -latomic -lz -pthread -lm -latomic -llzma -L/usr/local/lib/x86_64-linux-gnu -llc3 -L/usr/local/lib/x86_64-linux-gnu -lopus -L/usr/local/lib -lx264 -L/usr/local/lib/x86_64-linux-gnu -lopenh264 -lz -lva -lm -latomic -lm -latomic -lm -latomic -pthread -lva-drm -lva -lva-x11 -lva -lvdpau -lX11 -lm -lva -latomic -lX11 
debug - info FF_DEP_LIBS: libavdevice/libavdevice.a libavfilter/libavfilter.a libavformat/libavformat.a libavcodec/libavcodec.a libpostproc/libpostproc.a libswresample/libswresample.a libswscale/libswscale.a libavutil/libavutil.a
debug - info DEP_LIBS: libavdevice/libavdevice.a libavfilter/libavfilter.a libavformat/libavformat.a libavcodec/libavcodec.a libpostproc/libpostproc.a libswresample/libswresample.a libswscale/libswscale.a libavutil/libavutil.a
debug - info LD_O: -o 
debug - info LDFLAGS: -Llibavcodec -Llibavdevice -Llibavfilter -Llibavformat -Llibavutil -Llibpostproc -Llibswscale -Llibswresample -Wl,--as-needed -Wl,-z,noexecstack -Wl,--warn-common -Wl,-rpath-link=:libpostproc:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil
debug - info LDEXEFLAGS: 
debug - info EXTRALIBS: 
debug - info ELIBS: 
debug - info LD: @printf "LD\t%s\n" ; gcc
debug - info EXESUF: 
debug - info DECODE: decode3
debug - info LIBFUZZER_PATH: 
Current directory: ffmpeg ffplay ffprobe$ make decode/decode3
debug - info FF_EXTRALIBS: -lavdevice -lavfilter -lavformat -lavcodec -lpostproc -lswresample -lswscale -lavutil  -lm -latomic -lxcb -lxcb-shm -lxcb-shape -lxcb-xfixes -lasound -lSDL2 -lsndio -lXv -lX11 -lXext -pthread -lm -latomic -lva -lm -latomic -lz -pthread -lm -latomic -llzma -L/usr/local/lib/x86_64-linux-gnu -llc3 -L/usr/local/lib/x86_64-linux-gnu -lopus -L/usr/local/lib -lx264 -L/usr/local/lib/x86_64-linux-gnu -lopenh264 -lz -lva -lm -latomic -lm -latomic -lm -latomic -pthread -lva-drm -lva -lva-x11 -lva -lvdpau -lX11 -lm -lva -latomic -lX11 
debug - info FF_DEP_LIBS: libavdevice/libavdevice.a libavfilter/libavfilter.a libavformat/libavformat.a libavcodec/libavcodec.a libpostproc/libpostproc.a libswresample/libswresample.a libswscale/libswscale.a libavutil/libavutil.a
debug - info DEP_LIBS: libavdevice/libavdevice.a libavfilter/libavfilter.a libavformat/libavformat.a libavcodec/libavcodec.a libpostproc/libpostproc.a libswresample/libswresample.a libswscale/libswscale.a libavutil/libavutil.a
debug - info LD_O: -o 
debug - info LDFLAGS: -Llibavcodec -Llibavdevice -Llibavfilter -Llibavformat -Llibavutil -Llibpostproc -Llibswscale -Llibswresample -Wl,--as-needed -Wl,-z,noexecstack -Wl,--warn-common -Wl,-rpath-link=:libpostproc:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil
debug - info LDEXEFLAGS: 
debug - info EXTRALIBS: 
debug - info ELIBS: 
debug - info LD: @printf "LD\t%s\n" ; gcc
debug - info EXESUF: 
debug - info DECODE: decode3
debug - info LIBFUZZER_PATH: 
Current directory: ffmpeg ffplay ffprobe
CC      decode/decode3.o
LD      decode/decode3

没有decode目录,make decode/decode3会报错,手动创建decode目录也是可以的。

不然会报错:

src/decode/decode3.c: At top level:
src/decode/decode3.c:165:1: fatal error: opening dependency file decode/decode3.d: No such file or directory165 | }| ^
compilation terminated.
make: *** [src/ffbuild/common.mak:81: decode/decode3.o] Error 1

decode/Makefile中已经定义了OUTDIRS += decode,检查FFmpeg/Makefile中的OUTDIRS有:

$(sort $(OUTDIRS)):$(Q)mkdir -p $@

所以从这里判断make clean,重新make后应该可以直接make decode/decode3,试了下果然可以了。

STEP 5:运行调试

查找decode3的符号可以发现,这个是包含了所有FFmpeg的代码,不需要加载FFmpeg的动态库,所以FFmpeg中的源码更新后直接make decode/decode3即可

$ nm decode3 |  grep -E "avcodec_send_packet|avcodec_receive_frame|av_read_frame"
000000000031dd95 T avcodec_receive_frame
000000000041a5b6 T avcodec_send_packet
000000000009ea7c T av_read_frame

ldd也可以确定这一点:

$ ldd decode3linux-vdso.so.1 (0x00007ffe27536000)libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f04eadf4000)libdrm.so.2 => /usr/lib/x86_64-linux-gnu/libdrm.so.2 (0x00007f04eabe3000)libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f04ea9c6000)libopus.so.0 => /usr/local/lib/x86_64-linux-gnu/libopus.so.0 (0x00007f04ea76f000)libx264.so.152 => /usr/lib/x86_64-linux-gnu/libx264.so.152 (0x00007f04ea3ca000)libopenh264.so.7 => /usr/local/lib/x86_64-linux-gnu/libopenh264.so.7 (0x00007f04ea0b4000)libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f04e9e95000)libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f04e9aa4000)/lib64/ld-linux-x86-64.so.2 (0x00007f04edef6000)libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f04e98a0000)libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f04e9440000)libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f04e921d000)

vscode launch.json

vscode中的 launch.json中修改program和args即可以运行调试。

{// Use IntelliSense to learn about possible attributes.// Hover to view descriptions of existing attributes.// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387"version": "0.2.0","configurations": [{"name": "(gdb) Launch","type": "cppdbg","request": "launch","program": "${workspaceFolder}/build/decode/decode3","args": ["${workspaceFolder}/decode/256x144.mp4", "${workspaceFolder}/decode/256x144-yuv420p.yuv"],"stopAtEntry": false,"cwd": "${workspaceFolder}/","environment": [ ],"externalConsole": false,"MIMode": "gdb","setupCommands": [{"description": "Enable pretty-printing for gdb","text": "-enable-pretty-printing","ignoreFailures": true},{"description": "Set Disassembly Flavor to Intel","text": "-gdb-set disassembly-flavor intel","ignoreFailures": true}]}]
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/621461.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

什么是RESTful接口风格

开头语: 大家好!欢迎来到本篇博客,今天我们将深入讨论RESTful接口风格。RESTful是一种设计风格,用于构建可扩展、可维护的网络服务。本文将为您介绍RESTful的基本概念、设计原则以及实际应用中的一些技巧。 RESTful接口风格分享&…

el-popover设置 :visible 手动关闭弹窗后,无法点击空白处关闭弹窗。

<script setup lang"ts"> import { ref, unref } from "vue"; import { ClickOutside as vClickOutside } from "element-plus";const popoverShow ref(false); //是否显示 const popoverRef ref();/**点击空白处隐藏 */ const onClickO…

DSL查询文档--各种查询

DSL查询文档 elasticsearch的查询依然是基于JSON风格的DSL来实现的。 1查询所有 结果&#xff1a; 2全文检索&#xff08;full text&#xff09;查询 常见的全文检索查询包括&#xff1a; match查询&#xff1a;单字段查询 multi_match查询&#xff1a;多字段查询&#xff…

.NET开源免费、企业级、可商用内容管理系统 - SSCMS

前言 今天给大家推荐一款基于.NET Core开源、企业级、可商用、能够以最低的成本、最少的人力投入在最短的时间内架设一个功能齐全、性能优异、规模庞大并易于维护的内容管理系统&#xff1a;SSCMS。 系统官方介绍 SSCMS 内容管理系统基于微软 .NET Core 平台开发&#xff0c…

黑马程序员SpringBoot2-开发实用篇

视频连接&#xff1a;开发实用篇-67-手工启动热部署_哔哩哔哩_bilibili 热部署 手动启动热部署 热部署仅包含restart的过程。 自动启动热部署 按CtrlAltShift/打开下列界面。 禁用热部署 配置高级 ConfigurationProperties 宽松绑定/松散绑定 常用计量单位绑定 数据校验 设置…

Android音视频编码(2)

Android本身提供了音视频编解码工具&#xff0c;很多时候是不需要第三方工具的&#xff0c;比如ffmpeg, OpenCV等&#xff0c;在android中引入第三库比较复杂&#xff0c;在Android音视频编码中介绍了如何引入第三方库libpng来进行进行图片处理&#xff0c;同时引入这些第三方库…

JVM内存区域详解,一文弄懂JVM内存【内存分布、回收算法、垃圾回收器】

视频讲解地址 学习文档 一、内存区域 区域描述线程私有如何溢出程序计数器为了线程切换后能恢复到正确的执行位置&#xff0c;每个线程都要有一个独立的程序计数器。✅唯一一个不会内存溢出的地方虚拟机栈1. 每个方法执行的时候&#xff0c;Java虚拟机都会同步创建一个栈帧用于…

获取当前设备的IP

背景&#xff1a; 在本地使用自带webUI的项目时&#xff0c;需要制定webUI的访问地址。 一般本地访问使用&#xff1a;127.0.0.1&#xff0c;配置为可以从其他设备访问时&#xff0c;需要指定当前设备的IP&#xff0c;或者指定为0.0.0.0。 例如&#xff1a;使用locust的时候&a…

【Python学习】Python学习18- 方法OS 文件/目录方法

目录 【Python学习】Python学习17- File方法 前言os.access()语法&#xff1a; os.chdir(path)语法 os.chflags(path, flags)语法 os.chmod(path, mode)os.chown(path, uid, gid)os.chroot(path)os.close(fd)os.unlink(path)os.popen(command[, mode[, bufsize]])os.read(fd, …

Python--循环语句

在 Python 中&#xff0c;循环语句用于重复执行一段代码多次。Python 主要提供了两种类型的循环&#xff1a;for 循环和 while 循环。 1. for 循环 for 循环用于遍历可迭代对象&#xff08;如列表、元组、字典、字符串等&#xff09;中的每个元素&#xff0c;并对每个元素执行…

[NOIP2009 提高组] 潜伏者

一起来交流编程吧【CSDN app】&#xff1a; http://qm.qq.com/cgi-bin/qm/qr?_wv1027&kx9pL9ccIHGKNLE0CWviAqQ_q6HzxomLW&authKeyVslKe623ptw8VRepda%2Bh0Ttr8Ruz8v%2FBW5HpVzyTWU7ECwpHIZpULMj6qIHYZBVb&noverify0&gro [NOIP2009 提高组] 潜伏者 题目描述…

精通业务:资深程序员的核心优势

在IT行业&#xff0c;我们常常听到关于技术实力、项目经验、团队协作等方面的讨论&#xff0c;但有一个重要因素常常被忽视&#xff0c;那就是对业务的了解。 对于资深程序员来说&#xff0c;懂业务和不懂业务之间的区别&#xff0c;犹如一道深邃的鸿沟&#xff0c;决定着他们…

MCS-51---串行通信的特点

目录 一.同步通信和异步通信 1.异步通信 2.同步通信 二.串行通信的方式 1.单工 2.半双工 3.全双工 三.串行通信的速率 四.MCS-51单片机结构 五.串行口的控制 1.串行口控制寄存器(SCON) 2.电源控制寄存器(PCON) 六.波特率的设计 七.串行口的工作方式 1.方式0 2.…

DM数据库安装注意事项

数据库安装注意事项 一、安装前 一些参数需要在数据库创建实例前找用户确认。 参数名参数掩码参数值备注数据页大小PAGE_SIZE32数据文件使用的页大小(缺省使用8K&#xff0c;建议默认&#xff1a;32)&#xff0c;可以为 4K、8K、16K 或 32K 之一&#xff0c;选择的页大小越大…

k8s存储卷之动态

动态pv需要两个组件 1、卷插件&#xff0c;k8s本身支持的动态pv创建不包含NFS&#xff0c;需要声明和安装一个外部插件 Provisioner 存储分配器&#xff0c;动态创建pv&#xff0c;然后根据pvc的请求自动绑定和使用 2、StorageClass&#xff0c;用来定义pv的属性&#xff0c…

选择和训练模型(Machine Learning 研习之十一)

当您看到本文标题时&#xff0c;不禁感叹&#xff0c;总算是到了训练模型这一节了。 是啊&#xff0c;在之前的文章中&#xff0c;我们对数据进行了探索&#xff0c;以及对一个训练集和一个测试集进行了采样&#xff0c;也编写了一个预处理管道来自动清理&#xff0c;准备您的数…

大数据赋能电竞出海企业发展

近几年电竞行业发展迅速&#xff0c;我国单2022年新增近4万家电竞相关企业&#xff0c;竞争十分激烈。中国电竞市场规模在全球占比19%左右&#xff0c;海外有巨大的增量市场&#xff0c;特别是东南亚、中南亚和拉丁美洲是电竞市场增长最快的地区&#xff0c;在2020至2025年期间…

C#,求最长回文字符串的马拉车(Manacher)算法的源代码

一、回文字符串&#xff08;Palindromic String&#xff09; 回文字符串&#xff08;Palindromic String&#xff09;是指前、后向读起来完全相同的字符串。 回文字符串除了答题似乎没有什么用处 :P 二、求解思路 求解字符串的回文子串的基本思路&#xff1a; 1、遍历每个位…

系列五、Spring Security中的认证 授权(前后端分离)

一、Spring Security中的认证 & 授权&#xff08;前后端分离&#xff09; 1.1、MyWebSecurityConfigurerAdapter7002 /*** Author : 一叶浮萍归大海* Date: 2024/1/11 21:50* Description: Spring Security配置类*/ Configuration public class MyWebSecurityConfigurerA…

HTML---CSS-引入样式表和选择器

CSS : Cascading Style Sheet 层叠式样式表 HTML 用于控制网页的结构&#xff0c;CSS则用于控制网页的外观&#xff0c;想要做出美观好看的网页&#xff0c;CSS是必须的 引入外部样式表&#xff1a; 它的属性 rel 和 type是固定的 语法&#xff1a; <link rel"styles…