From ca91e38a3a4e43dbf0e1f21af005e8540904f829 Mon Sep 17 00:00:00 2001 From: Jon Hjelle Date: Thu, 21 Jan 2016 15:36:47 -0800 Subject: [PATCH] Update API for Objective-C RTCAudioTrack and RTCVideoTrack. BUG= R=tkchin@webrtc.org Review URL: https://codereview.webrtc.org/1553743003 . Patch from Jon Hjelle . Cr-Commit-Position: refs/heads/master@{#11350} --- webrtc/api/BUILD.gn | 6 ++ webrtc/api/api.gyp | 6 ++ webrtc/api/objc/RTCAudioTrack+Private.h | 25 +++++ webrtc/api/objc/RTCAudioTrack.h | 27 +++++ webrtc/api/objc/RTCAudioTrack.mm | 44 ++++++++ webrtc/api/objc/RTCMediaStreamTrack+Private.h | 11 +- webrtc/api/objc/RTCMediaStreamTrack.mm | 5 +- webrtc/api/objc/RTCVideoTrack+Private.h | 25 +++++ webrtc/api/objc/RTCVideoTrack.h | 39 +++++++ webrtc/api/objc/RTCVideoTrack.mm | 100 ++++++++++++++++++ 10 files changed, 284 insertions(+), 4 deletions(-) create mode 100644 webrtc/api/objc/RTCAudioTrack+Private.h create mode 100644 webrtc/api/objc/RTCAudioTrack.h create mode 100644 webrtc/api/objc/RTCAudioTrack.mm create mode 100644 webrtc/api/objc/RTCVideoTrack+Private.h create mode 100644 webrtc/api/objc/RTCVideoTrack.h create mode 100644 webrtc/api/objc/RTCVideoTrack.mm diff --git a/webrtc/api/BUILD.gn b/webrtc/api/BUILD.gn index 0e7a99a5d9..9144984257 100644 --- a/webrtc/api/BUILD.gn +++ b/webrtc/api/BUILD.gn @@ -29,6 +29,9 @@ if (is_ios) { ] sources = [ # Add these when there's a BUILD.gn for peer connection APIs + #"objc/RTCAudioTrack+Private.h", + #"objc/RTCAudioTrack.h", + #"objc/RTCAudioTrack.mm",s #"objc/RTCAVFoundationVideoSource+Private.h", #"objc/RTCAVFoundationVideoSource.h", #"objc/RTCAVFoundationVideoSource.mm", @@ -44,6 +47,9 @@ if (is_ios) { #"objc/RTCVideoSource+Private.h", #"objc/RTCVideoSource.h", #"objc/RTCVideoSource.mm", + #"objc/RTCVideoTrack+Private.h", + #"objc/RTCVideoTrack.h", + #"objc/RTCVideoTrack.mm", "objc/RTCIceServer+Private.h", "objc/RTCIceServer.h", "objc/RTCIceServer.mm", diff --git a/webrtc/api/api.gyp b/webrtc/api/api.gyp index c50a1d2109..5d40cd0f39 100644 --- a/webrtc/api/api.gyp +++ b/webrtc/api/api.gyp @@ -19,6 +19,9 @@ '../../talk/libjingle.gyp:libjingle_peerconnection', ], 'sources': [ + 'objc/RTCAudioTrack+Private.h', + 'objc/RTCAudioTrack.h', + 'objc/RTCAudioTrack.mm', 'objc/RTCAVFoundationVideoSource+Private.h', 'objc/RTCAVFoundationVideoSource.h', 'objc/RTCAVFoundationVideoSource.mm', @@ -55,6 +58,9 @@ 'objc/RTCVideoSource+Private.h', 'objc/RTCVideoSource.h', 'objc/RTCVideoSource.mm', + 'objc/RTCVideoTrack+Private.h', + 'objc/RTCVideoTrack.h', + 'objc/RTCVideoTrack.mm', 'objc/avfoundationvideocapturer.h', 'objc/avfoundationvideocapturer.mm', ], diff --git a/webrtc/api/objc/RTCAudioTrack+Private.h b/webrtc/api/objc/RTCAudioTrack+Private.h new file mode 100644 index 0000000000..36f72c7f25 --- /dev/null +++ b/webrtc/api/objc/RTCAudioTrack+Private.h @@ -0,0 +1,25 @@ +/* + * Copyright 2015 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 "RTCAudioTrack.h" + +#include "talk/app/webrtc/mediastreaminterface.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTCAudioTrack () + +/** AudioTrackInterface created or passed in at construction. */ +@property(nonatomic, readonly) + rtc::scoped_refptr nativeAudioTrack; + +@end + +NS_ASSUME_NONNULL_END diff --git a/webrtc/api/objc/RTCAudioTrack.h b/webrtc/api/objc/RTCAudioTrack.h new file mode 100644 index 0000000000..76036ccec8 --- /dev/null +++ b/webrtc/api/objc/RTCAudioTrack.h @@ -0,0 +1,27 @@ +/* + * Copyright 2015 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 "RTCMediaStreamTrack.h" + +NS_ASSUME_NONNULL_BEGIN + +@class RTCPeerConnectionFactory; + +@interface RTCAudioTrack : RTCMediaStreamTrack + +- (instancetype)init NS_UNAVAILABLE; + +/** Initialize an RTCAudioTrack with an id. */ +- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory + trackId:(NSString *)trackId; + +@end + +NS_ASSUME_NONNULL_END diff --git a/webrtc/api/objc/RTCAudioTrack.mm b/webrtc/api/objc/RTCAudioTrack.mm new file mode 100644 index 0000000000..158d1b362b --- /dev/null +++ b/webrtc/api/objc/RTCAudioTrack.mm @@ -0,0 +1,44 @@ +/* + * Copyright 2015 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 "RTCAudioTrack.h" + +#import "webrtc/api/objc/RTCAudioTrack+Private.h" +#import "webrtc/api/objc/RTCMediaStreamTrack+Private.h" +#import "webrtc/api/objc/RTCPeerConnectionFactory+Private.h" +#import "webrtc/base/objc/NSString+StdString.h" + +@implementation RTCAudioTrack + +- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory + trackId:(NSString *)trackId { + NSParameterAssert(factory); + NSParameterAssert(trackId.length); + std::string nativeId = [NSString stdStringForString:trackId]; + rtc::scoped_refptr track = + factory.nativeFactory->CreateAudioTrack(nativeId, nullptr); + return [self initWithNativeTrack:track type:RTCMediaStreamTrackTypeAudio]; +} + +- (instancetype)initWithNativeTrack: + (rtc::scoped_refptr)nativeTrack + type:(RTCMediaStreamTrackType)type { + NSParameterAssert(nativeTrack); + NSParameterAssert(type == RTCMediaStreamTrackTypeAudio); + return [super initWithNativeTrack:nativeTrack type:type]; +} + +#pragma mark - Private + +- (rtc::scoped_refptr)nativeAudioTrack { + return static_cast(self.nativeTrack.get()); +} + +@end diff --git a/webrtc/api/objc/RTCMediaStreamTrack+Private.h b/webrtc/api/objc/RTCMediaStreamTrack+Private.h index 3e17e63cd3..fcdcdad2ba 100644 --- a/webrtc/api/objc/RTCMediaStreamTrack+Private.h +++ b/webrtc/api/objc/RTCMediaStreamTrack+Private.h @@ -13,14 +13,18 @@ #include "talk/app/webrtc/mediastreaminterface.h" #include "webrtc/base/scoped_ptr.h" +typedef NS_ENUM(NSInteger, RTCMediaStreamTrackType) { + RTCMediaStreamTrackTypeAudio, + RTCMediaStreamTrackTypeVideo, +}; + NS_ASSUME_NONNULL_BEGIN @interface RTCMediaStreamTrack () /** - * The native MediaStreamTrackInterface representation of this - * RTCMediaStreamTrack object. This is needed to pass to the underlying C++ - * APIs. + * The native MediaStreamTrackInterface passed in or created during + * construction. */ @property(nonatomic, readonly) rtc::scoped_refptr nativeTrack; @@ -30,6 +34,7 @@ NS_ASSUME_NONNULL_BEGIN */ - (instancetype)initWithNativeTrack: (rtc::scoped_refptr)nativeTrack + type:(RTCMediaStreamTrackType)type NS_DESIGNATED_INITIALIZER; + (webrtc::MediaStreamTrackInterface::TrackState)nativeTrackStateForState: diff --git a/webrtc/api/objc/RTCMediaStreamTrack.mm b/webrtc/api/objc/RTCMediaStreamTrack.mm index e5751b0746..260c89d66e 100644 --- a/webrtc/api/objc/RTCMediaStreamTrack.mm +++ b/webrtc/api/objc/RTCMediaStreamTrack.mm @@ -15,6 +15,7 @@ @implementation RTCMediaStreamTrack { rtc::scoped_refptr _nativeTrack; + RTCMediaStreamTrackType _type; } - (NSString *)kind { @@ -53,10 +54,12 @@ } - (instancetype)initWithNativeTrack: - (rtc::scoped_refptr)nativeTrack { + (rtc::scoped_refptr)nativeTrack + type:(RTCMediaStreamTrackType)type { NSParameterAssert(nativeTrack); if (self = [super init]) { _nativeTrack = nativeTrack; + _type = type; } return self; } diff --git a/webrtc/api/objc/RTCVideoTrack+Private.h b/webrtc/api/objc/RTCVideoTrack+Private.h new file mode 100644 index 0000000000..4f55481b55 --- /dev/null +++ b/webrtc/api/objc/RTCVideoTrack+Private.h @@ -0,0 +1,25 @@ +/* + * Copyright 2015 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 "RTCVideoTrack.h" + +#include "talk/app/webrtc/mediastreaminterface.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTCVideoTrack () + +/** VideoTrackInterface created or passed in at construction. */ +@property(nonatomic, readonly) + rtc::scoped_refptr nativeVideoTrack; + +@end + +NS_ASSUME_NONNULL_END diff --git a/webrtc/api/objc/RTCVideoTrack.h b/webrtc/api/objc/RTCVideoTrack.h new file mode 100644 index 0000000000..e8dad3b9e1 --- /dev/null +++ b/webrtc/api/objc/RTCVideoTrack.h @@ -0,0 +1,39 @@ +/* + * Copyright 2015 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 "RTCMediaStreamTrack.h" + +NS_ASSUME_NONNULL_BEGIN + +@protocol RTCVideoRenderer; +@class RTCPeerConnectionFactory; +@class RTCVideoSource; + +@interface RTCVideoTrack : RTCMediaStreamTrack + +/** The video source for this video track. */ +@property(nonatomic, readonly) RTCVideoSource *source; + +- (instancetype)init NS_UNAVAILABLE; + +/** Initialize an RTCVideoTrack with its source and an id. */ +- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory + source:(RTCVideoSource *)source + trackId:(NSString *)trackId; + +/** Register a renderer that will render all frames received on this track. */ +- (void)addRenderer:(id)renderer; + +/** Deregister a renderer. */ +- (void)removeRenderer:(id)renderer; + +@end + +NS_ASSUME_NONNULL_END diff --git a/webrtc/api/objc/RTCVideoTrack.mm b/webrtc/api/objc/RTCVideoTrack.mm new file mode 100644 index 0000000000..7422eff926 --- /dev/null +++ b/webrtc/api/objc/RTCVideoTrack.mm @@ -0,0 +1,100 @@ +/* + * Copyright 2015 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 "RTCVideoTrack.h" + +#import "webrtc/api/objc/RTCMediaStreamTrack+Private.h" +#import "webrtc/api/objc/RTCPeerConnectionFactory+Private.h" +#import "webrtc/api/objc/RTCVideoRendererAdapter+Private.h" +#import "webrtc/api/objc/RTCVideoSource+Private.h" +#import "webrtc/api/objc/RTCVideoTrack+Private.h" +#import "webrtc/base/objc/NSString+StdString.h" + +@implementation RTCVideoTrack { + NSMutableArray *_adapters; +} + +@synthesize source = _source; + +- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory + source:(RTCVideoSource *)source + trackId:(NSString *)trackId { + NSParameterAssert(factory); + NSParameterAssert(source); + NSParameterAssert(trackId.length); + std::string nativeId = [NSString stdStringForString:trackId]; + rtc::scoped_refptr track = + factory.nativeFactory->CreateVideoTrack(nativeId, + source.nativeVideoSource); + return [self initWithNativeTrack:track type:RTCMediaStreamTrackTypeVideo]; +} + +- (instancetype)initWithNativeMediaTrack: + (rtc::scoped_refptr)nativeMediaTrack + type:(RTCMediaStreamTrackType)type { + NSParameterAssert(nativeMediaTrack); + NSParameterAssert(type == RTCMediaStreamTrackTypeVideo); + if (self = [super initWithNativeTrack:nativeMediaTrack type:type]) { + _adapters = [NSMutableArray array]; + rtc::scoped_refptr source = + self.nativeVideoTrack->GetSource(); + if (source) { + _source = [[RTCVideoSource alloc] initWithNativeVideoSource:source.get()]; + } + } + return self; +} + +- (void)dealloc { + for (RTCVideoRendererAdapter *adapter in _adapters) { + self.nativeVideoTrack->RemoveRenderer(adapter.nativeVideoRenderer); + } +} + +- (void)addRenderer:(id)renderer { + // Make sure we don't have this renderer yet. + for (RTCVideoRendererAdapter *adapter in _adapters) { + // Getting around unused variable error + if (adapter.videoRenderer != renderer) { + NSAssert(NO, @"|renderer| is already attached to this track"); + } + } + // Create a wrapper that provides a native pointer for us. + RTCVideoRendererAdapter* adapter = + [[RTCVideoRendererAdapter alloc] initWithNativeRenderer:renderer]; + [_adapters addObject:adapter]; + self.nativeVideoTrack->AddRenderer(adapter.nativeVideoRenderer); +} + +- (void)removeRenderer:(id)renderer { + RTCVideoRendererAdapter *adapter; + __block NSUInteger indexToRemove = NSNotFound; + [_adapters enumerateObjectsUsingBlock:^(RTCVideoRendererAdapter *adapter, + NSUInteger idx, + BOOL *stop) { + if (adapter.videoRenderer == renderer) { + indexToRemove = idx; + *stop = YES; + } + }]; + if (indexToRemove == NSNotFound) { + return; + } + self.nativeVideoTrack->RemoveRenderer(adapter.nativeVideoRenderer); + [_adapters removeObjectAtIndex:indexToRemove]; +} + +#pragma mark - Private + +- (rtc::scoped_refptr)nativeVideoTrack { + return static_cast(self.nativeTrack.get()); +} + +@end