OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2015 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #import "ARDStatsBuilder.h" | 11 #import "ARDStatsBuilder.h" |
12 | 12 |
13 #import "RTCPair.h" | 13 #import "webrtc/api/objc/RTCStatsReport.h" |
14 #import "RTCStatsReport.h" | |
15 | 14 |
16 #import "ARDBitrateTracker.h" | 15 #import "ARDBitrateTracker.h" |
17 #import "ARDUtilities.h" | 16 #import "ARDUtilities.h" |
18 | 17 |
19 @implementation ARDStatsBuilder { | 18 @implementation ARDStatsBuilder { |
20 // Connection stats. | 19 // Connection stats. |
21 NSString *_connRecvBitrate; | 20 NSString *_connRecvBitrate; |
22 NSString *_connRtt; | 21 NSString *_connRtt; |
23 NSString *_connSendBitrate; | 22 NSString *_connSendBitrate; |
24 NSString *_localCandType; | 23 NSString *_localCandType; |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 } else if ([reportType isEqualToString:@"VideoBwe"]) { | 142 } else if ([reportType isEqualToString:@"VideoBwe"]) { |
144 [self parseBweStatsReport:statsReport]; | 143 [self parseBweStatsReport:statsReport]; |
145 } else if ([reportType isEqualToString:@"googCandidatePair"]) { | 144 } else if ([reportType isEqualToString:@"googCandidatePair"]) { |
146 [self parseConnectionStatsReport:statsReport]; | 145 [self parseConnectionStatsReport:statsReport]; |
147 } | 146 } |
148 } | 147 } |
149 | 148 |
150 #pragma mark - Private | 149 #pragma mark - Private |
151 | 150 |
152 - (void)parseBweStatsReport:(RTCStatsReport *)statsReport { | 151 - (void)parseBweStatsReport:(RTCStatsReport *)statsReport { |
153 for (RTCPair *pair in statsReport.values) { | 152 [statsReport.values enumerateKeysAndObjectsUsingBlock:^( |
154 NSString *key = pair.key; | 153 NSString *key, NSString *value, BOOL *stop) { |
155 NSString *value = pair.value; | |
156 if ([key isEqualToString:@"googAvailableSendBandwidth"]) { | 154 if ([key isEqualToString:@"googAvailableSendBandwidth"]) { |
157 _availableSendBw = | 155 _availableSendBw = |
158 [ARDBitrateTracker bitrateStringForBitrate:value.doubleValue]; | 156 [ARDBitrateTracker bitrateStringForBitrate:value.doubleValue]; |
159 } else if ([key isEqualToString:@"googAvailableReceiveBandwidth"]) { | 157 } else if ([key isEqualToString:@"googAvailableReceiveBandwidth"]) { |
160 _availableRecvBw = | 158 _availableRecvBw = |
161 [ARDBitrateTracker bitrateStringForBitrate:value.doubleValue]; | 159 [ARDBitrateTracker bitrateStringForBitrate:value.doubleValue]; |
162 } else if ([key isEqualToString:@"googActualEncBitrate"]) { | 160 } else if ([key isEqualToString:@"googActualEncBitrate"]) { |
163 _actualEncBitrate = | 161 _actualEncBitrate = |
164 [ARDBitrateTracker bitrateStringForBitrate:value.doubleValue]; | 162 [ARDBitrateTracker bitrateStringForBitrate:value.doubleValue]; |
165 } else if ([key isEqualToString:@"googTargetEncBitrate"]) { | 163 } else if ([key isEqualToString:@"googTargetEncBitrate"]) { |
166 _targetEncBitrate = | 164 _targetEncBitrate = |
167 [ARDBitrateTracker bitrateStringForBitrate:value.doubleValue]; | 165 [ARDBitrateTracker bitrateStringForBitrate:value.doubleValue]; |
168 } | 166 } |
169 } | 167 }]; |
170 } | 168 } |
171 | 169 |
172 - (void)parseConnectionStatsReport:(RTCStatsReport *)statsReport { | 170 - (void)parseConnectionStatsReport:(RTCStatsReport *)statsReport { |
173 NSDictionary *values = [self dictionaryForReport:statsReport]; | 171 NSString *activeConnection = statsReport.values[@"googActiveConnection"]; |
174 NSString *activeConnection = [values[@"googActiveConnection"] firstObject]; | |
175 if (![activeConnection isEqualToString:@"true"]) { | 172 if (![activeConnection isEqualToString:@"true"]) { |
176 return; | 173 return; |
177 } | 174 } |
178 for (RTCPair *pair in statsReport.values) { | 175 [statsReport.values enumerateKeysAndObjectsUsingBlock:^( |
179 NSString *key = pair.key; | 176 NSString *key, NSString *value, BOOL *stop) { |
180 NSString *value = pair.value; | |
181 if ([key isEqualToString:@"googRtt"]) { | 177 if ([key isEqualToString:@"googRtt"]) { |
182 _connRtt = value; | 178 _connRtt = value; |
183 } else if ([key isEqualToString:@"googLocalCandidateType"]) { | 179 } else if ([key isEqualToString:@"googLocalCandidateType"]) { |
184 _localCandType = value; | 180 _localCandType = value; |
185 } else if ([key isEqualToString:@"googRemoteCandidateType"]) { | 181 } else if ([key isEqualToString:@"googRemoteCandidateType"]) { |
186 _remoteCandType = value; | 182 _remoteCandType = value; |
187 } else if ([key isEqualToString:@"googTransportType"]) { | 183 } else if ([key isEqualToString:@"googTransportType"]) { |
188 _transportType = value; | 184 _transportType = value; |
189 } else if ([key isEqualToString:@"bytesReceived"]) { | 185 } else if ([key isEqualToString:@"bytesReceived"]) { |
190 NSInteger byteCount = value.integerValue; | 186 NSInteger byteCount = value.integerValue; |
191 [_connRecvBitrateTracker updateBitrateWithCurrentByteCount:byteCount]; | 187 [_connRecvBitrateTracker updateBitrateWithCurrentByteCount:byteCount]; |
192 _connRecvBitrate = _connRecvBitrateTracker.bitrateString; | 188 _connRecvBitrate = _connRecvBitrateTracker.bitrateString; |
193 } else if ([key isEqualToString:@"bytesSent"]) { | 189 } else if ([key isEqualToString:@"bytesSent"]) { |
194 NSInteger byteCount = value.integerValue; | 190 NSInteger byteCount = value.integerValue; |
195 [_connSendBitrateTracker updateBitrateWithCurrentByteCount:byteCount]; | 191 [_connSendBitrateTracker updateBitrateWithCurrentByteCount:byteCount]; |
196 _connSendBitrate = _connSendBitrateTracker.bitrateString; | 192 _connSendBitrate = _connSendBitrateTracker.bitrateString; |
197 } | 193 } |
198 } | 194 }]; |
199 } | 195 } |
200 | 196 |
201 - (void)parseSendSsrcStatsReport:(RTCStatsReport *)statsReport { | 197 - (void)parseSendSsrcStatsReport:(RTCStatsReport *)statsReport { |
202 NSDictionary *values = [self dictionaryForReport:statsReport]; | 198 NSDictionary *values = statsReport.values; |
203 NSString *trackId = [values[@"googTrackId"] firstObject]; | 199 NSString *trackId = values[@"googTrackId"]; |
204 if (trackId.length && [trackId hasPrefix:@"ARDAMSv0"]) { | 200 if (trackId.length && [trackId hasPrefix:@"ARDAMSv0"]) { |
205 // Video track. | 201 // Video track. |
206 [self parseVideoSendStatsReport:statsReport]; | 202 [self parseVideoSendStatsReport:statsReport]; |
207 } else { | 203 } else { |
208 // Audio track. | 204 // Audio track. |
209 [self parseAudioSendStatsReport:statsReport]; | 205 [self parseAudioSendStatsReport:statsReport]; |
210 } | 206 } |
211 } | 207 } |
212 | 208 |
213 - (void)parseAudioSendStatsReport:(RTCStatsReport *)statsReport { | 209 - (void)parseAudioSendStatsReport:(RTCStatsReport *)statsReport { |
214 for (RTCPair *pair in statsReport.values) { | 210 [statsReport.values enumerateKeysAndObjectsUsingBlock:^( |
215 NSString *key = pair.key; | 211 NSString *key, NSString *value, BOOL *stop) { |
216 NSString *value = pair.value; | |
217 if ([key isEqualToString:@"googCodecName"]) { | 212 if ([key isEqualToString:@"googCodecName"]) { |
218 _audioSendCodec = value; | 213 _audioSendCodec = value; |
219 } else if ([key isEqualToString:@"bytesSent"]) { | 214 } else if ([key isEqualToString:@"bytesSent"]) { |
220 NSInteger byteCount = value.integerValue; | 215 NSInteger byteCount = value.integerValue; |
221 [_audioSendBitrateTracker updateBitrateWithCurrentByteCount:byteCount]; | 216 [_audioSendBitrateTracker updateBitrateWithCurrentByteCount:byteCount]; |
222 _audioSendBitrate = _audioSendBitrateTracker.bitrateString; | 217 _audioSendBitrate = _audioSendBitrateTracker.bitrateString; |
223 } | 218 } |
224 } | 219 }]; |
225 } | 220 } |
226 | 221 |
227 - (void)parseVideoSendStatsReport:(RTCStatsReport *)statsReport { | 222 - (void)parseVideoSendStatsReport:(RTCStatsReport *)statsReport { |
228 for (RTCPair *pair in statsReport.values) { | 223 [statsReport.values enumerateKeysAndObjectsUsingBlock:^( |
229 NSString *key = pair.key; | 224 NSString *key, NSString *value, BOOL *stop) { |
230 NSString *value = pair.value; | |
231 if ([key isEqualToString:@"googCodecName"]) { | 225 if ([key isEqualToString:@"googCodecName"]) { |
232 _videoSendCodec = value; | 226 _videoSendCodec = value; |
233 } else if ([key isEqualToString:@"googFrameHeightInput"]) { | 227 } else if ([key isEqualToString:@"googFrameHeightInput"]) { |
234 _videoInputHeight = value; | 228 _videoInputHeight = value; |
235 } else if ([key isEqualToString:@"googFrameWidthInput"]) { | 229 } else if ([key isEqualToString:@"googFrameWidthInput"]) { |
236 _videoInputWidth = value; | 230 _videoInputWidth = value; |
237 } else if ([key isEqualToString:@"googFrameRateInput"]) { | 231 } else if ([key isEqualToString:@"googFrameRateInput"]) { |
238 _videoInputFps = value; | 232 _videoInputFps = value; |
239 } else if ([key isEqualToString:@"googFrameHeightSent"]) { | 233 } else if ([key isEqualToString:@"googFrameHeightSent"]) { |
240 _videoSendHeight = value; | 234 _videoSendHeight = value; |
241 } else if ([key isEqualToString:@"googFrameWidthSent"]) { | 235 } else if ([key isEqualToString:@"googFrameWidthSent"]) { |
242 _videoSendWidth = value; | 236 _videoSendWidth = value; |
243 } else if ([key isEqualToString:@"googFrameRateSent"]) { | 237 } else if ([key isEqualToString:@"googFrameRateSent"]) { |
244 _videoSendFps = value; | 238 _videoSendFps = value; |
245 } else if ([key isEqualToString:@"googAvgEncodeMs"]) { | 239 } else if ([key isEqualToString:@"googAvgEncodeMs"]) { |
246 _videoEncodeMs = value; | 240 _videoEncodeMs = value; |
247 } else if ([key isEqualToString:@"bytesSent"]) { | 241 } else if ([key isEqualToString:@"bytesSent"]) { |
248 NSInteger byteCount = value.integerValue; | 242 NSInteger byteCount = value.integerValue; |
249 [_videoSendBitrateTracker updateBitrateWithCurrentByteCount:byteCount]; | 243 [_videoSendBitrateTracker updateBitrateWithCurrentByteCount:byteCount]; |
250 _videoSendBitrate = _videoSendBitrateTracker.bitrateString; | 244 _videoSendBitrate = _videoSendBitrateTracker.bitrateString; |
251 } | 245 } |
252 } | 246 }]; |
253 } | 247 } |
254 | 248 |
255 - (void)parseRecvSsrcStatsReport:(RTCStatsReport *)statsReport { | 249 - (void)parseRecvSsrcStatsReport:(RTCStatsReport *)statsReport { |
256 NSDictionary *values = [self dictionaryForReport:statsReport]; | 250 NSDictionary *values = statsReport.values; |
257 NSString *transportId = [values[@"transportId"] firstObject]; | 251 if (values[@"googFrameWidthReceived"]) { |
258 if ([values[@"googFrameWidthReceived"] firstObject]) { | |
259 [self parseVideoRecvStatsReport:statsReport]; | 252 [self parseVideoRecvStatsReport:statsReport]; |
260 } else { | 253 } else { |
261 [self parseAudioRecvStatsReport:statsReport]; | 254 [self parseAudioRecvStatsReport:statsReport]; |
262 } | 255 } |
263 } | 256 } |
264 | 257 |
265 - (void)parseAudioRecvStatsReport:(RTCStatsReport *)statsReport { | 258 - (void)parseAudioRecvStatsReport:(RTCStatsReport *)statsReport { |
266 for (RTCPair *pair in statsReport.values) { | 259 [statsReport.values enumerateKeysAndObjectsUsingBlock:^( |
267 NSString *key = pair.key; | 260 NSString *key, NSString *value, BOOL *stop) { |
268 NSString *value = pair.value; | |
269 if ([key isEqualToString:@"googCodecName"]) { | 261 if ([key isEqualToString:@"googCodecName"]) { |
270 _audioRecvCodec = value; | 262 _audioRecvCodec = value; |
271 } else if ([key isEqualToString:@"bytesReceived"]) { | 263 } else if ([key isEqualToString:@"bytesReceived"]) { |
272 NSInteger byteCount = value.integerValue; | 264 NSInteger byteCount = value.integerValue; |
273 [_audioRecvBitrateTracker updateBitrateWithCurrentByteCount:byteCount]; | 265 [_audioRecvBitrateTracker updateBitrateWithCurrentByteCount:byteCount]; |
274 _audioRecvBitrate = _audioRecvBitrateTracker.bitrateString; | 266 _audioRecvBitrate = _audioRecvBitrateTracker.bitrateString; |
275 } else if ([key isEqualToString:@"googSpeechExpandRate"]) { | 267 } else if ([key isEqualToString:@"googSpeechExpandRate"]) { |
276 _audioExpandRate = value; | 268 _audioExpandRate = value; |
277 } else if ([key isEqualToString:@"googCurrentDelayMs"]) { | 269 } else if ([key isEqualToString:@"googCurrentDelayMs"]) { |
278 _audioCurrentDelay = value; | 270 _audioCurrentDelay = value; |
279 } | 271 } |
280 } | 272 }]; |
281 } | 273 } |
282 | 274 |
283 - (void)parseVideoRecvStatsReport:(RTCStatsReport *)statsReport { | 275 - (void)parseVideoRecvStatsReport:(RTCStatsReport *)statsReport { |
284 for (RTCPair *pair in statsReport.values) { | 276 [statsReport.values enumerateKeysAndObjectsUsingBlock:^( |
285 NSString *key = pair.key; | 277 NSString *key, NSString *value, BOOL *stop) { |
286 NSString *value = pair.value; | |
287 if ([key isEqualToString:@"googFrameHeightReceived"]) { | 278 if ([key isEqualToString:@"googFrameHeightReceived"]) { |
288 _videoRecvHeight = value; | 279 _videoRecvHeight = value; |
289 } else if ([key isEqualToString:@"googFrameWidthReceived"]) { | 280 } else if ([key isEqualToString:@"googFrameWidthReceived"]) { |
290 _videoRecvWidth = value; | 281 _videoRecvWidth = value; |
291 } else if ([key isEqualToString:@"googFrameRateReceived"]) { | 282 } else if ([key isEqualToString:@"googFrameRateReceived"]) { |
292 _videoRecvFps = value; | 283 _videoRecvFps = value; |
293 } else if ([key isEqualToString:@"googFrameRateDecoded"]) { | 284 } else if ([key isEqualToString:@"googFrameRateDecoded"]) { |
294 _videoDecodedFps = value; | 285 _videoDecodedFps = value; |
295 } else if ([key isEqualToString:@"googFrameRateOutput"]) { | 286 } else if ([key isEqualToString:@"googFrameRateOutput"]) { |
296 _videoOutputFps = value; | 287 _videoOutputFps = value; |
297 } else if ([key isEqualToString:@"googDecodeMs"]) { | 288 } else if ([key isEqualToString:@"googDecodeMs"]) { |
298 _videoDecodeMs = value; | 289 _videoDecodeMs = value; |
299 } else if ([key isEqualToString:@"bytesReceived"]) { | 290 } else if ([key isEqualToString:@"bytesReceived"]) { |
300 NSInteger byteCount = value.integerValue; | 291 NSInteger byteCount = value.integerValue; |
301 [_videoRecvBitrateTracker updateBitrateWithCurrentByteCount:byteCount]; | 292 [_videoRecvBitrateTracker updateBitrateWithCurrentByteCount:byteCount]; |
302 _videoRecvBitrate = _videoRecvBitrateTracker.bitrateString; | 293 _videoRecvBitrate = _videoRecvBitrateTracker.bitrateString; |
303 } | 294 } |
304 } | 295 }]; |
305 } | |
306 | |
307 - (NSDictionary *)dictionaryForReport:(RTCStatsReport *)statsReport { | |
308 NSMutableDictionary *dict = [NSMutableDictionary dictionary]; | |
309 for (RTCPair *pair in statsReport.values) { | |
310 NSMutableArray *values = dict[pair.key]; | |
311 if (!values) { | |
312 values = [NSMutableArray arrayWithCapacity:1]; | |
313 dict[pair.key] = values; | |
314 } | |
315 [values addObject:pair.value]; | |
316 } | |
317 return dict; | |
318 } | 296 } |
319 | 297 |
320 @end | 298 @end |
321 | 299 |
OLD | NEW |