dqBuffer is blocking (mostly)

We are using the tegra multimedia API to encode H264 video received from a camera on a Jetson TX2.

We have been having an issue with dequeuing buffers for encoding. We are using code that was taken from the examples with a few modifications to integrate into our project and are seeing the dqBuffer() method of the NvV4l2ElementPlane class for the capture plane blocking, specifically the call to :

ret = v4l2_ioctl(fd, VIDIOC_DQBUF, &v4l2_buf);

I have ensured this is opened using O_NONBLOCK ,

NvVideoEncoder::createVideoEncoder("enc0", O_NONBLOCK)

, and I am also ensuring there are buffers available in the queue. This application runs reliably on Jetpack 3.1 but am having issues with Jetpack 3.3. Very often the dqBuffer() method will block for 10 seconds before returning. I will get anywhere from 1 to 10 buffers dequeued before it wedges permanently. This doesn’t happen every time or on every device, but it happens more often than not. I have added logging to narrow the problem so I could see exactly where the problem is, and very often this will fix the problem. I will delete the logging and the problem will be back. Occasionally I can repeat the problem with the logging, and that is how I have been able to trace the source of the problem.

I have tried both the V4L2_MEMORY_MMAP and V4L2_MEMORY_DMABUF options for the buffers and get the similar results although it seems to be a little bit better with the DMA option.

This looks very much like some sort of race condition internally and I have no idea what might be causing it.

I am wondering if anyone else has seen anything else like this or if anyone might have an idea what is happening?

Hi,
We have not well implemented O_NONBLOCK mode on r28.2.1(Jetpack 3.3). Please run in block mode.

Also please apply prebuilt lib at https://elinux.org/Jetson_TX2/28.2.1_patches
[MMAPI]Cannot run NvVideoDecoder in loop/Memory leak in NvVideoEncoder

Thanks for the reply. I changed the non-blocking behavior and returned it to the original blocking mode and used the patch you recommended with the same result.

I have found additional information in more testing I have done. I have been trying the get this to run both in and outside of a docker container. The pattern I have noticed is that if I run it outside the container after a fresh reboot, it will run fine. If I then run it inside the docker container, it will run fine also.
But, if I reboot the device and then try to run it inside the container first, I will find that dqbuffer blocks and does not dequeue data. If I then try to run it outside the container, I will get the same blocking behavior. It depends on where I run it first as to whether it will work either way.

If I run it outside the container first, it will then run both outside and inside the container fine.
If I run it inside the container first, it won’t work either inside or outside the container. I can repeat this every time across multiple devices.

I was wondering if it has to do with the device mappings I am using the create the docker container. I am mapping the following devices:

/dev/nvhost-ctrl \
      /dev/nvhost-ctrl-gpu \
      /dev/nvhost-prof-gpu \
      /dev/nvmap \
      /dev/nvhost-gpu \
      /dev/nvhost-as-gpu \
      /dev/nvhost-msenc \
      /dev/v4l \
      /dev/v4l-subdev0 \
      /dev/v4l-subdev1 \
      /dev/ttyTHS1 \
      /dev/ttyTHS2 \
      /dev/ttyTHS3 \
      /dev/video0 \
      /dev/video1 \
      /dev/bus/usb \
      /dev/bus/usb/001/001 \
      /dev/bus/usb/001/002 \
      /dev/bus/usb/002/001 \
      /dev/rtc \
      /dev/mmcblk1p1 \
      /dev/sda1 \
      /dev/can0 \
      /dev/can1

Probably you also need to include firmware path.
Please check https://devtalk.nvidia.com/default/topic/1046684/

THAT WAS IT!!!

THANK YOU!!!

Has this been implemented in 4.2?

Hi,

Yes. Please set ‘–blocking-mode 0’ in running 01_video_encode

Awesome, Thanks :)

Has the dqBuffer()'s blocking issue described at the top of the page been fixed in Jetpack 4.2?

From the comments above I deduce the non-blocking mode is now supported, therefore the driver should not block anymore. Can anyone confirm this please?

Hi,

Yes. Please refer to 01_video_encode.