This file is indexed.

/usr/share/psychtoolbox-3/PsychTests/LosslessMovieWritingTest.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
function LosslessMovieWritingTest(codec, nrchannels, bpc)
% LosslessMovieWritingTest - Test lossless encoding and decoding of video in movie files.
%
% LosslessMovieWritingTest([codec=huffyuv][, nrchannels=3][, bpc=8])
%
% This test is meant to exercise Screen's movie writing function with
% different GStreamer video codecs and to test if specific codecs are
% capable of encoding video without loss of information into a movie file.
%
% The test creates a test image, encodes/writes it into a movie file, then
% reads it back from the movie file and then compares the original test
% image against the image read back from the movie. If lossless encoding
% worked, both images should be identical.
%
% Optional parameters:
%
% 'codec' name of video codec to use. Defaults to huffyuv, for use of the
% lossless FFMpeg Huffman encoder. ffenc_ljpeg would be another option for
% a lossless codec, however ffenc_ljpeg can't be decoded by Psychtoolbox's
% GStreamer movie playback functions. Another lossless codec is
% 'ffenc_sgi', which allows for lossless encoding and relatively high
% compression rates, but its movie files can only be read by Psychtoolbox,
% not by other tools.
%
% 'nrchannels' How many color channels to test: 1, 3, or 4 are possible
% values for grayscale, RGB or RGBA encoding with 8 bpc. For 16 bpc
% encoding, only 1 or 3 channels are possible. Note that most codecs can't
% really encode the alpha channel and discard it instead, so nrchannels=4
% does not actually verify integrity of the alpha channel.
%
% 'bpc' Bitdepth for color encoding: 8 is the default, which should work.
% 16 is the other allowed option for 16 bpc testing. Most codecs can't
% encode 16 bpc though and will reduce precision to <= 8 bpc. Check the
% code of this script to see how a Psychtoolbox proprietary 16 bpc encoding
% can be used to handle lossless 16 bpc, and how this can be decoded. Only
% Psychtoolbox can handle movies in this proprietary encoding, no other 3rd
% party tools! Other constraints for 16 bpc mode: 1 layer grayscale images
% must have a height for which height * 2/3 is an integral value. 3 layer
% RGB images must not be wider than 2048 pixels for use with most codecs.
%
% This test script will write the - potentially huge - temporary test file
% into the current working directory and leave it there after the test!
%
% Requires a GPU which can handle at least 4096 x 4096 pixel textures,
% otherwise test failure will occur. The GPU must also support floating
% point textures for > 8 bpc tests.
%

% History:
% 01-Dec-2013  mk  Written.

global imgref;
global imgrefcheck;
global imgdec;

% Default to ffenc_huffyuv codec, aka lossless Huffmann YUV encoder:
if nargin < 1 || isempty(codec)
    codec = 'huffyuv';
end

% Define codec type:
codec = [':CodecType=' codec];

% Default to RGB 3-channel testing:
if nargin < 2 || isempty(nrchannels)
    nrchannels = 3;
end
if ~ismember(nrchannels, [1, 3, 4])
    error('Sorry, can only test 1, 3, or 4 channels.');
end

% Default to 8 bpc resolution:
if nargin < 3 || isempty(bpc)
    bpc = 8;
end

if ~ismember(bpc, [8, 16])
    error('Sorry, can only test 8 or 16 bpc.');
end

% A restriction of Psychtoolbox proprietary 16 bpc encoding:
if (bpc > 8) && ~ismember(nrchannels, [1, 3])
    error('Sorry, can only test 1 or 3 channels for bpc > 8.');
end

% Startup check and unified keynames, but old 0-255 color encoding:
PsychDefaultSetup(1);

% Fullscreen onscreen window with black background on screen 0:
win = Screen('Openwindow', 0, 0);

% Step 1: Create reference data:
if bpc == 8
    % 8 bpc: Build a huge msize x msize pixels, 3-layer RGB8 uint8 image
    % matrix which contains all possible RGB color pixel values for a RGB8
    % encoding once:
    
    % Use a msize by msize test image with 2^12 * 2^12 pixels to cover the
    % whole possible range of 2^24 different color value in a RGB8 image:
    msize = 2^12;
    nsize = msize;
    
    x = typecast(uint32(0:(msize * msize - 1)), 'uint8');
    y = reshape(x, 4, msize, msize);
    z = shiftdim(y, 1);
    
    % Now that we have a classic 4-layer color image, fill its alpha
    % channel with 255 instead of 0:
    z(:,:,4) = 255;
    
    % Extract wanted number of channels for test image:
    imgref = z(:,:,1:nrchannels);
    
    % Turn into a L8 / RGB8 / RGBA8 texture:
    tex = Screen('MakeTexture', win, imgref);
    
    % Readback to verify precision of GPU:
    imgrefcheck = Screen('GetImage', tex, [], [], [], nrchannels);
    
    highbitflag = 0;
else
    % 16 bpc: We can not cover the whole color value set. Best we can do is
    % randomly sample, which we'll do:
    
    % Use a msize by msize test image with 2^11 * 1200 pixels. 2^11 is the
    % maximum width most lossless codecs can handle if we use PTB's
    % proprietary 16 bpc encoding, which allows for at most a width half
    % the width of what the codec can do at best:
    msize = 2^11;
    nsize = 1200;
    
    % Draw msize x msize x 3 samples between 0 and 65535, normalize to
    % 0.0 - 1.0 range for floating point image textures. Note: We use
    % rand() instead of randi(), because randi() wasn't available in Octave 3.2,
    % and we want to continue support for it for now.
    imgref = single(floor(rand([nsize, msize, nrchannels]) * (2^16 - 1)) / (2^16 - 1));
    
    % Turn into a Luminance 32 bpc float or RGB 32 float texture:
    tex = Screen('MakeTexture', win, double(imgref), [], [], 2);
    
    % Readback in float precision to verify precision of GPU:
    imgrefcheck = single(Screen('GetImage', tex, [], [], 1, nrchannels));
    
    % Add keyword to request Psychtoolbox's own proprietary 16 bpc encoding:
    codec = [codec ' UsePTB16BPC'];
    
    % Set 'OpenMovie' specialflags1 setting 512 for 16 bpc PTB movie decode:
    highbitflag = 512;
end

if isequal(imgref, imgrefcheck)
    % No need to report the expected, so commented out:
    %fprintf('Ref image and reftexture are identical. Good.\n');
else
    warning('Ref image and reftexture are DIFFERENT!!! GPU or graphics driver malfunction?!?\n'); %#ok<WNTAG>
end

Screen('TextSize', win, 48);
Screen('DrawTexture', win, tex);
DrawFormattedText(win, 'REFERENCE IMAGE!\nEncoding...', 'center', 'center', 255);
Screen('Flip', win);

moviefile = [pwd filesep 'Testmovie.avi'];

% Step 2: Create a movie file:
movie = Screen('CreateMovie', win, moviefile, msize, nsize, 1, codec, nrchannels, bpc);

% Add 3 frames with our test image texture:
for i=1:3
    Screen('AddFrameToMovie', tex);
end

% Finish and close movie:
Screen('FinalizeMovie', movie);

% Step 3: Read movie. Use specialFlags1 = 256 to prevent deinterlacing, as
% that can incur some color-space conversions on 1 channel gray-scale data,
% which would be lossy and thereby defeat the purpose of this test. Optionally
% add a highbitflag of 512 for decoding 16 bpc HDR movies encoded in PTB's
% proprietary movie encoding format:
[movie durationSecs] = Screen('OpenMovie', win, moviefile, [], [], 256 + highbitflag, nrchannels);

% A very huge durationSecs indicates movie duration couldn't get queried.
% This in turn means some non-standard movie container which is not
% seekable. Try to handle this:
if durationSecs < realmax
    % This seek is crucially needed if no active playback but passive frame
    % fetching is used:
    Screen('SetMovieTimeIndex', movie, 0);
else
    % This is not a real seekable movie, but some special container like
    % multipart-mux'ed. Must use active playback to get this working at
    % all:
    Screen('PlayMovie', movie, 1, 0, 0);
end

% Fetch first frame from movie:
movietex = Screen('GetMovieImage', win, movie);
Screen('DrawTexture', win, movietex);
DrawFormattedText(win, 'DECODED MOVIE IMAGE!\nComparing...', 'center', 'center', 255);
Screen('Flip', win);

if bpc <= 8
    % Retrieve decoded image data:
    imgdec = Screen('GetImage', movietex, [], [], 0, nrchannels);
else
    % Retrieve decoded image data:
    imgdec = single(Screen('GetImage', movietex, [], [], 1, nrchannels));
end

% If encoding and decoding was lossless then imgref and imgdec should be
% identical, ie. imgdiff should be all-zero:
if bpc <= 8
    imgdec = int32(imgdec(:));
    imgref = int32(imgref(:));
    imgdiff = imgdec - imgref;
else
    imgdec = imgdec(:);
    imgref = imgref(:);
    imgdiff = imgdec - imgref;
    
    % Convert into 16 bpc encoding:
    imgdiff = int32(round(imgdiff * (2^16 - 1)));
end

% All zero imgdiff, ie., identical?
if ~any(imgdiff)
    fprintf('\n\nOriginal image and encoded->movie->decoded image are identical! Yay!\n\n');
    DrawFormattedText(win, 'IDENTICAL - SUCCESS!', 'center', 'center', [0 255 0]);
else
    fprintf('\n\nOriginal image and encoded->movie->decoded image are DIFFERENT!\n\n');
    DrawFormattedText(win, 'DIFFERENT - FAILURE!', 'center', 'center', [255 0 0]);
    
    mindelta = min(imgdiff) %#ok<NOPRT,NASGU>
    maxdelta = max(imgdiff) %#ok<NOPRT,NASGU>
    rangedelta = range(imgdiff) %#ok<NOPRT,NASGU>
    close all;
    hist(double(imgdiff));
    title('Error distribution in pixel values:');
end

Screen('Flip', win);
KbStrokeWait([], GetSecs + 5);

% Close movie:
Screen('CloseMovie', movie);

% Close display:
sca;