summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/tools_webrtc/matlab
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/tools_webrtc/matlab')
-rw-r--r--third_party/libwebrtc/tools_webrtc/matlab/maxUnwrap.m25
-rw-r--r--third_party/libwebrtc/tools_webrtc/matlab/parseLog.m54
-rw-r--r--third_party/libwebrtc/tools_webrtc/matlab/rtpAnalyze.m251
3 files changed, 330 insertions, 0 deletions
diff --git a/third_party/libwebrtc/tools_webrtc/matlab/maxUnwrap.m b/third_party/libwebrtc/tools_webrtc/matlab/maxUnwrap.m
new file mode 100644
index 0000000000..276c9523a4
--- /dev/null
+++ b/third_party/libwebrtc/tools_webrtc/matlab/maxUnwrap.m
@@ -0,0 +1,25 @@
+function sequence = maxUnwrap(sequence, max)
+%
+% sequence = maxUnwrap(sequence, max)
+% Unwraps when a wrap around is detected.
+%
+% Arguments
+%
+% sequence: The vector to unwrap.
+% max: The maximum value that the sequence can take,
+% and after which it will wrap over to 0.
+%
+% Return value
+%
+% sequence: The unwrapped vector.
+%
+
+% 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.
+
+sequence = round((unwrap(2 * pi * sequence / max) * max) / (2 * pi));
diff --git a/third_party/libwebrtc/tools_webrtc/matlab/parseLog.m b/third_party/libwebrtc/tools_webrtc/matlab/parseLog.m
new file mode 100644
index 0000000000..5d4c3f7bc1
--- /dev/null
+++ b/third_party/libwebrtc/tools_webrtc/matlab/parseLog.m
@@ -0,0 +1,54 @@
+function parsed = parseLog(filename)
+%
+% parsed = parseLog(filename)
+% Parses a DataLog text file, with the filename specified in the string
+% filename, into a struct with each column name as a field, and with the
+% column data stored as a vector in that field.
+%
+% Arguments
+%
+% filename: A string with the name of the file to parse.
+%
+% Return value
+%
+% parsed: A struct containing each column parsed from the input file
+% as a field and with the column data stored as a vector in that
+% field.
+%
+
+% 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.
+
+table = importdata(filename, ',', 1);
+if ~isstruct(table)
+ error('Malformed file, possibly empty or lacking data entries')
+end
+
+colheaders = table.textdata;
+if length(colheaders) == 1
+ colheaders = regexp(table.textdata{1}, ',', 'split');
+end
+
+parsed = struct;
+i = 1;
+while i <= length(colheaders)
+ % Checking for a multi-value column.
+ m = regexp(colheaders{i}, '([\w\t]+)\[(\d+)\]', 'tokens');
+ if ~isempty(m)
+ % Parse a multi-value column
+ n = str2double(m{1}{2}) - 1;
+ parsed.(strrep(m{1}{1}, ' ', '_')) = table.data(:, i:i+n);
+ i = i + n + 1;
+ elseif ~isempty(colheaders{i})
+ % Parse a single-value column
+ parsed.(strrep(colheaders{i}, ' ', '_')) = table.data(:, i);
+ i = i + 1;
+ else
+ error('Empty column');
+ end
+end
diff --git a/third_party/libwebrtc/tools_webrtc/matlab/rtpAnalyze.m b/third_party/libwebrtc/tools_webrtc/matlab/rtpAnalyze.m
new file mode 100644
index 0000000000..c51af9cca5
--- /dev/null
+++ b/third_party/libwebrtc/tools_webrtc/matlab/rtpAnalyze.m
@@ -0,0 +1,251 @@
+function rtpAnalyze( input_file )
+%RTP_ANALYZE Analyze RTP stream(s) from a txt file
+% The function takes the output from the command line tool rtp_analyze
+% and analyzes the stream(s) therein. First, process your rtpdump file
+% through rtp_analyze (from command line):
+% $ out/Debug/rtp_analyze my_file.rtp my_file.txt
+% Then load it with this function (in Matlab):
+% >> rtpAnalyze('my_file.txt')
+
+% Copyright (c) 2015 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.
+
+[SeqNo,TimeStamp,ArrTime,Size,PT,M,SSRC] = importfile(input_file);
+
+%% Filter out RTCP packets.
+% These appear as RTP packets having payload types 72 through 76.
+ix = not(ismember(PT, 72:76));
+fprintf('Removing %i RTCP packets\n', length(SeqNo) - sum(ix));
+SeqNo = SeqNo(ix);
+TimeStamp = TimeStamp(ix);
+ArrTime = ArrTime(ix);
+Size = Size(ix);
+PT = PT(ix);
+M = M(ix);
+SSRC = SSRC(ix);
+
+%% Find streams.
+[uSSRC, ~, uix] = unique(SSRC);
+
+% If there are multiple streams, select one and purge the other
+% streams from the data vectors. If there is only one stream, the
+% vectors are good to use as they are.
+if length(uSSRC) > 1
+ for i=1:length(uSSRC)
+ uPT = unique(PT(uix == i));
+ fprintf('%i: %s (%d packets, pt: %i', i, uSSRC{i}, ...
+ length(find(uix==i)), uPT(1));
+ if length(uPT) > 1
+ fprintf(', %i', uPT(2:end));
+ end
+ fprintf(')\n');
+ end
+ sel = input('Select stream number: ');
+ if sel < 1 || sel > length(uSSRC)
+ error('Out of range');
+ end
+ ix = find(uix == sel);
+ % This is where the data vectors are trimmed.
+ SeqNo = SeqNo(ix);
+ TimeStamp = TimeStamp(ix);
+ ArrTime = ArrTime(ix);
+ Size = Size(ix);
+ PT = PT(ix);
+ M = M(ix);
+ SSRC = SSRC(ix);
+end
+
+%% Unwrap SeqNo and TimeStamp.
+SeqNoUW = maxUnwrap(SeqNo, 65535);
+TimeStampUW = maxUnwrap(TimeStamp, 4294967295);
+
+%% Generate some stats for the stream.
+fprintf('Statistics:\n');
+fprintf('SSRC: %s\n', SSRC{1});
+uPT = unique(PT);
+if length(uPT) > 1
+ warning('This tool cannot yet handle changes in codec sample rate');
+end
+fprintf('Payload type(s): %i', uPT(1));
+if length(uPT) > 1
+ fprintf(', %i', uPT(2:end));
+end
+fprintf('\n');
+fprintf('Packets: %i\n', length(SeqNo));
+SortSeqNo = sort(SeqNoUW);
+fprintf('Missing sequence numbers: %i\n', ...
+ length(find(diff(SortSeqNo) > 1)));
+fprintf('Duplicated packets: %i\n', length(find(diff(SortSeqNo) == 0)));
+reorderIx = findReorderedPackets(SeqNoUW);
+fprintf('Reordered packets: %i\n', length(reorderIx));
+tsdiff = diff(TimeStampUW);
+tsdiff = tsdiff(diff(SeqNoUW) == 1);
+[utsdiff, ~, ixtsdiff] = unique(tsdiff);
+fprintf('Common packet sizes:\n');
+for i = 1:length(utsdiff)
+ fprintf(' %i samples (%i%%)\n', ...
+ utsdiff(i), ...
+ round(100 * length(find(ixtsdiff == i))/length(ixtsdiff)));
+end
+
+%% Trying to figure out sample rate.
+fs_est = (TimeStampUW(end) - TimeStampUW(1)) / (ArrTime(end) - ArrTime(1));
+fs_vec = [8, 16, 32, 48];
+fs = 0;
+for f = fs_vec
+ if abs((fs_est-f)/f) < 0.05 % 5% margin
+ fs = f;
+ break;
+ end
+end
+if fs == 0
+ fprintf('Cannot determine sample rate. I get it to %.2f kHz\n', ...
+ fs_est);
+ fs = input('Please, input a sample rate (in kHz): ');
+else
+ fprintf('Sample rate estimated to %i kHz\n', fs);
+end
+
+SendTimeMs = (TimeStampUW - TimeStampUW(1)) / fs;
+
+fprintf('Stream duration at sender: %.1f seconds\n', ...
+ (SendTimeMs(end) - SendTimeMs(1)) / 1000);
+
+fprintf('Stream duration at receiver: %.1f seconds\n', ...
+ (ArrTime(end) - ArrTime(1)) / 1000);
+
+fprintf('Clock drift: %.2f%%\n', ...
+ 100 * ((ArrTime(end) - ArrTime(1)) / ...
+ (SendTimeMs(end) - SendTimeMs(1)) - 1));
+
+fprintf('Sent average bitrate: %i kbps\n', ...
+ round(sum(Size) * 8 / (SendTimeMs(end)-SendTimeMs(1))));
+
+fprintf('Received average bitrate: %i kbps\n', ...
+ round(sum(Size) * 8 / (ArrTime(end)-ArrTime(1))));
+
+%% Plots.
+delay = ArrTime - SendTimeMs;
+delay = delay - min(delay);
+delayOrdered = delay;
+delayOrdered(reorderIx) = nan; % Set reordered packets to NaN.
+delayReordered = delay(reorderIx); % Pick the reordered packets.
+sendTimeMsReordered = SendTimeMs(reorderIx);
+
+% Sort time arrays in packet send order.
+[~, sortix] = sort(SeqNoUW);
+SendTimeMs = SendTimeMs(sortix);
+Size = Size(sortix);
+delayOrdered = delayOrdered(sortix);
+
+figure
+plot(SendTimeMs / 1000, delayOrdered, ...
+ sendTimeMsReordered / 1000, delayReordered, 'r.');
+xlabel('Send time [s]');
+ylabel('Relative transport delay [ms]');
+title(sprintf('SSRC: %s', SSRC{1}));
+
+SendBitrateKbps = 8 * Size(1:end-1) ./ diff(SendTimeMs);
+figure
+plot(SendTimeMs(1:end-1)/1000, SendBitrateKbps);
+xlabel('Send time [s]');
+ylabel('Send bitrate [kbps]');
+end
+
+%% Subfunctions.
+
+% findReorderedPackets returns the index to all packets that are considered
+% old compared with the largest seen sequence number. The input seqNo must
+% be unwrapped for this to work.
+function reorderIx = findReorderedPackets(seqNo)
+largestSeqNo = seqNo(1);
+reorderIx = [];
+for i = 2:length(seqNo)
+ if seqNo(i) < largestSeqNo
+ reorderIx = [reorderIx; i]; %#ok<AGROW>
+ else
+ largestSeqNo = seqNo(i);
+ end
+end
+end
+
+%% Auto-generated subfunction.
+function [SeqNo,TimeStamp,SendTime,Size,PT,M,SSRC] = ...
+ importfile(filename, startRow, endRow)
+%IMPORTFILE Import numeric data from a text file as column vectors.
+% [SEQNO,TIMESTAMP,SENDTIME,SIZE,PT,M,SSRC] = IMPORTFILE(FILENAME) Reads
+% data from text file FILENAME for the default selection.
+%
+% [SEQNO,TIMESTAMP,SENDTIME,SIZE,PT,M,SSRC] = IMPORTFILE(FILENAME,
+% STARTROW, ENDROW) Reads data from rows STARTROW through ENDROW of text
+% file FILENAME.
+%
+% Example:
+% [SeqNo,TimeStamp,SendTime,Size,PT,M,SSRC] =
+% importfile('rtpdump_recv.txt',2, 123);
+%
+% See also TEXTSCAN.
+
+% Auto-generated by MATLAB on 2015/05/28 09:55:50
+
+%% Initialize variables.
+if nargin<=2
+ startRow = 2;
+ endRow = inf;
+end
+
+%% Format string for each line of text:
+% column1: double (%f)
+% column2: double (%f)
+% column3: double (%f)
+% column4: double (%f)
+% column5: double (%f)
+% column6: double (%f)
+% column7: text (%s)
+% For more information, see the TEXTSCAN documentation.
+formatSpec = '%5f%11f%11f%6f%6f%3f%s%[^\n\r]';
+
+%% Open the text file.
+fileID = fopen(filename,'r');
+
+%% Read columns of data according to format string.
+% This call is based on the structure of the file used to generate this
+% code. If an error occurs for a different file, try regenerating the code
+% from the Import Tool.
+dataArray = textscan(fileID, formatSpec, endRow(1)-startRow(1)+1, ...
+ 'Delimiter', '', 'WhiteSpace', '', 'HeaderLines', startRow(1)-1, ...
+ 'ReturnOnError', false);
+for block=2:length(startRow)
+ frewind(fileID);
+ dataArrayBlock = textscan(fileID, formatSpec, ...
+ endRow(block)-startRow(block)+1, 'Delimiter', '', 'WhiteSpace', ...
+ '', 'HeaderLines', startRow(block)-1, 'ReturnOnError', false);
+ for col=1:length(dataArray)
+ dataArray{col} = [dataArray{col};dataArrayBlock{col}];
+ end
+end
+
+%% Close the text file.
+fclose(fileID);
+
+%% Post processing for unimportable data.
+% No unimportable data rules were applied during the import, so no post
+% processing code is included. To generate code which works for
+% unimportable data, select unimportable cells in a file and regenerate the
+% script.
+
+%% Allocate imported array to column variable names
+SeqNo = dataArray{:, 1};
+TimeStamp = dataArray{:, 2};
+SendTime = dataArray{:, 3};
+Size = dataArray{:, 4};
+PT = dataArray{:, 5};
+M = dataArray{:, 6};
+SSRC = dataArray{:, 7};
+end
+