2011-03-23 18 views
7

को ठीक तरह से कैसे साफ़ कर सकता हूं, मैं कैमरा पूर्वावलोकन दृश्य बनाने के लिए AVFoundation एपीआई का उपयोग कर रहा हूं और मुझे पूरा होने के बाद सफाई करने में समस्या आ रही है।मैं एक AVCaptureSession और AVCaptureVideoPreviewLayer

इस समस्या को मैंने पाया है कि सबसे अच्छा जवाब इस SO thread में है, धन्यवाद कोडो।

हालांकि, वह AVCaptureVideoPreviewLayer के विलोपन को संबोधित नहीं करता है, और यही वह जगह है जहां मुझे परेशानी हो रही है।

मेरे दृश्य नियंत्रक वर्ग में मेरे पास प्रारंभिक कैमेरा कैप्चर विधि में कुछ प्रारंभिक कोड है। कोडो के जवाब को सुनकर, मैं कतार वास्तव में बंद होने पर कॉलबैक पंजीकृत करने के लिए 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 जारी करता है और अंततः मेरे कैप्चर_क्लानअप कॉलबैक को कॉल करता है जो अंततः स्वयं को रिलीज़ करता है।

मुझे समझ में नहीं आता कि मुझे कंसोल त्रुटि क्यों मिल रही है और इसे कैसे ठीक किया जाए। [_previewLayer removeFromSuperlayer] पर कॉल करने पर लेयर को अंतिम रूप दिया क्यों जा रहा है यदि self.dealloc को नहीं कहा गया है।

नोट: स्वयं एक दृश्य नियंत्रक है और मैंने अभी तक इसे पॉप नहीं किया है, इसलिए इसे नेविगेशन कंटोलर द्वारा बनाए रखा गया है।

उत्तर

2

छोड़ने से पहले सत्र को रोकने का प्रयास करें:

[captureSession stopRunning]; 
संबंधित मुद्दे