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.
 
 
 

475 lines
18 KiB

//
// SCCaptureCore.m
// Snapchat
//
// Created by Lin Jia on 10/2/17.
//
//
#import "SCCaptureCore.h"
#import "SCCaptureDeviceAuthorizationChecker.h"
#import "SCCaptureResource.h"
#import "SCCaptureWorker.h"
#import "SCManagedCapturePreviewLayerController.h"
#import "SCManagedCapturerGLViewManagerAPI.h"
#import "SCManagedCapturerLSAComponentTrackerAPI.h"
#import "SCManagedCapturerV1_Private.h"
#import <SCAudio/SCAudioConfiguration.h>
#import <SCFoundation/SCAssertWrapper.h>
static const char *kSCCaptureDeviceAuthorizationManagerQueueLabel =
"com.snapchat.capture_device_authorization_checker_queue";
@implementation SCCaptureCore {
SCManagedCapturerV1 *_managedCapturerV1;
SCQueuePerformer *_queuePerformer;
SCCaptureDeviceAuthorizationChecker *_authorizationChecker;
}
@synthesize blackCameraDetector = _blackCameraDetector;
- (instancetype)init
{
SCTraceStart();
SCAssertMainThread();
self = [super init];
if (self) {
_managedCapturerV1 = [SCManagedCapturerV1 sharedInstance];
SCCaptureResource *resource = _managedCapturerV1.captureResource;
_queuePerformer = resource.queuePerformer;
_stateMachine = [[SCCaptureStateMachineContext alloc] initWithResource:resource];
SCQueuePerformer *authorizationCheckPerformer =
[[SCQueuePerformer alloc] initWithLabel:kSCCaptureDeviceAuthorizationManagerQueueLabel
qualityOfService:QOS_CLASS_USER_INTERACTIVE
queueType:DISPATCH_QUEUE_SERIAL
context:SCQueuePerformerContextCamera];
_authorizationChecker =
[[SCCaptureDeviceAuthorizationChecker alloc] initWithPerformer:authorizationCheckPerformer];
}
return self;
}
- (id<SCManagedCapturerLensAPI>)lensProcessingCore
{
return _managedCapturerV1.lensProcessingCore;
}
// For APIs inside protocol SCCapture, if they are related to capture state machine, we delegate to state machine.
- (void)setupWithDevicePositionAsynchronously:(SCManagedCaptureDevicePosition)devicePosition
completionHandler:(dispatch_block_t)completionHandler
context:(NSString *)context
{
[_stateMachine initializeCaptureWithDevicePositionAsynchronously:devicePosition
completionHandler:completionHandler
context:context];
}
- (SCCapturerToken *)startRunningAsynchronouslyWithCompletionHandler:(dispatch_block_t)completionHandler
context:(NSString *)context
{
return [_stateMachine startRunningWithContext:context completionHandler:completionHandler];
}
#pragma mark - Recording / Capture
- (void)captureStillImageAsynchronouslyWithAspectRatio:(CGFloat)aspectRatio
captureSessionID:(NSString *)captureSessionID
completionHandler:
(sc_managed_capturer_capture_still_image_completion_handler_t)completionHandler
context:(NSString *)context
{
[_stateMachine captureStillImageAsynchronouslyWithAspectRatio:aspectRatio
captureSessionID:captureSessionID
completionHandler:completionHandler
context:context];
}
- (void)stopRunningAsynchronously:(SCCapturerToken *)token
completionHandler:(sc_managed_capturer_stop_running_completion_handler_t)completionHandler
context:(NSString *)context
{
[_stateMachine stopRunningWithCapturerToken:token completionHandler:completionHandler context:context];
}
- (void)stopRunningAsynchronously:(SCCapturerToken *)token
completionHandler:(sc_managed_capturer_stop_running_completion_handler_t)completionHandler
after:(NSTimeInterval)delay
context:(NSString *)context
{
[_stateMachine stopRunningWithCapturerToken:token after:delay completionHandler:completionHandler context:context];
}
#pragma mark - Scanning
- (void)startScanAsynchronouslyWithScanConfiguration:(SCScanConfiguration *)configuration context:(NSString *)context
{
[_stateMachine startScanAsynchronouslyWithScanConfiguration:configuration context:context];
}
- (void)stopScanAsynchronouslyWithCompletionHandler:(dispatch_block_t)completionHandler context:(NSString *)context
{
[_stateMachine stopScanAsynchronouslyWithCompletionHandler:completionHandler context:context];
}
- (void)prepareForRecordingAsynchronouslyWithContext:(NSString *)context
audioConfiguration:(SCAudioConfiguration *)configuration
{
[_stateMachine prepareForRecordingAsynchronouslyWithAudioConfiguration:configuration context:context];
}
- (void)startRecordingAsynchronouslyWithOutputSettings:(SCManagedVideoCapturerOutputSettings *)outputSettings
audioConfiguration:(SCAudioConfiguration *)configuration
maxDuration:(NSTimeInterval)maxDuration
fileURL:(NSURL *)fileURL
captureSessionID:(NSString *)captureSessionID
completionHandler:
(sc_managed_capturer_start_recording_completion_handler_t)completionHandler
context:(NSString *)context
{
[_stateMachine startRecordingWithOutputSettings:outputSettings
audioConfiguration:configuration
maxDuration:maxDuration
fileURL:fileURL
captureSessionID:captureSessionID
completionHandler:completionHandler
context:context];
}
- (void)stopRecordingAsynchronouslyWithContext:(NSString *)context
{
[_stateMachine stopRecordingWithContext:context];
}
- (void)cancelRecordingAsynchronouslyWithContext:(NSString *)context
{
[_stateMachine cancelRecordingWithContext:context];
[[self snapCreationTriggers] markSnapCreationEndWithContext:context];
}
#pragma mark -
- (void)startStreamingAsynchronouslyWithCompletionHandler:(dispatch_block_t)completionHandler
context:(NSString *)context
{
[_managedCapturerV1 startStreamingAsynchronouslyWithCompletionHandler:completionHandler context:context];
}
- (void)addSampleBufferDisplayController:(id<SCManagedSampleBufferDisplayController>)sampleBufferDisplayController
context:(NSString *)context
{
[_managedCapturerV1 addSampleBufferDisplayController:sampleBufferDisplayController context:context];
}
#pragma mark - Utilities
- (void)convertViewCoordinates:(CGPoint)viewCoordinates
completionHandler:(sc_managed_capturer_convert_view_coordniates_completion_handler_t)completionHandler
context:(NSString *)context
{
[_managedCapturerV1 convertViewCoordinates:viewCoordinates completionHandler:completionHandler context:context];
}
- (void)detectLensCategoryOnNextFrame:(CGPoint)point
lenses:(NSArray<SCLens *> *)lenses
completion:(sc_managed_lenses_processor_category_point_completion_handler_t)completion
context:(NSString *)context
{
[_managedCapturerV1 detectLensCategoryOnNextFrame:point lenses:lenses completion:completion context:context];
}
#pragma mark - Configurations
- (void)setDevicePositionAsynchronously:(SCManagedCaptureDevicePosition)devicePosition
completionHandler:(dispatch_block_t)completionHandler
context:(NSString *)context
{
[_managedCapturerV1 setDevicePositionAsynchronously:devicePosition
completionHandler:completionHandler
context:context];
}
- (void)setFlashActive:(BOOL)flashActive
completionHandler:(dispatch_block_t)completionHandler
context:(NSString *)context
{
[_managedCapturerV1 setFlashActive:flashActive completionHandler:completionHandler context:context];
}
- (void)setLensesActive:(BOOL)lensesActive
completionHandler:(dispatch_block_t)completionHandler
context:(NSString *)context
{
[_managedCapturerV1 setLensesActive:lensesActive completionHandler:completionHandler context:context];
}
- (void)setLensesActive:(BOOL)lensesActive
filterFactory:(SCLookseryFilterFactory *)filterFactory
completionHandler:(dispatch_block_t)completionHandler
context:(NSString *)context
{
[_managedCapturerV1 setLensesActive:lensesActive
filterFactory:filterFactory
completionHandler:completionHandler
context:context];
}
- (void)setLensesInTalkActive:(BOOL)lensesActive
completionHandler:(dispatch_block_t)completionHandler
context:(NSString *)context
{
[_managedCapturerV1 setLensesInTalkActive:lensesActive completionHandler:completionHandler context:context];
}
- (void)setTorchActiveAsynchronously:(BOOL)torchActive
completionHandler:(dispatch_block_t)completionHandler
context:(NSString *)context
{
[_managedCapturerV1 setTorchActiveAsynchronously:torchActive completionHandler:completionHandler context:context];
}
- (void)setNightModeActiveAsynchronously:(BOOL)active
completionHandler:(dispatch_block_t)completionHandler
context:(NSString *)context
{
[_managedCapturerV1 setNightModeActiveAsynchronously:active completionHandler:completionHandler context:context];
}
- (void)lockZoomWithContext:(NSString *)context
{
[_managedCapturerV1 lockZoomWithContext:context];
}
- (void)unlockZoomWithContext:(NSString *)context
{
[_managedCapturerV1 unlockZoomWithContext:context];
}
- (void)setZoomFactorAsynchronously:(CGFloat)zoomFactor context:(NSString *)context
{
[_managedCapturerV1 setZoomFactorAsynchronously:zoomFactor context:context];
}
- (void)resetZoomFactorAsynchronously:(CGFloat)zoomFactor
devicePosition:(SCManagedCaptureDevicePosition)devicePosition
context:(NSString *)context
{
[_managedCapturerV1 resetZoomFactorAsynchronously:zoomFactor devicePosition:devicePosition context:context];
}
- (void)setExposurePointOfInterestAsynchronously:(CGPoint)pointOfInterest
fromUser:(BOOL)fromUser
completionHandler:(dispatch_block_t)completionHandler
context:(NSString *)context
{
[_managedCapturerV1 setExposurePointOfInterestAsynchronously:pointOfInterest
fromUser:fromUser
completionHandler:completionHandler
context:context];
}
- (void)setAutofocusPointOfInterestAsynchronously:(CGPoint)pointOfInterest
completionHandler:(dispatch_block_t)completionHandler
context:(NSString *)context
{
[_managedCapturerV1 setAutofocusPointOfInterestAsynchronously:pointOfInterest
completionHandler:completionHandler
context:context];
}
- (void)setPortraitModePointOfInterestAsynchronously:(CGPoint)pointOfInterest
completionHandler:(dispatch_block_t)completionHandler
context:(NSString *)context
{
[_managedCapturerV1 setPortraitModePointOfInterestAsynchronously:pointOfInterest
completionHandler:completionHandler
context:context];
}
- (void)continuousAutofocusAndExposureAsynchronouslyWithCompletionHandler:(dispatch_block_t)completionHandler
context:(NSString *)context
{
[_managedCapturerV1 continuousAutofocusAndExposureAsynchronouslyWithCompletionHandler:completionHandler
context:context];
}
// I need to call these three methods from SCAppDelegate explicitly so that I get the latest information.
- (void)applicationDidEnterBackground
{
[_managedCapturerV1 applicationDidEnterBackground];
}
- (void)applicationWillEnterForeground
{
[_managedCapturerV1 applicationWillEnterForeground];
}
- (void)applicationDidBecomeActive
{
[_managedCapturerV1 applicationDidBecomeActive];
}
- (void)applicationWillResignActive
{
[_managedCapturerV1 applicationWillResignActive];
}
- (void)mediaServicesWereReset
{
[_managedCapturerV1 mediaServicesWereReset];
}
- (void)mediaServicesWereLost
{
[_managedCapturerV1 mediaServicesWereLost];
}
#pragma mark - Add / Remove Listener
- (void)addListener:(id<SCManagedCapturerListener>)listener
{
[_managedCapturerV1 addListener:listener];
}
- (void)removeListener:(id<SCManagedCapturerListener>)listener
{
[_managedCapturerV1 removeListener:listener];
}
- (void)addVideoDataSourceListener:(id<SCManagedVideoDataSourceListener>)listener
{
[_managedCapturerV1 addVideoDataSourceListener:listener];
}
- (void)removeVideoDataSourceListener:(id<SCManagedVideoDataSourceListener>)listener
{
[_managedCapturerV1 removeVideoDataSourceListener:listener];
}
- (void)addDeviceCapacityAnalyzerListener:(id<SCManagedDeviceCapacityAnalyzerListener>)listener
{
[_managedCapturerV1 addDeviceCapacityAnalyzerListener:listener];
}
- (void)removeDeviceCapacityAnalyzerListener:(id<SCManagedDeviceCapacityAnalyzerListener>)listener
{
[_managedCapturerV1 removeDeviceCapacityAnalyzerListener:listener];
}
- (NSString *)debugInfo
{
return [_managedCapturerV1 debugInfo];
}
- (id<SCManagedVideoDataSource>)currentVideoDataSource
{
return [_managedCapturerV1 currentVideoDataSource];
}
// For APIs inside protocol SCCapture, if they are not related to capture state machine, we directly delegate to V1.
- (void)checkRestrictedCamera:(void (^)(BOOL, BOOL, AVAuthorizationStatus))callback
{
[_managedCapturerV1 checkRestrictedCamera:callback];
}
- (void)recreateAVCaptureSession
{
[_managedCapturerV1 recreateAVCaptureSession];
}
#pragma mark -
- (CMTime)firstWrittenAudioBufferDelay
{
return [SCCaptureWorker firstWrittenAudioBufferDelay:_managedCapturerV1.captureResource];
}
- (BOOL)audioQueueStarted
{
return [SCCaptureWorker audioQueueStarted:_managedCapturerV1.captureResource];
}
- (BOOL)isLensApplied
{
return [SCCaptureWorker isLensApplied:_managedCapturerV1.captureResource];
}
- (BOOL)isVideoMirrored
{
return [SCCaptureWorker isVideoMirrored:_managedCapturerV1.captureResource];
}
- (SCVideoCaptureSessionInfo)activeSession
{
return _managedCapturerV1.activeSession;
}
- (void)setBlackCameraDetector:(SCBlackCameraDetector *)blackCameraDetector
deviceMotionProvider:(id<SCDeviceMotionProvider>)deviceMotionProvider
fileInputDecider:(id<SCFileInputDecider>)fileInputDecider
arImageCaptureProvider:(id<SCManagedCapturerARImageCaptureProvider>)arImageCaptureProvider
glviewManager:(id<SCManagedCapturerGLViewManagerAPI>)glViewManager
lensAPIProvider:(id<SCManagedCapturerLensAPIProvider>)lensAPIProvider
lsaComponentTracker:(id<SCManagedCapturerLSAComponentTrackerAPI>)lsaComponentTracker
managedCapturerPreviewLayerControllerDelegate:
(id<SCManagedCapturePreviewLayerControllerDelegate>)previewLayerControllerDelegate
{
_managedCapturerV1.captureResource.blackCameraDetector = blackCameraDetector;
_managedCapturerV1.captureResource.deviceMotionProvider = deviceMotionProvider;
_managedCapturerV1.captureResource.fileInputDecider = fileInputDecider;
_managedCapturerV1.captureResource.arImageCaptureProvider = arImageCaptureProvider;
_managedCapturerV1.captureResource.videoPreviewGLViewManager = glViewManager;
[_managedCapturerV1.captureResource.videoPreviewGLViewManager
configureWithCaptureResource:_managedCapturerV1.captureResource];
_managedCapturerV1.captureResource.lensAPIProvider = lensAPIProvider;
_managedCapturerV1.captureResource.lsaTrackingComponentHandler = lsaComponentTracker;
[_managedCapturerV1.captureResource.lsaTrackingComponentHandler
configureWithCaptureResource:_managedCapturerV1.captureResource];
_managedCapturerV1.captureResource.previewLayerControllerDelegate = previewLayerControllerDelegate;
[SCManagedCapturePreviewLayerController sharedInstance].delegate =
_managedCapturerV1.captureResource.previewLayerControllerDelegate;
}
- (SCBlackCameraDetector *)blackCameraDetector
{
return _managedCapturerV1.captureResource.blackCameraDetector;
}
- (void)captureSingleVideoFrameAsynchronouslyWithCompletionHandler:
(sc_managed_capturer_capture_video_frame_completion_handler_t)completionHandler
context:(NSString *)context
{
[_managedCapturerV1 captureSingleVideoFrameAsynchronouslyWithCompletionHandler:completionHandler context:context];
}
- (void)sampleFrameWithCompletionHandler:(void (^)(UIImage *frame, CMTime presentationTime))completionHandler
context:(NSString *)context
{
[_managedCapturerV1 sampleFrameWithCompletionHandler:completionHandler context:context];
}
- (void)addTimedTask:(SCTimedTask *)task context:(NSString *)context
{
[_managedCapturerV1 addTimedTask:task context:context];
}
- (void)clearTimedTasksWithContext:(NSString *)context
{
[_managedCapturerV1 clearTimedTasksWithContext:context];
}
- (BOOL)authorizedForVideoCapture
{
return [_authorizationChecker authorizedForVideoCapture];
}
- (void)preloadVideoCaptureAuthorization
{
[_authorizationChecker preloadVideoCaptureAuthorization];
}
#pragma mark - Snap Creation triggers
- (SCSnapCreationTriggers *)snapCreationTriggers
{
return [_managedCapturerV1 snapCreationTriggers];
}
@end