1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker * Copyright (C) 2019 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker *
4*ec779b8eSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker *
8*ec779b8eSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker *
10*ec779b8eSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker */
16*ec779b8eSAndroid Build Coastguard Worker
17*ec779b8eSAndroid Build Coastguard Worker #include <set>
18*ec779b8eSAndroid Build Coastguard Worker
19*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "AudioProfile"
20*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
21*ec779b8eSAndroid Build Coastguard Worker
22*ec779b8eSAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
23*ec779b8eSAndroid Build Coastguard Worker #include <media/AudioContainers.h>
24*ec779b8eSAndroid Build Coastguard Worker #include <media/AudioProfile.h>
25*ec779b8eSAndroid Build Coastguard Worker #include <media/TypeConverter.h>
26*ec779b8eSAndroid Build Coastguard Worker #include <utils/Errors.h>
27*ec779b8eSAndroid Build Coastguard Worker
28*ec779b8eSAndroid Build Coastguard Worker namespace android {
29*ec779b8eSAndroid Build Coastguard Worker
30*ec779b8eSAndroid Build Coastguard Worker using media::audio::common::AudioChannelLayout;
31*ec779b8eSAndroid Build Coastguard Worker
operator ==(const AudioProfile & left,const AudioProfile & right)32*ec779b8eSAndroid Build Coastguard Worker bool operator == (const AudioProfile &left, const AudioProfile &right)
33*ec779b8eSAndroid Build Coastguard Worker {
34*ec779b8eSAndroid Build Coastguard Worker return (left.getFormat() == right.getFormat()) &&
35*ec779b8eSAndroid Build Coastguard Worker (left.getChannels() == right.getChannels()) &&
36*ec779b8eSAndroid Build Coastguard Worker (left.getSampleRates() == right.getSampleRates());
37*ec779b8eSAndroid Build Coastguard Worker }
38*ec779b8eSAndroid Build Coastguard Worker
39*ec779b8eSAndroid Build Coastguard Worker // static
createFullDynamic(audio_format_t dynamicFormat)40*ec779b8eSAndroid Build Coastguard Worker sp<AudioProfile> AudioProfile::createFullDynamic(audio_format_t dynamicFormat)
41*ec779b8eSAndroid Build Coastguard Worker {
42*ec779b8eSAndroid Build Coastguard Worker AudioProfile* dynamicProfile = new AudioProfile(dynamicFormat,
43*ec779b8eSAndroid Build Coastguard Worker ChannelMaskSet(), SampleRateSet());
44*ec779b8eSAndroid Build Coastguard Worker dynamicProfile->setDynamicFormat(true);
45*ec779b8eSAndroid Build Coastguard Worker dynamicProfile->setDynamicChannels(true);
46*ec779b8eSAndroid Build Coastguard Worker dynamicProfile->setDynamicRate(true);
47*ec779b8eSAndroid Build Coastguard Worker return dynamicProfile;
48*ec779b8eSAndroid Build Coastguard Worker }
49*ec779b8eSAndroid Build Coastguard Worker
AudioProfile(audio_format_t format,audio_channel_mask_t channelMasks,uint32_t samplingRate)50*ec779b8eSAndroid Build Coastguard Worker AudioProfile::AudioProfile(audio_format_t format,
51*ec779b8eSAndroid Build Coastguard Worker audio_channel_mask_t channelMasks,
52*ec779b8eSAndroid Build Coastguard Worker uint32_t samplingRate) :
53*ec779b8eSAndroid Build Coastguard Worker mName(""),
54*ec779b8eSAndroid Build Coastguard Worker mFormat(format)
55*ec779b8eSAndroid Build Coastguard Worker {
56*ec779b8eSAndroid Build Coastguard Worker mChannelMasks.insert(channelMasks);
57*ec779b8eSAndroid Build Coastguard Worker mSamplingRates.insert(samplingRate);
58*ec779b8eSAndroid Build Coastguard Worker }
59*ec779b8eSAndroid Build Coastguard Worker
AudioProfile(audio_format_t format,const ChannelMaskSet & channelMasks,const SampleRateSet & samplingRateCollection)60*ec779b8eSAndroid Build Coastguard Worker AudioProfile::AudioProfile(audio_format_t format,
61*ec779b8eSAndroid Build Coastguard Worker const ChannelMaskSet &channelMasks,
62*ec779b8eSAndroid Build Coastguard Worker const SampleRateSet &samplingRateCollection) :
63*ec779b8eSAndroid Build Coastguard Worker AudioProfile(format, channelMasks, samplingRateCollection,
64*ec779b8eSAndroid Build Coastguard Worker AUDIO_ENCAPSULATION_TYPE_NONE) {}
65*ec779b8eSAndroid Build Coastguard Worker
AudioProfile(audio_format_t format,const ChannelMaskSet & channelMasks,const SampleRateSet & samplingRateCollection,audio_encapsulation_type_t encapsulationType)66*ec779b8eSAndroid Build Coastguard Worker AudioProfile::AudioProfile(audio_format_t format,
67*ec779b8eSAndroid Build Coastguard Worker const ChannelMaskSet &channelMasks,
68*ec779b8eSAndroid Build Coastguard Worker const SampleRateSet &samplingRateCollection,
69*ec779b8eSAndroid Build Coastguard Worker audio_encapsulation_type_t encapsulationType) :
70*ec779b8eSAndroid Build Coastguard Worker mName(""),
71*ec779b8eSAndroid Build Coastguard Worker mFormat(format),
72*ec779b8eSAndroid Build Coastguard Worker mChannelMasks(channelMasks),
73*ec779b8eSAndroid Build Coastguard Worker mSamplingRates(samplingRateCollection),
74*ec779b8eSAndroid Build Coastguard Worker mEncapsulationType(encapsulationType) {}
75*ec779b8eSAndroid Build Coastguard Worker
setChannels(const ChannelMaskSet & channelMasks)76*ec779b8eSAndroid Build Coastguard Worker void AudioProfile::setChannels(const ChannelMaskSet &channelMasks)
77*ec779b8eSAndroid Build Coastguard Worker {
78*ec779b8eSAndroid Build Coastguard Worker if (mIsDynamicChannels) {
79*ec779b8eSAndroid Build Coastguard Worker mChannelMasks = channelMasks;
80*ec779b8eSAndroid Build Coastguard Worker }
81*ec779b8eSAndroid Build Coastguard Worker }
82*ec779b8eSAndroid Build Coastguard Worker
setSampleRates(const SampleRateSet & sampleRates)83*ec779b8eSAndroid Build Coastguard Worker void AudioProfile::setSampleRates(const SampleRateSet &sampleRates)
84*ec779b8eSAndroid Build Coastguard Worker {
85*ec779b8eSAndroid Build Coastguard Worker if (mIsDynamicRate) {
86*ec779b8eSAndroid Build Coastguard Worker mSamplingRates = sampleRates;
87*ec779b8eSAndroid Build Coastguard Worker }
88*ec779b8eSAndroid Build Coastguard Worker }
89*ec779b8eSAndroid Build Coastguard Worker
clear()90*ec779b8eSAndroid Build Coastguard Worker void AudioProfile::clear()
91*ec779b8eSAndroid Build Coastguard Worker {
92*ec779b8eSAndroid Build Coastguard Worker if (mIsDynamicChannels) {
93*ec779b8eSAndroid Build Coastguard Worker mChannelMasks.clear();
94*ec779b8eSAndroid Build Coastguard Worker }
95*ec779b8eSAndroid Build Coastguard Worker if (mIsDynamicRate) {
96*ec779b8eSAndroid Build Coastguard Worker mSamplingRates.clear();
97*ec779b8eSAndroid Build Coastguard Worker }
98*ec779b8eSAndroid Build Coastguard Worker }
99*ec779b8eSAndroid Build Coastguard Worker
dump(std::string * dst,int spaces) const100*ec779b8eSAndroid Build Coastguard Worker void AudioProfile::dump(std::string *dst, int spaces) const
101*ec779b8eSAndroid Build Coastguard Worker {
102*ec779b8eSAndroid Build Coastguard Worker dst->append(base::StringPrintf("\"%s\"; ", mName.c_str()));
103*ec779b8eSAndroid Build Coastguard Worker dst->append(base::StringPrintf("%s%s%s%s", mIsDynamicFormat ? "[dynamic format]" : "",
104*ec779b8eSAndroid Build Coastguard Worker mIsDynamicChannels ? "[dynamic channels]" : "",
105*ec779b8eSAndroid Build Coastguard Worker mIsDynamicRate ? "[dynamic rates]" : "", isDynamic() ? "; " : ""));
106*ec779b8eSAndroid Build Coastguard Worker dst->append(base::StringPrintf("%s (0x%x)\n", audio_format_to_string(mFormat), mFormat));
107*ec779b8eSAndroid Build Coastguard Worker
108*ec779b8eSAndroid Build Coastguard Worker if (!mSamplingRates.empty()) {
109*ec779b8eSAndroid Build Coastguard Worker dst->append(base::StringPrintf("%*ssampling rates: ", spaces, ""));
110*ec779b8eSAndroid Build Coastguard Worker for (auto it = mSamplingRates.begin(); it != mSamplingRates.end();) {
111*ec779b8eSAndroid Build Coastguard Worker dst->append(base::StringPrintf("%d", *it));
112*ec779b8eSAndroid Build Coastguard Worker dst->append(++it == mSamplingRates.end() ? "" : ", ");
113*ec779b8eSAndroid Build Coastguard Worker }
114*ec779b8eSAndroid Build Coastguard Worker dst->append("\n");
115*ec779b8eSAndroid Build Coastguard Worker }
116*ec779b8eSAndroid Build Coastguard Worker
117*ec779b8eSAndroid Build Coastguard Worker if (!mChannelMasks.empty()) {
118*ec779b8eSAndroid Build Coastguard Worker dst->append(base::StringPrintf("%*schannel masks: ", spaces, ""));
119*ec779b8eSAndroid Build Coastguard Worker for (auto it = mChannelMasks.begin(); it != mChannelMasks.end();) {
120*ec779b8eSAndroid Build Coastguard Worker dst->append(base::StringPrintf("0x%04x", *it));
121*ec779b8eSAndroid Build Coastguard Worker dst->append(++it == mChannelMasks.end() ? "" : ", ");
122*ec779b8eSAndroid Build Coastguard Worker }
123*ec779b8eSAndroid Build Coastguard Worker dst->append("\n");
124*ec779b8eSAndroid Build Coastguard Worker }
125*ec779b8eSAndroid Build Coastguard Worker
126*ec779b8eSAndroid Build Coastguard Worker dst->append(base::StringPrintf(
127*ec779b8eSAndroid Build Coastguard Worker "%*s%s\n", spaces, "", audio_encapsulation_type_to_string(mEncapsulationType)));
128*ec779b8eSAndroid Build Coastguard Worker }
129*ec779b8eSAndroid Build Coastguard Worker
equals(const sp<AudioProfile> & other,bool ignoreDynamicFlags) const130*ec779b8eSAndroid Build Coastguard Worker bool AudioProfile::equals(const sp<AudioProfile>& other, bool ignoreDynamicFlags) const
131*ec779b8eSAndroid Build Coastguard Worker {
132*ec779b8eSAndroid Build Coastguard Worker return other != nullptr &&
133*ec779b8eSAndroid Build Coastguard Worker mName.compare(other->mName) == 0 &&
134*ec779b8eSAndroid Build Coastguard Worker mFormat == other->getFormat() &&
135*ec779b8eSAndroid Build Coastguard Worker mChannelMasks == other->getChannels() &&
136*ec779b8eSAndroid Build Coastguard Worker mSamplingRates == other->getSampleRates() &&
137*ec779b8eSAndroid Build Coastguard Worker (ignoreDynamicFlags ||
138*ec779b8eSAndroid Build Coastguard Worker (mIsDynamicFormat == other->isDynamicFormat() &&
139*ec779b8eSAndroid Build Coastguard Worker mIsDynamicChannels == other->isDynamicChannels() &&
140*ec779b8eSAndroid Build Coastguard Worker mIsDynamicRate == other->isDynamicRate())) &&
141*ec779b8eSAndroid Build Coastguard Worker mEncapsulationType == other->getEncapsulationType();
142*ec779b8eSAndroid Build Coastguard Worker }
143*ec779b8eSAndroid Build Coastguard Worker
operator =(const AudioProfile & other)144*ec779b8eSAndroid Build Coastguard Worker AudioProfile& AudioProfile::operator=(const AudioProfile& other) {
145*ec779b8eSAndroid Build Coastguard Worker mName = other.mName;
146*ec779b8eSAndroid Build Coastguard Worker mFormat = other.mFormat;
147*ec779b8eSAndroid Build Coastguard Worker mChannelMasks = other.mChannelMasks;
148*ec779b8eSAndroid Build Coastguard Worker mSamplingRates = other.mSamplingRates;
149*ec779b8eSAndroid Build Coastguard Worker mEncapsulationType = other.mEncapsulationType;
150*ec779b8eSAndroid Build Coastguard Worker mIsDynamicFormat = other.mIsDynamicFormat;
151*ec779b8eSAndroid Build Coastguard Worker mIsDynamicChannels = other.mIsDynamicChannels;
152*ec779b8eSAndroid Build Coastguard Worker mIsDynamicRate = other.mIsDynamicRate;
153*ec779b8eSAndroid Build Coastguard Worker return *this;
154*ec779b8eSAndroid Build Coastguard Worker }
155*ec779b8eSAndroid Build Coastguard Worker
156*ec779b8eSAndroid Build Coastguard Worker ConversionResult<AudioProfile::Aidl>
toParcelable(bool isInput) const157*ec779b8eSAndroid Build Coastguard Worker AudioProfile::toParcelable(bool isInput) const {
158*ec779b8eSAndroid Build Coastguard Worker media::audio::common::AudioProfile parcelable = VALUE_OR_RETURN(toCommonParcelable(isInput));
159*ec779b8eSAndroid Build Coastguard Worker media::AudioProfileSys parcelableSys;
160*ec779b8eSAndroid Build Coastguard Worker parcelableSys.isDynamicFormat = mIsDynamicFormat;
161*ec779b8eSAndroid Build Coastguard Worker parcelableSys.isDynamicChannels = mIsDynamicChannels;
162*ec779b8eSAndroid Build Coastguard Worker parcelableSys.isDynamicRate = mIsDynamicRate;
163*ec779b8eSAndroid Build Coastguard Worker return std::make_pair(parcelable, parcelableSys);
164*ec779b8eSAndroid Build Coastguard Worker }
165*ec779b8eSAndroid Build Coastguard Worker
fromParcelable(const AudioProfile::Aidl & aidl,bool isInput)166*ec779b8eSAndroid Build Coastguard Worker ConversionResult<sp<AudioProfile>> AudioProfile::fromParcelable(
167*ec779b8eSAndroid Build Coastguard Worker const AudioProfile::Aidl& aidl, bool isInput) {
168*ec779b8eSAndroid Build Coastguard Worker sp<AudioProfile> legacy = VALUE_OR_RETURN(fromCommonParcelable(aidl.first, isInput));
169*ec779b8eSAndroid Build Coastguard Worker const auto& parcelableSys = aidl.second;
170*ec779b8eSAndroid Build Coastguard Worker legacy->mIsDynamicFormat = parcelableSys.isDynamicFormat;
171*ec779b8eSAndroid Build Coastguard Worker legacy->mIsDynamicChannels = parcelableSys.isDynamicChannels;
172*ec779b8eSAndroid Build Coastguard Worker legacy->mIsDynamicRate = parcelableSys.isDynamicRate;
173*ec779b8eSAndroid Build Coastguard Worker return legacy;
174*ec779b8eSAndroid Build Coastguard Worker }
175*ec779b8eSAndroid Build Coastguard Worker
176*ec779b8eSAndroid Build Coastguard Worker ConversionResult<media::audio::common::AudioProfile>
toCommonParcelable(bool isInput) const177*ec779b8eSAndroid Build Coastguard Worker AudioProfile::toCommonParcelable(bool isInput) const {
178*ec779b8eSAndroid Build Coastguard Worker media::audio::common::AudioProfile parcelable;
179*ec779b8eSAndroid Build Coastguard Worker parcelable.name = mName;
180*ec779b8eSAndroid Build Coastguard Worker parcelable.format = VALUE_OR_RETURN(
181*ec779b8eSAndroid Build Coastguard Worker legacy2aidl_audio_format_t_AudioFormatDescription(mFormat));
182*ec779b8eSAndroid Build Coastguard Worker // Note: legacy 'audio_profile' imposes a limit on the number of
183*ec779b8eSAndroid Build Coastguard Worker // channel masks and sampling rates. That's why it's not used here
184*ec779b8eSAndroid Build Coastguard Worker // and conversions are performed directly on the fields instead
185*ec779b8eSAndroid Build Coastguard Worker // of using 'legacy2aidl_audio_profile_AudioProfile' from AidlConversion.
186*ec779b8eSAndroid Build Coastguard Worker parcelable.channelMasks = VALUE_OR_RETURN(
187*ec779b8eSAndroid Build Coastguard Worker convertContainer<std::vector<AudioChannelLayout>>(
188*ec779b8eSAndroid Build Coastguard Worker mChannelMasks,
189*ec779b8eSAndroid Build Coastguard Worker [isInput](audio_channel_mask_t m) {
190*ec779b8eSAndroid Build Coastguard Worker return legacy2aidl_audio_channel_mask_t_AudioChannelLayout(m, isInput);
191*ec779b8eSAndroid Build Coastguard Worker }));
192*ec779b8eSAndroid Build Coastguard Worker parcelable.sampleRates = VALUE_OR_RETURN(
193*ec779b8eSAndroid Build Coastguard Worker convertContainer<std::vector<int32_t>>(mSamplingRates,
194*ec779b8eSAndroid Build Coastguard Worker convertIntegral<int32_t, uint32_t>));
195*ec779b8eSAndroid Build Coastguard Worker parcelable.encapsulationType = VALUE_OR_RETURN(
196*ec779b8eSAndroid Build Coastguard Worker legacy2aidl_audio_encapsulation_type_t_AudioEncapsulationType(mEncapsulationType));
197*ec779b8eSAndroid Build Coastguard Worker return parcelable;
198*ec779b8eSAndroid Build Coastguard Worker }
199*ec779b8eSAndroid Build Coastguard Worker
fromCommonParcelable(const media::audio::common::AudioProfile & aidl,bool isInput)200*ec779b8eSAndroid Build Coastguard Worker ConversionResult<sp<AudioProfile>> AudioProfile::fromCommonParcelable(
201*ec779b8eSAndroid Build Coastguard Worker const media::audio::common::AudioProfile& aidl, bool isInput) {
202*ec779b8eSAndroid Build Coastguard Worker sp<AudioProfile> legacy = new AudioProfile();
203*ec779b8eSAndroid Build Coastguard Worker legacy->mName = aidl.name;
204*ec779b8eSAndroid Build Coastguard Worker legacy->mFormat = VALUE_OR_RETURN(
205*ec779b8eSAndroid Build Coastguard Worker aidl2legacy_AudioFormatDescription_audio_format_t(aidl.format));
206*ec779b8eSAndroid Build Coastguard Worker legacy->mChannelMasks = VALUE_OR_RETURN(
207*ec779b8eSAndroid Build Coastguard Worker convertContainer<ChannelMaskSet>(aidl.channelMasks,
208*ec779b8eSAndroid Build Coastguard Worker [isInput](const AudioChannelLayout& l) {
209*ec779b8eSAndroid Build Coastguard Worker return aidl2legacy_AudioChannelLayout_audio_channel_mask_t(l, isInput);
210*ec779b8eSAndroid Build Coastguard Worker }));
211*ec779b8eSAndroid Build Coastguard Worker legacy->mSamplingRates = VALUE_OR_RETURN(
212*ec779b8eSAndroid Build Coastguard Worker convertContainer<SampleRateSet>(aidl.sampleRates,
213*ec779b8eSAndroid Build Coastguard Worker convertIntegral<uint32_t, int32_t>));
214*ec779b8eSAndroid Build Coastguard Worker legacy->mEncapsulationType = VALUE_OR_RETURN(
215*ec779b8eSAndroid Build Coastguard Worker aidl2legacy_AudioEncapsulationType_audio_encapsulation_type_t(
216*ec779b8eSAndroid Build Coastguard Worker aidl.encapsulationType));
217*ec779b8eSAndroid Build Coastguard Worker return legacy;
218*ec779b8eSAndroid Build Coastguard Worker }
219*ec779b8eSAndroid Build Coastguard Worker
220*ec779b8eSAndroid Build Coastguard Worker ConversionResult<sp<AudioProfile>>
aidl2legacy_AudioProfile(const AudioProfile::Aidl & aidl,bool isInput)221*ec779b8eSAndroid Build Coastguard Worker aidl2legacy_AudioProfile(const AudioProfile::Aidl& aidl, bool isInput) {
222*ec779b8eSAndroid Build Coastguard Worker return AudioProfile::fromParcelable(aidl, isInput);
223*ec779b8eSAndroid Build Coastguard Worker }
224*ec779b8eSAndroid Build Coastguard Worker
225*ec779b8eSAndroid Build Coastguard Worker ConversionResult<AudioProfile::Aidl>
legacy2aidl_AudioProfile(const sp<AudioProfile> & legacy,bool isInput)226*ec779b8eSAndroid Build Coastguard Worker legacy2aidl_AudioProfile(const sp<AudioProfile>& legacy, bool isInput) {
227*ec779b8eSAndroid Build Coastguard Worker return legacy->toParcelable(isInput);
228*ec779b8eSAndroid Build Coastguard Worker }
229*ec779b8eSAndroid Build Coastguard Worker
230*ec779b8eSAndroid Build Coastguard Worker ConversionResult<sp<AudioProfile>>
aidl2legacy_AudioProfile_common(const media::audio::common::AudioProfile & aidl,bool isInput)231*ec779b8eSAndroid Build Coastguard Worker aidl2legacy_AudioProfile_common(const media::audio::common::AudioProfile& aidl, bool isInput) {
232*ec779b8eSAndroid Build Coastguard Worker return AudioProfile::fromCommonParcelable(aidl, isInput);
233*ec779b8eSAndroid Build Coastguard Worker }
234*ec779b8eSAndroid Build Coastguard Worker
235*ec779b8eSAndroid Build Coastguard Worker ConversionResult<media::audio::common::AudioProfile>
legacy2aidl_AudioProfile_common(const sp<AudioProfile> & legacy,bool isInput)236*ec779b8eSAndroid Build Coastguard Worker legacy2aidl_AudioProfile_common(const sp<AudioProfile>& legacy, bool isInput) {
237*ec779b8eSAndroid Build Coastguard Worker return legacy->toCommonParcelable(isInput);
238*ec779b8eSAndroid Build Coastguard Worker }
239*ec779b8eSAndroid Build Coastguard Worker
add(const sp<AudioProfile> & profile)240*ec779b8eSAndroid Build Coastguard Worker ssize_t AudioProfileVector::add(const sp<AudioProfile> &profile)
241*ec779b8eSAndroid Build Coastguard Worker {
242*ec779b8eSAndroid Build Coastguard Worker ssize_t index = size();
243*ec779b8eSAndroid Build Coastguard Worker push_back(profile);
244*ec779b8eSAndroid Build Coastguard Worker return index;
245*ec779b8eSAndroid Build Coastguard Worker }
246*ec779b8eSAndroid Build Coastguard Worker
clearProfiles()247*ec779b8eSAndroid Build Coastguard Worker void AudioProfileVector::clearProfiles()
248*ec779b8eSAndroid Build Coastguard Worker {
249*ec779b8eSAndroid Build Coastguard Worker for (auto it = begin(); it != end();) {
250*ec779b8eSAndroid Build Coastguard Worker if ((*it)->isDynamicFormat() && (*it)->hasValidFormat()) {
251*ec779b8eSAndroid Build Coastguard Worker it = erase(it);
252*ec779b8eSAndroid Build Coastguard Worker } else {
253*ec779b8eSAndroid Build Coastguard Worker (*it)->clear();
254*ec779b8eSAndroid Build Coastguard Worker ++it;
255*ec779b8eSAndroid Build Coastguard Worker }
256*ec779b8eSAndroid Build Coastguard Worker }
257*ec779b8eSAndroid Build Coastguard Worker }
258*ec779b8eSAndroid Build Coastguard Worker
getFirstValidProfile() const259*ec779b8eSAndroid Build Coastguard Worker sp<AudioProfile> AudioProfileVector::getFirstValidProfile() const
260*ec779b8eSAndroid Build Coastguard Worker {
261*ec779b8eSAndroid Build Coastguard Worker for (const auto &profile : *this) {
262*ec779b8eSAndroid Build Coastguard Worker if (profile->isValid()) {
263*ec779b8eSAndroid Build Coastguard Worker return profile;
264*ec779b8eSAndroid Build Coastguard Worker }
265*ec779b8eSAndroid Build Coastguard Worker }
266*ec779b8eSAndroid Build Coastguard Worker return nullptr;
267*ec779b8eSAndroid Build Coastguard Worker }
268*ec779b8eSAndroid Build Coastguard Worker
getFirstValidProfileFor(audio_format_t format) const269*ec779b8eSAndroid Build Coastguard Worker sp<AudioProfile> AudioProfileVector::getFirstValidProfileFor(audio_format_t format) const
270*ec779b8eSAndroid Build Coastguard Worker {
271*ec779b8eSAndroid Build Coastguard Worker for (const auto &profile : *this) {
272*ec779b8eSAndroid Build Coastguard Worker if (profile->isValid() && profile->getFormat() == format) {
273*ec779b8eSAndroid Build Coastguard Worker return profile;
274*ec779b8eSAndroid Build Coastguard Worker }
275*ec779b8eSAndroid Build Coastguard Worker }
276*ec779b8eSAndroid Build Coastguard Worker return nullptr;
277*ec779b8eSAndroid Build Coastguard Worker }
278*ec779b8eSAndroid Build Coastguard Worker
getSupportedFormats() const279*ec779b8eSAndroid Build Coastguard Worker FormatVector AudioProfileVector::getSupportedFormats() const
280*ec779b8eSAndroid Build Coastguard Worker {
281*ec779b8eSAndroid Build Coastguard Worker FormatVector supportedFormats;
282*ec779b8eSAndroid Build Coastguard Worker for (const auto &profile : *this) {
283*ec779b8eSAndroid Build Coastguard Worker if (profile->hasValidFormat()) {
284*ec779b8eSAndroid Build Coastguard Worker supportedFormats.push_back(profile->getFormat());
285*ec779b8eSAndroid Build Coastguard Worker }
286*ec779b8eSAndroid Build Coastguard Worker }
287*ec779b8eSAndroid Build Coastguard Worker return supportedFormats;
288*ec779b8eSAndroid Build Coastguard Worker }
289*ec779b8eSAndroid Build Coastguard Worker
hasDynamicChannelsFor(audio_format_t format) const290*ec779b8eSAndroid Build Coastguard Worker bool AudioProfileVector::hasDynamicChannelsFor(audio_format_t format) const
291*ec779b8eSAndroid Build Coastguard Worker {
292*ec779b8eSAndroid Build Coastguard Worker for (const auto &profile : *this) {
293*ec779b8eSAndroid Build Coastguard Worker if (profile->getFormat() == format && profile->isDynamicChannels()) {
294*ec779b8eSAndroid Build Coastguard Worker return true;
295*ec779b8eSAndroid Build Coastguard Worker }
296*ec779b8eSAndroid Build Coastguard Worker }
297*ec779b8eSAndroid Build Coastguard Worker return false;
298*ec779b8eSAndroid Build Coastguard Worker }
299*ec779b8eSAndroid Build Coastguard Worker
hasDynamicFormat() const300*ec779b8eSAndroid Build Coastguard Worker bool AudioProfileVector::hasDynamicFormat() const
301*ec779b8eSAndroid Build Coastguard Worker {
302*ec779b8eSAndroid Build Coastguard Worker for (const auto &profile : *this) {
303*ec779b8eSAndroid Build Coastguard Worker if (profile->isDynamicFormat()) {
304*ec779b8eSAndroid Build Coastguard Worker return true;
305*ec779b8eSAndroid Build Coastguard Worker }
306*ec779b8eSAndroid Build Coastguard Worker }
307*ec779b8eSAndroid Build Coastguard Worker return false;
308*ec779b8eSAndroid Build Coastguard Worker }
309*ec779b8eSAndroid Build Coastguard Worker
hasDynamicProfile() const310*ec779b8eSAndroid Build Coastguard Worker bool AudioProfileVector::hasDynamicProfile() const
311*ec779b8eSAndroid Build Coastguard Worker {
312*ec779b8eSAndroid Build Coastguard Worker for (const auto &profile : *this) {
313*ec779b8eSAndroid Build Coastguard Worker if (profile->isDynamic()) {
314*ec779b8eSAndroid Build Coastguard Worker return true;
315*ec779b8eSAndroid Build Coastguard Worker }
316*ec779b8eSAndroid Build Coastguard Worker }
317*ec779b8eSAndroid Build Coastguard Worker return false;
318*ec779b8eSAndroid Build Coastguard Worker }
319*ec779b8eSAndroid Build Coastguard Worker
hasDynamicRateFor(audio_format_t format) const320*ec779b8eSAndroid Build Coastguard Worker bool AudioProfileVector::hasDynamicRateFor(audio_format_t format) const
321*ec779b8eSAndroid Build Coastguard Worker {
322*ec779b8eSAndroid Build Coastguard Worker for (const auto &profile : *this) {
323*ec779b8eSAndroid Build Coastguard Worker if (profile->getFormat() == format && profile->isDynamicRate()) {
324*ec779b8eSAndroid Build Coastguard Worker return true;
325*ec779b8eSAndroid Build Coastguard Worker }
326*ec779b8eSAndroid Build Coastguard Worker }
327*ec779b8eSAndroid Build Coastguard Worker return false;
328*ec779b8eSAndroid Build Coastguard Worker }
329*ec779b8eSAndroid Build Coastguard Worker
getSampleRatesFor(audio_format_t format) const330*ec779b8eSAndroid Build Coastguard Worker const SampleRateSet AudioProfileVector::getSampleRatesFor(audio_format_t format) const {
331*ec779b8eSAndroid Build Coastguard Worker for (const auto& profile : *this) {
332*ec779b8eSAndroid Build Coastguard Worker if (profile->getFormat() == format) {
333*ec779b8eSAndroid Build Coastguard Worker return profile->getSampleRates();
334*ec779b8eSAndroid Build Coastguard Worker }
335*ec779b8eSAndroid Build Coastguard Worker }
336*ec779b8eSAndroid Build Coastguard Worker return {};
337*ec779b8eSAndroid Build Coastguard Worker }
338*ec779b8eSAndroid Build Coastguard Worker
getChannelMasksFor(audio_format_t format) const339*ec779b8eSAndroid Build Coastguard Worker const ChannelMaskSet AudioProfileVector::getChannelMasksFor(audio_format_t format) const {
340*ec779b8eSAndroid Build Coastguard Worker for (const auto& profile : *this) {
341*ec779b8eSAndroid Build Coastguard Worker if (profile->getFormat() == format) {
342*ec779b8eSAndroid Build Coastguard Worker return profile->getChannels();
343*ec779b8eSAndroid Build Coastguard Worker }
344*ec779b8eSAndroid Build Coastguard Worker }
345*ec779b8eSAndroid Build Coastguard Worker return {};
346*ec779b8eSAndroid Build Coastguard Worker }
347*ec779b8eSAndroid Build Coastguard Worker
contains(const sp<AudioProfile> & profile,bool ignoreDynamicFlags) const348*ec779b8eSAndroid Build Coastguard Worker bool AudioProfileVector::contains(const sp<AudioProfile>& profile, bool ignoreDynamicFlags) const
349*ec779b8eSAndroid Build Coastguard Worker {
350*ec779b8eSAndroid Build Coastguard Worker for (const auto& audioProfile : *this) {
351*ec779b8eSAndroid Build Coastguard Worker if (audioProfile->equals(profile, ignoreDynamicFlags)) {
352*ec779b8eSAndroid Build Coastguard Worker return true;
353*ec779b8eSAndroid Build Coastguard Worker }
354*ec779b8eSAndroid Build Coastguard Worker }
355*ec779b8eSAndroid Build Coastguard Worker return false;
356*ec779b8eSAndroid Build Coastguard Worker }
357*ec779b8eSAndroid Build Coastguard Worker
dump(std::string * dst,int spaces) const358*ec779b8eSAndroid Build Coastguard Worker void AudioProfileVector::dump(std::string *dst, int spaces) const
359*ec779b8eSAndroid Build Coastguard Worker {
360*ec779b8eSAndroid Build Coastguard Worker dst->append(base::StringPrintf("%*s- Profiles (%zu):\n", spaces - 2, "", size()));
361*ec779b8eSAndroid Build Coastguard Worker for (size_t i = 0; i < size(); i++) {
362*ec779b8eSAndroid Build Coastguard Worker const std::string prefix = base::StringPrintf("%*s %zu. ", spaces, "", i + 1);
363*ec779b8eSAndroid Build Coastguard Worker dst->append(prefix);
364*ec779b8eSAndroid Build Coastguard Worker std::string profileStr;
365*ec779b8eSAndroid Build Coastguard Worker at(i)->dump(&profileStr, prefix.size());
366*ec779b8eSAndroid Build Coastguard Worker dst->append(profileStr);
367*ec779b8eSAndroid Build Coastguard Worker }
368*ec779b8eSAndroid Build Coastguard Worker }
369*ec779b8eSAndroid Build Coastguard Worker
equals(const AudioProfileVector & other) const370*ec779b8eSAndroid Build Coastguard Worker bool AudioProfileVector::equals(const AudioProfileVector& other) const
371*ec779b8eSAndroid Build Coastguard Worker {
372*ec779b8eSAndroid Build Coastguard Worker return std::equal(begin(), end(), other.begin(), other.end(),
373*ec779b8eSAndroid Build Coastguard Worker [](const sp<AudioProfile>& left, const sp<AudioProfile>& right) {
374*ec779b8eSAndroid Build Coastguard Worker return left->equals(right);
375*ec779b8eSAndroid Build Coastguard Worker });
376*ec779b8eSAndroid Build Coastguard Worker }
377*ec779b8eSAndroid Build Coastguard Worker
addAllValidProfiles(const AudioProfileVector & audioProfiles)378*ec779b8eSAndroid Build Coastguard Worker void AudioProfileVector::addAllValidProfiles(const AudioProfileVector& audioProfiles) {
379*ec779b8eSAndroid Build Coastguard Worker for (const auto& audioProfile : audioProfiles) {
380*ec779b8eSAndroid Build Coastguard Worker if (audioProfile->isValid() && !contains(audioProfile, true /*ignoreDynamicFlags*/)) {
381*ec779b8eSAndroid Build Coastguard Worker add(audioProfile);
382*ec779b8eSAndroid Build Coastguard Worker }
383*ec779b8eSAndroid Build Coastguard Worker }
384*ec779b8eSAndroid Build Coastguard Worker }
385*ec779b8eSAndroid Build Coastguard Worker
getSupportedChannelMasks() const386*ec779b8eSAndroid Build Coastguard Worker ChannelMaskSet AudioProfileVector::getSupportedChannelMasks() const {
387*ec779b8eSAndroid Build Coastguard Worker ChannelMaskSet channelMasks;
388*ec779b8eSAndroid Build Coastguard Worker for (const auto& profile : *this) {
389*ec779b8eSAndroid Build Coastguard Worker if (profile->isValid()) {
390*ec779b8eSAndroid Build Coastguard Worker channelMasks.insert(profile->getChannels().begin(), profile->getChannels().end());
391*ec779b8eSAndroid Build Coastguard Worker }
392*ec779b8eSAndroid Build Coastguard Worker }
393*ec779b8eSAndroid Build Coastguard Worker return channelMasks;
394*ec779b8eSAndroid Build Coastguard Worker }
395*ec779b8eSAndroid Build Coastguard Worker
396*ec779b8eSAndroid Build Coastguard Worker ConversionResult<AudioProfileVector>
aidl2legacy_AudioProfileVector(const AudioProfileVector::Aidl & aidl,bool isInput)397*ec779b8eSAndroid Build Coastguard Worker aidl2legacy_AudioProfileVector(const AudioProfileVector::Aidl& aidl, bool isInput) {
398*ec779b8eSAndroid Build Coastguard Worker return convertContainers<AudioProfileVector>(aidl.first, aidl.second,
399*ec779b8eSAndroid Build Coastguard Worker [isInput](const media::audio::common::AudioProfile& p,
400*ec779b8eSAndroid Build Coastguard Worker const media::AudioProfileSys& ps) {
401*ec779b8eSAndroid Build Coastguard Worker return aidl2legacy_AudioProfile(std::make_pair(p, ps), isInput);
402*ec779b8eSAndroid Build Coastguard Worker });
403*ec779b8eSAndroid Build Coastguard Worker }
404*ec779b8eSAndroid Build Coastguard Worker
405*ec779b8eSAndroid Build Coastguard Worker ConversionResult<AudioProfileVector::Aidl>
legacy2aidl_AudioProfileVector(const AudioProfileVector & legacy,bool isInput)406*ec779b8eSAndroid Build Coastguard Worker legacy2aidl_AudioProfileVector(const AudioProfileVector& legacy, bool isInput) {
407*ec779b8eSAndroid Build Coastguard Worker return convertContainerSplit<
408*ec779b8eSAndroid Build Coastguard Worker std::vector<media::audio::common::AudioProfile>,
409*ec779b8eSAndroid Build Coastguard Worker std::vector<media::AudioProfileSys>>(legacy,
410*ec779b8eSAndroid Build Coastguard Worker [isInput](const sp<AudioProfile>& p) {
411*ec779b8eSAndroid Build Coastguard Worker return legacy2aidl_AudioProfile(p, isInput);
412*ec779b8eSAndroid Build Coastguard Worker });
413*ec779b8eSAndroid Build Coastguard Worker }
414*ec779b8eSAndroid Build Coastguard Worker
intersectAudioProfiles(const AudioProfileVector & profiles1,const AudioProfileVector & profiles2)415*ec779b8eSAndroid Build Coastguard Worker AudioProfileVector intersectAudioProfiles(const AudioProfileVector& profiles1,
416*ec779b8eSAndroid Build Coastguard Worker const AudioProfileVector& profiles2)
417*ec779b8eSAndroid Build Coastguard Worker {
418*ec779b8eSAndroid Build Coastguard Worker std::map<audio_format_t, std::pair<ChannelMaskSet, SampleRateSet>> infos2;
419*ec779b8eSAndroid Build Coastguard Worker for (const auto& profile : profiles2) {
420*ec779b8eSAndroid Build Coastguard Worker infos2.emplace(profile->getFormat(),
421*ec779b8eSAndroid Build Coastguard Worker std::make_pair(profile->getChannels(), profile->getSampleRates()));
422*ec779b8eSAndroid Build Coastguard Worker }
423*ec779b8eSAndroid Build Coastguard Worker AudioProfileVector profiles;
424*ec779b8eSAndroid Build Coastguard Worker for (const auto& profile : profiles1) {
425*ec779b8eSAndroid Build Coastguard Worker const auto it = infos2.find(profile->getFormat());
426*ec779b8eSAndroid Build Coastguard Worker if (it == infos2.end()) {
427*ec779b8eSAndroid Build Coastguard Worker continue;
428*ec779b8eSAndroid Build Coastguard Worker }
429*ec779b8eSAndroid Build Coastguard Worker ChannelMaskSet channelMasks = SetIntersection(profile->getChannels(), it->second.first);
430*ec779b8eSAndroid Build Coastguard Worker if (channelMasks.empty()) {
431*ec779b8eSAndroid Build Coastguard Worker continue;
432*ec779b8eSAndroid Build Coastguard Worker }
433*ec779b8eSAndroid Build Coastguard Worker SampleRateSet sampleRates = SetIntersection(profile->getSampleRates(), it->second.second);
434*ec779b8eSAndroid Build Coastguard Worker if (sampleRates.empty()) {
435*ec779b8eSAndroid Build Coastguard Worker continue;
436*ec779b8eSAndroid Build Coastguard Worker }
437*ec779b8eSAndroid Build Coastguard Worker profiles.push_back(new AudioProfile(profile->getFormat(), channelMasks, sampleRates));
438*ec779b8eSAndroid Build Coastguard Worker }
439*ec779b8eSAndroid Build Coastguard Worker return profiles;
440*ec779b8eSAndroid Build Coastguard Worker }
441*ec779b8eSAndroid Build Coastguard Worker
442*ec779b8eSAndroid Build Coastguard Worker } // namespace android
443