为了搞硬件加速编解码,用了一周时间来看 CUDA,接下来开始加以总结。
参看:百度百科 -- CUDA
参看:CUDA基础介绍
参看:cuda入门
参看:CUDA知识普及
参看:CUDA学习笔记
CUDA (Compute Unified Device Architecture,统一计算设备架构),是显卡厂商 NVIDIA 在2007年推出的并行计算平台和编程模型。它利用图形处理器 (GPU) 能力,实现计算性能的显著提高。CUDA 是一种由 NVIDIA 推出的通用并行计算架构,该架构使 GPU 能够解决复杂的计算问题,从而能通过程序控制底层的硬件进行计算。它包含了CUDA 指令集架构 (ISA) 以及 GPU 内部的并行计算引擎。开发人员可以使用 C/C++/C++11 语言来为 CUDA 架构编写程序。CUDA 提供 host-device 的编程模式以及非常多的接口函数和科学计算库,通过同时执行大量的线程而达到并行的目的。
参看:CUDA Legacy GPUs
包含 GeForce、ION、Quadro、Tesla 等系列。
举个栗子:
我们用的是 NVIDIA GeForce GTX 1070 新出的上面莫有.... 不过点击 GeForce Desktop Products 还是可以看到相关信息的。参看:极致性价比 GeForce GTX 1070首发评测
CUDA 支持 Windows, Linux 和 Mac OS 的操作系统。
下载最新版本:CUDA Toolkit 下载地址
下载以往版本:Archived Releases
前面有讲 CUDA 支持 Windows, Linux 和 Mac OS 的操作系统。 我们主要介绍Windows 和 Linux 下的安装。
参看:CUDA Toolkit Documentation v8.0
与其他版本相比添加了哪些内容:
参看:Release Notes
Linux下的安装
参看:NVIDIA CUDA Installation Guide for Linux
参看:Ubuntu16.04安装CUDA+cuDNN+GPU版TensorFlow过程记录
$ lspci | grep -i nvidia
如果您没有看到任何设置,更新 Linux 的 PCI 硬件数据库维护通过输入 update-pciids (一般在/ sbin)在命令行并重新运行之前 lspci 命令。
你也可以参看: CUDA Legacy GPUs ,确认你的GPU 是否支持CUDA-capable。
$ gcc --version
$uname - r
这是在安装 CUDA 驱动程序之前必须安装的内核头文件和开发包的版本。 下面将多次使用此命令来指定要安装的软件包的版本。 请注意,以下是内核使用的常见情况。 更高级的案例(如自定义内核分支)应确保其内核头和源与正在运行的内核构建相匹配。我只介绍 Ubuntu 下的,其他操作系统的请自行查看。
Ubuntu 当前运行的内核的内核头文件和开发包安装:
$ sudo apt-get install linux-headers-$(uname -r)
上面这句话到到半天,其意思就是选择安装版本选择 runfile [local]
下载最新版本:CUDA Toolkit 下载地址
$ sudo /usr/local/cuda-X.Y/bin/uninstall_cuda_X.Y.pl
使用以下命令卸载一个runfile 驱动安装:$ sudo /usr/bin/nvidia-uninstall
使用下面的命令卸载一个RPM / Deb安装:$ sudo apt-get --purge remove # Ubuntu
我只介绍 Ubuntu 下的,其他操作系统的请自行查看。
$ sudo dpkg -i cuda-repo-__.deb
$ sudo apt-get update
$ sudo apt-get install cuda
$ cat /var/lib/apt/lists/*cuda*Packages | grep "Package:" # Ubuntu
$ sudo apt-get install cuda # Ubuntu
cuda-cross
$ sudo apt-get install cuda-drivers # Ubuntu
某些桌面环境(例如GNOME或KDE)将在新软件包可用时显示通知警报。$ lsmod | grep nouveau
在/etc/modprobe.d/blacklist-nouveau.conf中创建一个文件,内容如下:
blacklist nouveau
options nouveau modeset=0
重新生成内核initramfs:
$ sudo update-initramfs -u
$ sudo sh cuda__linux.run
安装程序将提示以下内容:#!/bin/bash
/sbin/modprobe nvidia
if [ "$?" -eq 0 ]; then
# Count the number of NVIDIA controllers found.
NVDEVS=`lspci | grep -i NVIDIA`
N3D=`echo "$NVDEVS" | grep "3D controller" | wc -l`
NVGA=`echo "$NVDEVS" | grep "VGA compatible controller" | wc -l`
N=`expr $N3D + $NVGA - 1`
for i in `seq 0 $N`; do
mknod -m 666 /dev/nvidia$i c 195 $i
done
mknod -m 666 /dev/nvidiactl c 195 255
else
exit 1
fi
/sbin/modprobe nvidia-uvm
if [ "$?" -eq 0 ]; then
# Find out the major device number used by the nvidia-uvm driver
D=`grep nvidia-uvm /proc/devices | awk '{print $1}'`
mknod -m 666 /dev/nvidia-uvm c $D 0
else
exit 1
fi
$ export PATH=/usr/local/cuda-8.0/bin${PATH:+:${PATH}}
另外,当使用 runfile 安装方法时,LD_LIBRARY_PATH 变量需要在 64 位系统上包含 /usr/local/cuda-8.0/lib64,或 32 位系统上的 /usr/local/cuda-8.0/lib$ export LD_LIBRARY_PATH=/usr/local/cuda-8.0/lib64\
${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
要更改32位操作系统的环境变量:
$ export LD_LIBRARY_PATH=/usr/local/cuda-8.0/lib\
${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
需要注意,使用带有runfile安装方法的自定义安装路径时,上述路径会发生变化。
$ cuda-install-samples-8.0.sh
该脚本与cuda-samples-8-0软件包一起安装。 cuda-samples-8-0软件包仅在/usr/local/cuda-8.0/samples中安装只读副本。
$ setenforce 0
从命令行作为超级用户。$ sudo /usr/local/cuda-8.0/bin/uninstall_cuda_8.0.pl
要卸载NVIDIA驱动程序,请运行nvidia-uninstall:
$ sudo /usr/bin/nvidia-uninstall
要启用 Nouveau 驱动程序,请删除在《2》禁止 Nouveau 驱动 部分中创建的黑名单文件,并按照该部分所述重新生成内核 initramfs/initrd。
Windows 下的安装 (以后再写)
参看:CUDA Installation Guide for Microsoft Windows、
参看:ffmpeg再学习 -- Linux 安装说明
写的很清楚了,然后主要是 x264 和 mp3lame 需要下载安装。
再然后,写配置脚本:
#! /bin/bash
./configure \
--enable-shared \
--disable-static \
--disable-yasm \
--disable-doc \
--enable-gpl \
--enable-pthreads \
--disable-w32threads \
--disable-os2threads \
--enable-debug \
--enable-nvenc \
--enable-cuda \
--enable-cuvid \
--extra-cflags="-Invidia_sdk -I/usr/local/cuda-8.0/include" \
--extra-ldflags="-Lnvidia_sdk -L/usr/local/cuda-8.0/lib64" \
--enable-nonfree \
--enable-libfreetype \
--enable-libfontconfig \
--enable-libnpp \
--enable-gpl \
--prefix=/usr/local/ffmpeg \
--enable-libx264 \
--enable-libmp3lame \
里面就有说明硬编/解码的类型了,这里面还有一些性能比较。我就不一一说明了。
从硬件上来说,Nvidia GPU有一到多个编解码器(解码器又称硬件加速引擎),它们独立于CUDA核。从视频格式上来说,编码支持H.264、H.265、无损压缩,位深度支持8bit、10bit,色域空间支持YUV 4:4:4和4:2:0,分辨率支持最高8K;解码支持MPEG-2、VC1、VP8、VP9、H.264、H.265、无损压缩,位深度支持8 bit、10bit、12bit,色域空间支持YUV 4:2:0,分辨率支持最高8K。Video Codec SDK已经被集成在ffmpeg工程中,但是ffmpeg对编解码器配置参数较少,如果需要充分的发挥编解码器特性,还需要直接使用SDK进行编程。
上述编解码的比较:
参看:说说4K硬解那些事儿【转自超能网】
参看:FFmpeg / libav
FFmpeg GPU HW加速的支持表:
将单个H.264解码为YUV
要将单个H.264编码的基本比特流文件解码为YUV,请使用以下命令:
FFMPEG: ffmpeg -vsync 0 -c:v h264_cuvid -i -f rawvideo
LIBAV: avconv -vsync 0 -c:v h264_cuvid -i -f rawvideo
将单个YUV文件编码为比特流FFMPEG: ffmpeg -f rawvideo -s:v 1920x1080 -r 30 -pix_fmt yuv420p -i -c:v h264_nvenc -preset slow -cq 10 -bf 2 -g 150
LIBAV: avconv -f rawvideo -s:v 1920x1080 -r 30 -pix_fmt yuv420p -i -c:v h264_nvenc -preset slow -cq 10 -bf 2 -g 150
HEVC (No B-frames)FFMPEG: ffmpeg -f rawvideo -s:v 1920x1080 -r 30 -pix_fmt yuv420p -i -vcodec hevc_nvenc -preset slow -cq 10 -g 150
LIBAV: avconv -f rawvideo -s:v 1920x1080 -r 30 -pix_fmt yuv420p -i -vcodec hevc_nvenc -preset slow -cq 10 -g 150
转码单个视频文件FFMPEG: ffmpeg -hwaccel cuvid -c:v h264_cuvid -i -vf scale_npp=1280:720 -c:v h264_nvenc
LIBAV: avconv -hwaccel cuvid -c:v h264_cuvid -i -vf scale_npp=1280:720 -c:v h264_nvenc
将单个视频文件转换为N个流FFMPEG: ffmpeg -hwaccel cuvid -c:v h264_cuvid -i -vf scale_npp=1280:720 -vcodec h264_nvenc -vf scale_npp 640:480 -vcodec h264_nvenc
LIBAV: avconv -hwaccel cuvid -c:v h264_cuvid -i -vf scale_npp=1280:720 -vcodec h264_nvenc -vf scale_npp 640:480 -vcodec h264_nvenc
将一张图片循环20000次生成视频,一个是硬编码一个是软编码,比较它们运行时间。
# time ./ffmpeg -f image2 -stream_loop 20000 -i 1.jpg -vcodec h264_nvenc -b:v 200k -r 10 -s 1920x1080 -y 2.mp4
# time ./ffmpeg -f image2 -stream_loop 20000 -i 1.jpg -vcodec libx264 -b:v 200k -r 10 -s 1920x1080 -y 2.mp4