在AVPlayerLayer中实时处理视频帧

时间:2012-08-23 00:02:25

标签: iphone ios opengl-es-2.0 avfoundation video-processing

我需要实时处理来自远程视频的视频帧,并在屏幕上显示已处理的帧。

我尝试过使用AVAssetReader,但由于AVURLAsset正在访问远程网址,因此调用AVAssetReader:initWithAsset会导致崩溃。

AVCaptureSession看起来不错,但它适用于相机,而不是视频文件(更不用说远程视频文件)。

因此,我现在正在探索这个:在AVPlayerLayer中显示远程视频,然后使用GL ES访问显示的内容。

问题:

  1. 如何将AVPlayerLayer(或一般的CALayer)转换为CAEAGLLayer并使用CVOpenGLESTextureCacheCreateTextureFromImage()读取像素?

  2. 或者还有其他更好的方法吗?

  3. 注意:性能是一个重要的考虑因素,否则简单的屏幕捕获技术就足够了。

2 个答案:

答案 0 :(得分:2)

现在可以在现代iOS上使用。如果您可以用Core Image表示实时处理,并且现在应该可以得到Core Image对自定义过滤器的广泛支持,则可以使用AVAsynchronousCIImageFilteringRequest传递到{{1} }。

如果您希望完全手动处理,可以签出AVPlayerItemVideoOutputCVMetalTextureCache。使用这些,您可以直接从视频中读取样本缓冲区,然后从纹理缓冲池将其转换为Metal纹理。从那里,您可以对纹理进行任何处理。请注意,使用这种方法,您需要负责显示最终的纹理(在您自己的Metal或SceneKit渲染管道中)。

Here's a blog post演示了此技术。

或者,如果您不想管理自己的渲染管道,则仍可以使用AVPlayerItem来获取示例缓冲区,使用vImage和Core Image之类的东西来处理它们(理想情况下,使用基本的金属支持{{ 1}}以获得最佳性能!),然后将其发送到AVSampleBufferDisplayLayer以直接在图层树中显示。这样,您可以根据自己的喜好处理帧,并且仍然让AVFoundation管理图层的显示。

答案 1 :(得分:0)

据我所知,Apple不提供对h.264解码器的直接访问,而且无法解决这个问题。您可以使用的一个API是资产界面,您可以在其中为其指定URL,然后将该磁盘上的文件读取为CoreVideo像素缓冲区。您可以尝试从URL下载,然后一次在一个视频帧中写入一个新资产(tmp目录中的文件)。然后,一旦完成下载并完全写入新的h264文件,请关闭写入会话,然后将该文件作为资产阅读器打开。您将无法使用此方法进行流式传输,因此需要先下载整个文件。否则,您可以尝试使用AVPlayerLayer方法来查看是否支持直接流式传输。请注意,纹理缓存逻辑不容易实现,您需要并且OpenGL视图已经正确配置,您最好只查看已经执行渲染的现有实现,而不是尝试从头开始。