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

  1. //
  2. // SCCaptureCore.m
  3. // Snapchat
  4. //
  5. // Created by Lin Jia on 10/2/17.
  6. //
  7. //
  8. #import "SCCaptureCore.h"
  9. #import "SCCaptureDeviceAuthorizationChecker.h"
  10. #import "SCCaptureResource.h"
  11. #import "SCCaptureWorker.h"
  12. #import "SCManagedCapturePreviewLayerController.h"
  13. #import "SCManagedCapturerGLViewManagerAPI.h"
  14. #import "SCManagedCapturerLSAComponentTrackerAPI.h"
  15. #import "SCManagedCapturerV1_Private.h"
  16. #import <SCAudio/SCAudioConfiguration.h>
  17. #import <SCFoundation/SCAssertWrapper.h>
  18. static const char *kSCCaptureDeviceAuthorizationManagerQueueLabel =
  19. "com.snapchat.capture_device_authorization_checker_queue";
  20. @implementation SCCaptureCore {
  21. SCManagedCapturerV1 *_managedCapturerV1;
  22. SCQueuePerformer *_queuePerformer;
  23. SCCaptureDeviceAuthorizationChecker *_authorizationChecker;
  24. }
  25. @synthesize blackCameraDetector = _blackCameraDetector;
  26. - (instancetype)init
  27. {
  28. SCTraceStart();
  29. SCAssertMainThread();
  30. self = [super init];
  31. if (self) {
  32. _managedCapturerV1 = [SCManagedCapturerV1 sharedInstance];
  33. SCCaptureResource *resource = _managedCapturerV1.captureResource;
  34. _queuePerformer = resource.queuePerformer;
  35. _stateMachine = [[SCCaptureStateMachineContext alloc] initWithResource:resource];
  36. SCQueuePerformer *authorizationCheckPerformer =
  37. [[SCQueuePerformer alloc] initWithLabel:kSCCaptureDeviceAuthorizationManagerQueueLabel
  38. qualityOfService:QOS_CLASS_USER_INTERACTIVE
  39. queueType:DISPATCH_QUEUE_SERIAL
  40. context:SCQueuePerformerContextCamera];
  41. _authorizationChecker =
  42. [[SCCaptureDeviceAuthorizationChecker alloc] initWithPerformer:authorizationCheckPerformer];
  43. }
  44. return self;
  45. }
  46. - (id<SCManagedCapturerLensAPI>)lensProcessingCore
  47. {
  48. return _managedCapturerV1.lensProcessingCore;
  49. }
  50. // For APIs inside protocol SCCapture, if they are related to capture state machine, we delegate to state machine.
  51. - (void)setupWithDevicePositionAsynchronously:(SCManagedCaptureDevicePosition)devicePosition
  52. completionHandler:(dispatch_block_t)completionHandler
  53. context:(NSString *)context
  54. {
  55. [_stateMachine initializeCaptureWithDevicePositionAsynchronously:devicePosition
  56. completionHandler:completionHandler
  57. context:context];
  58. }
  59. - (SCCapturerToken *)startRunningAsynchronouslyWithCompletionHandler:(dispatch_block_t)completionHandler
  60. context:(NSString *)context
  61. {
  62. return [_stateMachine startRunningWithContext:context completionHandler:completionHandler];
  63. }
  64. #pragma mark - Recording / Capture
  65. - (void)captureStillImageAsynchronouslyWithAspectRatio:(CGFloat)aspectRatio
  66. captureSessionID:(NSString *)captureSessionID
  67. completionHandler:
  68. (sc_managed_capturer_capture_still_image_completion_handler_t)completionHandler
  69. context:(NSString *)context
  70. {
  71. [_stateMachine captureStillImageAsynchronouslyWithAspectRatio:aspectRatio
  72. captureSessionID:captureSessionID
  73. completionHandler:completionHandler
  74. context:context];
  75. }
  76. - (void)stopRunningAsynchronously:(SCCapturerToken *)token
  77. completionHandler:(sc_managed_capturer_stop_running_completion_handler_t)completionHandler
  78. context:(NSString *)context
  79. {
  80. [_stateMachine stopRunningWithCapturerToken:token completionHandler:completionHandler context:context];
  81. }
  82. - (void)stopRunningAsynchronously:(SCCapturerToken *)token
  83. completionHandler:(sc_managed_capturer_stop_running_completion_handler_t)completionHandler
  84. after:(NSTimeInterval)delay
  85. context:(NSString *)context
  86. {
  87. [_stateMachine stopRunningWithCapturerToken:token after:delay completionHandler:completionHandler context:context];
  88. }
  89. #pragma mark - Scanning
  90. - (void)startScanAsynchronouslyWithScanConfiguration:(SCScanConfiguration *)configuration context:(NSString *)context
  91. {
  92. [_stateMachine startScanAsynchronouslyWithScanConfiguration:configuration context:context];
  93. }
  94. - (void)stopScanAsynchronouslyWithCompletionHandler:(dispatch_block_t)completionHandler context:(NSString *)context
  95. {
  96. [_stateMachine stopScanAsynchronouslyWithCompletionHandler:completionHandler context:context];
  97. }
  98. - (void)prepareForRecordingAsynchronouslyWithContext:(NSString *)context
  99. audioConfiguration:(SCAudioConfiguration *)configuration
  100. {
  101. [_stateMachine prepareForRecordingAsynchronouslyWithAudioConfiguration:configuration context:context];
  102. }
  103. - (void)startRecordingAsynchronouslyWithOutputSettings:(SCManagedVideoCapturerOutputSettings *)outputSettings
  104. audioConfiguration:(SCAudioConfiguration *)configuration
  105. maxDuration:(NSTimeInterval)maxDuration
  106. fileURL:(NSURL *)fileURL
  107. captureSessionID:(NSString *)captureSessionID
  108. completionHandler:
  109. (sc_managed_capturer_start_recording_completion_handler_t)completionHandler
  110. context:(NSString *)context
  111. {
  112. [_stateMachine startRecordingWithOutputSettings:outputSettings
  113. audioConfiguration:configuration
  114. maxDuration:maxDuration
  115. fileURL:fileURL
  116. captureSessionID:captureSessionID
  117. completionHandler:completionHandler
  118. context:context];
  119. }
  120. - (void)stopRecordingAsynchronouslyWithContext:(NSString *)context
  121. {
  122. [_stateMachine stopRecordingWithContext:context];
  123. }
  124. - (void)cancelRecordingAsynchronouslyWithContext:(NSString *)context
  125. {
  126. [_stateMachine cancelRecordingWithContext:context];
  127. [[self snapCreationTriggers] markSnapCreationEndWithContext:context];
  128. }
  129. #pragma mark -
  130. - (void)startStreamingAsynchronouslyWithCompletionHandler:(dispatch_block_t)completionHandler
  131. context:(NSString *)context
  132. {
  133. [_managedCapturerV1 startStreamingAsynchronouslyWithCompletionHandler:completionHandler context:context];
  134. }
  135. - (void)addSampleBufferDisplayController:(id<SCManagedSampleBufferDisplayController>)sampleBufferDisplayController
  136. context:(NSString *)context
  137. {
  138. [_managedCapturerV1 addSampleBufferDisplayController:sampleBufferDisplayController context:context];
  139. }
  140. #pragma mark - Utilities
  141. - (void)convertViewCoordinates:(CGPoint)viewCoordinates
  142. completionHandler:(sc_managed_capturer_convert_view_coordniates_completion_handler_t)completionHandler
  143. context:(NSString *)context
  144. {
  145. [_managedCapturerV1 convertViewCoordinates:viewCoordinates completionHandler:completionHandler context:context];
  146. }
  147. - (void)detectLensCategoryOnNextFrame:(CGPoint)point
  148. lenses:(NSArray<SCLens *> *)lenses
  149. completion:(sc_managed_lenses_processor_category_point_completion_handler_t)completion
  150. context:(NSString *)context
  151. {
  152. [_managedCapturerV1 detectLensCategoryOnNextFrame:point lenses:lenses completion:completion context:context];
  153. }
  154. #pragma mark - Configurations
  155. - (void)setDevicePositionAsynchronously:(SCManagedCaptureDevicePosition)devicePosition
  156. completionHandler:(dispatch_block_t)completionHandler
  157. context:(NSString *)context
  158. {
  159. [_managedCapturerV1 setDevicePositionAsynchronously:devicePosition
  160. completionHandler:completionHandler
  161. context:context];
  162. }
  163. - (void)setFlashActive:(BOOL)flashActive
  164. completionHandler:(dispatch_block_t)completionHandler
  165. context:(NSString *)context
  166. {
  167. [_managedCapturerV1 setFlashActive:flashActive completionHandler:completionHandler context:context];
  168. }
  169. - (void)setLensesActive:(BOOL)lensesActive
  170. completionHandler:(dispatch_block_t)completionHandler
  171. context:(NSString *)context
  172. {
  173. [_managedCapturerV1 setLensesActive:lensesActive completionHandler:completionHandler context:context];
  174. }
  175. - (void)setLensesActive:(BOOL)lensesActive
  176. filterFactory:(SCLookseryFilterFactory *)filterFactory
  177. completionHandler:(dispatch_block_t)completionHandler
  178. context:(NSString *)context
  179. {
  180. [_managedCapturerV1 setLensesActive:lensesActive
  181. filterFactory:filterFactory
  182. completionHandler:completionHandler
  183. context:context];
  184. }
  185. - (void)setLensesInTalkActive:(BOOL)lensesActive
  186. completionHandler:(dispatch_block_t)completionHandler
  187. context:(NSString *)context
  188. {
  189. [_managedCapturerV1 setLensesInTalkActive:lensesActive completionHandler:completionHandler context:context];
  190. }
  191. - (void)setTorchActiveAsynchronously:(BOOL)torchActive
  192. completionHandler:(dispatch_block_t)completionHandler
  193. context:(NSString *)context
  194. {
  195. [_managedCapturerV1 setTorchActiveAsynchronously:torchActive completionHandler:completionHandler context:context];
  196. }
  197. - (void)setNightModeActiveAsynchronously:(BOOL)active
  198. completionHandler:(dispatch_block_t)completionHandler
  199. context:(NSString *)context
  200. {
  201. [_managedCapturerV1 setNightModeActiveAsynchronously:active completionHandler:completionHandler context:context];
  202. }
  203. - (void)lockZoomWithContext:(NSString *)context
  204. {
  205. [_managedCapturerV1 lockZoomWithContext:context];
  206. }
  207. - (void)unlockZoomWithContext:(NSString *)context
  208. {
  209. [_managedCapturerV1 unlockZoomWithContext:context];
  210. }
  211. - (void)setZoomFactorAsynchronously:(CGFloat)zoomFactor context:(NSString *)context
  212. {
  213. [_managedCapturerV1 setZoomFactorAsynchronously:zoomFactor context:context];
  214. }
  215. - (void)resetZoomFactorAsynchronously:(CGFloat)zoomFactor
  216. devicePosition:(SCManagedCaptureDevicePosition)devicePosition
  217. context:(NSString *)context
  218. {
  219. [_managedCapturerV1 resetZoomFactorAsynchronously:zoomFactor devicePosition:devicePosition context:context];
  220. }
  221. - (void)setExposurePointOfInterestAsynchronously:(CGPoint)pointOfInterest
  222. fromUser:(BOOL)fromUser
  223. completionHandler:(dispatch_block_t)completionHandler
  224. context:(NSString *)context
  225. {
  226. [_managedCapturerV1 setExposurePointOfInterestAsynchronously:pointOfInterest
  227. fromUser:fromUser
  228. completionHandler:completionHandler
  229. context:context];
  230. }
  231. - (void)setAutofocusPointOfInterestAsynchronously:(CGPoint)pointOfInterest
  232. completionHandler:(dispatch_block_t)completionHandler
  233. context:(NSString *)context
  234. {
  235. [_managedCapturerV1 setAutofocusPointOfInterestAsynchronously:pointOfInterest
  236. completionHandler:completionHandler
  237. context:context];
  238. }
  239. - (void)setPortraitModePointOfInterestAsynchronously:(CGPoint)pointOfInterest
  240. completionHandler:(dispatch_block_t)completionHandler
  241. context:(NSString *)context
  242. {
  243. [_managedCapturerV1 setPortraitModePointOfInterestAsynchronously:pointOfInterest
  244. completionHandler:completionHandler
  245. context:context];
  246. }
  247. - (void)continuousAutofocusAndExposureAsynchronouslyWithCompletionHandler:(dispatch_block_t)completionHandler
  248. context:(NSString *)context
  249. {
  250. [_managedCapturerV1 continuousAutofocusAndExposureAsynchronouslyWithCompletionHandler:completionHandler
  251. context:context];
  252. }
  253. // I need to call these three methods from SCAppDelegate explicitly so that I get the latest information.
  254. - (void)applicationDidEnterBackground
  255. {
  256. [_managedCapturerV1 applicationDidEnterBackground];
  257. }
  258. - (void)applicationWillEnterForeground
  259. {
  260. [_managedCapturerV1 applicationWillEnterForeground];
  261. }
  262. - (void)applicationDidBecomeActive
  263. {
  264. [_managedCapturerV1 applicationDidBecomeActive];
  265. }
  266. - (void)applicationWillResignActive
  267. {
  268. [_managedCapturerV1 applicationWillResignActive];
  269. }
  270. - (void)mediaServicesWereReset
  271. {
  272. [_managedCapturerV1 mediaServicesWereReset];
  273. }
  274. - (void)mediaServicesWereLost
  275. {
  276. [_managedCapturerV1 mediaServicesWereLost];
  277. }
  278. #pragma mark - Add / Remove Listener
  279. - (void)addListener:(id<SCManagedCapturerListener>)listener
  280. {
  281. [_managedCapturerV1 addListener:listener];
  282. }
  283. - (void)removeListener:(id<SCManagedCapturerListener>)listener
  284. {
  285. [_managedCapturerV1 removeListener:listener];
  286. }
  287. - (void)addVideoDataSourceListener:(id<SCManagedVideoDataSourceListener>)listener
  288. {
  289. [_managedCapturerV1 addVideoDataSourceListener:listener];
  290. }
  291. - (void)removeVideoDataSourceListener:(id<SCManagedVideoDataSourceListener>)listener
  292. {
  293. [_managedCapturerV1 removeVideoDataSourceListener:listener];
  294. }
  295. - (void)addDeviceCapacityAnalyzerListener:(id<SCManagedDeviceCapacityAnalyzerListener>)listener
  296. {
  297. [_managedCapturerV1 addDeviceCapacityAnalyzerListener:listener];
  298. }
  299. - (void)removeDeviceCapacityAnalyzerListener:(id<SCManagedDeviceCapacityAnalyzerListener>)listener
  300. {
  301. [_managedCapturerV1 removeDeviceCapacityAnalyzerListener:listener];
  302. }
  303. - (NSString *)debugInfo
  304. {
  305. return [_managedCapturerV1 debugInfo];
  306. }
  307. - (id<SCManagedVideoDataSource>)currentVideoDataSource
  308. {
  309. return [_managedCapturerV1 currentVideoDataSource];
  310. }
  311. // For APIs inside protocol SCCapture, if they are not related to capture state machine, we directly delegate to V1.
  312. - (void)checkRestrictedCamera:(void (^)(BOOL, BOOL, AVAuthorizationStatus))callback
  313. {
  314. [_managedCapturerV1 checkRestrictedCamera:callback];
  315. }
  316. - (void)recreateAVCaptureSession
  317. {
  318. [_managedCapturerV1 recreateAVCaptureSession];
  319. }
  320. #pragma mark -
  321. - (CMTime)firstWrittenAudioBufferDelay
  322. {
  323. return [SCCaptureWorker firstWrittenAudioBufferDelay:_managedCapturerV1.captureResource];
  324. }
  325. - (BOOL)audioQueueStarted
  326. {
  327. return [SCCaptureWorker audioQueueStarted:_managedCapturerV1.captureResource];
  328. }
  329. - (BOOL)isLensApplied
  330. {
  331. return [SCCaptureWorker isLensApplied:_managedCapturerV1.captureResource];
  332. }
  333. - (BOOL)isVideoMirrored
  334. {
  335. return [SCCaptureWorker isVideoMirrored:_managedCapturerV1.captureResource];
  336. }
  337. - (SCVideoCaptureSessionInfo)activeSession
  338. {
  339. return _managedCapturerV1.activeSession;
  340. }
  341. - (void)setBlackCameraDetector:(SCBlackCameraDetector *)blackCameraDetector
  342. deviceMotionProvider:(id<SCDeviceMotionProvider>)deviceMotionProvider
  343. fileInputDecider:(id<SCFileInputDecider>)fileInputDecider
  344. arImageCaptureProvider:(id<SCManagedCapturerARImageCaptureProvider>)arImageCaptureProvider
  345. glviewManager:(id<SCManagedCapturerGLViewManagerAPI>)glViewManager
  346. lensAPIProvider:(id<SCManagedCapturerLensAPIProvider>)lensAPIProvider
  347. lsaComponentTracker:(id<SCManagedCapturerLSAComponentTrackerAPI>)lsaComponentTracker
  348. managedCapturerPreviewLayerControllerDelegate:
  349. (id<SCManagedCapturePreviewLayerControllerDelegate>)previewLayerControllerDelegate
  350. {
  351. _managedCapturerV1.captureResource.blackCameraDetector = blackCameraDetector;
  352. _managedCapturerV1.captureResource.deviceMotionProvider = deviceMotionProvider;
  353. _managedCapturerV1.captureResource.fileInputDecider = fileInputDecider;
  354. _managedCapturerV1.captureResource.arImageCaptureProvider = arImageCaptureProvider;
  355. _managedCapturerV1.captureResource.videoPreviewGLViewManager = glViewManager;
  356. [_managedCapturerV1.captureResource.videoPreviewGLViewManager
  357. configureWithCaptureResource:_managedCapturerV1.captureResource];
  358. _managedCapturerV1.captureResource.lensAPIProvider = lensAPIProvider;
  359. _managedCapturerV1.captureResource.lsaTrackingComponentHandler = lsaComponentTracker;
  360. [_managedCapturerV1.captureResource.lsaTrackingComponentHandler
  361. configureWithCaptureResource:_managedCapturerV1.captureResource];
  362. _managedCapturerV1.captureResource.previewLayerControllerDelegate = previewLayerControllerDelegate;
  363. [SCManagedCapturePreviewLayerController sharedInstance].delegate =
  364. _managedCapturerV1.captureResource.previewLayerControllerDelegate;
  365. }
  366. - (SCBlackCameraDetector *)blackCameraDetector
  367. {
  368. return _managedCapturerV1.captureResource.blackCameraDetector;
  369. }
  370. - (void)captureSingleVideoFrameAsynchronouslyWithCompletionHandler:
  371. (sc_managed_capturer_capture_video_frame_completion_handler_t)completionHandler
  372. context:(NSString *)context
  373. {
  374. [_managedCapturerV1 captureSingleVideoFrameAsynchronouslyWithCompletionHandler:completionHandler context:context];
  375. }
  376. - (void)sampleFrameWithCompletionHandler:(void (^)(UIImage *frame, CMTime presentationTime))completionHandler
  377. context:(NSString *)context
  378. {
  379. [_managedCapturerV1 sampleFrameWithCompletionHandler:completionHandler context:context];
  380. }
  381. - (void)addTimedTask:(SCTimedTask *)task context:(NSString *)context
  382. {
  383. [_managedCapturerV1 addTimedTask:task context:context];
  384. }
  385. - (void)clearTimedTasksWithContext:(NSString *)context
  386. {
  387. [_managedCapturerV1 clearTimedTasksWithContext:context];
  388. }
  389. - (BOOL)authorizedForVideoCapture
  390. {
  391. return [_authorizationChecker authorizedForVideoCapture];
  392. }
  393. - (void)preloadVideoCaptureAuthorization
  394. {
  395. [_authorizationChecker preloadVideoCaptureAuthorization];
  396. }
  397. #pragma mark - Snap Creation triggers
  398. - (SCSnapCreationTriggers *)snapCreationTriggers
  399. {
  400. return [_managedCapturerV1 snapCreationTriggers];
  401. }
  402. @end