Maybe fix camera crash on capture session stopping

This commit is contained in:
Ilya Laktyushin 2023-04-10 00:10:19 +04:00
parent cdc32a8910
commit 8d53183b65
3 changed files with 49 additions and 34 deletions

View File

@ -4,6 +4,7 @@
@class PGCameraMovieWriter;
@class PGRectangleDetector;
@class SQueue;
@interface PGCameraCaptureSession : AVCaptureSession
@ -65,4 +66,6 @@
+ (bool)_isZoomAvailableForDevice:(AVCaptureDevice *)device;
+ (SQueue *)cameraQueue;
@end

View File

@ -120,7 +120,7 @@ NSString *const PGCameraAdjustingFocusKey = @"adjustingFocus";
TGLegacyLog(@"ERROR: Camera runtime error: %@", notification.userInfo[AVCaptureSessionErrorKey]);
__weak PGCamera *weakSelf = self;
TGDispatchAfter(1.5f, [PGCamera cameraQueue]._dispatch_queue, ^
TGDispatchAfter(1.5f, [PGCameraCaptureSession cameraQueue]._dispatch_queue, ^
{
__strong PGCamera *strongSelf = weakSelf;
if (strongSelf == nil || strongSelf->_invalidated)
@ -198,7 +198,7 @@ NSString *const PGCameraAdjustingFocusKey = @"adjustingFocus";
[previewView setupWithCamera:self];
__weak PGCamera *weakSelf = self;
[[PGCamera cameraQueue] dispatch:^
[[PGCameraCaptureSession cameraQueue] dispatch:^
{
__strong PGCamera *strongSelf = weakSelf;
if (strongSelf == nil || strongSelf->_invalidated)
@ -225,7 +225,7 @@ NSString *const PGCameraAdjustingFocusKey = @"adjustingFocus";
if (_invalidated)
return;
[[PGCamera cameraQueue] dispatch:^
[[PGCameraCaptureSession cameraQueue] dispatch:^
{
if (self.captureSession.isRunning)
return;
@ -261,10 +261,11 @@ NSString *const PGCameraAdjustingFocusKey = @"adjustingFocus";
TGLegacyLog(@"Camera: stop capture");
[[PGCamera cameraQueue] dispatch:^
[[PGCameraCaptureSession cameraQueue] dispatch:^
{
if (_invalidated)
{
#if !TARGET_IPHONE_SIMULATOR
[self.captureSession beginConfiguration];
[self.captureSession resetFlashMode];
@ -279,16 +280,21 @@ NSString *const PGCameraAdjustingFocusKey = @"adjustingFocus";
for (AVCaptureOutput *output in self.captureSession.outputs)
[self.captureSession removeOutput:output];
#if !TARGET_IPHONE_SIMULATOR
[self.captureSession commitConfiguration];
#endif
}
TGLegacyLog(@"Camera: stop running");
#if !TARGET_IPHONE_SIMULATOR
[self.captureSession stopRunning];
@try {
[self.captureSession stopRunning];
} @catch (NSException *exception) {
TGLegacyLog(@"Camera: caught exception %@", exception.description);
[self.captureSession commitConfiguration];
[self.captureSession stopRunning];
TGLegacyLog(@"Camera: seems to be successfully resolved");
}
#endif
_capturing = false;
TGDispatchOnMainThread(^
@ -328,9 +334,9 @@ NSString *const PGCameraAdjustingFocusKey = @"adjustingFocus";
};
if (synchronous)
[[PGCamera cameraQueue] dispatchSync:block];
[[PGCameraCaptureSession cameraQueue] dispatchSync:block];
else
[[PGCamera cameraQueue] dispatch:block];
[[PGCameraCaptureSession cameraQueue] dispatch:block];
}
#pragma mark -
@ -361,7 +367,7 @@ NSString *const PGCameraAdjustingFocusKey = @"adjustingFocus";
{
bool videoMirrored = !self.disableResultMirroring ? _previewView.captureConnection.videoMirrored : false;
[[PGCamera cameraQueue] dispatch:^
[[PGCameraCaptureSession cameraQueue] dispatch:^
{
if (!self.captureSession.isRunning || self.captureSession.imageOutput.isCapturingStillImage || _invalidated)
return;
@ -410,13 +416,13 @@ NSString *const PGCameraAdjustingFocusKey = @"adjustingFocus";
if (CFAbsoluteTimeGetCurrent() - _captureStartTime > 0.4)
takePhoto();
else
TGDispatchAfter(0.4 - delta, [[PGCamera cameraQueue] _dispatch_queue], takePhoto);
TGDispatchAfter(0.4 - delta, [[PGCameraCaptureSession cameraQueue] _dispatch_queue], takePhoto);
}];
}
- (void)startVideoRecordingForMoment:(bool)moment completion:(void (^)(NSURL *, CGAffineTransform transform, CGSize dimensions, NSTimeInterval duration, bool success))completion
{
[[PGCamera cameraQueue] dispatch:^
[[PGCameraCaptureSession cameraQueue] dispatch:^
{
if (!self.captureSession.isRunning || _invalidated)
return;
@ -443,7 +449,7 @@ NSString *const PGCameraAdjustingFocusKey = @"adjustingFocus";
if (CFAbsoluteTimeGetCurrent() - _captureStartTime > 1.5)
startRecording();
else
TGDispatchAfter(1.5, [[PGCamera cameraQueue] _dispatch_queue], startRecording);
TGDispatchAfter(1.5, [[PGCameraCaptureSession cameraQueue] _dispatch_queue], startRecording);
TGDispatchOnMainThread(^
{
@ -455,7 +461,7 @@ NSString *const PGCameraAdjustingFocusKey = @"adjustingFocus";
- (void)stopVideoRecording
{
[[PGCamera cameraQueue] dispatch:^
[[PGCameraCaptureSession cameraQueue] dispatch:^
{
[self.captureSession stopVideoRecording];
@ -496,7 +502,7 @@ NSString *const PGCameraAdjustingFocusKey = @"adjustingFocus";
if (strongSelf == nil)
return;
[[PGCamera cameraQueue] dispatch:^
[[PGCameraCaptureSession cameraQueue] dispatch:^
{
strongSelf.captureSession.currentMode = cameraMode;
@ -584,7 +590,7 @@ NSString *const PGCameraAdjustingFocusKey = @"adjustingFocus";
- (void)_setFocusPoint:(CGPoint)point focusMode:(AVCaptureFocusMode)focusMode exposureMode:(AVCaptureExposureMode)exposureMode monitorSubjectAreaChange:(bool)monitorSubjectAreaChange
{
[[PGCamera cameraQueue] dispatch:^
[[PGCameraCaptureSession cameraQueue] dispatch:^
{
if (self.disabled)
return;
@ -600,7 +606,7 @@ NSString *const PGCameraAdjustingFocusKey = @"adjustingFocus";
- (void)beginExposureTargetBiasChange
{
[[PGCamera cameraQueue] dispatch:^
[[PGCameraCaptureSession cameraQueue] dispatch:^
{
if (self.disabled)
return;
@ -611,7 +617,7 @@ NSString *const PGCameraAdjustingFocusKey = @"adjustingFocus";
- (void)setExposureTargetBias:(CGFloat)bias
{
[[PGCamera cameraQueue] dispatch:^
[[PGCameraCaptureSession cameraQueue] dispatch:^
{
if (self.disabled)
return;
@ -622,7 +628,7 @@ NSString *const PGCameraAdjustingFocusKey = @"adjustingFocus";
- (void)endExposureTargetBiasChange
{
[[PGCamera cameraQueue] dispatch:^
[[PGCameraCaptureSession cameraQueue] dispatch:^
{
if (self.disabled)
return;
@ -661,7 +667,7 @@ NSString *const PGCameraAdjustingFocusKey = @"adjustingFocus";
- (void)setFlashMode:(PGCameraFlashMode)flashMode
{
[[PGCamera cameraQueue] dispatch:^
[[PGCameraCaptureSession cameraQueue] dispatch:^
{
self.captureSession.currentFlashMode = flashMode;
}];
@ -689,7 +695,7 @@ NSString *const PGCameraAdjustingFocusKey = @"adjustingFocus";
if (strongSelf == nil)
return;
[[PGCamera cameraQueue] dispatch:^
[[PGCameraCaptureSession cameraQueue] dispatch:^
{
[strongSelf.captureSession setCurrentCameraPosition:targetCameraPosition];
@ -744,7 +750,7 @@ NSString *const PGCameraAdjustingFocusKey = @"adjustingFocus";
if (self.cameraMode == PGCameraModeVideo) {
animated = false;
}
[[PGCamera cameraQueue] dispatch:^
[[PGCameraCaptureSession cameraQueue] dispatch:^
{
if (self.disabled)
return;
@ -786,18 +792,6 @@ NSString *const PGCameraAdjustingFocusKey = @"adjustingFocus";
return ([PGCameraCaptureSession _deviceWithCameraPosition:PGCameraPositionFront] != nil);
}
+ (SQueue *)cameraQueue
{
static dispatch_once_t onceToken;
static SQueue *queue = nil;
dispatch_once(&onceToken, ^
{
queue = [[SQueue alloc] init];
});
return queue;
}
+ (AVCaptureVideoOrientation)_videoOrientationForInterfaceOrientation:(UIInterfaceOrientation)deviceOrientation mirrored:(bool)mirrored
{
switch (deviceOrientation)

View File

@ -208,6 +208,7 @@ const NSInteger PGCameraFrameRate = 30;
- (void)reset
{
NSAssert([[PGCameraCaptureSession cameraQueue] isCurrentQueue], @"[[PGCameraCaptureSession cameraQueue] isCurrentQueue]");
[self beginConfiguration];
[self _removeAudioInputEndAudioSession:true];
@ -259,6 +260,8 @@ const NSInteger PGCameraFrameRate = 30;
- (void)setCurrentMode:(PGCameraMode)mode
{
NSAssert([[PGCameraCaptureSession cameraQueue] isCurrentQueue], @"[[PGCameraCaptureSession cameraQueue] isCurrentQueue]");
_currentMode = mode;
[self beginConfiguration];
@ -804,6 +807,7 @@ const NSInteger PGCameraFrameRate = 30;
- (void)setCurrentCameraPosition:(PGCameraPosition)position
{
NSAssert([[PGCameraCaptureSession cameraQueue] isCurrentQueue], @"[[PGCameraCaptureSession cameraQueue] isCurrentQueue]");
AVCaptureDevice *deviceForTargetPosition = [PGCameraCaptureSession _deviceWithCameraPosition:position];
if ([_videoDevice isEqual:deviceForTargetPosition])
return;
@ -1123,4 +1127,18 @@ static UIImageOrientation TGSnapshotOrientationForVideoOrientation(bool mirrored
}
}
#pragma mark -
+ (SQueue *)cameraQueue
{
static dispatch_once_t onceToken;
static SQueue *queue = nil;
dispatch_once(&onceToken, ^
{
queue = [[SQueue alloc] init];
});
return queue;
}
@end