0

I need to convert videostream data to cv::gpumat. Initially I tried copying to cv::Mat and then use upload to load it to gpumat. This process is very slow(20ms for a 640*480 frame).

I need a method to convert from openni videostream to gpumat directly. I tried the following code but it gives run time error

I am using opencv3.1, cuda-8.0, gtx titanx on ubuntu 16.04

#include "opencv2/opencv_modules.hpp"
#include <opencv2/core.hpp>
#include <opencv2/cudacodec.hpp>
#include <opencv2/highgui.hpp>

int main(int argc, const char* argv[])
{
    const std::string fname = argv[1];

    cv::cuda::GpuMat d_frame;
    cv::Ptr<cv::cudacodec::VideoReader> d_reader = cv::cudacodec::createVideoReader(fname);

    for (;;)
    {
        if (!d_reader->nextFrame(d_frame))
            break;

        cv::Mat frame;
        d_frame.download(frame);
        cv::imshow("GPU", frame);

        if (cv::waitKey(3) > 0)
            break;
    }
    return 0;
}

OpenCV Error: The function/feature is not implemented (The called functionality is disabled for current build or platform) in throw_no_cuda, file /home/krr/softwares/opencv-3.1.0/modules/core/include/opencv2/core/private.cuda.hpp, line 101
terminate called after throwing an instance of 'cv::Exception'
  what():  /home/krr/softwares/opencv-3.1.0/modules/core/include/opencv2/core/private.cuda.hpp:101: error: (-213) The called functionality is disabled for current build or platform in function throw_no_cuda
talonmies
  • 70,661
  • 34
  • 192
  • 269
user27665
  • 673
  • 7
  • 27

1 Answers1

1

Take a look into the source code. The framework called "throw_no_cuda()" (lines are different, version?). Also the error seems to be a duplicate of this one on github.

alalek:
https://developer.nvidia.com/nvidia-video-codec-sdk:

Note: For Video Codec SDK 7.0 and later, NVCUVID has been renamed to NVDECODE API.

OpenCV has no support for new API and there are no plans to add this. The latest CUDA version with NVCUVID is ~ CUDA 6.5.

Consider using ffmpeg with enabled CUDA features (via normal cv::VideoCapture - but it can't work with CUDA's cv ::GpuMat).

And further:

dapicard:
I found a way to define the codec used by the FFMpeg backend :

export OPENCV_FFMPEG_CAPTURE_OPTIONS="video_codec|h264_cuvid"

More generally, it is possible to define theses parameters, using the syntax parameter_name|value;parameter_name2|value2

That is, to use the hardware capabilities to decode videos (which you tried). Sidenote: ffmpeg also offers options to transcode videos directly on the gpu (i.e. without moving fromes away from gpu memory).
Frankly, using the proposed method will not result in the matrix being delivered to your gpu memory directly, but only solve the error. I don't think it is possible to grab the memory directly from ffmpeg directly, so you are stuck with moving it.

Community
  • 1
  • 1
HMoenck
  • 31
  • 4
  • Please include relevant content in your answer, as links can go stale, invalidating an answer. – Dragonthoughts Nov 07 '18 at 09:20
  • my opencv has cuda support as I have compiled other opencv gpu programs using the same cmake options. – user27665 Nov 07 '18 at 09:52
  • Yes. The issue is that the support stopped, and I'd strongly advise against using the old API. Using latest version, you can not get it directly into the gpu matrix according to github users (first quoteblock). However, you can use the hardware capabilities to decode videos on GPU. – HMoenck Nov 07 '18 at 09:59
  • And yes, it looks like throw_no_cuda() has broken semantics here. I corrected my post. Anyways, are you sure you can not live with moving it from the cv::Mat? This size of your matrix seems small and the bandwith to your gpu should be able to handle this faster. – HMoenck Nov 07 '18 at 10:08