AVCaptureSession в modalviewcontroller на iOS5 с ARC
Я схожу с ума, пытаясь заставить AVCaptureSession (в контроллере представления) быть представленным и отклоненным в моем проекте. Я в настоящее время на iOS5.1 и у меня включен ARC.
Я могу заставить его работать нормально в первый раз, когда я представляю view controller и начинаю сеанс, но когда я отклоняю и представляю второй раз, сеанс не запускается. Я подписался на уведомление "AVCaptureSessionRuntimeErrorNotification" и получаю следующую ошибку:
"Ошибка домена = код AVFoundationErrorDomain =-11819 " Невозможно завершить действие " UserInfo=0x1a4020 {NSLocalizedRecoverySuggestion= Попробуйте позже. NSLocalizedDescription= Невозможно завершить действие}"
Я предполагаю, что что-то не высвобождается должным образом в моей сессии, но с ARC нет выпусков, и я вместо этого устанавливаю все, чтобы быть выпущенным, равным нулю.
мои методы viewDidLoad в основном просто запускают initCamera
Метод initCamera:
AVCaptureSession *tmpSession = [[AVCaptureSession alloc] init];
session = tmpSession;
session.sessionPreset = AVCaptureSessionPresetMedium;
captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
captureVideoPreviewLayer.frame = self.vImagePreview.bounds;
[self.vImagePreview.layer addSublayer:captureVideoPreviewLayer];
rearCamera = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
input = [AVCaptureDeviceInput deviceInputWithDevice:rearCamera error:&error];
if (!input) {
// Handle the error appropriately.
NSLog(@"ERROR: trying to open camera: %@", error);
}
[session addInput:input];
videoDataOutput = [[AVCaptureVideoDataOutput alloc] init];
NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys: [NSNumber numberWithInt:kCVPixelFormatType_32BGRA], kCVPixelBufferPixelFormatTypeKey, nil];
[videoDataOutput setVideoSettings:outputSettings];
[videoDataOutput setAlwaysDiscardsLateVideoFrames:YES];
queue = dispatch_queue_create("cameraQueue", DISPATCH_QUEUE_SERIAL);
[videoDataOutput setSampleBufferDelegate:self queue:queue];
dispatch_release(queue);
[session addOutput:videoDataOutput];
NSNotificationCenter *notify =
[NSNotificationCenter defaultCenter];
[notify addObserver: self
selector: @selector(onVideoError:)
name: AVCaptureSessionRuntimeErrorNotification
object: session];
[session startRunning];
[rearCamera lockForConfiguration:nil];
rearCamera.whiteBalanceMode = AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance;
rearCamera.exposureMode = AVCaptureExposureModeContinuousAutoExposure;
rearCamera.focusMode = AVCaptureFocusModeContinuousAutoFocus;
[rearCamera unlockForConfiguration];
Метод
captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *) соединение
При первом представлении модального view controller вызов вызывается без проблем, но со второй попытки этот метод перестает вызываться (поскольку сеанс не начинается)
Для очистки я вызываю stopSession из моего родительского view controller перед тем, как закрыть, и это делает следующее:
if ([session isRunning]) {
[session removeInput:input];
[session stopRunning];
[vImagePreview removeFromSuperview];
vImagePreview = nil;
input = nil;
videoDataOutput = nil;
captureVideoPreviewLayer = nil;
session = nil;
queue = nil;
}
Мне кажется, что я пробовал все виды вещей, таких как выполнение dispatch_sync(очередь, ^{}) в очереди, чтобы дождаться его сброса, но это, кажется, не имеет значения (при вызове dispatch_sync I убрал вызов dispatch_release в моем методе камеры init). Я также пытался использовать метод dispatch_set_finalizer_f(queue, capture_cleanup), предложенный в другом вопросе, но я не знаю, что на самом деле нужно использовать в методе capture_cleanup, потому что все примеры, которые я нахожу, являются не-ARC-кодом, где они вызывают release для указатель на себя. Я также просмотрел весь пример кода, который я могу найти в Apple (SquareCam и AVCam), но это также не ARC. Любая помощь будет принята с благодарностью.
2 ответа
Я понял, что выполняю setFocusPointOfInterest на моей задней камере, и по какой-то причине он повреждает сеанс при повторном запуске. Я не понимаю, почему это вызвало проблему, но я буду изучать это.
Вы можете попробовать преобразовать проект SquareCam в ARC перед использованием исходного кода в вашей программе. Я смог сделать это, используя __bridge в местах, на которые жаловался конвертер, а также заменил goil: goto на простые операторы if.