Android多媒体开发介绍(转)

Android多媒体开发介绍

 

转自:http://blog.csdn.net/reiliu/article/details/9060557

一、       多媒体架构

基于第三方PacketVideo公司的OpenCORE来实现,支持所有通用的音频/视频/静态图像格式,包括:MPEG4、H.264、MP3、AAC、AMR、JPG、PNG、GIF等。从功能上分为两部分,一是音/视频的回放(PlayBack),二是音视频的纪录(Recorder)。

CODEC(编解码器)使用OpenMAX 1L interface接口进行扩展,可以方便地支持hardware / software codecplug-ins。

Open Core多媒体框架有一套通用可扩展的接口针对第三方的多媒体遍解码器,输入/出设备等等 。

多媒体文件的播放、下载,包括3GPP, MPEG-4,AAC and MP3containers

流媒体文件的下载、实时播放,包括:3GPP, HTTP and RTSP/RTP

动态视频和静态图像的编解码,如:MPEG-4, H.263 and AVC(H.264), JPEG

语音编码格式:AMR-NB and AMR-WB

音乐编码格式:MP3, AAC, AAC+

视频和图像格式:3GP、MPEG-4 and JPEG

视频会议:基于H324-M standard

 

二、       Media Framework名词解释

1.    OpenCore介绍

OpenCore是Android多媒体框架的核心,所有Android平台的音视频采集,播放的操作都是通过它来实现。通过Open Core程序员可以方便快速的开发出想要的多媒体应用程序,例如:音视频的采集,回放,视频会议,实时的流媒体播放等等应用。

2.    OpenCore代码结构

OpenCore的代码在Android代码的External/Opencore目录中。这个目录是OpenCore的根目录,其中包含的子目录如下所示:

Ø  android:这里面是一个上层的库,它实现了一个为Android使用的音视频采集,播放的接口,和DRM数字版权管理的接口实现。

Ø  baselibs:包含数据结构和线程安全等内容的底层库

Ø  codecs_v2:音视频的编解码器,基于OpenMAX实现

Ø  engines:核心部分,多媒体引擎的实现

Ø  extern_libs_v2:包含了khronos的OpenMAX的头文件

Ø  fileformats:文件格式的解析(parser)工具

Ø  nodes:提供一些PVMF的NODE,主要是编解码和文件解析方面的。

Ø  oscl:操作系统兼容库

Ø  pvmi:输入输出控制的抽象接口

Ø  protocols:主要是与网络相关的RTSP、RTP、HTTP等协议的相关内容

Ø  pvcommon:pvcommon库文件的Android.mk文件,没有源文件。

Ø  pvplayer:pvplayer库文件的Android.mk文件,没有源文件。

Ø  pvauthor:pvauthor库文件的Android.mk文件,没有源文件。

Ø  tools_v2:编译工具以及一些可注册的模块。

3.    OpenMax介绍

Ø  OpenMAX是Khronos制定的API,Khronos也是OpenGL的制定者。

Ø  OpenMAX是无授权费、跨平台的应用程序接口API,通过媒体加速组件能够在开发、集成和编程环节中实现跨多操作系统和处理器硬件平台,提供全面的流媒体编解码器和应用程序便携化。

Ø  在架构底层上为多媒体codec和数据处理定义了一套统一的编程接口(OpenMAX IL API),对多媒体数据的处理功能进行系统级抽象,为用户屏蔽了底层细节。因此多媒体应用程序和多媒体框架通过 OpenMAX IL可以以一种统一方式来使用codec和其他多媒体数据处理功能,具有了跨越软硬件平台的移植性。

Ø  OpenMax在系统中的位置

 

 

 

 

Ø  OpenMax层次

  OpenMAX AL(Appliction Layer)

OpenMAX AL API 在应用程序和多媒体中间件之间提供了一个标准化接口,多媒体中间件提供服务以实现被期待的 API 功能。 AL向多媒体接口提供应用册便携性。

  OpenMAXIL(Integration Layer)

OpenMAX IL 作为音频,视频和图像编解码器,能与多媒体编解码器交互,并以统一的行为支持组件(例如资源和皮肤)。编解码器供应商必须写私有的或者封闭的接口集成进移动设备。IL的目的是使用特征集合为编解码器提供一个系统抽象,为解决多个不同媒体系统之间轻便性的问题。

  OpenMAXDL(Development Layer)

OpenMAX DL 定义了一个API,它是音/视频和图像功能的集合。硅供应商能够在一个新的处理器上实现并优化其,然后编解码供应商使用其来编写更广泛的编解码器功能。它包括音频信号的处理功能,如FFT和filter;图像原始处理,如颜色空间转换和视频原始处理,以实现例如MPEG-4、H.264、MP3、AAC和JPEG等编解码器的优化。 OpenMAX通过iDL 和aDL来支持加速, iDL使用OpenMAX IL结构,aDL向OpenMAX DL API增加了异步接口。

 

三、       Media Framework架构

1. Camcorder Framework

 

 

2. Audio Software Overview

 

 

3. SurfaceFlinger

Ø  Android中的图形系统采用Client/Server架构。Server (即SurfaceFlinger)主要由c++代码编写而成。Client端代码分为两部分,一部分是由Java提供的供应用使用的api,另一部分则是由c++写成的底层实现。

Ø  Java View及其子类(如TextView, Button)要画在surface上。每个surface创建一个Canvas对象 (但属性时常改变),用来管理view在surface上的绘图操作,如画点画线。每个canvas对象对应一个bitmap,存储画在surface上的内容。

Ø  每个Surface通常对应两个buffer,一个front buffer, 一个back buffer。其中,back buffer就是canvas绘图时对应的bitmap,绘画总是在back buffer上,需要更新时,则将back buffer和front buffer互换。

Ø  SurfaceFlinger—High-LevelOverView

Ø  Java Surface (frameworks/base/core/java/android/view/Surface.java)。该对象被应用间接调用(通过SurfaceView,ViewRoot等), 应用需要创建surface,(并同时创建canvas), 将图形绘制到这个对象上,并最终投递到屏幕上。

Ø  C++ Surface(frameworks/base/libs/ui/Surface.cpp。 这个对象被Java Surface通过Jni 调用,实现Java Surface 的功能。

Ø   ISurface (以及其派生类BnSurface)。这个对象是应用和server之间的接口。C++ Surface创建这个ISurface (BnSurface)并发送命令,如更新surface内容到屏幕上。Server端接受这个命令并执行相应操作。

 

四、       Media API

Android提供Media API给开发人员使用:MediaPlayer、MediaRecorder、Android MediaAPIs。

1.    MediaPlayer

提供的基本接口如下:

Public Methods

static MediaPlayercreate(Context context, Uri uri)

Convenience method to createa MediaPlayer for a given Uri.  

int getCurrentPosition()

Gets the current playbackposition.    

int getDuration()

Gets the duration of thefile.    

int getVideoHeight()

Returns the height of thevideo.   

int getVideoWidth()

Returns the width of thevideo.   

boolean isPlaying()

Checks whether theMediaPlayer is playing.    

void pause()

Pauses playback.    

void prepare()

Prepares the player forplayback, synchronously.    

void prepareAsync()

Prepares the player forplayback, asynchronously.    

void release()

Releases resourcesassociated with this MediaPlayer object.   

void reset()

Resets the MediaPlayer toits uninitialized state.    

void seekTo(int msec)

Seeks to specified timeposition.   

void setAudioStreamType(intstreamtype)

Sets the audio stream typefor this MediaPlayer.   

void setDataSource(Stringpath)

Sets the data source(file-path or http/rtsp URL) to use.        

voidsetDisplay(SurfaceHolder sh)

Sets the SurfaceHolder touse for displaying the video portion of the media.    

void setVolume(floatleftVolume, float rightVolume)

Sets the volume on thisplayer.

void start()

Starts or resumesplayback.    

void stop()

Stops playback afterplayback has been stopped or paused.

可以看出MediaPlayer类提供了一个多媒体播放器的基本操作,播放,暂停,停止,设置音量等等。

2.    MediaPlayer结构

MediaPlayer JNI

代码位置 /frameworks/base/media/jni

MediaPlayer (Native)

代码位置/frameworks/base/media/libmedia

MediaPlayerService (Server)

代码位置/frameworks/base/media/libmediaplayerservice

MediaPlayerService HostProcess

代码位置/frameworks/base/media/mediaserver/main_mediaserver.cpp

PVPlayer

代码位置 /external/opencore/android/

3.    MediaPlayer调用

4.    Media Recorder

提供的基本接口如下:

Public Method:

void prepare()

Prepares the recorder tobegin capturing and encoding data.    

void release()

Releases resourcesassociated with this MediaRecorder object.    

void reset()

Restarts the MediaRecorderto its idle state.    

void setAudioEncoder(intaudio_encoder)

Sets the audio encoder to beused for recording.    

void setAudioSource(intaudio_source)

Sets the audio source to beused for recording.    

void setOutputFile(Stringpath)

Sets the path of the outputfile to be produced.    

void setOutputFormat(intoutput_format)

Sets the format of theoutput file produced during recording.    

voidsetPreviewDisplay(Surface sv)

Sets a Surface to show apreview of recorded media (video).   

void start()

Begins capturing andencoding data to the file specified with setOutputFile().    

void stop()

Stops recording.

 

五、       Android音频

 

 

 

 

 

 

 

Android Framework的音频子系统中,每一个音频流对应着一个AudioTrack类的一个实例,每个AudioTrack会在创建时注册到AudioFlinger中,由AudioFlinger把所有的AudioTrack进行混合(Mixer),然后输送到AudioHardware中进行播放。AudioTrack和AudioFlinger的通信机制通常,AudioTrack和AudioFlinger并不在同一个进程中,它们通过android中的binder机制建立联系。

 

 

1、Android音频处理的基本接口

 

在Android开发中,根据不同的场景,出于冲突处理策略的考虑,开发者需要利用不同的接口来进行音频资源的播放。

AudioManager为上层应用提供了声音设置管理接口.

AudioService为所有的音频相关的设置提供服务。他定义了了一个AudioSystemThread 的类,用来监控音频控制相关的信号,当有请求时,它会通过调用AudioSystem 的接口实现音频的控制,这里的消息处理是异步的。此外在AudioService还抽象出了一套发送音频控制信号的接口为AudioManager提供支持。 

AudioSystem提供了音频系统的基本类型定义,以及基本操作的接口。

  对于音调,可以通过ToneGenerator来播放;ToneGenerator提供了对DTMF音(ITU-T Q.23),以及呼叫监督音(3GPP TS 22.001)、专用音(3GPP TS 31.111)中规定的音频的支持,根据呼叫状态和漫游状态,该文件产生的音频路径为下行音频或者传输给扬声器或耳机。

对于提示音,可以通过Ringtone来播放;Ringtone和RingtoneManager为铃声、提示音、闹钟等提供了快速播放,以及管理接口。实质是对媒体播放器提供了一个简单的封装。

  对于游戏中的音频资源,可以通过SoundPool来播放。

对于录音功能,则需要通过MediaRecorder和AudioRecord等来进行音频记录。

除了这些直接的音频类外,对于音量调节、音频设备的管理等,Android还提供了相关的类来处理。

AudioManager通过音频服务,为上层提供了音量和铃声模式控制的接口,铃声模式控制包括扬声器、耳机、蓝牙等是否打开,麦克风是否静音等。在开发多媒体应用时会经常用到AudioManager,关于Android AudioManager音量控制流程。

SoundPool能够播放音频流的组合音,这对游戏应用而言显然非常有用。SoundPool可以从APK包中的资源文件或者文件系统中的文件将音频资源加载到内存中。在底层的实现上,SoundPool通过媒体播放服务可以将音频资源解码为一个16bit的单声道或者立体声的PCM流,这使得应用避免了在回放过程中进行解码造成的延迟。除了回放过程中延迟小的优点外,SoundPool还能够对一定数量的音频流进行同时播放。当要播放的音频流数量超过SoundPool所设定的最大值时,SoundPool将会停止已播放的一条低优先级的音频流。SoundPool最大播放音频流数量的设置,可以避免CPU过载和影响UI体验。

Android平台中关于音频的播放还有另一种方式是MediaPlayer。MediaPlayer的特点是同一时间却只能播放一个,适合较长但是对时间要求不高的情况。

 

2、MediaServer分析

  MediaServer是整个android中media部分的核心和灵魂。几乎所有与多媒体播放相关的内容都放在这里。包括了音视频的编解码以及显示输出。

1. 先初始化AudioFlinger

其初始化通过AudioFlinger的父类BindService创建唯一的AudioFlinger实例。

2. 然后初始化MediaPlayerService和CameraService

3. 最后初始化AudioPolicyService

 

3、AudioPolicyService 和AudioPolicyManager分析

AudioPolicyService是Android音频系统的两大服务之一,另一个服务是AudioFlinger,这两大服务都在系统启动时有 MediaSever加载。

AudioPolicyService主要完成以下任务:

l  JAVA应用层通过JNI,经由IAudioPolicyService接口,访问AudioPolicyService提供的服务

l  输入输出设备的连接状态

l  系统的音频策略(strategy)的切换

l  音量/音频参数的设置

AudioPolicyManager

   AudioPolicyService的很大一部分管理工作都是在AudioPolicyManager中完成的。包括音量管理,音频策略(strategy)管理,输入输出设备管理。

通过AudioPolicyService的 AudioCommandThread,最终会将设置应用到AudioFlinger的相应的Track中。

 

4、 AudioFlinger分析

AudioFlinger负责管理每个音轨AudioTrack及RecordTrack,主音量控制,每种声音流的属性设置,设备控制,音效控制。AudioFlinger是android中的一个service,在android启动时就已经被加载。

播放线程实际上是MixerThread的一个实例,会把该线程中的各个Track进行混合,必要时还要进行ReSample(重采样)的动作,转换为统一的采样率(44.1K),然后通过音频系统的AudioHardware层输出音频数据。

SRC[Sample Rate Converter,采样频率转换] SRC的作用就是改变信号的采样率,低采样率往高采样率转换时就是一个重采样的过程,重采样对象不再是原始信号,而是这个低采样率的信号,因为采样率不够需要插入更多的采样点以达到需要的采样率和采样大小。

三种平台的音频架构对比

一、android平台

 

 

  Android使用的是为智能终端专门制定的ALSA(AdvancedLinux Sound Architecture,高级Linux声音架构)框架。

从Android的音频架构及流程分析,由于其驱动库位于核心层,也就意味着音频设备厂商、用户无法象PC平台那样安装驱动来改善音质。我们在实际的应用中也能感受到,Android设备音质普遍偏差。音质出现偏差一个主要的问题是处在SRC这里。低采样率往高采样率转换时就是一个重采样的过程,重采样对象不再是原始信号,而是这个低采样率的信号,因为采样率不够需要插入更多的采样点以达到需要的采样率和采样大小

理论上SRC可以通过更换算法来实现音质提升,但却不太现实,SRC需要大量的浮点运算的资源,即便有了高质量的SRC算法,其运算也是以牺牲设备性能和耗电量为代价的,实用性差。

二、windowsphone平台

 

 

通用音频架构(UAA)

UAA分为独占模式和共享模式,它最大程度的降低了音频设备驱动对系统稳定性的影响,而且还能够增加信号处理流程的透明度,处理环节可以得到控制,在理论上说,它可以实现更加优秀的音质,也能非常显著的提升系统响应速度,大幅减低延时

应用程式在一般情况下都是走Shared Mode(共享模式)那条路径,这个路径被称作通道,根据上面关于共享模式的介绍,所有的声音讯号都会转送至Audio Engine(音效引擎)部分,有软件混音动作,就可能会经过SRC,使得声音出现偏差。而当应用程序发出使用独占模式的需求后,系统会切断共享模式这一条路径,声音讯号就会直接送达Kernel Mode最后到达底层的音频设备后输出,音频设备在此时也会完全100%配合独占模式送来的音频格式进行处理。

三、iOS平台

我们再把目光投向iOS,iOS非常封闭,我们甚至无法获知其架构的具体构成,但iOS设备不存在硬件设备多样性的问题,因此要实现更好音质也会更加简单。iOS可以实现针对性的开发和改良,以实现更好的音质。实际情况也是如此,目前为止,还没有一款Android设备的音质可以媲美任意一款iOS设备,这种差距,我们认为不是来自硬件,而是操作系统。

posted on 2017-02-23 23:46  信假名如  阅读(269)  评论(0编辑  收藏  举报

导航