Hi Guys,
I intend to read frames using live capture of camera and copy into it into cuda host memory and map it to device memory so that it can be used on GPU side. However, when I try to cudaMemCpy and display the image using cv::imshow I always get a NULL strip at the bottom ( black). But when I try to display the image using the NVBuffer pointer the whole frame gets displayed.
Following is the code snippet for reading the frame into character buffer using NVBuffer :
// Acquire a Frame.
UniqueObj<Frame> frame(iFrameConsumer->acquireFrame());
IFrame *iFrame = interface_cast<IFrame>(frame);
if (!iFrame)
break;
// Get the Frame's Image.
Image *image = iFrame->getImage();
EGLStream::NV::IImageNativeBuffer *iImageNativeBuffer
= interface_cast<EGLStream::NV::IImageNativeBuffer>(image);
TEST_ERROR_RETURN(!iImageNativeBuffer, "Failed to create an IImageNativeBuffer");
int fd = iImageNativeBuffer->createNvBuffer(Argus::Size {m_framesize.width, m_framesize.height},
NvBufferColorFormat_YUV420, NvBufferLayout_Pitch, &status);
if (status != STATUS_OK)
TEST_ERROR_RETURN(status != STATUS_OK, "Failed to create a native buffer");
#if 1
cudaSetDeviceFlags(cudaDeviceMapHost);
NvBufferParams params;
NvBufferGetParams(fd, ¶ms);
char *data_mem = NULL;
int size = m_framesize.width* m_framesize.height;
data_mem = (char *)mmap(NULL, fsize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, params.offset[0]);
When I try to imshow using data_mem pointer it works. Following is the working code snippet :
cv::Mat CudaOUTimgbuf1 = cv::Mat(m_framesize.height, m_framesize.width, CV_8UC1, (void *) data_mem , params.pitch[0];
cv::imshow("CudaOUTimgbuf1", CudaOUTimgbuf1);
cv::waitKey(1);
When I try to allocate cuda host memory and copy the contents of frame buffer using cudaMemCpy, I get a black NULL strip at the bottom of the window. Following is the code snippet:
char *h_myimagen = NULL;
char *d_myimagen = NULL;
int alloc1 = cudaHostAlloc((void **)&h_myimagen, ( m_framesize.height * m_framesize.width)*sizeof(unsigned char), cudaHostAllocMapped);
int getPtr1 = cudaHostGetDevicePointer((void **)&d_myimagen, (void *) h_myimagen, 0);
int copy1 = cudaMemcpy (d_myimagen,data_mem,m_framesize.width*m_framesize.height*sizeof(unsigned char),cudaMemcpyHostToDevice) ;
cv::Mat CudaOUTimgbuf1 = cv::Mat(m_framesize.height, m_framesize.width, CV_8UC1, (void *) h_myimagen , params.pitch[0];
cv::imshow("CudaOUTimgbuf1", CudaOUTimgbuf1);
cv::waitKey(1);
Also when I try to copy the buffer into cuda host memory using a nested loop instead of cudaMemCpy the same result is displayed. Following are the queries in this context:
-
My guess is that there is some trouble with allocation and access of allocated memory. Please correct me if I am wrong and guide me how to proceed forward.
-
When I change the size of the frame to 1920x1080, the program crashes with Segmentation Fault. The program works fine when the frame size is 640x480 or 1080x720 (but gives NULL output at the bottom of the frame). Is there an issue with allocating a bigger cuda memory ? Why does it crash ? If not, is there an issue with displaying the frame using cv::imshow?
Thanks