blob: cb82e888880644cb688f4bfeb282255d1eb089c0 [file] [log] [blame]
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +00001/*
Donald E Curtisa8736442015-08-05 15:48:13 -07002 * Copyright 2014 The WebRTC Project Authors. All rights reserved.
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +00003 *
Donald E Curtisa8736442015-08-05 15:48:13 -07004 * 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.
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +00009 */
10
11#import "APPRTCViewController.h"
12
13#import <AVFoundation/AVFoundation.h>
tkchin9eeb6242016-04-27 01:54:20 -070014
denicija124a6fc2017-03-31 02:47:29 -070015#import "WebRTC/RTCMTLNSVideoView.h"
tkchin9eeb6242016-04-27 01:54:20 -070016#import "WebRTC/RTCNSGLVideoView.h"
17#import "WebRTC/RTCVideoTrack.h"
hjon79858f82016-03-13 22:08:26 -070018
tkchin@webrtc.org87776a82014-12-09 19:32:35 +000019#import "ARDAppClient.h"
sakalc522e752017-04-05 12:17:48 -070020#import "ARDCaptureController.h"
sakalc4adacf2017-03-28 01:22:48 -070021#import "ARDSettingsModel.h"
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +000022
denicija647915f2016-10-20 01:46:41 -070023static NSUInteger const kContentWidth = 900;
24static NSUInteger const kRoomFieldWidth = 200;
25static NSUInteger const kActionItemHeight = 30;
26static NSUInteger const kBottomViewHeight = 200;
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +000027
28@class APPRTCMainView;
29@protocol APPRTCMainViewDelegate
30
31- (void)appRTCMainView:(APPRTCMainView*)mainView
denicija647915f2016-10-20 01:46:41 -070032 didEnterRoomId:(NSString*)roomId
33 loopback:(BOOL)isLoopback;
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +000034
35@end
36
37@interface APPRTCMainView : NSView
38
39@property(nonatomic, weak) id<APPRTCMainViewDelegate> delegate;
denicija124a6fc2017-03-31 02:47:29 -070040@property(nonatomic, readonly) NSView<RTCVideoRenderer>* localVideoView;
41@property(nonatomic, readonly) NSView<RTCVideoRenderer>* remoteVideoView;
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +000042
43- (void)displayLogMessage:(NSString*)message;
44
45@end
46
47@interface APPRTCMainView () <NSTextFieldDelegate, RTCNSGLVideoViewDelegate>
48@end
49@implementation APPRTCMainView {
50 NSScrollView* _scrollView;
denicija647915f2016-10-20 01:46:41 -070051 NSView* _actionItemsView;
52 NSButton* _connectButton;
53 NSButton* _loopbackButton;
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +000054 NSTextField* _roomField;
55 NSTextView* _logView;
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +000056 CGSize _localVideoSize;
57 CGSize _remoteVideoSize;
58}
59
tkchin2ddfdba2016-08-07 21:37:45 -070060@synthesize delegate = _delegate;
61@synthesize localVideoView = _localVideoView;
62@synthesize remoteVideoView = _remoteVideoView;
63
denicija647915f2016-10-20 01:46:41 -070064
65- (void)displayLogMessage:(NSString *)message {
adam.fedor8c6afef2017-06-13 05:25:33 -070066 dispatch_async(dispatch_get_main_queue(), ^{
67 _logView.string =
68 [NSString stringWithFormat:@"%@%@\n", _logView.string, message];
69 NSRange range = NSMakeRange(_logView.string.length, 0);
70 [_logView scrollRangeToVisible:range];
71 });
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +000072}
73
denicija647915f2016-10-20 01:46:41 -070074#pragma mark - Private
75
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +000076- (instancetype)initWithFrame:(NSRect)frame {
77 if (self = [super initWithFrame:frame]) {
78 [self setupViews];
79 }
80 return self;
81}
82
denicija647915f2016-10-20 01:46:41 -070083+ (BOOL)requiresConstraintBasedLayout {
84 return YES;
85}
86
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +000087- (void)updateConstraints {
88 NSParameterAssert(
denicija647915f2016-10-20 01:46:41 -070089 _roomField != nil &&
90 _scrollView != nil &&
91 _remoteVideoView != nil &&
92 _localVideoView != nil &&
93 _actionItemsView!= nil &&
94 _connectButton != nil &&
95 _loopbackButton != nil);
96
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +000097 [self removeConstraints:[self constraints]];
98 NSDictionary* viewsDictionary =
denicija647915f2016-10-20 01:46:41 -070099 NSDictionaryOfVariableBindings(_roomField,
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000100 _scrollView,
kthelgason314bc5f2016-08-31 10:23:27 -0700101 _remoteVideoView,
denicija647915f2016-10-20 01:46:41 -0700102 _localVideoView,
103 _actionItemsView,
104 _connectButton,
105 _loopbackButton);
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000106
107 NSSize remoteViewSize = [self remoteVideoViewSize];
108 NSDictionary* metrics = @{
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000109 @"remoteViewWidth" : @(remoteViewSize.width),
110 @"remoteViewHeight" : @(remoteViewSize.height),
denicija647915f2016-10-20 01:46:41 -0700111 @"kBottomViewHeight" : @(kBottomViewHeight),
112 @"localViewHeight" : @(remoteViewSize.height / 3),
113 @"localViewWidth" : @(remoteViewSize.width / 3),
114 @"kRoomFieldWidth" : @(kRoomFieldWidth),
115 @"kActionItemHeight" : @(kActionItemHeight)
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000116 };
117 // Declare this separately to avoid compiler warning about splitting string
118 // within an NSArray expression.
denicija647915f2016-10-20 01:46:41 -0700119 NSString* verticalConstraintLeft =
120 @"V:|-[_remoteVideoView(remoteViewHeight)]-[_scrollView(kBottomViewHeight)]-|";
121 NSString* verticalConstraintRight =
122 @"V:|-[_remoteVideoView(remoteViewHeight)]-[_actionItemsView(kBottomViewHeight)]-|";
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000123 NSArray* constraintFormats = @[
denicija647915f2016-10-20 01:46:41 -0700124 verticalConstraintLeft,
125 verticalConstraintRight,
126 @"H:|-[_remoteVideoView(remoteViewWidth)]-|",
127 @"V:|-[_localVideoView(localViewHeight)]",
128 @"H:|-[_localVideoView(localViewWidth)]",
129 @"H:|-[_scrollView(==_actionItemsView)]-[_actionItemsView]-|"
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000130 ];
denicija647915f2016-10-20 01:46:41 -0700131
132 NSArray* actionItemsConstraints = @[
133 @"H:|-[_roomField(kRoomFieldWidth)]-[_loopbackButton(kRoomFieldWidth)]",
134 @"H:|-[_connectButton(kRoomFieldWidth)]",
135 @"V:|-[_roomField(kActionItemHeight)]-[_connectButton(kActionItemHeight)]",
136 @"V:|-[_loopbackButton(kActionItemHeight)]",
137 ];
138
139 [APPRTCMainView addConstraints:constraintFormats
140 toView:self
141 viewsDictionary:viewsDictionary
142 metrics:metrics];
143 [APPRTCMainView addConstraints:actionItemsConstraints
144 toView:_actionItemsView
145 viewsDictionary:viewsDictionary
146 metrics:metrics];
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000147 [super updateConstraints];
148}
149
denicija647915f2016-10-20 01:46:41 -0700150#pragma mark - Constraints helper
151
152+ (void)addConstraints:(NSArray*)constraints toView:(NSView*)view
153 viewsDictionary:(NSDictionary*)viewsDictionary
154 metrics:(NSDictionary*)metrics {
155 for (NSString* constraintFormat in constraints) {
156 NSArray* constraints =
157 [NSLayoutConstraint constraintsWithVisualFormat:constraintFormat
158 options:0
159 metrics:metrics
160 views:viewsDictionary];
161 for (NSLayoutConstraint* constraint in constraints) {
162 [view addConstraint:constraint];
163 }
164 }
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000165}
166
denicija647915f2016-10-20 01:46:41 -0700167#pragma mark - Control actions
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000168
denicija647915f2016-10-20 01:46:41 -0700169- (void)startCall:(id)sender {
170 NSString* roomString = _roomField.stringValue;
171 // Generate room id for loopback options.
172 if (_loopbackButton.intValue && [roomString isEqualToString:@""]) {
173 roomString = [NSUUID UUID].UUIDString;
174 roomString = [roomString stringByReplacingOccurrencesOfString:@"-" withString:@""];
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000175 }
denicija647915f2016-10-20 01:46:41 -0700176 [self.delegate appRTCMainView:self
177 didEnterRoomId:roomString
178 loopback:_loopbackButton.intValue];
denicija124a6fc2017-03-31 02:47:29 -0700179 [self setNeedsUpdateConstraints:YES];
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000180}
181
182#pragma mark - RTCNSGLVideoViewDelegate
183
184- (void)videoView:(RTCNSGLVideoView*)videoView
185 didChangeVideoSize:(NSSize)size {
186 if (videoView == _remoteVideoView) {
187 _remoteVideoSize = size;
188 } else if (videoView == _localVideoView) {
189 _localVideoSize = size;
190 } else {
191 return;
192 }
denicija647915f2016-10-20 01:46:41 -0700193
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000194 [self setNeedsUpdateConstraints:YES];
195}
196
197#pragma mark - Private
198
199- (void)setupViews {
200 NSParameterAssert([[self subviews] count] == 0);
201
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000202 _logView = [[NSTextView alloc] initWithFrame:NSZeroRect];
denicija647915f2016-10-20 01:46:41 -0700203 [_logView setMinSize:NSMakeSize(0, kBottomViewHeight)];
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000204 [_logView setMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)];
205 [_logView setVerticallyResizable:YES];
206 [_logView setAutoresizingMask:NSViewWidthSizable];
207 NSTextContainer* textContainer = [_logView textContainer];
208 NSSize containerSize = NSMakeSize(kContentWidth, FLT_MAX);
209 [textContainer setContainerSize:containerSize];
210 [textContainer setWidthTracksTextView:YES];
211 [_logView setEditable:NO];
212
denicija647915f2016-10-20 01:46:41 -0700213 [self setupActionItemsView];
214
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000215 _scrollView = [[NSScrollView alloc] initWithFrame:NSZeroRect];
216 [_scrollView setTranslatesAutoresizingMaskIntoConstraints:NO];
217 [_scrollView setHasVerticalScroller:YES];
218 [_scrollView setDocumentView:_logView];
219 [self addSubview:_scrollView];
220
denicija124a6fc2017-03-31 02:47:29 -0700221// NOTE (daniela): Ignoring Clang diagonstic here.
222// We're performing run time check to make sure class is available on runtime.
223// If not we're providing sensible default.
224#pragma clang diagnostic push
225#pragma clang diagnostic ignored "-Wpartial-availability"
adam.fedor42742a52017-06-12 07:32:02 -0700226 if ([RTCMTLNSVideoView class] && [RTCMTLNSVideoView isMetalAvailable]) {
denicija124a6fc2017-03-31 02:47:29 -0700227 _remoteVideoView = [[RTCMTLNSVideoView alloc] initWithFrame:NSZeroRect];
228 _localVideoView = [[RTCMTLNSVideoView alloc] initWithFrame:NSZeroRect];
adam.fedor42742a52017-06-12 07:32:02 -0700229 }
230#pragma clang diagnostic pop
231 if (_remoteVideoView == nil) {
denicija124a6fc2017-03-31 02:47:29 -0700232 NSOpenGLPixelFormatAttribute attributes[] = {
233 NSOpenGLPFADoubleBuffer,
234 NSOpenGLPFADepthSize, 24,
235 NSOpenGLPFAOpenGLProfile,
236 NSOpenGLProfileVersion3_2Core,
237 0
238 };
239 NSOpenGLPixelFormat* pixelFormat =
240 [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
241
242 RTCNSGLVideoView* remote =
243 [[RTCNSGLVideoView alloc] initWithFrame:NSZeroRect pixelFormat:pixelFormat];
244 remote.delegate = self;
245 _remoteVideoView = remote;
246
247 RTCNSGLVideoView* local =
248 [[RTCNSGLVideoView alloc] initWithFrame:NSZeroRect pixelFormat:pixelFormat];
249 local.delegate = self;
250 _localVideoView = local;
251 }
denicija124a6fc2017-03-31 02:47:29 -0700252
253 [_remoteVideoView setTranslatesAutoresizingMaskIntoConstraints:NO];
254 [self addSubview:_remoteVideoView];
kthelgason314bc5f2016-08-31 10:23:27 -0700255 [_localVideoView setTranslatesAutoresizingMaskIntoConstraints:NO];
kthelgason314bc5f2016-08-31 10:23:27 -0700256 [self addSubview:_localVideoView];
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000257}
258
denicija647915f2016-10-20 01:46:41 -0700259- (void)setupActionItemsView {
260 _actionItemsView = [[NSView alloc] initWithFrame:NSZeroRect];
261 [_actionItemsView setTranslatesAutoresizingMaskIntoConstraints:NO];
262 [self addSubview:_actionItemsView];
263
264 _roomField = [[NSTextField alloc] initWithFrame:NSZeroRect];
265 [_roomField setTranslatesAutoresizingMaskIntoConstraints:NO];
magjeda445b9b2017-02-20 07:56:53 -0800266 [[_roomField cell] setPlaceholderString: @"Enter AppRTC room id"];
denicija647915f2016-10-20 01:46:41 -0700267 [_actionItemsView addSubview:_roomField];
268 [_roomField setEditable:YES];
269
270 _connectButton = [[NSButton alloc] initWithFrame:NSZeroRect];
271 [_connectButton setTranslatesAutoresizingMaskIntoConstraints:NO];
272 _connectButton.title = @"Start call";
273 _connectButton.bezelStyle = NSRoundedBezelStyle;
274 _connectButton.target = self;
275 _connectButton.action = @selector(startCall:);
276 [_actionItemsView addSubview:_connectButton];
277
278 _loopbackButton = [[NSButton alloc] initWithFrame:NSZeroRect];
279 [_loopbackButton setTranslatesAutoresizingMaskIntoConstraints:NO];
280 _loopbackButton.title = @"Loopback";
281 [_loopbackButton setButtonType:NSSwitchButton];
282 [_actionItemsView addSubview:_loopbackButton];
283}
284
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000285- (NSSize)remoteVideoViewSize {
denicija647915f2016-10-20 01:46:41 -0700286 if (!_remoteVideoView.bounds.size.width) {
287 return NSMakeSize(kContentWidth, 0);
288 }
289 NSInteger width = MAX(_remoteVideoView.bounds.size.width, kContentWidth);
kthelgason314bc5f2016-08-31 10:23:27 -0700290 NSInteger height = (width/16) * 9;
291 return NSMakeSize(width, height);
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000292}
293
294@end
295
296@interface APPRTCViewController ()
tkchin@webrtc.org87776a82014-12-09 19:32:35 +0000297 <ARDAppClientDelegate, APPRTCMainViewDelegate>
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000298@property(nonatomic, readonly) APPRTCMainView* mainView;
299@end
300
301@implementation APPRTCViewController {
tkchin@webrtc.org87776a82014-12-09 19:32:35 +0000302 ARDAppClient* _client;
tkchin@webrtc.org81257442014-11-04 23:06:15 +0000303 RTCVideoTrack* _localVideoTrack;
304 RTCVideoTrack* _remoteVideoTrack;
sakalc522e752017-04-05 12:17:48 -0700305 ARDCaptureController* _captureController;
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000306}
307
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000308- (void)dealloc {
309 [self disconnect];
310}
311
denicija647915f2016-10-20 01:46:41 -0700312- (void)viewDidAppear {
313 [super viewDidAppear];
314 [self displayUsageInstructions];
315}
316
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000317- (void)loadView {
318 APPRTCMainView* view = [[APPRTCMainView alloc] initWithFrame:NSZeroRect];
319 [view setTranslatesAutoresizingMaskIntoConstraints:NO];
320 view.delegate = self;
321 self.view = view;
322}
323
324- (void)windowWillClose:(NSNotification*)notification {
325 [self disconnect];
326}
327
denicija647915f2016-10-20 01:46:41 -0700328#pragma mark - Usage
329
330- (void)displayUsageInstructions {
331 [self.mainView displayLogMessage:
332 @"To start call:\n"
333 @"• Enter AppRTC room id (not neccessary for loopback)\n"
334 @"• Start call"];
335}
336
tkchin@webrtc.org87776a82014-12-09 19:32:35 +0000337#pragma mark - ARDAppClientDelegate
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000338
tkchin@webrtc.org87776a82014-12-09 19:32:35 +0000339- (void)appClient:(ARDAppClient *)client
340 didChangeState:(ARDAppClientState)state {
341 switch (state) {
342 case kARDAppClientStateConnected:
denicija647915f2016-10-20 01:46:41 -0700343 [self.mainView displayLogMessage:@"Client connected."];
tkchin@webrtc.org87776a82014-12-09 19:32:35 +0000344 break;
345 case kARDAppClientStateConnecting:
denicija647915f2016-10-20 01:46:41 -0700346 [self.mainView displayLogMessage:@"Client connecting."];
tkchin@webrtc.org87776a82014-12-09 19:32:35 +0000347 break;
348 case kARDAppClientStateDisconnected:
denicija647915f2016-10-20 01:46:41 -0700349 [self.mainView displayLogMessage:@"Client disconnected."];
tkchin@webrtc.org87776a82014-12-09 19:32:35 +0000350 [self resetUI];
351 _client = nil;
352 break;
353 }
354}
355
356- (void)appClient:(ARDAppClient *)client
hjon79858f82016-03-13 22:08:26 -0700357 didChangeConnectionState:(RTCIceConnectionState)state {
tkchin@webrtc.org3a63a3c2015-01-06 07:21:34 +0000358}
359
sakalc522e752017-04-05 12:17:48 -0700360- (void)appClient:(ARDAppClient*)client
361 didCreateLocalCapturer:(RTCCameraVideoCapturer*)localCapturer {
362 _captureController =
363 [[ARDCaptureController alloc] initWithCapturer:localCapturer
364 settings:[[ARDSettingsModel alloc] init]];
365 [_captureController startCapture];
366}
367
tkchin@webrtc.org3a63a3c2015-01-06 07:21:34 +0000368- (void)appClient:(ARDAppClient *)client
tkchin@webrtc.org87776a82014-12-09 19:32:35 +0000369 didReceiveLocalVideoTrack:(RTCVideoTrack *)localVideoTrack {
tkchin@webrtc.org81257442014-11-04 23:06:15 +0000370 _localVideoTrack = localVideoTrack;
kthelgason314bc5f2016-08-31 10:23:27 -0700371 [_localVideoTrack addRenderer:self.mainView.localVideoView];
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000372}
373
tkchin@webrtc.org87776a82014-12-09 19:32:35 +0000374- (void)appClient:(ARDAppClient *)client
375 didReceiveRemoteVideoTrack:(RTCVideoTrack *)remoteVideoTrack {
tkchin@webrtc.org81257442014-11-04 23:06:15 +0000376 _remoteVideoTrack = remoteVideoTrack;
377 [_remoteVideoTrack addRenderer:self.mainView.remoteVideoView];
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000378}
379
tkchin@webrtc.org87776a82014-12-09 19:32:35 +0000380- (void)appClient:(ARDAppClient *)client
381 didError:(NSError *)error {
382 [self showAlertWithMessage:[NSString stringWithFormat:@"%@", error]];
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000383 [self disconnect];
384}
385
Zeke Chind3325802015-08-14 11:00:02 -0700386- (void)appClient:(ARDAppClient *)client
387 didGetStats:(NSArray *)stats {
388}
389
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000390#pragma mark - APPRTCMainViewDelegate
391
392- (void)appRTCMainView:(APPRTCMainView*)mainView
denicija647915f2016-10-20 01:46:41 -0700393 didEnterRoomId:(NSString*)roomId
394 loopback:(BOOL)isLoopback {
395
396 if ([roomId isEqualToString:@""]) {
397 [self.mainView displayLogMessage:@"Missing room id"];
398 return;
399 }
400
sakalc522e752017-04-05 12:17:48 -0700401 [self disconnect];
sakalc4adacf2017-03-28 01:22:48 -0700402 ARDAppClient* client = [[ARDAppClient alloc] initWithDelegate:self];
tkchinab1293a2016-08-30 12:35:05 -0700403 [client connectToRoomWithId:roomId
sakalc4adacf2017-03-28 01:22:48 -0700404 settings:[[ARDSettingsModel alloc] init] // Use default settings.
Anders Carlssone1500582017-06-15 16:05:13 +0200405 isLoopback:isLoopback];
tkchin@webrtc.org87776a82014-12-09 19:32:35 +0000406 _client = client;
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000407}
408
409#pragma mark - Private
410
411- (APPRTCMainView*)mainView {
412 return (APPRTCMainView*)self.view;
413}
414
415- (void)showAlertWithMessage:(NSString*)message {
adam.fedor8c6afef2017-06-13 05:25:33 -0700416 dispatch_async(dispatch_get_main_queue(), ^{
417 NSAlert* alert = [[NSAlert alloc] init];
418 [alert setMessageText:message];
419 [alert runModal];
420 });
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000421}
422
tkchin@webrtc.org87776a82014-12-09 19:32:35 +0000423- (void)resetUI {
tkchin@webrtc.org81257442014-11-04 23:06:15 +0000424 [_remoteVideoTrack removeRenderer:self.mainView.remoteVideoView];
kthelgason314bc5f2016-08-31 10:23:27 -0700425 [_localVideoTrack removeRenderer:self.mainView.localVideoView];
tkchin@webrtc.org81257442014-11-04 23:06:15 +0000426 _remoteVideoTrack = nil;
kthelgason314bc5f2016-08-31 10:23:27 -0700427 _localVideoTrack = nil;
tkchin@webrtc.org81257442014-11-04 23:06:15 +0000428 [self.mainView.remoteVideoView renderFrame:nil];
kthelgason314bc5f2016-08-31 10:23:27 -0700429 [self.mainView.localVideoView renderFrame:nil];
tkchin@webrtc.org87776a82014-12-09 19:32:35 +0000430}
431
432- (void)disconnect {
433 [self resetUI];
sakalc522e752017-04-05 12:17:48 -0700434 [_captureController stopCapture];
435 _captureController = nil;
tkchin@webrtc.org87776a82014-12-09 19:32:35 +0000436 [_client disconnect];
tkchin@webrtc.orgacca6752014-05-30 22:26:06 +0000437}
438
439@end