2011-03-23 4 views
7

AVFoundation API를 사용하여 카메라 미리보기를 만들었으며 작업을 마친 후에 정리하는 데 문제가 있습니다.AVCaptureSession 및 AVCaptureVideoPreviewLayer를 올바르게 정리하는 방법

이 문제의 가장 좋은 대답은 SO thread입니다. 감사합니다. Codo.

그러나 그는 AVCaptureVideoPreviewLayer의 할당 해제 문제를 해결하지 못하므로 문제가 발생합니다.

내 View Controller 클래스에는 startCameraCapture 메서드에 몇 가지 초기화 코드가 있습니다. Codo의 대답을 듣고, 나는 큐가 정말로 닫힐 때 콜 될 콜백을 등록하기 위해 dispatch_set_finalizer_f(_captureQueue, capture_cleanup);을 사용하고있다. 대기열에서 내 개체를 호출하기 전에 내 개체가 사라지지 않았는지 확인하기 위해 자기도 보유하고 있습니다. 그런 다음 capture_cleanup 콜백을 사용하여 자체를 릴리스합니다. 여기

-(void) startCameraCapture { 
    _camSession = [[AVCaptureSession alloc] init]; 
    if (_previewLayer == nil) { 
     _previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:_camSession]; 
    } 
    _previewLayer.frame = self.compView.bgView.frame; 
    [self.compView.bgView.layer addSublayer:_previewLayer]; 

    // Get the default camera device 
    AVCaptureDevice* camera = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 

    // Create a AVCaptureInput with the camera device 
    NSError *error=nil; 
    AVCaptureInput* cameraInput = [[AVCaptureDeviceInput alloc] initWithDevice:camera error:&error]; 
    if (cameraInput == nil) { 
     NSLog(@"Error to create camera capture:%@",error); 

    } 

    AVCaptureVideoDataOutput* videoOutput = [[[AVCaptureVideoDataOutput alloc] init] autorelease]; 

    // create a queue to run the capture on 
    _captureQueue=dispatch_queue_create("captureQueue", NULL); 
    dispatch_set_context(_captureQueue, self); 
    dispatch_set_finalizer_f(_captureQueue, capture_cleanup); 

    // setup our delegate 
    [videoOutput setSampleBufferDelegate:self queue:_captureQueue]; 

    dispatch_release(_captureQueue); 

    // retain self as a workouround a queue finalization bug in apples's sdk 
    // per Stackoverflow answer https://stackoverflow.com/questions/3741121/how-to-properly-release-an-avcapturesession 
    [self retain]; 

    // configure the pixel format 
    videoOutput.videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA], (id)kCVPixelBufferPixelFormatTypeKey, 
           nil]; 

    // and the size of the frames we want 
    [_camSession setSessionPreset:AVCaptureSessionPresetMedium]; 

    // Add the input and output 
    [_camSession addInput:cameraInput]; 
    [_camSession addOutput:videoOutput]; 

    [cameraInput release]; 

    // Start the session 
    [_camSession startRunning];  
} 

capture_cleanup 콜백 :

static void capture_cleanup(void* p) 
    { 
     LiveCompViewController* ar = (LiveCompViewController*)p; 
     [ar release]; // releases capture session if dealloc is called 
    } 

그런 다음 내 정리 코드는 다음과 같습니다

-(void) stopCameraCapture { 
[_camSession stopRunning]; 
    [_camSession release]; 
    _camSession=nil;  

    // Remove the layer in order to release the camSession 
    [_previewLayer removeFromSuperlayer]; 
    _previewLayer = nil; 

} 

제가하는 데 문제는입니다 stopCameraCapture의 superlayer에서 _previewLayer을 제거 다음 콘솔 오류가 발생합니다.

"...modifying layer that is being finalized..."

그러나 레이어를 제거해야 해제되어 _camSession이 해제되어 dispatch_queue가 해제되고 마침내 자신을 릴리스하는 내 capture_cleanup 콜백이 호출됩니다.

콘솔 오류가 발생하는 이유와 해결 방법을 이해할 수 없습니다. self.dealloc이 호출되지 않은 경우 [_previewLayer removeFromSuperlayer]을 호출 할 때 레이어가 마무리되는 이유는 무엇입니까?

참고 : self는 viewController이며 아직 팝업하지 않았으므로 NavigationContoller에 의해 유지됩니다.

답변

2

해제하기 전에 세션을 중지하십시오 :

[captureSession stopRunning]; 
관련 문제