#11599: `gdigrab` Screen Capture Causes Cursor Flickering and Focus Loss on
Windows
(Multi-Monitor)
------------------------------------+----------------------------------
Reporter: Evgene | Owner: (none)
Type: defect | Status: new
Priority: critical | Component: ffmpeg
Version: git-master | Resolution:
Keywords: | Blocked By:
Blocking: | Reproduced by developer: 1
Analyzed by developer: 1 |
------------------------------------+----------------------------------
Description changed by Evgene:
Old description:
> **Environment**
> - **OS**: Windows 11 Enterprise LTSC (Build 22000)
> - **FFmpeg Version**: Custom build `N-119502-g12b853530a-20250515`
> (`libavdevice 62.0.100`)
> - **Hardware**: Multi-monitor setup, high-resolution displays
> - **Reproducible**: Yes, with provided command
>
> ---
>
> ### **Steps to Reproduce**
> 0. **Version**
> ```
> > ffmpeg -version
> ffmpeg version N-119502-g12b853530a-20250515 Copyright (c) 2000-2025 the
> FFmpeg developers
> built with gcc 14.2.0 (crosstool-NG 1.27.0.18_7458341)
> configuration: --prefix=/ffbuild/prefix --pkg-config-flags=--static
> --pkg-config=pkg-config --cross-prefix=x86_64-w64-mingw32- --arch=x86_64
> --target-os=mingw32 --enable-gpl --enable-version3 --disable-debug
> --enable-shared --disable-static --disable-w32threads --enable-pthreads
> --enable-iconv --enable-zlib --enable-libfribidi --enable-gmp --enable-
> libxml2 --enable-lzma --enable-fontconfig --enable-libharfbuzz --enable-
> libfreetype --enable-libvorbis --enable-opencl --disable-libpulse
> --enable-libvmaf --disable-libxcb --disable-xlib --enable-amf --enable-
> libaom --enable-libaribb24 --enable-avisynth --enable-chromaprint
> --enable-libdav1d --enable-libdavs2 --enable-libdvdread --enable-
> libdvdnav --disable-libfdk-aac --enable-ffnvcodec --enable-cuda-llvm
> --enable-frei0r --enable-libgme --enable-libkvazaar --enable-
> libaribcaption --enable-libass --enable-libbluray --enable-libjxl
> --enable-libmp3lame --enable-libopus --enable-librist --enable-libssh
> --enable-libtheora --enable-libvpx --enable-libwebp --enable-libzmq
> --enable-lv2 --enable-libvpl --enable-openal --enable-liboapv --enable-
> libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264
> --enable-libopenjpeg --enable-libopenmpt --enable-librav1e --enable-
> librubberband --enable-schannel --enable-sdl2 --enable-libsnappy
> --enable-libsoxr --enable-libsrt --enable-libsvtav1 --enable-libtwolame
> --enable-libuavs3d --disable-libdrm --enable-vaapi --enable-libvidstab
> --enable-vulkan --enable-libshaderc --enable-libplacebo --enable-libvvenc
> --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxvid
> --enable-libzimg --enable-libzvbi --extra-cflags=-DLIBTWOLAME_STATIC
> --extra-cxxflags= --extra-libs=-lgomp --extra-ldflags=-pthread --extra-
> ldexeflags= --cc=x86_64-w64-mingw32-gcc --cxx=x86_64-w64-mingw32-g++
> --ar=x86_64-w64-mingw32-gcc-ar --ranlib=x86_64-w64-mingw32-gcc-ranlib
> --nm=x86_64-w64-mingw32-gcc-nm --extra-version=20250515
> libavutil 60. 2.100 / 60. 2.100
> libavcodec 62. 3.101 / 62. 3.101
> libavformat 62. 0.102 / 62. 0.102
> libavdevice 62. 0.100 / 62. 0.100
> libavfilter 11. 0.100 / 11. 0.100
> libswscale 9. 0.100 / 9. 0.100
> libswresample 6. 0.100 / 6. 0.100
>
> Exiting with exit code 0
> ```
>
> ```
> > systeminfo | findstr /B /C:"OS Name" /B /C:"OS Version"
> OS Name: Microsoft Windows 11 Enterprise LTSC
> OS Version: 10.0.22000 N/A Build 22000
> ```
>
>
> 1. **Command**:
> ```shell
> ffmpeg \
> -loglevel level+info \
> -y \
> -framerate 10 \
> -threads 4 \
> -fflags nobuffer \
> -avioflags direct \
> -probesize 32 \
> -analyzeduration 0 \
> -f gdigrab \
> -i desktop \
> -map 0:v \
> -f rawvideo \
> -pix_fmt rgb24 \\.\pipe\ffmpeg_video
> ```
>
> 2. **Actions During Capture**:
> - Move cursor rapidly across secondary monitor.
> - Attempt to select text or drag UI elements (e.g., in a text editor).
>
> 3. **Result**:
> - Visible cursor flickering.
> - Intermittent loss of focus during interactions (e.g., text selection
> resets).
>
> ---
>
> ### **Root Cause**
> The `gdigrab` device in FFmpeg’s `avdevice` library forcibly repositions
> the cursor during frame capture[^1]. On multi-monitor/high-DPI systems,
> this introduces a race condition:
> - FFmpeg moves the cursor to capture its position/sprite.
> - Windows UI thread fails to restore the cursor quickly enough, causing
> flickering and focus instability.
>
> ---
>
> ### **Workaround (Verified)**
> **Patch `avdevice-62.dll`**:
> Modify the library to **skip cursor repositioning** during capture.
> Tools like x64dbg or Ghidra can be used to:
> - Locate the cursor position update logic in `gdigrab`’s capture loop.
> - NOP (disable) instructions that call `SetCursorPos()` or equivalent
> Win32 APIs.
>
> ---
>
> ### **Proposed Upstream Fix**
> 1. **FFmpeg Code Change**:
> In `libavdevice/gdigrab.c`, modify the cursor handling logic to:
> ```c
> // Replace physical cursor movement with position caching
> static void capture_cursor(...) {
> // GetCursorPos(&cursor_pos); // <-- Remove this
> // SetCursorPos(cursor_pos.x, cursor_pos.y); // <-- Remove this
> // Draw cursor sprite on frame using cached position
> }
> ```
>
> 2. **Alternative**: Modify `-draw_mouse 0` flag to avoid mouse
> interaction.
>
> ---
>
> ### **References**
> [^1]: [FFmpeg gdigrab Cursor Flicker Discussion
> (2020)](https://stackoverflow.com/questions/34023630)
> [^2]: [Previous conversation](https://ffmpeg.org/pipermail/ffmpeg-
> devel/2019-December/255101.html)
New description:
**Environment**
- **OS**: Windows 11 Enterprise LTSC (Build 22000)
- **FFmpeg Version**: Custom build `N-119502-g12b853530a-20250515`
(`libavdevice 62.0.100`)
- **Hardware**: Multi-monitor setup, high-resolution displays
- **Reproducible**: Yes, with provided command
---
### **Steps to Reproduce**
0. **Version**
```
> ffmpeg -version
ffmpeg version N-119502-g12b853530a-20250515 Copyright (c) 2000-2025 the
FFmpeg developers
built with gcc 14.2.0 (crosstool-NG 1.27.0.18_7458341)
configuration: --prefix=/ffbuild/prefix --pkg-config-flags=--static --pkg-
config=pkg-config --cross-prefix=x86_64-w64-mingw32- --arch=x86_64
--target-os=mingw32 --enable-gpl --enable-version3 --disable-debug
--enable-shared --disable-static --disable-w32threads --enable-pthreads
--enable-iconv --enable-zlib --enable-libfribidi --enable-gmp --enable-
libxml2 --enable-lzma --enable-fontconfig --enable-libharfbuzz --enable-
libfreetype --enable-libvorbis --enable-opencl --disable-libpulse
--enable-libvmaf --disable-libxcb --disable-xlib --enable-amf --enable-
libaom --enable-libaribb24 --enable-avisynth --enable-chromaprint
--enable-libdav1d --enable-libdavs2 --enable-libdvdread --enable-libdvdnav
--disable-libfdk-aac --enable-ffnvcodec --enable-cuda-llvm --enable-frei0r
--enable-libgme --enable-libkvazaar --enable-libaribcaption --enable-
libass --enable-libbluray --enable-libjxl --enable-libmp3lame --enable-
libopus --enable-librist --enable-libssh --enable-libtheora --enable-
libvpx --enable-libwebp --enable-libzmq --enable-lv2 --enable-libvpl
--enable-openal --enable-liboapv --enable-libopencore-amrnb --enable-
libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-
libopenmpt --enable-librav1e --enable-librubberband --enable-schannel
--enable-sdl2 --enable-libsnappy --enable-libsoxr --enable-libsrt
--enable-libsvtav1 --enable-libtwolame --enable-libuavs3d --disable-libdrm
--enable-vaapi --enable-libvidstab --enable-vulkan --enable-libshaderc
--enable-libplacebo --enable-libvvenc --enable-libx264 --enable-libx265
--enable-libxavs2 --enable-libxvid --enable-libzimg --enable-libzvbi
--extra-cflags=-DLIBTWOLAME_STATIC --extra-cxxflags= --extra-libs=-lgomp
--extra-ldflags=-pthread --extra-ldexeflags= --cc=x86_64-w64-mingw32-gcc
--cxx=x86_64-w64-mingw32-g++ --ar=x86_64-w64-mingw32-gcc-ar
--ranlib=x86_64-w64-mingw32-gcc-ranlib --nm=x86_64-w64-mingw32-gcc-nm
--extra-version=20250515
libavutil 60. 2.100 / 60. 2.100
libavcodec 62. 3.101 / 62. 3.101
libavformat 62. 0.102 / 62. 0.102
libavdevice 62. 0.100 / 62. 0.100
libavfilter 11. 0.100 / 11. 0.100
libswscale 9. 0.100 / 9. 0.100
libswresample 6. 0.100 / 6. 0.100
Exiting with exit code 0
```
```
> systeminfo | findstr /B /C:"OS Name" /B /C:"OS Version"
OS Name: Microsoft Windows 11 Enterprise LTSC
OS Version: 10.0.22000 N/A Build 22000
```
1. **Command**:
```shell
ffmpeg \
-loglevel level+info \
-y \
-framerate 10 \
-threads 4 \
-fflags nobuffer \
-avioflags direct \
-probesize 32 \
-analyzeduration 0 \
-f gdigrab \
-i desktop \
-map 0:v \
-f rawvideo \
-pix_fmt rgb24 \\.\pipe\ffmpeg_video
```
2. **Actions During Capture**:
- Observe the cursor: flickering will be clearly visible against a dark
background.
- Attempt to select text or drag UI elements (e.g., in a text editor).
3. **Result**:
- Visible cursor flickering.
- Intermittent loss of focus during interactions (e.g., text selection
resets).
---
### **Root Cause**
The `gdigrab` device in FFmpeg’s `avdevice` library forcibly repositions
the cursor during frame capture[^1]. On multi-monitor/high-DPI systems,
this introduces a race condition:
- FFmpeg moves the cursor to capture its position/sprite.
- Windows UI thread fails to restore the cursor quickly enough, causing
flickering and focus instability.
---
### **Workaround (Verified)**
**Patch `avdevice-62.dll`**:
Modify the library to **skip cursor repositioning** during capture.
Tools like x64dbg or Ghidra can be used to:
- Locate the cursor position update logic in `gdigrab`’s capture loop.
- NOP (disable) instructions that call `SetCursorPos()` or equivalent
Win32 APIs.
---
### **Proposed Upstream Fix**
1. **FFmpeg Code Change**:
In `libavdevice/gdigrab.c`, modify the cursor handling logic to:
```c
// Replace physical cursor movement with position caching
static void capture_cursor(...) {
// GetCursorPos(&cursor_pos); // <-- Remove this
// SetCursorPos(cursor_pos.x, cursor_pos.y); // <-- Remove this
// Draw cursor sprite on frame using cached position
}
```
2. **Alternative**: Modify `-draw_mouse 0` flag to avoid mouse
interaction.
---
### **References**
[^1]: [FFmpeg gdigrab Cursor Flicker Discussion
(2020)](https://stackoverflow.com/questions/34023630)
[^2]: [Previous conversation](https://ffmpeg.org/pipermail/ffmpeg-
devel/2019-December/255101.html)
--
--
Ticket URL: <https://trac.ffmpeg.org/ticket/11599#comment:1>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker
_______________________________________________
FFmpeg-trac mailing list
[email protected]
https://ffmpeg.org/mailman/listinfo/ffmpeg-trac
To unsubscribe, visit link above, or email
[email protected] with subject "unsubscribe".