Copy CUeglFrame data to CUarray, not effective

I am using the jetson_multimedia_api interface to decode video files in the MP4 format. Then, I am rendering the video data through OPENGL ES. The memory format I am using for the capture plane is DMA. Currently, I can decode the video data (stored in a DMA ID). I use the NvBufSurfaceFromFd and NvBufSurfaceMapEglImage interfaces to obtain a variable of type EGLImageKHR. Afterward, I use cuGraphicsEGLRegisterImage and cuGraphicsResourceGetMappedEglFrame to obtain a variable of type CUeglFrame, from which I can retrieve the video’s memory pointer, eglFrame.frame.pPitch.

On the other hand, I take the OpenGL-created 2D texture ID and convert it into an EGLImageKHR variable using the eglCreateImageKHR interface. Then, by using the cuGraphicsEGLRegisterImage and cuGraphicsSubResourceGetMappedArray interfaces, I transform the texture ID into a variable of type CUarray. Finally, through the cuMemcpy2D interface, I copy the data from the CUeglFrame variable to the CUarray variable, indirectly updating the data of the 2D texture. The process does not result in any errors. However, the texture data remains unchanged, meaning it has no effect.

Below is the copy function:
void CopyEglFrameToCuArray(const CUeglFrame& eglFrame, CUarray& cuArray) {
// Step 1: Get image data and information
const void* eglImageData = eglFrame.frame.pPitch[0];
int imageWidth = eglFrame.width;
int imageHeight = eglFrame.height;
// Get other image format information

// Step 2: Create CUarray object
CUDA_ARRAY_DESCRIPTOR arrayDesc;
memset(&arrayDesc, 0, sizeof(arrayDesc));
arrayDesc.Width = imageWidth;
arrayDesc.Height = imageHeight;
arrayDesc.Format = CU_AD_FORMAT_UNSIGNED_INT8; // Assuming image format is 8-bit unsigned integer

cuArrayCreate(&cuArray, &arrayDesc);

// Step 3: Use CUDA memory copy functions for data transfer
CUDA_MEMCPY2D copyDesc;
memset(&copyDesc, 0, sizeof(copyDesc));
copyDesc.srcMemoryType = CU_MEMORYTYPE_DEVICE; // Source memory type is device memory
copyDesc.srcDevice = eglImageData;             // Source data pointer
copyDesc.srcPitch = eglFrame.frame.pitch;      // Assuming image data pitch information is in pitch
copyDesc.dstMemoryType = CU_MEMORYTYPE_ARRAY;  // Destination memory type is array
copyDesc.dstArray = cuArray;                   // Destination array object
copyDesc.WidthInBytes = imageWidth * 4;        // Assuming each pixel is 4 bytes (RGBA)

cuMemcpy2D(&copyDesc);

}

Hi,

Have you checked the return value of cuMemcpy2D(.)?
Does it succedd?

Thanks.

yes. it returns success.

Hi,

Sorry for the late update.
Could you share a reproducible source so we can test it in our environment to get further information?

Thanks.

NvBufSurface* nvbuf_surf = 0;
cudaGraphicsResource_t cudaBuffer;
cudaArray_t cudaArray;
cudaError_t err,err1;
int dma_id =c->dmaId; // the dmaid is from jetson multimedia api demo code 00_video_decode

int ret = NvBufSurfaceFromFd(dma_id, (void**)(&nvbuf_surf));
NvBufSurfaceMapEglImage(nvbuf_surf, 0);
EGLImageKHR decode_egl_image = nvbuf_surf->surfaceList[0].mappedAddr.eglImage;
CUresult decode_uresult = CUDA_ERROR_UNKNOWN;//
CUgraphicsResource decode_cudaResource;
CUarray decode_cudaArray;
decode_uresult = cuGraphicsEGLRegisterImage(&decode_cudaResource, decode_egl_image, CU_GRAPHICS_REGISTER_FLAGS_NONE);
CUeglFrame eglFrame;
CUresult cu3 = cuGraphicsResourceGetMappedEglFrame(&eglFrame, decode_cudaResource, 0, 0);

CUgraphicsResource cudaResource;
CUarray cudaArray;
EGLImageKHR eglImage =(EGLImageKHR) bgfx::GetEglImageKHRByTextureId(th.idx);
if (eglImage != 0)
{
CUresult uresult = cuGraphicsEGLRegisterImage(&cudaResource, eglImage, cudaGraphicsRegisterFlagsWriteDiscard);

	if (uresult == CUDA_SUCCESS&& decode_uresult== CUDA_SUCCESS)
	{
		// Map the CUDA resource to obtain a CUDA array
		CUresult uresult1 = cuGraphicsSubResourceGetMappedArray(&cudaArray, cudaResource, plane, 0);

		CopyEglFrameToCuArray(eglFrame, cudaArray,plane);

	}
				
	if ( uresult == CUDA_SUCCESS)
	{
			cuGraphicsUnregisterResource(cudaResource);
	}
	if (decode_uresult == CUDA_SUCCESS)
	{
		cuGraphicsUnregisterResource(decode_cudaResource);
	}

}

void CopyEglFrameToCuArray(const CUeglFrame& eglFrame, CUarray& cuArray,int idx)
{
// 步骤 1: 获取图像数据
const void* eglImageData = eglFrame.frame.pPitch[idx];
printf(“plane count=%d. pitch=%d, wh=%d,%d.\n”, eglFrame.planeCount, eglFrame.pitch, eglFrame.width, eglFrame.height);;

// 步骤 2: 创建 CUarray 对象
CUDA_ARRAY_DESCRIPTOR arrayDesc;
memset(&arrayDesc, 0, sizeof(arrayDesc));
arrayDesc.Width = eglFrame.width;
arrayDesc.Height = eglFrame.height;
arrayDesc.Format = CU_AD_FORMAT_UNSIGNED_INT8;

cuArrayCreate(&cuArray, &arrayDesc);

// 步骤 3: 使用 CUDA 内存拷贝函数进行数据传输
CUDA_MEMCPY2D copyDesc;
memset(&copyDesc, 0, sizeof(copyDesc));
copyDesc.srcMemoryType = CU_MEMORYTYPE_DEVICE;
copyDesc.srcHost = eglImageData;
copyDesc.srcPitch = eglFrame.pitch;
copyDesc.dstMemoryType = CU_MEMORYTYPE_ARRAY;
copyDesc.dstArray = cuArray;
copyDesc.WidthInBytes = eglFrame.width * 3;

CUresult u = cuMemcpy2D(&copyDesc);
printf("copy ret=%d\n", u);

}

There is no update from you for a period, assuming this is not an issue any more.
Hence we are closing this topic. If need further support, please open a new one.
Thanks

Hi,

Could you share the complete reproducible source so we can run it internally?
Please share the compile instructions as well.

Thanks.