I got my AVCaptureSession to work, and it almost completely duplicates the user interface of Camera.app, however after a few seconds the application will crash, and I just can’t find what I'm doing wrong. I really hope someone knows how to optimize this!
I AM using ARC; and again, the whole session is working fine, but will work a bit later. The delegate method of AVCaptureSession is called as EVERY second seems. If there is a way to call this method only when the user clicks the “take a picture” button, how can I do this while maintaining a “live” preview level?
Thanks in advance!
Session setup
NSError *error = nil; session = [[AVCaptureSession alloc] init]; session.sessionPreset = AVCaptureSessionPresetMedium; device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error]; [session addInput:input]; output = [[AVCaptureVideoDataOutput alloc] init]; [session 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]; if(version >= 4.0 && version < 5.0) { output.minFrameDuration = CMTimeMake(1, 15); } output.alwaysDiscardsLateVideoFrames = YES; previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:session]; previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; [self.view.layer addSublayer:previewLayer]; [self.view addSubview:camera_overlay]; [session startRunning];
AVCaptureSession The delegate that is invoked:
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { UIImage *capture_image = [self imageFromSampleBuffer:sampleBuffer]; return capture_image; }
Method that gets UIImage from the fetch buffer
- (UIImage *)imageFromSampleBuffer:(CMSampleBufferRef)sampleBuffer { CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); CVPixelBufferLockBaseAddress(imageBuffer, 0); void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer); size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); size_t width = CVPixelBufferGetWidth(imageBuffer); size_t height = CVPixelBufferGetHeight(imageBuffer); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst); CGImageRef quartzImage = CGBitmapContextCreateImage(context); CVPixelBufferUnlockBaseAddress(imageBuffer,0); CGContextRelease(context); CGColorSpaceRelease(colorSpace); UIImage *image = [UIImage imageWithCGImage:quartzImage]; CGImageRelease(quartzImage); return image; }
source share