ffmpeg编译后执行可执行文件会提示各组件库的版本信息,这些版本信息从何而来是本文关注的重点

1、ffmpeg版本信息一探

1.1 windows下示例

  (1)假设你在windows下编译了ffmpeg,执行ffmpeg.exe便会出现下图所示的信息,图中列出了ffmpeg各组件的版本信息;

  (2)版本信息从何而来?
  打开ffmpeg.c文件,main函数调用了 ‘show_banner(argc, argv, options);’ 此函数原理很简单,调用了一些现有的宏,这些宏在一些头文件中,例如’libavcodec/version.h’ 中,就含有某个宏表示libavcodec的版本信息;

  (3)windows下编译的动态库命名带有版本信息(如’avdevice-57.dll,57为版本)又从何而来?
  1>、在ffmpeg的早期版本中,如ffmpeg2.5,在./configure之后会产生config,mak文件,ffmpeg各组件的版本信息就在此文件中,如’libavcodec_VERSION_MAJOR=56,脚本编译动态库的时候,动态库的名字会加上此宏。
  2>、在ffmpeg比较新的版本中,如ffmpeg3.4,在./configure之后也会产生一些mak文件,譬如 ffbuild/ 目录下的library.mak文件,其中的’-include $(SUBDIR)lib$(NAME).version 其实是将各组件目录下含版本信息的文件例如’libavcodec/libavcodec.version 包含进来,接着使用’LIBMAJOR := $(lib$(NAME)_VERSION_MAJOR)读取版本信息;然后在链接的时候(’$(SUBDIR)$(SLIBNAME_WITH_MAJOR): $(OBJS) $(SLIBOBJS) $(SUBDIR)lib$(NAME).ver)生成类似’avdevice-57.dll的命名;

2、通过动态库加载的方式获取版本号

2.1 新建名为symbol.c的文件,内容为:
#include <stdio.h>
#include <stdlib.h>#ifdef WIN32
#include <windows.h>
//#include <wtypes.h>
//#include <winbase.h>
#else
#include <dlfcn.h>
#endif//将版本信息转换成具体的数字
//#define AV_VERSION_INT(a,b,c) ((a)<<16 | (b)<<8 | (c))
void transport_version(unsigned int version_num, char *pname)
{int version_major, version_minor, version_micro;version_major = (version_num >> 16) & 0xff;version_minor = (version_num >> 8) & 0xff;version_micro = (version_num) & 0xff;printf("%s: %d, %d, %d\n", pname, version_major, version_minor, version_micro);
}//需要从so或dll文件中导出的函数声明
typedef unsigned (*avcodec_version_fuc)(void);//动态库名字加路径
char *psoavutil = "libavutil.so";
char *psoavcodec = "libavcodec.so";
char *psoavformat = "libavformat.so";
char *psoavdevice = "libavdevice.so";
char *psoavfilter = "libavfilter.so";
char *psoavscale = "libswscale.so";char *pdllavutil = "libavutil.dll";
char *pdllavcodec = "libavcodec.dll";
char *pdllavformat = "libavformat.dll";
char *pdllavdevice = "libavdevice.dll";
char *pdllavfilter = "libavfilter.dll";
char *pdllavscale = "libswscale.dll";#ifdef WIN32
void get_lib_version(char *pdllname, char *function)
{HINSTANCE pdllHandle;avcodec_version_fuc avcodec_version = NULL;//函数指针pdllHandle = LoadLibrary(pdllname);if (pdllHandle == NULL){printf("Cant open %s\n", pdllHandle);return;}avcodec_version = (avcodec_version_fuc)GetProcAddress(pdllHandle, function);if(avcodec_version == NULL){printf("Cant load symbol %s\n", function);FreeLibrary(pdllHandle);return;}transport_version(avcodec_version(),function);//关闭so文件FreeLibrary(pdllHandle);
}void get_ffmpeg_version(char *psoname, char *function)
{HINSTANCE pdllHandle;char *avcodec_version = NULL;//函数指针pdllHandle = LoadLibrary(pdllname);if (pdllHandle == NULL){printf("Cant open %s\n", pdllHandle);return;}avcodec_version = (avcodec_version_fuc)GetProcAddress(pdllHandle, function);if(avcodec_version == NULL){printf("Cant load symbol %s\n", function);FreeLibrary(pdllHandle);return;}printf("%s\n", avcodec_version);//关闭so文件FreeLibrary(pdllHandle);
}//windows动态加载方法
void main(int argc, char *argv[])
{get_lib_version(pdllavutil, "avutil_version");get_lib_version(pdllavcodec, "avcodec_version");get_lib_version(pdllavformat, "avformat_version");get_lib_version(pdllavdevice, "avdevice_version");get_lib_version(pdllavfilter, "avfilter_version");get_lib_version(pdllavscale, "swscale_version");get_ffmpeg_version(pdllavcodec, "av_codec_ffversion");
}#else
void get_lib_version(char *psoname, char *function)
{void *psoHandle;avcodec_version_fuc avcodec_version = NULL;//函数指针psoHandle = dlopen(psoname, RTLD_NOW | RTLD_GLOBAL);if (psoHandle == NULL){printf("Cant open %s\n", psoHandle);return;}avcodec_version = dlsym(psoHandle, function);if(avcodec_version == NULL){printf("Cant load symbol %s\n", function);dlclose(psoHandle);return;}transport_version(avcodec_version(),function);//关闭so文件dlclose(psoHandle);
}void get_ffmpeg_version(char *psoname, char *function)
{void *psoHandle;char *avcodec_version = NULL;//函数指针psoHandle = dlopen(psoname, RTLD_NOW | RTLD_GLOBAL);if (psoHandle == NULL){printf("Cant open %s\n", psoHandle);return;}avcodec_version = dlsym(psoHandle, function);if(avcodec_version == NULL){printf("Cant load symbol %s\n", function);dlclose(psoHandle);return;}printf("%s\n", avcodec_version);//关闭so文件dlclose(psoHandle);
}//linux动态加载方法
void main(int argc, char *argv[])
{get_lib_version(psoavutil, "avutil_version");get_lib_version(psoavcodec, "avcodec_version");get_lib_version(psoavformat, "avformat_version");get_lib_version(psoavdevice, "avdevice_version");get_lib_version(psoavfilter, "avfilter_version");get_lib_version(psoavscale, "swscale_version");get_ffmpeg_version(psoavcodec, "av_codec_ffversion");
}
#endif
2.2 新建Linux下的makefile脚本(Makefile)
src = $(wildcard *.c)
obj = $(src:.c:.o)CC = gcc
LDFALGS = -lm -ldldemo:$(obj)$(CC) -o $@ $^ $(LDFALGS).PHONY:clean
clean:rm -f $(obj) demo

编译方法,将.c代码跟makefile放在同一路径下,之后make就行

2.3 新建windows的makefile脚本(Makefile.vc)
src = $(wildcard *.c)
obj = $(src:.c:.o)CC = cl
LD = link
LDFALGS = -debug
CFLAGS = -DWIN32.PHONY: allall:clean demo.exedemo.exe:$(obj)$(LD) -libpath:./ $(LDFALGS) -PDB:./demo.pdb $(obj) -debug -out:./$@%.o:%.c$(CC) $(CFLAGS) -Fo$@ -c $< .PHONY:clean
clean:rm -f $(obj) demo.exe

编译方法,将.c代码跟Makefile.vc放在同一路径下,之后make -f Makefile.vc就行

动态库加载的代码参考1:https://blog.csdn.net/eydwyz/article/details/74932628
动态库加载的代码参考2:https://www.cnblogs.com/marblemm/p/7804056.html

【FFMPEG系列】之查看FFMPEG版本号相关推荐

  1. 【FFMPEG系列】之ffmpeg怎么利用gdb调试以及gdb调试快捷键

    1.编译可调试的FFmepg (1).使用命令: ./configure --enable-debug --disable-optimizations --disable-asm --disable- ...

  2. FFMPEG系列课程(一)打开视频解码器

    测试环境:windows10 开发工具:VS2013 从今天开始准备些FFmpeg的系列教程,今天是第一课我们研究下打开视频文件和视频×××.演示环境在windows上,在linux上代码也是一样. ...

  3. 【FFMPE系列】之FFMPEG常用命令

    1.查看支持的YUV格式 ffmpeg -pix_fmts 2.对YUV格式进行转换 ffmpeg -pix_fmt yuv420p -s 176x144 -i carphone_qcif.yuv - ...

  4. 音视频系列2:ffmpeg将H.264解码为RGB

    音视频系列2:ffmpeg将H.264解码为RGB 前言 源码 前言 喜大普奔,终于更新啦,上期说到,如何使用ffmpeg+rtmp进行拉流,不熟悉的小伙伴们,可以先看上一期.今天我们要实现的是使用f ...

  5. ffmpeg rtmp 花屏_音视频系列6:ffmpeg多线程拉流

    本文与csdn博客同步:https://blog.csdn.net/Hanghang_/article/details/105302384,欢迎关注,点赞,评论. 前言 本篇博客是音视频系列的续集与改 ...

  6. Android FFmpeg系列——7 实现快进/快退功能

    Android FFmpeg系列--0 编译.so库 Android FFmpeg系列--1 播放视频 Android FFmpeg系列--2 播放音频 Android FFmpeg系列--3 C多线 ...

  7. Android音视频学习系列(十) — 基于FFmpeg + OpenSL ES实现音频万能播放器

    系列文章 Android音视频学习系列(一) - JNI从入门到精通 Android音视频学习系列(二) - 交叉编译动态库.静态库的入门 Android音视频学习系列(三) - Shell脚本入门 ...

  8. ffmpeg系列之mp4与ts格式转换

    ffmpeg系列之mp4与ts格式转换 1. M3U 协议解析 1.1.Tag说明 2.HLS 与 M3U8 3.通过ffmpeg进行转换 3.1. mp4格式转换为ts格式 3.2. ts格式拼接命 ...

  9. 【FFmpeg】Windows 搭建 FFmpeg 命令行运行环境

    文章目录 前言 一.下载 FFMPEG 二.拷贝可执行文件 三.拷贝动态库文件 四.运行 ffmpeg 命令 总结 前言 Android 中需要使用到 FFMPEG , 先在 Windows 中搭建一 ...

  10. 【C++ 语言】Visual Studio 配置 FFMPEG 开发环境 ( VS2019 CMake 环境安装 | 下载 FFMPEG 开发包 | 配置 FFMPEG )

    文章目录 Visual Studio 2019 社区版 CMakeList 开发环境安装 创建 FFMPEG 配置项目 FFMPEG 开发包下载 FFMPEG 头文件 静态链接库 ( .lib ) 动 ...

最新文章

  1. REM——适合移动开发的自适应方案
  2. java regex
  3. 【Flask】Jinja2模板之过滤器
  4. 三种方式实现分布式锁
  5. 微软公有云Azure落地中国,全面大规模商用
  6. Core java class in Spring
  7. [C][变量作用域]语句块
  8. python打印长方形_利用python打印出菱形、三角形以及矩形的方法实例
  9. nginx哪个版本性能好_骁龙750g和天玑1000+哪个好-参数性能对比
  10. 十三、Swing绘图技术
  11. 女孩你让我留恋,你让我痴迷。
  12. HTML简单的网页代码编写
  13. (疑似问题)用IDM某些版本可能会导致系统永久性开机黑屏
  14. 金山反间谍清理专家能清除的部分恶意软件清单(截至2007年2月28日更新)
  15. 通过DSP采集AD7606的转换结果
  16. Win7和Win10共享出现没有权限使用网络资源的解决步骤
  17. 计算机系统维护技术txt,计算机系统维护技术作业装系统.docx
  18. MPI_Bcast函数的用法
  19. 传奇引擎注册服务器,GeeM2引擎架设传奇不能注册账号 进不去游戏
  20. java中以下为不合法字符常量_以下字符常量中不合法的是 ( )。 (1.0分)

热门文章

  1. 命名空间system中不存在data_patternplot包:用ggplot解决你对线性填充,不!所有填充的全部幻想。...
  2. mysql无法连接10061_Day062 连接数据库异常问题记录
  3. mysql ( )=,(mysql)
  4. oracle查看有哪些数据库用户登录,oracle如何查看当前有哪些用户连接到数据库,oracle当前有...
  5. E - Palindrome Numbers
  6. php怎么获取cid,Typecho根据文章cid获取文章信息
  7. mysql浮点数据怎么_MySQL数据浮点类型的实际应用操作
  8. linux替换windows换行符_vim编辑器的查找与替换
  9. 非经营性网站备案流程
  10. @Component注解的用法