关于苹果家原生音视频框架的调研

发布于: 2018-05-19 16:13
阅读: 1337
评论: 3
喜欢: 9

作者:Enum

原文链接:http://posts.enumsblog.com/posts/18003

TAG: iOS macOS


引言

关于 iOS / macOS 的音视频编解码,苹果提供了各种眼花缭乱的框架和组件,这些眼花缭乱的框架的职能到底是怎样的呢?

今天就结合自己的开发经验,对我所知道的相关框架做了一个简单的调研。

原生的组件

苹果为开发者提供了一系列原生的组件:

  • AVFoundation
  • AudioToolbox
  • CoreAudio / CoreAudioKit
  • VideoToolbox
  • CoreVideo
  • CoreMedia
  • OpenGL / GLKit & Metal
  • OpenCL
  • OpenAL

AVFoundation

Work with audiovisual assets, control device cameras, process audio, and configure system audio interactions.

AVFoundation 是开发者们用的最多的音视频播放的原生框架。

AVFoundation 是苹果原生的一套完整的音视频解决方案。从音视频编码,缓冲,解码,渲染播放等,功能十分强大。

相信大家对 AVFoundation 都已经非常熟悉了,这里就不再展开了。

AudioToolbox

Record or play audio, convert formats, parse audio streams, and configure your audio session.

AudioToolbox 提供音频录制、回放、格式转换等音频相关功能。

AudioToolbox 使用时开发者需要维护一个音频队列,并设置回调函数。当队列启动播放时框架会自动回调并开始播放队列。提供的为C语言接口,使用起来有些晦涩,具体可以参考官方文档。

CoreAudio / CoreAudioKit

Use specialized data types to interact with audio streams, complex buffers, and audiovisual timestamps.

CoreAudio 定义了一系列数据结构和方法,连接如 IOKit 等其他框架。它不参与声音的播放、解析等操作,它只是个连接其他框架的“胶水”。

VideoToolbox

Work directly with hardware-accelerated video encoding and decoding capabilities.

VideoToolbox 是 iOS 提供的硬件加速视频编解码接口。一套底层的硬件编码、解码接口。

通俗一点讲,可以将 VideoToolbox 理解为一个黑盒。解码时,将视频流中已经编码的帧数据给它,它会返回给你解码完成的图像的数据。编码时反过来。

使用 VideoToolbox 时,会要求开发者更直接地操作底层的视频帧数据,更多的解码细节会被暴露在开发者面前。例如在解码 H264 视频流时,SPS,SSP 等平时对开发者透明的参数集也需要开发者手动操作。如果你对这些不熟悉,在使用 VideoToolbox 以前必须要学习这些东西,否则代码是不会工作的。

Apps that don't need direct access to hardware encoders and decoders should not need to use VideoToolbox directly.

如果 App 中不直接访问硬件编码、解码器,就不该直接使用 VideoToolbox。

安卓中相同职能的接口为 MediaCodec。

CoreVideo

Process digital video—including manipulation of individual frames—using a pipeline-based API and support for both Metal and OpenGL.

提供一个支持 OpenGL 和 Metal 的操作视频帧的管道。

Apps that don't need to manipulate individual video frames should never need to use Core Video directly.

如果 App 中不直接操作视频帧,就不该直接使用 CoreVideo。

解码、渲染等都和 CoreVideo 无关,它只提供一个数据保持、交换的功能,仅仅作为一个管道。和 Core Audio 类似的,它也只是一个连接其他框架的“胶水”。最为大家熟知的就是解码完的像素数据容器CVPixelBuffer了,它就是来自 CoreVideo 框架。

CoreMedia

Represent time-based audio-visual assets with essential data types.

The Core Media framework defines the media pipeline used by AVFoundation and other high-level media frameworks found on Apple platforms.

CoreMedia 也是一个“胶水”框架,提供了一些可以流通在框架之间的数据结构。例如CMTime等,开发者们在视频开发中大多会用到。

OpenGL / GLKit & Metal

OpenGL 和 Metal 作为 GPU 图形接口,仅与渲染和图像处理有关。

在以上两者中能做的事:

  • 接收 CoreVideo 输出的帧数据直接显示视频内容。
  • 通过矩阵变换进行映射、形变、剪裁等简单后处理。
  • 通过着色器进行画面滤镜,色彩变换、滤镜等高级后处理。
  • 通过其他手段进行视频拼接融合、三维贴图等其他渲染后处理。

以上都是基于 GPU 的视频后处理,性能佳。常规的形变贴图、色彩变化后处理与直接渲染在性能压力上基本一致。而模糊等算法随视频规模、卷积核大小会对性能造成压力,但相比 CPU 模糊已经非常快了。

另外通过离屏渲染、Metal 计算命令等可以在不渲染到屏幕的情况下离屏进行图像后处理。

OpenCL

OpenCL 同样面向 GPU,区别于 OpenGL,它是专门为了 GPU 进行图像渲染、图像处理任务以外的任务的。

虽然 iOS 内置了 OpenCL,不过 API 是私有的。

它的关键词是:数据切割,高并发计算。

嗯,音视频没有什么关系。

OpenAL

OpenAL 主要用于处理多通道三维音效,API 风格与 OpenGL 相近。

Blender、Unity 等建模、游戏引擎都使用了 OpenAL 来处理三维音效。

第三方组件

还有一些常用的第三方组件:

  • ffmpeg
  • OpenCV

ffmpeg

ffmpeg 是一套跨平台音频编解码的解决方案。

由于它对音视频的编解码操作都是基于 CPU 运算的,因此有着很强的兼容性。但软件编解码在移动端有着很明显的缺陷:性能不佳、耗电、发热。

因此在移动端会主要以硬件编解码为主,ffmpeg 起到一个兜底的作用,对一些硬件无法支持的特殊尺寸、特殊格式的视频进行编解码。

OpenCV

OpenCV 作为计算机视觉相关模块,与图像处理以及识别有关。

OpenCV 能做的事:

  • 上下采样、池化、平滑(模糊)、边缘检测等简单后处理。
  • 直方图、角点等图像特征分析。
  • 各类匹配算法。
  • 参与图像渲染,圈圈点点。

需要注意的是 OpenCV 虽然功能很强大,但它的的 GPU 支持非常差,移动端貌似还不能支持 GPU,使用的都是 CPU,会对性能造成不小的压力。

另外 OpenCV 有 C、C++ 两种接口,官方比较推荐的是 C++ 接口,这在 Objective-C 和 Swift 里使用是很困难的,因此在 iOS 上使用也很水土不服。

集成解决方案

这类解决方案是以ijkplayer为代表的成套解决方案。

这类解决方案通常是跨平台的。集成了各个平台的硬件编解码接口,在不同的平台上编译不同的代码,并使用 ffmpeg 兜底,使得播放器整体功能完整,且兼顾了性能和兼容性。

结语

最后给以上调研的框架做个分类吧:

  • 集成解决方案:AVFoundationijkplayer
  • 胶水框架:CoreVideoCoreAudioCoreMedia
  • 渲染和后处理:OpenGL & MetalOpenALOpenCV
  • 真正干活的:VideoToolboxAudioToolbox
  • 兜底万能的:ffmpeg
  • 和音视频没什么关系的:OpenCL

读者可以根据需求来决定在哪一层插手。


Thanks for reading.

All the best wishes for you! 💕



1 楼

ttt

来瞧瞧

发表于 2018-05-30 17:35:26 引用
2 楼

星期8

你好 我没做过视频这块,都说ijkplayer是基于ffmpeg的。但是ffmpeg是软解码,上边也说了缺点很明显,那么ijkplayer是如何支持硬解码的呢 ?

发表于 2018-06-01 10:45:00 引用
3 楼

Enum

引用了以下评论:
2 楼

星期8

你好 我没做过视频这块,都说ijkplayer是基于ffmpeg的。但是ffmpeg是软解码,上边也说了缺点很明显,那么ijkplayer是如何支持硬解码的呢 ?

发表于 2018-06-01 10:45:00

ijkplayer里针对iOS和安卓分别写了硬解码的功能。iOS用了VideoToolbox,安卓用了MediaCodec。

发表于 2018-06-04 23:49:38 引用