1/* 2 * Copyright 2015 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 "RTCCameraPreviewView.h" 12 13#import <AVFoundation/AVFoundation.h> 14#import <UIKit/UIKit.h> 15 16#import "RTCDispatcher+Private.h" 17 18@implementation RTC_OBJC_TYPE (RTCCameraPreviewView) 19 20@synthesize captureSession = _captureSession; 21 22+ (Class)layerClass { 23 return [AVCaptureVideoPreviewLayer class]; 24} 25 26- (instancetype)initWithFrame:(CGRect)aRect { 27 self = [super initWithFrame:aRect]; 28 if (self) { 29 [self addOrientationObserver]; 30 } 31 return self; 32} 33 34- (instancetype)initWithCoder:(NSCoder*)aDecoder { 35 self = [super initWithCoder:aDecoder]; 36 if (self) { 37 [self addOrientationObserver]; 38 } 39 return self; 40} 41 42- (void)dealloc { 43 [self removeOrientationObserver]; 44} 45 46- (void)setCaptureSession:(AVCaptureSession *)captureSession { 47 if (_captureSession == captureSession) { 48 return; 49 } 50 _captureSession = captureSession; 51 [RTC_OBJC_TYPE(RTCDispatcher) 52 dispatchAsyncOnType:RTCDispatcherTypeMain 53 block:^{ 54 AVCaptureVideoPreviewLayer *previewLayer = [self previewLayer]; 55 [RTC_OBJC_TYPE(RTCDispatcher) 56 dispatchAsyncOnType:RTCDispatcherTypeCaptureSession 57 block:^{ 58 previewLayer.session = captureSession; 59 [RTC_OBJC_TYPE(RTCDispatcher) 60 dispatchAsyncOnType:RTCDispatcherTypeMain 61 block:^{ 62 [self setCorrectVideoOrientation]; 63 }]; 64 }]; 65 }]; 66} 67 68- (void)layoutSubviews { 69 [super layoutSubviews]; 70 71 // Update the video orientation based on the device orientation. 72 [self setCorrectVideoOrientation]; 73} 74 75-(void)orientationChanged:(NSNotification *)notification { 76 [self setCorrectVideoOrientation]; 77} 78 79- (void)setCorrectVideoOrientation { 80 // Get current device orientation. 81 UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation; 82 AVCaptureVideoPreviewLayer *previewLayer = [self previewLayer]; 83 84 // First check if we are allowed to set the video orientation. 85 if (previewLayer.connection.isVideoOrientationSupported) { 86 // Set the video orientation based on device orientation. 87 if (deviceOrientation == UIInterfaceOrientationPortraitUpsideDown) { 88 previewLayer.connection.videoOrientation = 89 AVCaptureVideoOrientationPortraitUpsideDown; 90 } else if (deviceOrientation == UIInterfaceOrientationLandscapeRight) { 91 previewLayer.connection.videoOrientation = 92 AVCaptureVideoOrientationLandscapeRight; 93 } else if (deviceOrientation == UIInterfaceOrientationLandscapeLeft) { 94 previewLayer.connection.videoOrientation = 95 AVCaptureVideoOrientationLandscapeLeft; 96 } else if (deviceOrientation == UIInterfaceOrientationPortrait) { 97 previewLayer.connection.videoOrientation = 98 AVCaptureVideoOrientationPortrait; 99 } 100 // If device orientation switches to FaceUp or FaceDown, don't change video orientation. 101 } 102} 103 104#pragma mark - Private 105 106- (void)addOrientationObserver { 107 [[NSNotificationCenter defaultCenter] addObserver:self 108 selector:@selector(orientationChanged:) 109 name:UIDeviceOrientationDidChangeNotification 110 object:nil]; 111} 112 113- (void)removeOrientationObserver { 114 [[NSNotificationCenter defaultCenter] removeObserver:self 115 name:UIDeviceOrientationDidChangeNotification 116 object:nil]; 117} 118 119- (AVCaptureVideoPreviewLayer *)previewLayer { 120 return (AVCaptureVideoPreviewLayer *)self.layer; 121} 122 123@end 124