By default, if you are using Screen('GetMovieImage')
then this will “block” waiting for the next frame, and your timing will be dictated by the frame rate of the movie. You could make your Flip
times a multiple of the movie frame rate. But another solution requires not using blocking mode and using a second buffer texture. If Screen('GetMovieImage')
returns a new frame, show that, if not, show the previous frame.
My movieStimulus class uses this technique (this is an OOP class and so me
refers to itself):
me.blocking = false;
me.texture = Screen('GetMovieImage', me.sM.win, me.movie, me.blocking);
if me.texture > 0
if ~isempty(me.buffertex) && ...
me.buffertex > 0 && ...
me.buffertex ~= me.texture && Screen(me.buffertex,'WindowKind') == -1
try Screen('Close', me.buffertex); end
me.buffertex=[];
end
Screen('DrawTexture', me.sM.win, me.texture, [], me.mvRect,...
angle,[],[],[],me.shader);
me.buffertex = me.texture; %copy new texture to buffer
elseif me.buffertex > 0
Screen('DrawTexture', me.sM.win, me.buffertex, [], me.mvRect,...
angle,[],[],[],me.shader)
end
Roughly it checks if texture
is > 0 (a new frame): if so check if a previous buffertex
is present and close it, then draw the new texture
and assign it to buffertex
| otherwise just draw buffertex
. Now the timing is only dictated by Screen('Flip')
, and so your other animations will work fine.You can see this in action easily with my toolbox:
m = metaStimulus;
m{1} = dotsStimulus('xPosition', 4, 'mask', true);
m{2} = movieStimulus('blocking', 0);
m.run; %test run of the stimuli
This creates a movie and an RDS stimulus, then runs them together at the FPS of the monitor display; the movie does not hold up the timing of the RDS…