在创建track之前,需要根据应用传下来的的参数获取对输出线程output,这个output应该是在AudioFling进行初始化的时候就已经运行起来了。
createTrack只是将track添加到指定的输出线程output,该线程会使用track传递下来的数据进行mix,然后写到输出设备中。
因此如何获得该输出线程output至关重要,
status_t AudioTrack::set(
audio_stream_type_t streamType,
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
int frameCountInt,
audio_output_flags_t flags,
callback_t cbf,
void* user,
int notificationFrames,
const sp<IMemory>& sharedBuffer,
bool threadCanCallJava,
int sessionId,
transfer_type transferType,
const audio_offload_info_t *offloadInfo,
int uid)
{
.....
//根据规则获得对应的输出线程output,output其实只是该线程的一个编号,
//所有的输出线程都保存在AudioFling中,后续使用的时候可以根据这个编号
//来进行查找
audio_io_handle_t output = AudioSystem::getOutput(
streamType,
sampleRate, format, channelMask,
flags,
offloadInfo);
if (output == 0) {
ALOGE("Could not get audio output for stream type %d", streamType);
return BAD_VALUE;
}
mVolume[LEFT] = 1.0f;
mVolume[RIGHT] = 1.0f;
mSendLevel = 0.0f;
mFrameCount = frameCount;
mReqFrameCount = frameCount;
mNotificationFramesReq = notificationFrames;
mNotificationFramesAct = 0;
mSessionId = sessionId;
if (uid == -1 || (IPCThreadState::self()->getCallingPid() != getpid())) {
mClientUid = IPCThreadState::self()->getCallingUid();
} else {
mClientUid = uid;
}
mAuxEffectId = 0;
mFlags = flags;
mCbf = cbf;
if (cbf != NULL) {
mAudioTrackThread = new AudioTrackThread(*this, threadCanCallJava);
mAudioTrackThread->run("AudioTrack", ANDROID_PRIORITY_AUDIO, 0 /*stack*/);
}
// create the IAudioTrack
status_t status = createTrack_l(streamType,
sampleRate,
format,
frameCount,
flags,
sharedBuffer,
output,
0 /*epoch*/);
}
audio_io_handle_t AudioSystem::getOutput(audio_stream_type_t stream,
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
audio_output_flags_t flags)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return 0;
return aps->getOutput(stream, samplingRate, format, channelMask, flags);
}
audio_io_handle_t AudioPolicyService::getOutput(audio_stream_type_t stream,
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
audio_output_flags_t flags)
{
if (mpAudioPolicy == NULL) {
return 0;
}
ALOGV("getOutput()");
Mutex::Autolock _l(mLock);
return mpAudioPolicy->get_output(mpAudioPolicy, stream, samplingRate, format, channelMask,
flags);
}
//输出线程的查找路径:StreamType->Strategy->Device->Output
audio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type stream,
uint32_t samplingRate,
uint32_t format,
uint32_t channelMask,
AudioSystem::output_flags flags)
{
audio_io_handle_t output = 0;
uint32_t latency = 0;
//步骤一、根据StreamType找到Strategy,对应关系一直不变
routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream);
//步骤二、根据Strategy找到Device,
audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
ALOGV("getOutput() stream %d, samplingRate %d, format %d, channelMask %x, flags %x",
stream, samplingRate, format, channelMask, flags);
#ifdef AUDIO_POLICY_TEST
if (mCurOutput != 0) {
ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelMask %x, mDirectOutput %d",
mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput);
if (mTestOutputs[mCurOutput] == 0) {
ALOGV("getOutput() opening test output");
AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL);
outputDesc->mDevice = mTestDevice;
outputDesc->mSamplingR