Android Framework学习笔记 -- 蓝牙设备播放流程

因为蓝牙通路与其他设备不同(多了一个蓝牙设备),因此播放的流程也与其他设备略有不同。

蓝牙设备的连接

从setDeviceConnectionState开始,AudioPolicyManager先注册Device后,再去打开设备对应的output,如果是duplicating类型的话,还要建一个DuplicateOutput,关联该output与mPrimaryOutput

//--->frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,
                                                      audio_policy_dev_state_t state,
                                                      const char *device_address,
                                                      const char *device_name)
{
    return setDeviceConnectionStateInt(device, state, device_address, device_name);
}

status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t device,
                                                     audio_policy_dev_state_t state,
                                                     const char *device_address,
                                                     const char *device_name)
{
    ...
    sp devDesc = mHwModules.getDeviceDescriptor(device, device_address, device_name);
    ...
    // handle output devices
    ...
    SortedVector  outputs;
    ssize_t index = mAvailableOutputDevices.indexOf(devDesc);
    mPreviousOutputs = mOutputs;
    ...(注册设备)
    if (index >= 0) {
        sp module = mHwModules.getModuleForDevice(device);
        if (module == 0) {
            mAvailableOutputDevices.remove(devDesc);
            return INVALID_OPERATION;
        }
        mAvailableOutputDevices[index]->attach(module);
    } else {
        return NO_MEMORY;
    }

    if (checkOutputsForDevice(devDesc, state, outputs, devDesc->mAddress) != NO_ERROR) {
        mAvailableOutputDevices.remove(devDesc);
        return INVALID_OPERATION;
    }
    ...
}


status_t AudioPolicyManager::checkOutputsForDevice(const sp devDesc,
                                                   audio_policy_dev_state_t state,
                                                   SortedVector& outputs,
                                                   const String8 address)
{
    ...
    // 打开设备所对应的output
    for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) {
        sp profile = profiles[profile_index];
        ...
        status_t status = mpClientInterface->openOutput(profile->getModuleHandle(),
                                                        &output,
                                                        &config,
                                                        &desc->mDevice,
                                                        address,
                                                        &desc->mLatency,
                                                        desc->mFlags);
    }
    ...
    // 后续处理
    if (output != AUDIO_IO_HANDLE_NONE) {
        addOutput(output, desc);
        ... 
        else if (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) &&
                        hasPrimaryOutput()) {
            ...
            // open a duplicating output thread for the new output and the primary output
            duplicatedOutput =
                    mpClientInterface->openDuplicateOutput(output,
                                                           mPrimaryOutput->mIoHandle);
            ...
        }
    }
}

openOutput的流程跟其他Output的流程是一样的,最终在AudioFlinger建立了对应Output的Thread。DuplicateOutput使用openDuplicateOutput来打开,最终也是在AudioFlinger建立一个DuplicatingThread。

//--->frameworks/av/services/audiopolicy/service/AudioPolicyClientImpl.cpp
// AudioPolicyService的转发
audio_io_handle_t AudioPolicyService::AudioPolicyClient::openDuplicateOutput(
                                                                audio_io_handle_t output1,
                                                                audio_io_handle_t output2)
{
    sp af = AudioSystem::get_audio_flinger();
    if (af == 0) {
        ALOGW("%s: could not get AudioFlinger", __func__);
        return 0;
    }
    return af->openDuplicateOutput(output1, output2);
}

//--->frameworks/av/services/audioflinger/AudioFlinger.cpp
audio_io_handle_t AudioFlinger::openDuplicateOutput(audio_io_handle_t output1,
        audio_io_handle_t output2)
{
    // 这里两个output对应的thread都是MixerThread,意味着DuplicatingThread对应的线程是MixerThread??
    Mutex::Autolock _l(mLock);
    MixerThread *thread1 = checkMixerThread_l(output1);
    MixerThread *thread2 = checkMixerThread_l(output2);
    ...

    audio_io_handle_t id = nextUniqueId();
    DuplicatingThread *thread = new DuplicatingThread(this, thread1, id, mSystemReady);
    thread->addOutputTrack(thread2);
    mPlaybackThreads.add(id, thread);
    thread->ioConfigChanged(AUDIO_OUTPUT_OPENED);
    return id;
}

//--->frameworks/av/services/audioflinger/Threads.cpp    
AudioFlinger::DuplicatingThread::DuplicatingThread(const sp& audioFlinger,
        AudioFlinger::MixerThread* mainThread, audio_io_handle_t id, bool systemReady)
    :   MixerThread(audioFlinger, mainThread->getOutput(), id, mainThread->outDevice(),
                    systemReady, DUPLICATING),
        mWaitTimeMs(UINT_MAX)
{
    addOutputTrack(mainThread);
}

DuplicatingThread的addOutputTrack会创建对应thread的track(也就是生产者啦)

//--->frameworks/av/services/audioflinger/Threads.cpp    
void AudioFlinger::DuplicatingThread::addOutputTrack(MixerThread *thread)
{
    Mutex::Autolock _l(mLock);
    // The downstream MixerThread consumes thread->frameCount() amount of frames per mix pass.
    // Adjust for thread->sampleRate() to determine minimum buffer frame count.
    // Then triple buffer because Threads do not run synchronously and may not be clock locked.
    const size_t frameCount =
            3 * sourceFramesNeeded(mSampleRate, thread->frameCount(), thread->sampleRate());

    sp outputTrack = new OutputTrack(thread,
                                            this,
                                            mSampleRate,
                                            mFormat,
                                            mChannelMask,
                                            frameCount,
                                            IPCThreadState::self()->getCallingUid());
    ...
}

DuplicatingThread播放

普通的连蓝牙播放(音乐,触屏音等)还不会用到DuplicatingThread,只有在需要双设备播放的情况下(如闹铃,来电等),才会用到DuplicatingThread。DuplicatingThread跟别的PlaybackThread一样,也有prepareTrack_l和mix,就是write的时候不大一样。

ssize_t AudioFlinger::DuplicatingThread::threadLoop_write()
{
    // 对每个Tracks写数据 这里DuplicatingThread相当于生产者了
    for (size_t i = 0; i < outputTracks.size(); i++) {
        outputTracks[i]->write(mSinkBuffer, writeFrames);
    }
    mStandby = false;
    return (ssize_t)mSinkBufferSize;
}

OutputThrack与AudioTrack类似,也是用obtainBuffer与releaseBuffer来驱动PlaybackThread

bool AudioFlinger::PlaybackThread::OutputTrack::write(void* data, uint32_t frames)
{
    ...
    while (waitTimeLeftMs) {
        ...
        status_t status = obtainBuffer(&mOutBuffer, waitTimeLeftMs);
        ...
        memcpy(mOutBuffer.raw, pInBuffer->raw, outFrames * mFrameSize);
        ...
        mClientProxy->releaseBuffer(&buf);

    }
    ...
}

DuplicatingThread作用很明了,就是把一个output的流dup到其他output,这个一开始看名字就看出来了,就是不知道关联的是那个output,驱动其他两个thread的方式。

你可能感兴趣的:(audio)