我正在开发一个应用程序,它需要尽可能多地捕获帧缓冲区.我已经想出如何强制iPhone以60 fps的速度捕获但是
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
方法每秒只被调用15次,这意味着iPhone将捕获输出降级为15 fps.
有人遇到过这样的问题吗?是否有可能提高捕获帧率?
更新我的代码:
camera = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; if([camera isTorchModeSupported:AVCaptureTorchModeOn]) { [camera lockForConfiguration:nil]; camera.torchMode=AVCaptureTorchModeOn; [camera unlockForConfiguration]; } [self configureCameraForHighestFrameRate:camera]; // 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); } // Set the output AVCaptureVideoDataOutput* videoOutput = [[AVCaptureVideoDataOutput alloc] init]; // create a queue to run the capture on dispatch_queue_t captureQueue=dispatch_queue_create("captureQueue", NULL); // setup our delegate [videoOutput setSampleBufferDelegate:self queue:captureQueue]; // configure the pixel format videoOutput.videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA], (id)kCVPixelBufferPixelFormatTypeKey, nil]; // Add the input and output [captureSession addInput:cameraInput]; [captureSession addOutput:videoOutput];
我在configureCameraForHighestFrameRate
这里采取了方法https://developer.apple.com/library/mac/documentation/AVFoundation/Reference/AVCaptureDevice_Class/Reference/Reference.html
我在iPhone 5上获得60 fps的样本,在iPhone 5s上获得120 fps的样本,无论是在captureOutput中进行实时运动检测,还是在使用AVAssetWriter将帧保存到视频时.
您必须将AVCaptureSession设置为支持60 fps的格式:
AVsession = [[AVCaptureSession alloc] init]; AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; AVCaptureDeviceInput *capInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error]; if (capInput) [AVsession addInput:capInput]; for(AVCaptureDeviceFormat *vFormat in [videoDevice formats] ) { CMFormatDescriptionRef description= vFormat.formatDescription; float maxrate=((AVFrameRateRange*)[vFormat.videoSupportedFrameRateRanges objectAtIndex:0]).maxFrameRate; if(maxrate>59 && CMFormatDescriptionGetMediaSubType(description)==kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) { if ( YES == [videoDevice lockForConfiguration:NULL] ) { videoDevice.activeFormat = vFormat; [videoDevice setActiveVideoMinFrameDuration:CMTimeMake(10,600)]; [videoDevice setActiveVideoMaxFrameDuration:CMTimeMake(10,600)]; [videoDevice unlockForConfiguration]; NSLog(@"formats %@ %@ %@",vFormat.mediaType,vFormat.formatDescription,vFormat.videoSupportedFrameRateRanges); } } } prevLayer = [AVCaptureVideoPreviewLayer layerWithSession: AVsession]; prevLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; [self.view.layer addSublayer: prevLayer]; AVCaptureVideoDataOutput *videoOut = [[AVCaptureVideoDataOutput alloc] init]; dispatch_queue_t videoQueue = dispatch_queue_create("videoQueue", NULL); [videoOut setSampleBufferDelegate:self queue:videoQueue]; videoOut.videoSettings = @{(id)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA)}; videoOut.alwaysDiscardsLateVideoFrames=YES; if (videoOut) { [AVsession addOutput:videoOut]; videoConnection = [videoOut connectionWithMediaType:AVMediaTypeVideo]; }
如果要使用AVAssetWriter写入文件,请另外两条注释.不要使用pixelAdaptor,只需使用样本
[videoWriterInput appendSampleBuffer:sampleBuffer]
其次在设置资产编写者时使用
[AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings sourceFormatHint:formatDescription];
sourceFormatHint在写入速度方面有所不同.