实际问题
几个答案将解决我的问题:
- 我可以像这样强制 a
CGImage
从直接数据提供者(使用 创建CGDataProviderCreateDirect
)重新加载其数据CGContextDrawImage
吗?还是有其他方法可以设置 self.layer.contents 来做到这一点? - 是否有
CGContext
配置或技巧可以用来渲染 1024x768 图像,至少 30 fps 与CGContextDrawImage
. - 有没有人能够成功地使用
CVOpenGLESTextureCacheCreateTextureFromImage
他们自己的纹理数据进行实时缓冲区更新?我认为我最大的问题是创建一个CVImageBuffer
,因为我从 Apples 的纹理文档中复制了其他属性。如果有人对此有更多信息,那就太棒了。 - 关于如何以 30 fps 从内存中获取图像到屏幕上的任何其他指南。
背景(批次):
我正在做一个项目,我需要实时修改 NPOT 图像数据的像素(最低 30 fps)并将其绘制在 iOS 的屏幕上。
我的第一个想法是使用 OpenGLglTexSubimage2D
进行更新,不幸的是最终速度非常慢(iPad 上为 6 fps),因为驱动程序将我的 RGB 数据每帧转换为 BGR。所以用你说的 BGR 发送它,我也是,但由于某种原因你不能glTexSubImage2D
用GL_BGR
go figure 调用。我知道有些慢是因为它不是 2 图像数据的幂,但我的要求决定了这一点。
更多阅读使我想到,CVOpenGLESTextureCacheCreateTextureFromImage
但所有示例都是使用直接相机输入来获取CVImageBufferRef
我尝试使用文档(没有官方但只是标题注释)来使我自己的 CVImageBuffer 形成我的图像数据,但它不适用于此(否错误只是调试器中的一个空纹理),这让我认为Apple专门为处理实时相机数据而构建了它,并且除了IDK之外,它还没有在这个领域之外进行过太多测试。
无论如何,在通过转储 OpenGL 并将我的想法切换到 CoreGraphics 来放弃我的尊严之后,我被引导到这个问题,这是在 iPhone 上绘制屏幕缓冲区的最快方法,
它建议使用CGImage
backed by CGDataProviderCreateDirect
,它允许您在CGImage 需要它,很棒吧?好吧,它似乎并不像宣传的那样有效。如果我使用CGContextDrawImage
,那么一切正常。我可以修改像素缓冲区,每次绘制时,它都会像它应该的那样从我的数据提供者那里请求图像数据,调用CGDataProviderDirectCallbacks
(Note:
他们似乎有一个内置的优化,如果更新的指针与之前的地址相同,则忽略更新的指针)。即使禁用插值,CGContextDrawImage 也不是超快(大约 18 fps),这从 6 fps 提高了。Apple 的文档告诉我使用self.layer.contents
会比CGContextDrawImage
. usingself.layer.contents
适用于第一次分配,但即使我CGImage
调用. 在我引用的 SO 问题中,用户通过每帧从数据源创建和销毁一个新的 CGImage 来展示他对问题的解决方案,这是一个非常缓慢的过程(是的,我确实尝试过),所以是时候提出真正的问题了。CGContextDrawImage
[layer setNeedsDisplay]
注意:我已经分析了所有这些操作,并且知道问题确实glTexSubImage
出在 OpenGL 上,并且CGContextDrawImage
确实是 CoreGraphics 的问题,所以没有“go profile”的答案。
编辑演示此技术的源代码现在可以在http://github.com/narpas/image-sequence-streaming找到