File: LoadMovieIntoTexturesDemoOSX.m

package info (click to toggle)
psychtoolbox-3 3.0.9%2Bsvn2579.dfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 63,408 kB
  • sloc: ansic: 73,310; cpp: 11,139; objc: 3,129; sh: 1,669; python: 382; php: 272; makefile: 172; java: 113
file content (298 lines) | stat: -rw-r--r-- 10,371 bytes parent folder | download
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;