【问题标题】:Switching AVCaptureSession preset when capturing a photo拍摄照片时切换 AVCaptureSession 预设
【发布时间】:2012-08-21 12:57:15
【问题描述】:

我目前的设置如下(基于Brad Larson的ColorTrackingCamera项目):

我正在使用设置为AVCaptureSessionPreset640x480AVCaptureSession,我让输出作为纹理通过OpenGL 场景运行。然后由片段着色器处理此纹理。

我需要这种“低质量”预设,因为我想在用户预览时保持高帧率。然后,当用户拍摄静止照片时,我想切换到更高质量的输出。

首先,我认为我可以更改 AVCaptureSession 上的 sessionPreset,但这会迫使相机重新对焦,从而破坏可用性。

[captureSession beginConfiguration];
captureSession.sessionPreset = AVCaptureSessionPresetPhoto;
[captureSession commitConfiguration];

目前我正在尝试向 AVCaptureSession 添加第二个AVCaptureStillImageOutput,但我得到了一个空的像素缓冲区,所以我觉得我有点卡住了。

这是我的会话设置代码:

...

// Add the video frame output
[captureSession beginConfiguration];

videoOutput = [[AVCaptureVideoDataOutput alloc] init];
[videoOutput setAlwaysDiscardsLateVideoFrames:YES];
[videoOutput setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]];
[videoOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()];

if ([captureSession canAddOutput:videoOutput])
{
    [captureSession addOutput:videoOutput];
}
else
{
    NSLog(@"Couldn't add video output");
}

[captureSession commitConfiguration];



// Add still output
[captureSession beginConfiguration];
stillOutput = [[AVCaptureStillImageOutput alloc] init];

if([captureSession canAddOutput:stillOutput])
{
    [captureSession addOutput:stillOutput];
}
else
{
    NSLog(@"Couldn't add still output");
}

[captureSession commitConfiguration];



// Start capturing
[captureSession setSessionPreset:AVCaptureSessionPreset640x480];
if(![captureSession isRunning])
{
    [captureSession startRunning];
};

...

这是我的捕获方法:

- (void)prepareForHighResolutionOutput
{
    AVCaptureConnection *videoConnection = nil;
    for (AVCaptureConnection *connection in stillOutput.connections) {
        for (AVCaptureInputPort *port in [connection inputPorts]) {
            if ([[port mediaType] isEqual:AVMediaTypeVideo] ) {
                videoConnection = connection;
                break;
            }
        }
        if (videoConnection) { break; }
    }

    [stillOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:
     ^(CMSampleBufferRef imageSampleBuffer, NSError *error) {
         CVImageBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(imageSampleBuffer);
         CVPixelBufferLockBaseAddress(pixelBuffer, 0);
         int width = CVPixelBufferGetWidth(pixelBuffer);
         int height = CVPixelBufferGetHeight(pixelBuffer);

         NSLog(@"%i x %i", width, height);
         CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
     }];
}

widthheight 结果为 0)

我已经阅读了 AVFoundation 文档的文档,但似乎我没有得到必要的东西。

【问题讨论】:

  • 您需要多快才能运行此预览版?使用运行视频预览的 AVCaptureStillImageOutput(在 iOS 4.3+ 上受支持),我在该视频预览的输入帧上看到 20 FPS。这不是摄像机的完整 30 FPS,但对于您要拍摄的场景的预览来说已经足够了。
  • 好吧,我在几分钟前找到了解决方案。我现在使用AVCaptureStillImageOutput 预设,但我必须明确设置outputSettings 以避免颜色空间之间的转换。我会立即将其发布为答案。

标签: iphone ios avfoundation


【解决方案1】:

我找到了针对我的具体问题的解决方案。如果有人偶然发现同样的问题,我希望它可以作为指导。

帧率大幅下降的原因与像素格式之间的内部转换有关。明确设置像素格式后,帧速率增加。

在我的情况下,我正在使用以下方法创建 BGRA 纹理:

// Let Core Video create the OpenGL texture from pixelbuffer
CVReturn err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, videoTextureCache, pixelBuffer, NULL,
                                                            GL_TEXTURE_2D, GL_RGBA, width, height, GL_BGRA,
                                                            GL_UNSIGNED_BYTE, 0, &videoTexture);

因此,当我设置 AVCaptureStillImageOutput 实例时,我将代码更改为:

// Add still output
stillOutput = [[AVCaptureStillImageOutput alloc] init];
[stillOutput setOutputSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]];

if([captureSession canAddOutput:stillOutput])
{
    [captureSession addOutput:stillOutput];
}
else
{
    NSLog(@"Couldn't add still output");
}

我希望有一天这对某人有所帮助;)

【讨论】:

  • 我正在尝试您的代码,但我仍在点击 640 x 480。可能有任何更新吗?
  • 我的代码中有类似的情况,我正在拍摄 640x480 的提要,但随后想拍摄高分辨率照片。不幸的是,即使添加了setOutputSettings: 参数,我的宽度和高度仍然为零。你能帮忙吗?
  • 请告诉我,您如何获得高质量?你的预设是AVCaptureSessionPreset640x480...
  • 能否提供最终代码。我不知道在哪里使用 CVOpenGLESTextureCacheCreateTextureFromImage
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-30
  • 2015-01-13
  • 2022-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多