Android音频系统之AudioFlinger(一)【转】

1.1 AudioFlinger

在上面的框架图中,我们可以看到AudioFlinger(下面简称AF)是整个音频系统的核心与难点。作为Android系统中的音频中枢,它同时也是 一个系统服务,启到承上(为上层提供访问接口)启下(通过HAL来管理音频设备)的作用。只有理解了AudioFlinger,才能以此为基础更好地深入 到其它模块,因而我们把它放在前面进行分析。

1.1.1 AudioFlinger服务的启动和运行

我们知道,Android中的系统服务分为两类,分别是Java层和Native层的System Services。其中AudioFlinger和SurfaceFlinger一样,都属于后者。Java层服务通常在 SystemServer.java中启动,比如后面会看到的AudioService就是这种情况。而Native层服务则通常是各服务方按照自己的特 定部署来决定何时启动、如何启动。例如AudioFlinger就是利用一个Linux程序来间接创建的,如下所示:

/*frameworks/av/media/mediaserver/Main_mediaserver.cpp*/

int main(int argc, char** argv)

{

sp<ProcessState>proc(ProcessState::self());

sp<IServiceManager>sm = defaultServiceManager();

ALOGI("ServiceManager: %p", sm.get());

AudioFlinger::instantiate();

MediaPlayerService::instantiate();

CameraService::instantiate();

AudioPolicyService::instantiate();

ProcessState::self()->startThreadPool();

IPCThreadState::self()->joinThreadPool();

}

这个mediaserver的目录下只有一个文件,它的任务很简单,就是把所有媒体相关的native层服务(包括AudioFlinger,MediaPlayerService,CameraService和AudioPolicyService)启动起来,可以参考其Android.mk:

LOCAL_SRC_FILES:=

main_mediaserver.cpp

LOCAL_SHARED_LIBRARIES := \

libaudioflinger\

libcameraservice\

libmediaplayerservice\

libutils \

libbinder

LOCAL_MODULE:= mediaserver

根据前面的分析,AudioFlinger的源码实现是放在libaudioflinger库中的,因而在编译mediaserver时要引用这个库,其 它服务也是一样的做法。编译生成的mediaserver将被烧录到设备的/system/bin/mediaserver路径中,然后由系统启动时的 init进程启动,其在Init.rc中的配置是:

service media /system/bin/mediaserver

class main

user media

group audio camera inetnet_bt net_bt_admin net_bw_acct drmrpc

ioprio rt 4

值得一提的是,这个AudioFlinger::instantiate()并不是AudioFlinger内部的静态类,而是 BinderService类的一个实现。包括AudioFlinger、AudioPolicyService等在内的几个服务都继承自这个统一的 Binder服务类,比如:

class AudioFlinger :

public BinderService<AudioFlinger>,

public BnAudioFlinger…

从名称上看,BinderService应该是实现了binder跨进程通信相关的功能,它是一个模板类,其中的函数instantiate将把模板指定的服务创建出来,并添加到ServiceManager中:

/*frameworks/native/include/binder/BinderService.h*/

template<typename SERVICE> …

static status_t  publish(bool allowIsolated = false) {

sp<IServiceManager> sm(defaultServiceManager());

returnsm->addService(String16(SERVICE::getServiceName()), new SERVICE(),allowIsolated);

}

static void instantiate(){ publish(); } //调用publish

回头看下AudioFlinger的构造函数,发现它只是简单地为内部一些变量做了初始化,除此之外就没有任何代码了:

AudioFlinger::AudioFlinger()

:BnAudioFlinger(),mPrimaryHardwareDev(NULL),

mHardwareStatus(AUDIO_HW_IDLE), // see alsoonFirstRef()

mMasterVolume(1.0f),mMasterVolumeSupportLvl(MVS_NONE), mMasterMute(false),

mNextUniqueId(1),mMode(AUDIO_MODE_INVALID), mBtNrecIsOff(false)

{

}

大家可能会觉得疑惑,那么AudioFlinger在什么情况下会开始执行实际的工作呢?没错,是在onFirstRef()中。 BnAudioFlinger是由RefBase层层继承而来的,并且IServiceManager::addService的第二个参数实际上是一个 强指针引用(constsp<IBinder>&),因而AudioFlinger具备了强指针被第一次引用时调用 onFirstRef的程序逻辑。如果大家不是很清楚这些细节的话,可以参考下本书的强指针章节,这里不再赘述。

void AudioFlinger::onFirstRef()

{

int rc = 0;

Mutex::Autolock _l(mLock);

charval_str[PROPERTY_VALUE_MAX] = { 0 };

if(property_get("ro.audio.flinger_standbytime_ms", val_str, NULL) >=0) {

uint32_t int_val;

if (1 ==sscanf(val_str, "%u", &int_val)) {

mStandbyTimeInNsecs= milliseconds(int_val);

ALOGI("Using%u mSec as standby time.", int_val);

} else {

mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;

}

}

mMode = AUDIO_MODE_NORMAL;

mMasterVolumeSW = 1.0;

mMasterVolume   = 1.0;

mHardwareStatus =AUDIO_HW_IDLE;

}

属性ro.audio.flinger_standbytime_ms为用户调整standby时间提供了一个接口,早期版本中这个时间值是固定的。接下来初始化几个重要的内部变量,和构造函数的做法不同的是,这里赋予的都是有效的值了。

从这时开始,AudioFlinger就是一个“有意义”的实体了,因为有人使用到了它。接下来其它进程可以通过ServiceManager来访问,并 调用createTrack、openOutput等一系列接口来驱使AudioFlinger执行音频处理操作,我们在后面章节会陆续讲解到。

时间: 2024-07-30 13:52:55

Android音频系统之AudioFlinger(一)【转】的相关文章

Android音频系统之AudioFlinger(四)【转】

Android音频系统之AudioFlinger(四) 分类: ALSA/Audio 2014-06-12 17:37 195人阅读 评论(0) 收藏 举报 1.1.1 AudioMixer 每一个MixerThread都有一个唯一对应的AudioMixer(在MixerThread中用mAudioMixer表示),它的作用如其名所表示的,就是为了完成音频的混音操作.   图 13?14 MixerThread示意图 如上图,MixerThread对外开放的接口主要涉及到Parameter(比如

Android音频系统之AudioFlinger(一)

http://blog.csdn.net/xuesen_lin/article/details/8805068 1.1 AudioFlinger 在上面的框架图中,我们可以看到AudioFlinger(下面简称AF)是整个音频系统的核心与难点.作为Android系统中的音频中枢,它同时也是一个系统服务,启到承上(为上层提供访问接口)启下(通过HAL来管理音频设备)的作用.只有理解了AudioFlinger,才能以此为基础更好地深入到其它模块,因而我们把它放在前面进行分析. 1.1.1 Audio

Android音频系统之AudioFlinger(二) 【转】

1.1.1 音频设备的管理 虽然AudioFlinger实体已经成功创建并初始化,但到目前为止它还是一块静态的内存空间,没有涉及到具体的工作. 从职能分布上来讲,AudioPolicyService是策略的制定者,比如什么时候打开音频接口设备.某种Stream类型的音频对应什么设备等等.而AudioFlinger则是策略的执行者,例如具体如何与音频设备通信,如何维护现有系统中的音频设备,以及多个音频流的混音如何处理等等都得由它来完成. 目前Audio系统中支持的音频设备接口(Audio Inte

Android音频系统之AudioFlinger(二)

1.1.1 音频设备的管理 虽然AudioFlinger实体已经成功创建并初始化,但到目前为止它还是一块静态的内存空间,没有涉及到具体的工作. 从职能分布上来讲,AudioPolicyService是策略的制定者,比如什么时候打开音频接口设备.某种Stream类型的音频对应什么设备等等.而AudioFlinger则是策略的执行者,例如具体如何与音频设备通信,如何维护现有系统中的音频设备,以及多个音频流的混音如何处理等等都得由它来完成. 目前Audio系统中支持的音频设备接口(Audio Inte

Android音频系统之AudioFlinger(三) 【转】

1.1.1 PlaybackThread的循环主体 当一个PlaybackThread进入主循环后(threadLoop),音频事务就正式开启了.仔细观察的话,我们会发现这个循环中会不断地调用以 “threadLoop_”开头的若干接口,比如threadLoop_mix.threadLoop_sleepTime. threadLoop_standby等等.以这样的前缀开头,是因为这些函数都是在threadLoop这个主体里被调用的,可以说代表了这个 PlaybackThread所需要完成的各个操

Android 音频系统:从 AudioTrack 到 AudioFlinger

1. Android 音频框架概述 Audio 是整个 Android 平台非常重要的一个组成部分,负责音频数据的采集和输出.音频流的控制.音频设备的管理.音量调节等,主要包括如下部分: Audio Application Framework:音频应用框架 AudioTrack:负责回放数据的输出,属 Android 应用框架 API 类 AudioRecord:负责录音数据的采集,属 Android 应用框架 API 类 AudioSystem: 负责音频事务的综合管理,属 Android 应

Android音频系统之音频框架

http://blog.csdn.net/xuesen_lin/article/details/8796492 我们可以结合目前已有的知识,想一下每一个层次都会包含哪些模块(先不考虑蓝牙音频部分)? ·        APP 这是整个音频体系的最上层,因而并不是Android系统实现的重点.比如厂商根据特定需求自己写的一个音乐播放器,游戏中使用到声音,或者调节音频的一类软件等等. ·        Framework 相信大家可以马上想到MediaPlayer和MediaRecorder,因为这

Android音频系统之音频框架(转http://blog.csdn.net/uiop78uiop78/article/details/8796492)

1.1 音频框架 转载请注明,From LXS, http://blog.csdn.net/uiop78uiop78/article/details/8796492 Android的音频系统在很长一段时间内都是外界诟病的焦点.的确,早期的Android系统在音频处理上相比于IOS有一定的差距,这也是很多专业的 音乐播放软件开发商没有推出Android平台产品的一个重要原因.但这并不代表它的音频框架一无是处,相反,基于Linux系统的Android平台有 很多值得我们学习的地方. 1.1.1 Li

Android音频系统之AudioTrack(一) 【转】

1.1 AudioTrack 1.1.1 AudioTrack应用实例 对于Android应用开发人员来讲,音频回放最熟悉的莫过于MediaPlayer,而AudioTrack相信用的人相对会少很多.这是因为 MediaPlayer提供了更完整的封装和状态控制,使得我们用很少的代码就可以实现一个简单的音乐播放器.而相比MediaPlayer,AudioTrack更为精练.高效,实际上MediaPlayerService的内部实现就是使用了AudioTrack. AudioTrack被用于PCM音