博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux + opencv + cuvid中使用cv::cuda::GpuMat类的一些坑
阅读量:5917 次
发布时间:2019-06-19

本文共 2798 字,大约阅读时间需要 9 分钟。

1.我最终成功实现了opencv中利用cuvid实现GPU视频解码:

核心代码是:

1 cv::cuda::GpuMat d_frame; 2     cv::Ptr
d_reader = cv::cudacodec::createVideoReader(mp4_file_name); 3 for (;;) 4 { 5 if (!d_reader->nextFrame(d_frame)) //BRGA格式 6 break; 7 gpu_frame_count++; 8 cv::Mat frame2; 9 d_frame.download(frame2);10 cv::imwrite("xxx.png", frame2);11 }

2.GupMat类的参考地址是:

  https://docs.opencv.org/master/d0/d60/classcv_1_1cuda_1_1GpuMat.html

  源码在: opencv-master/modules/core/include/opencv2/core/cuda.hpp

  GPUMat类的成员变量都是public的,就算没有提供访问的方法也没关系。

  一些重要的成员变量和成员函数是:

1 class CV_EXPORTS_W GpuMat 2 { 3 public: 4  5     /** @brief Performs data download from GpuMat (Blocking call) 6  7     This function copies data from device memory to host memory. As being a blocking call, it is 8     guaranteed that the copy operation is finished when this function returns. 9     */10     CV_WRAP void download(OutputArray dst) const;11 12     /** @brief Performs data download from GpuMat (Non-Blocking call)13 14     This function copies data from device memory to host memory. As being a non-blocking call, this15     function may return even if the copy operation is not finished.16 17     The copy operation may be overlapped with operations in other non-default streams if \p stream is18     not the default stream and \p dst is HostMem allocated with HostMem::PAGE_LOCKED option.19     */20     CV_WRAP void download(OutputArray dst, Stream& stream) const;21 22     //! the number of rows and columns23     int rows, cols;24 25     //! a distance between successive rows in bytes; includes the gap if any26     CV_PROP size_t step;27 28     //! pointer to the data29     uchar* data;30 31     //! helper fields used in locateROI and adjustROI32     uchar* datastart;33     const uchar* dataend;34 35 };

data是GPU内存中,存储图像数据的指针

datastart的地址与data相同

dataend指向图像存储空间的结束位置。(很可惜,这里是错误的)

rows 是图片的高度

cols是图片的宽度

channels() 返回4, 说明每个像素是四个字节,格式是BGRA

step是图片每行的字节数。注意:这个值是按2的幂对齐的。我测试中使用的图片,宽度是480,每像素四字节的话,一行应该是1920; 而此处的step值是2048, 每行多出来32像素,这些像素的alpha通道值为0。

因此,虽然看起来dataend-datastart是GPU内存所占空间大小,但实际的所占空间是:step*rows

 

3. GpuMat类使用dowmload()方法后,Mat类会去掉多余的对齐的像素

   具体怎么做到的呢?搜索了很久终于找到源码原来在:opencv-master/modules/core/src/cuda/gpu_mat.cu

   download方法的源码是:

1 void cv::cuda::GpuMat::download(OutputArray _dst) const2 {3     CV_DbgAssert( !empty() );4 5     _dst.create(size(), type());6     Mat dst = _dst.getMat();7 8     CV_CUDEV_SAFE_CALL( cudaMemcpy2D(dst.data, dst.step, data, step, cols * elemSize(), rows, cudaMemcpyDeviceToHost) );9 }

直接这样拷贝也是可以的:

cudaMemcpy(host_data, d_frame.data,  d_frame.rows * d_frame.step , cudaMemcpyDeviceToHost);
但要注意:
#include <cuda_runtime.h>
cudaGetDeviceCount(&num_devices);
cudaSetDevice(cuda_device);
//调用各种函数来初始化cuda运行环境,否则一执行就崩溃

    

转载于:https://www.cnblogs.com/ahfuzhang/p/10852659.html

你可能感兴趣的文章
工业物联网设备投资 从这三个地方可回收成本
查看>>
Windows 10隐私设置被用户狂吐槽:微软无力回应
查看>>
爱立信股价持续下跌 股东欲撤换CEO
查看>>
ARM免预付授权费用计划增加Cortex-M3架构设计 加速物联网发展
查看>>
大数据影响人类认知和行为习惯
查看>>
最受合作伙伴瞩目的5大新品和10大解决方案 | 科达2016巡展盘点
查看>>
数据中心里云应用部署的尴尬现状
查看>>
诺基亚支持韩国铁路移动宽带网络
查看>>
意法半导体嘴硬:我们有三大业务 苹果砍订单影响不大
查看>>
涨价停不下来?最主要的元凶还是闪存
查看>>
MySQL Group Replication 学习笔记
查看>>
并发性能测试程序编写
查看>>
Oracle Database 12c - Global Data Services
查看>>
全球微型逆变器霸主Enphase要夺回失地
查看>>
【MySQL】磁盘写满之后,数据库show status受到阻塞的原因
查看>>
技术分析:存储混合云优点和挑战
查看>>
IT行业从业者如何在ERP行业发展?
查看>>
A16Z 750万美元投资分布式文件系统 Tachyon
查看>>
c++中指针常量,常指针,指向常量的常指针区分
查看>>
《跨境电商 —— 阿里巴巴速卖通实操全攻略》一一第1章 速卖通入门第一步——开通账户...
查看>>