win11 + msys2
ffmpeg:4.4.2
Intel的硬件加速需要有集显的芯片。
ffmpeg启动qsv硬件加速需要先集成mfx的内容,先下载mfx的源码(GitHub - lu-zero/mfx_dispatch: Intel media sdk dispatcher),如果有版本要求,下载对应的版本,笔者这里使用的master分支代码。
代码下载完成后,移动到msys2用户目录下
进入mfx目录,mingw64.exe执行命令:
autoreconf -i
./configure --prefix=/mingw64
make -j4
make install
编译完成后,进入ffmpeg目录,进行配置ffmpeg
./configure --enable-shared --enable-static --arch=x86_64 --enable-postproc --enable-gpl --enable-libmfx --prefix=e:/ffmpeg --extra-cflags=-I/usr/local/include --extra-ldflags=-L/usr/local/lib --pkg-config="pkg-config --static"
至此intel的硬件加速就集成上了,可以写个demo输出一下codec,看看是否有xxx_qsv的编解码器。(后面会贴出代码)
ps:32位在编译的时候注意改一下安装目录,如果出现如下报错
打开Makefile.am文件,将下面四个*.a改成*.la
nvidia的硬件加速需要有nvidia显卡设备,并且有对应显卡驱动。
集成nvidia硬件加速需要先下载nvidia的声明文件(头文件),并安装起来。
下载地址:https://github.com/FFmpeg/nv-codec-headers
下载的时候要注意一下显卡驱动版本与这个声明文件的对应关系,过于领先的声明文件可能导致硬件加速异常。笔者下载的是11.0版本(8.0版本可能是太老了,ffmeg 4.4.2不支持)。
将对应文件移动到用户目录下,
进入 文件内,并make && make install
安装完成后,进入ffmpeg文件目录,执行
./configure --enable-shared --enable-static --arch=x86_64 --enable-postproc --enable-gpl --enable-libmfx --enable-cuvid --enable-nvenc --prefix=e:/ffmpeg --extra-cflags="-I/usr/local/include" --extra-ldflags=-L/usr/local/lib
并make && make install。
ps:nvidia硬件加速其实ffmpeg在配置的时候是自动检测的,安装了声明文件的设备并且成功检测到就会编译进去,理论上可以不增加 enable-cuvid和enable-nvenc配置项(亲测确实可以),但是不明确配置的话,如果找不到声明文件是不会报错的,到时候卡卡编译完一测试发现找不到对应编解码器就浪费时间了。
ok,集成完毕,运行demo输出一下codec
amf声明文件下载:https://github.com/GPUOpen-LibrariesAndSDKs/AMF
AMD显卡目前仅支持编码加速,不支持解码加速。
amf目前最新版本是1.4.26,官方给到的ffmpeg版本是4.3.2(见附带的ffmpeg),ffmpeg4.4.2的编译说明中,要求最低1.4.9。为了支持更多的驱动版本,笔者这里选择最低支持的版本。
下载完成后,在/usr/local/include目录下创建AMF文件夹,并且将下载的文件的./amf/public/include/ 下的两个文件夹拷贝到AMF文件夹下。
配置一下,然后编译安装吧。
./configure --enable-shared --enable-static --arch=x86_64 --enable-postproc --enable-gpl --enable-amf --prefix=e:/ffmpeg --extra-cflags="-I/usr/local/include -DAMF_CORE_STATICTIC" --extra-ldflags=-L/usr/local/lib
-DAMF_CORE_STATICTIC 这个选项,据说不配置会在运行的时候找不到某些dll文件,因为笔者暂时找不到amd的设备验证,所以先配置上。有环境验证的兄弟可以验证一下,把结果告诉我。
贴一下Intel,Nvidia,AMD三个硬件加速全部配置的命令
./configure --enable-shared --enable-static --arch=x86_64 --enable-postproc --enable-gpl --enable-libmfx --enable-amf --enable-cuvid --enable-nvenc --prefix=e:/ffmpeg --extra-cflags="-I/usr/local/include -DAMF_CORE_STATICTIC" --extra-ldflags=-L/usr/local/lib
结果:
头文件:stdafx.h
// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//
#pragma once
#include "targetver.h"
#include
#include
#include
extern "C"
{
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
};
#pragma comment(lib,"avcodec.lib")
#pragma comment(lib,"avformat.lib")
#pragma comment(lib,"avutil.lib")
代码文件(仅显示名称包含"26","aa","vc"的编解码器,不过滤的话太多了,不需要的话删除相关过滤代码)
#include "stdafx.h"
void printfCodec() {
char info[40000] = {0};
void *item = nullptr;
for (;;) {
const AVCodec *cur = av_codec_iterate(&item);
if (!cur) {
break;
}
int len = strlen(cur->name);
bool keeprun = false;
for (int i = 0; i < len - 1; ++i) {
if (cur->name[i] == '2' && cur->name[i + 1] == '6') {
keeprun = true;
break;
}
if (cur->name[i] == 'a' && cur->name[i + 1] == 'a') {
keeprun = true;
break;
}
if (cur->name[i] == 'v' && cur->name[i + 1] == 'c') {
keeprun = true;
break;
}
}
if (!keeprun) {
continue;
}
if (av_codec_is_decoder(cur) != 0) {
sprintf(info, "%s decoder:", info);
//continue;
} else {
sprintf(info, "%s encode:", info);
}
AVHWDeviceType tt = av_hwdevice_find_type_by_name(cur->name);
sprintf(info, "%s [%d]", info, tt);
switch (cur->type) {
case AVMEDIA_TYPE_VIDEO:
sprintf(info, "%s(video):", info);
break;
case AVMEDIA_TYPE_AUDIO:
sprintf(info, "%s(audio):", info);
break;
default:
sprintf(info, "%s(other):", info);
break;
}
sprintf(info, "%s[%10s]\n", info, cur->name);
}
printf(" %s \n",info);
}
int _tmain(int argc, _TCHAR* argv[])
{
printf(" %s \n",avcodec_configuration()); // 打印编译配置项
printf("\n");
printfCodec();
system("pause");
return 0;
}