Ubuntu20配置ffmpeg进行gpu硬件加速视频编码记录

Posted 小俊俊的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ubuntu20配置ffmpeg进行gpu硬件加速视频编码记录相关的知识,希望对你有一定的参考价值。

Ubuntu20配置ffmpeg进行gpu硬件加速视频编码记录

https://blog.csdn.net/qq_36383272/article/details/116304060?spm=1001.2014.3001.5501
https://blog.csdn.net/qq_36383272/article/details/118569908

现有环境

1.Ubuntu:20
2.显卡驱动:470
3.Cuda:11.1+cudnn

1.获取ffmpeg源码

git clone https://git.ffmpeg.org/ffmpeg.git

注:这个是最新的源码,对于较老的驱动需要自行去官网匹配。

2.安装aac、h264、h265库

sudo apt-get install libfdk-aac-dev libx264-dev libx265-dev

注:这个要在编译ffmpeg之前安装

3.安装ffnvcodec

git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git
cd nv-codec-headers
make
sudo make install

4.编译ffmpeg

终端进入ffmpeg文件夹,输入如下指令进行配置
静态配置:

./configure --prefix="/usr/local" --pkg-config-flags="--static"  --disable-asm --enable-gpl --enable-libx264 --enable-libx265 --enable-nonfree --enable-libfdk-aac --enable-ffplay

动态配置的指令:

./configure --prefix="/usr/local" --enable-shared --disable-static --disable-asm --enable-gpl --enable-libx264 --enable-libx265 --enable-nonfree --enable-libfdk-aac --enable-ffplay

选一个就可以。
在config后会输出

遇到:License: nonfree and unredistributable以及后面的东西,可以直接下一步。
接下来编译安装

make -j16
sudo make install

5.验证

ffmpeg -codecs | grep nv


这样就成功了,接下来进行测试。

6.测试

1.下载测试视频
本次使用原win7中的自带视频,Wildlife.wmv和Wildlife.yuv
链接: https://pan.baidu.com/s/1cmZy0sfyklJgBIcxQLkxmg 提取码: bw6k
2.测试
cpu测试指令

./ffmpeg -s 1280x720 -i Wildlife.yuv -c:v libx265 -c:a aac output.mp4

效果

Gpu测试指令

./ffmpeg -s 1280x720 -i Wildlife.yuv -c:v h264_nvenc -c:a aac output.mp4


cpu帧率fps=64.5
gpu帧率fps=806

7.python调用代码

import threading
import os
import time
from datetime import datetime

def thread_func(num): 
 os.system('/home/cj/work/gpu_ffmpeg/ffmpeg/ffmpeg -i /home/cj/work/video_gpu/test.avi -c:v h264_nvenc -b:v 5M ml%s.mp4 >>video_output.log 2>&1' % num)
 print('num=', num)

def many_thread(num):
 threads = []
 for i in range(num):
     t = threading.Thread(target=thread_func, args=(i,))
     threads.append(t)
 for t in threads:
     t.start()


if __name__ == '__main__':
 many_thread(1)

最后一行是并发数设置,这个需要和显卡性能匹配,查看网址为:
https://developer.nvidia.com/video-encode-and-decode-gpu-support-matrix-new

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函数中

参考网站

以上是关于Ubuntu20配置ffmpeg进行gpu硬件加速视频编码记录的主要内容,如果未能解决你的问题,请参考以下文章

ffmpeg 的硬件加速不起作用

FFmpeg 硬件加速介绍

FFmpeg使用显卡进行转码硬件加速的记录,以及和软压的比较

beaglebone black 是不是支持 gpu 硬件加速?

基于FFmpeg+VAAPI的硬件加速渲染技术

Keras学习环境配置-GPU加速版(Ubuntu 16.04 + CUDA8.0 + cuDNN6.0 + Tensorflow)