Expose setCodecPreferences/getCapabilities for iOS

Bug: webrtc:15749
Change-Id: I92f5d5dc5d9eb4d0a60c33ed724a0d3e8b4fa1a8
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/333402
Auto-Submit: Karim Ham <karim@karhm.com>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Reviewed-by: Peter Hanspers <peterhanspers@webrtc.org>
Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org>
Commit-Queue: Florent Castelli <orphis@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41601}
This commit is contained in:
Karim H 2024-01-04 09:28:49 +04:00 committed by WebRTC LUCI CQ
parent c708c00f95
commit 1b61c7161e
16 changed files with 721 additions and 0 deletions

View File

@ -65,6 +65,7 @@ Jie Mao <maojie0924@gmail.com>
Jiwon Kim <jwkim0000@gmail.com>
Johnny Wong <hellojinqiang@gmail.com>
Jose Antonio Olivera Ortega <josea.olivera@gmail.com>
Karim Hammache <karim@karhm.com>
Keiichi Enomoto <enm10k@gmail.com>
Kiran Thind <kiran.thind@gmail.com>
Korniltsev Anatoly <korniltsev.anatoly@gmail.com>

View File

@ -991,6 +991,12 @@ if (is_ios || is_mac) {
"objc/api/peerconnection/RTCRtcpParameters+Private.h",
"objc/api/peerconnection/RTCRtcpParameters.h",
"objc/api/peerconnection/RTCRtcpParameters.mm",
"objc/api/peerconnection/RTCRtpCapabilities+Private.h",
"objc/api/peerconnection/RTCRtpCapabilities.h",
"objc/api/peerconnection/RTCRtpCapabilities.mm",
"objc/api/peerconnection/RTCRtpCodecCapability+Private.h",
"objc/api/peerconnection/RTCRtpCodecCapability.h",
"objc/api/peerconnection/RTCRtpCodecCapability.mm",
"objc/api/peerconnection/RTCRtpCodecParameters+Private.h",
"objc/api/peerconnection/RTCRtpCodecParameters.h",
"objc/api/peerconnection/RTCRtpCodecParameters.mm",
@ -1000,6 +1006,9 @@ if (is_ios || is_mac) {
"objc/api/peerconnection/RTCRtpHeaderExtension+Private.h",
"objc/api/peerconnection/RTCRtpHeaderExtension.h",
"objc/api/peerconnection/RTCRtpHeaderExtension.mm",
"objc/api/peerconnection/RTCRtpHeaderExtensionCapability+Private.h",
"objc/api/peerconnection/RTCRtpHeaderExtensionCapability.h",
"objc/api/peerconnection/RTCRtpHeaderExtensionCapability.mm",
"objc/api/peerconnection/RTCRtpParameters+Private.h",
"objc/api/peerconnection/RTCRtpParameters.h",
"objc/api/peerconnection/RTCRtpParameters.mm",
@ -1309,9 +1318,12 @@ if (is_ios || is_mac) {
"objc/api/peerconnection/RTCPeerConnectionFactory.h",
"objc/api/peerconnection/RTCPeerConnectionFactoryOptions.h",
"objc/api/peerconnection/RTCRtcpParameters.h",
"objc/api/peerconnection/RTCRtpCapabilities.h",
"objc/api/peerconnection/RTCRtpCodecCapability.h",
"objc/api/peerconnection/RTCRtpCodecParameters.h",
"objc/api/peerconnection/RTCRtpEncodingParameters.h",
"objc/api/peerconnection/RTCRtpHeaderExtension.h",
"objc/api/peerconnection/RTCRtpHeaderExtensionCapability.h",
"objc/api/peerconnection/RTCRtpParameters.h",
"objc/api/peerconnection/RTCRtpReceiver.h",
"objc/api/peerconnection/RTCRtpSender.h",
@ -1423,9 +1435,12 @@ if (is_ios || is_mac) {
"objc/api/peerconnection/RTCPeerConnectionFactory.h",
"objc/api/peerconnection/RTCPeerConnectionFactoryOptions.h",
"objc/api/peerconnection/RTCRtcpParameters.h",
"objc/api/peerconnection/RTCRtpCapabilities.h",
"objc/api/peerconnection/RTCRtpCodecCapability.h",
"objc/api/peerconnection/RTCRtpCodecParameters.h",
"objc/api/peerconnection/RTCRtpEncodingParameters.h",
"objc/api/peerconnection/RTCRtpHeaderExtension.h",
"objc/api/peerconnection/RTCRtpHeaderExtensionCapability.h",
"objc/api/peerconnection/RTCRtpParameters.h",
"objc/api/peerconnection/RTCRtpReceiver.h",
"objc/api/peerconnection/RTCRtpSender.h",

View File

@ -14,6 +14,7 @@
NS_ASSUME_NONNULL_BEGIN
@class RTC_OBJC_TYPE(RTCRtpCapabilities);
@class RTC_OBJC_TYPE(RTCAudioSource);
@class RTC_OBJC_TYPE(RTCAudioTrack);
@class RTC_OBJC_TYPE(RTCConfiguration);
@ -51,6 +52,18 @@ RTC_OBJC_EXPORT
decoderFactory:(nullable id<RTC_OBJC_TYPE(RTCVideoDecoderFactory)>)decoderFactory
audioDevice:(nullable id<RTC_OBJC_TYPE(RTCAudioDevice)>)audioDevice;
/**
* Valid kind values are kRTCMediaStreamTrackKindAudio and
* kRTCMediaStreamTrackKindVideo.
*/
- (RTC_OBJC_TYPE(RTCRtpCapabilities) *)rtpSenderCapabilitiesForKind:(NSString *)kind;
/**
* Valid kind values are kRTCMediaStreamTrackKindAudio and
* kRTCMediaStreamTrackKindVideo.
*/
- (RTC_OBJC_TYPE(RTCRtpCapabilities) *)rtpReceiverCapabilitiesForKind:(NSString *)kind;
/** Initialize an RTCAudioSource with constraints. */
- (RTC_OBJC_TYPE(RTCAudioSource) *)audioSourceWithConstraints:
(nullable RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints;

View File

@ -13,6 +13,7 @@
#import "RTCPeerConnectionFactory+Native.h"
#import "RTCPeerConnectionFactory+Private.h"
#import "RTCPeerConnectionFactoryOptions+Private.h"
#import "RTCRtpCapabilities+Private.h"
#import "RTCAudioSource+Private.h"
#import "RTCAudioTrack+Private.h"
@ -38,6 +39,7 @@
#include "api/transport/field_trial_based_config.h"
#import "components/video_codec/RTCVideoDecoderFactoryH264.h"
#import "components/video_codec/RTCVideoEncoderFactoryH264.h"
#include "media/base/media_constants.h"
#include "modules/audio_device/include/audio_device.h"
#include "modules/audio_processing/include/audio_processing.h"
@ -214,6 +216,20 @@
return self;
}
- (RTC_OBJC_TYPE(RTCRtpCapabilities) *)rtpSenderCapabilitiesForKind:(NSString *)kind {
cricket::MediaType mediaType = [[self class] mediaTypeForKind:kind];
webrtc::RtpCapabilities rtpCapabilities = _nativeFactory->GetRtpSenderCapabilities(mediaType);
return [[RTC_OBJC_TYPE(RTCRtpCapabilities) alloc] initWithNativeRtpCapabilities:rtpCapabilities];
}
- (RTC_OBJC_TYPE(RTCRtpCapabilities) *)rtpReceiverCapabilitiesForKind:(NSString *)kind {
cricket::MediaType mediaType = [[self class] mediaTypeForKind:kind];
webrtc::RtpCapabilities rtpCapabilities = _nativeFactory->GetRtpReceiverCapabilities(mediaType);
return [[RTC_OBJC_TYPE(RTCRtpCapabilities) alloc] initWithNativeRtpCapabilities:rtpCapabilities];
}
- (RTC_OBJC_TYPE(RTCAudioSource) *)audioSourceWithConstraints:
(nullable RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints {
std::unique_ptr<webrtc::MediaConstraints> nativeConstraints;
@ -338,4 +354,17 @@
return _networkThread.get();
}
#pragma mark - Private
+ (cricket::MediaType)mediaTypeForKind:(NSString *)kind {
if (kind == kRTCMediaStreamTrackKindAudio) {
return cricket::MEDIA_TYPE_AUDIO;
} else if (kind == kRTCMediaStreamTrackKindVideo) {
return cricket::MEDIA_TYPE_VIDEO;
} else {
RTC_DCHECK_NOTREACHED();
return cricket::MEDIA_TYPE_UNSUPPORTED;
}
}
@end

View File

@ -0,0 +1,32 @@
/*
* Copyright 2024 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 "RTCRtpCapabilities.h"
#include "api/rtp_parameters.h"
NS_ASSUME_NONNULL_BEGIN
@interface RTC_OBJC_TYPE (RTCRtpCapabilities)()
/**
* The native RtpCapabilities representation of this RTCRtpCapabilities
* object. This is needed to pass to the underlying C++ APIs.
*/
@property(nonatomic, readonly) webrtc::RtpCapabilities nativeRtpCapabilities;
/**
* Initialize an RTCRtpCapabilities from a native RtpCapabilities.
*/
- (instancetype)initWithNativeRtpCapabilities:(const webrtc::RtpCapabilities &)rtpCapabilities;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,31 @@
/*
* Copyright 2024 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 "RTCMacros.h"
NS_ASSUME_NONNULL_BEGIN
@class RTC_OBJC_TYPE(RTCRtpCodecCapability);
@class RTC_OBJC_TYPE(RTCRtpHeaderExtensionCapability);
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCRtpCapabilities) : NSObject
@property(nonatomic, copy) NSArray<RTC_OBJC_TYPE(RTCRtpCodecCapability) *> *codecs;
@property(nonatomic, copy)
NSArray<RTC_OBJC_TYPE(RTCRtpHeaderExtensionCapability) *> *headerExtensions;
- (instancetype)init;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,60 @@
/*
* Copyright 2024 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 "RTCRtpCapabilities+Private.h"
#import "RTCRtpCodecCapability+Private.h"
#import "RTCRtpHeaderExtensionCapability+Private.h"
#import "base/RTCLogging.h"
#import "helpers/NSString+StdString.h"
@implementation RTC_OBJC_TYPE (RTCRtpCapabilities)
@synthesize codecs = _codecs;
@synthesize headerExtensions = _headerExtensions;
- (instancetype)init {
webrtc::RtpCapabilities nativeRtpCapabilities;
return [self initWithNativeRtpCapabilities:nativeRtpCapabilities];
}
- (instancetype)initWithNativeRtpCapabilities:
(const webrtc::RtpCapabilities &)nativeRtpCapabilities {
if (self = [super init]) {
NSMutableArray *codecs = [[NSMutableArray alloc] init];
for (const auto &codec : nativeRtpCapabilities.codecs) {
[codecs addObject:[[RTC_OBJC_TYPE(RTCRtpCodecCapability) alloc]
initWithNativeRtpCodecCapability:codec]];
}
_codecs = codecs;
NSMutableArray *headerExtensions = [[NSMutableArray alloc] init];
for (const auto &headerExtension : nativeRtpCapabilities.header_extensions) {
[headerExtensions addObject:[[RTC_OBJC_TYPE(RTCRtpHeaderExtensionCapability) alloc]
initWithNativeRtpHeaderExtensionCapability:headerExtension]];
}
_headerExtensions = headerExtensions;
}
return self;
}
- (webrtc::RtpCapabilities)nativeRtpCapabilities {
webrtc::RtpCapabilities rtpCapabilities;
for (RTC_OBJC_TYPE(RTCRtpCodecCapability) * codec in _codecs) {
rtpCapabilities.codecs.push_back(codec.nativeRtpCodecCapability);
}
for (RTC_OBJC_TYPE(RTCRtpHeaderExtensionCapability) * headerExtension in _headerExtensions) {
rtpCapabilities.header_extensions.push_back(headerExtension.nativeRtpHeaderExtensionCapability);
}
return rtpCapabilities;
}
@end

View File

@ -0,0 +1,33 @@
/*
* Copyright 2024 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 "RTCRtpCodecCapability.h"
#include "api/rtp_parameters.h"
NS_ASSUME_NONNULL_BEGIN
@interface RTC_OBJC_TYPE (RTCRtpCodecCapability)()
/**
* The native RtpCodecCapability representation of this RTCRtpCodecCapability
* object. This is needed to pass to the underlying C++ APIs.
*/
@property(nonatomic, readonly) webrtc::RtpCodecCapability nativeRtpCodecCapability;
/**
* Initialize an RTCRtpCodecCapability from a native RtpCodecCapability.
*/
- (instancetype)initWithNativeRtpCodecCapability:
(const webrtc::RtpCodecCapability &)nativeRtpCodecCapability;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,58 @@
/*
* Copyright 2024 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 "RTCMacros.h"
NS_ASSUME_NONNULL_BEGIN
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCRtpCodecCapability) : NSObject
/** The preferred RTP payload type. */
@property(nonatomic, readonly, nullable) NSNumber *preferredPayloadType;
/**
* The codec MIME subtype. Valid types are listed in:
* http://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml#rtp-parameters-2
*
* Several supported types are represented by the constants above.
*/
@property(nonatomic, readonly) NSString *name;
/**
* The media type of this codec. Equivalent to MIME top-level type.
*
* Valid values are kRTCMediaStreamTrackKindAudio and
* kRTCMediaStreamTrackKindVideo.
*/
@property(nonatomic, readonly) NSString *kind;
/** The codec clock rate expressed in Hertz. */
@property(nonatomic, readonly, nullable) NSNumber *clockRate;
/**
* The number of audio channels (mono=1, stereo=2).
* Set to null for video codecs.
**/
@property(nonatomic, readonly, nullable) NSNumber *numChannels;
/** The "format specific parameters" field from the "a=fmtp" line in the SDP */
@property(nonatomic, readonly) NSDictionary<NSString *, NSString *> *parameters;
/** The MIME type of the codec. */
@property(nonatomic, readonly) NSString *mimeType;
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,116 @@
/*
* Copyright 2024 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 "RTCRtpCodecCapability+Private.h"
#import "RTCMediaStreamTrack.h"
#import "helpers/NSString+StdString.h"
#include "media/base/media_constants.h"
#include "rtc_base/checks.h"
@implementation RTC_OBJC_TYPE (RTCRtpCodecCapability)
@synthesize preferredPayloadType = _preferredPayloadType;
@synthesize name = _name;
@synthesize kind = _kind;
@synthesize clockRate = _clockRate;
@synthesize numChannels = _numChannels;
@synthesize parameters = _parameters;
@synthesize mimeType = _mimeType;
- (instancetype)init {
webrtc::RtpCodecCapability rtpCodecCapability;
return [self initWithNativeRtpCodecCapability:rtpCodecCapability];
}
- (instancetype)initWithNativeRtpCodecCapability:
(const webrtc::RtpCodecCapability &)nativeRtpCodecCapability {
if (self = [super init]) {
if (nativeRtpCodecCapability.preferred_payload_type) {
_preferredPayloadType =
[NSNumber numberWithInt:*nativeRtpCodecCapability.preferred_payload_type];
}
_name = [NSString stringForStdString:nativeRtpCodecCapability.name];
switch (nativeRtpCodecCapability.kind) {
case cricket::MEDIA_TYPE_AUDIO:
_kind = kRTCMediaStreamTrackKindAudio;
break;
case cricket::MEDIA_TYPE_VIDEO:
_kind = kRTCMediaStreamTrackKindVideo;
break;
case cricket::MEDIA_TYPE_DATA:
RTC_DCHECK_NOTREACHED();
break;
case cricket::MEDIA_TYPE_UNSUPPORTED:
RTC_DCHECK_NOTREACHED();
break;
}
if (nativeRtpCodecCapability.clock_rate) {
_clockRate = [NSNumber numberWithInt:*nativeRtpCodecCapability.clock_rate];
}
if (nativeRtpCodecCapability.num_channels) {
_numChannels = [NSNumber numberWithInt:*nativeRtpCodecCapability.num_channels];
}
NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
for (const auto &parameter : nativeRtpCodecCapability.parameters) {
[parameters setObject:[NSString stringForStdString:parameter.second]
forKey:[NSString stringForStdString:parameter.first]];
}
_parameters = parameters;
_mimeType = [NSString stringForStdString:nativeRtpCodecCapability.mime_type()];
}
return self;
}
- (NSString *)description {
return [NSString stringWithFormat:@"RTC_OBJC_TYPE(RTCRtpCodecCapability) {\n "
@"preferredPayloadType: %@\n name: %@\n kind: %@\n "
@"clockRate: %@\n numChannels: %@\n parameters: %@\n "
@"mimeType: %@\n}",
_preferredPayloadType,
_name,
_kind,
_clockRate,
_numChannels,
_parameters,
_mimeType];
}
- (webrtc::RtpCodecCapability)nativeRtpCodecCapability {
webrtc::RtpCodecCapability rtpCodecCapability;
if (_preferredPayloadType != nil) {
rtpCodecCapability.preferred_payload_type = absl::optional<int>(_preferredPayloadType.intValue);
}
rtpCodecCapability.name = [NSString stdStringForString:_name];
// NSString pointer comparison is safe here since "kind" is readonly and only
// populated above.
if (_kind == kRTCMediaStreamTrackKindAudio) {
rtpCodecCapability.kind = cricket::MEDIA_TYPE_AUDIO;
} else if (_kind == kRTCMediaStreamTrackKindVideo) {
rtpCodecCapability.kind = cricket::MEDIA_TYPE_VIDEO;
} else {
RTC_DCHECK_NOTREACHED();
}
if (_clockRate != nil) {
rtpCodecCapability.clock_rate = absl::optional<int>(_clockRate.intValue);
}
if (_numChannels != nil) {
rtpCodecCapability.num_channels = absl::optional<int>(_numChannels.intValue);
}
for (NSString *paramKey in _parameters.allKeys) {
std::string key = [NSString stdStringForString:paramKey];
std::string value = [NSString stdStringForString:_parameters[paramKey]];
rtpCodecCapability.parameters[key] = value;
}
return rtpCodecCapability;
}
@end

View File

@ -0,0 +1,34 @@
/*
* Copyright 2024 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 "RTCRtpHeaderExtensionCapability.h"
#include "api/rtp_parameters.h"
NS_ASSUME_NONNULL_BEGIN
@interface RTC_OBJC_TYPE (RTCRtpHeaderExtensionCapability)()
/**
* The native RtpHeaderExtensionCapability representation of this
* RTCRtpHeaderExtensionCapability object. This is needed to pass to the underlying C++ APIs.
*/
@property(nonatomic,
readonly) webrtc::RtpHeaderExtensionCapability nativeRtpHeaderExtensionCapability;
/**
* Initialize an RTCRtpHeaderExtensionCapability from a native RtpHeaderExtensionCapability.
*/
- (instancetype)initWithNativeRtpHeaderExtensionCapability:
(const webrtc::RtpHeaderExtensionCapability &)rtpHeaderExtensionCapability;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,33 @@
/*
* Copyright 2024 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 "RTCMacros.h"
NS_ASSUME_NONNULL_BEGIN
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCRtpHeaderExtensionCapability) : NSObject
/** The URI of the RTP header extension, as defined in RFC5285. */
@property(nonatomic, readonly, copy) NSString *uri;
/** The value put in the RTP packet to identify the header extension. */
@property(nonatomic, readonly, nullable) NSNumber* preferredId;
/** Whether the header extension is encrypted or not. */
@property(nonatomic, readonly, getter=isPreferredEncrypted) BOOL preferredEncrypted;
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,56 @@
/*
* Copyright 2024 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 "RTCRtpHeaderExtensionCapability+Private.h"
#import "helpers/NSString+StdString.h"
@implementation RTC_OBJC_TYPE (RTCRtpHeaderExtensionCapability)
@synthesize uri = _uri;
@synthesize preferredId = _preferredId;
@synthesize preferredEncrypted = _preferredEncrypted;
- (instancetype)init {
webrtc::RtpHeaderExtensionCapability nativeRtpHeaderExtensionCapability;
return [self initWithNativeRtpHeaderExtensionCapability:nativeRtpHeaderExtensionCapability];
}
- (instancetype)initWithNativeRtpHeaderExtensionCapability:
(const webrtc::RtpHeaderExtensionCapability &)nativeRtpHeaderExtensionCapability {
if (self = [super init]) {
_uri = [NSString stringForStdString:nativeRtpHeaderExtensionCapability.uri];
if (nativeRtpHeaderExtensionCapability.preferred_id) {
_preferredId = [NSNumber numberWithInt:*nativeRtpHeaderExtensionCapability.preferred_id];
}
_preferredEncrypted = nativeRtpHeaderExtensionCapability.preferred_encrypt;
}
return self;
}
- (NSString *)description {
return [NSString stringWithFormat:@"RTC_OBJC_TYPE(RTCRtpHeaderExtensionCapability) {\n uri: "
@"%@\n preferredId: %@\n preferredEncrypted: %d\n}",
_uri,
_preferredId,
_preferredEncrypted];
}
- (webrtc::RtpHeaderExtensionCapability)nativeRtpHeaderExtensionCapability {
webrtc::RtpHeaderExtensionCapability rtpHeaderExtensionCapability;
rtpHeaderExtensionCapability.uri = [NSString stdStringForString:_uri];
if (_preferredId != nil) {
rtpHeaderExtensionCapability.preferred_id = absl::optional<int>(_preferredId.intValue);
}
rtpHeaderExtensionCapability.preferred_encrypt = _preferredEncrypted;
return rtpHeaderExtensionCapability;
}
@end

View File

@ -46,6 +46,7 @@ RTC_OBJC_EXPORT
@end
@class RTC_OBJC_TYPE(RTCRtpTransceiver);
@class RTC_OBJC_TYPE(RTCRtpCodecCapability);
/** The RTCRtpTransceiver maps to the RTCRtpTransceiver defined by the
* WebRTC specification. A transceiver represents a combination of an RTCRtpSender
@ -118,6 +119,12 @@ RTC_OBJC_EXPORT
*/
- (void)stopInternal;
/** The setCodecPreferences method overrides the default codec preferences used
* by WebRTC for this transceiver.
* https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-setcodecpreferences
*/
- (void)setCodecPreferences:(NSArray<RTC_OBJC_TYPE(RTCRtpCodecCapability) *> *)codecs;
/** An update of directionality does not take effect immediately. Instead,
* future calls to createOffer and createAnswer mark the corresponding media
* descriptions as sendrecv, sendonly, recvonly, or inactive.

View File

@ -10,6 +10,7 @@
#import "RTCRtpTransceiver+Private.h"
#import "RTCRtpCodecCapability+Private.h"
#import "RTCRtpEncodingParameters+Private.h"
#import "RTCRtpParameters+Private.h"
#import "RTCRtpReceiver+Private.h"
@ -17,6 +18,8 @@
#import "base/RTCLogging.h"
#import "helpers/NSString+StdString.h"
#include "api/rtp_parameters.h"
NSString *const kRTCRtpTransceiverErrorDomain = @"org.webrtc.RTCRtpTranceiver";
@implementation RTC_OBJC_TYPE (RTCRtpTransceiverInit)
@ -105,6 +108,14 @@ NSString *const kRTCRtpTransceiverErrorDomain = @"org.webrtc.RTCRtpTranceiver";
_nativeRtpTransceiver->StopInternal();
}
- (void)setCodecPreferences:(NSArray<RTC_OBJC_TYPE(RTCRtpCodecCapability) *> *)codecs {
std::vector<webrtc::RtpCodecCapability> codecCapabilities;
for (RTC_OBJC_TYPE(RTCRtpCodecCapability) * rtpCodecCapability in codecs) {
codecCapabilities.push_back(rtpCodecCapability.nativeRtpCodecCapability);
}
_nativeRtpTransceiver->SetCodecPreferences(codecCapabilities);
}
- (NSString *)description {
return [NSString
stringWithFormat:@"RTC_OBJC_TYPE(RTCRtpTransceiver) {\n sender: %@\n receiver: %@\n}",

View File

@ -8,6 +8,9 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#import "base/RTCVideoDecoderFactory.h"
#import "base/RTCVideoEncoderFactory.h"
#import "api/peerconnection/RTCAudioSource.h"
#import "api/peerconnection/RTCConfiguration.h"
#import "api/peerconnection/RTCDataChannel.h"
@ -16,6 +19,8 @@
#import "api/peerconnection/RTCMediaStreamTrack.h"
#import "api/peerconnection/RTCPeerConnection.h"
#import "api/peerconnection/RTCPeerConnectionFactory.h"
#import "api/peerconnection/RTCRtpCapabilities.h"
#import "api/peerconnection/RTCRtpCodecCapability.h"
#import "api/peerconnection/RTCRtpReceiver.h"
#import "api/peerconnection/RTCRtpSender.h"
#import "api/peerconnection/RTCRtpTransceiver.h"
@ -25,6 +30,40 @@
#import <XCTest/XCTest.h>
@interface MockVideoEncoderDecoderFactory
: NSObject <RTC_OBJC_TYPE (RTCVideoEncoderFactory), RTC_OBJC_TYPE (RTCVideoDecoderFactory)>
- (instancetype)initWithSupportedCodecs:
(nonnull NSArray<RTC_OBJC_TYPE(RTCVideoCodecInfo) *> *)supportedCodecs;
@end
@implementation MockVideoEncoderDecoderFactory {
NSArray<RTC_OBJC_TYPE(RTCVideoCodecInfo) *> *_supportedCodecs;
}
- (instancetype)initWithSupportedCodecs:
(nonnull NSArray<RTC_OBJC_TYPE(RTCVideoCodecInfo) *> *)supportedCodecs {
if (self = [super init]) {
_supportedCodecs = supportedCodecs;
}
return self;
}
- (nullable id<RTC_OBJC_TYPE(RTCVideoEncoder)>)createEncoder:
(nonnull RTC_OBJC_TYPE(RTCVideoCodecInfo) *)info {
return nil;
}
- (nullable id<RTC_OBJC_TYPE(RTCVideoDecoder)>)createDecoder:
(nonnull RTC_OBJC_TYPE(RTCVideoCodecInfo) *)info {
return nil;
}
- (nonnull NSArray<RTC_OBJC_TYPE(RTCVideoCodecInfo) *> *)supportedCodecs {
return _supportedCodecs;
}
@end
@interface RTCPeerConnectionFactoryTests : XCTestCase
@end
@ -325,6 +364,147 @@
}
}
- (void)testSenderCapabilities {
@autoreleasepool {
RTC_OBJC_TYPE(RTCPeerConnectionFactory) * factory;
MockVideoEncoderDecoderFactory *encoder;
MockVideoEncoderDecoderFactory *decoder;
NSArray<RTC_OBJC_TYPE(RTCVideoCodecInfo) *> *supportedCodecs = @[
[[RTC_OBJC_TYPE(RTCVideoCodecInfo) alloc] initWithName:@"VP8"],
[[RTC_OBJC_TYPE(RTCVideoCodecInfo) alloc] initWithName:@"H264"]
];
encoder = [[MockVideoEncoderDecoderFactory alloc] initWithSupportedCodecs:supportedCodecs];
decoder = [[MockVideoEncoderDecoderFactory alloc] initWithSupportedCodecs:supportedCodecs];
factory = [[RTC_OBJC_TYPE(RTCPeerConnectionFactory) alloc] initWithEncoderFactory:encoder
decoderFactory:decoder];
RTC_OBJC_TYPE(RTCRtpCapabilities) *capabilities =
[factory rtpSenderCapabilitiesForKind:kRTCMediaStreamTrackKindVideo];
NSMutableArray<NSString *> *codecNames = [NSMutableArray new];
for (RTC_OBJC_TYPE(RTCRtpCodecCapability) * codec in capabilities.codecs) {
[codecNames addObject:codec.name];
}
XCTAssertTrue([codecNames containsObject:@"VP8"]);
XCTAssertTrue([codecNames containsObject:@"H264"]);
factory = nil;
}
}
- (void)testReceiverCapabilities {
@autoreleasepool {
RTC_OBJC_TYPE(RTCPeerConnectionFactory) * factory;
MockVideoEncoderDecoderFactory *encoder;
MockVideoEncoderDecoderFactory *decoder;
NSArray<RTC_OBJC_TYPE(RTCVideoCodecInfo) *> *supportedCodecs = @[
[[RTC_OBJC_TYPE(RTCVideoCodecInfo) alloc] initWithName:@"VP8"],
[[RTC_OBJC_TYPE(RTCVideoCodecInfo) alloc] initWithName:@"H264"]
];
encoder = [[MockVideoEncoderDecoderFactory alloc] initWithSupportedCodecs:supportedCodecs];
decoder = [[MockVideoEncoderDecoderFactory alloc] initWithSupportedCodecs:supportedCodecs];
factory = [[RTC_OBJC_TYPE(RTCPeerConnectionFactory) alloc] initWithEncoderFactory:encoder
decoderFactory:decoder];
RTC_OBJC_TYPE(RTCRtpCapabilities) *capabilities =
[factory rtpReceiverCapabilitiesForKind:kRTCMediaStreamTrackKindVideo];
NSMutableArray<NSString *> *codecNames = [NSMutableArray new];
for (RTC_OBJC_TYPE(RTCRtpCodecCapability) * codec in capabilities.codecs) {
[codecNames addObject:codec.name];
}
XCTAssertTrue([codecNames containsObject:@"VP8"]);
XCTAssertTrue([codecNames containsObject:@"H264"]);
factory = nil;
}
}
- (void)testSetCodecPreferences {
@autoreleasepool {
RTC_OBJC_TYPE(RTCConfiguration) *config = [[RTC_OBJC_TYPE(RTCConfiguration) alloc] init];
RTC_OBJC_TYPE(RTCMediaConstraints) *constraints =
[[RTC_OBJC_TYPE(RTCMediaConstraints) alloc] initWithMandatoryConstraints:nil
optionalConstraints:nil];
RTC_OBJC_TYPE(RTCRtpTransceiverInit) *init =
[[RTC_OBJC_TYPE(RTCRtpTransceiverInit) alloc] init];
NSArray<RTC_OBJC_TYPE(RTCVideoCodecInfo) *> *supportedCodecs = @[
[[RTC_OBJC_TYPE(RTCVideoCodecInfo) alloc] initWithName:@"VP8"],
[[RTC_OBJC_TYPE(RTCVideoCodecInfo) alloc] initWithName:@"H264"]
];
MockVideoEncoderDecoderFactory *encoder =
[[MockVideoEncoderDecoderFactory alloc] initWithSupportedCodecs:supportedCodecs];
MockVideoEncoderDecoderFactory *decoder =
[[MockVideoEncoderDecoderFactory alloc] initWithSupportedCodecs:supportedCodecs];
RTC_OBJC_TYPE(RTCPeerConnectionFactory) * factory;
RTC_OBJC_TYPE(RTCPeerConnection) * peerConnection;
RTC_OBJC_TYPE(RTCRtpTransceiver) * tranceiver;
factory = [[RTC_OBJC_TYPE(RTCPeerConnectionFactory) alloc] initWithEncoderFactory:encoder
decoderFactory:decoder];
peerConnection = [factory peerConnectionWithConfiguration:config
constraints:constraints
delegate:nil];
tranceiver = [peerConnection addTransceiverOfType:RTCRtpMediaTypeVideo init:init];
XCTAssertNotNil(tranceiver);
RTC_OBJC_TYPE(RTCRtpCapabilities) *capabilities =
[factory rtpReceiverCapabilitiesForKind:kRTCMediaStreamTrackKindVideo];
RTC_OBJC_TYPE(RTCRtpCodecCapability) * targetCodec;
for (RTC_OBJC_TYPE(RTCRtpCodecCapability) * codec in capabilities.codecs) {
if ([codec.name isEqual:@"VP8"]) {
targetCodec = codec;
break;
}
}
XCTAssertNotNil(targetCodec);
[tranceiver setCodecPreferences:@[ targetCodec ]];
@autoreleasepool {
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
__block BOOL completed = NO;
[peerConnection
offerForConstraints:constraints
completionHandler:^(RTCSessionDescription *_Nullable sdp, NSError *_Nullable error) {
XCTAssertNil(error);
XCTAssertNotNil(sdp);
NSArray<NSString *> *rtpMaps = [self rtpMapsFromSDP:sdp.sdp];
XCTAssertEqual(1, rtpMaps.count);
XCTAssertNotNil(targetCodec.preferredPayloadType);
XCTAssertNotNil(targetCodec.clockRate);
NSString *expected =
[NSString stringWithFormat:@"a=rtpmap:%i VP8/%i",
targetCodec.preferredPayloadType.intValue,
targetCodec.clockRate.intValue];
XCTAssertTrue([expected isEqualToString:rtpMaps[0]]);
completed = YES;
dispatch_semaphore_signal(semaphore);
}];
[peerConnection close];
peerConnection = nil;
factory = nil;
tranceiver = nil;
dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 15.0 * NSEC_PER_SEC));
XCTAssertTrue(completed);
}
}
}
- (bool)negotiatePeerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)pc1
withPeerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)pc2
negotiationTimeout:(NSTimeInterval)timeout {
@ -377,4 +557,16 @@
dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeout * NSEC_PER_SEC)));
}
- (NSArray<NSString *> *)rtpMapsFromSDP:(NSString *)sdp {
NSMutableArray<NSString *> *rtpMaps = [NSMutableArray new];
NSArray *sdpLines =
[sdp componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
for (NSString *line in sdpLines) {
if ([line hasPrefix:@"a=rtpmap"]) {
[rtpMaps addObject:line];
}
}
return rtpMaps;
}
@end