Chromium Code Reviews| Index: webrtc/sdk/objc/Framework/Classes/PeerConnection/RTCCameraVideoCapturer.mm |
| diff --git a/webrtc/sdk/objc/Framework/Classes/PeerConnection/RTCCameraVideoCapturer.m b/webrtc/sdk/objc/Framework/Classes/PeerConnection/RTCCameraVideoCapturer.mm |
| similarity index 89% |
| rename from webrtc/sdk/objc/Framework/Classes/PeerConnection/RTCCameraVideoCapturer.m |
| rename to webrtc/sdk/objc/Framework/Classes/PeerConnection/RTCCameraVideoCapturer.mm |
| index a2290c2458405a1d39458f64eae820abfdc14bc9..bd7ef1c61f139f08705d8e560aac6355cc7cb1fc 100644 |
| --- a/webrtc/sdk/objc/Framework/Classes/PeerConnection/RTCCameraVideoCapturer.m |
| +++ b/webrtc/sdk/objc/Framework/Classes/PeerConnection/RTCCameraVideoCapturer.mm |
| @@ -10,6 +10,8 @@ |
| #import <Foundation/Foundation.h> |
| +#include "webrtc/rtc_base/atomicops.h" |
| + |
| #import "WebRTC/RTCCameraVideoCapturer.h" |
| #import "WebRTC/RTCLogging.h" |
| #import "WebRTC/RTCVideoFrameBuffer.h" |
| @@ -18,6 +20,7 @@ |
| #import "WebRTC/UIDevice+RTCDevice.h" |
| #endif |
| +#import "AVCaptureSession+Private.h" |
| #import "RTCDispatcher+Private.h" |
| const int64_t kNanosecondsPerSecond = 1000000000; |
| @@ -35,11 +38,14 @@ static inline BOOL IsMediaSubTypeSupported(FourCharCode mediaSubType) { |
| AVCaptureVideoDataOutput *_videoDataOutput; |
| AVCaptureSession *_captureSession; |
| AVCaptureDevice *_currentDevice; |
| - RTCVideoRotation _rotation; |
| BOOL _hasRetriedOnFatalError; |
| BOOL _isRunning; |
| // Will the session be running once all asynchronous operations have been completed? |
| BOOL _willBeRunning; |
| +#if TARGET_OS_IPHONE |
| + volatile int _switchingCameras; |
| + UIDeviceOrientation _orientation; |
| +#endif |
| } |
| @synthesize frameQueue = _frameQueue; |
| @@ -56,6 +62,8 @@ static inline BOOL IsMediaSubTypeSupported(FourCharCode mediaSubType) { |
| } |
| NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; |
| #if TARGET_OS_IPHONE |
| + _switchingCameras = 0; |
| + _orientation = UIDeviceOrientationPortrait; |
| [center addObserver:self |
| selector:@selector(deviceOrientationDidChange:) |
| name:UIDeviceOrientationDidChangeNotification |
| @@ -117,7 +125,7 @@ static inline BOOL IsMediaSubTypeSupported(FourCharCode mediaSubType) { |
| - (void)startCaptureWithDevice:(AVCaptureDevice *)device |
| format:(AVCaptureDeviceFormat *)format |
| fps:(NSInteger)fps { |
| - _willBeRunning = true; |
| + _willBeRunning = YES; |
| [RTCDispatcher |
| dispatchAsyncOnType:RTCDispatcherTypeCaptureSession |
| block:^{ |
| @@ -135,18 +143,23 @@ static inline BOOL IsMediaSubTypeSupported(FourCharCode mediaSubType) { |
| @"Failed to lock device %@. Error: %@", _currentDevice, error.userInfo); |
| return; |
| } |
| - |
| +#if TARGET_OS_IPHONE |
| + rtc::AtomicOps::Increment(&_switchingCameras); |
| +#endif |
| [self reconfigureCaptureSessionInput]; |
| [self updateOrientation]; |
| [_captureSession startRunning]; |
| [self updateDeviceCaptureFormat:format fps:fps]; |
| [_currentDevice unlockForConfiguration]; |
| - _isRunning = true; |
| + _isRunning = YES; |
| +#if TARGET_OS_IPHONE |
| + rtc::AtomicOps::Decrement(&_switchingCameras); |
|
tkchin_webrtc
2017/07/24 23:43:04
thinking about this again, I'm not even sure this
jtt_webrtc
2017/07/24 23:56:14
Done.
|
| +#endif |
| }]; |
| } |
| - (void)stopCapture { |
| - _willBeRunning = false; |
| + _willBeRunning = NO; |
| [RTCDispatcher |
| dispatchAsyncOnType:RTCDispatcherTypeCaptureSession |
| block:^{ |
| @@ -160,7 +173,7 @@ static inline BOOL IsMediaSubTypeSupported(FourCharCode mediaSubType) { |
| #if TARGET_OS_IPHONE |
| [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; |
| #endif |
| - _isRunning = false; |
| + _isRunning = NO; |
| }]; |
| } |
| @@ -192,11 +205,51 @@ static inline BOOL IsMediaSubTypeSupported(FourCharCode mediaSubType) { |
| return; |
| } |
| +#if TARGET_OS_IPHONE |
| + // Default to portrait orientation on iPhone. |
| + RTCVideoRotation rotation = RTCVideoRotation_90; |
| + // Check here, which camera this frame is from, to avoid any race conditions. |
| + AVCaptureDeviceInput *deviceInput = |
| + (AVCaptureDeviceInput *)((AVCaptureInputPort *)connection.inputPorts.firstObject).input; |
| + BOOL usingFrontCamera = deviceInput.device.position == AVCaptureDevicePositionFront; |
| + if (rtc::AtomicOps::AcquireLoad(&_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. |
| + AVCaptureDevicePosition cameraPosition = |
| + [AVCaptureSession devicePositionForSampleBuffer:sampleBuffer]; |
| + if (cameraPosition != AVCaptureDevicePositionUnspecified) { |
| + usingFrontCamera = cameraPosition == AVCaptureDevicePositionFront; |
| + } |
| + } |
| + switch (_orientation) { |
| + case UIDeviceOrientationPortrait: |
| + rotation = RTCVideoRotation_90; |
| + break; |
| + case UIDeviceOrientationPortraitUpsideDown: |
| + rotation = RTCVideoRotation_270; |
| + break; |
| + case UIDeviceOrientationLandscapeLeft: |
| + rotation = usingFrontCamera ? RTCVideoRotation_180 : RTCVideoRotation_0; |
| + break; |
| + case UIDeviceOrientationLandscapeRight: |
| + rotation = usingFrontCamera ? RTCVideoRotation_0 : RTCVideoRotation_180; |
| + break; |
| + case UIDeviceOrientationFaceUp: |
| + case UIDeviceOrientationFaceDown: |
| + case UIDeviceOrientationUnknown: |
| + // Ignore. |
| + break; |
| + } |
| +#else |
| + // No rotation on Mac. |
| + RTCVideoRotation rotation = RTCVideoRotation_0; |
| +#endif |
| + |
| RTCCVPixelBuffer *rtcPixelBuffer = [[RTCCVPixelBuffer alloc] initWithPixelBuffer:pixelBuffer]; |
| int64_t timeStampNs = CMTimeGetSeconds(CMSampleBufferGetPresentationTimeStamp(sampleBuffer)) * |
| - kNanosecondsPerSecond; |
| + kNanosecondsPerSecond; |
| RTCVideoFrame *videoFrame = [[RTCVideoFrame alloc] initWithBuffer:rtcPixelBuffer |
| - rotation:_rotation |
| + rotation:rotation |
| timeStampNs:timeStampNs]; |
| [self.delegate capturer:self didCaptureVideoFrame:videoFrame]; |
| } |
| @@ -399,26 +452,7 @@ static inline BOOL IsMediaSubTypeSupported(FourCharCode mediaSubType) { |
| NSAssert([RTCDispatcher isOnQueueForType:RTCDispatcherTypeCaptureSession], |
| @"updateOrientation must be called on the capture queue."); |
| #if TARGET_OS_IPHONE |
| - BOOL usingFrontCamera = _currentDevice.position == AVCaptureDevicePositionFront; |
| - switch ([UIDevice currentDevice].orientation) { |
| - case UIDeviceOrientationPortrait: |
| - _rotation = RTCVideoRotation_90; |
| - break; |
| - case UIDeviceOrientationPortraitUpsideDown: |
| - _rotation = RTCVideoRotation_270; |
| - break; |
| - case UIDeviceOrientationLandscapeLeft: |
| - _rotation = usingFrontCamera ? RTCVideoRotation_180 : RTCVideoRotation_0; |
| - break; |
| - case UIDeviceOrientationLandscapeRight: |
| - _rotation = usingFrontCamera ? RTCVideoRotation_0 : RTCVideoRotation_180; |
| - break; |
| - case UIDeviceOrientationFaceUp: |
| - case UIDeviceOrientationFaceDown: |
| - case UIDeviceOrientationUnknown: |
| - // Ignore. |
| - break; |
| - } |
| + _orientation = [UIDevice currentDevice].orientation; |
| #endif |
| } |