Adding entry point for the v2 stats API.

Bug: webrtc:10345
Change-Id: I9271376ff60f5fc6e9014b7dd9a8a5682bdbf452
Reviewed-on: https://webrtc-review.googlesource.com/c/123780
Commit-Queue: Peter Hanspers <peterhanspers@webrtc.org>
Reviewed-by: Kári Helgason <kthelgason@webrtc.org>
Reviewed-by: Anders Carlsson <andersc@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26801}
This commit is contained in:
Peter Hanspers 2019-02-21 17:27:09 +01:00 committed by Commit Bot
parent 26451933c1
commit bed8604664
6 changed files with 275 additions and 0 deletions

View File

@ -887,6 +887,9 @@ if (is_ios || is_mac) {
"objc/api/peerconnection/RTCSessionDescription+Private.h",
"objc/api/peerconnection/RTCSessionDescription.h",
"objc/api/peerconnection/RTCSessionDescription.mm",
"objc/api/peerconnection/RTCStatisticsReport+Private.h",
"objc/api/peerconnection/RTCStatisticsReport.h",
"objc/api/peerconnection/RTCStatisticsReport.mm",
"objc/api/peerconnection/RTCTracing.h",
"objc/api/peerconnection/RTCTracing.mm",
"objc/api/peerconnection/RTCVideoTrack+Private.h",
@ -917,6 +920,7 @@ if (is_ios || is_mac) {
":videotoolbox_objc",
"../api:create_peerconnection_factory",
"../api:libjingle_peerconnection_api",
"../api:rtc_stats_api",
"../api:scoped_refptr",
"../api/audio_codecs:audio_codecs_api",
"../api/audio_codecs:builtin_audio_decoder_factory",

View File

@ -12,12 +12,29 @@
#import "RTCLegacyStatsReport+Private.h"
#import "RTCMediaStreamTrack+Private.h"
#import "RTCStatisticsReport+Private.h"
#import "helpers/NSString+StdString.h"
#include "rtc_base/checks.h"
namespace webrtc {
class StatsCollectorCallbackAdapter : public RTCStatsCollectorCallback {
public:
StatsCollectorCallbackAdapter(RTCStatisticsCompletionHandler completion_handler)
: completion_handler_(completion_handler) {}
void OnStatsDelivered(const rtc::scoped_refptr<const RTCStatsReport> &report) override {
RTC_DCHECK(completion_handler_);
RTCStatisticsReport *statisticsReport = [[RTCStatisticsReport alloc] initWithReport:*report];
completion_handler_(statisticsReport);
completion_handler_ = nil;
}
private:
RTCStatisticsCompletionHandler completion_handler_;
};
class StatsObserverAdapter : public StatsObserver {
public:
StatsObserverAdapter(void (^completionHandler)
@ -46,6 +63,12 @@ class StatsObserverAdapter : public StatsObserver {
@implementation RTCPeerConnection (Stats)
- (void)statisticsWithCompletionHandler:(RTCStatisticsCompletionHandler)completionHandler {
rtc::scoped_refptr<webrtc::StatsCollectorCallbackAdapter> collector(
new rtc::RefCountedObject<webrtc::StatsCollectorCallbackAdapter>(completionHandler));
self.nativePeerConnection->GetStats(collector);
}
- (void)statsForTrack:(RTCMediaStreamTrack *)mediaStreamTrack
statsOutputLevel:(RTCStatsOutputLevel)statsOutputLevel
completionHandler:

View File

@ -25,6 +25,7 @@
@class RTCRtpTransceiver;
@class RTCRtpTransceiverInit;
@class RTCSessionDescription;
@class RTCStatisticsReport;
@class RTCLegacyStatsReport;
typedef NS_ENUM(NSInteger, RTCRtpMediaType);
@ -316,6 +317,8 @@ RTC_OBJC_EXPORT
@end
typedef void (^RTCStatisticsCompletionHandler)(RTCStatisticsReport *);
@interface RTCPeerConnection (Stats)
/** Gather stats for the given RTCMediaStreamTrack. If |mediaStreamTrack| is nil
@ -325,6 +328,9 @@ RTC_OBJC_EXPORT
statsOutputLevel:(RTCStatsOutputLevel)statsOutputLevel
completionHandler:(nullable void (^)(NSArray<RTCLegacyStatsReport *> *stats))completionHandler;
/** Gather statistic through the v2 statistics API. */
- (void)statisticsWithCompletionHandler:(RTCStatisticsCompletionHandler)completionHandler;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,19 @@
/*
* Copyright 2019 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.
*/
#import "RTCStatisticsReport.h"
#include "api/stats/rtc_stats_report.h"
@interface RTCStatisticsReport (Private)
- (instancetype)initWithReport:(const webrtc::RTCStatsReport &)report;
@end

View File

@ -0,0 +1,51 @@
/*
* Copyright 2019 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.
*/
#import <Foundation/Foundation.h>
@class RTCStatistics;
NS_ASSUME_NONNULL_BEGIN
/** A statistics report. Encapsulates a number of RTCStatistics objects. */
@interface RTCStatisticsReport : NSObject
/** The timestamp of the report in microseconds since 1970-01-01T00:00:00Z. */
@property(nonatomic, readonly) CFTimeInterval timestamp_us;
/** RTCStatistics objects by id. */
@property(nonatomic, readonly) NSDictionary<NSString *, RTCStatistics *> *statistics;
- (instancetype)init NS_UNAVAILABLE;
@end
/** A part of a report (a subreport) covering a certain area. */
@interface RTCStatistics : NSObject
/** The id of this subreport, e.g. "RTCMediaStreamTrack_receiver_2". */
@property(nonatomic, readonly) NSString *id;
/** The timestamp of the subreport in microseconds since 1970-01-01T00:00:00Z. */
@property(nonatomic, readonly) CFTimeInterval timestamp_us;
/** The type of the subreport, e.g. "track", "codec". */
@property(nonatomic, readonly) NSString *type;
/** The keys and values of the subreport, e.g. "totalFramesDuration = 5.551".
The values are either NSNumbers or NSStrings, or NSArrays encapsulating NSNumbers
or NSStrings. */
@property(nonatomic, readonly) NSDictionary<NSString *, NSObject *> *values;
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,172 @@
/*
* Copyright 2019 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.
*/
#import "RTCStatisticsReport+Private.h"
#include "helpers/NSString+StdString.h"
#include "rtc_base/checks.h"
namespace webrtc {
/** Converts a single value to a suitable NSNumber, NSString or NSArray containing NSNumbers
or NSStrings.*/
NSObject *ValueFromStatsMember(const RTCStatsMemberInterface *member) {
if (member->is_defined()) {
switch (member->type()) {
case RTCStatsMemberInterface::kBool:
return [NSNumber numberWithBool:*member->cast_to<RTCStatsMember<bool>>()];
case RTCStatsMemberInterface::kInt32:
return [NSNumber numberWithInt:*member->cast_to<RTCStatsMember<int32_t>>()];
case RTCStatsMemberInterface::kUint32:
return [NSNumber numberWithUnsignedInt:*member->cast_to<RTCStatsMember<uint32_t>>()];
case RTCStatsMemberInterface::kInt64:
return [NSNumber numberWithLong:*member->cast_to<RTCStatsMember<int64_t>>()];
case RTCStatsMemberInterface::kUint64:
return [NSNumber numberWithUnsignedLong:*member->cast_to<RTCStatsMember<uint64_t>>()];
case RTCStatsMemberInterface::kDouble:
return [NSNumber numberWithDouble:*member->cast_to<RTCStatsMember<double>>()];
case RTCStatsMemberInterface::kString:
return [NSString stringForStdString:*member->cast_to<RTCStatsMember<std::string>>()];
case RTCStatsMemberInterface::kSequenceBool: {
std::vector<bool> sequence = *member->cast_to<RTCStatsMember<std::vector<bool>>>();
NSMutableArray *array = [NSMutableArray arrayWithCapacity:sequence.size()];
for (const auto &item : sequence) {
[array addObject:[NSNumber numberWithBool:item]];
}
return [array copy];
}
case RTCStatsMemberInterface::kSequenceInt32: {
std::vector<int32_t> sequence = *member->cast_to<RTCStatsMember<std::vector<int32_t>>>();
NSMutableArray<NSNumber *> *array = [NSMutableArray arrayWithCapacity:sequence.size()];
for (const auto &item : sequence) {
[array addObject:[NSNumber numberWithInt:item]];
}
return [array copy];
}
case RTCStatsMemberInterface::kSequenceUint32: {
std::vector<uint32_t> sequence = *member->cast_to<RTCStatsMember<std::vector<uint32_t>>>();
NSMutableArray<NSNumber *> *array = [NSMutableArray arrayWithCapacity:sequence.size()];
for (const auto &item : sequence) {
[array addObject:[NSNumber numberWithUnsignedInt:item]];
}
return [array copy];
}
case RTCStatsMemberInterface::kSequenceInt64: {
std::vector<int64_t> sequence = *member->cast_to<RTCStatsMember<std::vector<int64_t>>>();
NSMutableArray<NSNumber *> *array = [NSMutableArray arrayWithCapacity:sequence.size()];
for (const auto &item : sequence) {
[array addObject:[NSNumber numberWithLong:item]];
}
return [array copy];
}
case RTCStatsMemberInterface::kSequenceUint64: {
std::vector<uint64_t> sequence = *member->cast_to<RTCStatsMember<std::vector<uint64_t>>>();
NSMutableArray<NSNumber *> *array = [NSMutableArray arrayWithCapacity:sequence.size()];
for (const auto &item : sequence) {
[array addObject:[NSNumber numberWithUnsignedLong:item]];
}
return [array copy];
}
case RTCStatsMemberInterface::kSequenceDouble: {
std::vector<double> sequence = *member->cast_to<RTCStatsMember<std::vector<double>>>();
NSMutableArray<NSNumber *> *array = [NSMutableArray arrayWithCapacity:sequence.size()];
for (const auto &item : sequence) {
[array addObject:[NSNumber numberWithDouble:item]];
}
return [array copy];
}
case RTCStatsMemberInterface::kSequenceString: {
std::vector<std::string> sequence =
*member->cast_to<RTCStatsMember<std::vector<std::string>>>();
NSMutableArray<NSString *> *array = [NSMutableArray arrayWithCapacity:sequence.size()];
for (const auto &item : sequence) {
[array addObject:[NSString stringForStdString:item]];
}
return [array copy];
}
default:
RTC_NOTREACHED();
}
}
return nil;
}
} // namespace webrtc
@implementation RTCStatistics
@synthesize id = _id;
@synthesize timestamp_us = _timestamp_us;
@synthesize type = _type;
@synthesize values = _values;
- (instancetype)initWithStatistics:(const webrtc::RTCStats &)statistics {
if (self = [super init]) {
_id = [NSString stringForStdString:statistics.id()];
_timestamp_us = statistics.timestamp_us();
_type = [NSString stringWithCString:statistics.type() encoding:NSUTF8StringEncoding];
NSMutableDictionary<NSString *, NSObject *> *values = [NSMutableDictionary dictionary];
for (const webrtc::RTCStatsMemberInterface *member : statistics.Members()) {
NSObject *value = ValueFromStatsMember(member);
if (value) {
NSString *name = [NSString stringWithCString:member->name() encoding:NSUTF8StringEncoding];
RTC_DCHECK(name.length > 0);
RTC_DCHECK(!values[name]);
values[name] = value;
}
}
_values = [values copy];
}
return self;
}
- (NSString *)description {
return [NSString stringWithFormat:@"id = %@, type = %@, timestamp = %.0f, values = %@",
self.id,
self.type,
self.timestamp_us,
self.values];
}
@end
@implementation RTCStatisticsReport
@synthesize timestamp_us = _timestamp_us;
@synthesize statistics = _statistics;
- (NSString *)description {
return [NSString
stringWithFormat:@"timestamp = %.0f, statistics = %@", self.timestamp_us, self.statistics];
}
@end
@implementation RTCStatisticsReport (Private)
- (instancetype)initWithReport:(const webrtc::RTCStatsReport &)report {
if (self = [super init]) {
_timestamp_us = report.timestamp_us();
NSMutableDictionary *statisticsById =
[NSMutableDictionary dictionaryWithCapacity:report.size()];
for (const auto &stat : report) {
RTCStatistics *statistics = [[RTCStatistics alloc] initWithStatistics:stat];
statisticsById[statistics.id] = statistics;
}
_statistics = [statisticsById copy];
}
return self;
}
@end