When you set exactly 1920×1080 on Windows via cv2.VideoCapture using the DirectShow (CAP_DSHOW) backend, OpenCV negotiates the capture format differently than Linux’s V4L2 backend does.
If the driver’s DirectShow filter graph doesn’t expose that exact combination (MJPG @ 60 FPS @ 1920×1080) as a supported media type, it silently falls back to uncompressed RGB24 or YUY2 — which are huge and slow to transfer (e.g., ~373 MB/s for 1080p60 RGB), so you end up with ~1 FPS.
When you instead request a slightly off resolution like 1900×1080, Windows can’t match it exactly. The backend then asks the driver for the nearest valid format, and the driver internally selects MJPG @ 1920×1080, which is compressed — and therefore fast.
So, the difference is purely about which pixel format ends up being negotiated.