blob: beb4a7a91b1600a95530c686cee0a8742e91dd80 [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()) {
39 return _signalingThread->Invoke<NSArray<RTC_OBJC_TYPE(RTCAudioTrack) *> *>(
40 RTC_FROM_HERE, [self]() { return self.audioTracks; });
41 }
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -080042 return [_audioTracks copy];
43}
44
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020045- (NSArray<RTC_OBJC_TYPE(RTCVideoTrack) *> *)videoTracks {
Byoungchan Lee2b46a582022-06-21 09:19:34 +090046 if (!_signalingThread->IsCurrent()) {
47 return _signalingThread->Invoke<NSArray<RTC_OBJC_TYPE(RTCVideoTrack) *> *>(
48 RTC_FROM_HERE, [self]() { return self.videoTracks; });
49 }
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -080050 return [_videoTracks copy];
51}
52
53- (NSString *)streamId {
Artem Titov63ee39d2022-05-13 14:46:42 +000054 return [NSString stringForStdString:_nativeMediaStream->id()];
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -080055}
56
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020057- (void)addAudioTrack:(RTC_OBJC_TYPE(RTCAudioTrack) *)audioTrack {
Byoungchan Lee2b46a582022-06-21 09:19:34 +090058 if (!_signalingThread->IsCurrent()) {
59 return _signalingThread->Invoke<void>(
60 RTC_FROM_HERE, [audioTrack, self]() { return [self addAudioTrack:audioTrack]; });
61 }
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -080062 if (_nativeMediaStream->AddTrack(audioTrack.nativeAudioTrack)) {
63 [_audioTracks addObject:audioTrack];
64 }
65}
66
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020067- (void)addVideoTrack:(RTC_OBJC_TYPE(RTCVideoTrack) *)videoTrack {
Byoungchan Lee2b46a582022-06-21 09:19:34 +090068 if (!_signalingThread->IsCurrent()) {
69 return _signalingThread->Invoke<void>(
70 RTC_FROM_HERE, [videoTrack, self]() { return [self addVideoTrack:videoTrack]; });
71 }
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -080072 if (_nativeMediaStream->AddTrack(videoTrack.nativeVideoTrack)) {
73 [_videoTracks addObject:videoTrack];
74 }
75}
76
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020077- (void)removeAudioTrack:(RTC_OBJC_TYPE(RTCAudioTrack) *)audioTrack {
Byoungchan Lee2b46a582022-06-21 09:19:34 +090078 if (!_signalingThread->IsCurrent()) {
79 return _signalingThread->Invoke<void>(
80 RTC_FROM_HERE, [audioTrack, self]() { return [self removeAudioTrack:audioTrack]; });
81 }
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -080082 NSUInteger index = [_audioTracks indexOfObjectIdenticalTo:audioTrack];
Byoungchan Lee2b46a582022-06-21 09:19:34 +090083 if (index == NSNotFound) {
84 RTC_LOG(LS_INFO) << "|removeAudioTrack| called on unexpected RTC_OBJC_TYPE(RTCAudioTrack)";
85 return;
86 }
87 if (_nativeMediaStream->RemoveTrack(audioTrack.nativeAudioTrack)) {
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -080088 [_audioTracks removeObjectAtIndex:index];
89 }
90}
91
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020092- (void)removeVideoTrack:(RTC_OBJC_TYPE(RTCVideoTrack) *)videoTrack {
Byoungchan Lee2b46a582022-06-21 09:19:34 +090093 if (!_signalingThread->IsCurrent()) {
94 return _signalingThread->Invoke<void>(
95 RTC_FROM_HERE, [videoTrack, self]() { return [self removeVideoTrack:videoTrack]; });
96 }
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -080097 NSUInteger index = [_videoTracks indexOfObjectIdenticalTo:videoTrack];
Byoungchan Lee2b46a582022-06-21 09:19:34 +090098 if (index == NSNotFound) {
99 RTC_LOG(LS_INFO) << "|removeVideoTrack| called on unexpected RTC_OBJC_TYPE(RTCVideoTrack)";
100 return;
101 }
102
103 if (_nativeMediaStream->RemoveTrack(videoTrack.nativeVideoTrack)) {
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -0800104 [_videoTracks removeObjectAtIndex:index];
105 }
106}
107
108- (NSString *)description {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200109 return [NSString stringWithFormat:@"RTC_OBJC_TYPE(RTCMediaStream):\n%@\nA=%lu\nV=%lu",
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -0800110 self.streamId,
111 (unsigned long)self.audioTracks.count,
112 (unsigned long)self.videoTracks.count];
113}
114
115#pragma mark - Private
116
117- (rtc::scoped_refptr<webrtc::MediaStreamInterface>)nativeMediaStream {
118 return _nativeMediaStream;
119}
120
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200121- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300122 nativeMediaStream:
123 (rtc::scoped_refptr<webrtc::MediaStreamInterface>)nativeMediaStream {
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -0800124 NSParameterAssert(nativeMediaStream);
125 if (self = [super init]) {
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300126 _factory = factory;
Byoungchan Lee2b46a582022-06-21 09:19:34 +0900127 _signalingThread = factory.signalingThread;
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300128
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -0800129 webrtc::AudioTrackVector audioTracks = nativeMediaStream->GetAudioTracks();
130 webrtc::VideoTrackVector videoTracks = nativeMediaStream->GetVideoTracks();
131
132 _audioTracks = [NSMutableArray arrayWithCapacity:audioTracks.size()];
133 _videoTracks = [NSMutableArray arrayWithCapacity:videoTracks.size()];
134 _nativeMediaStream = nativeMediaStream;
135
136 for (auto &track : audioTracks) {
137 RTCMediaStreamTrackType type = RTCMediaStreamTrackTypeAudio;
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200138 RTC_OBJC_TYPE(RTCAudioTrack) *audioTrack =
139 [[RTC_OBJC_TYPE(RTCAudioTrack) alloc] initWithFactory:_factory
140 nativeTrack:track
141 type:type];
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -0800142 [_audioTracks addObject:audioTrack];
143 }
144
145 for (auto &track : videoTracks) {
146 RTCMediaStreamTrackType type = RTCMediaStreamTrackTypeVideo;
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200147 RTC_OBJC_TYPE(RTCVideoTrack) *videoTrack =
148 [[RTC_OBJC_TYPE(RTCVideoTrack) alloc] initWithFactory:_factory
149 nativeTrack:track
150 type:type];
Jon Hjelle2bf9a5f2016-01-21 16:14:11 -0800151 [_videoTracks addObject:videoTrack];
152 }
153 }
154 return self;
155}
156
157@end