blob: 0018dd6945c7c68608fb471ea2a15fe93bae1ec5 [file] [log] [blame]
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -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 "RTCMediaStream+Private.h"
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -080012
tkchin9eeb6242016-04-27 01:54:20 -070013#import "RTCAudioTrack+Private.h"
14#import "RTCMediaStreamTrack+Private.h"
15#import "RTCPeerConnectionFactory+Private.h"
16#import "RTCVideoTrack+Private.h"
Artem Titov63ee39d2022-05-13 14:46:42 +000017#import "helpers/NSString+StdString.h"
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -080018
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020019@implementation RTC_OBJC_TYPE (RTCMediaStream) {
20 RTC_OBJC_TYPE(RTCPeerConnectionFactory) * _factory;
Byoungchan Lee2b46a582022-06-21 09:19:34 +090021 rtc::Thread *_signalingThread;
22 NSMutableArray *_audioTracks /* accessed on _signalingThread */;
23 NSMutableArray *_videoTracks /* accessed on _signalingThread */;
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -080024 rtc::scoped_refptr<webrtc::MediaStreamInterface> _nativeMediaStream;
25}
26
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020027- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory
hjona2f77982016-03-04 07:09:09 -080028 streamId:(NSString *)streamId {
29 NSParameterAssert(factory);
30 NSParameterAssert(streamId.length);
Artem Titov63ee39d2022-05-13 14:46:42 +000031 std::string nativeId = [NSString stdStringForString:streamId];
hjona2f77982016-03-04 07:09:09 -080032 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream =
33 factory.nativeFactory->CreateLocalMediaStream(nativeId);
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +030034 return [self initWithFactory:factory nativeMediaStream:stream];
hjona2f77982016-03-04 07:09:09 -080035}
36
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020037- (NSArray<RTC_OBJC_TYPE(RTCAudioTrack) *> *)audioTracks {
Byoungchan Lee2b46a582022-06-21 09:19:34 +090038 if (!_signalingThread->IsCurrent()) {
Danil Chapovalov9e09a1f2022-09-08 18:38:10 +020039 return _signalingThread->BlockingCall([self]() { return self.audioTracks; });
Byoungchan Lee2b46a582022-06-21 09:19:34 +090040 }
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -080041 return [_audioTracks copy];
42}
43
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020044- (NSArray<RTC_OBJC_TYPE(RTCVideoTrack) *> *)videoTracks {
Byoungchan Lee2b46a582022-06-21 09:19:34 +090045 if (!_signalingThread->IsCurrent()) {
Danil Chapovalov9e09a1f2022-09-08 18:38:10 +020046 return _signalingThread->BlockingCall([self]() { return self.videoTracks; });
Byoungchan Lee2b46a582022-06-21 09:19:34 +090047 }
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -080048 return [_videoTracks copy];
49}
50
51- (NSString *)streamId {
Artem Titov63ee39d2022-05-13 14:46:42 +000052 return [NSString stringForStdString:_nativeMediaStream->id()];
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -080053}
54
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020055- (void)addAudioTrack:(RTC_OBJC_TYPE(RTCAudioTrack) *)audioTrack {
Byoungchan Lee2b46a582022-06-21 09:19:34 +090056 if (!_signalingThread->IsCurrent()) {
Danil Chapovalov9e09a1f2022-09-08 18:38:10 +020057 return _signalingThread->BlockingCall(
58 [audioTrack, self]() { return [self addAudioTrack:audioTrack]; });
Byoungchan Lee2b46a582022-06-21 09:19:34 +090059 }
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -080060 if (_nativeMediaStream->AddTrack(audioTrack.nativeAudioTrack)) {
61 [_audioTracks addObject:audioTrack];
62 }
63}
64
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020065- (void)addVideoTrack:(RTC_OBJC_TYPE(RTCVideoTrack) *)videoTrack {
Byoungchan Lee2b46a582022-06-21 09:19:34 +090066 if (!_signalingThread->IsCurrent()) {
Danil Chapovalov9e09a1f2022-09-08 18:38:10 +020067 return _signalingThread->BlockingCall(
68 [videoTrack, self]() { return [self addVideoTrack:videoTrack]; });
Byoungchan Lee2b46a582022-06-21 09:19:34 +090069 }
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -080070 if (_nativeMediaStream->AddTrack(videoTrack.nativeVideoTrack)) {
71 [_videoTracks addObject:videoTrack];
72 }
73}
74
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020075- (void)removeAudioTrack:(RTC_OBJC_TYPE(RTCAudioTrack) *)audioTrack {
Byoungchan Lee2b46a582022-06-21 09:19:34 +090076 if (!_signalingThread->IsCurrent()) {
Danil Chapovalov9e09a1f2022-09-08 18:38:10 +020077 return _signalingThread->BlockingCall(
78 [audioTrack, self]() { return [self removeAudioTrack:audioTrack]; });
Byoungchan Lee2b46a582022-06-21 09:19:34 +090079 }
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -080080 NSUInteger index = [_audioTracks indexOfObjectIdenticalTo:audioTrack];
Byoungchan Lee2b46a582022-06-21 09:19:34 +090081 if (index == NSNotFound) {
82 RTC_LOG(LS_INFO) << "|removeAudioTrack| called on unexpected RTC_OBJC_TYPE(RTCAudioTrack)";
83 return;
84 }
85 if (_nativeMediaStream->RemoveTrack(audioTrack.nativeAudioTrack)) {
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -080086 [_audioTracks removeObjectAtIndex:index];
87 }
88}
89
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020090- (void)removeVideoTrack:(RTC_OBJC_TYPE(RTCVideoTrack) *)videoTrack {
Byoungchan Lee2b46a582022-06-21 09:19:34 +090091 if (!_signalingThread->IsCurrent()) {
Danil Chapovalov9e09a1f2022-09-08 18:38:10 +020092 return _signalingThread->BlockingCall(
93 [videoTrack, self]() { return [self removeVideoTrack:videoTrack]; });
Byoungchan Lee2b46a582022-06-21 09:19:34 +090094 }
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -080095 NSUInteger index = [_videoTracks indexOfObjectIdenticalTo:videoTrack];
Byoungchan Lee2b46a582022-06-21 09:19:34 +090096 if (index == NSNotFound) {
97 RTC_LOG(LS_INFO) << "|removeVideoTrack| called on unexpected RTC_OBJC_TYPE(RTCVideoTrack)";
98 return;
99 }
100
101 if (_nativeMediaStream->RemoveTrack(videoTrack.nativeVideoTrack)) {
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -0800102 [_videoTracks removeObjectAtIndex:index];
103 }
104}
105
106- (NSString *)description {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200107 return [NSString stringWithFormat:@"RTC_OBJC_TYPE(RTCMediaStream):\n%@\nA=%lu\nV=%lu",
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -0800108 self.streamId,
109 (unsigned long)self.audioTracks.count,
110 (unsigned long)self.videoTracks.count];
111}
112
113#pragma mark - Private
114
115- (rtc::scoped_refptr<webrtc::MediaStreamInterface>)nativeMediaStream {
116 return _nativeMediaStream;
117}
118
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200119- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300120 nativeMediaStream:
121 (rtc::scoped_refptr<webrtc::MediaStreamInterface>)nativeMediaStream {
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -0800122 NSParameterAssert(nativeMediaStream);
123 if (self = [super init]) {
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300124 _factory = factory;
Byoungchan Lee2b46a582022-06-21 09:19:34 +0900125 _signalingThread = factory.signalingThread;
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300126
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -0800127 webrtc::AudioTrackVector audioTracks = nativeMediaStream->GetAudioTracks();
128 webrtc::VideoTrackVector videoTracks = nativeMediaStream->GetVideoTracks();
129
130 _audioTracks = [NSMutableArray arrayWithCapacity:audioTracks.size()];
131 _videoTracks = [NSMutableArray arrayWithCapacity:videoTracks.size()];
132 _nativeMediaStream = nativeMediaStream;
133
134 for (auto &track : audioTracks) {
135 RTCMediaStreamTrackType type = RTCMediaStreamTrackTypeAudio;
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200136 RTC_OBJC_TYPE(RTCAudioTrack) *audioTrack =
137 [[RTC_OBJC_TYPE(RTCAudioTrack) alloc] initWithFactory:_factory
138 nativeTrack:track
139 type:type];
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -0800140 [_audioTracks addObject:audioTrack];
141 }
142
143 for (auto &track : videoTracks) {
144 RTCMediaStreamTrackType type = RTCMediaStreamTrackTypeVideo;
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200145 RTC_OBJC_TYPE(RTCVideoTrack) *videoTrack =
146 [[RTC_OBJC_TYPE(RTCVideoTrack) alloc] initWithFactory:_factory
147 nativeTrack:track
148 type:type];
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -0800149 [_videoTracks addObject:videoTrack];
150 }
151 }
152 return self;
153}
154
155@end