严格来说,具体到移动端音视频这个细分领域,除非你不依赖任何平台硬件加速能力(比如硬件编解码),否则我们可以大胆的说:根本不存在彻底的跨平台。
我们可以从更狭义的角度来说,移动端音视频领域的跨平台,其实是编译工具链和数据流程上的跨平台,基于这两个底座,接入依赖平台特性的功能模块,最终封装为多平台统一的native接口。
这里所谓的数据流程,或者叫pipeline,我们可以说它还包含了线程管理、内存管理、数据统计、日志管理等附属模块。
此外,如果要封装应用层面的API,则又要基于统一的native接口,依据各平台的语言特性,分别编写了。
用一张图来描述前面的思想,如下
下面我们用两个大家都熟知的开源项目ijkplayer和webrtc,看看他们的结构,来印证我们的想法。
ijkplayer
在ijkplayer中,对应数据流程的模块就是核心的ff_ffplay.c,我们知道它其实就脱胎于ffmpeg的ffplay.c,所以我们也可以说它直接用了ffmpeg的编译工具链、内存管理、日志管理等附属模块。
ff_ffplay.c中定义的两个核心队列,FrameQueue和PacketQueue驱动了音视频数据从读取、解封装、解码到渲染的流程。
截止目前的实现我们都可以说它是彻底跨平台的。但是具体到硬件解码,则完全呈现为平台相关。渲染方面,如果都选择用OpenGL进行渲染,那么也可以说是跨平台的,但对于Android平台,我们还需要做nativewindow(surface)渲染的支持,只能说是部分跨平台的。
但是注意,无论是Android MediaCodec解码还是ios VideoToolbox解码,都要配合ff_ffplay.c中的两个队列,也就是跨平台的底座,才能完成播放工作。
到了上层的接口方面,则对应ijkplayer.c,这里编写了一套双端统一的native接口,将一个播放器应有的常见接口都封装暴露出来。
再往上走,则分别对应Android平台的API:ijkMediaPlayer.java和ios平台的API:IJKFFMoviePlayerController.m。
WebRTC
在webrtc中,就更简单了,代码目录就代表着项目架构。
peer_connection串联起modules目录下的音视频组件、网络组件,rtc_base、logging、stats目录下对应着线程管理、内存管理、日志管理、数据统计等组件。
至于编译工具链则以Ninja+GN的形式存在。
api目录下是双端统一的native api,sdk目录下则为各端对应的上层接口。
除此之外,在其他的开源项目中,例如VLC,也能看到类似的架构。
理解了跨平台架构的主线,也就不会再觉得所谓跨平台是什么高深的东西了。
作者:灰度五十
版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。