当前位置:   article > 正文

Qt使用FFmpeg的动态库_libavcodec

libavcodec

FFmpeg 的社群来了,想加入微信社群的朋友请购买《FFmpeg原理》VIP版 电子书,里有更高级的内容与答疑服务。


C/C++ 项目有两种编译方式,MinGW 跟 MSVC,如下:

1,《MinGW编译静态库

2,《MSVC编译静态库

但是 MinGW 编译的静态库,是不能给 MSVC 的链接器使用的,虽然两者编译器生成的 .o 跟 .obj 目标文件是 ABI 兼容的,但是他们的链接器不通用。

而 静态库 实际上就是把 目标文件 打包在一起,所以 MinGW 编译的静态库,只能给 MinGW 编译方式的项目使用。MSVC 同理。


下面来讲一下 qt creator 如何引入 用 MinGW 方式编译出来的 FFmpeg 动态库。

MinGW 编译 FFmpeg 请参考 《用msys2与mingw编译FFmpeg》,编译完成之后,目录如下:

上图中,这些 lib 并不是静态库,而是动态库的导入库。而 dll 文件就是动态库,使用 FFmpeg 的库的时候,还需要按需引入一些头文件,哪些头文件后面会讲到。

实际上 ffmpeg-n4.4.1-mingw 目录,是有两种导入库的,一种是 xxx.lib ,一种是 xxx.dll.a ,如下:

可以这么理解这两种导入库,lib 是给 msvc 链接器用的,.a 的导入库是给 MinGW 链接器用的。MinGW 跟 MSVC 对于格式的处理有点不一样,所以需要分开。

这里提醒一下,虽然 dll 是用 MinGW 的 gcc 编译出来的,但是 dll 也可以给 MSVC 用的。他们是兼容的。

不过,我实际测试后发现,qt creator 的 MinGW 可以用 lib 导入库,也可以用 .a 导入库,都可以。但是 qt creator 的 MSVC 只能用 lib 导入库 ,用 .a 导入库来定位就会报错。


打开 Qt Creator,点击菜单栏的 New File or Project,选择 Non-Qt Project ,选择 Plain C Application。

项目名称填 ffmpeg-shared-libs-use,编译工具选 qmake,如下:

勾选编译环境 Kit ,Qt 5.15.2 MinGw 64-bit


然后把 C:\msys64\home\loken\ffmpeg\build64 这个目录拷贝到 ffmpeg-qt-version 项目目录下,如下:

然后 修改 ffmpeg-shared-libs-use.pro 的内容,修改为以下内容:

  1. TEMPLATE = app
  2. CONFIG += console c++11
  3. CONFIG -= app_bundle
  4. CONFIG -= qt
  5. #定义 DLL 的导入库的类型
  6. #DLL_IMPORT_TYPE = msvc
  7. DLL_IMPORT_TYPE = mingw
  8. #HEADERS += xxx.h
  9. SOURCES += main.c
  10. contains(QT_ARCH, i386) {
  11. message("32-bit")
  12. }
  13. contains(QT_ARCH, x86_64) {
  14. message("64-bit")
  15. message({% math %}DLL_IMPORT_TYPE)
  16. contains(DLL_IMPORT_TYPE, mingw) {
  17. INCLUDEPATH += {% endmath %}PWD/build64/ffmpeg-n4.4.1-mingw/include
  18. LIBS += {% math %}PWD/build64/ffmpeg-n4.4.1-mingw/lib/libavformat.dll.a \
  19. {% endmath %}PWD/build64/ffmpeg-n4.4.1-mingw/lib/libavcodec.dll.a \
  20. {% math %}PWD/build64/ffmpeg-n4.4.1-mingw/lib/libavdevice.dll.a \
  21. {% endmath %}PWD/build64/ffmpeg-n4.4.1-mingw/lib/libavfilter.dll.a \
  22. {% math %}PWD/build64/ffmpeg-n4.4.1-mingw/lib/libavutil.dll.a \
  23. {% endmath %}PWD/build64/ffmpeg-n4.4.1-mingw/lib/libpostproc.dll.a \
  24. {% math %}PWD/build64/ffmpeg-n4.4.1-mingw/lib/libswresample.dll.a \
  25. {% endmath %}PWD/build64/ffmpeg-n4.4.1-mingw/lib/libswscale.dll.a
  26. }
  27. contains(DLL_IMPORT_TYPE, msvc) {
  28. INCLUDEPATH += {% math %}PWD/build64/ffmpeg-n4.4.1-mingw/include
  29. LIBS += {% endmath %}PWD/build64/ffmpeg-n4.4.1-mingw/bin/avcodec.lib \
  30. {% math %}PWD/build64/ffmpeg-n4.4.1-mingw/bin/avdevice.lib \
  31. {% endmath %}PWD/build64/ffmpeg-n4.4.1-mingw/bin/avfilter.lib \
  32. {% math %}PWD/build64/ffmpeg-n4.4.1-mingw/bin/avformat.lib \
  33. {% endmath %}PWD/build64/ffmpeg-n4.4.1-mingw/bin/avutil.lib \
  34. {% math %}PWD/build64/ffmpeg-n4.4.1-mingw/bin/postproc.lib \
  35. {% endmath %}PWD/build64/ffmpeg-n4.4.1-mingw/bin/swresample.lib \
  36. $$PWD/build64/ffmpeg-n4.4.1-mingw/bin/swscale.lib
  37. }
  38. }

提示:gitbook 生成 html 的时候 改乱了 上面的代码,请按照下图进行修改:

然后把 main.c 的内容也修改一下,创建项目的时候只是输出了一个 hello world,我们现在在 main.c 里面调一下 FFmpeg 的一些 API 函数,如下:

  1. #include <stdio.h>
  2. #include "libavcodec/avcodec.h"
  3. #include "libavdevice/avdevice.h"
  4. #include "libavfilter/avfilter.h"
  5. #include "libavformat/avformat.h"
  6. int main()
  7. {
  8. printf("avcodec version is %u \n",avcodec_version());
  9. printf("avdevice version is %u \n",avdevice_version());
  10. printf("avfilter version is %u \n",avfilter_version());
  11. printf("avfilter version is %u \n",avformat_version());
  12. return 0;
  13. }

上面的代码打印了 4 个库的版本号,我为什么知道有这 4个函数可以用,可以用以下命令查看 dll 提供了哪些函数可以调用。

dumpbin /EXPORTS ./avcodec-58.dll > avcodec-58.txt

然后去 FFmpeg-n4.4.1 的源码里面搜这个函数的定义,有哪些参数,返回值就行了。一般在 头文件里面,所以我上面引入了 4个头文件。

也可以查官网的文档手册来看 API 函数的调用。


上面这样改好之后,点 qt creator 编译运行的时候会报找不到 一些dll,这时候需要把 这些缺失的 dll 复制到 exe 的同目录下,因为 我们的 FFmpeg 动态库在 MinGW 环境下编译的,所以依赖一些 MinGW的库,也需要把这些库复制过来,例如 libiconv-2.dll ,liblzma-5.dll 等等。

这些库一定要复制对,不要把 32位的 复制过来,推荐 Everything 搜索,如下:

复制完之后如下:

这样,再次运行,就可以正常打印出 信息,如下:


下面再使用 qt creator 的 MSVC 来编译 main.c 看看,如下:

同时要修改一下 DLL_IMPORT_TYPE 变量,设置为 msvc,这样链接的时候就会使用 lib 后缀的导入库,因为我 pro 文件里面用了这个 DLL_IMPORT_TYPE 变量来执行不同的分支代码。


前面 引入的 都是 msys2 + mingw 编译出来 FFmpeg 动态库。

qt creator 如何 引入 msys2 + msvc 编译出来 FFmpeg 动态库 原理也是类似的,这里就不讲解了。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Guff_9hys/article/detail/758443
推荐阅读
相关标签
  

闽ICP备14008679号