Yesterday I decided to tackle an issue I've been having for a while.
Context
I've been using the python library mss
for high-speed screen capturing for a few months. Specifically, I've been using sct.grab()
, and I've never gotten it above 60 fps, even with the multiprocessing
library. I've got a 144hz laptop screen and a 60hz monitor, and yesterday, with the help of a user going by Arty, I discovered that unplugging my HDMI from my laptop allowed the refresh rate to get to 144hz. While this is a great temporary solution, this program will end up being run on a machine that only has a 60hz monitor, since I am making it for some stuff at work.
The Problem
Arty, a stack overflow user who saw my previous post regarding the issue mentioned in the context section of this post, stated the following:
It means that lock is acquired inside
sct.grab()
, notwith
statement. I have looked into code of that library [here he is referring tolib\site-packages\mss\windows.py
] and it shows thatsct.grab()
uses Windows API functions likeCreateCompatibleBitmap()
andSelectObject()
andDeleteObject()
andBitBlt()
andGetDIBits()
. I'm sure one of Windows API functions among these ones inserts some pause like 1/60 of second. Also these functions may just wait till next monitor synchronization time point, once in 1/60 seconds. So this pause is naturally inserted by Win API.
This would unfortunately imply that it might not be possible to avoid the refresh rate cap, though I have not seen other people using mss
having this problem on other stack overflow threads. Sleuthing through code isn't my forte, I mainly use python for data science processing and haven't dug too deep into code before, nor do I have a lot of technical experience with python or windows, though I have tried to look for where this could be limited by looking through lib\ctypes
. Maybe I missed it, but does anyone know how to remove this refresh rate limit?
It is worth noting, I believe, that I have tried making multiple instances of mss.mss()
as a workaround, hoping that the refresh rate limit was only per instance, but this was not the case.
Edit 1 IInspectable has said that:
If indeed
BitBlt
is synchronized to the refresh rate (and that sounds plausible), then there's nothing you can do.
If this is the case, how can other people running Windows 10 machines, just as I am, bypass this limit? I've seen people talk about running mss in excess of 600 frames per second. Is there something within the BitBlt
function I need to change to bypass the fps limit?