多媒体框架

 1 android多媒体框架概述

在7.0时,为了安全考虑,将整个多媒体服务进程拆分成多个进程,每个功能都拥有独立的进程。

                                                                      图1 服务进程

        

2 mediaplayer和nuplayer调用关系

                                                                图2 mediaplayer播放流程

         在 Android Q 之前,多媒体框架的两个主要模块是 MediaPlayer 和 MediaCodec。MediaCodec 只负责解码和渲染。MediaCodec通过ACodec层通过OpenMAX-IL调用第三方编解码器,实现硬件编解码。芯片厂商只需要支持Khronos开发的OpenMAX接口即可实现MediaCodec硬件编解码。如图2,ACodec和OpenMax组合使用。

          谷歌在 Android Q 上推出 Codec2.0,取代 ACodec 和 OpenMAX。这可以看作是一组与 MediaCodec 一起工作的新中间件。

3 audio播放流程

        应用层通过mediaplayer接口去启动Android系统的播放器NuPlayer,Nuplayer通过mediaextractor(高通的有自己的解封装模块mmparser)去解封装mp3或flac等文件,把解封装好的数据通过ACodec传给OMX去解码(排除offload模式的adsp侧解码),然后NuPlayer拿到解码后的pcm数据通过AudioSink与AudioTrack交互去把pcm数据传给device设备,最后NuPlayer通过自身的子类NuPlayerRenderer去渲染播放。
        播放声音可以使用MediaPlayer和AudioTrack,MediaPlayer可以通过OMX去解码,所以可以播放flac等音频文件。但是AudioTrack只能播放解码后的pcm数据,通过上面的介绍我们也知道MediaPlayer解码后的数据也是需要去创建对应的track去把pcm数据传送给AudioTrack去输出的。

AudioTrack Native API 输出模式标识:

AUDIO_OUTPUT_FLAG_DIRECT直接输出到音频设备,不需要软件混音,一般用于HDMI
AUDIO_OUTPUT_FLAG_PRIMARY音频流需要输出到主音频设备,一般用于铃声
AUDIO_OUTPUT_FLAG_FAST音频流需要快速输出到音频设备,一般用于按键音游戏背景音等对延时要求较高的场景
AUDIO_OUTPUT_FLAG_DEEP_BUFFER    对延时要求不高的场景,音频视频播放等
AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD没有经过软件解码,直接到adsp解码

4 openCore,StageFright, NuPlayer的关系

         如果接触Android比较早的人,可能有听过openCore,StageFright。这2个旧的底层播放框架与nuplayer是并列的,都属于android底层播放器的实现框架。
         Android上的MediaPlayer播放底层框架已经经历了多次变动,从最早先的OpenCore到后来的StageFright再到现在的NuPlayer,这些框架在演进过程中一般都是先两种框架并存,然后再在某个版本中将其移除,早先Android中使用的是Stagefright + NuPlayer并存的方式,其中前者负责播放本地的媒体文件,后者用于播放网络流媒体文件,但是在后来的Android L开始NuPlayer渐渐开始替代了Stagefright,目前本地播放已经切换到NuPlayer上了,在Android N AOPS 源代码中已经移除了Stagefright。

5 MediaCodec ,OpenMAX,ACodec的关系

         OpenMAX确立了一套标准的接口,用于编解码,上层App直接调用这些接口,底层硬件厂商直接实现这些接口,从而实现了上层软件开发与底层芯片开发地彻底分离,加速了跨平台的多媒体组件的开发、整合和编程。

MediaCodec 是提供给上层应用的 Java 接口,实际底层调用的是( OpenCore,StageFright,nuplayer) 多媒体框架


StageFright 底层编解码能力是由 OpenMAX 框架提供,StageFright 遵循 OpenMAX 标准

NuPlayer是通过ACodec进行编解码

 

6 gstreamer

gstreamer通常与ffmpeg相比较,由于ffmpeg使用非常广泛,本文不再详细介绍。之前没有使用过gstreamer,所以此处列出。

安装gstreamer

使用国内ali源下载

apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-doc gstreamer1.0-tools gstreamer1.0-x gstreamer1.0-alsa gstreamer1.0-gl gstreamer1.0-gtk3 gstreamer1.0-qt5 gstreamer1.0-pulseaudio

播放视频

gstreamer 视频播放的时候一般选择filesrc + decodebin + sink 这三个plugin,其中videoconvert 主要是用于colorspace的转换,因为解码后的数据可能是多种格式的,需要统一转换成video sink支持的colorspace。

播放命令1:

gst-launch-1.0 filesrc location=1.mp4 !  decodebin !  videoconvert ! ximagesink

播放命令2:

gst-launch-1.0 filesrc location=sintel_trailer-480p.ogv ! oggdemux name=demux ! queue ! vorbisdec ! autoaudiosink demux. ! queue ! theoradec ! videoconvert ! autovideosink

        通过上面的命令2播放文件时,会创建如下pipeline:

可以看到这个pipeline由8个element构成,每个element都实现各自的功能:

        filesrc读取文件,oggdemux解析文件,分别提取audio,video数据,queue缓存数据,vorbisdec解码audio,autoaudiosink自动选择音频设备并输出,theoradec解码video,videoconvert转换video数据格式,autovideosink自动选择显示设备并输出。

        不同的element拥有不同数量及类型的pad,只有src pad的element被称为source element,只有sink pad的被称为sink element。

        element可以同时拥有多个相同的pad,例如oggdemux在解析文件后,会将audio,video通过不同的pad输出。

Gstreamer数据消息交互:

        在pipeline运行的过程中,各个element以及应用之间不可避免的需要进行数据消息的传输,gstreamer提供了bus系统以及多种数据类型(Buffers、Events、Messages,Queries)来达到此目的:

        Bus是gstreamer内部用于将消息从内部不同的streaming线程,传递到bus线程,再由bus所在线程将消息发送到应用程序。应用程序只需要向bus注册消息处理函数,即可接收到pipline中各element所发出的消息,使用bus后,应用程序就不用关心消息是从哪一个线程发出的,避免了处理多个线程同时发出消息的复杂性。

Buffers:用于从sources到sinks的媒体数据传输。

Events:用于element之间或者应用到element之间的信息传递,比如播放时的seek操作是通过event实现的。

Messages:是由element发出的消息,通过bus,以异步的方式被应用程序处理。通常用于传递errors, tags, state changes, buffering state, redirects等消息。消息处理是线程安全的。由于大部分消息是通过异步方式处理,所以会在应用程序里存在一点延迟,如果要及时的相应消息,需要在streaming线程捕获处理。

Queries:用于应用程序向gstreamer查询总时间,当前时间,文件大小等信息。

架构

Gstreamer是一个支持Windows,Linux,Android, iOS的跨平台的多媒体框架,应用程序可以通过管道(Pipeline)的方式,将多媒体处理的各个步骤串联起来,达到预期的效果。每个步骤通过元素(Element)基于GObject对象系统通过插件(plugins)的方式实现,方便了各项功能的扩展。
 

 Protocols:负责各种协议的处理,file,http,rtsp等。
Sources:负责数据源的处理,alsa,v4l2,tcp/udp等。
Formats:负责媒体容器的处理,avi,mp4,ogg等。
Codecs:负责媒体的编解码,mp3,vorbis等。
Filters:负责媒体流的处理,converters,mixers,effects等。
Sinks:负责媒体流输出到指定设备或目的地,alsa,xvideo,tcp/udp等。
 


 

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

步基

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值