• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
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
13#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
21#include <memory>
22
23#include "examples/objcnativeapi/objc/objc_call_client.h"
24
25@interface NADViewController ()
26
27@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;
30@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)
53  _remoteVideoView = [[RTC_OBJC_TYPE(RTCMTLVideoView) alloc] initWithFrame:CGRectZero];
54#else
55  _remoteVideoView = [[RTC_OBJC_TYPE(RTCEAGLVideoView) alloc] initWithFrame:CGRectZero];
56#endif
57  _remoteVideoView.translatesAutoresizingMaskIntoConstraints = NO;
58  [_view addSubview:_remoteVideoView];
59
60  _localVideoView = [[RTC_OBJC_TYPE(RTCCameraPreviewView) alloc] initWithFrame:CGRectZero];
61  _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
109  self.capturer = [[RTC_OBJC_TYPE(RTCCameraVideoCapturer) alloc] init];
110  self.localVideoView.captureSession = self.capturer.captureSession;
111
112  _call_client.reset(new webrtc_examples::ObjCCallClient());
113
114  // Start capturer.
115  AVCaptureDevice *selectedDevice = nil;
116  NSArray<AVCaptureDevice *> *captureDevices =
117      [RTC_OBJC_TYPE(RTCCameraVideoCapturer) captureDevices];
118  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 =
130      [RTC_OBJC_TYPE(RTCCameraVideoCapturer) supportedFormatsForDevice:selectedDevice];
131  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
162