% % Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. % % Use of this source code is governed by a BSD-style license % that can be found in the LICENSE file in the root of the source % tree. An additional intellectual property rights grant can be found % in the file PATENTS. All contributing project authors may % be found in the AUTHORS file in the root of the source tree. % function outStruct = parse_delay_file(file) fid = fopen(file, 'rb'); if fid == -1 error('Cannot open file %s', file); end textline = fgetl(fid); if ~strncmp(textline, '#!NetEQ_Delay_Logging', 21) error('Wrong file format'); end ver = sscanf(textline, '#!NetEQ_Delay_Logging%d.%d'); if ~all(ver == [2; 0]) error('Wrong version of delay logging function') end start_pos = ftell(fid); fseek(fid, -12, 'eof'); textline = fgetl(fid); if ~strncmp(textline, 'End of file', 21) error('File ending is not correct. Seems like the simulation ended abnormally.'); end fseek(fid,-12-4, 'eof'); Npackets = fread(fid, 1, 'int32'); fseek(fid, start_pos, 'bof'); rtpts = zeros(Npackets, 1); seqno = zeros(Npackets, 1); pt = zeros(Npackets, 1); plen = zeros(Npackets, 1); recin_t = nan*ones(Npackets, 1); decode_t = nan*ones(Npackets, 1); playout_delay = zeros(Npackets, 1); optbuf = zeros(Npackets, 1); fs_ix = 1; clock = 0; ts_ix = 1; ended = 0; late_packets = 0; fs_now = 8000; last_decode_k = 0; tot_expand = 0; tot_accelerate = 0; tot_preemptive = 0; while not(ended) signal = fread(fid, 1, '*int32'); switch signal case 3 % NETEQ_DELAY_LOGGING_SIGNAL_CLOCK clock = fread(fid, 1, '*float32'); % keep on reading batches of M until the signal is no longer "3" % read int32 + float32 in one go % this is to save execution time temp = [3; 0]; M = 120; while all(temp(1,:) == 3) fp = ftell(fid); temp = fread(fid, [2 M], '*int32'); end % back up to last clock event fseek(fid, fp - ftell(fid) + ... (find(temp(1,:) ~= 3, 1 ) - 2) * 2 * 4 + 4, 'cof'); % read the last clock value clock = fread(fid, 1, '*float32'); case 1 % NETEQ_DELAY_LOGGING_SIGNAL_RECIN temp_ts = fread(fid, 1, 'uint32'); if late_packets > 0 temp_ix = ts_ix - 1; while (temp_ix >= 1) && (rtpts(temp_ix) ~= temp_ts) % TODO(hlundin): use matlab vector search instead? temp_ix = temp_ix - 1; end if temp_ix >= 1 % the ts was found in the vector late_packets = late_packets - 1; else temp_ix = ts_ix; ts_ix = ts_ix + 1; end else temp_ix = ts_ix; ts_ix = ts_ix + 1; end rtpts(temp_ix) = temp_ts; seqno(temp_ix) = fread(fid, 1, 'uint16'); pt(temp_ix) = fread(fid, 1, 'int32'); plen(temp_ix) = fread(fid, 1, 'int16'); recin_t(temp_ix) = clock; case 2 % NETEQ_DELAY_LOGGING_SIGNAL_FLUSH % do nothing case 4 % NETEQ_DELAY_LOGGING_SIGNAL_EOF ended = 1; case 5 % NETEQ_DELAY_LOGGING_SIGNAL_DECODE last_decode_ts = fread(fid, 1, 'uint32'); temp_delay = fread(fid, 1, 'uint16'); k = find(rtpts(1:(ts_ix - 1))==last_decode_ts,1,'last'); if ~isempty(k) decode_t(k) = clock; playout_delay(k) = temp_delay + ... 5 * fs_now / 8000; % add overlap length last_decode_k = k; end case 6 % NETEQ_DELAY_LOGGING_SIGNAL_CHANGE_FS fsvec(fs_ix) = fread(fid, 1, 'uint16'); fschange_ts(fs_ix) = last_decode_ts; fs_now = fsvec(fs_ix); fs_ix = fs_ix + 1; case 7 % NETEQ_DELAY_LOGGING_SIGNAL_MERGE_INFO playout_delay(last_decode_k) = playout_delay(last_decode_k) ... + fread(fid, 1, 'int32'); case 8 % NETEQ_DELAY_LOGGING_SIGNAL_EXPAND_INFO temp = fread(fid, 1, 'int32'); if last_decode_k ~= 0 tot_expand = tot_expand + temp / (fs_now / 1000); end case 9 % NETEQ_DELAY_LOGGING_SIGNAL_ACCELERATE_INFO temp = fread(fid, 1, 'int32'); if last_decode_k ~= 0 tot_accelerate = tot_accelerate + temp / (fs_now / 1000); end case 10 % NETEQ_DELAY_LOGGING_SIGNAL_PREEMPTIVE_INFO temp = fread(fid, 1, 'int32'); if last_decode_k ~= 0 tot_preemptive = tot_preemptive + temp / (fs_now / 1000); end case 11 % NETEQ_DELAY_LOGGING_SIGNAL_OPTBUF optbuf(last_decode_k) = fread(fid, 1, 'int32'); case 12 % NETEQ_DELAY_LOGGING_SIGNAL_DECODE_ONE_DESC last_decode_ts = fread(fid, 1, 'uint32'); k = ts_ix - 1; while (k >= 1) && (rtpts(k) ~= last_decode_ts) % TODO(hlundin): use matlab vector search instead? k = k - 1; end if k < 1 % packet not received yet k = ts_ix; rtpts(ts_ix) = last_decode_ts; late_packets = late_packets + 1; end decode_t(k) = clock; playout_delay(k) = fread(fid, 1, 'uint16') + ... 5 * fs_now / 8000; % add overlap length last_decode_k = k; end end fclose(fid); outStruct = struct(... 'ts', rtpts, ... 'sn', seqno, ... 'pt', pt,... 'plen', plen,... 'arrival', recin_t,... 'decode', decode_t,... 'fs', fsvec(:),... 'fschange_ts', fschange_ts(:),... 'playout_delay', playout_delay,... 'tot_expand', tot_expand,... 'tot_accelerate', tot_accelerate,... 'tot_preemptive', tot_preemptive,... 'optbuf', optbuf);