opencv + cuda 實現視頻硬解碼


原文鏈接:https://note.youdao.com/ynoteshare/index.html?id=700052b0a49301059a34f20a00a830ca&type=note&_time=1638503513531

 

目錄:
 
一、教程目的(why)
實現基於Opencv的GPU視頻編解碼,並且可以使用RTSP協議采集IPC攝像頭h.264/h.265視頻
二、需要准備安裝包(what)
1.nvidia最新驅動.run
2.cuda10.1及對應cudnn+nvidia video codec sdk 9.1
3.ffmpeg最新版本+nv-codec-headers9.1
4.opencv4.2.0+opencv_contrib-4.2.0
 
0
 
三、配置步驟(how)
 
1.手動安裝最新nvidia驅動
使用ppa無法獲取最新驅動,因此手動安裝
 
注:安裝435版本以上
 
1)查看顯卡信息:
$ lspci | grep VGA #查看驅動信息 ubuntu-drivers devices
 
ps:查看驅動信息不顯示結果處理
 
2)下載驅動程序:
http://www.nvidia.cn/Download/index.aspx
選擇適合自己電腦的版本就可以,下載完之后是一個名稱為 NVIDIA-Linux-x86_64-xxx.xx.run 的文件。
 
3)禁用nouveau驅動
查看是否成功禁用
 
只要是安裝過NVIDIA顯卡驅動的,nouveau一般都被禁止了。可以通過命令
lsmod | grep nouveau
查看。如果沒有任何輸出就是禁用成功了。否則,請參考禁用步驟。
 
禁用步驟
1.創建/etc/modprobe.d/blacklist-nouveau.conf文件,你可以通過如下命令:
sudo gedit /etc/modprobe.d/blacklist-nouveau.conf
 
2.填入以下內容:
blacklist nouveau options nouveau modeset=0
 
3.重新生成kernel initramfs
sudo update-initramfs -u
 
4.重啟電腦
sudo reboot
 
4) 卸載原有驅動
sudo apt-get remove --purge nvidia*
 
5)安裝
sudo service lightdm stop sudo ./NVIDIA-Linux-x86_64-390.77.run sudo service lightdm start
 
如果提示unit lightdm.service not loaded
則先安裝LightDm: sudo apt install lightdm
安裝完畢后跳出一個界面,選擇lightdm,再sudo service lightdm stop
 
#使用ppa源安裝驅動(不推薦使用) sudo service lightdm stop sudo add-apt-repository ppa:graphics-drivers/ppa sudo apt- get update sudo apt-get install nvidia-(TAB鍵,可以看到有那些驅動) sudo apt-get install nvidia-396
 
6)驅動安裝選擇選項如下:
  • The distribution-provided pre-install script failed! Are you sure you want to continue? 選擇 yes 繼續。
  • Would you like to register the kernel module souces with DKMS? This will allow DKMS to automatically build a new module, if you install a different kernel later? 選擇 No 繼續。
  • Nvidia’s 32-bit compatibility libraries? 選擇 No 繼續。
  • Would you like to run the nvidia-xconfig utility to automatically update your x configuration so that the NVIDIA x driver will be used when you restart x? Any pre-existing x confile will be backed up. 選擇 Yes 繼續
 
7)驗證驅動安裝完成
nvidia-smi
 
2.CUDA10.1 +CUDNN+nvidia video codec sdk 9.1安裝
 
2.1 CUDA10.1安裝
 
1)在http://developer.nvidia.com/cuda-downloads上下載安裝包
0
你自己可以建個文件夾,然后在文件夾中輸入上述兩條命令:
sudo wget http://developer.nload.nvidia.com/compute/cuda/10.1/Prod/local_installers/cuda_10.1.243_418.87.00_linux.run$:sudo sh cuda_10.1.243_418.87.00_linux.run
 
2)再出現的提示中選擇continue和accept,直到出現如下畫面:
0
由於我之前已經安裝了Nvidia的顯卡驅動,這里不安裝driver,那么只需要移動到Driver,按enter鍵,將"[]"中的X去掉即是不選擇.然后在Install.
 
3)安裝成功
0
4)添加環境變量
sudo vi ~/.bashrc
 
在文件末尾添加
export PATH="/usr/local/cuda-10.1/bin:$PATH" export LD_LIBRARY_PATH="/usr/lcoal/cuda-10.1/lib64:$LD_LIBRARY_PATH"
 
最后使其生效
source ~/.bashrc
 
5)驗證安裝成功
 
終端輸入
cd /usr/local/cuda-10.1/samples/1_Utilities/deviceQuery sudo make./deviceQuery
 
0
出現Result = PASS則表示安裝成功通過!!
 
6)在終端輸入命令,實時查看GPU的使用情況:
watch -n 1 nvidia-smi
 
2.2 CUDNN安裝
 
1)官網下載https://developer.nvidia.com/rdp/cudnn-archive對應10.1版本cudnn
0
 
2) 找到對應版本下載安裝
解壓cudnn-10.1-linux-x64-v7.6.3.30.solitairetheme8的后綴名修改為tgz,然后用如下命令解壓
 
$ tar -xzvf cudnn-10.1-linux-x64-v7.6.3.30.tgz
 
拷貝.h 和 libs文件到cuda安裝目錄,並給予執行權限:
 
$ sudo cp cuda/include/cudnn.h /usr/local/cuda/include $ sudo cp cuda/lib64/libcudnn* /usr/local/cuda/lib64 $ sudo chmod a+r /usr/local/cuda/include/cudnn.h /usr/local/cuda/lib64/libcudnn*
 
 
可能問題
/sbin/ldconfig.real: /usr/local/cuda-11.1/targets/x86_64-linux/lib/libcudnn_ops_train.so.8 is not a symbolic link /sbin/ldconfig.real: /usr/local/cuda-11.1/targets/x86_64-linux/lib/libcudnn_adv_train.so.8 is not a symbolic link /sbin/ldconfig.real: /usr/local/cuda-11.1/targets/x86_64-linux/lib/libcudnn_cnn_infer.so.8 is not a symbolic link /sbin/ldconfig.real: /usr/local/cuda-11.1/targets/x86_64-linux/lib/libcudnn_ops_infer.so.8 is not a symbolic link /sbin/ldconfig.real: /usr/local/cuda-11.1/targets/x86_64-linux/lib/libcudnn_cnn_train.so.8 is not a symbolic link /sbin/ldconfig.real: /usr/local/cuda-11.1/targets/x86_64-linux/lib/libcudnn_adv_infer.so.8 is not a symbolic link /sbin/ldconfig.real: /usr/local/cuda-11.1/targets/x86_64-linux/lib/libcudnn.so.8 is not a symbolic link
解決方法
sudo ln -sf /usr/local/cuda-11.1/targets/x86_64-linux/lib/libcudnn_ops_train.so.8.0.2 /usr/local/cuda-11.1/targets/x86_64-linux/lib/libcudnn_ops_train.so.8 sudo ln -sf /usr/local/cuda-11.1/targets/x86_64-linux/lib/libcudnn_adv_train.so.8.0.2 /usr/local/cuda-11.1/targets/x86_64-linux/lib/libcudnn_adv_train.so.8 sudo ln -sf /usr/local/cuda-11.1/targets/x86_64-linux/lib/libcudnn_cnn_infer.so.8.0.2 /usr/local/cuda-11.1/targets/x86_64-linux/lib/libcudnn_cnn_infer.so.8 sudo ln -sf /usr/local/cuda-11.1/targets/x86_64-linux/lib/libcudnn_ops_infer.so.8.0.2 /usr/local/cuda-11.1/targets/x86_64-linux/lib/libcudnn_ops_infer.so.8 sudo ln -sf /usr/local/cuda-11.1/targets/x86_64-linux/lib/libcudnn_cnn_train.so.8.0.2 /usr/local/cuda-11.1/targets/x86_64-linux/lib/libcudnn_cnn_train.so.8 sudo ln -sf /usr/local/cuda-11.1/targets/x86_64-linux/lib/libcudnn_adv_infer.so.8.0.2 /usr/local/cuda-11.1/targets/x86_64-linux/lib/libcudnn_adv_infer.so.8 sudo ln -sf /usr/local/cuda-11.1/targets/x86_64-linux/lib/libcudnn.so.8.0.2 /usr/local/cuda-11.1/targets/x86_64-linux/lib/libcudnn.so.8
 
sudo ln -sf /usr/local/cuda-10.2/targets/x86_64-linux/lib/libcudnn_ops_train.so.8.0.3 /usr/local/cuda-10.2/targets/x86_64-linux/lib/libcudnn_ops_train.so.8 && \ sudo ln -sf /usr/local/cuda-10.2/targets/x86_64-linux/lib/libcudnn_adv_train.so.8.0.3 /usr/local/cuda-10.2/targets/x86_64-linux/lib/libcudnn_adv_train.so.8 && \ sudo ln -sf /usr/local/cuda-10.2/targets/x86_64-linux/lib/libcudnn_cnn_infer.so.8.0.3 /usr/local/cuda-10.2/targets/x86_64-linux/lib/libcudnn_cnn_infer.so.8 && \ sudo ln -sf /usr/local/cuda-10.2/targets/x86_64-linux/lib/libcudnn_ops_infer.so.8.0.3 /usr/local/cuda-10.2/targets/x86_64-linux/lib/libcudnn_ops_infer.so.8 && \ sudo ln -sf /usr/local/cuda-10.2/targets/x86_64-linux/lib/libcudnn_cnn_train.so.8.0.3 /usr/local/cuda-10.2/targets/x86_64-linux/lib/libcudnn_cnn_train.so.8 && \ sudo ln -sf /usr/local/cuda-10.2/targets/x86_64-linux/lib/libcudnn_adv_infer.so.8.0.3 /usr/local/cuda-10.2/targets/x86_64-linux/lib/libcudnn_adv_infer.so.8 && \ sudo ln -sf /usr/local/cuda-10.2/targets/x86_64-linux/lib/libcudnn.so.8.0.3 /usr/local/cuda-10.2/targets/x86_64-linux/lib/libcudnn.so.8 && \ sudo ln -sf /usr/lib/x86_64-linux-gnu/libcuda.so.450.66 /usr/lib/x86_64-linux-gnu/libcuda.so
 
ln -sf /usr/local/cuda-10.2/targets/x86_64-linux/lib/libcudnn_ops_train.so.8.0.3 /usr/local/cuda-10.2/targets/x86_64-linux/lib/libcudnn_ops_train.so.8 && \ ln -sf /usr/local/cuda-10.2/targets/x86_64-linux/lib/libcudnn_adv_train.so.8.0.3 /usr/local/cuda-10.2/targets/x86_64-linux/lib/libcudnn_adv_train.so.8 && \ ln -sf /usr/local/cuda-10.2/targets/x86_64-linux/lib/libcudnn_cnn_infer.so.8.0.3 /usr/local/cuda-10.2/targets/x86_64-linux/lib/libcudnn_cnn_infer.so.8 && \ ln -sf /usr/local/cuda-10.2/targets/x86_64-linux/lib/libcudnn_ops_infer.so.8.0.3 /usr/local/cuda-10.2/targets/x86_64-linux/lib/libcudnn_ops_infer.so.8 && \ ln -sf /usr/local/cuda-10.2/targets/x86_64-linux/lib/libcudnn_cnn_train.so.8.0.3 /usr/local/cuda-10.2/targets/x86_64-linux/lib/libcudnn_cnn_train.so.8 && \ ln -sf /usr/local/cuda-10.2/targets/x86_64-linux/lib/libcudnn_adv_infer.so.8.0.3 /usr/local/cuda-10.2/targets/x86_64-linux/lib/libcudnn_adv_infer.so.8 && \ ln -sf /usr/local/cuda-10.2/targets/x86_64-linux/lib/libcudnn.so.8.0.3 /usr/local/cuda-10.2/targets/x86_64-linux/lib/libcudnn.so.8
ubuntu終端一次多條命令方法和區別
1.每個命令之間用;隔開:各個命令都會執行,但不保證每個命令都執行成功。
2.每個命令之間用&&隔開:若前面的命令執行成功,才會去執行后面的命令。保證所有的命令執行完畢后,執行過程都是成功的。
3.每個命令之間用||隔開:||是或的意思,只有前面的命令執行失敗后才去執行下一條命令,直到執行成功一條命令為止。
 
安裝剩下的三個.deb文件:
 
#Install the runtime library, for example: sudo dpkg -i libcudnn7_7.6.3.30-1+cuda10.1_amd64.deb #Install the developer library, for example: sudo dpkg -i libcudnn7-dev_7.6.3.30-1+cuda10.1_amd64.deb # Install the code samples and the cuDNN Library User Guide, for example: sudo dpkg -i libcudnn7-doc_7.6.3.30-1+cuda10.1_amd64.deb
 
2.3 測試cudnn
 
cat /usr/local/cuda/include/cudnn.h | grep CUDNN_MAJOR -A 2
或者
# Copy the cuDNN sample to a writable path. cp -r /usr/src/cudnn_samples_v7/ $HOME # Go to the writable path. cd $HOME/cudnn_samples_v7/mnistCUDNN #Compile the mnistCUDNN sample. make clean && make #Run the mnistCUDNN sample. ./mnistCUDNN If cuDNN is properly installed and running on your Linux system, you will see a message similar to the following: Test passed!
 
2.4 nvidia video codec sdk 9.1安裝
 
注意:GPU編解碼必備!!!否則后續opencv編譯會報錯
0
fatal error: nvcuvid.h: No such file or directory
 
1.需要在英偉達官網把需要的組件下載下來( https://developer.nvidia.com/nvidia-video-codec-sdk#Download),當前最新為9.1版本
 
2.解壓縮之后把  Video_Codec_SDK_9.1.23/include/ 下面的cuviddec.h 和 nvcuvid.h文件拷貝到/usr/include下面就好了
 
3.繼續后續操作即可
 
2.5參考
 
3.ffmpeg + nv-codec-headers9.1安裝
 
3.1 安裝ffmpeg
 
 3.1.1 安裝基礎依賴:
sudo apt-get update sudo apt-get -y install 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
 
apt-get install yasm -y && apt-get install libx264-dev -y && apt-get install libx265-dev -y && \ apt-get install libvpx-dev -y && \ apt-get install libfdk-aac-dev -y && \ apt-get install libmp3lame-dev -y && \ apt-get install libopus-dev -y
 
3.1.2 安裝yasm  匯編編譯器,編譯某些依賴庫的時候需要
sudo apt-get install yasm #版本為1.3
 
3.1.3 安裝lib264 H.264視頻編碼器,如果需要輸出H.264編碼的視頻就需要此庫,所以可以說是必備
sudo apt-get install libx264-dev #版本為148
 
3.1.4 安裝libx265(顯卡不一定支持265編碼)
H.265/HEVC視頻編碼器。
如果不需要此編碼器,可以跳過,並在ffmpeg的configure命令中移除--enable-libx265
sudo apt-get install libx265-dev
 
3.1.5 安裝 libvpx
VP8/VP9視頻編/解碼器
如果不需要此編/解碼器,可以跳過,並在ffmpeg的configure命令中移除--enable-libvpx
sudo apt-get install libvpx-dev #版本為1.5
 
3.1.6 安裝 安裝libfdk-aac AAC音頻編碼器,必備
sudo apt-get install libfdk-aac-dev # 無版本要求
 
3.1.7 安裝libmp3lam MP3音頻編碼器,必備
sudo apt-get install libmp3lame-dev
   
 3.1.8安裝libopus
OPUS音頻編碼器
如果不需要此編碼器,可以跳過,並在ffmpeg的configure命令中移除--enable-libopus
sudo apt-get install libopus-dev # 1.1.2
 
3.1.9 安裝NVENC:
安裝依賴:
sudo apt-get -y install glew-utils libglew-dbg libglew-dev libglew1.13 \ libglewmx-dev libglewmx-dbg freeglut3 freeglut3-dev freeglut3-dbg libghc-glut-dev \ libghc-glut-doc libghc-glut-prof libalut-dev libxmu-dev libxmu-headers libxmu6 \ libxmu6-dbg libxmuu-dev libxmuu1 libxmuu1-dbg
   
3.1.10 下載ffmpeg
git clone https://github.com/FFmpeg/FFmpeg ffmpeg -b master
 
3.2 安裝nv-codec-headers9.1安裝
 
要讓ffmpeg能夠使用CUDA提供的GPU編解碼器,必須重新編譯ffmpeg,讓其能夠通過動態鏈接調用CUDA的能力
首先要編譯安裝nv-codec-headers庫--https://github.com/FFmpeg/nv-codec-headers/tree/sdk/9.1
執行如下命令安裝:
cuda10.2對應9.1版本,git clone下載的是最新版本,不適合
git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git #此為9.1版本 #有的需要下載9.0版本下載--cuda9.0需要9.0版本 cuda10.2用9.1版本即可 cd nv-codec-headers make sudo make install
 
然后cd到 ffmpeg目錄下
 
3.3 編譯ffmpeg
cd到ffmpeg安裝目錄下
 
編譯命令如下:
./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 -j8 sudo make -j8 install make -j8 distclean hash -r #清除緩存
 
配置環境
sudo vi /etc/ld.so.conf 添加: /usr/local/ffmpeg/lib sudo ldconfig
 
然后為 Ffmpeg 加入環境變量:
sudo vi /etc/profile 加入以下內容 export PATH=/usr/local/ffmpeg/bin:$PATH export FFMPEG_HOME=/usr/local/ffmpeg export PATH=$FFMPEG_HOME/bin:$PATH export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib #添加動態庫路徑 export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/ffmpeg/lib/pkgconfig:/usr/local/lib 執行 source /etc/profile
 
ffmpeg -h ffmpeg -version
 
3.4 常見問題解決
 
問題1:ERROR: freetype2 not found using pkg-config
解決1:安裝freetype 並將路徑添加到~/.bashrc中,並source ~/.bashrc
0
 
問題2:ERROR: vorbis not found using pkg-config
解決2:安裝依賴庫
sudo apt-get install -y autoconf automake build-essential git 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 wget zlib1g-dev apt install libavformat-dev apt install libavcodec-dev apt install libswresample-dev apt install libswscale-dev apt install libavutil-dev apt install libsdl1.2-dev
 
問題3:ERROR: opus not found using pkg-config
解決3:sudo apt-get install libopus-dev
 
3.5 驗證安裝
 
重新安裝完ffmpeg,使用ffmpeg -hwaccels命令查看支持的硬件加速選項
Hardware acceleration methods: cuvid
可以看到多出來一種叫做cuvid的硬件加速選項,這就是CUDA提供的GPU視頻編解碼加速選項
然后查看cuvid提供的GPU編解碼器ffmpeg -codecs | grep cuvid
DEV.LS h264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (decoders: h264 h264_cuvid ) (encoders: libx264 libx264rgb h264_nvenc nvenc nvenc_h264 ) DEV.L. hevc H.265 / HEVC (High Efficiency Video Coding) (decoders: hevc hevc_cuvid ) (encoders: libx265 nvenc_hevc hevc_nvenc ) DEVIL. mjpeg Motion JPEG (decoders: mjpeg mjpeg_cuvid ) DEV.L. mpeg1video MPEG-1 video (decoders: mpeg1video mpeg1_cuvid ) DEV.L. mpeg2video MPEG-2 video (decoders: mpeg2video mpegvideo mpeg2_cuvid ) DEV.L. mpeg4 MPEG-4 part 2 (decoders: mpeg4 mpeg4_cuvid ) D.V.L. vc1 SMPTE VC-1 (decoders: vc1 vc1_cuvid ) DEV.L. vp8 On2 VP8 (decoders: vp8 libvpx vp8_cuvid ) (encoders: libvpx ) DEV.L. vp9 Google VP9 (decoders: vp9 libvpx-vp9 vp9_cuvid ) (encoders: libvpx-vp9 )
所有帶有"cuvid"或"nvenc"的,都是CUDA提供的GPU編解碼器
可以看到,我們現在可以進行h264/hevc/mjpeg/mpeg1/mpeg2/mpeg4/vc1/vp8/vp9格式的GPU解碼,以及h264/hevc格式的GPU編碼
 
3.6 轉碼測試
 
ffmpeg -i input.flv -c:v h264_nvenc -c:a aac output.mp4 #docker容器中出現問題參考下面解決方法
倍速對比,同樣硬件條件下,gpu 提速在7-8倍左右。
frame=21022 fps=398 q=21.0 Lsize= 232698kB time=00:14:36.75 bitrate=2174.2kbits/s dup=137 drop=0 speed=16.6x
播放試了下播放效果,和cpu 播放無明顯差別。
 
3.7 使用GPU進行視頻轉碼
 
用GPU進行轉碼的命令和軟轉碼命令不太一樣,CPU轉碼的時候,我們可以依賴ffmpeg識別輸入視頻的編碼格式並選擇對應的解碼器,但ffmpeg只會自動選擇CPU解碼器,要讓ffmpeg使用GPU解碼器,必須先用ffprobe識別出輸入視頻的編碼格式,然后在命令行中指定對應的GPU解碼器。
例如,將h264編碼的源視頻轉碼為指定尺寸和碼率的h264編碼視頻:
ffmpeg -hwaccel cuvid -c:v h264_cuvid -i <input> -c:v h264_nvenc -b:v 2048k -vf scale_npp=1280:-1 -y <output>
 
使用GPU進行RTSP協議轉碼測試 ffmpeg -hwaccel cuvid -c:v h264_cuvid -rtsp_transport tcp -i "rtsp://admin:hk888888@192.168.1.235/h264/ch1/main/av_stream" -c:v h264_nvenc -b:v 2048k -vf scale_npp=1280:-1 -y /root/2.mp4
-hwaccel cuvid:指定使用cuvid硬件加速
-c:v h264_cuvid:使用h264_cuvid進行視頻解碼
-c:v h264_nvenc:使用h264_nvenc進行視頻編碼
-vf scale_npp=1280:-1:指定輸出視頻的寬高,注意,這里和軟解碼時使用的-vf scale=x:x不一樣
轉碼期間使用nvidia-smi查看顯卡狀態,能夠看到ffmpeg確實是在使用GPU進行轉碼:
+-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| | 0 62543 C ffmpeg 193MiB | +-----------------------------------------------------------------------------+
 
可能錯誤
出現:
[nvenc_hevc @ 0x3f928c0] Driver does not support the required nvenc API version. Required: 9.1 Found: 8.1 [nvenc_hevc @ 0x3f928c0] The minimum required Nvidia driver for nvenc is 390.25 or newer
原因可能是nv-codec-headers的版本是9.1,但是Nvidia driver版本只支持8.1。查看nv-codec-headers的所有tag,checkout到8.1版本,重新編譯ffmpeg成功。注意:要徹底刪除ffmpeg安裝包,重新編譯!!!
 
重點:nvidia-docker2遇到問題及解決
ffmpeg -hwaccel cuvid -c:v h264_cuvid -i 1.mp4 -c:v h264_nvenc -b:v 2048k -vf scale_npp=1280:-1 -y out.mp4
錯誤信息
使用測試命令,可能會報如下錯誤
Cannot load libnvcuvid.so.1 Cannot load libnvidia-encode.so.1 [h264_nvenc @ 0x17f6270] Cannot load libnvidia-encode.so.1 [h264_nvenc @ 0x17f6270] The minimum required Nvidia driver for nvenc is 445.87 or newer Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height
因為docker容器內沒有這兩個文件,經過我查找發現,在宿主機中有,我們需要拷貝今容器內,然后再作一個軟連接。
# 在這些目錄下查找上述文件 /lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu
找到這兩個文件,我們發現,他們其實是軟連接
我們ll命令文件,找到原始文件,
libnvcuvid.so.440.100
libnvidia-encode.so.440.100
后面的尾號可能不一樣,它是顯卡驅動版本號,
我們把這個拷貝到docker中,然后軟連接
# 宿主機 /usr/lib/x86_64-linux-gnu/libnvcuvid.so.440.100 /usr/lib/x86_64-linux-gnu/libnvidia-encode.so.440.100 # 拷貝到docker這里 /lib64/libnvcuvid.so.440.100 /lib64/libnvidia-encode.so.440.100 # docker內軟連接 ln -s /lib64/libnvcuvid.so.440.100 /lib64/libnvcuvid.so.1 ln -s /lib64/libnvidia-encode.so.440.100 /lib64/libnvidia-encode.so.1 # 然后上面的操作,也最好寫在dockerfile內
然后
vi /etc/ld.so.conf #添加軟連接路徑 /lib64 #更新 ldconfig
最后再次測試GPU視頻編解碼
 
3.8 GPU轉碼效率測試
 
在配有兩顆Intel-E5-2630v3 CPU和兩塊Nvidia Tesla M4顯卡的服務器上,進行h264視頻轉碼測試,成績如下:
  • GPU轉碼平均耗時:8s
  • CPU轉碼平均耗時:25s
並行轉碼時,CPU軟轉的效率有所提高,3個轉碼任務並行時32顆核心全被占滿,此時的成績
  • GPU轉碼平均耗時:8s
  • CPU轉碼平均耗時:18s
不難看出,並行時GPU的轉碼速度並沒有提高,可見一顆GPU同時只能執行一個轉碼任務。那么,如果服務器上插有多塊顯卡,ffmpeg是否會使用多顆GPU進行並行轉碼呢?
很遺憾,答案是否。
ffmpeg並不具備自動向不同GPU分配轉碼任務的能力,但經過一番調查后,發現可以通過-hwaccel_device參數指定轉碼任務使用的GPU!
向不同GPU提交轉碼任務
ffmpeg -hwaccel cuvid -hwaccel_device 0 -c:v h264_cuvid -i <input> -c:v h264_nvenc -b:v 2048k -vf scale_npp=1280:-1 -y <output> ffmpeg -hwaccel cuvid -hwaccel_device 1 -c:v h264_cuvid -i <input> -c:v h264_nvenc -b:v 2048k -vf scale_npp=1280:-1 -y <output>
-hwaccel_device N:指定某顆GPU執行轉碼任務,N為數字
此時nvidia-smi顯示:
+-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| | 0 96931 C ffmpeg 193MiB | | 1 96930 C ffmpeg 193MiB | +-----------------------------------------------------------------------------+
可以進行並行GPU轉碼了!
那么在占滿服務器資源時,GPU轉碼和CPU轉碼的效率如下:
  • GPU轉碼平均耗時:4s
  • CPU轉碼平均耗時:18s
GPU效率是CPU的4.5倍
 
3.9 參考
 
4.opencv 4.2.0+opencv_contirb安裝
 
4.1 opencv依賴庫---ubuntu16.04
 
ps:建議使用ubuntu官方源,本人在配置中使用其他原出現錯誤
 
[1] - 官方必須依賴庫
sudo apt-get update sudo apt-get install cmake git sudo apt-get install build-essential \ libgtk2.0-dev \ pkg-config \ libavcodec-dev \ libavformat-dev
[2] - 官方建議依賴庫
sudo apt-get install python-dev \ libtbb2 \ libtbb-dev \ libjpeg-dev \ libpng-dev \ libtiff-dev \ libjasper-dev \ libdc1394-22-dev
[3] - OPENGL 支持依賴庫
sudo apt-get install freeglut3-dev \ mesa-common-dev \ libgtkglext1 \ libgtkglext1-dev
[4] - 視頻解碼支持依賴庫
sudo apt-get install checkinstall \ yasm \ libgstreamer0.10-dev \ libgstreamer-plugins-base0.10-dev \ libv4l-dev \ libtbb-dev \ libqt4-dev \ libgtk2.0-dev \ libmp3lame-dev \ libtheora-dev \ libvorbis-dev \ libxvidcore-dev \ x264 \ v4l-utils
[5] - 其它可能依賴項
sudo apt-get install libgphoto2-dev libavresample-dev liblapacke-dev gtk+-3.0 sudo apt-get install libgtk-3-dev libeigen3-dev tesseract-ocr liblept5 leptonica-progs libleptonica-dev
 
 
ubuntu18.04
sudo apt-get update -y # Update the list of packages sudo apt-get remove -y x264 libx264-dev # Remove the older version of libx264-dev and x264 sudo apt-get install -y build-essential checkinstall cmake pkg-config yasm sudo apt-get install -y git gfortran sudo add-apt-repository -y "deb http://security.ubuntu.com/ubuntu xenial-security main" sudo apt-get install -y libjpeg8-dev libjasper-dev libpng12-dev sudo apt-get install -y libtiff5-dev sudo apt-get install -y libavcodec-dev libavformat-dev libswscale-dev libdc1394-22-dev sudo apt-get install -y libxine2-dev libv4l-dev sudo apt-get install -y libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev sudo apt-get install -y qt5-default libgtk2.0-dev libtbb-dev sudo apt-get install -y libatlas-base-dev sudo apt-get install -y libfaac-dev libmp3lame-dev libtheora-dev sudo apt-get install -y libvorbis-dev libxvidcore-dev sudo apt-get install -y libopencore-amrnb-dev libopencore-amrwb-dev sudo apt-get install -y x264 v4l-utils # Some Optional Dependencies sudo apt-get install -y libprotobuf-dev protobuf-compiler sudo apt-get install -y libgoogle-glog-dev libgflags-dev sudo apt-get install -y libgphoto2-dev libeigen3-dev libhdf5-dev doxygen
 
在安裝上述依賴包的過程中,可能會存在一些錯誤提示,這里我將自己遇到的問題列出,並給出解決方案;
錯誤1:
E: Unable to locate package libjasper-dev
執行:
sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu xenial-security main" sudo apt-get update sudo apt-get install libjasper-dev
再次執行安裝依賴包就行;
錯誤2:
E: Unable to locate package libgstreamer0.10-dev
執行:
sudo apt install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
即可;
 
 
4.2 opencv+opencv_contrib安裝配置
下載庫失敗問題解決方法1:
需要更改一些資源的下載路徑:
1.ippicv_2020_win_intel64_20191018_general.zip下載失敗
進入opencv4.3.0\3rdparty\ippicv目錄
將 ippicv.cmake 第47行的https://raw.githubusercontent.com
 
修改為:https://raw.staticdn.net
 
2.opencv_videoio_ffmpeg_64.dll、opencv_videoio_ffmpeg.dll下載失敗
進入opencv4.3.0\3rdparty\ffmpeg目錄
將 ffmpeg.cmake 第25行的https://raw.githubusercontent.com
 
修改為:https://raw.staticdn.net
 
3.boostdesc_bgm.i相關文件下載失敗
進入opencv_contrib-4.3.0\modules\xfeatures2d\cmake目錄
 
將 download_boostdesc.cmake中的https://raw.githubusercontent.com改為https://raw.staticdn.net
 
4.vgg_generated_120.i相關文件下載失敗
進入opencv_contrib-4.3.0\modules\xfeatures2d\cmake目錄
 
將 download_vgg.cmake中的https://raw.githubusercontent.com改為https://raw.staticdn.net
 
5.opencv_contrib-4.3.0\modules\face下沒有cmake目錄,直接去CMakeLists.txt里修改下載位置
 
 
下載庫失敗問題解決方法2:
1)下載opencv 以及對應版本的opencv_contrib https://github.com/opencv
 
2)opencv_contrib文件放入opencv文件內
 
3)手動ippicv下載
 
1,下載 ippicv_2019_lnx_intel64_general_20180723.tgz
保存路徑隨意,我是放在默認的下載路徑/home/lc/下載
 
2,修改opencv里相關配置文件
打開終端,輸入
    gedit /home/lc/opencv_source/opencv/3rdparty/ippicv/ippicv.cmake #記得lc換成自己的用戶名
將47行的
    "https://raw.githubusercontent.com/opencv/opencv_3rdparty/${IPPICV_COMMIT}/ippicv/"
改為步驟1中手動下載的文件的本地路徑:
     "file:///home/lc/下載/" #(僅供參考,根據自己的路徑填寫)
編輯完成保存退出。
 
3,cmake時,到了下載ippicv那一步時會自動從本地下載。
 
 
4)face_landmark_model.dat下載
 
安裝opencv4.2.0+ contrib時卡在face_landmark_model.dat下載的地方,一直下載不下來。
解決辦法:
a.手動下載 face_landmark_model.dat ,鏈接如下, 文件放置路徑隨意
b. 修改相應的配置文件
$ gedit /home/usrname/tool/opencv-3.4.0/opencv_contrib-3.4.0/modules/face/CMakeLists.txt #usrname 換成自己的用戶名, <tool/opencv-3.4.0>換成自己opencv源碼對應的文件夾
將CMakeLists.txt文件的第19行修改為本地路徑,即將原來的網址修改為下載的文件保存的路徑
"file:///home/usrname/install/" #"https://raw.githubusercontent.com/opencv/opencv_3rdparty/${__commit_hash}/" # usrname記得替換為自己的用戶名,路徑記得替換為自己文件對應的路徑
我將下載下來的face_landmark_model.dat 放在 /home/usrname/install/ 下,所以把下載網址換為本地, 如上所示。
c. 重新編譯即可。
 
5)boostdesc_bgm.i等下載
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
拷貝到opencv_contrib/modules/xfeatures2d/src/目錄下,而且網上直接可以用的資源並不多。所以本人在這篇文章里分享一下資源。
提取碼:e1wc
然后更改opencv_contrib/modules/xfeatures2d/cmake/里的下載路徑即可
 
5)開始編譯
 
首選 無python版本
cd opencv mkdir build cd build sudo cmake -D CMAKE_INSTALL_PREFIX=/usr/local/opencv-4.2.0 \ -D CMAKE_BUILD_TYPE=Debug \ -D OPENCV_EXTRA_MODULES_PATH=../opencv_contrib-4.2.0/modules \ -D BUILD_opencv_hdf=OFF \ -D BUILD_opencv_python3=ON \ -D WITH_CUDA=ON \ -D WITH_OPENGL=ON \ -D WITH_OPENMP=ON \ -D WITH_GTK=ON \ -D WITH_OPENCL=ON \ -D WITH_VTK=ON -D WITH_TBB=ON \ -D WITH_GSTREAMER=ON \ -D WITH_CUDNN=ON \ -D WITH_CUBLAS=ON \ -D WITH_GTK_2_X=ON \ -D BUILD_EXAMPLES=ON \ -D OPENCV_ENABLE_NONFREE=ON \ -D WITH_FFMPEG=ON \ -D OPENCV_GENERATE_PKGCONFIG=ON \ -D WITH_NVCUVID=ON \ -D CUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda-10.2 \ -D CUDA_ARCH_BIN=5.3,6.0,6.1,7.0,7.5 \ -D CUDA_ARCH_PTX=7.5 \ ..
#有anacodna版本,會有問題 cd opencv mkdir build cd build sudo cmake -D CMAKE_INSTALL_PREFIX=/usr/local/opencv-4.2.0 \ -D CMAKE_BUILD_TYPE=Debug \ -D OPENCV_EXTRA_MODULES_PATH=../opencv_contrib-4.2.0/modules \ -D BUILD_opencv_python3=ON \ -D PYTHON_DEFAULT_EXECUTABLE=/root/anaconda3/lib/python3.7 \ -D BUILD_opencv_python2=OFF \ -D PYTHON3_EXCUTABLE=/root/anaconda3/lib/python3.7 \ -D PYTHON3_INCLUDE_DIR=/root/anaconda3/include/python3.7m \ -D PYTHON3_LIBRARY=/root/anaconda3/lib/libpython3.7m.so.1.0 \ -D PYTHON_NUMPY_PATH==/root/anaconda3/lib/python3.7/site-packages \ -D BUILD_opencv_hdf=OFF \ -D WITH_CUDA=ON \ -D WITH_OPENGL=ON \ -D WITH_OPENMP=ON \ -D WITH_GTK=ON \ -D WITH_VTK=ON -D WITH_TBB=ON \ -D WITH_GSTREAMER=ON \ -D WITH_CUDNN=ON \ -D WITH_CUBLAS=ON \ -D WITH_GTK_2_X=ON \ -D BUILD_EXAMPLES=ON \ -D OPENCV_ENABLE_NONFREE=ON \ -D WITH_FFMPEG=ON \ -D OPENCV_GENERATE_PKGCONFIG=ON \ -D WITH_NVCUVID=ON \ -D CUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda-10.2 \ -D CUDA_ARCH_BIN=5.3,6.0,6.1,7.0,7.5 \ -D CUDA_ARCH_PTX=7.5 \ ..
 
ps:重要注意事項!!!!
1.cmake選項注意:
-D WITH_OPENGL=ON #打開OPENGL,必須
-D WITH_GTK_2_X=ON #必須,否則OPENGL無法打開
-D BUILD_EXAMPLES=ON #用於后續驗證GPU編解碼
-D WITH_NVCUVID=ON #用於安裝顯卡編解碼相關庫 必須
 
2.輸出configure驗證檢測:
【1】查看cuda是否打開,重點是NVCUVID是否打開
0
docker中配置問題 無NVCUVID解決辦法
 
需要將host(主機)中的libnvcuvid.so與libnvcuvid.so.1 libnvcuvid.so.440.80.2(庫的實體)放入到docker的/usr/lib/x86_64-linux-gnu/路徑下,並在docker中創建軟連接
ln -s /usr/lib/x86_64-linux-gnu/libnvcuvid.so.450.80.02 /usr/lib/x86_64-linux-gnu/libnvcuvid.so.1 ln -s /usr/lib/x86_64-linux-gnu/libnvcuvid.so.1 /usr/lib/x86_64-linux-gnu/libnvcuvid.so sudo ln -s /usr/lib/x86_64-linux-gnu/libnvcuvid.so /usr/lib/libnvcuvid.so sudo ln -s /usr/lib/x86_64-linux-gnu/libnvcuvid.so.1 /usr/lib/libnvcuvid.so.1
重新cmake
 
【2】查看ffmpeg是否打開
0
【3】查看OpenGL support是否打開
0
 
如果FFMPEG=NO,則建議使用cmake-gui進行cmake,具體步驟如下:
使用cmake-gui編譯
# 安裝cmake-gui sudo apt-get install cmake-qt-gui # 進入opencv源代碼目錄 cd opencv # 創建一個build文件夾,用於存放生成的代碼 mkdir build cd build # 啟動cmake-gui cmake-gui ..
 
0
step.1 點擊 “Browse Source” ,選擇源代碼根路徑opencv ,
 
step.2 點擊 “Browse Build”,選擇目標代碼目錄 build
 
step.3 點擊 “Configure”,彈出CMakeSetup窗口,選擇Unix Makefiles,選擇Use default native compilers生成配置項
 
step.4 配置編譯參數
 
Name Value 備注 CMAKE_BUILD_TYPE Release CMAKE_INSTALL_PREFIX /usr/local/opencv4.2.0 安裝目錄 OPENCV_EXTRA_MODULES_PATH opencv-4.2.0/opencv_contrib/modules opencv_contrib目錄 BUILD_DOCS ON 構建文檔 BUILD_EXAMPLES ON 構建所有示例 INSTALL_PYTHON_EXAMPLES ON INSTALL_C_EXAMPLES ON OPENCV_GENERATE_PKGCONFIG ON 務必勾選-后面就無需自己造opencv4.pc WITH_OPENGL ON
其余選擇項,參考上述cmake指令
 
step.5 再次點擊"Configure",然后點擊"Generate"
 
step.6 開始編譯
 
cd到build目錄下
sudo make -j12 sudo make install
可能錯誤解決
1.編譯opencv_contrib庫時出現如下錯誤:
fatal error: vgg_generated_120.i: No such file or directory
 
Solutions:
Step 1:在如下鏈接下載缺失文件
Step 2:將所有文件復制到如下目錄里面
opencv_contrib/modules/xfeatures2d/src/
Step 3:重新make
make -j4
 
2.make中可能出現的錯誤
XXX.hpp 沒有那個文件或者目錄 fatal error: features2d/test/test_detectors_invariance.impl.hpp: No such file
一般是說在features2d/test目錄下沒有XXX.hpp什么的,處理方式是將opencv-4.1.2/modules/features2d/test該目錄下對於的缺少文件復制到opencv_contrib-4.1.2/modules/xfeatures2d/test該目錄下,然后修改報錯的文件的#include,將前面的地址刪除,就讓其在本地找
 
例如 :
報錯說在文件test_rotation_and_scale_invariance.cpp中找不到
#include "xxxx/test_detectors_invariance.impl.hpp",
那么就在opencv-4.1.2/modules/features2d/test下去找test_detectors_invariance.impl.hpp文件,
將其復制到opencv_contrib-4.1.2/modules/xfeatures2d/test目錄,
然后打開test_rotation_and_scale_invariance.cpp文件,
修改#include "xxxx/test_detectors_invariance.impl.hpp"為#include "test_detectors_invariance.impl.hpp"即可
如果覺得每個文件去找很麻煩,那么干脆將目錄中的所有文件復制過去,之后就對於報錯文件的#include位置就好了。
cp ../modules/features2d/test/test_detectors_regression.impl.hpp ../opencv_contrib-4.2.0/modules/xfeatures2d/test/ cp ../modules/features2d/test/test_descriptors_regression.impl.hpp ../opencv_contrib-4.2.0/modules/xfeatures2d/test/ cp ../modules/features2d/test/test_detectors_invariance.impl.hpp ../opencv_contrib-4.2.0/modules/xfeatures2d/test/ cp ../modules/features2d/test/test_descriptors_invariance.impl.hpp ../opencv_contrib-4.2.0/modules/xfeatures2d/test/ cp ../modules/features2d/test/test_invariance_utils.hpp ../opencv_contrib-4.2.0/modules/xfeatures2d/test/
 
3.anaconda編譯錯誤
報錯信息如下
libtbb.so.2: undefined reference to `__cxa_init_primary_exception@CXXABI_1.3
解決:
anaconda3/lib中的libtbb.so.2文件出現了一些無法解釋的錯誤,到x86_64-linux-gnu下復制相同名字的文件進行替換編譯成功。暫時不知道為什么,這個tbb文件是intel的一個多線程庫,推測還是系統或者編譯路徑配置的問題
 
4.對於opencv2/xfeatures2d/cuda.hpp: No such file or directory 類問題的解決方法
遇到問題
/usr/local/arm/opencv-3.4.0/opencv_contrib-3.4.0/modules/xfeatures2d/include/opencv2/xfeatures2d.hpp:42:10: fatal error: /opencv2/xfeatures2d.hpp: No such file or directory #include "/opencv2/xfeatures2d.hpp" ^~~~~~~~~~~~~~~~~~~~~~~~~~ compilation terminated.
根據給的路徑找到xfeature2d.hpp的文件並打開,找到第42行如下:
40 #ifndef __OPENCV_XFEATURES2D_HPP__ 41 #define __OPENCV_XFEATURES2D_HPP__ 42 #include"/opencv2/xfeatures2d.hpp"
改為絕對路徑
40 #ifndef __OPENCV_XFEATURES2D_HPP__ 41 #define __OPENCV_XFEATURES2D_HPP__ 42#include"/usr/local/arm/opencv3.4.0/opencv_contrib3.4.0/modules/xfeatures2d/include/opencv2/xfeatures2d.hpp"
 
之后可能會遇到問題5,如下
 
5.遇到問題
undefined reference to `cv::cuda::SURF_CUDA::SURF_CUDA()'
解決方法
修改 <build_dir>/samples/gpu/CMakeFiles/example_gpu_surf_keypoint_matcher.dir/link.txt by 在
"<build_dir>/modules/xfeatures2d/CMakeFiles/opencv_xfeatures2d.dir/src/surf.cuda.cpp.o" 增加如下命令:
CMakeFiles/example_gpu_surf_keypoint_matcher.dir/surf_keypoint_matcher.cpp.o ../../modules/xfeatures2d/CMakeFiles/opencv_xfeatures2d.dir/src/surf.cuda.cpp.o ../../modules/xfeatures2d/CMakeFiles/cuda_compile_1.dir/src/cuda/cuda_compile_1_generated_surf.cu.o -o .....
 
6)opencv環境變量配置
環境配置添加opencv庫路徑
sudo gedit /etc/ld.so.conf.d/opencv.conf ##若沒有則創建文件 //打開后可能是空文件,在文件內容最后添加 /usr/local/opencv-4.2.0/lib ##lib庫路徑,根據個人設置路徑改變
 
更新系統庫
sudo ldconfig
 
配置bash
sudo gedit /etc/bash.bashrc //在末尾添加 PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/opencv-4.2.0/lib/pkgconfig #根據opencv的lib設置的路徑更改 export PKG_CONFIG_PATH
 
保存退出,然后執行如下命令使得配置生效
source /etc/bash.bashrc //激活配置然后更新database sudo updatedb
 
配置本地bash
打開~/.bashrc
$ gedit ~/.bashrc
 
在文件末尾增加以下內容
export PKG_CONFIG_PATH=/usr/local/opencv-4.2.0/lib/pkgconfig export LD_LIBRARY_PATH=/usr/local/opencv-4.2.0/lib
 
更新~/.bashrc
$ source ~/.bashrc
 
查詢OpenCV版本
pkg-config opencv4 --modversion # or pkg-config --cflags --libs opencv4 #出現如下問題: Package opencv was not found in the pkg-config search path. Perhaps you should add the directory containing `opencv4.pc' to the PKG_CONFIG_PATH environment variable No package 'opencv4' found
 
原因:在configrue時,為指定 OPENCV_GENERATE_PKGCONFIG為NO(OFF為關閉),而安裝后並未自動生成響應的opencv4.pc文件
當然,如果你勾選吧,那么,就沒有下面4.3的問題啦
 
4.3 創建opencv4.pc
 
sudo gedit /usr/local/lib/pkgconfig/opencv4.pc
 
添加如下內容
# Package Information for pkg-config prefix=/usr/local exec_prefix=${prefix} libdir=${exec_prefix}/lib includedir_old=${prefix}/include/opencv4/opencv includedir_new=${prefix}/include/opencv4 Name: OpenCV Description: Open Source Computer Vision Library Version: 4.2.0 Libs: -L${exec_prefix}/lib -lopencv_gapi -lopencv_stitching -lopencv_aruco -lopencv_bgsegm -lopencv_bioinspired -lopencv_ccalib -lopencv_dnn_objdetect -lopencv_dpm -lopencv_face -lopencv_freetype -lopencv_fuzzy -lopencv_hfs -lopencv_img_hash -lopencv_line_descriptor -lopencv_quality -lopencv_reg -lopencv_rgbd -lopencv_saliency -lopencv_stereo -lopencv_structured_light -lopencv_phase_unwrapping -lopencv_superres -lopencv_optflow -lopencv_surface_matching -lopencv_tracking -lopencv_datasets -lopencv_text -lopencv_dnn -lopencv_plot -lopencv_videostab -lopencv_video -lopencv_xfeatures2d -lopencv_shape -lopencv_ml -lopencv_ximgproc -lopencv_xobjdetect -lopencv_objdetect -lopencv_calib3d -lopencv_features2d -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs -lopencv_flann -lopencv_xphoto -lopencv_photo -lopencv_imgproc -lopencv_core Libs.private: -ldl -lm -lpthread -lrt Cflags: -I${includedir_old} -I${includedir_new}
 
再次pkg-config測試
pkg-config--cflags --libs opencv4 -I/usr/local/include/opencv4/opencv -I/usr/local/include/opencv4 -L/usr/local/lib -lopencv_gapi -lopencv_stitching -lopencv_aruco -lopencv_bgsegm -lopencv_bioinspired -lopencv_ccalib -lopencv_dnn_objdetect -lopencv_dpm -lopencv_face -lopencv_freetype -lopencv_fuzzy -lopencv_hfs -lopencv_img_hash -lopencv_line_descriptor -lopencv_quality -lopencv_reg -lopencv_rgbd -lopencv_saliency -lopencv_stereo -lopencv_structured_light -lopencv_phase_unwrapping -lopencv_superres -lopencv_optflow -lopencv_surface_matching -lopencv_tracking -lopencv_datasets -lopencv_text -lopencv_dnn -lopencv_plot -lopencv_videostab -lopencv_video -lopencv_xfeatures2d -lopencv_shape -lopencv_ml -lopencv_ximgproc -lopencv_xobjdetect -lopencv_objdetect -lopencv_calib3d -lopencv_features2d -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs -lopencv_flann -lopencv_xphoto -lopencv_photo -lopencv_imgproc -lopencv_core
 
測試成功!
 
pkg-config 命令介紹:用於獲得某一個庫/模塊的所有編譯相關的信息
所有用opencv的其他程序,在編譯時,只需要寫“pkg-config opencv –libs –cflags”,而不需要自己去找opencv的頭文件在哪里,要鏈接的庫在哪里!省時省力!
 
sudo ldconfig 命令介紹: ldconfig是一個動態鏈接庫管理命令,其目的為了讓動態鏈接庫為系統所共享。
主要是在默認搜尋目錄/lib和/usr/lib以及動態庫配置文件/etc/ld.so.conf內所列的目錄下,否則需要 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/<you_dir>/lib
搜索出可共享的動態鏈接庫(格式如lib*.so*),進而創建出動態裝入程序(ld.so)所需的連接和緩存文件,
緩存文件默認為/etc/ld.so.cache,此文件保存已排好序的動態鏈接庫名字列表。
linux下的共享庫機制采用了類似高速緩存機制,將庫信息保存在/etc/ld.so.cache,程序連接的時候首先從這個文件里查找,然后再到ld.so.conf的路徑中查找。
為了讓動態鏈接庫為系統所共享,需運行動態鏈接庫的管理命令ldconfig,此執行程序存放在/sbin目錄下。
 
 
 
 
 
5.OpenCV GPU視頻編解碼測試
 
opencv_cuda.cpp
#include <iostream> #include "opencv2/opencv_modules.hpp" #if defined(HAVE_OPENCV_CUDACODEC) #include <string> #include <vector> #include <algorithm> #include <numeric> #include <opencv2/core.hpp> #include <opencv2/core/opengl.hpp> #include <opencv2/cudacodec.hpp> #include <opencv2/highgui.hpp> int main(int argc, const char* argv[]) { if (argc != 2) return -1; const std::string fname(argv[1]); //顯示視頻 //cv::namedWindow("CPU", cv::WINDOW_NORMAL); cv::namedWindow("GPU", cv::WINDOW_OPENGL); cv::cuda::setGlDevice(); //cv::Mat frame; //cv::VideoCapture reader(fname); cv::cuda::GpuMat d_frame; cv::Ptr<cv::cudacodec::VideoReader> d_reader = cv::cudacodec::createVideoReader(fname); cv::TickMeter tm; std::vector<double> cpu_times; std::vector<double> gpu_times; int gpu_frame_count=0, cpu_frame_count=0; /* for (;;) { tm.reset(); tm.start(); if (!reader.read(frame)) break; tm.stop(); cpu_times.push_back(tm.getTimeMilli()); cpu_frame_count++; cv::imshow("CPU", frame); if (cv::waitKey(3) > 0) break; } */ for (;;) { tm.reset(); tm.start(); if (!d_reader->nextFrame(d_frame)) break; tm.stop(); gpu_times.push_back(tm.getTimeMilli()); gpu_frame_count++; cv::imshow("GPU", d_frame); if (cv::waitKey(3) > 0) break; } if (!cpu_times.empty() || !gpu_times.empty()) { std::cout << std::endl << "Results:" << std::endl; //std::sort(cpu_times.begin(), cpu_times.end()); std::sort(gpu_times.begin(), gpu_times.end()); //double cpu_avg = std::accumulate(cpu_times.begin(), cpu_times.end(), 0.0) / cpu_times.size(); double gpu_avg = std::accumulate(gpu_times.begin(), gpu_times.end(), 0.0) / gpu_times.size(); //std::cout << "CPU : Avg : " << cpu_avg << " ms FPS : " << 1000.0 / cpu_avg << " Frames " << cpu_frame_count << std::endl; std::cout << "GPU : Avg : " << gpu_avg << " ms FPS : " << 1000.0 / gpu_avg << " Frames " << gpu_frame_count << std::endl; } return 0; } #else int main() { std::cout << "OpenCV was built without CUDA Video decoding support\n" << std::endl; return 0; } #endif
 
Makefile
opencv_cuda.o:opencv_cuda.cpp g++ -std=c++11 -g -o main.out opencv_cuda.cpp `pkg-config opencv4 --cflags --libs` \ -I/usr/local/opencv-4.2.0/include/opencv4/opencv2 \ -I/usr/local/cuda/include \ -L/usr/local/cuda/lib64 \ -I/usr/include/eigen3 \ -L/usr/lib/x86_64-linux-gnu -lcuda -ldl -lnvcuvid clean: rm *.o main.out
 
編譯並運行
make ./main.out test.h264 # or ./main.out rtsp://admin:hk888888@10.171.1.233/h265/ch1/main/av_stream
 
 

報錯:

The called functionality is disabled for current build or platform in function 'throw_no_cuda' 
解決辦法:
發現cmake配置出來沒有 NVCUVID,查看 /home/zty/opencv-3.4.16/cmake/OpenCVDetectCUDA.cmake的第49-77行:
       find_path(_header_result
        ${_filename}
        PATHS "${CUDA_TOOLKIT_TARGET_DIR}" "${CUDA_TOOLKIT_ROOT_DIR}"
        ENV CUDA_PATH
        ENV CUDA_INC_PATH
        PATH_SUFFIXES include
        NO_DEFAULT_PATH
        )
      if("x${_header_result}" STREQUAL "x_header_result-NOTFOUND")
        set(${_result} 0)
      else()
        set(${_result} 1)
      endif()
      unset(_header_result CACHE)
    endmacro()
    ocv_cuda_SEARCH_NVCUVID_HEADER("nvcuvid.h" HAVE_NVCUVID_HEADER)
    ocv_cuda_SEARCH_NVCUVID_HEADER("dynlink_nvcuvid.h" HAVE_DYNLINK_NVCUVID_HEADER)
    find_cuda_helper_libs(nvcuvid)
    if(WIN32)
      find_cuda_helper_libs(nvcuvenc)
    endif()
    if(CUDA_nvcuvid_LIBRARY AND (${HAVE_NVCUVID_HEADER} OR ${HAVE_DYNLINK_NVCUVID_HEADER}))
      # make sure to have both header and library before enabling
      set(HAVE_NVCUVID 1)
    endif()
    if(CUDA_nvcuvenc_LIBRARY)
      set(HAVE_NVCUVENC 1)
    endif()
  endif()
發現他會找${CUDA_TOOLKIT_TARGET_DIR} 和${CUDA_TOOLKIT_ROOT_DIR}文件夾,查找nvcuvid.h或者dynlink_nvcuvid.h
如果找到了才會啟動NVCUVID
因為之前將nvcuvid.h拷貝到了/usr/include下面,因此


PATHS "${CUDA_TOOLKIT_TARGET_DIR}" "${CUDA_TOOLKIT_ROOT_DIR}"
改為
PATHS "${CUDA_TOOLKIT_TARGET_DIR}" "${CUDA_TOOLKIT_ROOT_DIR}" "/usr/include"
重新cmake, make, make install
 
 
運行效果(4k視頻、H265編碼)
 
cpu利用率
0
GPU使用
0
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM