blob: 7f6ffbb7e5cafd8e7777fbafce7205cd76872054 [file] [log] [blame]
Anders Carlsson73119182018-03-15 09:41:03 +01001/*
2 * Copyright 2018 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
11#import "NADViewController.h"
12
Anders Carlsson7bca8ca2018-08-30 09:30:29 +020013#import "sdk/objc/base/RTCVideoRenderer.h"
14#import "sdk/objc/components/capturer/RTCCameraVideoCapturer.h"
15#if defined(RTC_SUPPORTS_METAL)
16#import "sdk/objc/components/renderer/metal/RTCMTLVideoView.h" // nogncheck
17#endif
18#import "sdk/objc/components/renderer/opengl/RTCEAGLVideoView.h"
19#import "sdk/objc/helpers/RTCCameraPreviewView.h"
20
Anders Carlsson73119182018-03-15 09:41:03 +010021#include <memory>
22
Steve Anton10542f22019-01-11 09:11:00 -080023#include "examples/objcnativeapi/objc/objc_call_client.h"
Anders Carlsson73119182018-03-15 09:41:03 +010024
25@interface NADViewController ()
26
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020027@property(nonatomic) RTC_OBJC_TYPE(RTCCameraVideoCapturer) * capturer;
28@property(nonatomic) RTC_OBJC_TYPE(RTCCameraPreviewView) * localVideoView;
29@property(nonatomic) __kindof UIView<RTC_OBJC_TYPE(RTCVideoRenderer)> *remoteVideoView;
Anders Carlsson73119182018-03-15 09:41:03 +010030@property(nonatomic) UIButton *callButton;
31@property(nonatomic) UIButton *hangUpButton;
32
33@end
34
35@implementation NADViewController {
36 std::unique_ptr<webrtc_examples::ObjCCallClient> _call_client;
37
38 UIView *_view;
39}
40
41@synthesize capturer = _capturer;
42@synthesize localVideoView = _localVideoView;
43@synthesize remoteVideoView = _remoteVideoView;
44@synthesize callButton = _callButton;
45@synthesize hangUpButton = _hangUpButton;
46
47#pragma mark - View controller lifecycle
48
49- (void)loadView {
50 _view = [[UIView alloc] initWithFrame:CGRectZero];
51
52#if defined(RTC_SUPPORTS_METAL)
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020053 _remoteVideoView = [[RTC_OBJC_TYPE(RTCMTLVideoView) alloc] initWithFrame:CGRectZero];
Anders Carlsson73119182018-03-15 09:41:03 +010054#else
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020055 _remoteVideoView = [[RTC_OBJC_TYPE(RTCEAGLVideoView) alloc] initWithFrame:CGRectZero];
Anders Carlsson73119182018-03-15 09:41:03 +010056#endif
57 _remoteVideoView.translatesAutoresizingMaskIntoConstraints = NO;
58 [_view addSubview:_remoteVideoView];
59
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020060 _localVideoView = [[RTC_OBJC_TYPE(RTCCameraPreviewView) alloc] initWithFrame:CGRectZero];
Anders Carlsson73119182018-03-15 09:41:03 +010061 _localVideoView.translatesAutoresizingMaskIntoConstraints = NO;
62 [_view addSubview:_localVideoView];
63
64 _callButton = [UIButton buttonWithType:UIButtonTypeSystem];
65 _callButton.translatesAutoresizingMaskIntoConstraints = NO;
66 [_callButton setTitle:@"Call" forState:UIControlStateNormal];
67 [_callButton addTarget:self action:@selector(call:) forControlEvents:UIControlEventTouchUpInside];
68 [_view addSubview:_callButton];
69
70 _hangUpButton = [UIButton buttonWithType:UIButtonTypeSystem];
71 _hangUpButton.translatesAutoresizingMaskIntoConstraints = NO;
72 [_hangUpButton setTitle:@"Hang up" forState:UIControlStateNormal];
73 [_hangUpButton addTarget:self
74 action:@selector(hangUp:)
75 forControlEvents:UIControlEventTouchUpInside];
76 [_view addSubview:_hangUpButton];
77
78 UILayoutGuide *margin = _view.layoutMarginsGuide;
79 [_remoteVideoView.leadingAnchor constraintEqualToAnchor:margin.leadingAnchor].active = YES;
80 [_remoteVideoView.topAnchor constraintEqualToAnchor:margin.topAnchor].active = YES;
81 [_remoteVideoView.trailingAnchor constraintEqualToAnchor:margin.trailingAnchor].active = YES;
82 [_remoteVideoView.bottomAnchor constraintEqualToAnchor:margin.bottomAnchor].active = YES;
83
84 [_localVideoView.leadingAnchor constraintEqualToAnchor:margin.leadingAnchor constant:8.0].active =
85 YES;
86 [_localVideoView.topAnchor constraintEqualToAnchor:margin.topAnchor constant:8.0].active = YES;
87 [_localVideoView.widthAnchor constraintEqualToConstant:60].active = YES;
88 [_localVideoView.heightAnchor constraintEqualToConstant:60].active = YES;
89
90 [_callButton.leadingAnchor constraintEqualToAnchor:margin.leadingAnchor constant:8.0].active =
91 YES;
92 [_callButton.bottomAnchor constraintEqualToAnchor:margin.bottomAnchor constant:8.0].active = YES;
93 [_callButton.widthAnchor constraintEqualToConstant:100].active = YES;
94 [_callButton.heightAnchor constraintEqualToConstant:40].active = YES;
95
96 [_hangUpButton.trailingAnchor constraintEqualToAnchor:margin.trailingAnchor constant:8.0].active =
97 YES;
98 [_hangUpButton.bottomAnchor constraintEqualToAnchor:margin.bottomAnchor constant:8.0].active =
99 YES;
100 [_hangUpButton.widthAnchor constraintEqualToConstant:100].active = YES;
101 [_hangUpButton.heightAnchor constraintEqualToConstant:40].active = YES;
102
103 self.view = _view;
104}
105
106- (void)viewDidLoad {
107 [super viewDidLoad];
108
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200109 self.capturer = [[RTC_OBJC_TYPE(RTCCameraVideoCapturer) alloc] init];
Anders Carlsson73119182018-03-15 09:41:03 +0100110 self.localVideoView.captureSession = self.capturer.captureSession;
111
112 _call_client.reset(new webrtc_examples::ObjCCallClient());
113
114 // Start capturer.
115 AVCaptureDevice *selectedDevice = nil;
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200116 NSArray<AVCaptureDevice *> *captureDevices =
117 [RTC_OBJC_TYPE(RTCCameraVideoCapturer) captureDevices];
Anders Carlsson73119182018-03-15 09:41:03 +0100118 for (AVCaptureDevice *device in captureDevices) {
119 if (device.position == AVCaptureDevicePositionFront) {
120 selectedDevice = device;
121 break;
122 }
123 }
124
125 AVCaptureDeviceFormat *selectedFormat = nil;
126 int targetWidth = 640;
127 int targetHeight = 480;
128 int currentDiff = INT_MAX;
129 NSArray<AVCaptureDeviceFormat *> *formats =
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200130 [RTC_OBJC_TYPE(RTCCameraVideoCapturer) supportedFormatsForDevice:selectedDevice];
Anders Carlsson73119182018-03-15 09:41:03 +0100131 for (AVCaptureDeviceFormat *format in formats) {
132 CMVideoDimensions dimension = CMVideoFormatDescriptionGetDimensions(format.formatDescription);
133 FourCharCode pixelFormat = CMFormatDescriptionGetMediaSubType(format.formatDescription);
134 int diff = abs(targetWidth - dimension.width) + abs(targetHeight - dimension.height);
135 if (diff < currentDiff) {
136 selectedFormat = format;
137 currentDiff = diff;
138 } else if (diff == currentDiff && pixelFormat == [_capturer preferredOutputPixelFormat]) {
139 selectedFormat = format;
140 }
141 }
142
143 [self.capturer startCaptureWithDevice:selectedDevice format:selectedFormat fps:30];
144}
145
146- (void)didReceiveMemoryWarning {
147 [super didReceiveMemoryWarning];
148 // Dispose of any resources that can be recreated.
149}
150
151#pragma mark - Actions
152
153- (IBAction)call:(id)sender {
154 _call_client->Call(self.capturer, self.remoteVideoView);
155}
156
157- (IBAction)hangUp:(id)sender {
158 _call_client->Hangup();
159}
160
161@end