xref: /aosp_15_r20/external/webrtc/examples/objcnativeapi/objc/NADViewController.mm (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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