Windows系统下Mysys,MinGW编译FFmpeg库教程(支持x264编码)

⌚Time: 2022-05-16 03:09:59

👨‍💻Author: Jack Ge

系统:Windows10 1909


准备工具

FFmpeg源码:下载地址

MSYS-1.0.11:下载地址

PKG-CONFIG:下载地址

yasm-1.3.0-win32:下载地址

coreutils-5.97-3-msys-1.0.13-bin.tar.lzma:下载地址

x264源码:下载地址

MinGW-4.8.1:下载地址


环境搭建

安装MSYS-1.0.11.exe,我将其安装在"C:\msys64"路径下

弹出窗口,输入'n'回车


编译x264

到C:\msys\1.0目录下,双击msys.bat启动mysys,测试gcc


gcc -v

出现版本信息说明正常

否则,输入以下命令


export PATH=/C/Qt/Tools/MinGW/bin:$PATH

其中/C/Qt/Tools/MinGW/bin是我的mingw的bin目录路径(C:\Qt\Tools\MinGW\bin)

切换到x264源码目录,并编译x264


cd /C/Users/m/Downloads/x264-master.tar/x264-master/x264-master

./configure --prefix=./build --enable-static --disable-asm

make

make install

--disable-asm 因为没有安装nasm工具,关闭汇编优化功能(可能影响程序执行效率)

--enable-static 生成静态链接库供ffmpeg编译时使用

--prefix=./build 编译x264生成文件的目录

编译成功后,在C:\Users\m\Downloads\x264-master.tar\x264-master\x264-master\build目录下有三个子目录

bin目录存放x264程序,include存放x264的头文件,lib存放静态库文件,include和lib目录是我们编译ffmpeg要用到的


编译ffmpeg

切换目录到ffmpeg源码目录,编译


cd /C/Users/m/Downloads/ffmpeg-2.4.tar/ffmpeg-2.4

./configure --prefix=./build --enable-shared --disable-static --enable-yasm --enable-libx264 --enable-gpl --target-os=mingw32 --arch=

x86_64 --extra-cflags="-I/C/Users/m/Downloads/x264-master.tar/x264-master/x264-master/build/include -Dx264_bit_depth=X2

64_BIT_DEPTH" --extra-ldflags="-L/C/Users/m/Downloads/x264-master.tar/x264-master/x264-master/build/lib"

make

make install

configure选项说明:

--prefix=./build 编译后安装的目标文件夹

--enable-shared 生成动态链接库

--enable-yasm 启用汇编优化功能

--enable-libx264 启用x264编码功能

--enable-gpl 使用x264功能必须启用的选项

--arch=x86_64 编译64位版本库,(如果是32位,使用--arch=x86)

-I 指定附加头文件目录,此处附加x264头文件的目录

-L 指定附加库目录,此处附加x264静态库文件的目录

-D 编译时定义宏,相当于#define x264_bit_depth X264_BIT_DEPTH,将x264_bit_depth替换。否则编译时出现如下错误:

编译成功后的ffmpeg库就在C:\Users\m\Downloads\ffmpeg-2.4.tar\ffmpeg-2.4\build目录下了。其中有四个目录

bin目录存放编译好的动态库文件和对应lib文件,ffmpeg程序。

而include文件夹内包含ffmpeg的头文件

lib文件夹包含libxxx.dll.a文件,对于mingw-g++,.a文件是静态库文件,因此只需要在编译链接时使用参数-lxxx.dll,就可以使用它了。通常静态库文件在运行时,不依赖额外的库文件。但是ffmpeg的libxxx.dll.a在运行时,还是需要bin文件夹内dll动态库文件的支持。这大概是库文件的名字带有dll的原因。

libxxx.dll.a类似于msvc的dll动态库文件所对应的lib文件。并不是一个完整的静态库文件。在被编译进程序后,运行时还是需要dll文件的支撑。

share文件夹内有一些程序例子


测试ffmpeg程序


ffmpeg -v

测试x264编码功能,将视频文件转换为x264编码


ffmpeg -i input.mp4 -vcodec libx264 out.mp4

转换成功


ffmpeg hello word

msvc:

新建一个控制台工程

主程序编辑以下代码


#define __STDC_CONSTANT_MACROS

#include "stdafx.h"



//因为ffmpeg是用c语言写的,对于fmpeg的头文件,需要用extern "C" 修饰,以正常使用它的库

extern "C"

{

#include "libavutil/log.h"

};



int _tmain(int argc, _TCHAR* argv[])

{

    // 设置控制台输出级别

    av_log_set_level(AV_LOG_DEBUG);

    // 打印输出字符串Hello World !

    av_log(NULL, AV_LOG_DEBUG, "%s", "Hello World !\n");

    av_log(NULL, AV_LOG_DEBUG, "%s", "Hello World !\n");

    system("pause");

    return 0;

}


配置头文件目录为ffmpeg库的include文件夹

你还可能需要下载msinttypes-r26.zip这个文件并解压。其中包括c99标准的两个头文件inttypes.h,stdint.h。并将解压后的目录也加入项目头文件附加包含目录里面

配置附加库目录为ffmpeg库目录里bin文件夹

配置要链接的库,就是ffmpeg库的bin文件夹里面所有的lib文件名

将ffmpeg库的bin文件夹里面的dll文件拷贝到程序目录下

之后点击编译运行

mingw:

用记事本编辑一个源程序

helloword.cpp




extern "C"

{

#include "libavutil/log.h"

};



int main(int argc, char* argv[])

{

    // 设置控制台输出级别

    av_log_set_level(AV_LOG_DEBUG);

    // 打印输出字符串Hello World !

    av_log(NULL, AV_LOG_DEBUG, "%s", "Hello World !\n");

    av_log(NULL, AV_LOG_DEBUG, "%s", "Hello World !\n");

    system("pause");

    return 0;

}

使用如下命令编译


g++ helloword.cpp -D__STDC_CONSTANT_MACROS -I../build/include -L../build/lib -lavcodec.dll -lavdevice.dll -lavfilter.dll -lavformat.dll -lavutil.dll -lswresample.dll -lswscale.dll

-D__STDC_CONSTANT_MACROS 定义__STDC_CONSTANT_MACROS宏

-I 指定头文件目录,也就是fffmpeg库的include文件夹

-L 指定库文件目录,也就是ffmpeg库的lib文件夹

-lxxx 指定链接的库文件,也就是ffmpeg库的lib文件夹内libxxx.dll.a。在链接参数-l中,需要去掉lib前缀和.a后缀

编译通过后,同样的将ffmpeg库的bin目录下的所有dll文件拷贝到程序所在目录,之后运行程序


./a.exe


之前在使用mysys2进行编译时,我会遇到以下问题

通过使用参数--target-os=mingw32可以得到解决,而之后的问题

无法解决,因此只能使用mysys-1.0.11进行编译,并且使用mysys-1.0.11不会遇到以上的问题