Opened 14 months ago

Last modified 14 months ago

#11599 new defect

`gdigrab` Screen Capture Causes Cursor Flickering and Focus Loss on Windows (Multi-Monitor)

Reported by: Evgene Owned by:
Priority: critical Component: ffmpeg
Version: git-master Keywords:
Cc: Blocked By:
Blocking: Reproduced by developer: yes
Analyzed by developer: yes

Description (last modified by Evgene)

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

  1. 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

`

  1. 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).
  1. 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

}
`

  1. 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)

Change History (1)

comment:1 by Evgene, 14 months ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.