I see code from @Honey_Patouceul’s link and try to write converter from GpuMat to GstBuffer:
GstBuffer *DmaBuffer::toGstBuffer(const cv::cuda::GpuMat &mat)
{
EGLImageKHR image = NvEGLImageFromFd(m_eglDisplay, m_fd);
CUresult status;
CUeglFrame eglFrame;
CUgraphicsResource pResource = NULL;
cudaFree(0);
status = cuGraphicsEGLRegisterImage(&pResource, image, CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE);
if (status != CUDA_SUCCESS) {
printf("cuGraphicsEGLRegisterImage failed : %d \n", status);
return 0;
}
status = cuGraphicsResourceGetMappedEglFrame(&eglFrame, pResource, 0, 0);
if (status != CUDA_SUCCESS) {
printf ("cuGraphicsSubResourceGetMappedArray failed\n");
}
status = cuCtxSynchronize();
if (status != CUDA_SUCCESS) {
printf ("cuCtxSynchronize failed \n");
}
if (eglFrame.frameType == CU_EGL_FRAME_TYPE_PITCH) {
if (eglFrame.eglColorFormat == CU_EGL_COLOR_FORMAT_RGBA) {
cv::cuda::GpuMat mapped(cv::Size(eglFrame.width, eglFrame.height), CV_8UC4,
eglFrame.frame.pPitch[0]);
mat.copyTo(mapped);
} else {
printf ("Invalid eglcolorformat for opencv\n");
}
}
else {
printf ("Invalid frame type for opencv\n");
}
status = cuCtxSynchronize();
if (status != CUDA_SUCCESS) {
printf ("cuCtxSynchronize failed after memcpy \n");
}
status = cuGraphicsUnregisterResource(pResource);
if (status != CUDA_SUCCESS) {
printf("cuGraphicsEGLUnRegisterResource failed: %d \n", status);
}
GstBuffer *buffer = gst_buffer_new_wrapped_full(GstMemoryFlags(0),
m_params.nv_buffer,
m_params.nv_buffer_size, 0,
m_params.nv_buffer_size,
NULL, NULL);
GstMemory *inmem = gst_buffer_peek_memory(buffer, 0);
inmem->allocator->mem_type = "nvcam";
NvDestroyEGLImage(m_eglDisplay, image);
return buffer;
}
I call this method from appsrc “need-data” signal and it stuck at cuGraphicsEGLRegisterImage call sometimes. It looks like thread synchronization issue, but I can’t understand what I doing wrong. Source code of nvivafilter can help me, but it’s closed source plugin:(