超详细-Docker中使用CUDA加速FFMPEG和OPENCV实现视频硬解编码
由于许多博客都是编译旧版,故本文基于CUDA12.0+CUDNN8编译opencv-4.8.0,ffmpeg-5.1,使用最新的Video_Codec_SDK_12.2.72,该记录过程避免大家踩坑
1. 宿主机显卡驱动
2. 安装Nvidia-docker
- 可参考我的另一篇博客Win11的WSL2使用Docker部署深度学习环境-Python和Docker基操中的Linux系统Docker安装命令
3. 拉取cuda和cudnn镜像
- 进入docker hub拉取自己需要的cuda和cudnn镜像(如果想自己安装cuda和cudnn可参考我的另一篇博客全网最详细搭建Win10+WSL2+Ubuntu-22.04LTS+CUDA+Xfce4+noVNC个人工作站,里面有讲到如何安装cuda和cudnn,图方便可直接通过
docker pull nvidia/cuda:12.0.1-cudnn8-devel-ubuntu20.04
拉取),我使用的版本如下:
4. 创建容器
docker run -dit --gpus all -h meiwu -e NVIDIA_DRIVER_CAPABILITIES=compute,utility,video --name opencv_cuda nvidia/cuda:12.0.1-cudnn8-devel-ubuntu20.04 bash
- 注意:其中
--gpus all
和-e NVIDIA_DRIVER_CAPABILITIES=compute,utility,video
为必需指令,不可缺少
5. 编译FFMPEG
- 安装编译工具和依赖
apt update apt-get update apt upgrade apt-get upgrade apt install -y libreadline-dev libbz2-dev libsm6 libxrender1 libxext-dev libgomp1 liblzma-dev libgl1-mesa-glx libprotobuf-dev protobuf-compiler libglib2.0-0 mpich openmpi-bin libopenmpi-dev libass-dev apt-get install -y gcc g++ make cmake zlib1g zlib1g-dev openssl libsqlite3-dev libssl-dev libffi-dev unzip pciutils net-tools libblas-dev gfortran libblas3 libopenblas-dev git-lfs libswresample-dev autoconf automake build-essential libass-dev libfreetype6-dev libsdl2-dev libtheora-dev libtool libva-dev libvdpau-dev libvorbis-dev libxcb1-dev libxcb-shm0-dev libxcb-xfixes0-dev pkg-config texinfo zlib1g-dev yasm libx264-dev libx265-dev libvpx-dev libfdk-aac-dev libmp3lame-dev libopus-dev
- 下载编译nv-codec-headers-sdk
- 通过
git clone https://github.com/FFmpeg/nv-codec-headers.git
下载nv-codec-headers-sdk,我使用的是sdk/12.0版本,使用git checkout sdk/12.0
版本切换 - 使用
sudo make -j&(nproc)
和sudo make install
进行编译和安装
- 通过
- 进入Video Codec SDK根据自己的需求下载对应的SDK,与FFMPEG的对应关系自行看官方文档,我使用的是最新版本Video_Codec_SDK_12.2.72。将对应的头文件和动态链接库COPY到CUDA中:
cp ./Video_Codec_SDK_12.2.72/Lib/linux/stubs/x86_64/* /usr/local/cuda/lib64/stubs cp ./Video_Codec_SDK_12.2.72/Interface/* /usr/local/cuda/include cp ./Video_Codec_SDK_12.2.72/Lib/linux/stubs/x86_64/* /usr/local/cuda-12.0/lib64/stubs cp ./Video_Codec_SDK_12.2.72/Interface/* /usr/local/cuda-12.0/include cp ./Video_Codec_SDK_12.2.72/Interface/* /usr/include
- 下载FFMPEG并解压
wget http://ffmpeg.org/releases/ffmpeg-5.1.tar.gz && tar zxvf ffmpeg-5.1.tar.gz
- 编译FFMPEG,cd到ffmpeg-5.1文件夹下
./configure --prefix=/usr/local/ffmpeg --disable-asm --disable-x86asm \ --enable-cuda --enable-cuvid --enable-nvenc \ --enable-nonfree --enable-libnpp \ --extra-cflags=-I/usr/local/cuda/include \ --extra-cflags=-fPIC --extra-ldflags=-L/usr/local/cuda/lib64 \ --enable-gpl --enable-libx264 --enable-libx265 \ --enable-shared \ --enable-libass \ --enable-libfdk-aac \ --enable-libfreetype \ --enable-libmp3lame \ --enable-libopus \ --enable-libtheora \ --enable-libvorbis make -j&(nproc) sudo make install
- 配置环境变量
sudo vi /root/.bashrc export FFMPEG_HOME=/usr/local/ffmpeg export PATH=$PATH:$FFMPEG_HOME/bin export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$FFMPEG_HOME/lib export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$FFMPEG_HOME/lib/pkgconfig:/usr/local/lib source ~/.bashrc
- 测试和硬解码成功
ffmpeg -i test.mp4 -c:v h264_nvenc -c:a aac output.mp4
ffmpeg -codecs | grep cuvid
查看cuvid支持的编解码协议
6. 编译OPENCV
-
下载opencv和opencv_contrib
git clone https://github.com/opencv/opencv.git cd opencv git checkout 4.8.0 git clone https://github.com/opencv/opencv_contrib.git cd opencv_contrib git checkout 4.8.0
-
修改OpenCVDetectCUDA.cmake,加入
"/usr/include" "/usr/local/include/ffnvcodec"
vi opencv/cmake/OpenCVDetectCUDA.cmake
-
添加libnvcuvid.so软连接
sudo ln -s /usr/lib/x86_64-linux-gnu/libnvcuvid.so.1 /usr/lib/x86_64-linux-gnu/libnvcuvid.so
-
修改opencv_contrib的cudacodec CMakeLists.txt文件
vi opencv_contrib/modules/cudacodec/CMakeLists.txt # 增加以下内容 include_directories(/usr/local/include/ffnvcodec)
-
安装numpy
pip install numpy==1.24.4
-
修改precomp.hpp,增加nvcuvid头文件
vi /home/meiwu/opencv_contrib/modules/cudacodec/src/precomp.hpp # 增加以下内容 #include <nvcuvid.h>
-
开始编译,cd到opencv目录下执行,其中cmake参数太多就不一一讲解,具体含义可自行查找资料
mkdir build cd build cmake -D CMAKE_BUILD_TYPE=RELEASE \ -D CMAKE_INSTALL_PREFIX=/usr/local \ -D INSTALL_PYTHON_EXAMPLES=ON \ -D INSTALL_C_EXAMPLES=ON \ -D BUILD_opencv_python2=OFF \ -D BUILD_opencv_python3=ON \ -D BUILD_opencv_cudacodec=ON \ -D BUILD_TIFF=ON \ -D ENABLE_FAST_MATH=1 \ -D OPENCV_EXTRA_MODULES_PATH=/home/opencv_contrib/modules \ -D PYTHON3_EXECUTABLE=/home/envpy3.8/bin/python3.8 \ -D PYTHON3_INCLUDE_DIR=/home/envpy3.8/include/python3.8 \ -D PYTHON3_LIBRARY=/home/envpy3.8/lib/libpython3.8.so \ -D PYTHON3_NUMPY_INCLUDE_DIRS=/home/envpy3.8/lib/python3.8/site-packages/numpy/core/include \ -D PYTHON3_PACKAGES_PATH=/home/envpy3.8/lib/python3.8/site-packages \ -D PYTHON_DEFAULT_EXECUTABLE=/home/envpy3.8/bin/python3.8 \ -D OPENCV_PYTHON3_INSTALL_PATH=/home/envpy3.8/lib/python3.8/site-packages \ -D OPENCV_ENABLE_NONFREE=ON \ -D WITH_LIBV4L=ON \ -D WITH_CUBLAS=1 \ -D WITH_CUDA=ON \ -D WITH_CUDNN=ON \ -D WITH_TBB=ON \ -D WITH_GTK_2_X=ON \ -D WITH_OPENCL=ON \ -D WITH_FFMPEG=ON \ -D WITH_NVCUVID=ON \ -D CUDA_ARCH_BIN=8.6 \ -D CUDA_FAST_MATH=1 \ -D WITH_V4L=ON .. make -j&(nproc) make install
NVIDIA CUDA
中得为YES并且出现NVCUVID
才算配置成功 -
测试验证
>>> import cv2 >>> cv2.__version__ '4.8.0' >>> video_gpu = cv2.cudacodec.createVideoReader('/home/meiwu/test.mp4') >>> _, img_gpu = video_gpu.nextFrame() >>> img_cpu = img_gpu.download() >>> img_cpu.shape (720, 1280, 4)
-
安装低版本(4.2以下)的opencv,编译过程中可能会缺少以下文件:
boostdesc_bgm.i boostdesc_bgm_bi.i boostdesc_bgm_hd.i boostdesc_lbgm.i boostdesc_binboost_064.i boostdesc_binboost_128.i boostdesc_binboost_256.i vgg_generated_120.i vgg_generated_64.i vgg_generated_80.i vgg_generated_48.i
将以上的文件cp至
opencv_contrib/modules/xfeatures2d/src/
,百度网盘分享链接如下:链接:https://pan.baidu.com/s/1hnIopHg_BfuXLd1tv3e0Hw 提取码:f7a2
若要转载请注明出处🚀,谢谢💕💕