有问题的问题是使用AVFoundation
来设置一个输出显示在AVCaptureVideoPreviewLayer
中的相机,并将其作为像素缓冲区处理。为了通过- processSampleBuffer:
方法处理像素缓冲区,必须以正确的方向提供,这取决于设备方向。
据我所知,这可以通过在-captureOutput:didOutputSampleBuffer:fromConnection:
中访问原始像素值,或通过设置videoOrientation
来旋转样本缓冲区委托方法中给定的像素缓冲区来完成相应AVCaptureConnection
上的属性,确保像素缓冲区以所需方向提供。设置概述如下:
- (void)setupCamera
{
AVCaptureSession *session = [AVCaptureSession new];
AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:backCamera error:nil];
AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
[session addInput:deviceInput];
dispatch_queue_t videoOutputQueue = dispatch_queue_create("com.MyApp.videoQueue", DISPATCH_QUEUE_SERIAL);
dispatch_set_target_queue(videoOutputQueue, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0));
AVCaptureVideoDataOutput *videoOutput = [AVCaptureVideoDataOutput new];
videoOutput.alwaysDiscardsLateVideoFrames = YES;
[videoOutput setSampleBufferDelegate:self queue:videoOutputQueue];
[session addOutput:videoOutput];
// more setup
}
- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection
{
connection.videoOrientation = [self getCurrentOrientation]; // setting this to a new value causes the preview layer to freeze momentarily
[self processSampleBuffer:sampleBuffer]; // some arbitrary image processing method
}
就像素缓冲区的方向而言,这可以正常工作,但是,只要将设备旋转到新的方向,给connection.videoOrientation
一个新值,预览图层就会冻结几分之一秒。阻止委托方法的线程(例如通过添加睡眠)不会冻结预览层,因此不是问题。对解决方案的任何帮助都非常感谢!