2010-11-21 44 views

回答

19

从iOS 4.0开始,您可以使用AVCaptureDeviceInput将摄像头作为设备输入,并将其连接到AVCaptureVideoDataOutput,并将其设置为代表。通过为摄像机设置一个32bpp的BGRA格式,代表对象将以完美的格式接收来自摄像机的每帧,并立即传送到glTexImage2D(或glTexSubImage2D,如果设备不支持非幂次幂纹理; I认为MBX设备属于这一类)。

有一堆帧大小和帧速率选项;猜测你必须调整这些取决于你想要使用GPU的其他因素。我发现一个完全无关紧要的场景,只有带有纹理的四边形才能显示最新的帧,仅在新帧到达iPhone 4时重新绘制,才能够显示该设备的最大720p 24fps的素材,而没有任何明显的延迟。我没有做过比这更彻底的基准测试,所以希望别人能提供建议。

原则上,根据API,帧可以返回一些在扫描线之间的内存填充,这意味着在发布到GL之前需要对内容进行一些混洗,因此您需要为此实现代码路径。在实践中,纯粹从经验角度来讲,似乎iOS的当前版本从来没有以这种形式返回图像,所以它不是真正的性能问题。

编辑:它现在非常接近三年后。在此期间,苹果公司发布了iOS 5,6和7.其中5款产品分别推出了CVOpenGLESTextureCVOpenGLESTextureCache,这些都是将视频从捕获设备传输到OpenGL的智能方式。 Apple提供样本代码here,其中特别感兴趣的部分在RippleViewController.m,特别是其setupAVCapturecaptureOutput:didOutputSampleBuffer:fromConnection: - 见行196-329。可悲的条款和条件阻止代码的重复,这里不附加整个项目,但一步一步的设置是:

  1. 创建CVOpenGLESTextureCacheCreateAVCaptureSession;
  2. 为视频抓取合适的AVCaptureDevice;
  3. 用该捕获设备创建一个AVCaptureDeviceInput;
  4. 附加一个AVCaptureVideoDataOutput并告诉它将您称为样本缓冲区委托。

在接收每个样品缓冲液:

  1. 从它那里得到的CVImageBufferRef;
  2. 使用CVOpenGLESTextureCacheCreateTextureFromImage从CV图像缓冲区获得Y和UV CVOpenGLESTextureRef;
  3. 从CV OpenGLES纹理引用中获取纹理目标和名称以绑定它们;
  4. 在着色器中结合了亮度和色度。
+0

感谢您的回答。我会去挖。 – Eonil 2010-11-22 07:35:43

+1

把整件事情联系起来只有200条线;抱歉没有发布代码 - 我只在工作时解决了问题,因此我被禁止发布我的内容。但它确实很平凡,我花了很多时间去弄清楚文档中哪些是合适的类,而不是编码。 – Tommy 2010-11-22 10:30:29

+0

@Eonil如果您喜欢他的回答,请将其标记为已接受的答案。 – pr1001 2011-02-26 13:11:10

0

使用RosyWriter为更好的示例如何做OpenGL视频渲染。性能非常好,特别是如果您降低帧速率(在1080P/30时大约10%,在1080P/15时大于5%)。