Loading services/audiopolicy/common/include/policy.h +15 −0 Original line number Diff line number Diff line Loading @@ -126,3 +126,18 @@ static inline int32_t source_priority(audio_source_t inputSource) } return 0; } /* Indicates if audio formats are equivalent when considering a match between * audio HAL supported formats and client requested formats */ static inline bool audio_formats_match(audio_format_t format1, audio_format_t format2) { if (audio_is_linear_pcm(format1) && (audio_bytes_per_sample(format1) > 2) && audio_is_linear_pcm(format2) && (audio_bytes_per_sample(format2) > 2)) { return true; } return format1 == format2; } services/audiopolicy/common/managerdefinitions/include/AudioPort.h +6 −0 Original line number Diff line number Diff line Loading @@ -110,6 +110,12 @@ public: static int compareFormats(audio_format_t format1, audio_format_t format2); // Used to select an audio HAL output stream with a sample format providing the // less degradation for a given AudioTrack sample format. static bool isBetterFormatMatch(audio_format_t newFormat, audio_format_t currentFormat, audio_format_t targetFormat); audio_module_handle_t getModuleHandle() const; uint32_t getModuleVersion() const; const char *getModuleName() const; Loading services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp +26 −0 Original line number Diff line number Diff line Loading @@ -268,6 +268,32 @@ int AudioPort::compareFormats(audio_format_t format1, audio_format_t format2) return index1 - index2; } bool AudioPort::isBetterFormatMatch(audio_format_t newFormat, audio_format_t currentFormat, audio_format_t targetFormat) { if (newFormat == currentFormat) { return false; } if (currentFormat == AUDIO_FORMAT_INVALID) { return true; } if (newFormat == targetFormat) { return true; } int currentDiffBytes = (int)audio_bytes_per_sample(targetFormat) - audio_bytes_per_sample(currentFormat); int newDiffBytes = (int)audio_bytes_per_sample(targetFormat) - audio_bytes_per_sample(newFormat); if (abs(newDiffBytes) < abs(currentDiffBytes)) { return true; } else if (abs(newDiffBytes) == abs(currentDiffBytes)) { return (newDiffBytes >= 0); } return false; } void AudioPort::pickAudioProfile(uint32_t &samplingRate, audio_channel_mask_t &channelMask, audio_format_t &format) const Loading services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -31,7 +31,7 @@ namespace android { status_t AudioProfile::checkExact(uint32_t samplingRate, audio_channel_mask_t channelMask, audio_format_t format) const { if (format == mFormat && if (audio_formats_match(format, mFormat) && (mChannelMasks.isEmpty() || supportsChannels(channelMask)) && (mSamplingRates.isEmpty() || supportsRate(samplingRate))) { return NO_ERROR; Loading services/audiopolicy/managerdefault/AudioPolicyManager.cpp +38 −17 Original line number Diff line number Diff line Loading @@ -876,7 +876,7 @@ audio_io_handle_t AudioPolicyManager::getOutputForDevice( outputDesc = desc; // reuse direct output if currently open and configured with same parameters if ((samplingRate == outputDesc->mSamplingRate) && (format == outputDesc->mFormat) && audio_formats_match(format, outputDesc->mFormat) && (channelMask == outputDesc->mChannelMask)) { outputDesc->mDirectOpenCount++; ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i)); Loading Loading @@ -927,7 +927,7 @@ audio_io_handle_t AudioPolicyManager::getOutputForDevice( // only accept an output with the requested parameters if (status != NO_ERROR || (samplingRate != 0 && samplingRate != config.sample_rate) || (format != AUDIO_FORMAT_DEFAULT && format != config.format) || (format != AUDIO_FORMAT_DEFAULT && !audio_formats_match(format, config.format)) || (channelMask != 0 && channelMask != config.channel_mask)) { ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d," "format %d %d, channelMask %04x %04x", output, samplingRate, Loading Loading @@ -992,8 +992,9 @@ audio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_h // devices (the list was previously build by getOutputsForDevice()). // The priority is as follows: // 1: the output with the highest number of requested policy flags // 2: the primary output // 3: the first output in the list // 2: the output with the bit depth the closest to the requested one // 3: the primary output // 4: the first output in the list if (outputs.size() == 0) { return 0; Loading @@ -1003,8 +1004,11 @@ audio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_h } int maxCommonFlags = 0; audio_io_handle_t outputFlags = 0; audio_io_handle_t outputPrimary = 0; audio_io_handle_t outputForFlags = 0; audio_io_handle_t outputForPrimary = 0; audio_io_handle_t outputForFormat = 0; audio_format_t bestFormat = AUDIO_FORMAT_INVALID; audio_format_t bestFormatForFlags = AUDIO_FORMAT_INVALID; for (size_t i = 0; i < outputs.size(); i++) { sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]); Loading @@ -1012,31 +1016,48 @@ audio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_h // if a valid format is specified, skip output if not compatible if (format != AUDIO_FORMAT_INVALID) { if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) { if (format != outputDesc->mFormat) { if (!audio_formats_match(format, outputDesc->mFormat)) { continue; } } else if (!audio_is_linear_pcm(format)) { continue; } if (AudioPort::isBetterFormatMatch( outputDesc->mFormat, bestFormat, format)) { outputForFormat = outputs[i]; bestFormat = outputDesc->mFormat; } } int commonFlags = popcount(outputDesc->mProfile->getFlags() & flags); if (commonFlags > maxCommonFlags) { outputFlags = outputs[i]; if (commonFlags >= maxCommonFlags) { if (commonFlags == maxCommonFlags) { if (AudioPort::isBetterFormatMatch( outputDesc->mFormat, bestFormatForFlags, format)) { outputForFlags = outputs[i]; bestFormatForFlags = outputDesc->mFormat; } } else { outputForFlags = outputs[i]; maxCommonFlags = commonFlags; bestFormatForFlags = outputDesc->mFormat; } ALOGV("selectOutput() commonFlags for output %d, %04x", outputs[i], commonFlags); } if (outputDesc->mProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) { outputPrimary = outputs[i]; outputForPrimary = outputs[i]; } } } if (outputFlags != 0) { return outputFlags; if (outputForFlags != 0) { return outputForFlags; } if (outputForFormat != 0) { return outputForFormat; } if (outputPrimary != 0) { return outputPrimary; if (outputForPrimary != 0) { return outputForPrimary; } return outputs[0]; Loading Loading @@ -1509,7 +1530,7 @@ audio_io_handle_t AudioPolicyManager::getInputForDevice(audio_devices_t device, // and current input properties are not exactly as requested. if ((desc->mSamplingRate != samplingRate || desc->mChannelMask != channelMask || desc->mFormat != format) && !audio_formats_match(desc->mFormat, format)) && (source_priority(desc->getHighestPrioritySource(false /*activeOnly*/)) < source_priority(inputSource))) { ALOGV("%s: ", __FUNCTION__); Loading Loading @@ -1544,7 +1565,7 @@ audio_io_handle_t AudioPolicyManager::getInputForDevice(audio_devices_t device, // only accept input with the exact requested set of parameters if (status != NO_ERROR || input == AUDIO_IO_HANDLE_NONE || (profileSamplingRate != config.sample_rate) || (profileFormat != config.format) || !audio_formats_match(profileFormat, config.format) || (profileChannelMask != config.channel_mask)) { ALOGW("getInputForAttr() failed opening input: samplingRate %d" ", format %d, channelMask %x", Loading Loading
services/audiopolicy/common/include/policy.h +15 −0 Original line number Diff line number Diff line Loading @@ -126,3 +126,18 @@ static inline int32_t source_priority(audio_source_t inputSource) } return 0; } /* Indicates if audio formats are equivalent when considering a match between * audio HAL supported formats and client requested formats */ static inline bool audio_formats_match(audio_format_t format1, audio_format_t format2) { if (audio_is_linear_pcm(format1) && (audio_bytes_per_sample(format1) > 2) && audio_is_linear_pcm(format2) && (audio_bytes_per_sample(format2) > 2)) { return true; } return format1 == format2; }
services/audiopolicy/common/managerdefinitions/include/AudioPort.h +6 −0 Original line number Diff line number Diff line Loading @@ -110,6 +110,12 @@ public: static int compareFormats(audio_format_t format1, audio_format_t format2); // Used to select an audio HAL output stream with a sample format providing the // less degradation for a given AudioTrack sample format. static bool isBetterFormatMatch(audio_format_t newFormat, audio_format_t currentFormat, audio_format_t targetFormat); audio_module_handle_t getModuleHandle() const; uint32_t getModuleVersion() const; const char *getModuleName() const; Loading
services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp +26 −0 Original line number Diff line number Diff line Loading @@ -268,6 +268,32 @@ int AudioPort::compareFormats(audio_format_t format1, audio_format_t format2) return index1 - index2; } bool AudioPort::isBetterFormatMatch(audio_format_t newFormat, audio_format_t currentFormat, audio_format_t targetFormat) { if (newFormat == currentFormat) { return false; } if (currentFormat == AUDIO_FORMAT_INVALID) { return true; } if (newFormat == targetFormat) { return true; } int currentDiffBytes = (int)audio_bytes_per_sample(targetFormat) - audio_bytes_per_sample(currentFormat); int newDiffBytes = (int)audio_bytes_per_sample(targetFormat) - audio_bytes_per_sample(newFormat); if (abs(newDiffBytes) < abs(currentDiffBytes)) { return true; } else if (abs(newDiffBytes) == abs(currentDiffBytes)) { return (newDiffBytes >= 0); } return false; } void AudioPort::pickAudioProfile(uint32_t &samplingRate, audio_channel_mask_t &channelMask, audio_format_t &format) const Loading
services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -31,7 +31,7 @@ namespace android { status_t AudioProfile::checkExact(uint32_t samplingRate, audio_channel_mask_t channelMask, audio_format_t format) const { if (format == mFormat && if (audio_formats_match(format, mFormat) && (mChannelMasks.isEmpty() || supportsChannels(channelMask)) && (mSamplingRates.isEmpty() || supportsRate(samplingRate))) { return NO_ERROR; Loading
services/audiopolicy/managerdefault/AudioPolicyManager.cpp +38 −17 Original line number Diff line number Diff line Loading @@ -876,7 +876,7 @@ audio_io_handle_t AudioPolicyManager::getOutputForDevice( outputDesc = desc; // reuse direct output if currently open and configured with same parameters if ((samplingRate == outputDesc->mSamplingRate) && (format == outputDesc->mFormat) && audio_formats_match(format, outputDesc->mFormat) && (channelMask == outputDesc->mChannelMask)) { outputDesc->mDirectOpenCount++; ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i)); Loading Loading @@ -927,7 +927,7 @@ audio_io_handle_t AudioPolicyManager::getOutputForDevice( // only accept an output with the requested parameters if (status != NO_ERROR || (samplingRate != 0 && samplingRate != config.sample_rate) || (format != AUDIO_FORMAT_DEFAULT && format != config.format) || (format != AUDIO_FORMAT_DEFAULT && !audio_formats_match(format, config.format)) || (channelMask != 0 && channelMask != config.channel_mask)) { ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d," "format %d %d, channelMask %04x %04x", output, samplingRate, Loading Loading @@ -992,8 +992,9 @@ audio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_h // devices (the list was previously build by getOutputsForDevice()). // The priority is as follows: // 1: the output with the highest number of requested policy flags // 2: the primary output // 3: the first output in the list // 2: the output with the bit depth the closest to the requested one // 3: the primary output // 4: the first output in the list if (outputs.size() == 0) { return 0; Loading @@ -1003,8 +1004,11 @@ audio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_h } int maxCommonFlags = 0; audio_io_handle_t outputFlags = 0; audio_io_handle_t outputPrimary = 0; audio_io_handle_t outputForFlags = 0; audio_io_handle_t outputForPrimary = 0; audio_io_handle_t outputForFormat = 0; audio_format_t bestFormat = AUDIO_FORMAT_INVALID; audio_format_t bestFormatForFlags = AUDIO_FORMAT_INVALID; for (size_t i = 0; i < outputs.size(); i++) { sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]); Loading @@ -1012,31 +1016,48 @@ audio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_h // if a valid format is specified, skip output if not compatible if (format != AUDIO_FORMAT_INVALID) { if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) { if (format != outputDesc->mFormat) { if (!audio_formats_match(format, outputDesc->mFormat)) { continue; } } else if (!audio_is_linear_pcm(format)) { continue; } if (AudioPort::isBetterFormatMatch( outputDesc->mFormat, bestFormat, format)) { outputForFormat = outputs[i]; bestFormat = outputDesc->mFormat; } } int commonFlags = popcount(outputDesc->mProfile->getFlags() & flags); if (commonFlags > maxCommonFlags) { outputFlags = outputs[i]; if (commonFlags >= maxCommonFlags) { if (commonFlags == maxCommonFlags) { if (AudioPort::isBetterFormatMatch( outputDesc->mFormat, bestFormatForFlags, format)) { outputForFlags = outputs[i]; bestFormatForFlags = outputDesc->mFormat; } } else { outputForFlags = outputs[i]; maxCommonFlags = commonFlags; bestFormatForFlags = outputDesc->mFormat; } ALOGV("selectOutput() commonFlags for output %d, %04x", outputs[i], commonFlags); } if (outputDesc->mProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) { outputPrimary = outputs[i]; outputForPrimary = outputs[i]; } } } if (outputFlags != 0) { return outputFlags; if (outputForFlags != 0) { return outputForFlags; } if (outputForFormat != 0) { return outputForFormat; } if (outputPrimary != 0) { return outputPrimary; if (outputForPrimary != 0) { return outputForPrimary; } return outputs[0]; Loading Loading @@ -1509,7 +1530,7 @@ audio_io_handle_t AudioPolicyManager::getInputForDevice(audio_devices_t device, // and current input properties are not exactly as requested. if ((desc->mSamplingRate != samplingRate || desc->mChannelMask != channelMask || desc->mFormat != format) && !audio_formats_match(desc->mFormat, format)) && (source_priority(desc->getHighestPrioritySource(false /*activeOnly*/)) < source_priority(inputSource))) { ALOGV("%s: ", __FUNCTION__); Loading Loading @@ -1544,7 +1565,7 @@ audio_io_handle_t AudioPolicyManager::getInputForDevice(audio_devices_t device, // only accept input with the exact requested set of parameters if (status != NO_ERROR || input == AUDIO_IO_HANDLE_NONE || (profileSamplingRate != config.sample_rate) || (profileFormat != config.format) || !audio_formats_match(profileFormat, config.format) || (profileChannelMask != config.channel_mask)) { ALOGW("getInputForAttr() failed opening input: samplingRate %d" ", format %d, channelMask %x", Loading