【问题标题】:Trouble rendering camera feed as OpenGL texture (iOS)无法将相机源渲染为 OpenGL 纹理 (iOS)
【发布时间】:2014-02-01 17:57:38
【问题描述】:

我花了几天时间试图解决这个问题,但没有成功。

我正在尝试将相机输入渲染到 OpenGL 纹理。我设法让它在不使用 CVOpenGLESTextureCacheCreateTextureFromImage 的情况下工作,只需从 sampleBuffer 中创建 CGImage。我的表现很糟糕,我需要使用缓存。

作为参考,我使用了RosyWriter 示例。我改变了几十次,但这就是我现在得到的,在我看来这只是一个例子,但更简化了。

我不会粘贴 AV 设置代码(如果需要我可以)。这是委托方法的实现:

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
    CVImageBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
    size_t frameWidth = CVPixelBufferGetWidth(pixelBuffer);
    size_t frameHeight = CVPixelBufferGetHeight(pixelBuffer);
    CVOpenGLESTextureRef texture = NULL;
    CVReturn err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault,
                                                                videoTextureCache,
                                                                pixelBuffer,
                                                                NULL,
                                                                GL_TEXTURE_2D,
                                                                GL_RGBA,
                                                                frameWidth,
                                                                frameHeight,
                                                                GL_BGRA,
                                                                GL_UNSIGNED_BYTE,
                                                                0,
                                                                &texture);


    if (!texture || err) {
        NSLog(@"CVOpenGLESTextureCacheCreateTextureFromImage failed (error: %d)", err);
        return;
    }
}

如您所见,我删除了预览队列(尝试使用它,但没有成功)以及我认为不必要的任何内容。

传递给函数的属性看起来没问题(pixelBuffer 有 iosurface,frameWidth/Height 是正确的)。

CVOpenGLESTextureCacheCreateTextureFromImage 日志

“创建 IOSurface 图像(纹理)失败”

并返回错误

CVOpenGLESTextureCacheCreateTextureFromImage 失败(错误:-6683)

正如我所说,我尝试了很多东西,有不同的错误,有时只是有黑色纹理。

我刚开始使用 OpenGL,所以这可能是显而易见的,无论如何,如果有人看看这个问题,那就太好了。我粘贴了我认为相关的代码,如果有其他需要我会更新。

更新

将此行添加到 AV 输出设置后,我停止接收错误,而是得到一个空白的黑色纹理。我怀疑它可能有颜色范围/格式的东西,有什么想法吗?

[output setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]];

【问题讨论】:

标签: ios opengl-es


【解决方案1】:

好的,更新中提到的行解决了错误。之后,我有一个空白图像,不知道该怎么办。我使用了新的 XCode 5 OpenGL 调试器(Capture OpenGL ES frame in the debug window),发现有错误:

Texture #2 使用不受支持的 wrap 参数或非幂的两个纹理。请改用 GL_CLAMP_TO_EDGE,或调整纹理大小。

在那之后很清楚该怎么做,首先我通过添加以下内容更改了包装:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

并且出现了一个相机框架,但纹理没有更新。添加发布方法后,一切都开始正常了。

CFRelease(texture);
CVOpenGLESTextureCacheFlush(videoTextureCache, 0);

现在我不确定是否应该通过调整像素缓冲区的大小(可能会获得性能提升)来使纹理成为 2 的幂,还是保持原样。

无论如何希望这对某人有所帮助,因为我花了太多时间来解决这个问题。

【讨论】:

  • 使用非二次幂纹理你会非常好。如果将相机馈送缩放为二次方,您将在性能和质量方面损失更多,即使是较旧的设备也可以在不到一毫秒的时间内渲染 NPOT 相机帧。
  • 感谢您发布此信息,这是一个很好的性能提升。 @BradLarson 你知道如何从内存中的现有数据创建一个 CVPixelBufferRef 吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-27
  • 1970-01-01
相关资源
最近更新 更多