2011-03-22 17 views
8

मैं मानक AVFoundation के वर्गों का उपयोग कर रहा वीडियो को पकड़ने और पूर्वावलोकन दिखाने के लिए (http://developer.apple.com/library/ios/#qa/qa1702/_index.html)फोकस (ऑटोफ़ोकस) कैमरे में काम नहीं कर रहा (AVFoundation AVCaptureSession)

यहाँ मेरी कोड है:

- (void)setupCaptureSession {  
    NSError *error = nil; 

    [self setCaptureSession: [[AVCaptureSession alloc] init]]; 

    self.captureSession.sessionPreset = AVCaptureSessionPresetMedium; 

    device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 

    if ([device isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus] && [device lockForConfiguration:&error]) { 
     [device setFocusMode:AVCaptureFocusModeContinuousAutoFocus]; 
     [device unlockForConfiguration]; 
    } 

    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device 
                     error:&error]; 
    if (!input) { 
     // TODO: Obsługa błędu, gdy nie uda się utworzyć wejścia 
    } 
    [[self captureSession] addInput:input]; 

    AVCaptureVideoDataOutput *output = [[[AVCaptureVideoDataOutput alloc] init] autorelease]; 
    [[self captureSession] addOutput:output]; 

    dispatch_queue_t queue = dispatch_queue_create("myQueue", NULL); 
    [output setSampleBufferDelegate:self queue:queue]; 
    dispatch_release(queue); 

    output.videoSettings = 
    [NSDictionary dictionaryWithObject: 
    [NSNumber numberWithInt:kCVPixelFormatType_32BGRA] 
           forKey:(id)kCVPixelBufferPixelFormatTypeKey]; 


    output.minFrameDuration = CMTimeMake(1, 15); 

    [[self captureSession] startRunning]; 

    AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession]; 
    captureVideoPreviewLayer.frame = previewLayer.bounds; 
    [previewLayer.layer insertSublayer:captureVideoPreviewLayer atIndex:0]; 
    [previewLayer setHidden:NO]; 

    mutex = YES; 
} 

// Delegate routine that is called when a sample buffer was written 
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer 
     fromConnection:(AVCaptureConnection *)connection { 
    if (mutex && ![device isAdjustingFocus] && ![device isAdjustingExposure] && ![device isAdjustingWhiteBalance]) { 
     // something 
    } 
} 

// Create a UIImage from sample buffer data 
- (UIImage *) imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer { 
    // Get a CMSampleBuffer's Core Video image buffer for the media data 
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
    // Lock the base address of the pixel buffer 
    CVPixelBufferLockBaseAddress(imageBuffer, 0); 

    // Get the number of bytes per row for the pixel buffer 
    void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer); 

    // Get the number of bytes per row for the pixel buffer 
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); 
    // Get the pixel buffer width and height 
    size_t width = CVPixelBufferGetWidth(imageBuffer); 
    size_t height = CVPixelBufferGetHeight(imageBuffer); 

    // Create a device-dependent RGB color space 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 

    // Create a bitmap graphics context with the sample buffer data 
    CGContextRef context = CGBitmapContextCreate(baseAddress, width, height, 8, 
               bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst); 
    // Create a Quartz image from the pixel data in the bitmap graphics context 
    CGImageRef quartzImage = CGBitmapContextCreateImage(context); 
    // Unlock the pixel buffer 
    CVPixelBufferUnlockBaseAddress(imageBuffer,0); 

    // Free up the context and color space 
    CGContextRelease(context); 
    CGColorSpaceRelease(colorSpace); 

    // Create an image object from the Quartz image 
    UIImage *image = [UIImage imageWithCGImage:quartzImage]; 

    // Release the Quartz image 
    CGImageRelease(quartzImage); 

    return (image); 
} 

सब कुछ ठीक काम कर रहा है लेकिन कभी-कभी इसमें कुछ समस्याएं होती हैं:

  • कैमरा फोकस काम नहीं कर रहा है - इसकी यादृच्छिक, कभी-कभी काम करता है, कभी-कभी नहीं। मैंने आईफोन 4 और 3 जीएस दोनों अलग-अलग उपकरणों पर कोशिश की। मैंने इसे गूगल करने की कोशिश की, लेकिन कोई परिणाम नहीं। लोग केवल टूटे हुए उपकरणों के बारे में उल्लेख कर रहे हैं, लेकिन मैंने 3 आईफोन 4 और एक आईफोन 3 जीएस पर जांच की है। समस्या हर जगह है।
  • कैमरा काफी लंबा लोड हो रहा है। मैं स्कैनरकिट एपीआई का उपयोग कर रहा हूं, जो उसी कारण से कैमरे का उपयोग कर रहा है और यह मेरे कार्यान्वयन से लगभग दो गुना तेजी से लोड हो रहा है।

कोई विचार क्या समस्या हो सकती है? पहला मुद्दा निश्चित रूप से अधिक महत्वपूर्ण है।

+0

वीडियो इनपुट बनाने के बाद फोकस मोड सेट करने का प्रयास करें। आपके कोड के बीच यह एकमात्र अंतर है। आप यह भी जांचना चाहेंगे कि यह आपके कोड में कुछ बिंदु पर सेट मोड में है। –

+0

अभी भी वही, कोई अन्य विचार? – woojtekr

+0

मैंने अपने ऐप के साथ खेला और मैंने आपकी समस्या का पुनरुत्पादन किया। मुझे इस मुद्दे को डीबग करने का मौका नहीं मिला है। मैं इसे डब्ल्यूडब्ल्यूडीसी 2010 से AVCamDemo के साथ पुन: उत्पन्न करने की कोशिश करके शुरू करूंगा। –

उत्तर

1

कुछ बिंदुओं, मैंने देखा है कि वीडियो प्रीसेट फोटो प्रीसेट की तुलना में प्रारंभ करने में अधिक समय लेता है।

क्या आप वीडियो रिकॉर्ड कर रहे हैं या तस्वीरें ले रहे हैं?

मैंने देखा है कि आपके पास मध्यम गुणवत्ता सेटिंग है लेकिन 32 बीजीआरए के साथ, यह कैप्चर मोड को फ़ोटो पर सेट करने और कैप्चर करने के बाद छवि को कम करने के लिए बेहतर काम कर सकता है। 32 बीजीआरए के बजाय AVVideoCodecJPEG भी सेट करें।

[device setOutputSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCMPixelFormat_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]]; 

तुम भी subjectAreaChangeMonitoring को सूचनाओं के लिए रजिस्टर और, एक फिर से फ़ोकस मजबूर अपने किसी भी बिंदु पर AVCaptureFocusModeAutoFocus को फोकस प्रकार के परिवर्तन से अगर करना चाह सकते हैं:

[device setOutputSettings:[NSDictionary dictionaryWithObject:AVVideoCodecJPEG forKey:AVVideoCodecKey]]; 
बजाय

आप मैन्युअल रूप से ऑटोफोकस सेट करने के लिए कोड जोड़ना चाहते हैं और कभी-कभी इसकी आवश्यकता होने पर स्वचालित रूप से इसे रीसेट कर सकते हैं।

मैंने रुचि के फोकस बिंदु सेट करने के लिए कोड में संशोधन किया है और एक प्रतिनिधि विधि में कैमरा कॉन्फ़िगरेशन त्रुटि आउटपुट लॉग इन किया है।

- (void)setupCaptureSession {  
    NSError *error = nil; 

    [self setCaptureSession: [[AVCaptureSession alloc] init]]; 

    self.captureSession.sessionPreset = AVCaptureSessionPresetMedium; 

    device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 

    if ([device isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus] && [device lockForConfiguration:&error]){ 
     [device setFocusMode:AVCaptureFocusModeContinuousAutoFocus]; 
     if ([device isFocusPointOfInterestSupported]) 
      [device setFocusPointOfInterest:CGPointMake(0.5f,0.5f)]; 
     [device unlockForConfiguration]; 
    }else { 
     if ([[self delegate] 
       respondsToSelector:@selector(captureManager:didFailWithError:)]) { 
       [[self delegate] captureManager:self didFailWithError:error]; 
     } 
    } 

    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device 
                     error:&error]; 
    if (!input) { 
     // TODO: Obsługa błędu, gdy nie uda się utworzyć wejścia 
    } 
    [[self captureSession] addInput:input]; 

    AVCaptureVideoDataOutput *output = [[[AVCaptureVideoDataOutput alloc] init] autorelease]; 
    [[self captureSession] addOutput:output]; 

    dispatch_queue_t queue = dispatch_queue_create("myQueue", NULL); 
    [output setSampleBufferDelegate:self queue:queue]; 
    dispatch_release(queue); 

    output.videoSettings = 
    [NSDictionary dictionaryWithObject: 
    [NSNumber numberWithInt:kCVPixelFormatType_32BGRA] 
           forKey:(id)kCVPixelBufferPixelFormatTypeKey]; 


    output.minFrameDuration = CMTimeMake(1, 15); 

    [[self captureSession] startRunning]; 

    AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession]; 
    captureVideoPreviewLayer.frame = previewLayer.bounds; 
    [previewLayer.layer insertSublayer:captureVideoPreviewLayer atIndex:0]; 
    [previewLayer setHidden:NO]; 

    mutex = YES; 
} 
9

पुराना प्रश्न लेकिन वैसे भी किसी को निराशा के घंटे बचा सकता है। setFocusMode पर कॉल करने से पहले ब्याज बिंदु सेट करना महत्वपूर्ण है, अन्यथा आपका कैमरा पिछले फोकस बिंदु पर फ़ोकस सेट करेगा। setFocusModeCOMMIT के रूप में सोचें। setExposureMode पर भी लागू होता है।

ऐप्पल द्वारा AVCam नमूना पूरी तरह से गलत और टूटा हुआ है।

+1

आप मुझे बहुत समय बचाते हैं बहुत धन्यवाद – devfreak

+1

बहुत सच्चा और उपयोगी :-) –