Objective C API to read and set RtpParameters
This change adds the Objective C API functions to get and set RtpSender's
RtpParameters, which allows setting bitrate limits for audio and video and
turning off RtpSenders to pre-initialize the encoder.
This CL adds only the smallest set of methods required to support bitrate
limiting - there is no way to create an RtpSender, for example, or to set
its track. The only supported functionality is this:
RTCPeerConnection.senders - a read-only property returning the array
of all RTCRtpSenders for the connection.
RTCRtpSender.parameters - a read-only property returning the current
parameters
RTCRtpSender.setParameters: - a method to change the parameters.
RTCRtpSender.track - a read-only property returning the
RTCMediaStreamTrack corresponding to the sender. It is necessary
to be able to identify RTCRtpSenders for video and audio. The
track object is of the base RTCMediaStreamTrack type, not of the
specific subclass for audio and video - just like it is in the
Java API.
BUG=
Review URL: https://codereview.webrtc.org/1854393002
Cr-Commit-Position: refs/heads/master@{#12297}
diff --git a/webrtc/api/objc/RTCMediaStreamTrack+Private.h b/webrtc/api/objc/RTCMediaStreamTrack+Private.h
index 155e312..4fff1f8 100644
--- a/webrtc/api/objc/RTCMediaStreamTrack+Private.h
+++ b/webrtc/api/objc/RTCMediaStreamTrack+Private.h
@@ -37,6 +37,11 @@
type:(RTCMediaStreamTrackType)type
NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithNativeTrack:
+ (rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)nativeTrack;
+
+- (BOOL)isEqualToTrack:(RTCMediaStreamTrack *)track;
+
+ (webrtc::MediaStreamTrackInterface::TrackState)nativeTrackStateForState:
(RTCMediaStreamTrackState)state;
diff --git a/webrtc/api/objc/RTCMediaStreamTrack.mm b/webrtc/api/objc/RTCMediaStreamTrack.mm
index 25979b3..7f24c94 100644
--- a/webrtc/api/objc/RTCMediaStreamTrack.mm
+++ b/webrtc/api/objc/RTCMediaStreamTrack.mm
@@ -47,6 +47,20 @@
readyState];
}
+- (BOOL)isEqual:(id)object {
+ if (self == object) {
+ return YES;
+ }
+ if (![object isMemberOfClass:[self class]]) {
+ return NO;
+ }
+ return [self isEqualToTrack:(RTCMediaStreamTrack *)object];
+}
+
+- (NSUInteger)hash {
+ return (NSUInteger)_nativeTrack.get();
+}
+
#pragma mark - Private
- (rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)nativeTrack {
@@ -64,6 +78,29 @@
return self;
}
+- (instancetype)initWithNativeTrack:
+ (rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)nativeTrack {
+ NSParameterAssert(nativeTrack);
+ if (nativeTrack->kind() ==
+ std::string(webrtc::MediaStreamTrackInterface::kAudioKind)) {
+ return [self initWithNativeTrack:nativeTrack
+ type:RTCMediaStreamTrackTypeAudio];
+ }
+ if (nativeTrack->kind() ==
+ std::string(webrtc::MediaStreamTrackInterface::kVideoKind)) {
+ return [self initWithNativeTrack:nativeTrack
+ type:RTCMediaStreamTrackTypeVideo];
+ }
+ return nil;
+}
+
+- (BOOL)isEqualToTrack:(RTCMediaStreamTrack *)track {
+ if (!track) {
+ return NO;
+ }
+ return _nativeTrack == track.nativeTrack;
+}
+
+ (webrtc::MediaStreamTrackInterface::TrackState)nativeTrackStateForState:
(RTCMediaStreamTrackState)state {
switch (state) {
diff --git a/webrtc/api/objc/RTCPeerConnection.h b/webrtc/api/objc/RTCPeerConnection.h
index e0f9b78..471a8de 100644
--- a/webrtc/api/objc/RTCPeerConnection.h
+++ b/webrtc/api/objc/RTCPeerConnection.h
@@ -18,6 +18,7 @@
@class RTCMediaStream;
@class RTCMediaStreamTrack;
@class RTCPeerConnectionFactory;
+@class RTCRtpSender;
@class RTCSessionDescription;
@class RTCStatsReport;
@@ -115,6 +116,12 @@
@property(nonatomic, readonly) RTCIceConnectionState iceConnectionState;
@property(nonatomic, readonly) RTCIceGatheringState iceGatheringState;
+/** Gets all RTCRtpSenders associated with this peer connection.
+ * Note: reading this property returns different instances of RTCRtpSender.
+ * Use isEqual: instead of == to compare RTCRtpSender instances.
+ */
+@property(nonatomic, readonly) NSArray<RTCRtpSender *> *senders;
+
- (instancetype)init NS_UNAVAILABLE;
/** Sets the PeerConnection's global configuration to |configuration|.
diff --git a/webrtc/api/objc/RTCPeerConnection.mm b/webrtc/api/objc/RTCPeerConnection.mm
index 50d05f1..657ba57 100644
--- a/webrtc/api/objc/RTCPeerConnection.mm
+++ b/webrtc/api/objc/RTCPeerConnection.mm
@@ -19,6 +19,7 @@
#import "webrtc/api/objc/RTCMediaConstraints+Private.h"
#import "webrtc/api/objc/RTCMediaStream+Private.h"
#import "webrtc/api/objc/RTCPeerConnectionFactory+Private.h"
+#import "webrtc/api/objc/RTCRtpSender+Private.h"
#import "webrtc/api/objc/RTCSessionDescription+Private.h"
#import "webrtc/api/objc/RTCStatsReport+Private.h"
#import "webrtc/base/objc/RTCLogging.h"
@@ -311,6 +312,18 @@
_peerConnection->SetRemoteDescription(observer, sdp.nativeDescription);
}
+- (NSArray<RTCRtpSender *> *)senders {
+ std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenders(
+ _peerConnection->GetSenders());
+ NSMutableArray *senders = [[NSMutableArray alloc] init];
+ for (const auto &nativeSender : nativeSenders) {
+ RTCRtpSender *sender =
+ [[RTCRtpSender alloc] initWithNativeRtpSender:nativeSender];
+ [senders addObject:sender];
+ }
+ return senders;
+}
+
#pragma mark - Private
+ (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState:
diff --git a/webrtc/api/objc/RTCRtpEncodingParameters+Private.h b/webrtc/api/objc/RTCRtpEncodingParameters+Private.h
new file mode 100644
index 0000000..9b752d2
--- /dev/null
+++ b/webrtc/api/objc/RTCRtpEncodingParameters+Private.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2016 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>
+
+#import "webrtc/api/objc/RTCRtpEncodingParameters.h"
+
+#include "webrtc/api/rtpparameters.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface RTCRtpEncodingParameters ()
+
+/** Returns the equivalent native RtpEncodingParameters structure. */
+@property(nonatomic, readonly) webrtc::RtpEncodingParameters nativeParameters;
+
+/** Initialize the object with a native RtpEncodingParameters structure. */
+- (instancetype)initWithNativeParameters:
+ (const webrtc::RtpEncodingParameters &)nativeParameters;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/webrtc/api/objc/RTCRtpEncodingParameters.h b/webrtc/api/objc/RTCRtpEncodingParameters.h
new file mode 100644
index 0000000..8f7f22e
--- /dev/null
+++ b/webrtc/api/objc/RTCRtpEncodingParameters.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2016 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>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface RTCRtpEncodingParameters : NSObject
+
+/** Controls whether the encoding is currently transmitted. */
+@property(nonatomic, assign) BOOL isActive;
+
+/** The maximum bitrate to use for the encoding, or nil if there is no
+ * limit.
+ */
+@property(nonatomic, copy, nullable) NSNumber *maxBitrateBps;
+
+- (instancetype)init NS_DESIGNATED_INITIALIZER;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/webrtc/api/objc/RTCRtpEncodingParameters.mm b/webrtc/api/objc/RTCRtpEncodingParameters.mm
new file mode 100644
index 0000000..af07a04
--- /dev/null
+++ b/webrtc/api/objc/RTCRtpEncodingParameters.mm
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2016 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 "RTCRtpEncodingParameters+Private.h"
+
+@implementation RTCRtpEncodingParameters
+
+@synthesize isActive = _isActive;
+@synthesize maxBitrateBps = _maxBitrateBps;
+
+static const int kBitrateUnlimited = -1;
+
+- (instancetype)init {
+ return [super init];
+}
+
+- (instancetype)initWithNativeParameters:
+ (const webrtc::RtpEncodingParameters &)nativeParameters {
+ if (self = [self init]) {
+ _isActive = nativeParameters.active;
+ // TODO(skvlad): Replace with rtc::Optional once the C++ code is updated.
+ if (nativeParameters.max_bitrate_bps != kBitrateUnlimited) {
+ _maxBitrateBps =
+ [NSNumber numberWithInt:nativeParameters.max_bitrate_bps];
+ }
+ }
+ return self;
+}
+
+- (webrtc::RtpEncodingParameters)nativeParameters {
+ webrtc::RtpEncodingParameters parameters;
+ parameters.active = _isActive;
+ if (_maxBitrateBps != nil) {
+ parameters.max_bitrate_bps = _maxBitrateBps.intValue;
+ }
+ return parameters;
+}
+
+@end
diff --git a/webrtc/api/objc/RTCRtpParameters+Private.h b/webrtc/api/objc/RTCRtpParameters+Private.h
new file mode 100644
index 0000000..e037033
--- /dev/null
+++ b/webrtc/api/objc/RTCRtpParameters+Private.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2016 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>
+
+#import "webrtc/api/objc/RTCRtpParameters.h"
+
+#include "webrtc/api/rtpparameters.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface RTCRtpParameters ()
+
+/** Returns the equivalent native RtpParameters structure. */
+@property(nonatomic, readonly) webrtc::RtpParameters nativeParameters;
+
+/** Initialize the object with a native RtpParameters structure. */
+- (instancetype)initWithNativeParameters:
+ (const webrtc::RtpParameters &)nativeParameters;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/webrtc/api/objc/RTCRtpParameters.h b/webrtc/api/objc/RTCRtpParameters.h
new file mode 100644
index 0000000..d38e9ef
--- /dev/null
+++ b/webrtc/api/objc/RTCRtpParameters.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2016 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>
+
+#import "webrtc/api/objc/RTCRtpEncodingParameters.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface RTCRtpParameters : NSObject
+
+/** The currently active encodings in the order of preference. */
+@property(nonatomic, copy) NSArray<RTCRtpEncodingParameters *> *encodings;
+
+- (instancetype)init NS_DESIGNATED_INITIALIZER;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/webrtc/api/objc/RTCRtpParameters.mm b/webrtc/api/objc/RTCRtpParameters.mm
new file mode 100644
index 0000000..e8c4a44
--- /dev/null
+++ b/webrtc/api/objc/RTCRtpParameters.mm
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2016 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 "RTCRtpParameters+Private.h"
+#import "RTCRtpEncodingParameters+Private.h"
+
+@implementation RTCRtpParameters
+
+@synthesize encodings = _encodings;
+
+- (instancetype)init {
+ return [super init];
+}
+
+- (instancetype)initWithNativeParameters:
+ (const webrtc::RtpParameters &)nativeParameters {
+ if (self = [self init]) {
+ NSMutableArray *encodings = [[NSMutableArray alloc] init];
+ for (const auto &encoding : nativeParameters.encodings) {
+ [encodings addObject:[[RTCRtpEncodingParameters alloc]
+ initWithNativeParameters:encoding]];
+ }
+ _encodings = encodings;
+ }
+ return self;
+}
+
+- (webrtc::RtpParameters)nativeParameters {
+ webrtc::RtpParameters parameters;
+ for (RTCRtpEncodingParameters *encoding in _encodings) {
+ parameters.encodings.push_back(encoding.nativeParameters);
+ }
+ return parameters;
+}
+
+@end
diff --git a/webrtc/api/objc/RTCRtpSender+Private.h b/webrtc/api/objc/RTCRtpSender+Private.h
new file mode 100644
index 0000000..1954195
--- /dev/null
+++ b/webrtc/api/objc/RTCRtpSender+Private.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2016 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 "RTCRtpSender.h"
+
+#include "webrtc/api/rtpsenderinterface.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface RTCRtpSender ()
+
+/** Initialize an RTCRtpSender with a native RtpSenderInterface. */
+- (instancetype)initWithNativeRtpSender:
+ (rtc::scoped_refptr<webrtc::RtpSenderInterface>)nativeRtpSender
+ NS_DESIGNATED_INITIALIZER;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/webrtc/api/objc/RTCRtpSender.h b/webrtc/api/objc/RTCRtpSender.h
new file mode 100644
index 0000000..c7108fa
--- /dev/null
+++ b/webrtc/api/objc/RTCRtpSender.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2016 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>
+
+#import "webrtc/api/objc/RTCRtpParameters.h"
+#import "webrtc/api/objc/RTCMediaStreamTrack.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@protocol RTCRtpSender <NSObject>
+
+/** The currently active RTCRtpParameters, as defined in
+ * https://www.w3.org/TR/webrtc/#idl-def-RTCRtpParameters.
+ */
+@property(nonatomic, readonly) RTCRtpParameters *parameters;
+
+/** The RTCMediaStreamTrack associated with the sender.
+ * Note: reading this property returns a new instance of
+ * RTCMediaStreamTrack. Use isEqual: instead of == to compare
+ * RTCMediaStreamTrack instances.
+ */
+@property(nonatomic, readonly) RTCMediaStreamTrack *track;
+
+/** Set the new RTCRtpParameters to be used by the sender.
+ * Returns YES if the new parameters were applied, NO otherwise.
+ */
+- (BOOL)setParameters:(RTCRtpParameters *)parameters;
+
+@end
+
+@interface RTCRtpSender : NSObject <RTCRtpSender>
+
+- (instancetype)init NS_UNAVAILABLE;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/webrtc/api/objc/RTCRtpSender.mm b/webrtc/api/objc/RTCRtpSender.mm
new file mode 100644
index 0000000..1ad6761
--- /dev/null
+++ b/webrtc/api/objc/RTCRtpSender.mm
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2016 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 "RTCRtpSender.h"
+
+#import "webrtc/api/objc/RTCRtpParameters+Private.h"
+#import "webrtc/api/objc/RTCRtpSender+Private.h"
+#import "webrtc/api/objc/RTCMediaStreamTrack+Private.h"
+
+#include "webrtc/api/mediastreaminterface.h"
+#include "webrtc/api/rtpsenderinterface.h"
+
+@implementation RTCRtpSender {
+ rtc::scoped_refptr<webrtc::RtpSenderInterface> _nativeRtpSender;
+}
+
+- (instancetype)initWithNativeRtpSender:
+ (rtc::scoped_refptr<webrtc::RtpSenderInterface>)nativeRtpSender {
+ if (self = [super init]) {
+ _nativeRtpSender = nativeRtpSender;
+ }
+ return self;
+}
+
+- (RTCRtpParameters *)parameters {
+ return [[RTCRtpParameters alloc]
+ initWithNativeParameters:_nativeRtpSender->GetParameters()];
+}
+
+- (BOOL)setParameters:(RTCRtpParameters *)parameters {
+ return _nativeRtpSender->SetParameters(parameters.nativeParameters);
+}
+
+- (RTCMediaStreamTrack *)track {
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> nativeTrack(
+ _nativeRtpSender->track());
+ if (nativeTrack) {
+ return [[RTCMediaStreamTrack alloc] initWithNativeTrack:nativeTrack];
+ }
+ return nil;
+}
+
+@end