blob: aaaa7d16cb1b024c11dcc453649db73a83b078fb [file] [log] [blame]
François Gaffie112b0af2015-11-19 16:13:25 +01001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Mikhail Naganovfa69dc62018-07-27 09:58:58 -070017#include <set>
Mikhail Naganove50f6282018-07-26 16:20:43 -070018
jiabinb6776432019-08-19 10:10:17 -070019#define LOG_TAG "AudioProfile"
François Gaffie112b0af2015-11-19 16:13:25 +010020//#define LOG_NDEBUG 0
21
jiabinb6776432019-08-19 10:10:17 -070022#include <android-base/stringprintf.h>
jiabin4562b3b2019-07-29 10:13:34 -070023#include <media/AudioContainers.h>
jiabinb6776432019-08-19 10:10:17 -070024#include <media/AudioProfile.h>
25#include <media/TypeConverter.h>
Mikhail Naganove50f6282018-07-26 16:20:43 -070026#include <utils/Errors.h>
27
François Gaffie112b0af2015-11-19 16:13:25 +010028namespace android {
29
jiabinb6776432019-08-19 10:10:17 -070030bool operator == (const AudioProfile &left, const AudioProfile &right)
Mikhail Naganove50f6282018-07-26 16:20:43 -070031{
jiabinb6776432019-08-19 10:10:17 -070032 return (left.getFormat() == right.getFormat()) &&
33 (left.getChannels() == right.getChannels()) &&
34 (left.getSampleRates() == right.getSampleRates());
Mikhail Naganove50f6282018-07-26 16:20:43 -070035}
36
jiabinb6776432019-08-19 10:10:17 -070037// static
38sp<AudioProfile> AudioProfile::createFullDynamic(audio_format_t dynamicFormat)
Mikhail Naganov21b43362018-06-04 10:37:09 -070039{
jiabinb6776432019-08-19 10:10:17 -070040 AudioProfile* dynamicProfile = new AudioProfile(dynamicFormat,
jiabin4562b3b2019-07-29 10:13:34 -070041 ChannelMaskSet(), SampleRateSet());
Mikhail Naganov21b43362018-06-04 10:37:09 -070042 dynamicProfile->setDynamicFormat(true);
43 dynamicProfile->setDynamicChannels(true);
44 dynamicProfile->setDynamicRate(true);
45 return dynamicProfile;
46}
47
Mikhail Naganove50f6282018-07-26 16:20:43 -070048AudioProfile::AudioProfile(audio_format_t format,
49 audio_channel_mask_t channelMasks,
50 uint32_t samplingRate) :
jiabinb6776432019-08-19 10:10:17 -070051 mName(""),
Mikhail Naganove50f6282018-07-26 16:20:43 -070052 mFormat(format)
53{
jiabin4562b3b2019-07-29 10:13:34 -070054 mChannelMasks.insert(channelMasks);
55 mSamplingRates.insert(samplingRate);
Mikhail Naganove50f6282018-07-26 16:20:43 -070056}
57
58AudioProfile::AudioProfile(audio_format_t format,
jiabin4562b3b2019-07-29 10:13:34 -070059 const ChannelMaskSet &channelMasks,
60 const SampleRateSet &samplingRateCollection) :
jiabinb6776432019-08-19 10:10:17 -070061 mName(""),
Mikhail Naganove50f6282018-07-26 16:20:43 -070062 mFormat(format),
63 mChannelMasks(channelMasks),
64 mSamplingRates(samplingRateCollection) {}
65
jiabin4562b3b2019-07-29 10:13:34 -070066void AudioProfile::setChannels(const ChannelMaskSet &channelMasks)
Mikhail Naganove50f6282018-07-26 16:20:43 -070067{
68 if (mIsDynamicChannels) {
69 mChannelMasks = channelMasks;
70 }
71}
72
jiabin4562b3b2019-07-29 10:13:34 -070073void AudioProfile::setSampleRates(const SampleRateSet &sampleRates)
Mikhail Naganove50f6282018-07-26 16:20:43 -070074{
75 if (mIsDynamicRate) {
76 mSamplingRates = sampleRates;
77 }
78}
79
80void AudioProfile::clear()
81{
82 if (mIsDynamicChannels) {
83 mChannelMasks.clear();
84 }
85 if (mIsDynamicRate) {
86 mSamplingRates.clear();
87 }
88}
89
jiabinb6776432019-08-19 10:10:17 -070090void AudioProfile::dump(std::string *dst, int spaces) const
François Gaffie112b0af2015-11-19 16:13:25 +010091{
jiabinb6776432019-08-19 10:10:17 -070092 dst->append(base::StringPrintf("%s%s%s\n", mIsDynamicFormat ? "[dynamic format]" : "",
François Gaffie112b0af2015-11-19 16:13:25 +010093 mIsDynamicChannels ? "[dynamic channels]" : "",
jiabinb6776432019-08-19 10:10:17 -070094 mIsDynamicRate ? "[dynamic rates]" : ""));
François Gaffie112b0af2015-11-19 16:13:25 +010095 if (mName.length() != 0) {
jiabinb6776432019-08-19 10:10:17 -070096 dst->append(base::StringPrintf("%*s- name: %s\n", spaces, "", mName.c_str()));
François Gaffie112b0af2015-11-19 16:13:25 +010097 }
98 std::string formatLiteral;
99 if (FormatConverter::toString(mFormat, formatLiteral)) {
jiabinb6776432019-08-19 10:10:17 -0700100 dst->append(base::StringPrintf("%*s- format: %s\n", spaces, "", formatLiteral.c_str()));
François Gaffie112b0af2015-11-19 16:13:25 +0100101 }
jiabin4562b3b2019-07-29 10:13:34 -0700102 if (!mSamplingRates.empty()) {
jiabinb6776432019-08-19 10:10:17 -0700103 dst->append(base::StringPrintf("%*s- sampling rates:", spaces, ""));
jiabin4562b3b2019-07-29 10:13:34 -0700104 for (auto it = mSamplingRates.begin(); it != mSamplingRates.end();) {
jiabinb6776432019-08-19 10:10:17 -0700105 dst->append(base::StringPrintf("%d", *it));
jiabin4562b3b2019-07-29 10:13:34 -0700106 dst->append(++it == mSamplingRates.end() ? "" : ", ");
François Gaffie112b0af2015-11-19 16:13:25 +0100107 }
Andy Hungbb54e202018-10-05 11:42:02 -0700108 dst->append("\n");
François Gaffie112b0af2015-11-19 16:13:25 +0100109 }
110
jiabin4562b3b2019-07-29 10:13:34 -0700111 if (!mChannelMasks.empty()) {
jiabinb6776432019-08-19 10:10:17 -0700112 dst->append(base::StringPrintf("%*s- channel masks:", spaces, ""));
jiabin4562b3b2019-07-29 10:13:34 -0700113 for (auto it = mChannelMasks.begin(); it != mChannelMasks.end();) {
jiabinb6776432019-08-19 10:10:17 -0700114 dst->append(base::StringPrintf("0x%04x", *it));
jiabin4562b3b2019-07-29 10:13:34 -0700115 dst->append(++it == mChannelMasks.end() ? "" : ", ");
François Gaffie112b0af2015-11-19 16:13:25 +0100116 }
Andy Hungbb54e202018-10-05 11:42:02 -0700117 dst->append("\n");
François Gaffie112b0af2015-11-19 16:13:25 +0100118 }
François Gaffie112b0af2015-11-19 16:13:25 +0100119}
120
jiabinb6776432019-08-19 10:10:17 -0700121ssize_t AudioProfileVectorBase::add(const sp<AudioProfile> &profile)
Mikhail Naganove50f6282018-07-26 16:20:43 -0700122{
jiabin4562b3b2019-07-29 10:13:34 -0700123 ssize_t index = size();
124 push_back(profile);
Mikhail Naganove50f6282018-07-26 16:20:43 -0700125 return index;
126}
127
jiabinb6776432019-08-19 10:10:17 -0700128void AudioProfileVectorBase::clearProfiles()
Mikhail Naganove50f6282018-07-26 16:20:43 -0700129{
jiabin4562b3b2019-07-29 10:13:34 -0700130 for (auto it = begin(); it != end();) {
131 if ((*it)->isDynamicFormat() && (*it)->hasValidFormat()) {
132 it = erase(it);
133 } else {
134 (*it)->clear();
135 ++it;
Mikhail Naganove50f6282018-07-26 16:20:43 -0700136 }
Mikhail Naganove50f6282018-07-26 16:20:43 -0700137 }
138}
139
jiabinb6776432019-08-19 10:10:17 -0700140sp<AudioProfile> AudioProfileVectorBase::getFirstValidProfile() const
Mikhail Naganove50f6282018-07-26 16:20:43 -0700141{
jiabin4562b3b2019-07-29 10:13:34 -0700142 for (const auto &profile : *this) {
143 if (profile->isValid()) {
144 return profile;
Mikhail Naganove50f6282018-07-26 16:20:43 -0700145 }
146 }
jiabin4562b3b2019-07-29 10:13:34 -0700147 return nullptr;
Mikhail Naganove50f6282018-07-26 16:20:43 -0700148}
149
jiabinb6776432019-08-19 10:10:17 -0700150sp<AudioProfile> AudioProfileVectorBase::getFirstValidProfileFor(audio_format_t format) const
Mikhail Naganove50f6282018-07-26 16:20:43 -0700151{
jiabin4562b3b2019-07-29 10:13:34 -0700152 for (const auto &profile : *this) {
153 if (profile->isValid() && profile->getFormat() == format) {
154 return profile;
Mikhail Naganove50f6282018-07-26 16:20:43 -0700155 }
156 }
jiabin4562b3b2019-07-29 10:13:34 -0700157 return nullptr;
Mikhail Naganove50f6282018-07-26 16:20:43 -0700158}
159
jiabinb6776432019-08-19 10:10:17 -0700160FormatVector AudioProfileVectorBase::getSupportedFormats() const
Mikhail Naganove50f6282018-07-26 16:20:43 -0700161{
162 FormatVector supportedFormats;
jiabin4562b3b2019-07-29 10:13:34 -0700163 for (const auto &profile : *this) {
164 if (profile->hasValidFormat()) {
165 supportedFormats.push_back(profile->getFormat());
Mikhail Naganove50f6282018-07-26 16:20:43 -0700166 }
167 }
168 return supportedFormats;
169}
170
jiabinb6776432019-08-19 10:10:17 -0700171bool AudioProfileVectorBase::hasDynamicChannelsFor(audio_format_t format) const
Mikhail Naganove50f6282018-07-26 16:20:43 -0700172{
jiabin4562b3b2019-07-29 10:13:34 -0700173 for (const auto &profile : *this) {
Mikhail Naganove50f6282018-07-26 16:20:43 -0700174 if (profile->getFormat() == format && profile->isDynamicChannels()) {
175 return true;
176 }
177 }
178 return false;
179}
180
jiabinb6776432019-08-19 10:10:17 -0700181bool AudioProfileVectorBase::hasDynamicFormat() const
182{
183 for (const auto &profile : *this) {
184 if (profile->isDynamicFormat()) {
185 return true;
186 }
187 }
188 return false;
189}
190
191bool AudioProfileVectorBase::hasDynamicProfile() const
Mikhail Naganove50f6282018-07-26 16:20:43 -0700192{
jiabin4562b3b2019-07-29 10:13:34 -0700193 for (const auto &profile : *this) {
194 if (profile->isDynamic()) {
Mikhail Naganove50f6282018-07-26 16:20:43 -0700195 return true;
196 }
197 }
198 return false;
199}
200
jiabinb6776432019-08-19 10:10:17 -0700201bool AudioProfileVectorBase::hasDynamicRateFor(audio_format_t format) const
Mikhail Naganove50f6282018-07-26 16:20:43 -0700202{
jiabin4562b3b2019-07-29 10:13:34 -0700203 for (const auto &profile : *this) {
Mikhail Naganove50f6282018-07-26 16:20:43 -0700204 if (profile->getFormat() == format && profile->isDynamicRate()) {
205 return true;
206 }
207 }
208 return false;
209}
210
jiabinb6776432019-08-19 10:10:17 -0700211void AudioProfileVectorBase::dump(std::string *dst, int spaces) const
Mikhail Naganove50f6282018-07-26 16:20:43 -0700212{
jiabinb6776432019-08-19 10:10:17 -0700213 dst->append(base::StringPrintf("%*s- Profiles:\n", spaces, ""));
Mikhail Naganove50f6282018-07-26 16:20:43 -0700214 for (size_t i = 0; i < size(); i++) {
jiabinb6776432019-08-19 10:10:17 -0700215 dst->append(base::StringPrintf("%*sProfile %zu:", spaces + 4, "", i));
216 std::string profileStr;
217 at(i)->dump(&profileStr, spaces + 8);
218 dst->append(profileStr);
Mikhail Naganove50f6282018-07-26 16:20:43 -0700219 }
220}
221
Mikhail Naganov1b2a7942017-12-08 10:18:09 -0800222} // namespace android