5

Sto impazzendo cercando di ottenere una AVCaptureSession (in un controller di visualizzazione) da presentare e chiudere nel mio progetto. Sono attualmente su iOS5.1 e ho abilitato ARC.AVCaptureSession in modalviewcontroller su iOS5 con ARC

Posso farlo funzionare correttamente la prima volta che presento il viewcontroller e avviare la sessione, ma quando si chiude e si presenta una seconda volta la sessione non verrà avviata. Mi sono iscritto alla notifica "AVCaptureSessionRuntimeErrorNotification" e ricevo il seguente errore:

"errore di dominio = Codice AVFoundationErrorDomain = -11.819 'Può azione non completa' UserInfo = 0x1a4020 {. NSLocalizedRecoverySuggestion = Riprovare più tardi, NSLocalizedDescription = Azione non può completare}"

Suppongo che qualcosa non venga rilasciato correttamente nella mia sessione, ma con ARC non ci sono versioni e invece ho impostato tutto per essere rilasciato a zero.

miei metodi viewDidLoad fondamentalmente solo innesca initCamera

initCamera metodo:

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]; 

Il metodo

captureOutput: (AVCaptureOutput *) captureOutput didOutputSampleBuffer: (CMSampleBufferRef) sampleBuffer fromConnection: (AVCaptureConnection *) collegamento

viene chiamato nessun problema la prima volta che presento il modal viewcontroller, ma al secondo tentativo questo metodo smette di essere chiamato (perché la sessione non parte)

Per ripulire Sto chiamando stopSession dal mio Viewcontroller padre prima di chiudere e che fa il seguente:

if ([session isRunning]) { 
    [session removeInput:input]; 
    [session stopRunning]; 

    [vImagePreview removeFromSuperview]; 
    vImagePreview = nil; 


    input = nil; 
    videoDataOutput = nil; 
    captureVideoPreviewLayer = nil; 
    session = nil; 

    queue = nil; 


} 

mi sento come ho provato ogni sorta di cose, come l'esecuzione di un dispatch_sync (coda^{}) sulla coda di attesa per essere lavata, ma che doesn sembra che faccia la differenza (quando chiami il dispatch_sync ho rimosso la chiamata dispatch_release nel mio metodo della macchina fotografica init). Ho anche provato a usare il metodo dispatch_set_finalizer_f (queue, capture_cleanup) suggerito in un'altra domanda, ma non so che cosa deve effettivamente andare nel metodo capture_cleanup perché tutti gli esempi che trovo sono codice non ARC dove chiamano release su puntatore a sé. Ho anche analizzato tutto il codice di esempio che posso trovare su Apple (SquareCam e AVCam), ma anche questi non sono ARC. Qualsiasi aiuto sarebbe molto apprezzato.

risposta

5

Mi sono reso conto che stavo eseguendo un setFocusPointOfInterest sulla mia fotocamera posteriore e per qualche motivo stava corrompendo la sessione di rilancio. Non capisco perché questo abbia causato il problema, ma lo esaminerò.

+0

Questo ha risolto anche il mio problema. – yuxhuang

0

Si potrebbe provare a convertire il progetto SquareCam in ARC prima di utilizzare la sorgente nel programma. Sono stato in grado di farlo utilizzando un cast __bridge nei posti in cui il convertitore si stava lamentando, e ho anche sostituito il "bail:" goto con semplici istruzioni if.