Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: webrtc/examples/objc/AppRTCDemo/ARDStatsBuilder.m

Issue 1289623005: Add stats overlay to iOS AppRTCDemo. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright 2015 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
11 #import "ARDStatsBuilder.h"
12
13 #import "RTCPair.h"
14 #import "RTCStatsReport.h"
15
16 #import "ARDBitrateTracker.h"
17 #import "ARDUtilities.h"
18
19 @implementation ARDStatsBuilder {
20 // Connection stats.
21 NSString *_connRecvBitrate;
22 NSString *_connRtt;
23 NSString *_connSendBitrate;
24 NSString *_localCandType;
25 NSString *_remoteCandType;
26 NSString *_transportType;
27
28 // BWE stats.
29 NSString *_actualEncBitrate;
30 NSString *_availableRecvBw;
31 NSString *_availableSendBw;
32 NSString *_targetEncBitrate;
33
34 // Video send stats.
35 NSString *_videoEncodeMs;
36 NSString *_videoInputFps;
37 NSString *_videoInputHeight;
38 NSString *_videoInputWidth;
39 NSString *_videoSendCodec;
40 NSString *_videoSendBitrate;
41 NSString *_videoSendFps;
42 NSString *_videoSendHeight;
43 NSString *_videoSendWidth;
44
45 // Video receive stats.
46 NSString *_videoDecodeMs;
47 NSString *_videoDecodedFps;
48 NSString *_videoOutputFps;
49 NSString *_videoRecvBitrate;
50 NSString *_videoRecvFps;
51 NSString *_videoRecvHeight;
52 NSString *_videoRecvWidth;
53
54 // Audio send stats.
55 NSString *_audioSendBitrate;
56 NSString *_audioSendCodec;
57
58 // Audio receive stats.
59 NSString *_audioCurrentDelay;
60 NSString *_audioExpandRate;
61 NSString *_audioRecvBitrate;
62 NSString *_audioRecvCodec;
63
64 // Bitrate trackers.
65 ARDBitrateTracker *_audioRecvBitrateTracker;
66 ARDBitrateTracker *_audioSendBitrateTracker;
67 ARDBitrateTracker *_connRecvBitrateTracker;
68 ARDBitrateTracker *_connSendBitrateTracker;
69 ARDBitrateTracker *_videoRecvBitrateTracker;
70 ARDBitrateTracker *_videoSendBitrateTracker;
71 }
72
73 - (instancetype)init {
74 if (self = [super init]) {
75 _audioSendBitrateTracker = [[ARDBitrateTracker alloc] init];
76 _audioRecvBitrateTracker = [[ARDBitrateTracker alloc] init];
77 _connSendBitrateTracker = [[ARDBitrateTracker alloc] init];
78 _connRecvBitrateTracker = [[ARDBitrateTracker alloc] init];
79 _videoSendBitrateTracker = [[ARDBitrateTracker alloc] init];
80 _videoRecvBitrateTracker = [[ARDBitrateTracker alloc] init];
81 }
82 return self;
83 }
84
85 - (NSString *)statsString {
86 NSMutableString *result = [NSMutableString string];
87 // TODO(tkchin): CPU utilization.
jiayl2 2015/08/13 22:21:50 nit: make the TODO more clear about what's needed
tkchin_webrtc 2015/08/13 23:55:31 Nothing left, that was a TODO for myself in this C
88 NSString *systemStatsFormat = @"(cpu)%ld%%\n";
89 [result appendString:[NSString stringWithFormat:systemStatsFormat,
90 (long)ARDGetCpuUsagePercentage()]];
91
92 // Connection stats.
93 NSString *connStatsFormat = @"CN %@ms | %@->%@/%@ | (s)%@ | (r)%@\n";
94 [result appendString:[NSString stringWithFormat:connStatsFormat,
95 _connRtt,
96 _localCandType, _remoteCandType, _transportType,
97 _connSendBitrate, _connRecvBitrate]];
98
99 // Video send stats.
100 NSString *videoSendFormat = @"VS (input) %@x%@@%@fps | (sent) %@x%@@%@fps\n"
101 "VS (enc) %@/%@ | (sent) %@/%@ | %@ms | %@\n";
102 [result appendString:[NSString stringWithFormat:videoSendFormat,
103 _videoInputWidth, _videoInputHeight, _videoInputFps,
104 _videoSendWidth, _videoSendHeight, _videoSendFps,
105 _actualEncBitrate, _targetEncBitrate,
106 _videoSendBitrate, _availableSendBw,
107 _videoEncodeMs,
108 _videoSendCodec]];
109
110 // Video receive stats.
111 NSString *videoReceiveFormat =
112 @"VR (recv) %@x%@@%@fps | (decoded)%@ | (output)%@fps | %@/%@ | %@ms\n";
113 [result appendString:[NSString stringWithFormat:videoReceiveFormat,
114 _videoRecvWidth, _videoRecvHeight, _videoRecvFps,
115 _videoDecodedFps,
116 _videoOutputFps,
117 _videoRecvBitrate, _availableRecvBw,
118 _videoDecodeMs]];
119
120 // Audio send stats.
121 NSString *audioSendFormat = @"AS %@ | %@\n";
122 [result appendString:[NSString stringWithFormat:audioSendFormat,
123 _audioSendBitrate, _audioSendCodec]];
124
125 // Audio receive stats.
126 NSString *audioReceiveFormat = @"AR %@ | %@ | %@ms | (expandrate)%@";
127 [result appendString:[NSString stringWithFormat:audioReceiveFormat,
128 _audioRecvBitrate, _audioRecvCodec, _audioCurrentDelay,
129 _audioExpandRate]];
130
131 return result;
132 }
133
134 - (void)parseStatsReport:(RTCStatsReport *)statsReport {
135 NSString *reportType = statsReport.type;
136 if ([reportType isEqualToString:@"ssrc"] &&
137 [statsReport.reportId rangeOfString:@"ssrc"].location != NSNotFound) {
138 if ([statsReport.reportId rangeOfString:@"send"].location != NSNotFound) {
139 [self parseSendSsrcStatsReport:statsReport];
140 }
141 if ([statsReport.reportId rangeOfString:@"recv"].location != NSNotFound) {
142 [self parseRecvSsrcStatsReport:statsReport];
143 }
144 } else if ([reportType isEqualToString:@"VideoBwe"]) {
145 [self parseBweStatsReport:statsReport];
146 } else if ([reportType isEqualToString:@"googCandidatePair"]) {
147 [self parseConnectionStatsReport:statsReport];
148 }
149 }
150
151 #pragma mark - Private
152
153 - (void)parseBweStatsReport:(RTCStatsReport *)statsReport {
154 for (RTCPair *pair in statsReport.values) {
155 NSString *key = pair.key;
156 NSString *value = pair.value;
157 if ([key isEqualToString:@"googAvailableSendBandwidth"]) {
158 _availableSendBw =
159 [ARDBitrateTracker bitrateStringForBitrate:value.doubleValue];
160 } else if ([key isEqualToString:@"googAvailableReceiveBandwidth"]) {
161 _availableRecvBw =
162 [ARDBitrateTracker bitrateStringForBitrate:value.doubleValue];
163 } else if ([key isEqualToString:@"googActualEncBitrate"]) {
164 _actualEncBitrate =
165 [ARDBitrateTracker bitrateStringForBitrate:value.doubleValue];
166 } else if ([key isEqualToString:@"googTargetEncBitrate"]) {
167 _targetEncBitrate =
168 [ARDBitrateTracker bitrateStringForBitrate:value.doubleValue];
169 }
170 }
171 }
172
173 - (void)parseConnectionStatsReport:(RTCStatsReport *)statsReport {
174 for (RTCPair *pair in statsReport.values) {
175 NSString *key = pair.key;
176 NSString *value = pair.value;
177 if ([key isEqualToString:@"googRtt"]) {
178 _connRtt = value;
179 } else if ([key isEqualToString:@"googLocalCandidateType"]) {
180 _localCandType = value;
181 } else if ([key isEqualToString:@"googRemoteCandidateType"]) {
182 _remoteCandType = value;
183 } else if ([key isEqualToString:@"googTransportType"]) {
184 _transportType = value;
185 } else if ([key isEqualToString:@"bytesReceived"]) {
186 NSInteger byteCount = value.integerValue;
187 [_connRecvBitrateTracker updateBitrateWithCurrentByteCount:byteCount];
188 _connRecvBitrate = _connRecvBitrateTracker.bitrateString;
189 } else if ([key isEqualToString:@"bytesSent"]) {
190 NSInteger byteCount = value.integerValue;
191 [_connSendBitrateTracker updateBitrateWithCurrentByteCount:byteCount];
192 _connSendBitrate = _connSendBitrateTracker.bitrateString;
193 }
194 }
195 }
196
197 - (void)parseSendSsrcStatsReport:(RTCStatsReport *)statsReport {
198 NSDictionary *values = [self dictionaryForReport:statsReport];
199 NSString *trackId = [values[@"googTrackId"] firstObject];
200 if (trackId.length && [trackId hasPrefix:@"ARDAMSv0"]) {
201 // Video track.
202 [self parseVideoSendStatsReport:statsReport];
203 } else {
204 // Audio track.
205 [self parseAudioSendStatsReport:statsReport];
206 }
207 }
208
209 - (void)parseAudioSendStatsReport:(RTCStatsReport *)statsReport {
210 for (RTCPair *pair in statsReport.values) {
211 NSString *key = pair.key;
212 NSString *value = pair.value;
213 if ([key isEqualToString:@"googCodecName"]) {
214 _audioSendCodec = value;
215 } else if ([key isEqualToString:@"bytesSent"]) {
216 NSInteger byteCount = value.integerValue;
217 [_audioSendBitrateTracker updateBitrateWithCurrentByteCount:byteCount];
218 _audioSendBitrate = _audioSendBitrateTracker.bitrateString;
219 }
220 }
221 }
222
223 - (void)parseVideoSendStatsReport:(RTCStatsReport *)statsReport {
224 for (RTCPair *pair in statsReport.values) {
225 NSString *key = pair.key;
226 NSString *value = pair.value;
227 if ([key isEqualToString:@"googCodecName"]) {
228 _videoSendCodec = value;
229 } else if ([key isEqualToString:@"googFrameHeightInput"]) {
230 _videoInputHeight = value;
231 } else if ([key isEqualToString:@"googFrameWidthInput"]) {
232 _videoInputWidth = value;
233 } else if ([key isEqualToString:@"googFrameRateInput"]) {
234 _videoInputFps = value;
235 } else if ([key isEqualToString:@"googFrameHeightSent"]) {
236 _videoSendHeight = value;
237 } else if ([key isEqualToString:@"googFrameWidthSent"]) {
238 _videoSendWidth = value;
239 } else if ([key isEqualToString:@"googFrameRateSent"]) {
240 _videoSendFps = value;
241 } else if ([key isEqualToString:@"googAvgEncodeMs"]) {
242 _videoEncodeMs = value;
243 } else if ([key isEqualToString:@"bytesSent"]) {
244 NSInteger byteCount = value.integerValue;
245 [_videoSendBitrateTracker updateBitrateWithCurrentByteCount:byteCount];
246 _videoSendBitrate = _videoSendBitrateTracker.bitrateString;
247 }
248 }
249 }
250
251 - (void)parseRecvSsrcStatsReport:(RTCStatsReport *)statsReport {
252 NSDictionary *values = [self dictionaryForReport:statsReport];
253 NSString *transportId = [values[@"transportId"] firstObject];
254 if ([values[@"googFrameWidthReceived"] firstObject]) {
255 [self parseVideoRecvStatsReport:statsReport];
256 } else {
257 [self parseAudioRecvStatsReport:statsReport];
258 }
259 }
260
261 - (void)parseAudioRecvStatsReport:(RTCStatsReport *)statsReport {
262 for (RTCPair *pair in statsReport.values) {
263 NSString *key = pair.key;
264 NSString *value = pair.value;
265 if ([key isEqualToString:@"googCodecName"]) {
266 _audioRecvCodec = value;
267 } else if ([key isEqualToString:@"bytesReceived"]) {
268 NSInteger byteCount = value.integerValue;
269 [_audioRecvBitrateTracker updateBitrateWithCurrentByteCount:byteCount];
270 _audioRecvBitrate = _audioRecvBitrateTracker.bitrateString;
271 } else if ([key isEqualToString:@"googSpeechExpandRate"]) {
272 _audioExpandRate = value;
273 } else if ([key isEqualToString:@"googCurrentDelayMs"]) {
274 _audioCurrentDelay = value;
275 }
276 }
277 }
278
279 - (void)parseVideoRecvStatsReport:(RTCStatsReport *)statsReport {
280 for (RTCPair *pair in statsReport.values) {
281 NSString *key = pair.key;
282 NSString *value = pair.value;
283 if ([key isEqualToString:@"googFrameHeightReceived"]) {
284 _videoRecvHeight = value;
285 } else if ([key isEqualToString:@"googFrameWidthReceived"]) {
286 _videoRecvWidth = value;
287 } else if ([key isEqualToString:@"googFrameRateReceived"]) {
288 _videoRecvFps = value;
289 } else if ([key isEqualToString:@"googFrameRateDecoded"]) {
290 _videoDecodedFps = value;
291 } else if ([key isEqualToString:@"googFrameRateOutput"]) {
292 _videoOutputFps = value;
293 } else if ([key isEqualToString:@"googDecodeMs"]) {
294 _videoDecodeMs = value;
295 } else if ([key isEqualToString:@"bytesReceived"]) {
296 NSInteger byteCount = value.integerValue;
297 [_videoRecvBitrateTracker updateBitrateWithCurrentByteCount:byteCount];
298 _videoRecvBitrate = _videoRecvBitrateTracker.bitrateString;
299 }
300 }
301 }
302
303 - (NSDictionary *)dictionaryForReport:(RTCStatsReport *)statsReport {
304 NSMutableDictionary *dict = [NSMutableDictionary dictionary];
305 for (RTCPair *pair in statsReport.values) {
306 NSMutableArray *values = dict[pair.key];
307 if (!values) {
308 values = [NSMutableArray arrayWithCapacity:1];
309 dict[pair.key] = values;
310 }
311 [values addObject:pair.value];
312 }
313 return dict;
314 }
315
316 @end
317
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698