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.

76 lines
2.7 KiB

  1. //
  2. // SCManagedCapturerARSessionHandler.m
  3. // Snapchat
  4. //
  5. // Created by Xiaokang Liu on 16/03/2018.
  6. //
  7. #import "SCManagedCapturerARSessionHandler.h"
  8. #import "SCCaptureResource.h"
  9. #import "SCManagedCaptureSession.h"
  10. #import <SCBase/SCAvailability.h>
  11. #import <SCFoundation/SCAssertWrapper.h>
  12. #import <SCFoundation/SCQueuePerformer.h>
  13. @import ARKit;
  14. static CGFloat const kSCManagedCapturerARKitShutdownTimeoutDuration = 2;
  15. @interface SCManagedCapturerARSessionHandler () {
  16. SCCaptureResource *__weak _captureResource;
  17. dispatch_semaphore_t _arSesssionShutdownSemaphore;
  18. }
  19. @end
  20. @implementation SCManagedCapturerARSessionHandler
  21. - (instancetype)initWithCaptureResource:(SCCaptureResource *)captureResource
  22. {
  23. self = [super init];
  24. if (self) {
  25. SCAssert(captureResource, @"");
  26. _captureResource = captureResource;
  27. _arSesssionShutdownSemaphore = dispatch_semaphore_create(0);
  28. }
  29. return self;
  30. }
  31. - (void)stopObserving
  32. {
  33. [[NSNotificationCenter defaultCenter] removeObserver:self
  34. name:AVCaptureSessionDidStopRunningNotification
  35. object:nil];
  36. }
  37. - (void)stopARSessionRunning
  38. {
  39. SCAssertPerformer(_captureResource.queuePerformer);
  40. SCAssert(SC_AT_LEAST_IOS_11, @"Shoule be only call from iOS 11+");
  41. if (@available(iOS 11.0, *)) {
  42. // ARSession stops its internal AVCaptureSession asynchronously. We listen for its callback and actually restart
  43. // our own capture session once it's finished shutting down so the two ARSessions don't conflict.
  44. [[NSNotificationCenter defaultCenter] addObserver:self
  45. selector:@selector(_completeARSessionShutdown:)
  46. name:AVCaptureSessionDidStopRunningNotification
  47. object:nil];
  48. [_captureResource.arSession pause];
  49. dispatch_semaphore_wait(
  50. _arSesssionShutdownSemaphore,
  51. dispatch_time(DISPATCH_TIME_NOW, (int64_t)(kSCManagedCapturerARKitShutdownTimeoutDuration * NSEC_PER_SEC)));
  52. }
  53. }
  54. - (void)_completeARSessionShutdown:(NSNotification *)note
  55. {
  56. // This notification is only registered for IMMEDIATELY before arkit shutdown.
  57. // Explicitly guard that the notification object IS NOT the main session's.
  58. SC_GUARD_ELSE_RETURN(![note.object isEqual:_captureResource.managedSession.avSession]);
  59. [[NSNotificationCenter defaultCenter] removeObserver:self
  60. name:AVCaptureSessionDidStopRunningNotification
  61. object:nil];
  62. dispatch_semaphore_signal(_arSesssionShutdownSemaphore);
  63. }
  64. @end