MMAPI, how can we capture H264 frame from USB camera using MMAPI?

Hi moderators and geek friends,

After playing with TX2 and MMAPI a while, I get some experiences on capture YUY2 from a USB camera from sample codes 12_camera_v4l2_cuda and v4l2cuda. They are directly utilizing V4L2 iotcl() calls to setup and capture raw frames from camera. (BTW there is a wonderful website offering online raw image view, http://rawpixels.net/)

But, it shows at 12_camera_v4l2_cuda that only YUYV/YVYU/UYVY/VYUY are supported. I get a USB camera which can produce

video/x-h264, stream-format=(string)byte-stream, alignment=(string)au, width=(int)640, height=(int)480, pixel-aspect-ratio=(fraction)1/1, colorimetry=(string)2:4:7:1, framerate=(fraction)20/1

and normal YUY2 frames.
Thus, I am wondering if MMAPI supports capturing H264 frame or not? If it does, could you kindly share your codes here or give some guides and hints? :)

Hi fengxueem,
We don’t have sample code same as this and you need to implement by your self. You can get h264 stream via v4l2 and sent it to NvVideoDecoder to get decoded YUV420.

Hi DaneLLL,
I have one more question about NvVideoDecoder. When we detect a resolution change event and set up decoder and converter in 02_video_dec_cuda, we set up decoder’s capture plane by

ret = dec->capture_plane.setupPlane(V4L2_MEMORY_, min_dec_capture_buffers + 5, false, false);

It’s using MMAP to transfer data. But when I try to map these buffers by changing the 3rd parameter from false to true. I get errors which tell me these buffers cannot be mapped. Why is that?
BTW, my intention to do so was to save the frame to a file on disk. Since, they cannot be mapped, I send these buffers to NvViderConverter as shared buffers

ctx->conv->output_plane.qBuffer(conv_output_buffer, dec_buffer)

just like what 02_video_dec_cuda does, then read the frame out of the capture plane(MMAP) of converter and save it to the disk.

Dynamic resolution change is not working fine and tracked at https://devtalk.nvidia.com/default/topic/1032037/

Does your case work well in fixed resolution?

Hi DaneLLL,
Yes, it works well in fixed resolution. However, what bothers me is why the buffers of NvVideoDecoder’s capture plane cannot be mapped.
Using the exact same code as 02_video_dec_cuda, only try to change the 3rd parameter of

ret = dec->capture_plane.setupPlane(V4L2_MEMORY_MMAP, min_dec_capture_buffers + 5, false, false);

from false to true at line 515 of videodec_main.cpp. And the program won’t run and tells me that the buffers cannot be mapped. As far as I know, normally buffers transfered via MMAP between different devices should be able to mapped to our main memory, right? I am curious about what is stopping the map of these buffers?

Hi fengxueem,
Decoded buffers are in blocklinear format, which is not open for access. You need to convert decoded buffers into pitch linear by NvVideoConverter.

Thanks a lot! It’s a short but solid answer!