Skip to content

Commit

Permalink
Darwin improvements
Browse files Browse the repository at this point in the history
[Mac/iOS] feat: Add RTCYUVHelper for darwin. (#28)

Cross-platform `RTCMTLVideoView` for both iOS / macOS (#40)

rotationOverride should not be assign (#44)

[ObjC] Expose properties / methods required for AV1 codec support (#60)

Workaround: Render PixelBuffer in RTCMTLVideoView (#58)

Improve iOS/macOS H264 encoder (#70)

fix: fix video encoder not resuming correctly upon foregrounding (#75).

add PrivacyInfo.xcprivacy to darwin frameworks. (#112)

Add NSPrivacyCollectedDataTypes key to xcprivacy file (#114)

Thread-safe `RTCInitFieldTrialDictionary` (#116)

Co-authored-by: Hiroshi Horie <[email protected]>
  • Loading branch information
cloudwebrtc and hiroshihorie committed May 22, 2024
1 parent 9aaaab5 commit e71c396
Show file tree
Hide file tree
Showing 18 changed files with 661 additions and 222 deletions.
21 changes: 16 additions & 5 deletions sdk/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,15 @@ if (is_ios || is_mac) {
"objc/helpers/RTCDispatcher+Private.h",
"objc/helpers/RTCDispatcher.h",
"objc/helpers/RTCDispatcher.m",
"objc/helpers/RTCYUVHelper.h",
"objc/helpers/RTCYUVHelper.mm",
"objc/helpers/scoped_cftyperef.h",
]

deps = [
":base_objc",
"../rtc_base:checks",
"//third_party/libyuv",
]

absl_deps = [ "//third_party/abseil-cpp/absl/strings" ]
Expand Down Expand Up @@ -617,17 +620,13 @@ if (is_ios || is_mac) {
"Metal.framework",
"MetalKit.framework",
]
if (is_ios) {
if (is_ios || is_mac) {
sources += [
"objc/components/renderer/metal/RTCMTLVideoView.h",
"objc/components/renderer/metal/RTCMTLVideoView.m",
]
}
if (is_mac) {
sources += [
"objc/components/renderer/metal/RTCMTLNSVideoView.h",
"objc/components/renderer/metal/RTCMTLNSVideoView.m",
]
frameworks += [ "AppKit.framework" ]
}
deps = [
Expand Down Expand Up @@ -1287,6 +1286,13 @@ if (is_ios || is_mac) {
}
}

bundle_data("darwin_privacy_info") {
sources = [
"objc/PrivacyInfo.xcprivacy",
]
outputs = [ "{{bundle_resources_dir}}/{{source_file_part}}" ]
}

if (is_ios) {
apple_framework_bundle_with_umbrella_header("framework_objc") {
info_plist = "objc/Info.plist"
Expand Down Expand Up @@ -1334,6 +1340,7 @@ if (is_ios || is_mac) {
"objc/components/video_frame_buffer/RTCCVPixelBuffer.h",
"objc/helpers/RTCCameraPreviewView.h",
"objc/helpers/RTCDispatcher.h",
"objc/helpers/RTCYUVHelper.h",
"objc/helpers/UIDevice+RTCDevice.h",
"objc/api/peerconnection/RTCAudioDeviceModule.h",
"objc/api/peerconnection/RTCIODevice.h",
Expand Down Expand Up @@ -1417,6 +1424,7 @@ if (is_ios || is_mac) {
":videocapture_objc",
":videocodec_objc",
":videotoolbox_objc",
":darwin_privacy_info",
]
if (!build_with_chromium) {
deps += [
Expand Down Expand Up @@ -1526,6 +1534,7 @@ if (is_ios || is_mac) {
"objc/base/RTCYUVPlanarBuffer.h",
"objc/components/capturer/RTCCameraVideoCapturer.h",
"objc/components/capturer/RTCFileVideoCapturer.h",
"objc/components/renderer/metal/RTCMTLVideoView.h",
"objc/components/renderer/metal/RTCMTLNSVideoView.h",
"objc/components/renderer/opengl/RTCVideoViewShading.h",
"objc/components/video_codec/RTCCodecSpecificInfoH264.h",
Expand All @@ -1538,6 +1547,7 @@ if (is_ios || is_mac) {
"objc/components/video_codec/RTCVideoEncoderH264.h",
"objc/components/video_frame_buffer/RTCCVPixelBuffer.h",
"objc/helpers/RTCDispatcher.h",
"objc/helpers/RTCYUVHelper.h",
# Added for Simulcast support
"objc/components/video_codec/RTCVideoEncoderFactorySimulcast.h",
"objc/api/video_codec/RTCVideoEncoderSimulcast.h",
Expand All @@ -1558,6 +1568,7 @@ if (is_ios || is_mac) {
":videocapture_objc",
":videocodec_objc",
":videotoolbox_objc",
":darwin_privacy_info",
]
if (!build_with_chromium) {
deps += [
Expand Down
28 changes: 28 additions & 0 deletions sdk/objc/PrivacyInfo.xcprivacy
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyCollectedDataTypes</key>
<array/>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>35F9.1</string>
<string>8FFB.1</string>
</array>
</dict>
</array>
</dict>
</plist>
31 changes: 21 additions & 10 deletions sdk/objc/api/peerconnection/RTCFieldTrials.mm
Original file line number Diff line number Diff line change
Expand Up @@ -10,47 +10,58 @@

#import "RTCFieldTrials.h"

#import <os/lock.h>
#include <memory>

#import "base/RTCLogging.h"

#include "system_wrappers/include/field_trial.h"

NSString *const kRTCFieldTrialAudioForceABWENoTWCCKey = @"WebRTC-Audio-ABWENoTWCC";
NSString * const kRTCFieldTrialFlexFec03AdvertisedKey = @"WebRTC-FlexFEC-03-Advertised";
NSString * const kRTCFieldTrialFlexFec03Key = @"WebRTC-FlexFEC-03";
NSString * const kRTCFieldTrialH264HighProfileKey = @"WebRTC-H264HighProfile";
NSString * const kRTCFieldTrialMinimizeResamplingOnMobileKey =
NSString *const kRTCFieldTrialFlexFec03AdvertisedKey = @"WebRTC-FlexFEC-03-Advertised";
NSString *const kRTCFieldTrialFlexFec03Key = @"WebRTC-FlexFEC-03";
NSString *const kRTCFieldTrialH264HighProfileKey = @"WebRTC-H264HighProfile";
NSString *const kRTCFieldTrialMinimizeResamplingOnMobileKey =
@"WebRTC-Audio-MinimizeResamplingOnMobile";
NSString *const kRTCFieldTrialUseNWPathMonitor = @"WebRTC-Network-UseNWPathMonitor";
NSString * const kRTCFieldTrialEnabledValue = @"Enabled";
NSString *const kRTCFieldTrialEnabledValue = @"Enabled";

// InitFieldTrialsFromString stores the char*, so the char array must outlive
// the application.
static char *gFieldTrialInitString = nullptr;
static os_unfair_lock fieldTrialLock = OS_UNFAIR_LOCK_INIT;

void RTCInitFieldTrialDictionary(NSDictionary<NSString *, NSString *> *fieldTrials) {
if (!fieldTrials) {
RTCLogWarning(@"No fieldTrials provided.");
return;
}

// Assemble the keys and values into the field trial string.
// We don't perform any extra format checking. That should be done by the underlying WebRTC calls.
NSMutableString *fieldTrialInitString = [NSMutableString string];
for (NSString *key in fieldTrials) {
NSString *fieldTrialEntry = [NSString stringWithFormat:@"%@/%@/", key, fieldTrials[key]];
[fieldTrialInitString appendString:fieldTrialEntry];
}

size_t len = fieldTrialInitString.length + 1;

// Locking before modifying global variable
os_unfair_lock_lock(&fieldTrialLock);
if (gFieldTrialInitString != nullptr) {
delete[] gFieldTrialInitString;
gFieldTrialInitString = nullptr;
}

gFieldTrialInitString = new char[len];
if (![fieldTrialInitString getCString:gFieldTrialInitString
maxLength:len
encoding:NSUTF8StringEncoding]) {
bool success = [fieldTrialInitString getCString:gFieldTrialInitString
maxLength:len
encoding:NSUTF8StringEncoding];
if (!success) {
RTCLogError(@"Failed to convert field trial string.");
os_unfair_lock_unlock(&fieldTrialLock);
return;
}

webrtc::field_trial::InitFieldTrialsFromString(gFieldTrialInitString);
os_unfair_lock_unlock(&fieldTrialLock);
}
4 changes: 4 additions & 0 deletions sdk/objc/api/peerconnection/RTCPeerConnectionFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ NS_ASSUME_NONNULL_BEGIN
@class RTC_OBJC_TYPE(RTCVideoTrack);
@class RTC_OBJC_TYPE(RTCPeerConnectionFactoryOptions);
@class RTC_OBJC_TYPE(RTCAudioDeviceModule);
@class RTC_OBJC_TYPE(RTCRtpCapabilities);

typedef NS_ENUM(NSInteger, RTCRtpMediaType);

@protocol RTC_OBJC_TYPE
(RTCPeerConnectionDelegate);
@protocol RTC_OBJC_TYPE
Expand Down
17 changes: 17 additions & 0 deletions sdk/objc/api/peerconnection/RTCPeerConnectionFactory.mm
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
#import "RTCPeerConnection+Private.h"
#import "RTCVideoSource+Private.h"
#import "RTCVideoTrack+Private.h"
#import "RTCRtpReceiver+Private.h"
#import "RTCRtpCapabilities+Private.h"
#import "RTCRtpCodecCapability+Private.h"
#import "base/RTCLogging.h"
#import "base/RTCVideoDecoderFactory.h"
#import "base/RTCVideoEncoderFactory.h"
Expand Down Expand Up @@ -130,6 +133,20 @@ - (instancetype)init {
#endif
}

- (RTC_OBJC_TYPE(RTCRtpCapabilities) *)rtpSenderCapabilitiesFor:(RTCRtpMediaType)mediaType {

webrtc::RtpCapabilities capabilities = _nativeFactory->GetRtpSenderCapabilities([RTCRtpReceiver nativeMediaTypeForMediaType: mediaType]);

return [[RTCRtpCapabilities alloc] initWithNativeRtpCapabilities: capabilities];
}

- (RTC_OBJC_TYPE(RTCRtpCapabilities) *)rtpReceiverCapabilitiesFor:(RTCRtpMediaType)mediaType {

webrtc::RtpCapabilities capabilities = _nativeFactory->GetRtpReceiverCapabilities([RTCRtpReceiver nativeMediaTypeForMediaType: mediaType]);

return [[RTCRtpCapabilities alloc] initWithNativeRtpCapabilities: capabilities];
}

- (instancetype)
initWithBypassVoiceProcessing:(BOOL)bypassVoiceProcessing
encoderFactory:(nullable id<RTC_OBJC_TYPE(RTCVideoEncoderFactory)>)encoderFactory
Expand Down
1 change: 1 addition & 0 deletions sdk/objc/api/peerconnection/RTCRtpCodecParameters.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ RTC_EXTERN const NSString *const kRTCComfortNoiseCodecName;
RTC_EXTERN const NSString *const kRTCVp8CodecName;
RTC_EXTERN const NSString *const kRTCVp9CodecName;
RTC_EXTERN const NSString *const kRTCH264CodecName;
RTC_EXTERN const NSString *const kRTCAv1CodecName;

/** Defined in https://www.w3.org/TR/webrtc/#idl-def-rtcrtpcodecparameters */
RTC_OBJC_EXPORT
Expand Down
1 change: 1 addition & 0 deletions sdk/objc/api/peerconnection/RTCRtpCodecParameters.mm
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
const NSString * const kRTCVp8CodecName = @(cricket::kVp8CodecName);
const NSString * const kRTCVp9CodecName = @(cricket::kVp9CodecName);
const NSString * const kRTCH264CodecName = @(cricket::kH264CodecName);
const NSString * const kRTCAv1CodecName = @(cricket::kAv1CodecName);

@implementation RTC_OBJC_TYPE (RTCRtpCodecParameters)

Expand Down
4 changes: 4 additions & 0 deletions sdk/objc/api/peerconnection/RTCRtpEncodingParameters.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ RTC_OBJC_EXPORT
https://w3c.github.io/webrtc-extensions/#dom-rtcrtpencodingparameters-adaptiveptime */
@property(nonatomic, assign) BOOL adaptiveAudioPacketTime;

/** A case-sensitive identifier of the scalability mode to be used for this stream.
https://w3c.github.io/webrtc-svc/#rtcrtpencodingparameters */
@property(nonatomic, copy, nullable) NSString *scalabilityMode;

- (instancetype)init;

@end
Expand Down
7 changes: 7 additions & 0 deletions sdk/objc/api/peerconnection/RTCRtpEncodingParameters.mm
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ @implementation RTC_OBJC_TYPE (RTCRtpEncodingParameters)
@synthesize bitratePriority = _bitratePriority;
@synthesize networkPriority = _networkPriority;
@synthesize adaptiveAudioPacketTime = _adaptiveAudioPacketTime;
@synthesize scalabilityMode = _scalabilityMode;

- (instancetype)init {
webrtc::RtpEncodingParameters nativeParameters;
Expand Down Expand Up @@ -59,6 +60,9 @@ - (instancetype)initWithNativeParameters:
if (nativeParameters.ssrc) {
_ssrc = [NSNumber numberWithUnsignedLong:*nativeParameters.ssrc];
}
if (nativeParameters.scalability_mode) {
_scalabilityMode = [NSString stringWithUTF8String:nativeParameters.scalability_mode->c_str()];
}
_bitratePriority = nativeParameters.bitrate_priority;
_networkPriority = [RTC_OBJC_TYPE(RTCRtpEncodingParameters)
priorityFromNativePriority:nativeParameters.network_priority];
Expand Down Expand Up @@ -92,6 +96,9 @@ - (instancetype)initWithNativeParameters:
if (_ssrc != nil) {
parameters.ssrc = absl::optional<uint32_t>(_ssrc.unsignedLongValue);
}
if (_scalabilityMode != nil) {
parameters.scalability_mode = absl::optional<std::string>(std::string([_scalabilityMode UTF8String]));
}
parameters.bitrate_priority = _bitratePriority;
parameters.network_priority =
[RTC_OBJC_TYPE(RTCRtpEncodingParameters) nativePriorityFromPriority:_networkPriority];
Expand Down
4 changes: 4 additions & 0 deletions sdk/objc/api/peerconnection/RTCRtpTransceiver.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#import "RTCRtpReceiver.h"
#import "RTCRtpSender.h"

@class RTC_OBJC_TYPE(RTCRtpCodecCapability);

NS_ASSUME_NONNULL_BEGIN

extern NSString *const kRTCRtpTransceiverErrorDomain;
Expand Down Expand Up @@ -105,6 +107,8 @@ RTC_OBJC_EXPORT
*/
@property(nonatomic, readonly) RTCRtpTransceiverDirection direction;

@property(nonatomic, copy) NSArray<RTC_OBJC_TYPE(RTCRtpCodecCapability) *> *codecPreferences;

/** The currentDirection attribute indicates the current direction negotiated
* for this transceiver. If this transceiver has never been represented in an
* offer/answer exchange, or if the transceiver is stopped, the value is not
Expand Down
16 changes: 16 additions & 0 deletions sdk/objc/api/peerconnection/RTCRtpTransceiver.mm
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#import "RTCRtpParameters+Private.h"
#import "RTCRtpReceiver+Private.h"
#import "RTCRtpSender+Private.h"
#import "RTCRtpCodecCapability.h"
#import "RTCRtpCodecCapability+Private.h"
#import "base/RTCLogging.h"
#import "helpers/NSString+StdString.h"

Expand Down Expand Up @@ -68,6 +70,20 @@ - (NSString *)mid {
}
}

- (NSArray<RTC_OBJC_TYPE(RTCRtpCodecCapability) *> *)codecPreferences {

NSMutableArray *result = [NSMutableArray array];

std::vector<webrtc::RtpCodecCapability> capabilities = _nativeRtpTransceiver->codec_preferences();

for (auto & element : capabilities) {
RTCRtpCodecCapability *object = [[RTCRtpCodecCapability alloc] initWithNativeRtpCodecCapability: element];
[result addObject: object];
}

return result;
}

@synthesize sender = _sender;
@synthesize receiver = _receiver;

Expand Down
Loading

0 comments on commit e71c396

Please sign in to comment.