Android多媒体SDK中的组件化设计思想

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 17:55   2325   0

本文主要介绍金山云Android推流、短视频SDK设计中,为保证SDK的灵活性、可扩展性,在SDK组件化方向上所做的一些探索。

成熟的PC端多媒体架构简介

PC诞生之初,就有了强烈的多媒体处理需求,在几十年发展中,比较知名的几个多媒体框架有:

  • 微软的DirectShow
  • 开源跨平台的GStreamer
  • FFMPEG
  • VLC

其中,FFMPEG更偏重于提供muxer/demuxer, encoder/decoder等实用稳定的多媒体组件,VLC更偏重于提供ALL IN ONE的软件产品,其框架更多的是为特定的应用场景服务,灵活性及扩展性均不及DirectShow和GStreamer.

DirectShow和GStreamer的组件化设计

DirectShow与GStreamer均为组件化设计的多媒体框架,具体工作均交由各个组件来实现。

DirectShow的Filter Graph

微软提供了可视化的组件编辑工具GraphEdit,借助该工具,我们可以通过直观的方式将各个DirectShow的组件连接起来,并对实际效果进行预览。
比如下图的连接方式就实现了一个基本的视频文件播放器:

4469440-1ff8dc15fb177c18.png
DirectShow框架下的视频播放Pipeline

根据上图,我们可以看到,一个典型的视频播放器包含一个视频源分离模块(Demuxer), 一个视频解码模块,一个音频解码模块,一个视频渲染模块,一个音频渲染模块。在DirectShow中,这些模块被称为Filter,连接起来的各个Filter组成了一个Filter Graph。

各个Filter包含不同类型与数目的引脚,通过引脚间的连接,实现数据流在不同模块间的传递。
这些引脚在DirectShow中称为Pin, 其中产生数据的Pin被称为Source Pin,接受数据的Pin称为Sink Pin。
例如分离模块中包含音视频两个Source Pin, 解码模块包含一个Sink Pin和一个Source Pin, 渲染模块只有一个Sink Pin。

当然我们也可以通过选择组合不同的Filter组成新的Filter Graph来达成不同的功能,或者增添、更改当前Filter Graph中的Filter来动态调整Filter Graph的功能特性。

GStreamer的Pipeline

GStreamer中存在类似的组件化结构,例如下图的Pipeline实现了一个简单的ogg音频文件播放器:

4469440-3cd5ee966a489545.png
GStreamer框架下的ogg播放器

如图中所示的source, demuxer, decoder, output模块,在GStreamer中被称为Element, Element上的引脚被称为Pad, 输入输出引脚分别被称为Source Pad和Sink Pad,而连接起来的各个Element则组成了一个Pipeline。

GStreamer同样支持使用不同的Element及连接方式来组成不同的Pipeline,以及对其中的Element进行增添、改动来调整Pipeline的功能特性。

背后的工作

前面我们看到了DirectShow和GStreamer直观、灵活的组合方式,以及强大的扩展性,但要实现这些特性是需要框架完成大量的配套工作的。

  • 模块间连接时的协商过程。
    在多媒体处理中,存在着多种数据类型,例如未解码的视频数据(其中又存在多种编码格式HEVC/AVC/VP9等),解码后的视频数据(又包含RGB/I420/YV12/NV12等),不同模块能够处理的数据类型是不同的,因此两种框架均实现了完善的协商过程。
    例如,对于不支持的连接方式,抛出错误,或者智能添加一个转换模块来完成连接。

  • 模块的动态添加及移除处理。
    例如在播放或者编辑视频的过程中,需要添加、改变或者移除一种特效Filter,就需要对已连接的模块进行动态重建。
    两种框架均实现了该功能,不过为此也做了大量的工作,例如模块在变动过程中的状态处理、数据流处理等。

  • 模块间的数据传送。
    一般存在两种方式,一种为push模式,另一种为pull模式。
    两种框架均对push及pull模式做了支持。例如上面GStremer框架下的ogg播放器,ogg-demuxer的sink pad就以pull模式从file-source拉取数据,后继模块则均以push模式运行,由上一级模块的src pad将数据推送到后一级的sink pad。

  • 状态控制和事件响应。
    GStreamer中,要控制Pipeline的c3jY{NyNX[8kXiuXY yNi[h

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP