gstreamer/subprojects/gst-plugins-bad/sys
Marek Vasut 5d2d602e4a 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/5598>
2023-11-04 15:51:45 +01:00
..
aja aja: Move clang-format configuration from the top-level to the plugin subdirectory 2023-10-27 11:44:36 +00:00
amfcodec amfav1enc: Workaround driver bug with bt601 color matrix 2023-06-16 10:10:33 +00:00
androidmedia androidmedia/enc: handle codec-data before popping GstVideoCodecFrames 2023-09-15 17:47:17 +03:00
applemedia vtdec: Fix deadlock when attempting to negotiate 2023-10-20 13:50:16 +02:00
asio meson: Call pkgconfig.generate in the loop where we declare plugins dependencies 2022-09-01 21:17:35 +00:00
bluez avdtputil: Use int instead of int range for fixed bitpool values 2023-05-17 03:13:54 +00:00
d3d11 d3d11: Set MaxAnisotropy value for the best quality 2023-11-01 15:41:08 +00:00
d3d12 d3d12: Fix build with GST_DISABLE_GST_DEBUG 2023-11-03 13:31:03 +00:00
d3dvideosink d3dvideosink: Fix navigation event leak 2023-06-15 05:09:46 +00:00
decklink decklink: Fix broken COM string conversion 2023-10-09 20:10:25 +09:00
directshow sys: avoid double definition of symbol MEDIASUBTYPE_I420 2023-03-23 00:56:04 +00:00
directsound meson: Call pkgconfig.generate in the loop where we declare plugins dependencies 2022-09-01 21:17:35 +00:00
dvb doc: Fix newline char between authors 2023-05-20 05:48:23 +00:00
dwrite d3d12, dwrite, va: Fix various msys2 build error/warning 2023-10-12 10:53:58 +00:00
fbdev meson: Call pkgconfig.generate in the loop where we declare plugins dependencies 2022-09-01 21:17:35 +00:00
ipcpipeline meson: Call pkgconfig.generate in the loop where we declare plugins dependencies 2022-09-01 21:17:35 +00:00
kms kmssink: Add TIDSS auto-detection 2023-10-12 18:25:50 +00:00
magicleap meson: Call pkgconfig.generate in the loop where we declare plugins dependencies 2022-09-01 21:17:35 +00:00
mediafoundation mediafoundation: Fix build with GST_DISABLE_GST_DEBUG 2023-11-03 13:31:03 +00:00
msdk msdkvpp: Use filter flag to handle passthrough for tone mapping 2023-10-12 05:02:37 +00:00
nvcodec nvencoder: Add support for new preset/tune/multi-pass options 2023-10-14 11:03:40 +00:00
opensles meson: Call pkgconfig.generate in the loop where we declare plugins dependencies 2022-09-01 21:17:35 +00:00
qsv qsv: Remove x86_64 constraint on Linux 2023-07-14 13:12:29 +00:00
shm shm: drop use of GSlice allocator 2023-02-03 17:48:10 +00:00
tinyalsa meson: Call pkgconfig.generate in the loop where we declare plugins dependencies 2022-09-01 21:17:35 +00:00
uvcgadget uvcsink: use the pad's current caps to update caps_changed 2023-10-06 15:55:23 +00:00
uvch264 meson: Add a wrap file for libgudev 2023-04-19 22:47:19 +00:00
v4l2codecs v4l2codecs: Avoid QBUF/DQBUF struct timeval .tv_usec wrap-around at frame 1000000 2023-11-04 15:51:45 +01:00
va va: Use vaMapBuffer2 2023-10-23 19:40:16 +00:00
wasapi wasapi: Don't redefine GUIDs when building under newer MinGW 2023-08-09 14:47:57 +00:00
wasapi2 wasapi2: Fix build with GST_DISABLE_GST_DEBUG 2023-11-03 13:31:03 +00:00
wic bad: Update indent 2023-02-28 10:12:31 +00:00
win32ipc win32ipc: Fix pipe handle leak 2023-08-23 18:33:04 +09:00
winks doc: Fix newline char between authors 2023-05-20 05:48:23 +00:00
winscreencap winscreencap: Warn for deprecated plugin use 2022-12-08 17:48:11 +00:00
meson.build aja: Integrate AJA plugin into the build system 2023-10-26 09:36:09 +03:00