Leave AudioProfileVector only in libaudiofoundation.

Make AudioProfileVector only in libaudiofoundation. In policy part,
instead of having policy specific AudioProfileVector deriving from
AudioProfileVector in libaudiofoundation, make all the functions as
global functions. In that case, AudioPortBase does not need to be a
template class. That helps make the structure clearer.

Test: audio smoke test
Test: CTS for AudioTrack, AudioRecord, AudioManager
Test: audiopolicy_tests, AudioHostTest
Bug: 135621476
Change-Id: I36b12123cf52c3f82cef09a965403791dff74093
gugelfrei
jiabin 5 years ago
parent 861df4b5ff
commit 3e277cc0f1

@ -22,13 +22,13 @@
namespace android {
void AudioPortFoundation::toAudioPort(struct audio_port *port) const {
void AudioPortBase::toAudioPort(struct audio_port *port) const {
// TODO: update this function once audio_port structure reflects the new profile definition.
// For compatibility reason: flatening the AudioProfile into audio_port structure.
FormatSet flatenedFormats;
SampleRateSet flatenedRates;
ChannelMaskSet flatenedChannels;
for (const auto& profile : *getAudioProfileVectorBase()) {
for (const auto& profile : mProfiles) {
if (profile->isValid()) {
audio_format_t formatToExport = profile->getFormat();
const SampleRateSet &ratesToExport = profile->getSampleRates();
@ -64,13 +64,13 @@ void AudioPortFoundation::toAudioPort(struct audio_port *port) const {
}
}
void AudioPortFoundation::dump(std::string *dst, int spaces, bool verbose) const {
void AudioPortBase::dump(std::string *dst, int spaces, bool verbose) const {
if (!mName.empty()) {
dst->append(base::StringPrintf("%*s- name: %s\n", spaces, "", mName.c_str()));
}
if (verbose) {
std::string profilesStr;
getAudioProfileVectorBase()->dump(&profilesStr, spaces);
mProfiles.dump(&profilesStr, spaces);
dst->append(profilesStr);
if (mGains.size() != 0) {

@ -1,5 +1,5 @@
/*
* Copyright (C) 2015 The Android Open Source Project
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -118,14 +118,14 @@ void AudioProfile::dump(std::string *dst, int spaces) const
}
}
ssize_t AudioProfileVectorBase::add(const sp<AudioProfile> &profile)
ssize_t AudioProfileVector::add(const sp<AudioProfile> &profile)
{
ssize_t index = size();
push_back(profile);
return index;
}
void AudioProfileVectorBase::clearProfiles()
void AudioProfileVector::clearProfiles()
{
for (auto it = begin(); it != end();) {
if ((*it)->isDynamicFormat() && (*it)->hasValidFormat()) {
@ -137,7 +137,7 @@ void AudioProfileVectorBase::clearProfiles()
}
}
sp<AudioProfile> AudioProfileVectorBase::getFirstValidProfile() const
sp<AudioProfile> AudioProfileVector::getFirstValidProfile() const
{
for (const auto &profile : *this) {
if (profile->isValid()) {
@ -147,7 +147,7 @@ sp<AudioProfile> AudioProfileVectorBase::getFirstValidProfile() const
return nullptr;
}
sp<AudioProfile> AudioProfileVectorBase::getFirstValidProfileFor(audio_format_t format) const
sp<AudioProfile> AudioProfileVector::getFirstValidProfileFor(audio_format_t format) const
{
for (const auto &profile : *this) {
if (profile->isValid() && profile->getFormat() == format) {
@ -157,7 +157,7 @@ sp<AudioProfile> AudioProfileVectorBase::getFirstValidProfileFor(audio_format_t
return nullptr;
}
FormatVector AudioProfileVectorBase::getSupportedFormats() const
FormatVector AudioProfileVector::getSupportedFormats() const
{
FormatVector supportedFormats;
for (const auto &profile : *this) {
@ -168,7 +168,7 @@ FormatVector AudioProfileVectorBase::getSupportedFormats() const
return supportedFormats;
}
bool AudioProfileVectorBase::hasDynamicChannelsFor(audio_format_t format) const
bool AudioProfileVector::hasDynamicChannelsFor(audio_format_t format) const
{
for (const auto &profile : *this) {
if (profile->getFormat() == format && profile->isDynamicChannels()) {
@ -178,7 +178,7 @@ bool AudioProfileVectorBase::hasDynamicChannelsFor(audio_format_t format) const
return false;
}
bool AudioProfileVectorBase::hasDynamicFormat() const
bool AudioProfileVector::hasDynamicFormat() const
{
for (const auto &profile : *this) {
if (profile->isDynamicFormat()) {
@ -188,7 +188,7 @@ bool AudioProfileVectorBase::hasDynamicFormat() const
return false;
}
bool AudioProfileVectorBase::hasDynamicProfile() const
bool AudioProfileVector::hasDynamicProfile() const
{
for (const auto &profile : *this) {
if (profile->isDynamic()) {
@ -198,7 +198,7 @@ bool AudioProfileVectorBase::hasDynamicProfile() const
return false;
}
bool AudioProfileVectorBase::hasDynamicRateFor(audio_format_t format) const
bool AudioProfileVector::hasDynamicRateFor(audio_format_t format) const
{
for (const auto &profile : *this) {
if (profile->getFormat() == format && profile->isDynamicRate()) {
@ -208,7 +208,7 @@ bool AudioProfileVectorBase::hasDynamicRateFor(audio_format_t format) const
return false;
}
void AudioProfileVectorBase::dump(std::string *dst, int spaces) const
void AudioProfileVector::dump(std::string *dst, int spaces) const
{
dst->append(base::StringPrintf("%*s- Profiles:\n", spaces, ""));
for (size_t i = 0; i < size(); i++) {

@ -27,13 +27,13 @@
namespace android {
class AudioPortFoundation : public virtual RefBase
class AudioPortBase : public virtual RefBase
{
public:
AudioPortFoundation(const std::string& name, audio_port_type_t type, audio_port_role_t role) :
AudioPortBase(const std::string& name, audio_port_type_t type, audio_port_role_t role) :
mName(name), mType(type), mRole(role) {}
virtual ~AudioPortFoundation() = default;
virtual ~AudioPortBase() = default;
void setName(const std::string &name) { mName = name; }
const std::string &getName() const { return mName; }
@ -48,15 +48,17 @@ public:
virtual void toAudioPort(struct audio_port *port) const;
virtual AudioProfileVectorBase* getAudioProfileVectorBase() const = 0;
virtual void addAudioProfile(const sp<AudioProfile> &profile) {
getAudioProfileVectorBase()->add(profile);
mProfiles.add(profile);
}
virtual void clearAudioProfiles() {
getAudioProfileVectorBase()->clearProfiles();
mProfiles.clearProfiles();
}
bool hasValidAudioProfile() const { return getAudioProfileVectorBase()->hasValidProfile(); }
bool hasValidAudioProfile() const { return mProfiles.hasValidProfile(); }
void setAudioProfiles(const AudioProfileVector &profiles) { mProfiles = profiles; }
AudioProfileVector &getAudioProfiles() { return mProfiles; }
status_t checkGain(const struct audio_gain_config *gainConfig, int index) const {
if (index < 0 || (size_t)index >= mGains.size()) {
@ -78,31 +80,7 @@ protected:
std::string mName;
audio_port_type_t mType;
audio_port_role_t mRole;
};
template <typename ProfileVector,
typename = typename std::enable_if<std::is_base_of<
AudioProfileVectorBase, ProfileVector>::value>::type>
class AudioPortBase : public AudioPortFoundation
{
public:
AudioPortBase(const std::string& name, audio_port_type_t type, audio_port_role_t role) :
AudioPortFoundation(name, type, role) {}
virtual ~AudioPortBase() {}
AudioProfileVectorBase* getAudioProfileVectorBase() const override {
return static_cast<AudioProfileVectorBase*>(const_cast<ProfileVector*>(&mProfiles));
}
void addAudioProfile(const sp<AudioProfile> &profile) override { mProfiles.add(profile); }
void clearAudioProfiles() override { return mProfiles.clearProfiles(); }
void setAudioProfiles(const ProfileVector &profiles) { mProfiles = profiles; }
ProfileVector &getAudioProfiles() { return mProfiles; }
protected:
ProfileVector mProfiles; // AudioProfiles supported by this port (format, Rates, Channels)
AudioProfileVector mProfiles; // AudioProfiles supported by this port (format, Rates, Channels)
};

@ -77,10 +77,10 @@ private:
bool mIsDynamicRate = false;
};
class AudioProfileVectorBase : public std::vector<sp<AudioProfile> >
class AudioProfileVector : public std::vector<sp<AudioProfile>>
{
public:
virtual ~AudioProfileVectorBase() = default;
virtual ~AudioProfileVector() = default;
virtual ssize_t add(const sp<AudioProfile> &profile);

@ -33,8 +33,7 @@ namespace android {
class HwModule;
class AudioRoute;
class AudioPort : public virtual RefBase, public AudioPortBase<AudioProfileVector>,
private HandleGenerator<audio_port_handle_t>
class AudioPort : public AudioPortBase, private HandleGenerator<audio_port_handle_t>
{
public:
AudioPort(const std::string& name, audio_port_type_t type, audio_port_role_t role) :
@ -42,6 +41,10 @@ public:
virtual ~AudioPort() {}
void addAudioProfile(const sp<AudioProfile> &profile) {
addAudioProfileAndSort(mProfiles, profile);
}
virtual void setFlags(uint32_t flags)
{
//force direct flag if offload flag is set: offloading implies a direct output stream
@ -63,7 +66,7 @@ public:
virtual void importAudioPort(const sp<AudioPort>& port, bool force = false);
bool hasDynamicAudioProfile() const { return getAudioProfileVectorBase()->hasDynamicProfile(); }
bool hasDynamicAudioProfile() const { return mProfiles.hasDynamicProfile(); }
// searches for an exact match
virtual status_t checkExactAudioProfile(const struct audio_port_config *config) const;
@ -74,7 +77,8 @@ public:
audio_channel_mask_t &channelMask,
audio_format_t &format) const
{
return mProfiles.checkCompatibleProfile(samplingRate, channelMask, format, mType, mRole);
return checkCompatibleProfile(
mProfiles, samplingRate, channelMask, format, mType, mRole);
}
void pickAudioProfile(uint32_t &samplingRate,

@ -21,48 +21,47 @@
namespace android {
class AudioProfileVector : public AudioProfileVectorBase {
public:
virtual ~AudioProfileVector() = default;
void sortAudioProfiles(AudioProfileVector &audioProfileVector);
ssize_t add(const sp<AudioProfile> &profile) override;
ssize_t addAudioProfileAndSort(AudioProfileVector &audioProfileVector,
const sp<AudioProfile> &profile);
// This API is intended to be used by the policy manager once retrieving capabilities
// for a profile with dynamic format, rate and channels attributes
ssize_t addProfileFromHal(const sp<AudioProfile> &profileToAdd);
void appendProfiles(const AudioProfileVectorBase& audioProfiles) {
insert(end(), audioProfiles.begin(), audioProfiles.end());
}
// One audio profile will be added for each format supported by Audio HAL
void addProfilesForFormats(AudioProfileVector &audioProfileVector,
const FormatVector &formatVector);
status_t checkExactProfile(const uint32_t samplingRate,
audio_channel_mask_t channelMask,
audio_format_t format) const;
// This API is intended to be used by the policy manager once retrieving capabilities
// for a profile with dynamic format, rate and channels attributes
void addDynamicAudioProfileAndSort(AudioProfileVector &audioProfileVector,
const sp<AudioProfile> &profileToAdd);
status_t checkCompatibleProfile(uint32_t &samplingRate,
audio_channel_mask_t &channelMask,
audio_format_t &format,
audio_port_type_t portType,
audio_port_role_t portRole) const;
void appendAudioProfiles(AudioProfileVector &audioProfileVector,
const AudioProfileVector &audioProfileVectorToAppend);
// Assuming that this profile vector contains input profiles,
// find the best matching config from 'outputProfiles', according to
// the given preferences for audio formats and channel masks.
// Note: std::vectors are used because specialized containers for formats
// and channels can be sorted and use their own ordering.
status_t findBestMatchingOutputConfig(
const AudioProfileVector &outputProfiles,
const std::vector<audio_format_t> &preferredFormats, // order: most pref -> least pref
const std::vector<audio_channel_mask_t> &preferredOutputChannels,
bool preferHigherSamplingRates,
audio_config_base *bestOutputConfig) const;
status_t checkExactProfile(const AudioProfileVector &audioProfileVector,
const uint32_t samplingRate,
audio_channel_mask_t channelMask,
audio_format_t format);
// One audio profile will be added for each format supported by Audio HAL
void setFormats(const FormatVector &formats);
status_t checkCompatibleProfile(const AudioProfileVector &audioProfileVector,
uint32_t &samplingRate,
audio_channel_mask_t &channelMask,
audio_format_t &format,
audio_port_type_t portType,
audio_port_role_t portRole);
// Assuming that this profile vector contains input profiles,
// find the best matching config from 'outputProfiles', according to
// the given preferences for audio formats and channel masks.
// Note: std::vectors are used because specialized containers for formats
// and channels can be sorted and use their own ordering.
status_t findBestMatchingOutputConfig(
const AudioProfileVector &audioProfileVector,
const AudioProfileVector &outputProfileVector,
const std::vector<audio_format_t> &preferredFormatVector, // order: most pref -> least pref
const std::vector<audio_channel_mask_t> &preferredOutputChannelVector,
bool preferHigherSamplingRates,
audio_config_base &bestOutputConfig);
private:
sp<AudioProfile> getProfileFor(audio_format_t format) const;
void setSampleRatesFor(const SampleRateSet &sampleRates, audio_format_t format);
void setChannelsFor(const ChannelMaskSet &channelMasks, audio_format_t format);
};
} // namespace android

@ -94,9 +94,8 @@ status_t AudioPort::checkExactAudioProfile(const struct audio_port_config *confi
}
if (config_mask != 0) {
// TODO should we check sample_rate / channel_mask / format separately?
status = mProfiles.checkExactProfile(config->sample_rate,
config->channel_mask,
config->format);
status = checkExactProfile(mProfiles, config->sample_rate,
config->channel_mask, config->format);
}
return status;
}

@ -32,8 +32,141 @@
namespace android {
status_t checkExact(const sp<AudioProfile> &audioProfile, uint32_t samplingRate,
audio_channel_mask_t channelMask, audio_format_t format)
void sortAudioProfiles(AudioProfileVector &audioProfileVector) {
std::sort(audioProfileVector.begin(), audioProfileVector.end(),
[](const sp<AudioProfile> & a, const sp<AudioProfile> & b)
{
return AudioPort::compareFormats(a->getFormat(), b->getFormat()) < 0;
});
}
ssize_t addAudioProfileAndSort(AudioProfileVector &audioProfileVector,
const sp<AudioProfile> &profile)
{
ssize_t ret = audioProfileVector.add(profile);
// we sort from worst to best, so that AUDIO_FORMAT_DEFAULT is always the first entry.
sortAudioProfiles(audioProfileVector);
return ret;
}
sp<AudioProfile> getAudioProfileForFormat(const AudioProfileVector &audioProfileVector,
audio_format_t format)
{
for (const auto &profile : audioProfileVector) {
if (profile->getFormat() == format) {
return profile;
}
}
return nullptr;
}
void setSampleRatesForAudioProfiles(AudioProfileVector &audioProfileVector,
const SampleRateSet &sampleRateSet,
audio_format_t format)
{
for (const auto &profile : audioProfileVector) {
if (profile->getFormat() == format && profile->isDynamicRate()) {
if (profile->hasValidRates()) {
// Need to create a new profile with same format
sp<AudioProfile> profileToAdd = new AudioProfile(
format, profile->getChannels(), sampleRateSet);
profileToAdd->setDynamicFormat(true); // need to set to allow cleaning
addAudioProfileAndSort(audioProfileVector, profileToAdd);
} else {
profile->setSampleRates(sampleRateSet);
}
return;
}
}
}
void setChannelsForAudioProfiles(AudioProfileVector &audioProfileVector,
const ChannelMaskSet &channelMaskSet,
audio_format_t format)
{
for (const auto &profile : audioProfileVector) {
if (profile->getFormat() == format && profile->isDynamicChannels()) {
if (profile->hasValidChannels()) {
// Need to create a new profile with same format
sp<AudioProfile> profileToAdd = new AudioProfile(format, channelMaskSet,
profile->getSampleRates());
profileToAdd->setDynamicFormat(true); // need to set to allow cleaning
addAudioProfileAndSort(audioProfileVector, profileToAdd);
} else {
profile->setChannels(channelMaskSet);
}
return;
}
}
}
void addProfilesForFormats(AudioProfileVector &audioProfileVector, const FormatVector &formatVector)
{
// Only allow to change the format of dynamic profile
sp<AudioProfile> dynamicFormatProfile = getAudioProfileForFormat(
audioProfileVector, gDynamicFormat);
if (!dynamicFormatProfile) {
return;
}
for (const auto &format : formatVector) {
sp<AudioProfile> profile = new AudioProfile(format,
dynamicFormatProfile->getChannels(),
dynamicFormatProfile->getSampleRates());
profile->setDynamicFormat(true);
profile->setDynamicChannels(dynamicFormatProfile->isDynamicChannels());
profile->setDynamicRate(dynamicFormatProfile->isDynamicRate());
addAudioProfileAndSort(audioProfileVector, profile);
}
}
void addDynamicAudioProfileAndSort(AudioProfileVector &audioProfileVector,
const sp<AudioProfile> &profileToAdd)
{
// Check valid profile to add:
if (!profileToAdd->hasValidFormat()) {
ALOGW("Adding dynamic audio profile without valid format");
return;
}
if (!profileToAdd->hasValidChannels() && !profileToAdd->hasValidRates()) {
FormatVector formats;
formats.push_back(profileToAdd->getFormat());
addProfilesForFormats(audioProfileVector, FormatVector(formats));
return;
}
if (!profileToAdd->hasValidChannels() && profileToAdd->hasValidRates()) {
setSampleRatesForAudioProfiles(
audioProfileVector, profileToAdd->getSampleRates(), profileToAdd->getFormat());
return;
}
if (profileToAdd->hasValidChannels() && !profileToAdd->hasValidRates()) {
setChannelsForAudioProfiles(
audioProfileVector, profileToAdd->getChannels(), profileToAdd->getFormat());
return;
}
// Go through the list of profile to avoid duplicates
for (size_t profileIndex = 0; profileIndex < audioProfileVector.size(); profileIndex++) {
const sp<AudioProfile> &profile = audioProfileVector.at(profileIndex);
if (profile->isValid() && profile == profileToAdd) {
// Nothing to do
return;
}
}
profileToAdd->setDynamicFormat(true); // set the format as dynamic to allow removal
addAudioProfileAndSort(audioProfileVector, profileToAdd);
}
void appendAudioProfiles(AudioProfileVector &audioProfileVector,
const AudioProfileVector &audioProfileVectorToAppend)
{
audioProfileVector.insert(audioProfileVector.end(),
audioProfileVectorToAppend.begin(),
audioProfileVectorToAppend.end());
}
status_t checkExact(const sp<AudioProfile> &audioProfile,
uint32_t samplingRate,
audio_channel_mask_t channelMask,
audio_format_t format)
{
if (audio_formats_match(format, audioProfile->getFormat()) &&
audioProfile->supportsChannels(channelMask) &&
@ -173,60 +306,16 @@ status_t checkCompatibleChannelMask(const sp<AudioProfile> &audioProfile,
return bestMatch > 0 ? NO_ERROR : BAD_VALUE;
}
ssize_t AudioProfileVector::add(const sp<AudioProfile> &profile)
{
ssize_t index = size();
push_back(profile);
// we sort from worst to best, so that AUDIO_FORMAT_DEFAULT is always the first entry.
std::sort(begin(), end(),
[](const sp<AudioProfile> & a, const sp<AudioProfile> & b)
{
return AudioPort::compareFormats(a->getFormat(), b->getFormat()) < 0;
});
return index;
}
ssize_t AudioProfileVector::addProfileFromHal(const sp<AudioProfile> &profileToAdd)
{
// Check valid profile to add:
if (!profileToAdd->hasValidFormat()) {
return -1;
}
if (!profileToAdd->hasValidChannels() && !profileToAdd->hasValidRates()) {
FormatVector formats;
formats.push_back(profileToAdd->getFormat());
setFormats(FormatVector(formats));
return 0;
}
if (!profileToAdd->hasValidChannels() && profileToAdd->hasValidRates()) {
setSampleRatesFor(profileToAdd->getSampleRates(), profileToAdd->getFormat());
return 0;
}
if (profileToAdd->hasValidChannels() && !profileToAdd->hasValidRates()) {
setChannelsFor(profileToAdd->getChannels(), profileToAdd->getFormat());
return 0;
}
// Go through the list of profile to avoid duplicates
for (size_t profileIndex = 0; profileIndex < size(); profileIndex++) {
const sp<AudioProfile> &profile = at(profileIndex);
if (profile->isValid() && profile == profileToAdd) {
// Nothing to do
return profileIndex;
}
}
profileToAdd->setDynamicFormat(true); // set the format as dynamic to allow removal
return add(profileToAdd);
}
status_t AudioProfileVector::checkExactProfile(const uint32_t samplingRate,
audio_channel_mask_t channelMask,
audio_format_t format) const
status_t checkExactProfile(const AudioProfileVector& audioProfileVector,
const uint32_t samplingRate,
audio_channel_mask_t channelMask,
audio_format_t format)
{
if (empty()) {
if (audioProfileVector.empty()) {
return NO_ERROR;
}
for (const auto& profile : *this) {
for (const auto& profile : audioProfileVector) {
if (checkExact(profile, samplingRate, channelMask, format) == NO_ERROR) {
return NO_ERROR;
}
@ -234,13 +323,14 @@ status_t AudioProfileVector::checkExactProfile(const uint32_t samplingRate,
return BAD_VALUE;
}
status_t AudioProfileVector::checkCompatibleProfile(uint32_t &samplingRate,
audio_channel_mask_t &channelMask,
audio_format_t &format,
audio_port_type_t portType,
audio_port_role_t portRole) const
status_t checkCompatibleProfile(const AudioProfileVector &audioProfileVector,
uint32_t &samplingRate,
audio_channel_mask_t &channelMask,
audio_format_t &format,
audio_port_type_t portType,
audio_port_role_t portRole)
{
if (empty()) {
if (audioProfileVector.empty()) {
return NO_ERROR;
}
@ -249,8 +339,8 @@ status_t AudioProfileVector::checkCompatibleProfile(uint32_t &samplingRate,
&& audio_is_linear_pcm(format);
// iterate from best format to worst format (reverse order)
for (ssize_t i = size() - 1; i >= 0 ; --i) {
const sp<AudioProfile> profile = at(i);
for (ssize_t i = audioProfileVector.size() - 1; i >= 0 ; --i) {
const sp<AudioProfile> profile = audioProfileVector.at(i);
audio_format_t formatToCompare = profile->getFormat();
if (formatToCompare == format ||
(checkInexact
@ -306,23 +396,25 @@ std::vector<typename T::value_type> intersectAndOrder(
return result;
}
status_t AudioProfileVector::findBestMatchingOutputConfig(const AudioProfileVector& outputProfiles,
const std::vector<audio_format_t>& preferredFormats,
const std::vector<audio_channel_mask_t>& preferredOutputChannels,
bool preferHigherSamplingRates,
audio_config_base *bestOutputConfig) const
status_t findBestMatchingOutputConfig(
const AudioProfileVector &audioProfileVector,
const AudioProfileVector &outputProfileVector,
const std::vector<audio_format_t> &preferredFormatVector, // order: most pref -> least pref
const std::vector<audio_channel_mask_t> &preferredOutputChannelVector,
bool preferHigherSamplingRates,
audio_config_base &bestOutputConfig)
{
auto formats = intersectFilterAndOrder(getSupportedFormats(),
outputProfiles.getSupportedFormats(), preferredFormats);
auto formats = intersectFilterAndOrder(audioProfileVector.getSupportedFormats(),
outputProfileVector.getSupportedFormats(), preferredFormatVector);
// Pick the best compatible profile.
for (const auto& f : formats) {
sp<AudioProfile> inputProfile = getFirstValidProfileFor(f);
sp<AudioProfile> outputProfile = outputProfiles.getFirstValidProfileFor(f);
sp<AudioProfile> inputProfile = audioProfileVector.getFirstValidProfileFor(f);
sp<AudioProfile> outputProfile = outputProfileVector.getFirstValidProfileFor(f);
if (inputProfile == nullptr || outputProfile == nullptr) {
continue;
}
auto channels = intersectFilterAndOrder(asOutMask(inputProfile->getChannels()),
outputProfile->getChannels(), preferredOutputChannels);
outputProfile->getChannels(), preferredOutputChannelVector);
if (channels.empty()) {
continue;
}
@ -336,77 +428,12 @@ status_t AudioProfileVector::findBestMatchingOutputConfig(const AudioProfileVect
}
ALOGD("%s() found channel mask %#x and sample rate %d for format %#x.",
__func__, *channels.begin(), *sampleRates.begin(), f);
bestOutputConfig->format = f;
bestOutputConfig->sample_rate = *sampleRates.begin();
bestOutputConfig->channel_mask = *channels.begin();
bestOutputConfig.format = f;
bestOutputConfig.sample_rate = *sampleRates.begin();
bestOutputConfig.channel_mask = *channels.begin();
return NO_ERROR;
}
return BAD_VALUE;
}
void AudioProfileVector::setFormats(const FormatVector &formats)
{
// Only allow to change the format of dynamic profile
sp<AudioProfile> dynamicFormatProfile = getProfileFor(gDynamicFormat);
if (dynamicFormatProfile == 0) {
return;
}
for (const auto &format : formats) {
sp<AudioProfile> profile = new AudioProfile(format,
dynamicFormatProfile->getChannels(),
dynamicFormatProfile->getSampleRates());
profile->setDynamicFormat(true);
profile->setDynamicChannels(dynamicFormatProfile->isDynamicChannels());
profile->setDynamicRate(dynamicFormatProfile->isDynamicRate());
add(profile);
}
}
sp<AudioProfile> AudioProfileVector::getProfileFor(audio_format_t format) const
{
for (const auto &profile : *this) {
if (profile->getFormat() == format) {
return profile;
}
}
return nullptr;
}
void AudioProfileVector::setSampleRatesFor(
const SampleRateSet &sampleRates, audio_format_t format)
{
for (const auto &profile : *this) {
if (profile->getFormat() == format && profile->isDynamicRate()) {
if (profile->hasValidRates()) {
// Need to create a new profile with same format
sp<AudioProfile> profileToAdd = new AudioProfile(format, profile->getChannels(),
sampleRates);
profileToAdd->setDynamicFormat(true); // need to set to allow cleaning
add(profileToAdd);
} else {
profile->setSampleRates(sampleRates);
}
return;
}
}
}
void AudioProfileVector::setChannelsFor(const ChannelMaskSet &channelMasks, audio_format_t format)
{
for (const auto &profile : *this) {
if (profile->getFormat() == format && profile->isDynamicChannels()) {
if (profile->hasValidChannels()) {
// Need to create a new profile with same format
sp<AudioProfile> profileToAdd = new AudioProfile(format, channelMasks,
profile->getSampleRates());
profileToAdd->setDynamicFormat(true); // need to set to allow cleaning
add(profileToAdd);
} else {
profile->setChannels(channelMasks);
}
return;
}
}
}
} // namespace android

@ -440,6 +440,9 @@ Return<MixPortTraits::Element> MixPortTraits::deserialize(const xmlNode *child,
if (profiles.empty()) {
profiles.add(AudioProfile::createFullDynamic(gDynamicFormat));
}
// The audio profiles are in order of listed in audio policy configuration file.
// Sort audio profiles accroding to the format.
sortAudioProfiles(profiles);
mixPort->setAudioProfiles(profiles);
std::string flags = getXmlAttribute(child, Attributes::flags);
@ -524,6 +527,9 @@ Return<DevicePortTraits::Element> DevicePortTraits::deserialize(const xmlNode *c
if (profiles.empty()) {
profiles.add(AudioProfile::createFullDynamic(gDynamicFormat));
}
// The audio profiles are in order of listed in audio policy configuration file.
// Sort audio profiles accroding to the format.
sortAudioProfiles(profiles);
deviceDesc->setAudioProfiles(profiles);
// Deserialize AudioGain children

@ -1359,19 +1359,19 @@ status_t AudioPolicyManager::getBestMsdAudioProfileFor(const sp<DeviceDescriptor
// Each IOProfile represents a MixPort from audio_policy_configuration.xml
for (const auto &inProfile : inputProfiles) {
if (hwAvSync == ((inProfile->getFlags() & AUDIO_INPUT_FLAG_HW_AV_SYNC) != 0)) {
msdProfiles.appendProfiles(inProfile->getAudioProfiles());
appendAudioProfiles(msdProfiles, inProfile->getAudioProfiles());
}
}
AudioProfileVector deviceProfiles;
for (const auto &outProfile : outputProfiles) {
if (hwAvSync == ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0)) {
deviceProfiles.appendProfiles(outProfile->getAudioProfiles());
appendAudioProfiles(deviceProfiles, outProfile->getAudioProfiles());
}
}
struct audio_config_base bestSinkConfig;
status_t result = msdProfiles.findBestMatchingOutputConfig(deviceProfiles,
status_t result = findBestMatchingOutputConfig(msdProfiles, deviceProfiles,
compressedFormatsOrder, surroundChannelMasksOrder, true /*preferHigherSamplingRates*/,
&bestSinkConfig);
bestSinkConfig);
if (result != NO_ERROR) {
ALOGD("%s() no matching profiles found for device: %s, hwAvSync: %d",
__func__, outputDevice->toString().c_str(), hwAvSync);
@ -6207,7 +6207,7 @@ void AudioPolicyManager::updateAudioProfiles(const sp<DeviceDescriptor>& devDesc
|| isDeviceOfModule(devDesc, AUDIO_HARDWARE_MODULE_ID_MSD)) {
modifySurroundFormats(devDesc, &formats);
}
profiles.setFormats(formats);
addProfilesForFormats(profiles, formats);
}
for (audio_format_t format : profiles.getSupportedFormats()) {
@ -6243,7 +6243,8 @@ void AudioPolicyManager::updateAudioProfiles(const sp<DeviceDescriptor>& devDesc
}
}
}
profiles.addProfileFromHal(new AudioProfile(format, channelMasks, samplingRates));
addDynamicAudioProfileAndSort(
profiles, new AudioProfile(format, channelMasks, samplingRates));
}
}

Loading…
Cancel
Save