I’ve actually run into another issue in trying to get this to work with standard uchar pointers instead of GpuMats. I had assumed setting eglFrame.frame.pPitch[0] and [1] to the Y and UV planes respectively would work, but the buffer ends up not copying anything.
Is this format/order of function calls with regards to the EGL object handling correct?
cv::cuda::GpuMat d_frame_rgb(4504, 4504, CV_8UC3);
EGLImageKHR eglimage;
eglimage = NvEGLImageFromFd(ctx.eglDisplay, buffer->planes[0].fd);
CUresult status;
CUeglFrame eglFrame;
CUgraphicsResource pResource = NULL;
cudaFree(0);
status = cuGraphicsEGLRegisterImage(&pResource, eglimage, CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE);
if(status != CUDA_SUCCESS)
cerr << "cuGraphicsEGLRegisterImage failed\n";
status = cuGraphicsResourceGetMappedEglFrame(&eglFrame, pResource, 0, 0);
if (status != CUDA_SUCCESS)
cerr << "cuGraphicsResourceGetMappedEglFrame failed\n";
status = cuCtxSynchronize();
if (status != CUDA_SUCCESS)
cerr << "cuCtxSynchronize failed\n";
uchar* d_frame_y_uchar;
uchar2* d_frame_uv_uchar;
cudaMalloc(&d_frame_y_uchar, 4504*4608*sizeof(uchar));
cudaMalloc(&d_frame_uv_uchar, (4504/2)*(4608/2)*sizeof(uchar2));
eglFrame.frame.pPitch[0] = (void*)d_frame_y_uchar;
eglFrame.frame.pPitch[1] = (void*)d_frame_uv_uchar;
if(d_frame_y_uchar != eglFrame.frame.pPitch[0])
cerr << "ERROR copying y frame to EGLFRame object\n";
if(d_frame_uv_uchar != eglFrame.frame.pPitch[1])
cerr << "ERROR copying uv frame to EGLFRame object\n";
make_pattern(d_frame_rgb);
convertRGBtoNV12M(d_frame_rgb, d_frame_y_uchar, d_frame_uv_uchar);
read_video_frame(d_frame_y_uchar, d_frame_uv_uchar, *buffer);
status = cuCtxSynchronize();
if (status != CUDA_SUCCESS)
cerr << "cuCtxSynchronize 2 failed\n";
status = cuGraphicsUnregisterResource(pResource);
if (status != CUDA_SUCCESS)
cerr << "cuGraphicsUnregisterResource failed\n";
NvDestroyEGLImage(ctx.eglDisplay, eglimage);
int read_video_frame(uchar* yframe, uchar2* uvframe, NvBuffer & buffer)
{
for(unsigned int i = 0; i < buffer.n_planes; i++){
NvBuffer::NvBufferPlane &plane = buffer.planes[i];
if(i == 0){
cudaMemcpy(plane.data, yframe, plane.fmt.bytesperpixel * plane.fmt.width * plane.fmt.height, cudaMemcpyDeviceToDevice);
}else{
cudaMemcpy(plane.data, uvframe, plane.fmt.bytesperpixel * plane.fmt.width * plane.fmt.height, cudaMemcpyDeviceToDevice);
}
plane.bytesused = plane.fmt.bytesperpixel * plane.fmt.width * plane.fmt.height;
}
return 0;
}
I can get it to work without issues with GpuMats like in OpenCV CUDA processing from gstreamer pipeline [JP4, JP5], but something about the uchar pointers results in the capture plane buffers writing nothing to the file. Without using EGLFrames, using uchar pointers only works, so there is something regarding EGLFrames/EGLImages that I don’t seem to understand yet.