1*d9f75844SAndroid Build Coastguard Worker/* 2*d9f75844SAndroid Build Coastguard Worker * Copyright 2018 The WebRTC Project Authors. All rights reserved. 3*d9f75844SAndroid Build Coastguard Worker * 4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*d9f75844SAndroid Build Coastguard Worker */ 10*d9f75844SAndroid Build Coastguard Worker 11*d9f75844SAndroid Build Coastguard Worker#import "NADViewController.h" 12*d9f75844SAndroid Build Coastguard Worker 13*d9f75844SAndroid Build Coastguard Worker#import "sdk/objc/base/RTCVideoRenderer.h" 14*d9f75844SAndroid Build Coastguard Worker#import "sdk/objc/components/capturer/RTCCameraVideoCapturer.h" 15*d9f75844SAndroid Build Coastguard Worker#import "sdk/objc/components/renderer/metal/RTCMTLVideoView.h" 16*d9f75844SAndroid Build Coastguard Worker#import "sdk/objc/helpers/RTCCameraPreviewView.h" 17*d9f75844SAndroid Build Coastguard Worker 18*d9f75844SAndroid Build Coastguard Worker#include <memory> 19*d9f75844SAndroid Build Coastguard Worker 20*d9f75844SAndroid Build Coastguard Worker#include "examples/objcnativeapi/objc/objc_call_client.h" 21*d9f75844SAndroid Build Coastguard Worker 22*d9f75844SAndroid Build Coastguard Worker@interface NADViewController () 23*d9f75844SAndroid Build Coastguard Worker 24*d9f75844SAndroid Build Coastguard Worker@property(nonatomic) RTC_OBJC_TYPE(RTCCameraVideoCapturer) * capturer; 25*d9f75844SAndroid Build Coastguard Worker@property(nonatomic) RTC_OBJC_TYPE(RTCCameraPreviewView) * localVideoView; 26*d9f75844SAndroid Build Coastguard Worker@property(nonatomic) __kindof UIView<RTC_OBJC_TYPE(RTCVideoRenderer)> *remoteVideoView; 27*d9f75844SAndroid Build Coastguard Worker@property(nonatomic) UIButton *callButton; 28*d9f75844SAndroid Build Coastguard Worker@property(nonatomic) UIButton *hangUpButton; 29*d9f75844SAndroid Build Coastguard Worker 30*d9f75844SAndroid Build Coastguard Worker@end 31*d9f75844SAndroid Build Coastguard Worker 32*d9f75844SAndroid Build Coastguard Worker@implementation NADViewController { 33*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<webrtc_examples::ObjCCallClient> _call_client; 34*d9f75844SAndroid Build Coastguard Worker 35*d9f75844SAndroid Build Coastguard Worker UIView *_view; 36*d9f75844SAndroid Build Coastguard Worker} 37*d9f75844SAndroid Build Coastguard Worker 38*d9f75844SAndroid Build Coastguard Worker@synthesize capturer = _capturer; 39*d9f75844SAndroid Build Coastguard Worker@synthesize localVideoView = _localVideoView; 40*d9f75844SAndroid Build Coastguard Worker@synthesize remoteVideoView = _remoteVideoView; 41*d9f75844SAndroid Build Coastguard Worker@synthesize callButton = _callButton; 42*d9f75844SAndroid Build Coastguard Worker@synthesize hangUpButton = _hangUpButton; 43*d9f75844SAndroid Build Coastguard Worker 44*d9f75844SAndroid Build Coastguard Worker#pragma mark - View controller lifecycle 45*d9f75844SAndroid Build Coastguard Worker 46*d9f75844SAndroid Build Coastguard Worker- (void)loadView { 47*d9f75844SAndroid Build Coastguard Worker _view = [[UIView alloc] initWithFrame:CGRectZero]; 48*d9f75844SAndroid Build Coastguard Worker 49*d9f75844SAndroid Build Coastguard Worker _remoteVideoView = [[RTC_OBJC_TYPE(RTCMTLVideoView) alloc] initWithFrame:CGRectZero]; 50*d9f75844SAndroid Build Coastguard Worker _remoteVideoView.translatesAutoresizingMaskIntoConstraints = NO; 51*d9f75844SAndroid Build Coastguard Worker [_view addSubview:_remoteVideoView]; 52*d9f75844SAndroid Build Coastguard Worker 53*d9f75844SAndroid Build Coastguard Worker _localVideoView = [[RTC_OBJC_TYPE(RTCCameraPreviewView) alloc] initWithFrame:CGRectZero]; 54*d9f75844SAndroid Build Coastguard Worker _localVideoView.translatesAutoresizingMaskIntoConstraints = NO; 55*d9f75844SAndroid Build Coastguard Worker [_view addSubview:_localVideoView]; 56*d9f75844SAndroid Build Coastguard Worker 57*d9f75844SAndroid Build Coastguard Worker _callButton = [UIButton buttonWithType:UIButtonTypeSystem]; 58*d9f75844SAndroid Build Coastguard Worker _callButton.translatesAutoresizingMaskIntoConstraints = NO; 59*d9f75844SAndroid Build Coastguard Worker [_callButton setTitle:@"Call" forState:UIControlStateNormal]; 60*d9f75844SAndroid Build Coastguard Worker [_callButton addTarget:self action:@selector(call:) forControlEvents:UIControlEventTouchUpInside]; 61*d9f75844SAndroid Build Coastguard Worker [_view addSubview:_callButton]; 62*d9f75844SAndroid Build Coastguard Worker 63*d9f75844SAndroid Build Coastguard Worker _hangUpButton = [UIButton buttonWithType:UIButtonTypeSystem]; 64*d9f75844SAndroid Build Coastguard Worker _hangUpButton.translatesAutoresizingMaskIntoConstraints = NO; 65*d9f75844SAndroid Build Coastguard Worker [_hangUpButton setTitle:@"Hang up" forState:UIControlStateNormal]; 66*d9f75844SAndroid Build Coastguard Worker [_hangUpButton addTarget:self 67*d9f75844SAndroid Build Coastguard Worker action:@selector(hangUp:) 68*d9f75844SAndroid Build Coastguard Worker forControlEvents:UIControlEventTouchUpInside]; 69*d9f75844SAndroid Build Coastguard Worker [_view addSubview:_hangUpButton]; 70*d9f75844SAndroid Build Coastguard Worker 71*d9f75844SAndroid Build Coastguard Worker UILayoutGuide *margin = _view.layoutMarginsGuide; 72*d9f75844SAndroid Build Coastguard Worker [_remoteVideoView.leadingAnchor constraintEqualToAnchor:margin.leadingAnchor].active = YES; 73*d9f75844SAndroid Build Coastguard Worker [_remoteVideoView.topAnchor constraintEqualToAnchor:margin.topAnchor].active = YES; 74*d9f75844SAndroid Build Coastguard Worker [_remoteVideoView.trailingAnchor constraintEqualToAnchor:margin.trailingAnchor].active = YES; 75*d9f75844SAndroid Build Coastguard Worker [_remoteVideoView.bottomAnchor constraintEqualToAnchor:margin.bottomAnchor].active = YES; 76*d9f75844SAndroid Build Coastguard Worker 77*d9f75844SAndroid Build Coastguard Worker [_localVideoView.leadingAnchor constraintEqualToAnchor:margin.leadingAnchor constant:8.0].active = 78*d9f75844SAndroid Build Coastguard Worker YES; 79*d9f75844SAndroid Build Coastguard Worker [_localVideoView.topAnchor constraintEqualToAnchor:margin.topAnchor constant:8.0].active = YES; 80*d9f75844SAndroid Build Coastguard Worker [_localVideoView.widthAnchor constraintEqualToConstant:60].active = YES; 81*d9f75844SAndroid Build Coastguard Worker [_localVideoView.heightAnchor constraintEqualToConstant:60].active = YES; 82*d9f75844SAndroid Build Coastguard Worker 83*d9f75844SAndroid Build Coastguard Worker [_callButton.leadingAnchor constraintEqualToAnchor:margin.leadingAnchor constant:8.0].active = 84*d9f75844SAndroid Build Coastguard Worker YES; 85*d9f75844SAndroid Build Coastguard Worker [_callButton.bottomAnchor constraintEqualToAnchor:margin.bottomAnchor constant:8.0].active = YES; 86*d9f75844SAndroid Build Coastguard Worker [_callButton.widthAnchor constraintEqualToConstant:100].active = YES; 87*d9f75844SAndroid Build Coastguard Worker [_callButton.heightAnchor constraintEqualToConstant:40].active = YES; 88*d9f75844SAndroid Build Coastguard Worker 89*d9f75844SAndroid Build Coastguard Worker [_hangUpButton.trailingAnchor constraintEqualToAnchor:margin.trailingAnchor constant:8.0].active = 90*d9f75844SAndroid Build Coastguard Worker YES; 91*d9f75844SAndroid Build Coastguard Worker [_hangUpButton.bottomAnchor constraintEqualToAnchor:margin.bottomAnchor constant:8.0].active = 92*d9f75844SAndroid Build Coastguard Worker YES; 93*d9f75844SAndroid Build Coastguard Worker [_hangUpButton.widthAnchor constraintEqualToConstant:100].active = YES; 94*d9f75844SAndroid Build Coastguard Worker [_hangUpButton.heightAnchor constraintEqualToConstant:40].active = YES; 95*d9f75844SAndroid Build Coastguard Worker 96*d9f75844SAndroid Build Coastguard Worker self.view = _view; 97*d9f75844SAndroid Build Coastguard Worker} 98*d9f75844SAndroid Build Coastguard Worker 99*d9f75844SAndroid Build Coastguard Worker- (void)viewDidLoad { 100*d9f75844SAndroid Build Coastguard Worker [super viewDidLoad]; 101*d9f75844SAndroid Build Coastguard Worker 102*d9f75844SAndroid Build Coastguard Worker self.capturer = [[RTC_OBJC_TYPE(RTCCameraVideoCapturer) alloc] init]; 103*d9f75844SAndroid Build Coastguard Worker self.localVideoView.captureSession = self.capturer.captureSession; 104*d9f75844SAndroid Build Coastguard Worker 105*d9f75844SAndroid Build Coastguard Worker _call_client.reset(new webrtc_examples::ObjCCallClient()); 106*d9f75844SAndroid Build Coastguard Worker 107*d9f75844SAndroid Build Coastguard Worker // Start capturer. 108*d9f75844SAndroid Build Coastguard Worker AVCaptureDevice *selectedDevice = nil; 109*d9f75844SAndroid Build Coastguard Worker NSArray<AVCaptureDevice *> *captureDevices = 110*d9f75844SAndroid Build Coastguard Worker [RTC_OBJC_TYPE(RTCCameraVideoCapturer) captureDevices]; 111*d9f75844SAndroid Build Coastguard Worker for (AVCaptureDevice *device in captureDevices) { 112*d9f75844SAndroid Build Coastguard Worker if (device.position == AVCaptureDevicePositionFront) { 113*d9f75844SAndroid Build Coastguard Worker selectedDevice = device; 114*d9f75844SAndroid Build Coastguard Worker break; 115*d9f75844SAndroid Build Coastguard Worker } 116*d9f75844SAndroid Build Coastguard Worker } 117*d9f75844SAndroid Build Coastguard Worker 118*d9f75844SAndroid Build Coastguard Worker AVCaptureDeviceFormat *selectedFormat = nil; 119*d9f75844SAndroid Build Coastguard Worker int targetWidth = 640; 120*d9f75844SAndroid Build Coastguard Worker int targetHeight = 480; 121*d9f75844SAndroid Build Coastguard Worker int currentDiff = INT_MAX; 122*d9f75844SAndroid Build Coastguard Worker NSArray<AVCaptureDeviceFormat *> *formats = 123*d9f75844SAndroid Build Coastguard Worker [RTC_OBJC_TYPE(RTCCameraVideoCapturer) supportedFormatsForDevice:selectedDevice]; 124*d9f75844SAndroid Build Coastguard Worker for (AVCaptureDeviceFormat *format in formats) { 125*d9f75844SAndroid Build Coastguard Worker CMVideoDimensions dimension = CMVideoFormatDescriptionGetDimensions(format.formatDescription); 126*d9f75844SAndroid Build Coastguard Worker FourCharCode pixelFormat = CMFormatDescriptionGetMediaSubType(format.formatDescription); 127*d9f75844SAndroid Build Coastguard Worker int diff = abs(targetWidth - dimension.width) + abs(targetHeight - dimension.height); 128*d9f75844SAndroid Build Coastguard Worker if (diff < currentDiff) { 129*d9f75844SAndroid Build Coastguard Worker selectedFormat = format; 130*d9f75844SAndroid Build Coastguard Worker currentDiff = diff; 131*d9f75844SAndroid Build Coastguard Worker } else if (diff == currentDiff && pixelFormat == [_capturer preferredOutputPixelFormat]) { 132*d9f75844SAndroid Build Coastguard Worker selectedFormat = format; 133*d9f75844SAndroid Build Coastguard Worker } 134*d9f75844SAndroid Build Coastguard Worker } 135*d9f75844SAndroid Build Coastguard Worker 136*d9f75844SAndroid Build Coastguard Worker [self.capturer startCaptureWithDevice:selectedDevice format:selectedFormat fps:30]; 137*d9f75844SAndroid Build Coastguard Worker} 138*d9f75844SAndroid Build Coastguard Worker 139*d9f75844SAndroid Build Coastguard Worker- (void)didReceiveMemoryWarning { 140*d9f75844SAndroid Build Coastguard Worker [super didReceiveMemoryWarning]; 141*d9f75844SAndroid Build Coastguard Worker // Dispose of any resources that can be recreated. 142*d9f75844SAndroid Build Coastguard Worker} 143*d9f75844SAndroid Build Coastguard Worker 144*d9f75844SAndroid Build Coastguard Worker#pragma mark - Actions 145*d9f75844SAndroid Build Coastguard Worker 146*d9f75844SAndroid Build Coastguard Worker- (IBAction)call:(id)sender { 147*d9f75844SAndroid Build Coastguard Worker _call_client->Call(self.capturer, self.remoteVideoView); 148*d9f75844SAndroid Build Coastguard Worker} 149*d9f75844SAndroid Build Coastguard Worker 150*d9f75844SAndroid Build Coastguard Worker- (IBAction)hangUp:(id)sender { 151*d9f75844SAndroid Build Coastguard Worker _call_client->Hangup(); 152*d9f75844SAndroid Build Coastguard Worker} 153*d9f75844SAndroid Build Coastguard Worker 154*d9f75844SAndroid Build Coastguard Worker@end 155