I've been using mss
for screen capturing for a while, and no matter what I can't get it above 60 fps, even with multiprocessing
. Here's the code:
import multiprocessing as mp
import time
import mss
def task():
start = time.time()
for x in range(600):
with mss.mss() as sct:
sct.grab({'mon': 1, 'top': 690, 'left': 750, 'width': 450, 'height': 50})
print(time.time() - start)
if __name__ == '__main__':
for x in range(3):
p = mp.Process(target=task)
p.start()
Changing the int
in the range()
function does not make a difference to overall capturing speed. Here are the results:
1 process, 60 fps per process, 60 fps combined, ~10 seconds per process
2 processes, 30 fps per process, 60 fps combined, ~20 seconds per process
3 processes, 20 fps per process, 60 fps combined, ~30 seconds per process
Anyone know what could be causing this?
It should be noted that changing the bounding box ({'mon': 1, 'top': 690, 'left': 750, 'width': 450, 'height': 50}
) resolution does not affect the framerate. Capturing my whole screen, down to a single pixel, it's all at 60 fps.
Extra Info
Python 3.10.4
Windows 10 Laptop, ASUS TUF Gaming FXGT505-FXGT505
Intel I7 9750H, GTX 1650, 16gb ram, 144hz screen w/ 60hz monitor as primary
In the cases where I actively do image processing with mss screen capture, the processing does not affect the framerate, even with multiprocessing
.
Arty pointed out the following:
It means that lock is acquired inside sct.grab(), not with statement. I have looked into code of that library 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
As a result, I disconnected my monitor entirely, and this did speed up the capture rate to 144 hz. Disconnecting my monitor is a good temporary solution for me, but some people only have a 60hz monitor and nothing else. I am going to look for a more permanent one by sleuthing through the Win Api, once I figure out how to do so. Any help would be appreciated.
It should be noted that changing the monitor that is being captured to the 144hz monitor still limits the capture rate to 60fps.