请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

关于 ninja 在使用 ffmpeg 时的 BUILD.gn 编译配置

想问超哥一个有关编译的问题,我在项目中使用了 ffmpeg 的库函数(例如 avformat_open_input,avformat_find_stream_info,avcodec_open2,sws_scale 等等)。按照我的理解,在项目中 include 路径应该这么写:
图片描述
然后,在 BUILD.gn 中我们只需要加入这样一句话就行了:
图片描述
因为按照我的理解,我都把整个库放到 third_party 中了(webrtc 下载下来 third_party 就自带这个库),那么应该不涉及所有静态链接/动态链接的问题,因为我是直接根据源码进行编译的,并不是只有一个 .h 文件再和 .so 进行连接。然而,我编译的时候出现这样的问题:
图片描述
很明显,这个是进行 LINK 的时候出了问题,按理来说不应该会出现这个问题呀。如果我在 BUILD.gn 加上下面内容:
图片描述
也就是再带上 ubuntu 系统上的链接库,但这样编译会出现如下错误:
图片描述
相当于找不到 libswscale.so 这个库,但我确信 ffmpeg 已经安装且这个库已经在系统的 include 路径中:
图片描述
而如果我直接删掉 swscale 这个依赖:
图片描述
而编译结果如下:
图片描述
似乎另外两个依赖也是白加的。
综上所述,我就很疑惑,因为可能有几种情况我不能确定是哪一种(可能是 ffmpeg 的版本原因,也可能是默认引用路径引到了 WebRTC 自带的 .so 库里面,但 WebRTC 自带的 .so 库没有 swscale.so —— 我 find 的结果也确实)
所以我想问一下正确的 BUILD.gn 应该是怎么配置的,只要这个配置对了我就能够自己调出来…

正在回答

3回答

webrtc有自己的ffmpeg 库,你要用的话需要把使用ffmpeg 的开关打开。如果你打开了webrtc中的ffmpeg, 你的项目中再另外引用自己的ffmpeg 就会产生冲突。 所以你首要的要确定webrtc 中有没有打开ffmpeg,如果打开了,你看看能不能你自己的也用webrtc 中的ffmpeg,如果不能用的话就比较麻烦了,你需要把你用的ffmpeg 的接口都改一下名字。 你说的这类问题是所有搞音视频的人都比较挠头的问题

1 回复 有任何疑惑可以回复我~
提问者 奕帝传说_梦 2024-11-19 12:20:18

这个问题我解决了,WebRTC 多少有点坑的,先说个结论:

如果我们这样写:

#include "third_party/ffmpeg/libavcodec/avcodec.h"
#include "third_party/ffmpeg/libavformat/avformat.h"
#include "third_party/ffmpeg/libswscale/swscale.h"

它在编译时是直接使用 C++ 来编译的,因此链接库它是带参数的;其实从我上面给出的图也能看出来... 我上面的提示都是 :

ld.lld: error: undefined symbol: avcodec_free_context(AVCodecContext**)
>>> referenced by MP4VideoDecoder.cc:23 (../../examples/MyFECExp/MP4VideoDecoder.cc:23)
>>>               obj/examples/MyFECExp/MP4VideoDecoder.o:(webrtc::videoplayermodule::MP4VideoDecoder::~MP4VideoDecoder())

给出的 symbol 都是 avcodec_free_context(AVCodecContext**) 这样子的,然后,非常感谢超哥提示,WebRTC 是不会用操作系统的链接库的,而是会用自己的链接库!我们看看它的编译指令:

"vpython3" "../../build/toolchain/gcc_link_wrapper.py" --output="./MyFECExp" 
-- ../../third_party/llvm-build/Release+Asserts/bin/clang++ -Werror -fuse-ld=lld -Wl,--fatal-warnings 
-Wl,--build-id=fast -fPIC -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--color-diagnostics 
-Wl,--undefined-version -Wl,--no-call-graph-profile-sort -m64 -no-canonical-prefixes -Wl,--gdb-index 
-Wl,-z,defs -Wl,--as-needed -nostdlib++ --sysroot=../../build/linux/debian_bullseye_amd64-sysroot 
-rdynamic -pie -Wl,--disable-new-dtags -o "./MyFECExp" -Wl,--start-group @"./MyFECExp.rsp" 
-Wl,--end-group   -lX11 -lXcomposite -lXext -lXrender ../../third_party/llvm-build/
Release+Asserts/lib/clang/20/lib/x86_64-unknown-linux-gnu/libclang_rt.builtins.a -ldl -lpthread 
-lrt -lgmodule-2.0 -lgthread-2.0 -lgtk-3 -lgdk-3 -lpangocairo-1.0 -lpango-1.0 -lharfbuzz 
-latk-1.0 -lcairo-gobject -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0 -lm 
-lz -Wl,--start-group  -Wl,--end-group

其中有一句话:

--sysroot=../../build/linux/debian_bullseye_amd64-sysroot

这其实就是告诉了操作系统:我优先在这个目录下找链接库!这里还在 linux 目录下的 debian...amd64 目录下,显然这是 WebRTC 为了做一些多平台的迁移支持,所以使用 ninja 编译时没有用本地的链接库,而是直接用自己提供的库。然后我们去这个目录下的库看看,在我这里具体用的目录如下:

WebRTC/src/build/linux/debian_bullseye_amd64-sysroot/usr/lib/x86_64-linux-gnu

这里就是一个大坑了,首先它没有 swscale 这个库,这就是为什么我上面 libs 加了也白加;其次我这个目录下 libavformat.so 这个文件还是损坏的,它好像下载下来就是损坏的,如果大家用的是超哥推荐的 4096 版本的话需要检查一下...

https://img1.sycdn.imooc.com/szimg/673c10550984e20a08870558.jpg

其次,它自带的是 C 语言的库呀... 我们用 nm 看一下就可以看出来:

https://img1.sycdn.imooc.com/szimg/673c1033094462e507360097.jpg

OK问题找到,我的做法比较暴力:

找到 WebRTC/third_party 对应版本的 ffmpeg (4096 使用的是 7.0),然后编译一下把新的 .so 文件丢到上面那个库文件夹里面。然后 #include 的时候这样写:

extern "C" {
#include "third_party/ffmpeg/libavcodec/avcodec.h"
#include "third_party/ffmpeg/libavformat/avformat.h"
#include "third_party/ffmpeg/libswscale/swscale.h"
}

也就是让它用 C 的方式来 LINK ,别带参数!

其实吧,这个问题我一年前想把 ffmpeg 塞到 ns3 里面做实验的时候就遇到过,但人总是不长记性的;我之前用的是一种更暴力的做法,直接改了 ffmpeg 的 MakeFile 文件,然后编译了一个 C++ 版本的 .so 文件塞到 ns3 的 lib 里面去了... 我记得这种方法也很简单,只需要改 MakeFile 几个符号就行了....

1 回复 有任何疑惑可以回复我~
提问者 奕帝传说_梦 2024-11-19 12:24:22

And 对于 Build.gn 的写法,这张图是正确的:

https://img1.sycdn.imooc.com/szimg/673b521f0998da2c10420711.jpg

也就是 deps 加上 //third_party/ffmpeg

然后在 libs 处加上 avformat, avcodec 和 swscale;前提是你要把编译好的 libswscale.so 丢到 build 你操作系统相应的目录中!例如我的丢到  WebRTC/src/build/linux/debian_bullseye_amd64-sysroot/usr/lib/x86_64-linux-gnu 这里

0 回复 有任何疑惑可以回复我~
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信