Android Audio System

开机启动加载多媒体服务位于:

frameworks/base/media/mediaserver/main_mediaserver.cpp

 1 int main(int argc, char** argv)
 2 {
 3     sp<ProcessState> proc(ProcessState::self());
 4     sp<IServiceManager> sm = defaultServiceManager();
 5     LOGI("ServiceManager: %p", sm.get());
 6     AudioFlinger::instantiate();        
 7     MediaPlayerService::instantiate();
 8     MemoryDumper::instantiate();
 9     CameraService::instantiate();
10     AudioPolicyService::instantiate();
11     ProcessState::self()->startThreadPool();
12     IPCThreadState::self()->joinThreadPool();
13 }

 由此可知,Android系统开机启动了AudioFlinger、MediaPlayerService、CameraService、AudioPolicyService、MemoryDumper服务。

一、 AudioFlinger

class AudioFlinger :
    public BinderService<AudioFlinger>,
    public BnAudioFlinger
{

AudioFlinger 继承BinderService<?>,BinderService取得传入类的名字,由BinderService创建并加入服务列表。

template<typename SERVICE>
class BinderService
{
public:
    static status_t publish() {
        sp<IServiceManager> sm(defaultServiceManager());
        return sm->addService(String16(SERVICE::getServiceName()), new SERVICE());
    }

    static void publishAndJoinThreadPool() {
        sp<ProcessState> proc(ProcessState::self());
        sp<IServiceManager> sm(defaultServiceManager());
        sm->addService(String16(SERVICE::getServiceName()), new SERVICE());
        ProcessState::self()->startThreadPool();
        IPCThreadState::self()->joinThreadPool();
    }

    static void instantiate() { publish(); }

   static status_t shutdown() {
        return NO_ERROR;
    }
};

 再来看实例化AudioFlinger,并把实例加入服务队列,sm->addService(String16(SERVICE::getServiceName()), new SERVICE());

AudioFlinger::AudioFlinger()
    : BnAudioFlinger(), // init super class
        mAudioHardware(0), mMasterVolume(1.0f), mMasterMute(false), mNextUniqueId(1)
{
    mHardwareStatus = AUDIO_HW_IDLE;//init  hardware state IDLE

    // add by chipeng , for fsync
    mFd =0;
    int ret  = 0 ;
    ret |=  pthread_mutex_init(&Fasyc_Mutex, NULL);
    if ( ret != 0 ){
    LOGE("Failed to initialize pthread Fasyc_Mutex!");
    }
    // create hardware interface
    mAudioHardware = AudioHardwareInterface::create();
    // init hardware state INIT
    mHardwareStatus = AUDIO_HW_INIT;
    if (mAudioHardware->initCheck() == NO_ERROR) {
        // open 16-bit output stream for s/w mixer
        mMode = AudioSystem::MODE_NORMAL;
        setMode(mMode);
        // set volume
        setMasterVolume(1.0f);
        // set mute
        setMasterMute(false);
    } else {
        LOGE("Couldn't even initialize the stubbed audio hardware!");
    }
#ifdef LVMX
    LifeVibes::init();
    mLifeVibesClientPid = -1;
#endif

 

 AudioFlinger实例通过如下方法调用

const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();

该方法实现位于 frameworks/base/media/libmedia/AudioSystem.cpp

// establish binder interface to AudioFlinger service
const sp<IAudioFlinger>& AudioSystem::get_audio_flinger()
{
    Mutex::Autolock _l(gLock);
    if (gAudioFlinger.get() == 0) {
        // get service manager
        sp<IServiceManager> sm = defaultServiceManager();
        sp<IBinder> binder;
        do {
            // get service
            binder = sm->getService(String16("media.audio_flinger")); 
if (binder != 0) break; LOGW("AudioFlinger not published, waiting..."); usleep(500000); // 0.5 s } while(true); if (gAudioFlingerClient == NULL) { gAudioFlingerClient = new AudioFlingerClient(); } else { if (gAudioErrorCallback) { gAudioErrorCallback(NO_ERROR); } } binder->linkToDeath(gAudioFlingerClient); gAudioFlinger = interface_cast<IAudioFlinger>(binder); gAudioFlinger->registerClient(gAudioFlingerClient); } LOGE_IF(gAudioFlinger==0, "no AudioFlinger!?"); return gAudioFlinger; }

 创建AudioFlingerClient实例,通过Binder连接服务端与客户端。

构造AudioTrack会调用AudioFlinger如下方法

    // IAudioFlinger interface
    virtual sp<IAudioTrack> createTrack(
                                pid_t pid,
                                int streamType,
                                uint32_t sampleRate,
                                int format,
                                int channelCount,
                                int frameCount,
                                uint32_t flags,
                                const sp<IMemory>& sharedBuffer,
                                int output,
                                int *sessionId,
                                status_t *status);

 AudioFlinger类中createTrack实现如下

sp<IAudioTrack> AudioFlinger::createTrack(
        pid_t pid,
        int streamType,
        uint32_t sampleRate,
        int format,
        int channelCount,
        int frameCount,
        uint32_t flags,
        const sp<IMemory>& sharedBuffer,
        int output,
        int *sessionId,
        status_t *status)
{
    sp<PlaybackThread::Track> track;
    sp<TrackHandle> trackHandle;
    sp<Client> client;
    wp<Client> wclient;
    status_t lStatus;
    int lSessionId;

    if (streamType >= AudioSystem::NUM_STREAM_TYPES) {
        LOGE("invalid stream type");
        lStatus = BAD_VALUE;
        goto Exit;
    }

    {
        Mutex::Autolock _l(mLock);
        PlaybackThread *thread = checkPlaybackThread_l(output);
        PlaybackThread *effectThread = NULL; 
if (thread == NULL) { LOGE("unknown output thread"); lStatus = BAD_VALUE; goto Exit; } wclient = mClients.valueFor(pid); if (wclient != NULL) { client = wclient.promote(); } else { client = new Client(this, pid); mClients.add(pid, client); } LOGV("createTrack() sessionId: %d", (sessionId == NULL) ? -2 : *sessionId); if (sessionId != NULL && *sessionId != AudioSystem::SESSION_OUTPUT_MIX) { for (size_t i = 0; i < mPlaybackThreads.size(); i++) { sp<PlaybackThread> t = mPlaybackThreads.valueAt(i); if (mPlaybackThreads.keyAt(i) != output) { // prevent same audio session on different output threads uint32_t sessions = t->hasAudioSession(*sessionId); if (sessions & PlaybackThread::TRACK_SESSION) { lStatus = BAD_VALUE; goto Exit; } // check if an effect with same session ID is waiting for a track to be created if (sessions & PlaybackThread::EFFECT_SESSION) { effectThread = t.get(); } } } lSessionId = *sessionId; } else { // if no audio session id is provided, create one here lSessionId = nextUniqueId(); if (sessionId != NULL) { *sessionId = lSessionId; } } LOGV("createTrack() lSessionId: %d", lSessionId); track = thread->createTrack_l(client, streamType, sampleRate, format, channelCount, frameCount, sharedBuffer, lSessionId, &lStatus); // move effect chain to this output thread if an effect on same session was waiting // for a track to be created if (lStatus == NO_ERROR && effectThread != NULL) { Mutex::Autolock _dl(thread->mLock); Mutex::Autolock _sl(effectThread->mLock); moveEffectChain_l(lSessionId, effectThread, thread, true); } } if (lStatus == NO_ERROR) { trackHandle = new TrackHandle(track); } else { // remove local strong reference to Client before deleting the Track so that the Client // destructor is called by the TrackBase destructor with mLock held client.clear(); track.clear(); } Exit: if(status) { *status = lStatus; } return trackHandle; }

 

posted on 2012-07-25 17:36  RTFSC  阅读(1420)  评论(0编辑  收藏  举报

导航