Loading services/audiopolicy/AudioPolicyManager.cpp +74 −7 Original line number Diff line number Diff line Loading @@ -254,7 +254,7 @@ status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device, return NO_MEMORY; } if (checkOutputsForDevice(device, state, outputs, address) != NO_ERROR) { if (checkOutputsForDevice(devDesc, state, outputs, address) != NO_ERROR) { mAvailableOutputDevices.remove(devDesc); return INVALID_OPERATION; } Loading @@ -275,7 +275,7 @@ status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device, // remove device from available output devices mAvailableOutputDevices.remove(devDesc); checkOutputsForDevice(device, state, outputs, address); checkOutputsForDevice(devDesc, state, outputs, address); } break; default: Loading Loading @@ -2983,7 +2983,7 @@ void AudioPolicyManager::findIoHandlesByAddress(sp<AudioOutputDescriptor> desc / patchDesc->mPatch.sinks[j].ext.device.address; if (strncmp(patchAddr, address.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) { ALOGV("checkOutputsForDevice(): adding opened output %d on same address %s", ALOGV("findIoHandlesByAddress(): adding opened output %d on same address %s", desc->mIoHandle, patchDesc->mPatch.sinks[j].ext.device.address); outputs.add(desc->mIoHandle); break; Loading @@ -2993,12 +2993,15 @@ void AudioPolicyManager::findIoHandlesByAddress(sp<AudioOutputDescriptor> desc / } } status_t AudioPolicyManager::checkOutputsForDevice(audio_devices_t device, status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor> devDesc, audio_policy_dev_state_t state, SortedVector<audio_io_handle_t>& outputs, const String8 address) { audio_devices_t device = devDesc->mDeviceType; sp<AudioOutputDescriptor> desc; // erase all current sample rates, formats and channel masks devDesc->clearCapabilities(); if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) { // first list already open outputs that can be routed to this device Loading Loading @@ -3047,6 +3050,9 @@ status_t AudioPolicyManager::checkOutputsForDevice(audio_devices_t device, for (j = 0; j < outputs.size(); j++) { desc = mOutputs.valueFor(outputs.itemAt(j)); if (!desc->isDuplicated() && desc->mProfile == profile) { // matching profile: save the sample rates, format and channel masks supported // by the profile in our device descriptor devDesc->importAudioPort(profile); break; } } Loading Loading @@ -3196,6 +3202,8 @@ status_t AudioPolicyManager::checkOutputsForDevice(audio_devices_t device, profile_index--; } else { outputs.add(output); devDesc->importAudioPort(profile); if (deviceDistinguishesOnAddress(device)) { ALOGV("checkOutputsForDevice(): setOutputDevice(dev=0x%x, addr=%s)", device, address.string()); Loading Loading @@ -5575,16 +5583,22 @@ void AudioPolicyManager::AudioPort::toAudioPort(struct audio_port *port) const port->type = mType; unsigned int i; for (i = 0; i < mSamplingRates.size() && i < AUDIO_PORT_MAX_SAMPLING_RATES; i++) { if (mSamplingRates[i] != 0) { port->sample_rates[i] = mSamplingRates[i]; } } port->num_sample_rates = i; for (i = 0; i < mChannelMasks.size() && i < AUDIO_PORT_MAX_CHANNEL_MASKS; i++) { if (mChannelMasks[i] != 0) { port->channel_masks[i] = mChannelMasks[i]; } } port->num_channel_masks = i; for (i = 0; i < mFormats.size() && i < AUDIO_PORT_MAX_FORMATS; i++) { if (mFormats[i] != 0) { port->formats[i] = mFormats[i]; } } port->num_formats = i; ALOGV("AudioPort::toAudioPort() num gains %zu", mGains.size()); Loading @@ -5595,6 +5609,59 @@ void AudioPolicyManager::AudioPort::toAudioPort(struct audio_port *port) const port->num_gains = i; } void AudioPolicyManager::AudioPort::importAudioPort(const sp<AudioPort> port) { for (size_t k = 0 ; k < port->mSamplingRates.size() ; k++) { const uint32_t rate = port->mSamplingRates.itemAt(k); if (rate != 0) { // skip "dynamic" rates bool hasRate = false; for (size_t l = 0 ; l < mSamplingRates.size() ; l++) { if (rate == mSamplingRates.itemAt(l)) { hasRate = true; break; } } if (!hasRate) { // never import a sampling rate twice mSamplingRates.add(rate); } } } for (size_t k = 0 ; k < port->mChannelMasks.size() ; k++) { const audio_channel_mask_t mask = port->mChannelMasks.itemAt(k); if (mask != 0) { // skip "dynamic" masks bool hasMask = false; for (size_t l = 0 ; l < mChannelMasks.size() ; l++) { if (mask == mChannelMasks.itemAt(l)) { hasMask = true; break; } } if (!hasMask) { // never import a channel mask twice mChannelMasks.add(mask); } } } for (size_t k = 0 ; k < port->mFormats.size() ; k++) { const audio_format_t format = port->mFormats.itemAt(k); if (format != 0) { // skip "dynamic" formats bool hasFormat = false; for (size_t l = 0 ; l < mFormats.size() ; l++) { if (format == mFormats.itemAt(l)) { hasFormat = true; break; } } if (!hasFormat) { // never import a channel mask twice mFormats.add(format); } } } } void AudioPolicyManager::AudioPort::clearCapabilities() { mChannelMasks.clear(); mFormats.clear(); mSamplingRates.clear(); } void AudioPolicyManager::AudioPort::loadSamplingRates(char *name) { Loading services/audiopolicy/AudioPolicyManager.h +4 −1 Original line number Diff line number Diff line Loading @@ -238,6 +238,9 @@ protected: virtual void toAudioPort(struct audio_port *port) const; void importAudioPort(const sp<AudioPort> port); void clearCapabilities(); void loadSamplingRates(char *name); void loadFormats(char *name); void loadOutChannels(char *name); Loading Loading @@ -628,7 +631,7 @@ protected: // when a device is disconnected, checks if an output is not used any more and // returns its handle if any. // transfers the audio tracks and effects from one output thread to another accordingly. status_t checkOutputsForDevice(audio_devices_t device, status_t checkOutputsForDevice(const sp<DeviceDescriptor> devDesc, audio_policy_dev_state_t state, SortedVector<audio_io_handle_t>& outputs, const String8 address); Loading Loading
services/audiopolicy/AudioPolicyManager.cpp +74 −7 Original line number Diff line number Diff line Loading @@ -254,7 +254,7 @@ status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device, return NO_MEMORY; } if (checkOutputsForDevice(device, state, outputs, address) != NO_ERROR) { if (checkOutputsForDevice(devDesc, state, outputs, address) != NO_ERROR) { mAvailableOutputDevices.remove(devDesc); return INVALID_OPERATION; } Loading @@ -275,7 +275,7 @@ status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device, // remove device from available output devices mAvailableOutputDevices.remove(devDesc); checkOutputsForDevice(device, state, outputs, address); checkOutputsForDevice(devDesc, state, outputs, address); } break; default: Loading Loading @@ -2983,7 +2983,7 @@ void AudioPolicyManager::findIoHandlesByAddress(sp<AudioOutputDescriptor> desc / patchDesc->mPatch.sinks[j].ext.device.address; if (strncmp(patchAddr, address.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) { ALOGV("checkOutputsForDevice(): adding opened output %d on same address %s", ALOGV("findIoHandlesByAddress(): adding opened output %d on same address %s", desc->mIoHandle, patchDesc->mPatch.sinks[j].ext.device.address); outputs.add(desc->mIoHandle); break; Loading @@ -2993,12 +2993,15 @@ void AudioPolicyManager::findIoHandlesByAddress(sp<AudioOutputDescriptor> desc / } } status_t AudioPolicyManager::checkOutputsForDevice(audio_devices_t device, status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor> devDesc, audio_policy_dev_state_t state, SortedVector<audio_io_handle_t>& outputs, const String8 address) { audio_devices_t device = devDesc->mDeviceType; sp<AudioOutputDescriptor> desc; // erase all current sample rates, formats and channel masks devDesc->clearCapabilities(); if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) { // first list already open outputs that can be routed to this device Loading Loading @@ -3047,6 +3050,9 @@ status_t AudioPolicyManager::checkOutputsForDevice(audio_devices_t device, for (j = 0; j < outputs.size(); j++) { desc = mOutputs.valueFor(outputs.itemAt(j)); if (!desc->isDuplicated() && desc->mProfile == profile) { // matching profile: save the sample rates, format and channel masks supported // by the profile in our device descriptor devDesc->importAudioPort(profile); break; } } Loading Loading @@ -3196,6 +3202,8 @@ status_t AudioPolicyManager::checkOutputsForDevice(audio_devices_t device, profile_index--; } else { outputs.add(output); devDesc->importAudioPort(profile); if (deviceDistinguishesOnAddress(device)) { ALOGV("checkOutputsForDevice(): setOutputDevice(dev=0x%x, addr=%s)", device, address.string()); Loading Loading @@ -5575,16 +5583,22 @@ void AudioPolicyManager::AudioPort::toAudioPort(struct audio_port *port) const port->type = mType; unsigned int i; for (i = 0; i < mSamplingRates.size() && i < AUDIO_PORT_MAX_SAMPLING_RATES; i++) { if (mSamplingRates[i] != 0) { port->sample_rates[i] = mSamplingRates[i]; } } port->num_sample_rates = i; for (i = 0; i < mChannelMasks.size() && i < AUDIO_PORT_MAX_CHANNEL_MASKS; i++) { if (mChannelMasks[i] != 0) { port->channel_masks[i] = mChannelMasks[i]; } } port->num_channel_masks = i; for (i = 0; i < mFormats.size() && i < AUDIO_PORT_MAX_FORMATS; i++) { if (mFormats[i] != 0) { port->formats[i] = mFormats[i]; } } port->num_formats = i; ALOGV("AudioPort::toAudioPort() num gains %zu", mGains.size()); Loading @@ -5595,6 +5609,59 @@ void AudioPolicyManager::AudioPort::toAudioPort(struct audio_port *port) const port->num_gains = i; } void AudioPolicyManager::AudioPort::importAudioPort(const sp<AudioPort> port) { for (size_t k = 0 ; k < port->mSamplingRates.size() ; k++) { const uint32_t rate = port->mSamplingRates.itemAt(k); if (rate != 0) { // skip "dynamic" rates bool hasRate = false; for (size_t l = 0 ; l < mSamplingRates.size() ; l++) { if (rate == mSamplingRates.itemAt(l)) { hasRate = true; break; } } if (!hasRate) { // never import a sampling rate twice mSamplingRates.add(rate); } } } for (size_t k = 0 ; k < port->mChannelMasks.size() ; k++) { const audio_channel_mask_t mask = port->mChannelMasks.itemAt(k); if (mask != 0) { // skip "dynamic" masks bool hasMask = false; for (size_t l = 0 ; l < mChannelMasks.size() ; l++) { if (mask == mChannelMasks.itemAt(l)) { hasMask = true; break; } } if (!hasMask) { // never import a channel mask twice mChannelMasks.add(mask); } } } for (size_t k = 0 ; k < port->mFormats.size() ; k++) { const audio_format_t format = port->mFormats.itemAt(k); if (format != 0) { // skip "dynamic" formats bool hasFormat = false; for (size_t l = 0 ; l < mFormats.size() ; l++) { if (format == mFormats.itemAt(l)) { hasFormat = true; break; } } if (!hasFormat) { // never import a channel mask twice mFormats.add(format); } } } } void AudioPolicyManager::AudioPort::clearCapabilities() { mChannelMasks.clear(); mFormats.clear(); mSamplingRates.clear(); } void AudioPolicyManager::AudioPort::loadSamplingRates(char *name) { Loading
services/audiopolicy/AudioPolicyManager.h +4 −1 Original line number Diff line number Diff line Loading @@ -238,6 +238,9 @@ protected: virtual void toAudioPort(struct audio_port *port) const; void importAudioPort(const sp<AudioPort> port); void clearCapabilities(); void loadSamplingRates(char *name); void loadFormats(char *name); void loadOutChannels(char *name); Loading Loading @@ -628,7 +631,7 @@ protected: // when a device is disconnected, checks if an output is not used any more and // returns its handle if any. // transfers the audio tracks and effects from one output thread to another accordingly. status_t checkOutputsForDevice(audio_devices_t device, status_t checkOutputsForDevice(const sp<DeviceDescriptor> devDesc, audio_policy_dev_state_t state, SortedVector<audio_io_handle_t>& outputs, const String8 address); Loading