Я использую классы AV Foundation для захвата живого видеопотока с камеры и обработки образцов видео.Это хорошо работает.Однако у меня возникают проблемы с правильным освобождением экземпляров основы AV (сеанс захвата, слой предварительного просмотра, ввод и вывод), как только я закончу.
Когда мне больше не нужен сеанс и все связанные объекты, я останавливаюзахватить сессию и выпустить ееЭто работает большую часть времени.Однако иногда происходит сбой приложения с сигналом EXEC_BAD_ACCESS, возникающим во втором потоке, который был создан в очереди отправки (и где обрабатываются образцы видео).Сбой происходит в основном из-за моего собственного экземпляра класса, который служит образцом делегата буфера и освобождается после того, как я остановил сеанс захвата.
В документации Apple упоминается проблема: остановка сеанса захвата является асинхроннойоперация.То есть: это происходит не сразу.В частности, второй поток продолжает обрабатывать сэмплы видео и получать доступ к различным экземплярам, таким как сеанс захвата или устройства ввода и вывода.
Так как же правильно освободить AVCaptureSession и все связанные экземпляры?Есть ли уведомление, которое достоверно сообщает мне, что AVCaptureSession завершен?
Вот мой код:
Объявления:
AVCaptureSession* session;
AVCaptureVideoPreviewLayer* previewLayer;
UIView* view;
Настройка экземпляров:
AVCaptureDevice* camera = [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo];
session = [[AVCaptureSession alloc] init];
AVCaptureDeviceInput* input = [AVCaptureDeviceInput deviceInputWithDevice: camera error: &error];
[session addInput: input];
AVCaptureVideoDataOutput* output = [[[AVCaptureVideoDataOutput alloc] init] autorelease];
[session addOutput: output];
dispatch_queue_t queue = dispatch_queue_create("augm_reality", NULL);
[output setSampleBufferDelegate: self queue: queue];
dispatch_release(queue);
previewLayer = [[AVCaptureVideoPreviewLayer layerWithSession: session] retain];
previewLayer.frame = view.bounds;
[view.layer addSublayer: previewLayer];
[session startRunning];
Очистка:
[previewLayer removeFromSuperlayer];
[previewLayer release];
[session stopRunning];
[session release];