diff options
Diffstat (limited to 'third_party/libwebrtc/sdk')
22 files changed, 741 insertions, 19 deletions
diff --git a/third_party/libwebrtc/sdk/BUILD.gn b/third_party/libwebrtc/sdk/BUILD.gn index 586d4d1911..e973448f05 100644 --- a/third_party/libwebrtc/sdk/BUILD.gn +++ b/third_party/libwebrtc/sdk/BUILD.gn @@ -996,6 +996,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", @@ -1005,6 +1011,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", @@ -1314,9 +1323,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", @@ -1428,9 +1440,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", diff --git a/third_party/libwebrtc/sdk/android/api/org/webrtc/Dav1dDecoder.java b/third_party/libwebrtc/sdk/android/api/org/webrtc/Dav1dDecoder.java index ecb16bc3a1..2a79988470 100644 --- a/third_party/libwebrtc/sdk/android/api/org/webrtc/Dav1dDecoder.java +++ b/third_party/libwebrtc/sdk/android/api/org/webrtc/Dav1dDecoder.java @@ -12,7 +12,7 @@ package org.webrtc; public class Dav1dDecoder extends WrappedNativeVideoDecoder { @Override - public long createNativeVideoDecoder() { + public long createNative(long webrtcEnvRef) { return nativeCreateDecoder(); } diff --git a/third_party/libwebrtc/sdk/android/api/org/webrtc/LibvpxVp8Decoder.java b/third_party/libwebrtc/sdk/android/api/org/webrtc/LibvpxVp8Decoder.java index 54ad0aa137..7d3e95973d 100644 --- a/third_party/libwebrtc/sdk/android/api/org/webrtc/LibvpxVp8Decoder.java +++ b/third_party/libwebrtc/sdk/android/api/org/webrtc/LibvpxVp8Decoder.java @@ -12,9 +12,9 @@ package org.webrtc; public class LibvpxVp8Decoder extends WrappedNativeVideoDecoder { @Override - public long createNativeVideoDecoder() { - return nativeCreateDecoder(); + public long createNative(long webrtcEnvRef) { + return nativeCreateDecoder(webrtcEnvRef); } - static native long nativeCreateDecoder(); + static native long nativeCreateDecoder(long webrtcEnvRef); } diff --git a/third_party/libwebrtc/sdk/android/api/org/webrtc/LibvpxVp9Decoder.java b/third_party/libwebrtc/sdk/android/api/org/webrtc/LibvpxVp9Decoder.java index 90a24433a3..34718cfa8c 100644 --- a/third_party/libwebrtc/sdk/android/api/org/webrtc/LibvpxVp9Decoder.java +++ b/third_party/libwebrtc/sdk/android/api/org/webrtc/LibvpxVp9Decoder.java @@ -12,7 +12,7 @@ package org.webrtc; public class LibvpxVp9Decoder extends WrappedNativeVideoDecoder { @Override - public long createNativeVideoDecoder() { + public long createNative(long webrtcEnvRef) { return nativeCreateDecoder(); } diff --git a/third_party/libwebrtc/sdk/android/api/org/webrtc/SoftwareVideoDecoderFactory.java b/third_party/libwebrtc/sdk/android/api/org/webrtc/SoftwareVideoDecoderFactory.java index 2ac42e834e..1b1cd44a92 100644 --- a/third_party/libwebrtc/sdk/android/api/org/webrtc/SoftwareVideoDecoderFactory.java +++ b/third_party/libwebrtc/sdk/android/api/org/webrtc/SoftwareVideoDecoderFactory.java @@ -11,7 +11,6 @@ package org.webrtc; import androidx.annotation.Nullable; -import java.util.Arrays; import java.util.List; public class SoftwareVideoDecoderFactory implements VideoDecoderFactory { @@ -26,16 +25,14 @@ public class SoftwareVideoDecoderFactory implements VideoDecoderFactory { @Nullable @Override public VideoDecoder createDecoder(VideoCodecInfo info) { - long nativeDecoder = nativeCreateDecoder(nativeFactory, info); - if (nativeDecoder == 0) { + if (!nativeIsSupported(nativeFactory, info)) { Logging.w(TAG, "Trying to create decoder for unsupported format. " + info); return null; } - return new WrappedNativeVideoDecoder() { @Override - public long createNativeVideoDecoder() { - return nativeDecoder; + public long createNative(long webrtcEnvRef) { + return nativeCreate(nativeFactory, webrtcEnvRef, info); } }; } @@ -47,7 +44,10 @@ public class SoftwareVideoDecoderFactory implements VideoDecoderFactory { private static native long nativeCreateFactory(); - private static native long nativeCreateDecoder(long factory, VideoCodecInfo videoCodecInfo); + private static native boolean nativeIsSupported(long factory, VideoCodecInfo info); + + private static native long nativeCreate( + long factory, long webrtcEnvRef, VideoCodecInfo info); private static native List<VideoCodecInfo> nativeGetSupportedCodecs(long factory); } diff --git a/third_party/libwebrtc/sdk/android/api/org/webrtc/VideoDecoder.java b/third_party/libwebrtc/sdk/android/api/org/webrtc/VideoDecoder.java index a80fa4fef2..195daf5260 100644 --- a/third_party/libwebrtc/sdk/android/api/org/webrtc/VideoDecoder.java +++ b/third_party/libwebrtc/sdk/android/api/org/webrtc/VideoDecoder.java @@ -56,11 +56,11 @@ public interface VideoDecoder { * decoder (e.g., an Android platform decoder), or alternatively 2) a native * decoder (e.g., a software decoder or a C++ decoder adapter). * - * For case 1), createNativeVideoDecoder() should return zero. + * For case 1), createNative() should return zero. * In this case, we expect the native library to call the decoder through * JNI using the Java interface declared below. * - * For case 2), createNativeVideoDecoder() should return a non-zero value. + * For case 2), createNative() should return a non-zero value. * In this case, we expect the native library to treat the returned value as * a raw pointer of type webrtc::VideoDecoder* (ownership is transferred to * the caller). The native library should then directly call the @@ -69,7 +69,7 @@ public interface VideoDecoder { * UnsupportedOperationException. */ @CalledByNative - default long createNativeVideoDecoder() { + default long createNative(long webrtcEnvRef) { return 0; } diff --git a/third_party/libwebrtc/sdk/android/api/org/webrtc/VideoDecoderFallback.java b/third_party/libwebrtc/sdk/android/api/org/webrtc/VideoDecoderFallback.java index ddfa3ecd40..1e7bae9b27 100644 --- a/third_party/libwebrtc/sdk/android/api/org/webrtc/VideoDecoderFallback.java +++ b/third_party/libwebrtc/sdk/android/api/org/webrtc/VideoDecoderFallback.java @@ -23,9 +23,10 @@ public class VideoDecoderFallback extends WrappedNativeVideoDecoder { } @Override - public long createNativeVideoDecoder() { - return nativeCreateDecoder(fallback, primary); + public long createNative(long webrtcEnvRef) { + return nativeCreate(webrtcEnvRef, fallback, primary); } - private static native long nativeCreateDecoder(VideoDecoder fallback, VideoDecoder primary); + private static native long nativeCreate( + long webrtcEnvRef, VideoDecoder fallback, VideoDecoder primary); } diff --git a/third_party/libwebrtc/sdk/android/api/org/webrtc/WrappedNativeVideoDecoder.java b/third_party/libwebrtc/sdk/android/api/org/webrtc/WrappedNativeVideoDecoder.java index 027120e48e..d762e757e4 100644 --- a/third_party/libwebrtc/sdk/android/api/org/webrtc/WrappedNativeVideoDecoder.java +++ b/third_party/libwebrtc/sdk/android/api/org/webrtc/WrappedNativeVideoDecoder.java @@ -14,7 +14,7 @@ package org.webrtc; * Wraps a native webrtc::VideoDecoder. */ public abstract class WrappedNativeVideoDecoder implements VideoDecoder { - @Override public abstract long createNativeVideoDecoder(); + @Override public abstract long createNative(long webrtcEnvRef); @Override public final VideoCodecStatus initDecode(Settings settings, Callback decodeCallback) { diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.h index 5575af98c9..17777f6d5d 100644 --- a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.h +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.h @@ -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; diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.mm index 445006f0d0..64be41ae15 100644 --- a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.mm +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.mm @@ -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 diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCapabilities+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCapabilities+Private.h new file mode 100644 index 0000000000..be51993f2f --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCapabilities+Private.h @@ -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 diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCapabilities.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCapabilities.h new file mode 100644 index 0000000000..7e898b5a80 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCapabilities.h @@ -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 diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCapabilities.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCapabilities.mm new file mode 100644 index 0000000000..85537a91ad --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCapabilities.mm @@ -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 diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecCapability+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecCapability+Private.h new file mode 100644 index 0000000000..6af13b3b23 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecCapability+Private.h @@ -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 diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecCapability.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecCapability.h new file mode 100644 index 0000000000..5604148e5d --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecCapability.h @@ -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 diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecCapability.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecCapability.mm new file mode 100644 index 0000000000..2dc1e5dc4b --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpCodecCapability.mm @@ -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 ¶meter : 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 diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability+Private.h new file mode 100644 index 0000000000..4e800bc996 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability+Private.h @@ -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 diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability.h new file mode 100644 index 0000000000..7a5d442e6a --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability.h @@ -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 diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability.mm new file mode 100644 index 0000000000..c9af744a92 --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability.mm @@ -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 diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpTransceiver.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpTransceiver.h index fd59013639..1701f680a4 100644 --- a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpTransceiver.h +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpTransceiver.h @@ -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. diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpTransceiver.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpTransceiver.mm index ae1cf79864..eb0ad96738 100644 --- a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpTransceiver.mm +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpTransceiver.mm @@ -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}", diff --git a/third_party/libwebrtc/sdk/objc/unittests/RTCPeerConnectionFactory_xctest.m b/third_party/libwebrtc/sdk/objc/unittests/RTCPeerConnectionFactory_xctest.m index 56c74971b6..7d42b6bdbb 100644 --- a/third_party/libwebrtc/sdk/objc/unittests/RTCPeerConnectionFactory_xctest.m +++ b/third_party/libwebrtc/sdk/objc/unittests/RTCPeerConnectionFactory_xctest.m @@ -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,148 @@ } } +- (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:^(RTC_OBJC_TYPE(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 +558,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 |