Hi,
My topic is heavly based on this post
I’m currently trying to directly map a NvBuffer to a Opencv::GpuMat with NvBufferMemMap and NvBufferMemSyncForDevice on a Jetson TX2i.
I took the main from the samples available in /usr/src/jetson_multimedia_api/ and took precisely the number 07. (Video convert)
In the sample the NvBuffer is created with NvBufferCreateEx with the thread_context. I inlaided a little snippet of code in the function read_video_frame
(OpenCV Version 4.5.4).
The following is working :
void *ptr;
NvBufferMemMap(src_dma_fd, 0, NvBufferMem_Read_Write, &ptr);
NvBufferMemSyncForCpu(src_dma_fd, 0, &ptr);
cv::Mat plane_y;
static cv::Mat y_only(src_param.height[0], src_param.width[0], CV_8U);
plane_y = {src_param.height[0], // 1080
src_param.width[0], // 1920
CV_8U,
ptr, // y
src_param.pitch[0]}; // 2048
static cv::cuda::GpuMat cuda_plane_y(src_param.height[0], src_param.width[0], CV_8U);
cuda_plane_y.upload(plane_y);
cuda_plane_y.download(y_only);
cv::imshow("img", y_only);
cv::waitKey(0);
The following is not working :
void *ptr;
NvBufferMemMap(src_dma_fd, 0, NvBufferMem_Read_Write, &ptr);
NvBufferMemSyncForDevice(src_dma_fd, 0, &ptr);
cv::cuda::GpuMat plane_y;
static cv::Mat y_only(src_param.height[0], src_param.width[0], CV_8U);
plane_y = {src_param.height[0], // 1080
src_param.width[0], // 1920
CV_8U,
ptr, // y
src_param.pitch[0]}; // 2048
plane_y.download(y_only);
cv::imshow("img", y_only);
cv::waitKey(0);
error: (-217:Gpu API call) invalid argument in function 'download'
Changing NvBufferMemSyncForCpu does not work for me.
I’m only trying to directly map to a GpuMat to avoid memory transfer time.
What i already did to debug :
Changing my GpuMat constructor to
cv::cuda::GpuMat plane_y = cv::cuda::GpuMat(src_param.height[0], // 1080
src_param.width[0], // 1920
CV_8U,
ptr); // 2048
Doesn’t work either.
Adding or deleting the pitch also do not change my problem.
And in a final effort, changing to a non-static y_only cv::Mat did not work.
My question is, does context have to specify something when creating a NvBuffer that the memory is shared between Device and CPU ?
Or i’m missing something important in my code to make it successful ?
Best regards.
~S.