【问题标题】:Real-time processing of video frames in AVPlayerLayerAVPlayerLayer中视频帧的实时处理
【发布时间】:2012-08-23 00:02:24
【问题描述】:

我需要实时处理来自远程视频的视频帧,并将处理后的帧呈现在屏幕上。

我曾尝试使用 AVAssetReader,但由于 AVURLAsset 正在访问远程 URL,调用 AVAssetReader:initWithAsset 会导致崩溃。

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

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

问题:

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

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

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

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      这现在可以在现代 iOS 上实现。如果你能够使用 Core Image 来表示你的实时处理——并且你现在应该能够给予 Core Image 对自定义过滤器的广泛支持——你可以根据文档使用AVAsynchronousCIImageFilteringRequest 传递给AVPlayerItem .

      如果您希望完全手动处理,可以查看AVPlayerItemVideoOutputCVMetalTextureCache。使用这些,您可以直接从视频中读取样本缓冲区,并将它们从纹理缓冲池中转换为金属纹理。从那里,你可以对纹理做任何你想做的事情。请注意,使用这种方法,您负责显示生成的纹理(在您自己的 Metal 或 SceneKit 渲染管道中)。

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

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

      【讨论】:

        猜你喜欢
        • 2011-03-29
        • 2012-12-31
        • 1970-01-01
        • 2016-11-07
        • 1970-01-01
        • 1970-01-01
        • 2019-01-11
        • 1970-01-01
        相关资源
        最近更新 更多