Hi rus8, very helpful. I think I might be very close but just missing a tiny step.
This is what I learn from your post and boil it down to this line:
cv::cuda::GpuMat d_mat(dsexample->processing_height, dsexample->processing_width, CV_8UC4,
surface->surfaceList[0].dataPtr,data_pitch);
I am able to compile it without error. But when I run it, it will have this error:
terminate called after throwing an instance of 'cv::Exception'
what(): OpenCV(4.3.0) /home/cuda-opencv/install/opencv-4.3.0/modules/core/include/opencv2/core/cuda/common.hpp:102: error: (-217:Gpu API call) invalid texture reference in function 'bindTexture'
does this imply the CV_8UC4 type is not correct? or is the data_pitch issue?
Thanks a again for your help.
Attached below please find my code:
/**
* Called when element recieves an input buffer from upstream element.
*/
static GstFlowReturn
gst_dsexample_transform_ip (GstBaseTransform * btrans, GstBuffer * inbuf)
{
GstDsExample *dsexample = GST_DSEXAMPLE (btrans);
GstMapInfo in_map_info;
GstFlowReturn flow_ret = GST_FLOW_ERROR;
NvBufSurface *surface = NULL;
dsexample->frame_num++;
CHECK_CUDA_STATUS (cudaSetDevice (dsexample->gpu_id),
"Unable to set cuda device");
memset (&in_map_info, 0, sizeof (in_map_info));
if (!gst_buffer_map (inbuf, &in_map_info, GST_MAP_READ)) {
g_print ("Error: Failed to map gst buffer\n");
goto error;
}
surface = (NvBufSurface *) in_map_info.data;
if (CHECK_NVDS_MEMORY_AND_GPUID (dsexample, surface))
goto error;
#ifdef __aarch64__
/*Tegra: To use the converted buffer in CUDA, create an EGLImage and then use
* CUDA-EGL interop APIs */
if (USE_EGLIMAGE) {
if (NvBufSurfaceMapEglImage (surface, 0) !=0 ) {
goto error;
}
/* dsexample->inter_buf->surfaceList[0].mappedAddr.eglImage
* Use interop APIs cuGraphicsEGLRegisterImage and
* cuGraphicsResourceGetMappedEglFrame to access the buffer in CUDA */
#if 1
CUresult status;
CUeglFrame eglFrame;
CUgraphicsResource pResource = NULL;
cudaFree(0);
status = cuGraphicsEGLRegisterImage(&pResource,
surface->surfaceList[0].mappedAddr.eglImage,
CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE);
status = cuGraphicsResourceGetMappedEglFrame(&eglFrame, pResource, 0, 0);
status = cuCtxSynchronize();
cv::cuda::GpuMat d_mat(dsexample->processing_height, dsexample->processing_width, CV_8UC4, eglFrame.frame.pPitch[0]);
//filter->apply (d_mat, d_mat);
undistort(dsexample,d_mat);
status = cuCtxSynchronize();
status = cuGraphicsUnregisterResource(pResource);
#endif
/* Destroy the EGLImage */
//NvBufSurfaceUnMapEglImage (dsexample->inter_buf, 0);
NvBufSurfaceUnMapEglImage (surface, 0);
}
#else
/* dGPU: is this section of code correct to run in dGPU? */
if (USE_EGLIMAGE) {
surface->numFilled = 1;
surface->batchSize = 1;
#if 1
CUresult status;
NvBufSurfaceParams * surf_params = & surface->surfaceList[0];
int data_pitch = surf_params->planeParams.pitch[0];
uint8_t * gpu_pitched_image = (unsigned char *) surface->surfaceList[0].dataPtr;
cudaFree(0);
status = cuCtxSynchronize();
cv::cuda::GpuMat d_mat(dsexample->processing_height, dsexample->processing_width, CV_8UC4,
surface->surfaceList[0].dataPtr,data_pitch);
//filter->apply (d_mat, d_mat);
undistort(dsexample,d_mat);
status = cuCtxSynchronize();
#endif
}
#endif
flow_ret = GST_FLOW_OK;
error:
gst_buffer_unmap (inbuf, &in_map_info);
return flow_ret;
Thanks a lot for your help again.