1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgfunction plotBenchmark(fileNames, export)
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org%PLOTBENCHMARK Plots and exports video codec benchmarking results.
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org%   PLOTBENCHMARK(FILENAMES, EXPORT) parses the video codec benchmarking result
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org%   files given by the cell array of strings FILENAME. It plots the results and
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org%   optionally exports each plot to an appropriately named file.
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org%
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org%   EXPORT parameter:
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org%       'none'  No file exports.
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org%       'eps'   Exports to eps files (default).
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org%       'pdf'   Exports to eps files and uses the command-line utility
11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org%               epstopdf to obtain pdf files.
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org%
13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org%   Example:
14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org%       plotBenchmark({'H264Benchmark.txt' 'LSVXBenchmark.txt'}, 'pdf')
15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgif (nargin < 1)
17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    error('Too few input arguments');
18b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgelseif (nargin < 2)
19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    export = 'eps';
20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgend
21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgif ~iscell(fileNames)
23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if ischar(fileNames)
24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        % one single file name as a string is ok
25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if size(fileNames,1) > 1
26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            % this is a char matrix, not ok
27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            error('First argument must not be a char matrix');
28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        end
29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        % wrap in a cell array
30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        fileNames = {fileNames};
31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    else
32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        error('First argument must be a cell array of strings');
33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    end
34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgend
35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgif ~ischar(export)
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    error('Second argument must be a string');
38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgend
39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgoutpath = 'BenchmarkPlots';
41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org[status, errMsg] = mkdir(outpath);
42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgif status == 0
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    error(errMsg);
44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgend
45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnCases = 0;
47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgtestCases = [];
48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org% Read each test result file
49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgfor fileIdx = 1:length(fileNames)
50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if ~isstr(fileNames{fileIdx})
51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        error('First argument must be a cell array of strings');
52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    end
53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    fid = fopen(fileNames{fileIdx}, 'rt');
55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if fid == -1
56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        error(['Unable to open ' fileNames{fileIdx}]);
57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    end
58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    version = '1.0';
60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if ~strcmp(fgetl(fid), ['#!benchmark' version])
61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        fclose(fid);
62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        error(['Requires benchmark file format version ' version]);
63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    end
64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    % Parse results file into testCases struct
66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    codec = fgetl(fid);
67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    tline = fgetl(fid);
68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    while(tline ~= -1)
69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        nCases = nCases + 1;
70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        delim = strfind(tline, ',');
72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        name = tline(1:delim(1)-1);
73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        % Drop underscored suffix from name
74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        underscore = strfind(name, '_'); 
75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if ~isempty(underscore)
76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            name = name(1:underscore(1)-1);
77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        end
78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        resolution = tline(delim(1)+1:delim(2)-1);
80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        frameRate = tline(delim(2)+1:end);
81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        tline = fgetl(fid);
83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        delim = strfind(tline, ',');
84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        bitrateLabel = tline(1:delim(1)-1); 
85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        bitrate = sscanf(tline(delim(1):end),',%f');
86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        tline = fgetl(fid);
88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        delim = strfind(tline, ',');
89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        psnrLabel = tline(1:delim(1)-1); 
90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        psnr = sscanf(tline(delim(1):end),',%f'); 
91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        % Default data for the optional lines
94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        speedLabel = 'Default';
95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        speed = 0;
96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        ssimLabel = 'Default';
97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        ssim = 0;
98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        
99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        tline = fgetl(fid);
100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        delim = strfind(tline, ',');
101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        
102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        while ~isempty(delim)
103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            % More data
104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            % Check type of data
105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            if strncmp(lower(tline), 'speed', 5)
106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                % Speed data included
107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                speedLabel = tline(1:delim(1)-1);
108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                speed = sscanf(tline(delim(1):end), ',%f');
109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                tline = fgetl(fid);
111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                
112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            elseif strncmp(lower(tline), 'encode time', 11)
113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                % Encode and decode times included
114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                % TODO: take care of the data
115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                
116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                % pop two lines from file
117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                tline = fgetl(fid);
118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                tline = fgetl(fid);
119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                
120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            elseif strncmp(tline, 'SSIM', 4)
121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                % SSIM data included
122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                ssimLabel = tline(1:delim(1)-1);
123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                ssim = sscanf(tline(delim(1):end), ',%f');
124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                tline = fgetl(fid);
126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            end
127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            delim = strfind(tline, ',');
128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        end
129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        testCases = [testCases struct('codec', codec, 'name', name, 'resolution', ...
131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            resolution, 'frameRate', frameRate, 'bitrate', bitrate, 'psnr', psnr, ...
132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            'speed', speed, 'bitrateLabel', bitrateLabel, 'psnrLabel', psnrLabel, ...
133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            'speedLabel', speedLabel, ...
134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            'ssim', ssim, 'ssimLabel', ssimLabel)];
135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        tline = fgetl(fid);
137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    end
138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    fclose(fid);
140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgend
141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgi = 0;
143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgcasesPsnr = testCases;
144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgwhile ~isempty(casesPsnr)
145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    i = i + 1;
146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    casesPsnr = plotOnePsnr(casesPsnr, i, export, outpath);
147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgend
148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgcasesSSIM = testCases;
150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgwhile ~isempty(casesSSIM)
151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    i = i + 1;
152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    casesSSIM = plotOneSSIM(casesSSIM, i, export, outpath);
153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgend
154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgcasesSpeed = testCases;
156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgwhile ~isempty(casesSpeed)
157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if casesSpeed(1).speed == 0
158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        casesSpeed = casesSpeed(2:end);
159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    else
160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        i = i + 1;
161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        casesSpeed = plotOneSpeed(casesSpeed, i, export, outpath);
162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    end
163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgend
164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org%%%%%%%%%%%%%%%%%%
168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org%% SUBFUNCTIONS %%
169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org%%%%%%%%%%%%%%%%%%
170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgfunction casesOut = plotOnePsnr(cases, num, export, outpath)
172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org% Find matching specs
173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgplotIdx = 1;
174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgfor i = 2:length(cases)
175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if strcmp(cases(1).resolution, cases(i).resolution) & ...
176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        strcmp(cases(1).frameRate, cases(i).frameRate)
177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        plotIdx = [plotIdx i];
178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    end
179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgend
180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org% Return unplotted cases
182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgcasesOut = cases(setdiff(1:length(cases), plotIdx));
183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgcases = cases(plotIdx);
184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org% Prune similar results
186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgfor i = 1:length(cases)
187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    simIndx = find(abs(cases(i).bitrate - [cases(i).bitrate(2:end) ; 0]) < 10);
188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    while ~isempty(simIndx)
189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        diffIndx = setdiff(1:length(cases(i).bitrate), simIndx);
190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        cases(i).psnr = cases(i).psnr(diffIndx);
191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        cases(i).bitrate = cases(i).bitrate(diffIndx);
192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        simIndx = find(abs(cases(i).bitrate - [cases(i).bitrate(2:end) ; 0]) < 10);
193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    end
194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgend
195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org% Prepare figure with axis labels and so on
197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orghFig = figure(num);
198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclf;
199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orghold on;
200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orggrid on;
201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgaxis([0 1100 20 50]);
202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgset(gca, 'XTick', 0:200:1000);
203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgset(gca, 'YTick', 20:10:60);
204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgxlabel(cases(1).bitrateLabel);
205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgylabel(cases(1).psnrLabel);
206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgres = cases(1).resolution;
207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgfrRate = cases(1).frameRate;
208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgtitle([res ', ' frRate]);
209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orghLines = [];
211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgcodecs = {};
212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgsequences = {};
213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgi = 0;
214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgwhile ~isempty(cases)
215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    i = i + 1;
216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    [cases, hLine, codec, sequences] = plotOneCodec(cases, 'bitrate', 'psnr', i, sequences, 1);
217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    % Stored to generate the legend
219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    hLines = [hLines ; hLine];
220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    codecs = {codecs{:} codec};
221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgend
222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orglegend(hLines, codecs, 4);
223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orghold off;
224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgif ~strcmp(export, 'none')
226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    % Export figure to an eps file
227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    res = stripws(res);
228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    frRate = stripws(frRate);
229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    exportName = [outpath '/psnr-' res '-' frRate];
230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    exportfig(hFig, exportName, 'Format', 'eps2', 'Color', 'cmyk');
231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgend
232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgif strcmp(export, 'pdf')
234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    % Use the epstopdf utility to convert to pdf
235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    system(['epstopdf ' exportName '.eps']);  
236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgend
237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgfunction casesOut = plotOneSSIM(cases, num, export, outpath)
240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org% Find matching specs
241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgplotIdx = 1;
242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgfor i = 2:length(cases)
243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if strcmp(cases(1).resolution, cases(i).resolution) & ...
244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        strcmp(cases(1).frameRate, cases(i).frameRate)
245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        plotIdx = [plotIdx i];
246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    end
247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgend
248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org% Return unplotted cases
250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgcasesOut = cases(setdiff(1:length(cases), plotIdx));
251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgcases = cases(plotIdx);
252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org% Prune similar results
254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgfor i = 1:length(cases)
255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    simIndx = find(abs(cases(i).bitrate - [cases(i).bitrate(2:end) ; 0]) < 10);
256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    while ~isempty(simIndx)
257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        diffIndx = setdiff(1:length(cases(i).bitrate), simIndx);
258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        cases(i).ssim = cases(i).ssim(diffIndx);
259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        cases(i).bitrate = cases(i).bitrate(diffIndx);
260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        simIndx = find(abs(cases(i).bitrate - [cases(i).bitrate(2:end) ; 0]) < 10);
261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    end
262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgend
263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org% Prepare figure with axis labels and so on
265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orghFig = figure(num);
266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclf;
267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orghold on;
268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orggrid on;
269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgaxis([0 1100 0.5 1]); % y-limit are set to 'auto' below
270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgset(gca, 'XTick', 0:200:1000);
271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org%set(gca, 'YTick', 20:10:60);
272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgxlabel(cases(1).bitrateLabel);
273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgylabel(cases(1).ssimLabel);
274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgres = cases(1).resolution;
275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgfrRate = cases(1).frameRate;
276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgtitle([res ', ' frRate]);
277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orghLines = [];
279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgcodecs = {};
280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgsequences = {};
281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgi = 0;
282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgwhile ~isempty(cases)
283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    i = i + 1;
284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    [cases, hLine, codec, sequences] = plotOneCodec(cases, 'bitrate', 'ssim', i, sequences, 1);
285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    % Stored to generate the legend
287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    hLines = [hLines ; hLine];
288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    codecs = {codecs{:} codec};
289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgend
290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org%set(gca,'YLimMode','auto')
291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgset(gca,'YLim',[0.5 1])
292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgset(gca,'YScale','log')
293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orglegend(hLines, codecs, 4);
294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orghold off;
295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgif ~strcmp(export, 'none')
297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    % Export figure to an eps file
298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    res = stripws(res);
299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    frRate = stripws(frRate);
300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    exportName = [outpath '/psnr-' res '-' frRate];
301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    exportfig(hFig, exportName, 'Format', 'eps2', 'Color', 'cmyk');
302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgend
303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgif strcmp(export, 'pdf')
305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    % Use the epstopdf utility to convert to pdf
306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    system(['epstopdf ' exportName '.eps']);  
307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgend
308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgfunction casesOut = plotOneSpeed(cases, num, export, outpath)
311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org% Find matching specs
312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgplotIdx = 1;
313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgfor i = 2:length(cases)
314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if strcmp(cases(1).resolution, cases(i).resolution) & ...
315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        strcmp(cases(1).frameRate, cases(i).frameRate) & ...
316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        strcmp(cases(1).name, cases(i).name)
317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        plotIdx = [plotIdx i];
318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    end
319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgend
320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org% Return unplotted cases
322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgcasesOut = cases(setdiff(1:length(cases), plotIdx));
323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgcases = cases(plotIdx);
324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org% Prune similar results
326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgfor i = 1:length(cases)
327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    simIndx = find(abs(cases(i).psnr - [cases(i).psnr(2:end) ; 0]) < 0.25);
328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    while ~isempty(simIndx)
329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        diffIndx = setdiff(1:length(cases(i).psnr), simIndx);
330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        cases(i).psnr = cases(i).psnr(diffIndx);
331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        cases(i).speed = cases(i).speed(diffIndx);
332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        simIndx = find(abs(cases(i).psnr - [cases(i).psnr(2:end) ; 0]) < 0.25);
333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    end
334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgend
335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orghFig = figure(num);
337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclf;
338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orghold on;
339b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org%grid on;
340b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgxlabel(cases(1).psnrLabel);
341b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgylabel(cases(1).speedLabel);
342b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgres = cases(1).resolution;
343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgname = cases(1).name;
344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgfrRate = cases(1).frameRate;
345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgtitle([name ', ' res ', ' frRate]);
346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orghLines = [];
348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgcodecs = {};
349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgsequences = {};
350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgi = 0;
351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgwhile ~isempty(cases)
352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    i = i + 1;
353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    [cases, hLine, codec, sequences] = plotOneCodec(cases, 'psnr', 'speed', i, sequences, 0);
354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    % Stored to generate the legend
356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    hLines = [hLines ; hLine];
357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    codecs = {codecs{:} codec};
358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgend
359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orglegend(hLines, codecs, 1);
360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orghold off;
361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgif ~strcmp(export, 'none')
363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    % Export figure to an eps file
364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    res = stripws(res);
365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    frRate = stripws(frRate);
366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    exportName = [outpath '/speed-' name '-' res '-' frRate];
367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    exportfig(hFig, exportName, 'Format', 'eps2', 'Color', 'cmyk');
368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgend
369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgif strcmp(export, 'pdf')
371b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    % Use the epstopdf utility to convert to pdf
372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    system(['epstopdf ' exportName '.eps']);  
373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgend
374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgfunction [casesOut, hLine, codec, sequences] = plotOneCodec(cases, xfield, yfield, num, sequences, annotatePlot)
377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgplotStr = {'gx-', 'bo-', 'r^-', 'kd-', 'cx-', 'go--', 'b^--'};
378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org% Find matching codecs
379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgplotIdx = 1;
380b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgfor i = 2:length(cases)
381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if strcmp(cases(1).codec, cases(i).codec)
382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        plotIdx = [plotIdx i];
383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    end
384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgend
385b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org% Return unplotted cases
387b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgcasesOut = cases(setdiff(1:length(cases), plotIdx));
388b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgcases = cases(plotIdx);
389b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
390b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgfor i = 1:length(cases)
391b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    % Plot a single case
392b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    hLine = plot(getfield(cases(i), xfield), getfield(cases(i), yfield), plotStr{num}, ...
393b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        'LineWidth', 1.1, 'MarkerSize', 6);
394b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgend
395b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org% hLine handle and codec are returned to construct the legend afterwards
397b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgcodec = cases(1).codec;
398b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
399b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgif annotatePlot == 0
400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return;
401b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgend
402b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
403b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgfor i = 1:length(cases)
404b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    % Print the codec name as a text label
405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    % Ensure each codec is only printed once
406b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    sequencePlotted = 0;
407b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    for j = 1:length(sequences)
408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if strcmp(cases(i).name, sequences{j})
409b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            sequencePlotted = 1;
410b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            break;
411b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        end
412b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    end
413b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
414b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if sequencePlotted == 0
415b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        text(getfield(cases(i), xfield, {1}), getfield(cases(i), yfield, {1}), ...
416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            ['    ' cases(i).name]);
417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        sequences = {sequences{:} cases(i).name};
418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    end
419b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgend
420b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org% Strip whitespace from string
423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgfunction str = stripws(str)
424b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgif ~isstr(str)
425b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    error('String required');
426b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgend
427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstr = str(setdiff(1:length(str), find(isspace(str) == 1)));
428