Hi everyone,
We are currently facing an issue with video playback stability on Windows 11, which could disrupt our eye-tracking experiment.
While playback is smooth on macOS and in standalone PsychoPy scripts, we see serious instability on Windows. This includes frequent frame drops, frozen final frames, movie.status never reaching FINISHED, and persistent warnings like Video catchup needed, Max reportNDroppedFrames reached, and Multiple dropped frames have occurred.
We use H.264 MP4 files (1920×1080, 30 fps, about 2.1 Mbps, variable bitrate) because our experiment requires frame-accurate timing.
The problem seems to be specific to the platform: the same videos work perfectly on macOS and when used in standalone PsychoPy scripts.
The display timing is not the bottleneck since window.flip() remains stable at about 59.93 Hz.
The duration of the movie is correctly given as 23.0 seconds—the metadata has been read properly.
get_frame(0.0) takes 350 to 550 ms, causing a major decoding delay at startup.
MovieStim3 reports catch-up warnings at:
- The onset (at about 0.55 s) is because the videoClock started before the first frame was ready.
- About halfway through playback (at around 1.3 seconds and 3.0 seconds), this happens during transitions from GOP to keyframe, which indicates decoding spikes.
- No errors were reported by OpenGL. The hardware is Intel UHD Graphics 770 with OpenGL 4.6.
The following script generates the same frame-drop warnings on Windows—even if OpenSesame, loops, or experimental logic is not used.
from psychopy import visual, core, event
from psychopy.visual import MovieStim3
win = visual.Window([1920, 1080], fullscr=True, monitor=“testMonitor”, units=“pix”)
movie = MovieStim3(win, ‘test_video.mp4’, size=(1920, 1080), flipVert=False)
movie.play()
while movie.status != movie.FINISHED:
movie.draw()
win.flip()
if event.getKeys(\['escape'\]):
break
win.close()
core.quit()
What we’ve tried
- Reducing the experiment to a single 5-second video → the problem still exists.
- Re-encoded video with:
-
- Short keyframes (-g 10 -keyint_min 10)
- Lower resolution (720p)
- After removing the audio, the decoding spikes were reduced but not eliminated.
- Causing thread deadlocks resulted from preloading frames or forcing GPU updates.
- Manually resetting videoClock.reset(-movie._nextFrameT) before each draw() call removes the catch-up warnings but bypasses the internal timing logic. The root cause seems to be a Windows-specific timing or synchronization issue. At the start, there is a clock desync because videoClock starts running before get_frame(0.0)finishes, causing about a 500ms delay and immediate catch-up loops. The catch-up logic is strict. When ffpyplayer hits decoding spikes, such as at GOP boundaries, MovieStim3 drops frames and moves forward, worsening the stuttering until playback stops.
This behavior does not happen on macOS, which suggests the problem is specific to Windows and may be related to thread scheduling, ffpyplayer, or OpenGL texture binding.
Does anyone have an idea on how to resolve this issue?
Is there a known problem involving the desynchronization of MovieStim3 and _videoClock on Windows 11?
Which of VLCMovieStim, MovieStim2, or another backend would be more stable when it comes to frame-accurate video playback on Windows?
Is there a set of recommended video encoding settings (for example, relating to GOP structure and bitrate) in order to prevent decoding spikes?
Please let me know if you have any suggestions. We want to resolve this without switching software, as the experimental logic is already complete.
Thanks in advance for any insight!