This file is indexed.

/usr/share/psychtoolbox-3/PsychDemos/MovieDemos/DetectionRTInVideoDemo.m is in psychtoolbox-3-common 3.0.11.20131230.dfsg1-1build1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
function DetectionRTInVideoDemo(moviename, timeOfEvent, trials)
%
% DetectionRTInVideoDemo(moviename, timeOfEvent, trials)
%
% A demo implementation of how to collect reaction time for detection of a
% specific time-locked event in a movie file.
%
% Parameters:
% moviename - Filename of moviefile to use. If none is provided, then the
% simple DualDiscs collision movie is used which is part of PTB.
%
% timeOfEvent - Time (in seconds) when the timelocked event happens which
% should be detected by the subject. Default is time of contact of the
% DualDiscs collision.
%
% trials - Number of trials to run. Defaults to 10 or ESC key press.
%
% How the demo works: Read the source code - its well documented ;-)
% This demo demonstrates the optimal way if you have movies with sound
% (that needs to be played in sync with the video) or long movies that
% don't fit into memory or that you don't want to load into memory.
%
% It uses automatic synchronized audio-video playback. The central
% while-loop checks for arrival of new frames for display and displays them
% when their time has come. It also registers subjects keypress responses
% and does all the bookkeeping and sanity checking.
%
% An alternative approach would be to preload the whole 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 MovieDemo. The
% advantage of that 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 would be: 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.
%

% History:
% 12/19/05  mk  Wrote it.
% 02/03/06  mk  Adapted for use on Windows.
% 03/11/12  mk  Cleanup.
% 06/17/13  mk  Cleanup.

if nargin < 1
    % Default movie is our own disc collision movie:
    moviename = [ PsychtoolboxRoot 'PsychDemos/MovieDemos/DualDiscs.mov' ];
end;

if nargin < 2
    timeOfEvent = 1.16;
end;

if nargin < 3
    trials = 10;
end;

fprintf('Loading probe movie %s ...\n', moviename);
fprintf('Time locked probe event will happen at time %f secs after start of movie.\n', timeOfEvent);
fprintf('Will run %i trials or until ESCape key is pressed.\n', trials);

% 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');

% Query keycodes for ESCAPE key and Space key:
esc=KbName('ESCAPE');
space=KbName('space');

try
    % Child protection: Make sure we run on the OSX / OpenGL Psychtoolbox.
    % Abort if we don't:
    AssertOpenGL;
    
    % 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 background color 'background':
    win = Screen('OpenWindow', screen, background);
    
    % Hide the mouse cursor:
    HideCursor;
    
    % Show instructions...
    tsize=30;
    Screen('TextSize', win, tsize);
    [x, y]=Screen('DrawText', win, 'Collision detection fake experiment.',40, 100); %#ok<*ASGLU>
    [x, y]=Screen('DrawText', win, 'Press ESC-ape key to abort anytime.', 40, y + 10 + tsize);
    [x, y]=Screen('DrawText', win, 'Press SPACE key when you see the discs colliding', 40, y + 10 + tsize);
    Screen('DrawText', win, 'Press any key to start the experiment...', 40, y + 10 + tsize);
    
    % Flip to show the grey screen:
    Screen('Flip',win);
    
    % Wait for keypress + release...
    KbStrokeWait;
    
    % Show cleared screen...
    Screen('Flip',win);
    
    % Wait a second...
    WaitSecs(1);
    
    % Main trial loop: Do 'trials' trials...
    for i=1:trials
        % Open the moviefile and query some infos like duration, framerate,
        % width and height of video frames. We could also query the total count of frames in
        % the movie, but computing 'framecount' takes long, so avoid to query
        % this property if you don't need it!
        [movie movieduration fps] = Screen('OpenMovie', win, moviename);
        
        % We estimate framecount instead of querying it - faster:
        framecount = movieduration * fps;
        
        % Start playback of the movie:
        % Play 'movie', at a playbackrate = 1 (normal speed forward),
        % play it once, aka with loopflag = 0,
        % play audio track at volume 1.0  = 100% audio volume.
        Screen('PlayMovie', movie, 1, 0, 1.0);
        
        % Video playback and key response RT collection loop:
        % This loop repeats until either the subject responded with a
        % keypress to indicate s(he) detected the event in the vido, or
        % until the end of the movie is reached.
        movietexture=0;     % Texture handle for the current movie frame.
        reactiontime=-1;    % Variable to store reaction time.
        lastpts=0;          % Presentation timestamp of last frame.
        onsettime=-1;       % Realtime at which the event was shown to the subject.
        rejecttrial=0;      % Flag which is set to 1 to reject an invalid trial.
        
        while(movietexture>=0 && reactiontime==-1)
            % Check if a new movie video frame is ready for visual
            % presentation: This call polls for arrival of a new frame. 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.
            % Arrival of textures is automatically synchronized to the
            % audio track and to real-world time. If the video display loop
            % can't keep up with the flow of time and the soundtrack,
            % the engine will automatically skip/drop frames to keep video
            % in sync with audio as good as possible. If the pts of a new
            % texture is greater than the 'timeOfEvent' then you'll know
            % that this texture will show the visual target event as soon
            % as you draw and 'Flip' it.
            % In case that no new video texture is available yet for
            % presentation, 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 playback.
            
            % The 0 - flag means: Don't wait for arrival of new frame, just
            % return a zero or -1 'movietexture' if none is ready.
            [movietexture pts] = Screen('GetMovieImage', win, movie, 0);
            
            % Is it a valid texture?
            if (movietexture>0)
                % Yes. Draw the texture into backbuffer:
                Screen('DrawTexture', win, movietexture);
                
                % Flip the display to show the image at next retrace:
                % vbl will contain the exact system time of image onset on
                % screen: This should be accurate in the sub-millisecond
                % range.
                vbl=Screen('Flip', win);
                % Is this the event video frame we've been waiting for?
                if (onsettime==-1 && pts >= timeOfEvent)
                    % Yes: This is the first frame with a pts timestamp that is
                    % equal or greater than the timeOfEvent, so 'vbl' is
                    % the exact time when the event was presented to the
                    % subject. Define it as onsettime:
                    onsettime = vbl;
                    
                    % Compare current pts to last one to see if the movie
                    % decoder skipped a frame at this crucial point in
                    % time. That would invalidate this trial.
                    if (pts - lastpts > 1.5*(1/fps))
                        % Difference to last frame is more than 1.5 times
                        % the expected difference under assumption 'no
                        % skip'. We skipped in the wrong moment!
                        rejecttrial=1;
                    end;
                end;
                
                % Keep track of the frames pts in order to check for skipped frames:
                lastpts=pts;
                
                % Delete the texture. We don't need it anymore:
                Screen('Close', movietexture);
                movietexture=0;
            end;
            
            % Done with drawing. Check the keyboard for subjects response:
            [keyIsDown, secs, keyCode]=KbCheck;
            if (keyIsDown==1)
                % Abort requested?
                if keyCode(esc)
                    % This signals abortion:
                    rejecttrial=-1;
                    % Break out of display loop:
                    break;
                end;
                
                % Space key pressed to indicate detection of event?
                if keyCode(space)
                    % Response too early (before event happened?)
                    if (onsettime==-1)
                        % Reject this trial:
                        rejecttrial=2;
                    else
                        % Valid response: Difference between 'secs' and
                        % 'onsettime' is the reaction time:
                        reactiontime=secs - onsettime;
                    end;
                end;
                
            end;
        end; % ...of display loop...
        
        % Stop movie playback, in case it isn't already stopped. We do this
        % by selection of a playback rate of zero: This will also return
        % the number of frames that had to be dropped to keep audio, video
        % and realtime in sync.
        droppedcount = Screen('PlayMovie', movie, 0, 0, 0);
        if (droppedcount > 0.2*framecount)
            % Over 20% of all frames skipped?!? Playback problems! We
            % reject this trial...
            rejecttrial=4;
        end;
        
        % Close the moviefile.
        Screen('CloseMovie', movie);
        
        % Check if aborted.
        if (rejecttrial==-1)
            % Break out of trial loop
            break;
        end;
        
        if (reactiontime==-1 && rejecttrial==0)
            rejecttrial=3;
        end;
        
        % Print out trials result if it was a valid trial:
        if (rejecttrial==0)
            fprintf('Trial %i valid: Reaction time was %f msecs.\n', i, 1000 * reactiontime);
        end;
        
        if (rejecttrial==1)
            fprintf('Trial %i rejected due to skip in video playback at time of event.\n', i);
        end;
        
        if (rejecttrial==2)
            fprintf('Trial %i rejected. False detection by subject.\n', i);
        end;
        
        if (rejecttrial==3)
            fprintf('Trial %i rejected. No detection by subject. Asleep?!?\n', i);
        end;
        
        if (rejecttrial==4)
            fprintf('Trial %i rejected. Way too many skips in movie playback!!!\n', i);
        end;
        
        % Wait for subject to release keys:
        KbReleaseWait;
        
    end; % Trial done. Next trial...
    
    % Done with the experiment. Close onscreen window and finish.
    ShowCursor;
    Screen('CloseAll');
    fprintf('Done. Bye!\n');
    return;
catch %#ok<CTCH>
    % Error handling: Close all windows and movies, release all ressources.
    sca;
    psychrethrow(psychlasterror);
end;