Używam klas AV Foundation do przechwytywania strumienia wideo na żywo z kamery i przetwarzania próbek wideo. To działa ładnie. Mam jednak problemy z właściwym wypuszczeniem instancji fundacji AV (sesja przechwytywania, warstwa podglądu, wejście i wyjście) po zakończeniu.Jak poprawnie zwolnić AVCaptureSession
Gdy nie potrzebuję już sesji i wszystkich powiązanych obiektów, zatrzymuję sesję przechwytywania i zwalniam ją. Działa to przez większość czasu. Czasami jednak aplikacja ulega awarii z sygnałem EXEC_BAD_ACCESS podniesionym w drugim wątku, który został utworzony przez kolejkę wysyłkową (i gdzie przetwarzane są próbki wideo). Przyczyną awarii jest głównie moja własna instancja klasy, która służy jako delegat bufora próbek i jest zwalniana po zatrzymaniu sesji przechwytywania.
Dokumentacja Apple wspomina o problemie: Zatrzymanie sesji przechwytywania jest operacją asynchroniczną. To znaczy: nie dzieje się to natychmiast. W szczególności drugi wątek kontynuuje przetwarzanie próbek wideo i dostęp do różnych instancji, takich jak sesja przechwytywania lub urządzenia wejściowe i wyjściowe.
Jak właściwie wypuścić AVCaptureSession i wszystkie powiązane instancje? Czy istnieje powiadomienie, które niezawodnie informuje mnie, że sesja AVCaptureSession została zakończona?
Oto mój kod:
Deklaracje:
AVCaptureSession* session;
AVCaptureVideoPreviewLayer* previewLayer;
UIView* view;
Konfiguracja instancji:
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];
Cleanup:
[previewLayer removeFromSuperlayer];
[previewLayer release];
[session stopRunning];
[session release];
Co to jest AugmReality w funkcji capture_cleanup? nie dostaję tego. – NiravPatel
* AugmReality * to niestandardowa klasa mojej aplikacji implementująca delegata bufora próbki. Zatem zmienna * p * (lub * ar *) odnosi się do instancji, którą chcę zwolnić, ale nie może, dopóki sesja przechwytywania nie zostanie całkowicie zatrzymana. – Codo