1% 2% Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3% 4% Use of this source code is governed by a BSD-style license 5% that can be found in the LICENSE file in the root of the source 6% tree. An additional intellectual property rights grant can be found 7% in the file PATENTS. All contributing project authors may 8% be found in the AUTHORS file in the root of the source tree. 9% 10 11function outStruct = parse_delay_file(file) 12 13fid = fopen(file, 'rb'); 14if fid == -1 15 error('Cannot open file %s', file); 16end 17 18textline = fgetl(fid); 19if ~strncmp(textline, '#!NetEQ_Delay_Logging', 21) 20 error('Wrong file format'); 21end 22 23ver = sscanf(textline, '#!NetEQ_Delay_Logging%d.%d'); 24if ~all(ver == [2; 0]) 25 error('Wrong version of delay logging function') 26end 27 28 29start_pos = ftell(fid); 30fseek(fid, -12, 'eof'); 31textline = fgetl(fid); 32if ~strncmp(textline, 'End of file', 21) 33 error('File ending is not correct. Seems like the simulation ended abnormally.'); 34end 35 36fseek(fid,-12-4, 'eof'); 37Npackets = fread(fid, 1, 'int32'); 38fseek(fid, start_pos, 'bof'); 39 40rtpts = zeros(Npackets, 1); 41seqno = zeros(Npackets, 1); 42pt = zeros(Npackets, 1); 43plen = zeros(Npackets, 1); 44recin_t = nan*ones(Npackets, 1); 45decode_t = nan*ones(Npackets, 1); 46playout_delay = zeros(Npackets, 1); 47optbuf = zeros(Npackets, 1); 48 49fs_ix = 1; 50clock = 0; 51ts_ix = 1; 52ended = 0; 53late_packets = 0; 54fs_now = 8000; 55last_decode_k = 0; 56tot_expand = 0; 57tot_accelerate = 0; 58tot_preemptive = 0; 59 60while not(ended) 61 signal = fread(fid, 1, '*int32'); 62 63 switch signal 64 case 3 % NETEQ_DELAY_LOGGING_SIGNAL_CLOCK 65 clock = fread(fid, 1, '*float32'); 66 67 % keep on reading batches of M until the signal is no longer "3" 68 % read int32 + float32 in one go 69 % this is to save execution time 70 temp = [3; 0]; 71 M = 120; 72 while all(temp(1,:) == 3) 73 fp = ftell(fid); 74 temp = fread(fid, [2 M], '*int32'); 75 end 76 77 % back up to last clock event 78 fseek(fid, fp - ftell(fid) + ... 79 (find(temp(1,:) ~= 3, 1 ) - 2) * 2 * 4 + 4, 'cof'); 80 % read the last clock value 81 clock = fread(fid, 1, '*float32'); 82 83 case 1 % NETEQ_DELAY_LOGGING_SIGNAL_RECIN 84 temp_ts = fread(fid, 1, 'uint32'); 85 86 if late_packets > 0 87 temp_ix = ts_ix - 1; 88 while (temp_ix >= 1) && (rtpts(temp_ix) ~= temp_ts) 89 % TODO(hlundin): use matlab vector search instead? 90 temp_ix = temp_ix - 1; 91 end 92 93 if temp_ix >= 1 94 % the ts was found in the vector 95 late_packets = late_packets - 1; 96 else 97 temp_ix = ts_ix; 98 ts_ix = ts_ix + 1; 99 end 100 else 101 temp_ix = ts_ix; 102 ts_ix = ts_ix + 1; 103 end 104 105 rtpts(temp_ix) = temp_ts; 106 seqno(temp_ix) = fread(fid, 1, 'uint16'); 107 pt(temp_ix) = fread(fid, 1, 'int32'); 108 plen(temp_ix) = fread(fid, 1, 'int16'); 109 recin_t(temp_ix) = clock; 110 111 case 2 % NETEQ_DELAY_LOGGING_SIGNAL_FLUSH 112 % do nothing 113 114 case 4 % NETEQ_DELAY_LOGGING_SIGNAL_EOF 115 ended = 1; 116 117 case 5 % NETEQ_DELAY_LOGGING_SIGNAL_DECODE 118 last_decode_ts = fread(fid, 1, 'uint32'); 119 temp_delay = fread(fid, 1, 'uint16'); 120 121 k = find(rtpts(1:(ts_ix - 1))==last_decode_ts,1,'last'); 122 if ~isempty(k) 123 decode_t(k) = clock; 124 playout_delay(k) = temp_delay + ... 125 5 * fs_now / 8000; % add overlap length 126 last_decode_k = k; 127 end 128 129 case 6 % NETEQ_DELAY_LOGGING_SIGNAL_CHANGE_FS 130 fsvec(fs_ix) = fread(fid, 1, 'uint16'); 131 fschange_ts(fs_ix) = last_decode_ts; 132 fs_now = fsvec(fs_ix); 133 fs_ix = fs_ix + 1; 134 135 case 7 % NETEQ_DELAY_LOGGING_SIGNAL_MERGE_INFO 136 playout_delay(last_decode_k) = playout_delay(last_decode_k) ... 137 + fread(fid, 1, 'int32'); 138 139 case 8 % NETEQ_DELAY_LOGGING_SIGNAL_EXPAND_INFO 140 temp = fread(fid, 1, 'int32'); 141 if last_decode_k ~= 0 142 tot_expand = tot_expand + temp / (fs_now / 1000); 143 end 144 145 case 9 % NETEQ_DELAY_LOGGING_SIGNAL_ACCELERATE_INFO 146 temp = fread(fid, 1, 'int32'); 147 if last_decode_k ~= 0 148 tot_accelerate = tot_accelerate + temp / (fs_now / 1000); 149 end 150 151 case 10 % NETEQ_DELAY_LOGGING_SIGNAL_PREEMPTIVE_INFO 152 temp = fread(fid, 1, 'int32'); 153 if last_decode_k ~= 0 154 tot_preemptive = tot_preemptive + temp / (fs_now / 1000); 155 end 156 157 case 11 % NETEQ_DELAY_LOGGING_SIGNAL_OPTBUF 158 optbuf(last_decode_k) = fread(fid, 1, 'int32'); 159 160 case 12 % NETEQ_DELAY_LOGGING_SIGNAL_DECODE_ONE_DESC 161 last_decode_ts = fread(fid, 1, 'uint32'); 162 k = ts_ix - 1; 163 164 while (k >= 1) && (rtpts(k) ~= last_decode_ts) 165 % TODO(hlundin): use matlab vector search instead? 166 k = k - 1; 167 end 168 169 if k < 1 170 % packet not received yet 171 k = ts_ix; 172 rtpts(ts_ix) = last_decode_ts; 173 late_packets = late_packets + 1; 174 end 175 176 decode_t(k) = clock; 177 playout_delay(k) = fread(fid, 1, 'uint16') + ... 178 5 * fs_now / 8000; % add overlap length 179 last_decode_k = k; 180 181 end 182 183end 184 185 186fclose(fid); 187 188outStruct = struct(... 189 'ts', rtpts, ... 190 'sn', seqno, ... 191 'pt', pt,... 192 'plen', plen,... 193 'arrival', recin_t,... 194 'decode', decode_t,... 195 'fs', fsvec(:),... 196 'fschange_ts', fschange_ts(:),... 197 'playout_delay', playout_delay,... 198 'tot_expand', tot_expand,... 199 'tot_accelerate', tot_accelerate,... 200 'tot_preemptive', tot_preemptive,... 201 'optbuf', optbuf); 202