2014 snapchat source code
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
// // SCFeatureImageCaptureImpl.m // SCCamera // // Created by Kristian Bauer on 4/18/18. //
#import "SCFeatureImageCaptureImpl.h"
#import "SCLogger+Camera.h" #import "SCManagedCapturePreviewLayerController.h" #import "SCManagedCapturerLensAPI.h" #import "SCManagedCapturerListener.h" #import "SCManagedCapturerUtils.h" #import "SCManagedStillImageCapturer.h"
#import <SCFoundation/SCDeviceName.h> #import <SCFoundation/SCLog.h> #import <SCFoundation/SCQueuePerformer.h> #import <SCFoundation/SCTraceODPCompatible.h> #import <SCGhostToSnappable/SCGhostToSnappableSignal.h> #import <SCLogger/SCCameraMetrics.h> #import <SCLogger/SCLogger+Performance.h>
@interface SCFeatureImageCaptureImpl () @property (nonatomic, strong, readwrite) id<SCCapturer> capturer; @property (nonatomic, strong, readwrite) SCLogger *logger; @property (nonatomic, assign) AVCameraViewType cameraViewType; @property (nonatomic, strong, readwrite) SCManagedCapturerState *managedCapturerState;
/** * Whether user has attempted image capture in current session. Reset on foreground of app. */ @property (nonatomic, assign) BOOL hasTriedCapturing; @end
@interface SCFeatureImageCaptureImpl (SCManagedCapturerListener) <SCManagedCapturerListener> @end
@implementation SCFeatureImageCaptureImpl @synthesize delegate = _delegate; @synthesize imagePromise = _imagePromise;
- (instancetype)initWithCapturer:(id<SCCapturer>)capturer logger:(SCLogger *)logger cameraViewType:(AVCameraViewType)cameraViewType { SCTraceODPCompatibleStart(2); self = [super init]; if (self) { _capturer = capturer; [_capturer addListener:self]; _logger = logger; _cameraViewType = cameraViewType;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_viewWillEnterForeground) name:UIApplicationWillEnterForegroundNotification object:nil]; } return self; }
- (void)dealloc { [_capturer removeListener:self]; }
#pragma mark - SCFeatureImageCapture
- (void)captureImage:(NSString *)captureSessionID { SCTraceODPCompatibleStart(2); [_logger logTimedEventStart:kSCCameraMetricsRecordingDelay uniqueId:@"IMAGE" isUniqueEvent:NO]; BOOL asyncCaptureEnabled = [self _asynchronousCaptureEnabled:_managedCapturerState]; SCLogCameraFeatureInfo(@"[%@] takeImage begin async: %@", NSStringFromClass([self class]), asyncCaptureEnabled ? @"YES" : @"NO");
if (asyncCaptureEnabled) { SCQueuePerformer *performer = [[SCQueuePerformer alloc] initWithLabel:"com.snapchat.image-capture-promise" qualityOfService:QOS_CLASS_USER_INTERACTIVE queueType:DISPATCH_QUEUE_SERIAL context:SCQueuePerformerContextCoreCamera]; _imagePromise = [[SCPromise alloc] initWithPerformer:performer]; }
@weakify(self); [_capturer captureStillImageAsynchronouslyWithAspectRatio:SCManagedCapturedImageAndVideoAspectRatio() captureSessionID:captureSessionID completionHandler:^(UIImage *fullScreenImage, NSDictionary *metadata, NSError *error, SCManagedCapturerState *state) { @strongify(self); SC_GUARD_ELSE_RETURN(self); [self _takeImageCallback:fullScreenImage metadata:metadata error:error state:state]; } context:SCCapturerContext]; [_logger logCameraCaptureFinishedWithDuration:0]; }
#pragma mark - Private
- (void)_viewWillEnterForeground { SCTraceODPCompatibleStart(2); _hasTriedCapturing = NO; }
- (void)_takeImageCallback:(UIImage *)image metadata:(NSDictionary *)metadata error:(NSError *)error state:(SCManagedCapturerState *)state { SCTraceODPCompatibleStart(2); [self _logCaptureComplete:state];
if (image) { [_delegate featureImageCapture:self willCompleteWithImage:image]; if (_imagePromise) { [_imagePromise completeWithValue:image]; } } else { if (_imagePromise) { [_imagePromise completeWithError:[NSError errorWithDomain:@"" code:-1 userInfo:nil]]; } [_delegate featureImageCapture:self didCompleteWithError:error]; } _imagePromise = nil; [_delegate featureImageCapturedDidComplete:self]; }
- (BOOL)_asynchronousCaptureEnabled:(SCManagedCapturerState *)state { SCTraceODPCompatibleStart(2); BOOL shouldCaptureImageFromVideoBuffer = [SCDeviceName isSimilarToIphone5orNewer] && ![SCDeviceName isSimilarToIphone6orNewer]; // Fast image capture is disabled in following cases // (1) flash is on; // (2) lenses are active; // (3) SCPhotoCapturer is not supported; // (4) not main camera for iPhoneX; return !state.flashActive && !state.lensesActive && !_capturer.lensProcessingCore.appliedLens && (SCPhotoCapturerIsEnabled() || shouldCaptureImageFromVideoBuffer) && (![SCDeviceName isIphoneX] || (_cameraViewType == AVCameraViewNoReply)); }
- (void)_logCaptureComplete:(SCManagedCapturerState *)state { SCTraceODPCompatibleStart(2); NSDictionary *params = @{ @"type" : @"image", @"lenses_active" : @(state.lensesActive), @"is_back_camera" : @(state.devicePosition != SCManagedCaptureDevicePositionFront), @"is_main_camera" : @(_cameraViewType == AVCameraViewNoReply), @"is_first_attempt_after_app_startup" : @(!_hasTriedCapturing), @"app_startup_type" : SCLaunchType(), @"app_startup_time" : @(SCAppStartupTimeMicros() / 1000.0), @"time_elapse_after_app_startup" : @(SCTimeElapseAfterAppStartupMicros() / 1000.0), }; [_logger logTimedEventEnd:kSCCameraMetricsRecordingDelay uniqueId:@"IMAGE" parameters:params]; _hasTriedCapturing = YES; }
@end
@implementation SCFeatureImageCaptureImpl (SCManagedCapturerListener)
- (void)managedCapturer:(id<SCCapturer>)managedCapturer didChangeState:(SCManagedCapturerState *)state { SCTraceODPCompatibleStart(2); _managedCapturerState = [state copy]; }
- (void)managedCapturer:(id<SCCapturer>)managedCapturer didCapturePhoto:(SCManagedCapturerState *)state { SCTraceODPCompatibleStart(2); if (_imagePromise) { [[SCManagedCapturePreviewLayerController sharedInstance] pause]; } }
@end
|