Ebusy error in unexpected place v4l2 encoder

Hi,

caught an error in v4l2 encoder non-blocking mode, qbuffer capture_plane randomly return ebusy error.

Example with modified 01_video_encode:

./video_encode ~/source.yuv 1280 720 H264 ~/h1.stats --blocking-mode 0 --stats

# ./video_encode ~/hall.yuv 1280 720 H264 ~/h1.stats --blocking-mode 0 --stats
Creating Encoder in non-blocking mode
Opening in O_NONBLOCKING MODE
NvMMLiteOpen : Block : BlockType = 4
===== NVMEDIA: NVENC =====
NvMMLiteBlockCreate : Block : BlockType = 4
875967048
842091865
H264: Profile = 66, Level = 51
Created the PollThread and Encoder Thread
Starting Device Poll Thread
..........10000..........20000..........30000.....[ERROR] (NvV4l2ElementPlane.cpp:256) <enc0> Capture Plane:Error while Qing buffer: Device or resource busy
Error while Qing buffer at capture plane
Capture plane dequeued 0 size buffer
----------- Element = enc0 -----------
Total Profiling time = 86.6671
Average FPS = 408.783
Total units processed = 35429
Average latency(usec) = 19048
Minimum latency(usec) = 8889
Maximum latency(usec) = 89813
-------------------------------------
Encoder is in error
App run failed

jetson tx2, lastes l4t2
# R32 (release), REVISION: 4.3, GCID: 21589087, BOARD: t186ref, EABI: aarch64, DATE: Fri Jun 26 04:34:27 UTC 2020

# dpkg -l | grep nvidia
ii  ffmpeg                                     7:4.2.2-nvidia                                   arm64        Tools for transcoding, streaming and playing
of multimedia files
ii  nvidia-l4t-3d-core                         32.4.3-20200625213407                            arm64        NVIDIA GL EGL Package
ii  nvidia-l4t-apt-source                      32.4.3-20200625213407                            arm64        NVIDIA L4T apt source list debian package
ii  nvidia-l4t-bootloader                      32.4.3-20200709231533                            arm64        NVIDIA Bootloader Package
ii  nvidia-l4t-camera                          32.4.3-20200625213407                            arm64        NVIDIA Camera Package
ii  nvidia-l4t-configs                         32.4.3-20200625213407                            arm64        NVIDIA configs debian package
ii  nvidia-l4t-core                            32.4.3-20200625213407                            arm64        NVIDIA Core Package
ii  nvidia-l4t-cuda                            32.4.3-20200625213407                            arm64        NVIDIA CUDA Package
ii  nvidia-l4t-firmware                        32.4.3-20200625213407                            arm64        NVIDIA Firmware Package
ii  nvidia-l4t-graphics-demos                  32.4.3-20200625213407                            arm64        NVIDIA graphics demo applications
ii  nvidia-l4t-gstreamer                       32.4.3-20200625213407                            arm64        NVIDIA GST Application files
ii  nvidia-l4t-init                            32.4.3-20200625213407                            arm64        NVIDIA Init debian package
ii  nvidia-l4t-initrd                          32.4.3-20200625213407                            arm64        NVIDIA initrd debian package
ii  nvidia-l4t-jetson-io                       32.4.3-20200625213407                            arm64        NVIDIA Jetson.IO debian package
ii  nvidia-l4t-jetson-multimedia-api           32.4.3-20200625213407                            arm64        NVIDIA Jetson Multimedia API is a collection
of lower-level APIs that support flexible application development.
ii  nvidia-l4t-kernel                          4.9.140-tegra-32.4.3-20200625213407              arm64        NVIDIA Kernel Package
ii  nvidia-l4t-kernel-dtbs                     4.9.140-tegra-32.4.3-20200625213407              arm64        NVIDIA Kernel DTB Package
ii  nvidia-l4t-kernel-headers                  4.9.140-tegra-32.4.3-20200625213407              arm64        NVIDIA Linux Tegra Kernel Headers Package
ii  nvidia-l4t-multimedia                      32.4.3-20200625213407                            arm64        NVIDIA Multimedia Package
ii  nvidia-l4t-multimedia-utils                32.4.3-20200625213407                            arm64        NVIDIA Multimedia Package
ii  nvidia-l4t-oem-config                      32.4.3-20200625213407                            arm64        NVIDIA OEM-Config Package
ii  nvidia-l4t-tools                           32.4.3-20200709231533                            arm64        NVIDIA Public Test Tools Package
ii  nvidia-l4t-wayland                         32.4.3-20200625213407                            arm64        NVIDIA Wayland Package
ii  nvidia-l4t-weston                          32.4.3-20200625213407                            arm64        NVIDIA Weston Package
ii  nvidia-l4t-x11                             32.4.3-20200625213407                            arm64        NVIDIA X11 Package
ii  nvidia-l4t-xusb-firmware                   32.4.3-20200625213407                            arm64        NVIDIA USB Firmware Package
ii  nvidia-opencv                              4.4-b186                                         arm64        NVIDIA OpenCV Meta Package

patch

  • added little sleep between dqbuffer and qbuffer capture_plane
  • seek to start file after each reading next frame
diff -ruN jetson_multimedia_api.orig/samples/01_video_encode/video_encode_main.cpp jetson_multimedia_api/samples/01_video_encode/video_encode_main.cpp
--- jetson_multimedia_api.orig/samples/01_video_encode/video_encode_main.cpp    2020-07-30 23:41:18.891615012 +0300
+++ jetson_multimedia_api/samples/01_video_encode/video_encode_main.cpp 2020-07-31 00:09:15.610160262 +0300
@@ -35,6 +35,7 @@
 #include <string.h>
 #include <fcntl.h>
 #include <poll.h>
+#include <unistd.h>
 #include "nvbuf_utils.h"

 #include "video_encode.h"
@@ -225,6 +226,10 @@
             write_encoder_output_frame(ctx->gdr_out_file, buffer);

     num_encoded_frames++;
+    if (!(num_encoded_frames % 1000))
+      cout << "." << flush;
+    if (!(num_encoded_frames % 10000))
+      cout << num_encoded_frames << flush;

     if (ctx->report_metadata)
     {
@@ -317,6 +322,8 @@
         }
     }

+    usleep(300);
+
     /* encoder qbuffer for capture plane */
     if (enc->capture_plane.qBuffer(*v4l2_buf, NULL) < 0)
     {
@@ -880,6 +887,7 @@
                     v4l2_output_buf.m.planes[2].bytesused = 0;
                 }
             }
+            ctx.in_file->seekg(0);

             /* Encoder supported input metadata specific configurations */
             if (ctx.input_metadata)

Hi,
We are not sure why the patch is required in real usecase. Please share more information and explanation. Thanks.

Hi,

usecase - streaming encode incoming raw frames and some work. It seems that the longer the pause between dqbuffer and qbuffer, the more likely a bug in qbuffer is. Even simple memcpy or annexb_to_mp4 conversion does not guarantee the absence of errors, especially when several encoders are running in parallel.
Thanks

Hi,

looks like non-blocking api useless. In my async case switch to blocking api in separate thread more useful. Thanks for your support.

Hi,
We will check this condition in non-blocking mode. If blocking mode is also good for your usecase, suggest you use it for further development.