1. 程式人生 > >【GPU編解碼】GPU硬編碼

【GPU編解碼】GPU硬編碼

cuda 說明 閱讀 cnblogs itl href ble con info

【GPU編解碼】GPU硬編碼

一、OpenCV中的硬編碼

OpenCV2.4.6中,已實現利用GPU進行寫視頻,編碼過程由cv::gpu::VideoWriter_GPU完成,其示例程序如下。

技術分享
 1 int main(int argc, const char* argv[])
 2 {
 3     if (argc != 2)
 4     {
 5         std::cerr << "Usage : video_writer <input video file>" << std::endl;
 6         return -1;
 7     }
 8 
 9     const double FPS = 25.0;
10     cv::VideoCapture reader(argv[1]);
11 
12     if (!reader.isOpened())
13     {
14         std::cerr << "Can‘t open input video file" << std::endl;
15         return -1;
16     }
17 
18     cv::gpu::printShortCudaDeviceInfo(cv::gpu::getDevice());
19     cv::gpu::VideoWriter_GPU d_writer;
20 
21     cv::Mat frame;
22     cv::gpu::GpuMat d_frame;
23 
24     for (int i = 1;; ++i)
25     {
26         std::cout << "Read " << i << " frame" << std::endl;
27         reader >> frame;
28         if (frame.empty())
29         {
30             std::cout << "Stop" << std::endl;
31             break;
32         }
33         cv::resize(frame,frame,cv::Size(704,576));
34         if (!d_writer.isOpened())
35         {
36             std::cout << "Open GPU Writer" << std::endl;
37 
38             d_writer.open("output_gpu.avi", frame.size(), FPS);
39         }
40         d_frame.upload(frame);
41         std::cout << "Write " << i << " frame" << std::endl;
42         d_writer.write(d_frame);
43     }
44     return 0;
45 }
技術分享

深入閱讀cv::gpu::VideoWriter_GPU類的實現,發現其底層編碼實現是基於NVCUVENC庫,視頻文件的封裝是FFmpeg。

二、NVCUVENC庫

NVCUVENC庫是NVIDIA公司提供的視頻編碼庫,可以實現H.264的GPU編碼,接收原始YUV frames數據,編碼產生NAL packets。

利用NVCUVENC庫進行視頻硬編碼的基本步驟如下:

1.檢測是否支持NVCUVENC

2.新建編碼器,設置編碼類型

3.設置編碼參數,註冊回調函數

4.創建編碼器相關資源

5.循環編碼每幀數據

6.刪除編碼器,釋放資源

偽代碼示意圖如下所示,其中編碼前緩沖區的分配,以及編碼後的數據處理都由回調函數。

技術分享

回調函數說明:

AcquireBitstream() 分配coded bitstream緩沖區

ReleaseBitstream() 處理、保存coded bitstream

OnBeginFrame() 編碼前的初始化工作

OnEndFrame() 編碼後的統計工作

回調函數的調用順序:

技術分享

【GPU編解碼】GPU硬編碼