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 |
} |