1/* 2 * libjingle 3 * Copyright 2013 Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28#if !defined(__has_feature) || !__has_feature(objc_arc) 29#error "This file requires ARC support." 30#endif 31 32#import "RTCVideoTrack+Internal.h" 33 34#import "RTCMediaStreamTrack+Internal.h" 35#import "RTCPeerConnectionFactory+Internal.h" 36#import "RTCVideoRendererAdapter.h" 37#import "RTCMediaSource+Internal.h" 38#import "RTCVideoSource+Internal.h" 39 40@implementation RTCVideoTrack { 41 NSMutableArray* _adapters; 42} 43 44@synthesize source = _source; 45 46- (instancetype)initWithFactory:(RTCPeerConnectionFactory*)factory 47 source:(RTCVideoSource*)source 48 trackId:(NSString*)trackId { 49 NSParameterAssert(factory); 50 NSParameterAssert(source); 51 NSParameterAssert(trackId.length); 52 rtc::scoped_refptr<webrtc::VideoTrackInterface> track = 53 factory.nativeFactory->CreateVideoTrack([trackId UTF8String], 54 source.videoSource); 55 if (self = [super initWithMediaTrack:track]) { 56 [self configure]; 57 _source = source; 58 } 59 return self; 60} 61 62- (instancetype)initWithMediaTrack: 63 (rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)mediaTrack { 64 if (self = [super initWithMediaTrack:mediaTrack]) { 65 [self configure]; 66 rtc::scoped_refptr<webrtc::VideoSourceInterface> source = 67 self.nativeVideoTrack->GetSource(); 68 if (source) { 69 _source = [[RTCVideoSource alloc] initWithMediaSource:source.get()]; 70 } 71 } 72 return self; 73} 74 75- (void)configure { 76 _adapters = [NSMutableArray array]; 77} 78 79- (void)dealloc { 80 for (RTCVideoRendererAdapter *adapter in _adapters) { 81 self.nativeVideoTrack->RemoveRenderer(adapter.nativeVideoRenderer); 82 } 83} 84 85- (void)addRenderer:(id<RTCVideoRenderer>)renderer { 86 // Make sure we don't have this renderer yet. 87 for (RTCVideoRendererAdapter* adapter in _adapters) { 88 NSParameterAssert(adapter.videoRenderer != renderer); 89 } 90 // Create a wrapper that provides a native pointer for us. 91 RTCVideoRendererAdapter* adapter = 92 [[RTCVideoRendererAdapter alloc] initWithVideoRenderer:renderer]; 93 [_adapters addObject:adapter]; 94 self.nativeVideoTrack->AddRenderer(adapter.nativeVideoRenderer); 95} 96 97- (void)removeRenderer:(id<RTCVideoRenderer>)renderer { 98 RTCVideoRendererAdapter* adapter = nil; 99 NSUInteger indexToRemove = NSNotFound; 100 for (NSUInteger i = 0; i < _adapters.count; i++) { 101 adapter = _adapters[i]; 102 if (adapter.videoRenderer == renderer) { 103 indexToRemove = i; 104 break; 105 } 106 } 107 if (indexToRemove == NSNotFound) { 108 return; 109 } 110 self.nativeVideoTrack->RemoveRenderer(adapter.nativeVideoRenderer); 111 [_adapters removeObjectAtIndex:indexToRemove]; 112} 113 114@end 115 116@implementation RTCVideoTrack (Internal) 117 118- (rtc::scoped_refptr<webrtc::VideoTrackInterface>)nativeVideoTrack { 119 return static_cast<webrtc::VideoTrackInterface*>(self.mediaTrack.get()); 120} 121 122@end 123