How to save YUV420 buffer with Pitch layout into YUV file?

Hi, I’m using TX2 NX with JP 4.6.3.

I’m having a NvBuffer created by NvBufferCreateEx() with params

        NvBufferCreateParams params = {
            .width = 1920,
            .height = 1080,
            .payloadType = NvBufferPayload_SurfArray,
            .memsize = 1,
            .layout = NvBufferLayout_Pitch,
            .colorFormat = NvBufferColorFormat_YUV420,
            .nvbuf_tag = NvBufferTag_CAMERA
        };

The image data was copied from another buffer to this by transform function.
My question is, how to save this buffer into YUV420 binary file correctly?

This is what I did:

    NvBufferParams buf_params;

    if (NvBufferGetParams (fd, &buf_params) != 0) {
        return -1;
    }

        void *pdata = NULL;
        NvBufferMemMap(fd, 0, NvBufferMem_Read, &pdata);
        NvBufferMemSyncForCpu(fd, 0, &pdata);
        // printf("saving image %dx%d into YUV file '%s', pitch %d\n", width, height, path, pitch);
        printf("planes %d, %ux%u pitch %u offset %u psize %u layout %u, %ux%u pitch %u offset %u psize %u layout %u, , %ux%u pitch %u offset %u psize %u layout %u\n", buf_params.num_planes,
            buf_params.width[0], buf_params.height[0], buf_params.pitch[0], buf_params.offset[0], buf_params.psize[0], buf_params.layout[0],
            buf_params.width[1], buf_params.height[1], buf_params.pitch[1], buf_params.offset[1], buf_params.psize[1], buf_params.layout[1],
            buf_params.width[2], buf_params.height[2], buf_params.pitch[2], buf_params.offset[2], buf_params.psize[2], buf_params.layout[2]);

        FILE *f = fopen(path, "w");
        // Write Y
        void *data = pdata + buf_params.offset[0];
        uint32_t writen = 0;
        for (int i = 0; i < buf_params.height[0]; ++i) {
            writen += fwrite(data , 1, buf_params.width[0], f);
            data += buf_params.pitch[0];
        }
        printf("  wrote %ubytes Y\n", writen);
        // write u
        data = pdata + buf_params.offset[1];
        writen = 0;
        for (int i = 0; i < buf_params.height[1]; ++i) {
            writen += fwrite(data , 1, buf_params.width[1], f);
            data += buf_params.pitch[1];
        }
        printf("  wrote %ubytes U\n", writen);
        // write V
        data = pdata + buf_params.offset[2];
        writen = 0;
        for (int i = 0; i < buf_params.height[2]; ++i) {
            writen += fwrite(data , 1, buf_params.width[2], f);
            data += buf_params.pitch[2];
        }
        printf("  wrote %ubytes V\n", writen);

        fclose(f);

        NvBufferMemUnMap(fd, 0, &pdata);

This is what it printed when saving file:

planes 3, 1920x1080 pitch 2048 offset 0 psize 2228224 layout 0, 960x540 pitch 1024 offset 2228224 psize 655360 layout 0, , 960x540 pitch 1024 offset 2883584 psize 655360 layout 0                                                            
  wrote 2073600bytes Y                                                                                                 
  wrote 518400bytes U                                                                                                  
  wrote 518400bytes V

But the saved file looks really weird, looks like not even a line is correctly written.
Can you please point me that I did something wrong or is there any better way or example code for this? Thank you.

hello Hnil.DN,

had you tried Applications Using V4L2 IOCTL Directly by using V4L2 IOCTL to dump the content for checking?
you may see-also MMAPI sample app, 07_video_convert for sample codes.

Thank you for pointing out the sample app. It works with this sample.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.