关于苹果家原生音视频框架的调研
发布于:2018-05-19 16:13,阅读数:2944,点赞数: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。