【GPU編解碼】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解碼數據包

其示例偽代碼如下圖所示

 


免責聲明!

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



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