1. 程式人生 > >【計算機視覺】【平行計算與CUDA開發】GPU硬解碼---CUVID

【計算機視覺】【平行計算與CUDA開發】GPU硬解碼---CUVID

問題描述:專案中,需要對高清監控視訊分析處理,經測試,其解碼過程所佔CPU資源較多,導致整個系統處理效率不高,解碼成為系統的瓶頸。

解決思路:

利用GPU解碼高清視訊,降低解碼所佔用CPU資源,加速解碼過程。

一、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。

二、視訊解碼庫CUVID

CUVID是基於CUDA的視訊解碼庫,利用CUVID進行解碼,主要包括以下四個步驟:

1.解析視訊資料檔案

2.在GPU端解碼

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

三、CUVID解碼rtsp視訊流

基本思路:跳過VideoSource模組,利用其他方式解析視訊資料檔案。

基本步驟:

1.利用FFmpeg解析rtsp視訊流

2.建立VideoParser

3.利用FFmpeg讀取資料包(AVpacket)

4.將資料包傳輸到VideoParser(AVpacket ---> CUVIDSOURCEDATAPACKET)

5.VideoParser解碼資料包

其示例虛擬碼如下圖所示