0

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(), not with statement. I have looked into code of that library [here he is referring to lib\site-packages\mss\windows.py] and it shows that sct.grab() uses Windows API functions like CreateCompatibleBitmap() and SelectObject() and DeleteObject() and BitBlt() and GetDIBits(). 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?

BappoHotel
  • 52
  • 10
  • If indeed `BitBlt` is synchronized to the refresh rate (and that sounds plausible), then there's nothing you can do. Out of curiosity, have you tried running this on Windows 11? Prior to Windows 11 the system would not correctly report the refresh rate for external displays and rather default to 60Hz (which seems to agree with your descriptions). – IInspectable Oct 15 '22 at 06:20
  • @IInspectable I have not, I don't have access to a Windows 11 machine and I will not be upgrading my computer just to try this out. I've seen other people say they're running mss in excess of 600 fps, I doubt that their monitor has that refresh rate. Is there any reason other people wouldn't have the same limitations as me? – BappoHotel Oct 15 '22 at 07:44

0 Answers0