gstreamer/subprojects/gst-plugins-bad/sys/v4l2codecs
Marek Vasut a0755e5d74 v4l2codecs: Avoid QBUF/DQBUF struct timeval .tv_usec wrap-around at frame 1000000
When decoding stream using hardware V4L2 decoder element, in any of the
currently supported formats, the decoding will fail once frame number
1000000 is reached. The reported error clearly indicates a wrap-around
occured, instead of receiving decoded frame 1000000, frame 0 is received
from the hardware V4L2 decoder driver.

The problem is actually not in the driver itself, but rather in gstreamer,
which uses `struct v4l2_buffer` member `.timestamp` in a special way. The
timestamp of buffers with encoded data added to the SINK (input) queue of
the driver is copied by the driver into matching buffers with decoded data
added to the SOURCE (output) queue of the driver. In fact, the timestamp
is not a timestamp at all, but rather in this special case, only part of
it is used as an incrementing frame counter.

The `.timestamp` is of type `struct timeval`, which is defined in
`sys/time.h` [1]. Only the `tv_usec` member of this structure is used
for the incrementing frame counter. However, suseconds_t tv_usec [2]
may be limited to range [-1, 1000000]:
"
[XSI] The type suseconds_t shall be a signed integer type capable of
      storing values at least in the range [-1, 1000000].
"
Therefore, once frame 1000000 is reached, a rollover occurs and decoding
fails.

Fix this by using both `struct timeval` members, `.tv_sec` and `.tv_usec`
with matching modular arithmetic, this way the failure would occur again
just short of 2^84 frames, which should be plenty.

[1] https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_time.h.html
[2] https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_types.h.html

A test case using stateless hardware h264 decoder, the WARN/ERROR output
in gstreamer log indicates a failure occurred. With this change, that
error no longer occurs and the WARN/ERROR are not present:
```
pc$ gst-launch-1.0 videotestsrc num-buffers=1001001 pattern=6 ! \
                   video/x-raw,width=16,height=16,format=I420 ! \
                   x264enc ! filesink location=/tmp/test.h264

dut$ GST_DEBUG="*:3" gst-launch-1.0 filesrc location=/tmp/test.h264 ! \
                                    h264parse ! v4l2slh264dec ! fakesink
...
0:03:51.393677606 12111     0x370df400 WARN      \
  v4l2codecs-decoder gstv4l2decoder.c:1157:gst_v4l2_request_set_done:<v4l2decoder2> \
  Requested frame 1000000, but driver returned frame 0.
0:03:51.394140597 12111     0x370df400 WARN      \
  v4l2codecs-decoder gstv4l2decoder.c:1157:gst_v4l2_request_set_done:<v4l2decoder2> \
  Requested frame 1000001, but driver returned frame 1.
0:03:51.394425216 12111     0x370df400 WARN      \
  v4l2codecs-decoder gstv4l2decoder.c:1157:gst_v4l2_request_set_done:<v4l2decoder2> \
  Requested frame 1000002, but driver returned frame 2.
0:03:51.394665211 12111     0x370df400 WARN      \
  v4l2codecs-decoder gstv4l2decoder.c:1157:gst_v4l2_request_set_done:<v4l2decoder2> \
  Requested frame 1000003, but driver returned frame 3.
0:03:51.394785833 12111     0x370df400 WARN      \
  v4l2codecs-h264dec gstv4l2codech264dec.c:1059:gst_v4l2_codec_h264_dec_output_picture:<v4l2slh264dec0> \
  error: Failed to decode frame 1000000
ERROR: from element /GstPipeline:pipeline0/v4l2slh264dec:v4l2slh264dec0: Failed to decode frame 1000000
```

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5603>
2023-11-04 16:59:51 +00:00
..
linux v4l2codecs: Align v4l2 headers with HEVC final uAPI 2022-07-22 10:21:02 -04:00
gstv4l2codecallocator.c v4l2codecs: Fix segfault when destroying non-detached allocator 2021-11-02 15:25:48 +00:00
gstv4l2codecallocator.h Move files from gst-plugins-bad into the "subprojects/gst-plugins-bad/" subdir 2021-09-24 16:14:36 -03:00
gstv4l2codecalphadecodebin.c Move files from gst-plugins-bad into the "subprojects/gst-plugins-bad/" subdir 2021-09-24 16:14:36 -03:00
gstv4l2codecalphadecodebin.h Move files from gst-plugins-bad into the "subprojects/gst-plugins-bad/" subdir 2021-09-24 16:14:36 -03:00
gstv4l2codecdevice.c v4l2codecs: Warn user when no media devices are found 2022-09-29 19:12:14 +00:00
gstv4l2codecdevice.h Move files from gst-plugins-bad into the "subprojects/gst-plugins-bad/" subdir 2021-09-24 16:14:36 -03:00
gstv4l2codech264dec.c plugins: Fix various trivial clang compiler warnings 2023-03-18 19:52:40 +00:00
gstv4l2codech264dec.h Move files from gst-plugins-bad into the "subprojects/gst-plugins-bad/" subdir 2021-09-24 16:14:36 -03:00
gstv4l2codech265dec.c v4l2codecs: h265: Fix entry_point_offsets array leak 2023-10-18 00:17:54 +00:00
gstv4l2codech265dec.h v4l2codecs: Add v4l2 stateless H265 decoder 2022-07-22 10:21:02 -04:00
gstv4l2codecmpeg2dec.c v4l2codecs: Allow output caps to be updated 2022-11-16 13:12:38 +00:00
gstv4l2codecmpeg2dec.h v4l2codecs: mpeg2: Check that the decoder output formats 2021-12-10 21:37:14 +00:00
gstv4l2codecpool.c Move files from gst-plugins-bad into the "subprojects/gst-plugins-bad/" subdir 2021-09-24 16:14:36 -03:00
gstv4l2codecpool.h Move files from gst-plugins-bad into the "subprojects/gst-plugins-bad/" subdir 2021-09-24 16:14:36 -03:00
gstv4l2codecvp8dec.c v4l2codecs: Allow output caps to be updated 2022-11-16 13:12:38 +00:00
gstv4l2codecvp8dec.h Move files from gst-plugins-bad into the "subprojects/gst-plugins-bad/" subdir 2021-09-24 16:14:36 -03:00
gstv4l2codecvp9dec.c v4l2codecs: Allow output caps to be updated 2022-11-16 13:12:38 +00:00
gstv4l2codecvp9dec.h v4l2codecs: vp9: Add alpha decodebin wrapper 2021-12-10 21:37:14 +00:00
gstv4l2decoder.c v4l2codecs: Avoid QBUF/DQBUF struct timeval .tv_usec wrap-around at frame 1000000 2023-11-04 16:59:51 +00:00
gstv4l2decoder.h v4l2codecs: Trace request by it FD 2022-03-25 21:40:28 +00:00
gstv4l2format.c v4l2codecs: Fix tiled formats stride conversion 2023-10-11 16:48:50 +01:00
gstv4l2format.h v4l2codecs: Add P010 pixel format 2022-06-13 16:44:29 +02:00
meson.build meson: Call pkgconfig.generate in the loop where we declare plugins dependencies 2022-09-01 21:17:35 +00:00
plugin.c v4l2codecs: Add v4l2 stateless H265 decoder 2022-07-22 10:21:02 -04:00