gstreamer/subprojects
James Cowgill 1e27ea63af v4l2: Record buffer states in pool to fix dequeue race
The `gst_v4l2_buffer_pool_dqbuf` function contains this ominous comment:

    /* get our GstBuffer with that index from the pool, if the buffer was
     * outstanding we have a serious problem.
     */
    outbuf = pool->buffers[group->buffer.index];

Unfortunately it is common for buffers in _output_ buffer pools to be
both queued and outstanding at the same time. This can happen if the
upstream element keeps a reference to the buffer, or in an encoder
element itself when it keeps a reference to the input buffer for each
frame.

Since the current code doesn't handle this case properly we can end up
with crashes in other elements such as:

    (gst-launch-1.0:32559): CRITICAL **: 17:33:35.740: gst_video_frame_map_id: assertion 'GST_IS_BUFFER (buffer)' failed

and:

    (gst-launch-1.0:231): GStreamer-CRITICAL **: 00:16:20.882: write map requested on non-writable buffer

Both these crashes are caused by a race condition related to releasing
the same buffer twice from two different threads. If a buffer is queued
and outstanding this situation is possible:

**Thread 1**
- Calls `gst_buffer_unref` decrementing the reference count to zero.
- The core GstBufferPool object marks the buffer non-outstanding.
- Calls the V4L2 release buffer function.
- If the buffer is _not_ queued:
  - Release it back to the free pool (containing non-queued buffers).

**Thread 2**
- Dequeues the queued output buffer.
  - Marks the buffer as not queued.
- If the buffer is _not_ outstanding:
  - Calls the V4L2 release buffer function.
  - Release it back to the free pool (containing non-queued buffers).

If both of these threads run at exactly the same time there is a small
window where the buffer is marked both not outstanding and not queued
but before it has been released. In this case the buffer will be freed
twice causing the above crashes.

Unfortunately the variable recording whether a buffer is outstanding is
part of the core `GstBuffer` object and is managed by `GstBufferPool` so
it's not as straightforward as adding a mutex. Instead we can fix this
by additionally recording the buffer state in `GstV4l2BufferPool`, and
handle "internal" and "external" buffer release separately so we can
detect when a buffer becomes not outstanding.

In the new solution:
- The "external" buffer pool release and the "dqbuf" functions
  atomically update the buffer state and determine if a buffer is still
  queued or outstanding.
- Subsequent code and a new
  `gst_v4l2_buffer_pool_complete_release_buffer` function can proceed to
  release (or not) a buffer knowing that it's not racing with another
  thread.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1010>
2021-11-11 22:30:31 +00:00
..
gst-devtools Back to development 2021-11-03 19:31:23 +00:00
gst-docs docs: app-dev: events: seeking: use CLOCK_TIME_NONE instead of -1 and fix parameter names 2021-11-09 17:46:31 +00:00
gst-editing-services meson:ges: Fix typo adding ges gir to libs list 2021-11-08 11:10:11 -03:00
gst-examples webrtc janus rust: Update extra dependencies 2021-11-10 16:13:38 +00:00
gst-integration-testsuites gst-integration-tests: medias: update git module to latest commit 2021-11-08 18:59:58 +00:00
gst-libav Back to development 2021-11-03 19:31:23 +00:00
gst-omx Back to development 2021-11-03 19:31:23 +00:00
gst-plugins-bad avtp: crf: Process also local CRF streams 2021-11-10 16:53:04 +00:00
gst-plugins-base glcontext/egl: add missing unref 2021-11-10 15:27:45 +00:00
gst-plugins-good v4l2: Record buffer states in pool to fix dequeue race 2021-11-11 22:30:31 +00:00
gst-plugins-ugly Back to development 2021-11-03 19:31:23 +00:00
gst-python gst-python: Add option to disable python plugin 2021-11-10 13:38:04 -05:00
gst-rtsp-server Back to development 2021-11-03 19:31:23 +00:00
gstreamer bin: Don't check twice for adding a bin to itself or removing it from itself 2021-11-08 20:31:44 +00:00
gstreamer-sharp Back to development 2021-11-03 19:31:23 +00:00
gstreamer-vaapi Back to development 2021-11-03 19:31:23 +00:00
macos-bison-binary New subproject macos-bison-binary to provide bison on macOS 2021-08-28 23:44:52 +05:30
win-flex-bison-binaries win-flex-bison: Use gstreamer mirror as primary source 2020-01-18 17:54:48 +05:30
win-nasm win-nasm: Use gstreamer mirror as primary source 2020-01-18 17:54:48 +05:30
avtp.wrap Revert "Revert "Add libavtp wrap file"" 2020-06-30 15:47:18 -07:00
bindinator.wrap Pin all wrap files to closest tag or commit sha1 2021-10-14 22:34:49 +00:00
cairo.wrap Pin all wrap files to closest tag or commit sha1 2021-10-14 22:34:49 +00:00
dav1d.wrap Add dav1d wrap file 2020-05-02 09:55:12 +00:00
dssim.wrap Pin all wrap files to closest tag or commit sha1 2021-10-14 22:34:49 +00:00
dv.wrap subprojects: add libdv wrap 2021-01-14 19:16:01 +00:00
expat.wrap meson: Update expat.wrap for MSVC fix 2020-11-05 13:09:46 +05:30
fdk-aac.wrap subprojects: fdk-aac: add fallback_url 2021-10-28 23:29:27 +00:00
FFmpeg.wrap wraps:ffmpeg: Move to 4.4 2021-10-15 02:32:40 +00:00
fontconfig.wrap Pin all wrap files to closest tag or commit sha1 2021-10-14 22:34:49 +00:00
freetype2.wrap Pin all wrap files to closest tag or commit sha1 2021-10-14 22:34:49 +00:00
fribidi.wrap Pin all wrap files to closest tag or commit sha1 2021-10-14 22:34:49 +00:00
gl-headers.wrap Move files from gst-plugins-base into the "subprojects/gst-plugins-base/" subdir 2021-09-24 16:13:26 -03:00
glib-networking.wrap Pin all wrap files to closest tag or commit sha1 2021-10-14 22:34:49 +00:00
glib.wrap Pin all wrap files to closest tag or commit sha1 2021-10-14 22:34:49 +00:00
graphene.wrap Pin all wrap files to closest tag or commit sha1 2021-10-14 22:34:49 +00:00
gst-plugins-rs.wrap re-add gst-plugins-rs.wrap 2021-11-02 10:15:42 +01:00
gtk-sharp.wrap Pin all wrap files to closest tag or commit sha1 2021-10-14 22:34:49 +00:00
harfbuzz.wrap harfbuzz.wrap: Use the latest tag instead of tip of git 2021-07-02 17:08:48 +03:00
json-glib.wrap Pin all wrap files to closest tag or commit sha1 2021-10-14 22:34:49 +00:00
lame.wrap meson: Support building lame as subproject 2021-10-16 00:43:10 +00:00
libdrm.wrap subprojects: add libdrm wrap 2020-04-03 10:15:09 +02:00
libffi.wrap subprojects: use libffi and gl-headers from gstreamer gitlab repos 2019-01-28 23:19:19 +01:00
libjpeg-turbo.wrap subprojects: Bump libjpeg-turbo version to 2.1.0-2 for x86 MSVC build 2021-08-04 19:22:30 +09:00
libmicrodns.wrap subprojects: libmicrodns: pin to 0.1.2 release 2020-07-07 15:23:29 +01:00
libnice.wrap Pin all wrap files to closest tag or commit sha1 2021-10-14 22:34:49 +00:00
libopenjp2.wrap wrap: libopenjp2: use patch version 7 2021-10-22 19:47:27 +00:00
libpsl.wrap libpsl.wrap: pin to 0.21.1 tag 2020-10-26 12:13:12 +00:00
libsoup.wrap Pin all wrap files to closest tag or commit sha1 2021-10-14 22:34:49 +00:00
libwpe.wrap subprojects: Update libwpe and wpebackend-fdo for fallback support 2020-10-12 12:29:01 +00:00
libxml2.wrap libxml2: update wrap path to 2.9.7-6 2020-02-19 13:45:52 +01:00
ogg.wrap subprojects: Update ogg and vorbis wraps 2021-10-19 17:42:21 +00:00
openh264.wrap openh264: update to v2.1.1 2020-05-31 11:11:18 +01:00
opus.wrap Pin all wrap files to closest tag or commit sha1 2021-10-14 22:34:49 +00:00
orc.wrap Pin all wrap files to closest tag or commit sha1 2021-10-14 22:34:49 +00:00
pango.wrap subprojects: pin pango wrap to tag 2021-08-08 19:42:24 +01:00
pixman.wrap Pin all wrap files to closest tag or commit sha1 2021-10-14 22:34:49 +00:00
proxy-libintl.wrap subprojects: proxy-libintl: fix push-url 2019-08-14 18:51:43 +01:00
pycairo.wrap {pygobject,pycairo}.wrap: point to stable refs 2020-09-15 15:51:42 +03:00
pygobject.wrap Pin all wrap files to closest tag or commit sha1 2021-10-14 22:34:49 +00:00
sqlite3.wrap Update to sqlite3 from wrapdb 2021-08-24 20:52:06 +00:00
vorbis.wrap subprojects: Update ogg and vorbis wraps 2021-10-19 17:42:21 +00:00
webrtc-audio-processing.wrap Pin all wrap files to closest tag or commit sha1 2021-10-14 22:34:49 +00:00
wpebackend-fdo.wrap subprojects: Update libwpe and wpebackend-fdo for fallback support 2020-10-12 12:29:01 +00:00
x264.wrap x264: update to latest stable 160.3011 2020-07-30 15:52:38 +01:00
zlib.wrap meson: Update zlib.wrap to use wrapdb instead of github fork 2021-01-13 12:55:06 +00:00