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