問題描述:項目中,須要對高清監控視頻分析處理,經測試,其解碼過程所佔CPU資源較多,致使整個系統處理效率不高,解碼成爲系統的瓶頸。css
解決思路:html
利用GPU解碼高清視頻,下降解碼所佔用CPU資源,加速解碼過程。ide
1、OpenCV中的硬解碼函數
OpenCV2.4.6中,已實現利用GPU進行讀取視頻,由cv::gpu::VideoReader_GPU完成,其示例程序以下。測試
1 int main(int argc, const char* argv[]) 2 { 3 if (argc != 2) 4 return -1; 5 const std::string fname(argv[1]); 6 cv::namedWindow("GPU", cv::WINDOW_OPENGL); 7 cv::gpu::setGlDevice(); 8 9 cv::gpu::GpuMat d_frame; 10 cv::gpu::VideoReader_GPU d_reader(fname); 11 d_reader.dumpFormat(std::cout); 12 for (;;) 13 { 14 if (!d_reader.read(d_frame)) 15 break; 16 //.... 17 cv::imshow("GPU", d_frame); 18 if (cv::waitKey(3) > 0) 19 break; 20 } 21 return 0; 22 }
閱讀OpenCV中VideoReader_GPU源碼,可發現其底層實現是藉助於視頻解碼庫CUVID。spa
2、視頻解碼庫CUVIDcode
CUVID是基於CUDA的視頻解碼庫,利用CUVID進行解碼,主要包括如下四個步驟:orm
1.解析視頻數據文件視頻
2.在GPU端解碼htm
3.轉換解碼後的數據(YUV420、NV12 ---> RGBA)
4.將RGBA數據顯示出來
下圖爲利用CUVID解碼的僞代碼示意圖,其中VideoSource用來解析視頻數據文件,VideoParser用來解碼數據。
VideoSource的回調函數HandleVideoData(),當VideoSource的狀態設置爲Started時,開始解析視頻文件,並建立VideoParser,解碼數據。
VideoParser的回調函數:
HandleVideoSequence() 建立解碼器或重設解碼器
HandlePictureDecode() 解碼每幀視頻數據
HandlePictureDisplay() 轉換,處理,顯示解碼後的數據
OpenCV中VideoReader_GPU能夠方便地利用GPU讀取視頻文件,加速解碼過程,但OpenCV中VideoReader_GPU沒法讀取rtsp視頻流數據。
這是由於CUVID中CuvideoSource不支持rtsp視頻流數據,不能由rtsp地址建立VideoSource。
3、CUVID解碼rtsp視頻流
基本思路:跳過VideoSource模塊,利用其餘方式解析視頻數據文件。
基本步驟:
1.利用FFmpeg解析rtsp視頻流
2.建立VideoParser
3.利用FFmpeg讀取數據包(AVpacket)
4.將數據包傳輸到VideoParser(AVpacket ---> CUVIDSOURCEDATAPACKET)
5.VideoParser解碼數據包
其示例僞代碼以下圖所示