1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298
|
function LoadMovieIntoTexturesDemoOSX(moviename, fromTime, toTime, indexisFrames, benchmark)
%
% LoadMovieIntoTexturesDemoOSX(moviename [, fromTime=0][, toTime=end][, indexisFrames=0][, benchmark=0])
%
% A demo implementation on how to load a movie into standard
% Psychtoolbox textures for precisely controlled presentation timing and
% presentation order.
%
% Parameters:
% moviename - Filename of moviefile to use. If none is provided, then the
% simple DualDiscs collision movie is used which is part of PTB.
%
% fromTime - Start time (in seconds) from which the movie should be read
% into textures. Defaults to start of movie, if not provided.
%
% toTime - End time (in seconds) upto which the movie should be read
% into textures. Defaults to end of movie, if not provided.
%
% indexIsFrames - If set to 1 then the fromTime and toTime parameters are
% interpreted as frameindex (starting with 0 for the first frame), instead
% of seconds.
%
% benchmark - If you set this parameter to 1, the demo will compute the
% time it takes to load the movie and the maximum display speed without
% syncing to vertical refresh. All visual progress feedback is disabled.
% This is mostly useful to benchmark different movie file formats and
% codecs for their relative efficiency on a given machine.
%
% How the demo works: Read the source code - its well documented ;-)
%
% This demo "preloads" the movie into textures:
% The whole movie gets read into PTB textures before start of trial. Then
% you show the textures in quick succession like in MovieDemoOSX. The
% advantage of this approach is exact control over display timing and
% display order: You can show frames in any order you like at any rate you
% like (and that your hardware likes). Disadvantage: Longer trial
% setup time for loading the whole movie, higher memory consumption (keep
% all n frames in memory instead of only the current one) and the inability
% to play sound in sync with video.
%
% To make it a bit more interesting, you can use this demo to "browse" short
% videoclips, e.g., for selection of interesting parts...
%
% History:
% 12/25/05 mk Wrote it.
% 02/03/06 mk Adapted for use on Windows.
% 09/03/09 mk Add support for frameindex seeking instead of timeindex.
% Child protection: Make sure we run on the OSX / OpenGL Psychtoolbox.
% Abort if we don't:
AssertOpenGL;
% Switch KbName into unified mode: It will use the names of the OS-X
% platform on all platforms in order to make this script portable:
KbName('UnifyKeyNames');
esc=KbName('ESCAPE');
space=KbName('SPACE');
right=KbName('RightArrow');
left=KbName('LeftArrow');
if nargin < 1
moviename = [];
end
if isempty(moviename)
% Default movie is our own disc collision movie:
moviename = [ PsychtoolboxRoot 'PsychDemos/QuicktimeDemos/DualDiscs.mov' ];
end;
if nargin < 2
% Default to beginning of movie:
fromTime=0;
end;
if isempty(fromTime)
fromTime=0;
end
if nargin < 3
% Default to end of movie:
toTime=100000;
end;
if isempty(toTime)
% Default to end of movie:
toTime=100000;
end;
if nargin < 4
indexisFrames = [];
end
if isempty(indexisFrames)
indexisFrames = 0;
end
if nargin < 5
benchmark = [];
end;
if isempty(benchmark)
benchmark = 0;
end;
fprintf('Loading movie %s ...\n', moviename);
try
% Background color will be a grey one:
background=[128, 128, 128];
% Open onscreen window. We use the display with the highest number on
% multi-display setups:
screen=max(Screen('Screens'));
% This will open a screen with default settings, aka black background,
% fullscreen, double buffered with 32 bits color depth:
win = Screen('OpenWindow', screen); % , 0, [0 0 800 600]);
% Hide the mouse cursor:
HideCursor;
% Clear screen to background color:
Screen('FillRect', win, background);
% Show instructions...
tsize=20;
Screen('TextSize', win, tsize);
Screen('DrawText', win, 'Loading movie into textures. Please wait...',40, 100);
% Flip to show the startup screen:
Screen('Flip',win);
% Open the moviefile and query some infos like duration, framerate,
% width and height of video frames...
[movie movieduration fps imgw imgh] = Screen('OpenMovie', win, moviename);
% Move to requested timeindex where texture loading should start:
Screen('SetMovieTimeIndex', movie, fromTime, indexisFrames);
movietexture=0; % Texture handle for the current movie frame.
lastpts=-1; % Presentation timestamp of last frame.
pts=-1;
count=0; % Number of loaded movie frames.
tloadstart=GetSecs;
% Movie to texture conversion loop:
while (movietexture>=0) & ((~indexisFrames & (pts < toTime)) | (indexisFrames & (fromTime + count <= toTime))) %#ok<OR2,AND2>
% This call waits for arrival of a new frame from the movie. If
% a new frame is ready, it converts the video frame into a
% Psychtoolbox texture image and returns a handle in
% 'movietexture'. 'pts' contains a so called presentation
% timestamp. That is the time (in seconds since start of movie)
% at which this video frame should be shown on the screen.
% In case that no valid video texture is available, this function
% will return a zero texture handle to indicate this. If no new
% texture will become available anymore, because the end of the
% movie is reached, it will return a handle of -1 to indicate end
% of movie.
% The 1 - flag means: Wait for arrival of new frame. Next
% invocation of this command will retrieve the next frame in
% the movie.
[movietexture pts] = Screen('GetMovieImage', win, movie, 1);
% Valid and *new* texture? If pts would be *smaller* than
% lastpts then we would have ran over the end of movie - in
% that case, the time will automatically wrap around to zero.
% If we don't check for this, we'll have an infinite loop!
if (movietexture>0 & pts>lastpts) %#ok<AND2>
% Store its texture handle and exact movie timestamp in
% arrays for later use:
count=count + 1;
texids(count)=movietexture;
texpts(count)=pts;
lastpts=pts;
else
break;
end;
% Allow for abortion...
if KbCheck
break;
end;
if (benchmark==0)
% Show the progress text:
Screen('DrawText', win, ['Loaded texture ' num2str(count) '...'],40, 100);
Screen('Flip',win);
end;
end;
if (benchmark>0)
% Compute movie load & conversion rate in frames per second.
loadrate = count / (GetSecs - tloadstart);
% Compute same rate in Megapixels per second:
loadvolume = loadrate * imgw * imgh / 1024 / 1024;
fprintf('Movie to texture conversion speed is %f frames per second == %f Megapixels/second.\n', loadrate, loadvolume);
end;
% Ok, now the requested part of the movie has been (hopefully) loaded
% and converted into standard PTB textures. We can simply use the
% 'DrawTexture' command in a loop to show the textures...
% Clear screen to background color:
Screen('Flip',win);
currentindex=1;
autoplay=0;
totalcount = 0;
tstart=GetSecs;
% Browse and Draw loop:
while(count>0)
% Draw texture 'currentindex'
Screen('DrawTexture', win, texids(currentindex));
if (benchmark==0)
% Draw some help text:
[x, y]=Screen('DrawText', win, 'Press left-/right cursor key to navigate in movie, SPACE to toggle playback, ESC to exit.',10, 40);
[x, y]=Screen('DrawText', win, ['Framerate(fps): ' num2str(fps) ', total duration of movie (secs) ' num2str(movieduration)],10, y+10+tsize);
% Draw info on current position in movie:
Screen('DrawText', win, ['Frame ' num2str(currentindex) ' of ' num2str(count) ' : Timeindex(secs) = ' num2str(texpts(currentindex))], 10, y + 10 + tsize);
% Show drawn stuff:
Screen('Flip', win);
% Check for key press:
[keyIsDown, secs, keyCode]=KbCheck;
if keyIsDown
if (keyCode(esc))
% Exit
break;
end;
if (keyCode(space))
% Toggle playback on space.
autoplay=1-autoplay;
end;
if (keyCode(right) && currentindex<count)
% One frame forward:
currentindex=currentindex+1;
end;
if (keyCode(left) && currentindex>1)
% One frame backward:
currentindex=currentindex-1;
end;
% Wait for key-release:
KbReleaseWait;
end;
else
% Benchmark mode: Repeat until Keypress.
Screen('Flip', win, 0, 2, 2);
totalcount=totalcount + 1;
autoplay=1;
if KbCheck
break;
end;
end;
% Update frameindex if in autoplay mode:
if autoplay==1
currentindex=mod(currentindex, count) + 1;
end;
end;
% Done. Flip a last time to show grey background:
Screen('Flip', win);
if (benchmark>0)
playbackrate = totalcount / (GetSecs - tstart);
playbackvolume = playbackrate * imgw * imgh / 1024 / 1024;
fprintf('Movietexture playback rate is %f frames per second == %f Megapixels/second.\n', playbackrate, playbackvolume);
end;
% This will release all textures...
Screen('Close', texids);
% Close movie file.
Screen('CloseMovie', movie);
ShowCursor;
Screen('CloseAll');
fprintf('Done. Bye!\n');
return;
catch
% Error handling: Close all windows and movies, release all ressources.
ShowCursor;
Screen('CloseAll');
psychrethrow(psychlasterror);
end;
|