How to get the Y value of YUV420M format video data from NvBuffer?

Hi Nvidia:
MMAPI R28.1, example 12_camera_v4l2_cuda, in function
conv_capture_dqbuf_thread_callback(struct v4l2_buffer *v4l2_buf,
NvBuffer * buffer,
NvBuffer * shared_buffer,
void *arg)
we can get the Y value of YUV420M format video data from NvBuffer by
buffer->planes[0].data //start address of Y value
buffer->planes[0].bytesused //size of Y value

but in MMAPI R28.2, example 12_camera_v4l2_cuda, how to get the Y vlaue of YUV420M format video data from
NvBuffer:ctx->render_dmabuf_fd?

and there is another problem:
when example 12_camera_v4l2_cuda of MMAPI 28.1 copy to /tegra_multimedia_api/sample/ of MMAPI 28.2,compile and run, the program run successful,but CTRL+C keys pressed,the program stoped failed. How to solve this prblem?

Expected your reply! Thanks a lot!

Please try with “NvBufferGetParams(dmabuf_fd, &parm)”

Hi WayneWWW:
Thank you for your reply.

function int NvBufferGetParams(int dmabuf_fd,
NvBufferParams * params
)
NvBufferParams define as:
typedef struct _NvBufferParams
{
uint32_t dmabuf_fd;
void *nv_buffer;
NvBufferPayloadType payloadType;
int32_t memsize;
uint32_t nv_buffer_size;
uint32_t pixel_format;
uint32_t num_planes;
uint32_t width[MAX_NUM_PLANES];
uint32_t height[MAX_NUM_PLANES];
uint32_t pitch[MAX_NUM_PLANES];
uint32_t offset[MAX_NUM_PLANES];
uint32_t psize[MAX_NUM_PLANES];
uint32_t layout[MAX_NUM_PLANES];
}NvBufferParams;
in NvBufferParams struct, it is still not find where the Y value of YUV420M format video data saved.

and is there any way to solve the program stop problem?

Expected your reply again! Thanks!

Please refer to the usecase of 10_camera_recording.

Reading the structure, it seems like you’d start at the nv_buffer address, and then add offset[0] bytes to that, to get at the start of the Y plane. Then you’d get each scanline at pitch[0] bytes separation.
Does this not work?

Hi snarky:
Thanks for your reply.
On MMAPI R28.1, in function
conv_capture_dqbuf_thread_callback(struct v4l2_buffer *v4l2_buf,
NvBuffer * buffer,
NvBuffer * shared_buffer,
void *arg)
below codes added for rendering YUV420M data as grey video:
void *data;
NvBuffer::NvBufferPlane &plane = buffer->planes[1];
data = (void *)plane.data;
memset(data,128,v4l2_buf->m.planes[1].bytesused);

void *data1;
NvBuffer::NvBufferPlane &plane1 = buffer->planes[2];
data1 = (void *)plane1.data;
memset(data1,128,v4l2_buf->m.planes[2].bytesused);

ctx->renderer->render(buffer->planes[0].fd);

according to your method,On MMAPI R28.2, in function
conv_capture_dqbuf_thread_callback(struct v4l2_buffer v4l2_buf,
NvBuffer * buffer,
NvBuffer * shared_buffer,
void arg)
below codes added could render YUV420M data as grey video too:
NvBufferGetParams(ctx->render_dmabuf_fd, &parm);
memset((unsigned char
)(parm.nv_buffer)+parm.offset[1],128,parm.pitch[1]);
memset((unsigned char
)(parm.nv_buffer)+parm.offset[2],128,parm.pitch[2]);
ctx->renderer->render(ctx->render_dmabuf_fd);

but the result is “Segmentation fault(core dumped)” when codes added.
so it is not the method to get Y value from YUV420M format video data.

expected your reply again! Thank you!

feng.baoying,

Please try with below code snippet in 10_camera_recording.
The NvBufferMemMap and NvBufferMemSyncForCpu will help you map the Y plane value to ptr_y.

if (DO_CPU_PROCESS) {
            NvBufferParams par;
            NvBufferGetParams (fd, &par);
            void *ptr_y;
            uint8_t *ptr_cur;
            int i, j, a, b;
            NvBufferMemMap(fd, Y_INDEX, NvBufferMem_Write, &ptr_y);
            NvBufferMemSyncForCpu(fd, Y_INDEX, &ptr_y);
            ptr_cur = (uint8_t *)ptr_y + par.pitch[Y_INDEX]*START_POS + START_POS;

            // overwrite some pixels to put an 'N' on each Y plane
            // scan array_n to decide which pixel should be overwritten
            for (i=0; i < FONT_SIZE; i++) {
                for (j=0; j < FONT_SIZE; j++) {
                    a = i>>SHIFT_BITS;
                    b = j>>SHIFT_BITS;
                    if (array_n[a][b])
                        (*ptr_cur) = 0xff; // white color
                    ptr_cur++;
                }
                ptr_cur = (uint8_t *)ptr_y + par.pitch[Y_INDEX]*(START_POS + i)  + START_POS;
            }
            NvBufferMemSyncForDevice (fd, Y_INDEX, &ptr_y);
            NvBufferMemUnMap(fd, Y_INDEX, &ptr_y);
        }

Hi:WayneWWW
Thanks for your reply!
I will read the code of 10_camera_recording detailed later and test the method you give.
And the other problem:
when example 12_camera_v4l2_cuda of MMAPI 28.1 copy to /tegra_multimedia_api/sample/ of MMAPI 28.2,compile and run, the program run successful,but CTRL+C keys pressed,the program not stoped completely. How to solve this prblem?
Expected your reply again! Thanks!

In fact, there are many changes between rel-28.1 and rel-28.2 mmapi sample. There may be some compatibility issue. Also, this looks like a different issue from your original topic. Please file a new one for this.

Where is NvBufferMemSyncForCpu documented? A Google search doesn’t find anything.