FFmpeg使用显卡进行转码硬件加速的记录,以及和软压的比较
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FFmpeg使用显卡进行转码硬件加速的记录,以及和软压的比较相关的知识,希望对你有一定的参考价值。
参考技术A 操作系统:Windows 10
FFmpeg版本:20171204
显卡:GTX 965M
最近是有比较多的压制需求,使用libx265软压的速度实在是慢的受不了,所以还是希望能用显卡硬压起码速度快一点。之前有人跟我提过硬压质量似乎不及软压,但是决定还是试一试。在ffmpeg官网找到硬压的 相关信息 。
由于我用的是windows,所以驱动基本没有特别配置。而且windows版的ffmpeg也是参数配置好的,所以这方面没有考虑太多。linux平台可能需要配置一下参数啥的。
压制分为两步,先是对视频解码再编码。ffmpeg在两步都提供了硬件加速方案。
在官网给出的例子是基于h264的,h265的硬件参数啥的可以用:
ffmpeg -codecs | sls cuvid (备注:sls是powershell的命令,类似于linux下的grep命令)
可以看到这条:
DEV.L. hevc H.265 / HEVC (High Efficiency Video Coding) (decoders: hevc hevc_qsv hevc_cuvid ) (encoders: libx265 nvenc_hevc hevc_nvenc hevc_qsv )
解码器提供了 hevc , hevc_qsv , hevc_cuvid ; 编码器提供了 libx265 , nvenc_hevc , hevc_nvenc , hevc_qsv ,但是这个 nvenc_hevc 其实已经作废了,你用它的话他会提示你自动给你转到 hevc_nvenc 。
解码器的这三个用法我是不太懂有啥区别,也没去做太多研究,因为在实践中使用硬解的话是没办法同时硬压字幕的,会报错,况且硬解对于整体压制速度并没有太大提升,所以就抛弃硬解了。
编码器的部分, libx265 就是软压, hevc_qsv 似乎是英特尔的集显硬压,具体看 这里 。那么留给n卡的只有 hevc_nvenc 可以用了。
使用这条命令来查看该方法的参数:
ffmpeg -h encoder=hevc_nvenc
可以得到可用参数,我们这里探究的是-cq参数,给出的描述是:
-cq <float> E..V.... Set target quality level (0 to 51, 0 means automatic) for constant quality mode in VBR rate control (from 0 to 51) (default 0)
我感兴趣的原因是它和libx265,也就是软压的-crf参数很类似。所以接下来都是在其他参数不考虑的情况下对不同cq的对比。
我用的是谍影重重5的预告片压制测试,原视频数据如下:
在使用命令
ffmpeg -i original.mov -c:v hevc_nvenc -cq X cqx.mp4
进行测试后。结果如下:
Libx265 (软压)
-cq 0(默认)
-cq 1
-cq 10
-cq 20
-cq 30
-cq 35
-cq 38
-cq 41
-cq 51
对比视频在 这里 。
可以看到cq在1到30的变化并不大,在41以上画面基本上是没办法看了。在和libx265的默认软压对比后,-cq值落在35到40之间是比较好的选择。
在后续的实际应用中,我在压制画面动作较少的视频,如交响乐视频的情况下,-cq 37是一个对于我来说比较好的选择。
ffmpeg使用硬件加速hwaccelcuvidh264_cuvidh264_nvenc
文章目录
ffmpeg支持硬件加速的原理
ffmpeg的硬件加速原理大概就是采用硬件对编解码进行处理,硬件有转码进行解码的sdk,比如nvidia的sdk等
所用环境说明
- ffmpeg版本:4.2.2
- cuda版本:10.2
- nvidia驱动版本:470.57.02
先放一个结论:GPU的解码肯定是要比CPU快的,但前提是两个都是差不对水平的硬件,而且GPU的成本相对CPU来说要低很多;比如我的测试机,一个GTX970M的显卡,基本跟一个7700k的i7差不多(甚至更好)了;
ffmpeg使用硬件加速
安装nvidia驱动
从官网下载NVIDIA-Linux-x86_64-470.57.02.run,直接安装
安装cuda
下载cuda_10.2.89_440.33.01_linux.run也是直接安装
安装完成后修改profile,将cuda中的bin目录写到path中
sudo vi /etc/profile
export PATH=/usr/local/cuda/bin:$PATH
让配置生效
source /etc/profile
验证是否找到了nvcc
nvcc --version(或者nvcc -V)
输出如下内容
加入header
git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git
make
sudo make install
安装pkgconfig
sudo apt-get install pkgconfig
开始配置
由于使用到了硬件加速,那么在配置configure中也需要将其加入进来
./configure --prefix=/usr/local/ffmpeg --enable-gpl --enable-nonfree --enable-pthreads --extra-cflags=-g --extra-cflags=-O0 --extra-libs=-lstdc++ --extra-cxxflags=-g --extra-cxxflags=-O0 --extra-cxxflags=-fpermissive --enable-debug=3 --disable-optimizations --disable-stripping --disable-x86asm --enable-cuda-nvcc --enable-cuvid --enable-shared --enable-nvenc --enable-shared
接着执行make,产生ffmpeg可执行文件
在ffmpeg中看如何使用硬件加速
假设在ffmpeg工程文件夹下有有个1.mp4的文件
查看目前可以用的hwaccel选项
./ffmpeg -hwaccels
出现如下内容
普通的解码命令
cpu解码
./ffmpeg -i aa.mp4 output2.yuv -y
gpu解码
./ffmpeg -c:v h264_cuvid -i aa.mp4 -c:v h264_nvenc output.yuv -y
仅仅是转码,不做缩放
./ffmpeg -c:v h264_cuvid -i a.mp4 -c:a copy -vf "format=yuv420p,hwupload_cuda" -c:v h264_nvenc 2.mp4 -y
转码,外带一个缩放
cpu操作命令
./ffmpeg -i a.mp4 -vf scale=1280:720 2.mp4 -y
gpu操作命令
./ffmpeg -c:v h264_cuvid -i a.mp4 -c:a copy -vf "format=yuv420p,hwupload_cuda,scale_cuda=1280:720" -c:v h264_nvenc -b:v 5M 2.mp4 -y
题外话,如何使用scale_npp
配置configure中需要将其加进来
./configure --prefix=/usr/local/ffmpeg --enable-gpl --enable-nonfree --enable-pthreads --extra-cflags=-g --extra-cflags=-O0 --extra-libs=-lstdc++ --extra-cxxflags=-g --extra-cxxflags=-O0 --extra-cxxflags=-fpermissive --enable-debug=3 --disable-optimizations --disable-stripping --disable-x86asm --enable-cuda-nvcc --enable-cuvid --enable-shared --enable-nvenc --enable-shared --enable-libnpp --extra-cflags=-I/usr/local/cuda/include --extra-ldflags=-L/usr/local/cuda/lib64
make后得到的ffmpeg,启动这个快速的缩放命令
./ffmpeg -hwaccel cuvid -c:v h264_cuvid -i aa.mp4 -c:v h264_nvenc -b:v 2048k -vf scale_npp=1280:-1 -y 2.mp4
在ffmpeg4.2.2上编译后使用上面的命令会报错,提示找不到npp这个滤镜;重新到GitHub拉去4.4后,重新configure、make后执行通过,测试如下
同一个视频平均才18.7X,GPU使用率最大不到15%;比使用scale_cuda来做缩放要慢一点,以下是同一个视频采用scale_cuda来缩放的速度
测试的命令分别如下
./ffmpeg -c:v h264_cuvid -i aa.mp4 -c:a copy -vf "format=yuv420p,hwupload_cuda,scale_cuda=1280:720" -c:v h264_nvenc -b:v 2048k 2.mp4 -y
./ffmpeg -hwaccel cuvid -c:v h264_cuvid -i aa.mp4 -c:a copy -c:v h264_nvenc -b:v 2048k -vf scale_npp=1280:720 2.mp4 -y
简单分析一下ffmpeg源码中的硬件加速部分
在cuviddec.c中的cuvid_decode_packet函数,其中的一行代码是这样的
ret = CHECK_CU(ctx->cvdl->cuvidParseVideoData(ctx->cuparser, &cupkt));
这个函数在dynlink_nvcuvid.h中有对应的声明
/************************************************************************************************/
//! \\ingroup FUNCTS
//! \\fn CUresult CUDAAPI cuvidParseVideoData(CUvideoparser obj, CUVIDSOURCEDATAPACKET *pPacket)
//! Parse the video data from source data packet in pPacket
//! Extracts parameter sets like SPS, PPS, bitstream etc. from pPacket and
//! calls back pfnDecodePicture with CUVIDPICPARAMS data for kicking of HW decoding
//! calls back pfnSequenceCallback with CUVIDEOFORMAT data for initial sequence header or when
//! the decoder encounters a video format change
//! calls back pfnDisplayPicture with CUVIDPARSERDISPINFO data to display a video frame
/************************************************************************************************/
typedef CUresult CUDAAPI tcuvidParseVideoData(CUvideoparser obj, CUVIDSOURCEDATAPACKET *pPacket);
整个流程详细的内容差不多都在cuviddec.c中的cuvid_output_frame函数中
参考网站
- ffmpeg安装ERROR: cuvid requested
- FFmpeg-Nvidia硬解码
- ffmpeg4.3 安装 in Ubuntu18.04
- NVIDIA FFmpeg 转码指南
- NVIDIA FFmpeg Transcoding Guide
- USING FFMPEG WITH NVIDIA
GPU HARDWARE
ACCELERATION - ffmpeg命令行使用nvidia CUDA scaling高速转分辨率转码(libnpp)
- 视频和视频帧:Intel GPU(核显)的编解码故事
- ffmpeg解码的软解及硬解(cuda和qsv)使用方法
- ffmpeg 采用cuda 硬编解码
- CUDA和FFMPEG硬件解码视频流
以上是关于FFmpeg使用显卡进行转码硬件加速的记录,以及和软压的比较的主要内容,如果未能解决你的问题,请参考以下文章
Ubuntu20配置ffmpeg进行gpu硬件加速视频编码记录
ffmpeg使用硬件加速hwaccelcuvidh264_cuvidh264_nvenc
ffmpeg使用硬件加速hwaccelcuvidh264_cuvidh264_nvenc