| Index: webrtc/sdk/objc/Framework/Classes/Video/RTCAVFoundationVideoCapturerInternal.mm
|
| diff --git a/webrtc/sdk/objc/Framework/Classes/Video/RTCAVFoundationVideoCapturerInternal.mm b/webrtc/sdk/objc/Framework/Classes/Video/RTCAVFoundationVideoCapturerInternal.mm
|
| index 166a609824941775e629936bb6e4c03905d20242..91187d5ff2e96e3a93de88b9baa21e2ff91ff0e0 100644
|
| --- a/webrtc/sdk/objc/Framework/Classes/Video/RTCAVFoundationVideoCapturerInternal.mm
|
| +++ b/webrtc/sdk/objc/Framework/Classes/Video/RTCAVFoundationVideoCapturerInternal.mm
|
| @@ -17,6 +17,7 @@
|
| #endif
|
|
|
| #import "RTCDispatcher+Private.h"
|
| +#import "RTCImageHelper.h"
|
| #import "WebRTC/RTCLogging.h"
|
|
|
| #include "avfoundationformatmapper.h"
|
| @@ -28,11 +29,14 @@
|
| AVCaptureVideoDataOutput *_videoDataOutput;
|
| // The cricket::VideoCapturer that owns this class. Should never be NULL.
|
| webrtc::AVFoundationVideoCapturer *_capturer;
|
| - webrtc::VideoRotation _rotation;
|
| BOOL _hasRetriedOnFatalError;
|
| BOOL _isRunning;
|
| BOOL _hasStarted;
|
| rtc::CriticalSection _crit;
|
| + BOOL _switchingCameras;
|
| +#if TARGET_OS_IPHONE
|
| + UIDeviceOrientation _orientation;
|
| +#endif
|
| }
|
|
|
| @synthesize captureSession = _captureSession;
|
| @@ -56,7 +60,9 @@
|
| return nil;
|
| }
|
| NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
| + _switchingCameras = NO;
|
| #if TARGET_OS_IPHONE
|
| + _orientation = UIDeviceOrientationPortrait;
|
| [center addObserver:self
|
| selector:@selector(deviceOrientationDidChange:)
|
| name:UIDeviceOrientationDidChangeNotification
|
| @@ -157,24 +163,16 @@
|
| if (self.hasStarted) {
|
| return;
|
| }
|
| - self.hasStarted = YES;
|
| [RTCDispatcher
|
| dispatchAsyncOnType:RTCDispatcherTypeCaptureSession
|
| block:^{
|
| -#if TARGET_OS_IPHONE
|
| - // Default to portrait orientation on iPhone. This will be reset in
|
| - // updateOrientation unless orientation is unknown/faceup/facedown.
|
| - _rotation = webrtc::kVideoRotation_90;
|
| -#else
|
| - // No rotation on Mac.
|
| - _rotation = webrtc::kVideoRotation_0;
|
| -#endif
|
| [self updateOrientation];
|
| #if TARGET_OS_IPHONE
|
| [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
|
| #endif
|
| AVCaptureSession *captureSession = self.captureSession;
|
| [captureSession startRunning];
|
| + self.hasStarted = YES;
|
| }];
|
| }
|
|
|
| @@ -218,7 +216,45 @@
|
| if (!self.hasStarted) {
|
| return;
|
| }
|
| - _capturer->CaptureSampleBuffer(sampleBuffer, _rotation);
|
| +
|
| +#if TARGET_OS_IPHONE
|
| + // Default to portrait orientation on iPhone.
|
| + webrtc::VideoRotation rotation = webrtc::kVideoRotation_90;
|
| + AVCaptureDeviceInput *deviceInput =
|
| + (AVCaptureDeviceInput *)((AVCaptureInputPort *)connection.inputPorts.firstObject).input;
|
| + BOOL usingFrontCamera = deviceInput.device.position == AVCaptureDevicePositionFront;
|
| + // We gate checking the image's EXIF only if we're switching cameras as we don't need to parse
|
| + // the image's attachments and dictionaries for every video image.
|
| + if (_switchingCameras) {
|
| + // Check the image's EXIF for the actual camera the image came as the image could have been
|
| + // delayed as we set alwaysDiscardsLateVideoFrames to NO.
|
| + usingFrontCamera = [RTCImageHelper isFrontCameraFromSampleBuffer:sampleBuffer];
|
| + }
|
| + switch (_orientation) {
|
| + case UIDeviceOrientationPortrait:
|
| + rotation = webrtc::kVideoRotation_90;
|
| + break;
|
| + case UIDeviceOrientationPortraitUpsideDown:
|
| + rotation = webrtc::kVideoRotation_270;
|
| + break;
|
| + case UIDeviceOrientationLandscapeLeft:
|
| + rotation = usingFrontCamera ? webrtc::kVideoRotation_180 : webrtc::kVideoRotation_0;
|
| + break;
|
| + case UIDeviceOrientationLandscapeRight:
|
| + rotation = usingFrontCamera ? webrtc::kVideoRotation_0 : webrtc::kVideoRotation_180;
|
| + break;
|
| + case UIDeviceOrientationFaceUp:
|
| + case UIDeviceOrientationFaceDown:
|
| + case UIDeviceOrientationUnknown:
|
| + // Ignore.
|
| + break;
|
| + }
|
| +#else
|
| + // No rotation on Mac.
|
| + webrtc::VideoRotation rotation = webrtc::kVideoRotation_0;
|
| +#endif
|
| +
|
| + _capturer->CaptureSampleBuffer(sampleBuffer, rotation);
|
| }
|
|
|
| - (void)captureOutput:(AVCaptureOutput *)captureOutput
|
| @@ -448,56 +484,37 @@
|
| // Called from capture session queue.
|
| - (void)updateOrientation {
|
| #if TARGET_OS_IPHONE
|
| - switch ([UIDevice currentDevice].orientation) {
|
| - case UIDeviceOrientationPortrait:
|
| - _rotation = webrtc::kVideoRotation_90;
|
| - break;
|
| - case UIDeviceOrientationPortraitUpsideDown:
|
| - _rotation = webrtc::kVideoRotation_270;
|
| - break;
|
| - case UIDeviceOrientationLandscapeLeft:
|
| - _rotation =
|
| - _capturer->GetUseBackCamera() ? webrtc::kVideoRotation_0 : webrtc::kVideoRotation_180;
|
| - break;
|
| - case UIDeviceOrientationLandscapeRight:
|
| - _rotation =
|
| - _capturer->GetUseBackCamera() ? webrtc::kVideoRotation_180 : webrtc::kVideoRotation_0;
|
| - break;
|
| - case UIDeviceOrientationFaceUp:
|
| - case UIDeviceOrientationFaceDown:
|
| - case UIDeviceOrientationUnknown:
|
| - // Ignore.
|
| - break;
|
| - }
|
| + _orientation = [UIDevice currentDevice].orientation;
|
| #endif
|
| }
|
|
|
| // Update the current session input to match what's stored in _useBackCamera.
|
| - (void)updateSessionInputForUseBackCamera:(BOOL)useBackCamera {
|
| - [RTCDispatcher dispatchAsyncOnType:RTCDispatcherTypeCaptureSession
|
| - block:^{
|
| - [_captureSession beginConfiguration];
|
| - AVCaptureDeviceInput *oldInput = _backCameraInput;
|
| - AVCaptureDeviceInput *newInput = _frontCameraInput;
|
| - if (useBackCamera) {
|
| - oldInput = _frontCameraInput;
|
| - newInput = _backCameraInput;
|
| - }
|
| - if (oldInput) {
|
| - // Ok to remove this even if it's not attached. Will be no-op.
|
| - [_captureSession removeInput:oldInput];
|
| - }
|
| - if (newInput) {
|
| - [_captureSession addInput:newInput];
|
| - }
|
| - [self updateOrientation];
|
| - AVCaptureDevice *newDevice = newInput.device;
|
| - const cricket::VideoFormat *format =
|
| - _capturer->GetCaptureFormat();
|
| - webrtc::SetFormatForCaptureDevice(
|
| - newDevice, _captureSession, *format);
|
| - [_captureSession commitConfiguration];
|
| - }];
|
| + [RTCDispatcher
|
| + dispatchAsyncOnType:RTCDispatcherTypeCaptureSession
|
| + block:^{
|
| + _switchingCameras = YES;
|
| + [_captureSession beginConfiguration];
|
| + AVCaptureDeviceInput *oldInput = _backCameraInput;
|
| + AVCaptureDeviceInput *newInput = _frontCameraInput;
|
| + if (useBackCamera) {
|
| + oldInput = _frontCameraInput;
|
| + newInput = _backCameraInput;
|
| + }
|
| + if (oldInput) {
|
| + // Ok to remove this even if it's not attached. Will be no-op.
|
| + [_captureSession removeInput:oldInput];
|
| + }
|
| + if (newInput) {
|
| + [_captureSession addInput:newInput];
|
| + }
|
| + [self updateOrientation];
|
| + AVCaptureDevice *newDevice = newInput.device;
|
| + const cricket::VideoFormat *format = _capturer->GetCaptureFormat();
|
| + webrtc::SetFormatForCaptureDevice(newDevice, _captureSession, *format);
|
| + [_captureSession commitConfiguration];
|
| + _switchingCameras = NO;
|
| + }];
|
| }
|
|
|
| @end
|
|
|