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

发布于:2018-05-19 16:13,阅读数:2687,点赞数:9


# 引言

关于 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 兜底,使得播放器整体功能完整,且兼顾了性能和兼容性。

# 结语

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

- 集成解决方案:`AVFoundation`、`ijkplayer`。
- 胶水框架:`CoreVideo`、`CoreAudio`、`CoreMedia`。
- 渲染和后处理:`OpenGL` & `Metal`、`OpenAL`、`OpenCV`。
- 真正干活的:`VideoToolbox`、`AudioToolbox`。
- 兜底万能的:`ffmpeg`。
- 和音视频没什么关系的:`OpenCL`。

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



评论:3条


1楼:2018-05-30 17:35:26

ttt:

来瞧瞧


2楼:2018-06-01 10:45:00

星期8:

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


3楼:2018-06-04 23:49:38

yuu:

引用:2楼

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


返回列表

返回归档

返回主页