前面讲到AudioFlinger打开设备,但是后面贴了图片就没继续了,现在继续看看:
audio_io_handle_t AudioFlinger::openOutput(audio_module_handle_t module,
audio_devices_t *pDevices,
uint32_t *pSamplingRate,
audio_format_t *pFormat,
audio_channel_mask_t *pChannelMask,
uint32_t *pLatencyMs,
audio_output_flags_t flags)
就这个地方了!
准备打开如下:
outHwDev = findSuitableHwDev_l(module, *pDevices);
if (outHwDev == NULL)
return 0;
audio_hw_device_t *hwDevHal = outHwDev->hwDevice();
先查找适合的设备,然后在打开,查找适合的设备如下:
AudioFlinger::AudioHwDevice* AudioFlinger::findSuitableHwDev_l(
audio_module_handle_t module,
audio_devices_t devices)
{
// if module is 0, the request comes from an old policy manager and we should load
// well known modules
if (module == 0) {
ALOGW("findSuitableHwDev_l() loading well know audio hw modules");
for (size_t i = 0; i < ARRAY_SIZE(audio_interfaces); i++) {
loadHwModule_l(audio_interfaces[i]);
}
// then try to find a module supporting the requested device.
for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
AudioHwDevice *audioHwDevice = mAudioHwDevs.valueAt(i);
audio_hw_device_t *dev = audioHwDevice->hwDevice();
if ((dev->get_supported_devices != NULL) &&
(dev->get_supported_devices(dev) & devices) == devices)
return audioHwDevice;
}
} else {
// check a match for the requested module handle
AudioHwDevice *audioHwDevice = mAudioHwDevs.valueFor(module);
if (audioHwDevice != NULL) {
return audioHwDevice;
}
}
return NULL;
}
这个地方有两个遍历:
<1> : 遍历了所有的interfaces,这个接口非常的重要,就相当于通向不同设备的道路的大门,一般较多的AudioHardwareInterface,AudioHardwareA2dpInterface等等,使用不同的接口,就以为的操作不同的接口了!
<2> : 遍历了所有的设备,然后选择支持的设备返回,上面有name参考,打印出来即primary,a2dp,usb等等
然后通过上面返回的设备打开设备流:
status = hwDevHal->open_output_stream(hwDevHal,
id,
*pDevices,
(audio_output_flags_t)flags,
&config,
&outStream);
然后创建播放线程:
if ((flags & AUDIO_OUTPUT_FLAG_DIRECT) ||
(config.format != AUDIO_FORMAT_PCM_16_BIT) ||
(config.channel_mask != AUDIO_CHANNEL_OUT_STEREO)) {
thread = new DirectOutputThread(this, output, id, *pDevices);
ALOGV("openOutput() created direct output: ID %d thread %p", id, thread);
} else {
thread = new MixerThread(this, output, id, *pDevices);
ALOGV("openOutput() created mixer output: ID %d thread %p", id, thread);
}
mPlaybackThreads.add(id, thread);
将穿件的播放线程添加到mPlaybackThreads中,AudioFlinger,创建好的线程会把该线程和它的Id保存在AudioFlinger的成员变量mPlaybackThreads 中,mPlaybackThreads是一个Vector,AudioFlinger创建的线程都会保存在里面,最后,openOutput返回该线程的 Id,该Id也就是所谓的audio_io_handle_t,AudioFlinger的调用者这能看到这个audio_io_handle_t,当需 要访问时传入该audio_io_handle_t,AudioFlinger会通过mPlaybackThreads,得到该线程的指针.所以可以每个播