CLOSED. Copy Argus EGLStream::IFrame to Npp8u CUDA buffer

Hi Nvidia,

I need fast(HW) copy argus frame from camera to CUDA Npp8u* buffer.

I have the frame:

[b]UniqueObj< Frame > frameLeft{ iFrameConsumerLeft->acquireFrame() };
IFrame * iFrameLeft{ interface_cast< IFrame >( frameLeft ) }; 

NV::IImageNativeBuffer * iNativeBufferLeft{ interface_cast< NV::IImageNativeBuffer >( iFrameLeft->getImage() ) };
int fdLeft = iNativeBufferLeft->createNvBuffer( STREAM_SIZE, NvBufferColorFormat_YUV420, NvBufferLayout_Pitch );

EGLImageKHR egl_imageLeft{ NvEGLImageFromFd( egl_display, fdLeft ) };

CUgraphicsResource pResourceLeft;

cuGraphicsEGLRegisterImage( & pResourceLeft, * egl_imageLeft, CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE );

CUeglFrame eglFrameLeft;

cuGraphicsResourceGetMappedEglFrame( & eglFrameLeft, pResourceLeft, 0, 0 );[/b]

and i have Npp8 buffer:

[b]Npp8u* pPanoImgCUDA = nppiMalloc_8u_C2( STREAM_SIZE.width(), STREAM_SIZE.height(), & panoPitch );
[/b]

and then i will convert yuv frame to rgb: nppiYUV422ToRGB_8u_C2C3R(***)

How i can do copy frame data to Npp8u buffer?
It is device to device or host to device?

[s]May be i need somthing like this:

[b]NvBufferParams params;
    NvBufferGetParams(fdLeft, &params);

    for (int i = 0; i < params.num_planes; i++) {
        uint32_t width = params.width[i];
        uint32_t height = params.height[i];
        uint32_t pitch = params.pitch[i];

        size_t fsize = pitch * height;
        uint8_t* data_mem = (uint8_t*)mmap(0, fsize, PROT_READ | PROT_WRITE, MAP_SHARED, fdLeft, params.offset[i]);

        ...(data_mem, pitch);
    }
[/b]

It is HW copy?
[/s]
Please help.

Best regards, Viktor.

Hi vsw,
Please refer to the sample

tegra_multimedia_api\argus\samples\cudaHistogram

You can get the frame as CUeglFrame and do memcpy to Npp8u CUDA buffer.

Please also note that the EGLframe size is only 1/4 when dealing with YUV420.

e.g Y plane: 1920x1080
uv plane: 960*540 with channel=2.

If you don’t handle it well, it would crash when cuda runtime.

Similar topic:
https://devtalk.nvidia.com/default/topic/1027288/jetson-tx1/libargus-crashing-with-cuda-opengl-interop/post/5228961/#5228961

Yes, it works. Thank you.

Now i can copy frame to cuda memory:

uint y_offset{ h * w };
uint u_offset{ ( h * w / 4 ) };

cudaMemcpy( eglInPanoInv.frame.pArray[ 0 ], eglLeft.frame.pPitch[ 0 ], y_offset, cudaMemcpyDefault );
cudaMemcpy( eglInPanoInv.frame.pArray[ 1 ], eglLeft.frame.pPitch[ 1 ], u_offset, cudaMemcpyDefault );
cudaMemcpy( eglInPanoInv.frame.pArray[ 2 ], eglLeft.frame.pPitch[ 2 ], u_offset, cudaMemcpyDefault );

It is possible to copy rect from src CUArray to dst CUArray?
I have tried cudaMemcpyArraytoArray but it have different type and always segmentation fault:

cudaMemcpyArrayToArray( ( cudaArray * ) ( eglInPanoInv.frame.pArray[ 0 ] ), 0, 0, ( cudaArray * ) ( eglLeft.frame.pArray[ 0 ] ), 0, 0, y_offset );

And what is difference between pArray and pPitch?

I have understood how to make cudaArray:

cudaArray * ca0, * ca1, * ca2;
        cudaChannelFormatDesc channelDesc{ cudaCreateChannelDesc( 8, 0, 0, 0, cudaChannelFormatKindUnsigned ) };

        cudaMallocArray( & ca0, & channelDesc, w, h );
        cudaMallocArray( & ca1, & channelDesc, w / 2, h / 2 );
        cudaMallocArray( & ca2, & channelDesc, w / 2, h / 2 );

        cudaMemcpy2DToArray( ca0, 0, 0, ( eglLeft.frame.pArray[ 0 ] ), w, w, h, cudaMemcpyDefault );
        cudaMemcpy2DToArray( ca1, 0, 0, ( eglLeft.frame.pArray[ 1 ] ), w / 2, w / 2, h / 2, cudaMemcpyDefault );
        cudaMemcpy2DToArray( ca2, 0, 0, ( eglLeft.frame.pArray[ 2 ] ), w / 2, w / 2, h / 2, cudaMemcpyDefault );

        cudaMemcpy2DFromArray( eglInPanoInv.frame.pArray[ 0 ], 2048, ca0, 0, 0, 2048, 2048, cudaMemcpyDefault );
        cudaMemcpy2DFromArray( eglInPanoInv.frame.pArray[ 1 ], 2048 / 2, ca1, 0, 0, 2048 / 2, 2048 / 2, cudaMemcpyDefault );
        cudaMemcpy2DFromArray( eglInPanoInv.frame.pArray[ 2 ], 2048 / 2, ca2, 0, 0, 2048 / 2, 2048 / 2, cudaMemcpyDefault );

Here is i copy of rectangle(2048x2048) from source camera frame(3840x2160) for encoding to h264.
But the image is gray with artifacts.

How i can calculate pitch for new rect UV plane arrays?
Do i need 2channel uv array?

After this:
https://devtalk.nvidia.com/default/topic/1029251/jetson-tx1/closed-cudaarray-from-nv-iimagenativebuffer-without-copy-/

Frames have real color.

Closed.