blob: fb015c620782e8a84aa3fc580764acd29d5ddbb7 [file] [log] [blame]
Jon Hjelleca91e382016-01-21 15:36:47 -08001/*
2 * Copyright 2015 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
tkchin9eeb6242016-04-27 01:54:20 -070011#import "RTCVideoTrack+Private.h"
Jon Hjelleca91e382016-01-21 15:36:47 -080012
tkchin9eeb6242016-04-27 01:54:20 -070013#import "RTCMediaStreamTrack+Private.h"
14#import "RTCPeerConnectionFactory+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070015#import "RTCVideoSource+Private.h"
Anders Carlsson7bca8ca2018-08-30 09:30:29 +020016#import "api/RTCVideoRendererAdapter+Private.h"
Artem Titov63ee39d2022-05-13 14:46:42 +000017#import "helpers/NSString+StdString.h"
Jon Hjelleca91e382016-01-21 15:36:47 -080018
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020019@implementation RTC_OBJC_TYPE (RTCVideoTrack) {
Byoungchan Lee2b46a582022-06-21 09:19:34 +090020 rtc::Thread *_workerThread;
21 NSMutableArray *_adapters /* accessed on _workerThread */;
Jon Hjelleca91e382016-01-21 15:36:47 -080022}
23
24@synthesize source = _source;
25
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020026- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory
27 source:(RTC_OBJC_TYPE(RTCVideoSource) *)source
Jon Hjelleca91e382016-01-21 15:36:47 -080028 trackId:(NSString *)trackId {
29 NSParameterAssert(factory);
30 NSParameterAssert(source);
31 NSParameterAssert(trackId.length);
Artem Titov63ee39d2022-05-13 14:46:42 +000032 std::string nativeId = [NSString stdStringForString:trackId];
Jon Hjelleca91e382016-01-21 15:36:47 -080033 rtc::scoped_refptr<webrtc::VideoTrackInterface> track =
Niels Möller03486fc2022-04-25 10:46:59 +020034 factory.nativeFactory->CreateVideoTrack(nativeId, source.nativeVideoSource.get());
Yura Yaroshevich01cee072018-07-11 15:35:40 +030035 if (self = [self initWithFactory:factory nativeTrack:track type:RTCMediaStreamTrackTypeVideo]) {
hjona2f77982016-03-04 07:09:09 -080036 _source = source;
37 }
38 return self;
Jon Hjelleca91e382016-01-21 15:36:47 -080039}
40
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020041- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory
Yura Yaroshevich01cee072018-07-11 15:35:40 +030042 nativeTrack:
43 (rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)nativeMediaTrack
44 type:(RTCMediaStreamTrackType)type {
45 NSParameterAssert(factory);
Jon Hjelleca91e382016-01-21 15:36:47 -080046 NSParameterAssert(nativeMediaTrack);
47 NSParameterAssert(type == RTCMediaStreamTrackTypeVideo);
Yura Yaroshevich01cee072018-07-11 15:35:40 +030048 if (self = [super initWithFactory:factory nativeTrack:nativeMediaTrack type:type]) {
Jon Hjelleca91e382016-01-21 15:36:47 -080049 _adapters = [NSMutableArray array];
Byoungchan Lee2b46a582022-06-21 09:19:34 +090050 _workerThread = factory.workerThread;
Jon Hjelleca91e382016-01-21 15:36:47 -080051 }
52 return self;
53}
54
55- (void)dealloc {
56 for (RTCVideoRendererAdapter *adapter in _adapters) {
Niels Möller8f597622016-03-23 10:33:07 +010057 self.nativeVideoTrack->RemoveSink(adapter.nativeVideoRenderer);
Jon Hjelleca91e382016-01-21 15:36:47 -080058 }
59}
60
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020061- (RTC_OBJC_TYPE(RTCVideoSource) *)source {
hjona2f77982016-03-04 07:09:09 -080062 if (!_source) {
Niels Möllerac0d1832022-01-17 15:26:54 +010063 rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> source(
64 self.nativeVideoTrack->GetSource());
hjona2f77982016-03-04 07:09:09 -080065 if (source) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020066 _source = [[RTC_OBJC_TYPE(RTCVideoSource) alloc] initWithFactory:self.factory
Niels Möllerac0d1832022-01-17 15:26:54 +010067 nativeVideoSource:source];
hjona2f77982016-03-04 07:09:09 -080068 }
69 }
70 return _source;
71}
72
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020073- (void)addRenderer:(id<RTC_OBJC_TYPE(RTCVideoRenderer)>)renderer {
Byoungchan Lee2b46a582022-06-21 09:19:34 +090074 if (!_workerThread->IsCurrent()) {
75 _workerThread->Invoke<void>(RTC_FROM_HERE, [renderer, self] { [self addRenderer:renderer]; });
76 return;
77 }
78
Jon Hjelleca91e382016-01-21 15:36:47 -080079 // Make sure we don't have this renderer yet.
80 for (RTCVideoRendererAdapter *adapter in _adapters) {
tkchin5fa51e22016-10-05 13:16:03 -070081 if (adapter.videoRenderer == renderer) {
Byoungchan Lee2b46a582022-06-21 09:19:34 +090082 RTC_LOG(LS_INFO) << "|renderer| is already attached to this track";
tkchin5fa51e22016-10-05 13:16:03 -070083 return;
Jon Hjelleca91e382016-01-21 15:36:47 -080084 }
85 }
86 // Create a wrapper that provides a native pointer for us.
87 RTCVideoRendererAdapter* adapter =
88 [[RTCVideoRendererAdapter alloc] initWithNativeRenderer:renderer];
89 [_adapters addObject:adapter];
Niels Möller8f597622016-03-23 10:33:07 +010090 self.nativeVideoTrack->AddOrUpdateSink(adapter.nativeVideoRenderer,
91 rtc::VideoSinkWants());
Jon Hjelleca91e382016-01-21 15:36:47 -080092}
93
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020094- (void)removeRenderer:(id<RTC_OBJC_TYPE(RTCVideoRenderer)>)renderer {
Byoungchan Lee2b46a582022-06-21 09:19:34 +090095 if (!_workerThread->IsCurrent()) {
96 _workerThread->Invoke<void>(RTC_FROM_HERE,
97 [renderer, self] { [self removeRenderer:renderer]; });
98 return;
99 }
Jon Hjelleca91e382016-01-21 15:36:47 -0800100 __block NSUInteger indexToRemove = NSNotFound;
101 [_adapters enumerateObjectsUsingBlock:^(RTCVideoRendererAdapter *adapter,
102 NSUInteger idx,
103 BOOL *stop) {
104 if (adapter.videoRenderer == renderer) {
105 indexToRemove = idx;
106 *stop = YES;
107 }
108 }];
109 if (indexToRemove == NSNotFound) {
Byoungchan Lee2b46a582022-06-21 09:19:34 +0900110 RTC_LOG(LS_INFO) << "removeRenderer called with a renderer that has not been previously added";
Jon Hjelleca91e382016-01-21 15:36:47 -0800111 return;
112 }
hjona2f77982016-03-04 07:09:09 -0800113 RTCVideoRendererAdapter *adapterToRemove =
114 [_adapters objectAtIndex:indexToRemove];
Niels Möller8f597622016-03-23 10:33:07 +0100115 self.nativeVideoTrack->RemoveSink(adapterToRemove.nativeVideoRenderer);
Jon Hjelleca91e382016-01-21 15:36:47 -0800116 [_adapters removeObjectAtIndex:indexToRemove];
117}
118
119#pragma mark - Private
120
121- (rtc::scoped_refptr<webrtc::VideoTrackInterface>)nativeVideoTrack {
Niels Möllerac0d1832022-01-17 15:26:54 +0100122 return rtc::scoped_refptr<webrtc::VideoTrackInterface>(
123 static_cast<webrtc::VideoTrackInterface *>(self.nativeTrack.get()));
Jon Hjelleca91e382016-01-21 15:36:47 -0800124}
125
126@end