blob: d6524d580152305b0c6d0a8f6bcd0a0f390fab7b [file] [log] [blame]
Songyue Han73d6d112024-06-05 17:39:06 +00001/*
2 * Copyright 2024, 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
17//#define LOG_NDEBUG 0
18#define LOG_TAG "AudioCapabilities"
19
20#include <android-base/strings.h>
21#include <android-base/properties.h>
22
23#include <media/AudioCapabilities.h>
24#include <media/CodecCapabilities.h>
25#include <media/stagefright/MediaCodecConstants.h>
26
27namespace android {
28
29const Range<int>& AudioCapabilities::getBitrateRange() const {
30 return mBitrateRange;
31}
32
33const std::vector<int>& AudioCapabilities::getSupportedSampleRates() const {
34 return mSampleRates;
35}
36
37const std::vector<Range<int>>&
38 AudioCapabilities::getSupportedSampleRateRanges() const {
39 return mSampleRateRanges;
40}
41
42int AudioCapabilities::getMaxInputChannelCount() const {
43 int overallMax = 0;
44 for (int i = mInputChannelRanges.size() - 1; i >= 0; i--) {
45 int lmax = mInputChannelRanges[i].upper();
46 if (lmax > overallMax) {
47 overallMax = lmax;
48 }
49 }
50 return overallMax;
51}
52
53int AudioCapabilities::getMinInputChannelCount() const {
54 int overallMin = MAX_INPUT_CHANNEL_COUNT;
55 for (int i = mInputChannelRanges.size() - 1; i >= 0; i--) {
56 int lmin = mInputChannelRanges[i].lower();
57 if (lmin < overallMin) {
58 overallMin = lmin;
59 }
60 }
61 return overallMin;
62}
63
64const std::vector<Range<int>>&
65 AudioCapabilities::getInputChannelCountRanges() const {
66 return mInputChannelRanges;
67}
68
69// static
70std::shared_ptr<AudioCapabilities> AudioCapabilities::Create(std::string mediaType,
71 std::vector<ProfileLevel> profLevs, const sp<AMessage> &format) {
72 std::shared_ptr<AudioCapabilities> caps(new AudioCapabilities());
73 caps->init(mediaType, profLevs, format);
74 return caps;
75}
76
77void AudioCapabilities::init(std::string mediaType, std::vector<ProfileLevel> profLevs,
78 const sp<AMessage> &format) {
79 mMediaType = mediaType;
80 mProfileLevels = profLevs;
81
82 initWithPlatformLimits();
83 applyLevelLimits();
84 parseFromInfo(format);
85}
86
87void AudioCapabilities::initWithPlatformLimits() {
88 mBitrateRange = Range<int>(0, INT_MAX);
89 mInputChannelRanges.push_back(Range<int>(1, MAX_INPUT_CHANNEL_COUNT));
90
91 const int minSampleRate = base::GetIntProperty("ro.mediacodec.min_sample_rate", 7350);
92 const int maxSampleRate = base::GetIntProperty("ro.mediacodec.max_sample_rate", 192000);
93 mSampleRateRanges.push_back(Range<int>(minSampleRate, maxSampleRate));
94}
95
96bool AudioCapabilities::supports(int sampleRate, int inputChannels) {
97 // channels and sample rates are checked orthogonally
98 if (inputChannels != 0
99 && !std::any_of(mInputChannelRanges.begin(), mInputChannelRanges.end(),
100 [inputChannels](const Range<int> &a) { return a.contains(inputChannels); })) {
101 return false;
102 }
103 if (sampleRate != 0
104 && !std::any_of(mSampleRateRanges.begin(), mSampleRateRanges.end(),
105 [sampleRate](const Range<int> &a) { return a.contains(sampleRate); })) {
106 return false;
107 }
108 return true;
109}
110
111bool AudioCapabilities::isSampleRateSupported(int sampleRate) {
112 return supports(sampleRate, 0);
113}
114
115void AudioCapabilities::limitSampleRates(std::vector<int> rates) {
116 std::vector<Range<int>> sampleRateRanges;
117 std::sort(rates.begin(), rates.end());
118 for (int rate : rates) {
119 if (supports(rate, 0 /* channels */)) {
120 sampleRateRanges.push_back(Range<int>(rate, rate));
121 }
122 }
123 mSampleRateRanges = intersectSortedDistinctRanges(mSampleRateRanges, sampleRateRanges);
124 createDiscreteSampleRates();
125}
126
127void AudioCapabilities::createDiscreteSampleRates() {
128 mSampleRates.clear();
129 for (int i = 0; i < mSampleRateRanges.size(); i++) {
130 mSampleRates.push_back(mSampleRateRanges[i].lower());
131 }
132}
133
134void AudioCapabilities::limitSampleRates(std::vector<Range<int>> rateRanges) {
135 sortDistinctRanges(&rateRanges);
136 mSampleRateRanges = intersectSortedDistinctRanges(mSampleRateRanges, rateRanges);
137 // check if all values are discrete
138 for (Range<int> range: mSampleRateRanges) {
139 if (range.lower() != range.upper()) {
140 mSampleRates.clear();
141 return;
142 }
143 }
144 createDiscreteSampleRates();
145}
146
147void AudioCapabilities::applyLevelLimits() {
148 std::vector<int> sampleRates;
149 std::optional<Range<int>> sampleRateRange;
150 std::optional<Range<int>> bitRates;
151 int maxChannels = MAX_INPUT_CHANNEL_COUNT;
152
153 // const char *mediaType = mMediaType.c_str();
154 if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_MPEG)) {
155 sampleRates = {
156 8000, 11025, 12000,
157 16000, 22050, 24000,
158 32000, 44100, 48000 };
159 bitRates = Range<int>(8000, 320000);
160 maxChannels = 2;
161 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_AMR_NB)) {
162 sampleRates = { 8000 };
163 bitRates = Range<int>(4750, 12200);
164 maxChannels = 1;
165 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_AMR_WB)) {
166 sampleRates = { 16000 };
167 bitRates = Range<int>(6600, 23850);
168 maxChannels = 1;
169 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_AAC)) {
170 sampleRates = {
171 7350, 8000,
172 11025, 12000, 16000,
173 22050, 24000, 32000,
174 44100, 48000, 64000,
175 88200, 96000 };
176 bitRates = Range<int>(8000, 510000);
177 maxChannels = 48;
178 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_VORBIS)) {
179 bitRates = Range<int>(32000, 500000);
180 sampleRateRange = Range<int>(8000, 192000);
181 maxChannels = 255;
182 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_OPUS)) {
183 bitRates = Range<int>(6000, 510000);
184 sampleRates = { 8000, 12000, 16000, 24000, 48000 };
185 maxChannels = 255;
186 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_RAW)) {
187 sampleRateRange = Range<int>(1, 192000);
188 bitRates = Range<int>(1, 10000000);
189 maxChannels = MAX_NUM_CHANNELS;
190 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_FLAC)) {
191 sampleRateRange = Range<int>(1, 655350);
192 // lossless codec, so bitrate is ignored
193 maxChannels = 255;
194 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_G711_ALAW)
195 || base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_G711_MLAW)) {
196 sampleRates = { 8000 };
197 bitRates = Range<int>(64000, 64000);
198 // platform allows multiple channels for this format
199 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_MSGSM)) {
200 sampleRates = { 8000 };
201 bitRates = Range<int>(13000, 13000);
202 maxChannels = 1;
203 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_AC3)) {
204 maxChannels = 6;
205 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_EAC3)) {
206 maxChannels = 16;
207 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_EAC3_JOC)) {
208 sampleRates = { 48000 };
209 bitRates = Range<int>(32000, 6144000);
210 maxChannels = 16;
211 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_AC4)) {
212 sampleRates = { 44100, 48000, 96000, 192000 };
213 bitRates = Range<int>(16000, 2688000);
214 maxChannels = 24;
215 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_DTS)) {
216 sampleRates = { 44100, 48000 };
217 bitRates = Range<int>(96000, 1524000);
218 maxChannels = 6;
219 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_DTS_HD)) {
220 for (ProfileLevel profileLevel: mProfileLevels) {
221 switch (profileLevel.mProfile) {
222 case DTS_HDProfileLBR:
223 sampleRates = { 22050, 24000, 44100, 48000 };
224 bitRates = Range<int>(32000, 768000);
225 break;
226 case DTS_HDProfileHRA:
227 case DTS_HDProfileMA:
228 sampleRates = { 44100, 48000, 88200, 96000, 176400, 192000 };
229 bitRates = Range<int>(96000, 24500000);
230 break;
231 default:
232 ALOGW("Unrecognized profile %d for %s", profileLevel.mProfile,
233 mMediaType.c_str());
234 mError |= ERROR_CAPABILITIES_UNRECOGNIZED;
235 sampleRates = { 44100, 48000, 88200, 96000, 176400, 192000 };
236 bitRates = Range<int>(96000, 24500000);
237 }
238 }
239 maxChannels = 8;
240 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_DTS_UHD)) {
241 for (ProfileLevel profileLevel: mProfileLevels) {
242 switch (profileLevel.mProfile) {
243 case DTS_UHDProfileP2:
244 sampleRates = { 48000 };
245 bitRates = Range<int>(96000, 768000);
246 maxChannels = 10;
247 break;
248 case DTS_UHDProfileP1:
249 sampleRates = { 44100, 48000, 88200, 96000, 176400, 192000 };
250 bitRates = Range<int>(96000, 24500000);
251 maxChannels = 32;
252 break;
253 default:
254 ALOGW("Unrecognized profile %d for %s", profileLevel.mProfile,
255 mMediaType.c_str());
256 mError |= ERROR_CAPABILITIES_UNRECOGNIZED;
257 sampleRates = { 44100, 48000, 88200, 96000, 176400, 192000 };
258 bitRates = Range<int>(96000, 24500000);
259 maxChannels = 32;
260 }
261 }
262 } else {
263 ALOGW("Unsupported mediaType %s", mMediaType.c_str());
264 mError |= ERROR_CAPABILITIES_UNSUPPORTED;
265 }
266
267 // restrict ranges
268 if (!sampleRates.empty()) {
269 limitSampleRates(sampleRates);
270 } else if (sampleRateRange) {
271 std::vector<Range<int>> rateRanges = { sampleRateRange.value() };
272 limitSampleRates(rateRanges);
273 }
274
275 Range<int> channelRange = Range<int>(1, maxChannels);
276 std::vector<Range<int>> inputChannels = { channelRange };
277 applyLimits(inputChannels, bitRates);
278}
279
280void AudioCapabilities::applyLimits(
281 const std::vector<Range<int>> &inputChannels,
282 const std::optional<Range<int>> &bitRates) {
283 // clamp & make a local copy
284 std::vector<Range<int>> inputChannelsCopy(inputChannels.size());
285 for (int i = 0; i < inputChannels.size(); i++) {
286 int lower = inputChannels[i].clamp(1);
287 int upper = inputChannels[i].clamp(MAX_INPUT_CHANNEL_COUNT);
288 inputChannelsCopy[i] = Range<int>(lower, upper);
289 }
290
291 // sort, intersect with existing, & save channel list
292 sortDistinctRanges(&inputChannelsCopy);
293 mInputChannelRanges = intersectSortedDistinctRanges(inputChannelsCopy, mInputChannelRanges);
294
295 if (bitRates) {
296 mBitrateRange = mBitrateRange.intersect(bitRates.value());
297 }
298}
299
300void AudioCapabilities::parseFromInfo(const sp<AMessage> &format) {
301 int maxInputChannels = MAX_INPUT_CHANNEL_COUNT;
302 std::vector<Range<int>> channels = { Range<int>(1, maxInputChannels) };
303 std::optional<Range<int>> bitRates = POSITIVE_INTEGERS;
304
305 AString rateAString;
306 if (format->findString("sample-rate-ranges", &rateAString)) {
307 std::vector<std::string> rateStrings = base::Split(std::string(rateAString.c_str()), ",");
308 std::vector<Range<int>> rateRanges;
309 for (std::string rateString : rateStrings) {
310 std::optional<Range<int>> rateRange = ParseIntRange(rateString);
311 if (!rateRange) {
312 continue;
313 }
314 rateRanges.push_back(rateRange.value());
315 }
316 limitSampleRates(rateRanges);
317 }
318
319 // we will prefer channel-ranges over max-channel-count
320 AString valueStr;
321 if (format->findString("channel-ranges", &valueStr)) {
322 std::vector<std::string> channelStrings = base::Split(std::string(valueStr.c_str()), ",");
323 std::vector<Range<int>> channelRanges;
324 for (std::string channelString : channelStrings) {
325 std::optional<Range<int>> channelRange = ParseIntRange(channelString);
326 if (!channelRange) {
327 continue;
328 }
329 channelRanges.push_back(channelRange.value());
330 }
331 channels = channelRanges;
332 } else if (format->findString("channel-range", &valueStr)) {
333 std::optional<Range<int>> oneRange = ParseIntRange(std::string(valueStr.c_str()));
334 if (oneRange) {
335 channels = { oneRange.value() };
336 }
337 } else if (format->findString("max-channel-count", &valueStr)) {
338 maxInputChannels = std::atoi(valueStr.c_str());
339 if (maxInputChannels == 0) {
340 channels = { Range<int>(0, 0) };
341 } else {
342 channels = { Range<int>(1, maxInputChannels) };
343 }
344 } else if ((mError & ERROR_CAPABILITIES_UNSUPPORTED) != 0) {
345 maxInputChannels = 0;
346 channels = { Range<int>(0, 0) };
347 }
348
349 if (format->findString("bitrate-range", &valueStr)) {
350 std::optional<Range<int>> parsedBitrate = ParseIntRange(valueStr.c_str());
351 if (parsedBitrate) {
352 bitRates = bitRates.value().intersect(parsedBitrate.value());
353 }
354 }
355
356 applyLimits(channels, bitRates);
357}
358
359void AudioCapabilities::getDefaultFormat(sp<AMessage> &format) {
360 // report settings that have only a single choice
361 if (mBitrateRange.lower() == mBitrateRange.upper()) {
362 format->setInt32(KEY_BIT_RATE, mBitrateRange.lower());
363 }
364 if (getMaxInputChannelCount() == 1) {
365 // mono-only format
366 format->setInt32(KEY_CHANNEL_COUNT, 1);
367 }
368 if (!mSampleRates.empty() && mSampleRates.size() == 1) {
369 format->setInt32(KEY_SAMPLE_RATE, mSampleRates[0]);
370 }
371}
372
373bool AudioCapabilities::supportsFormat(const sp<AMessage> &format) {
374 int32_t sampleRate;
375 format->findInt32(KEY_SAMPLE_RATE, &sampleRate);
376 int32_t channels;
377 format->findInt32(KEY_CHANNEL_COUNT, &channels);
378
379 if (!supports(sampleRate, channels)) {
380 return false;
381 }
382
383 if (!CodecCapabilities::SupportsBitrate(mBitrateRange, format)) {
384 return false;
385 }
386
387 // nothing to do for:
388 // KEY_CHANNEL_MASK: codecs don't get this
389 // KEY_IS_ADTS: required feature for all AAC decoders
390 return true;
391}
392
393} // namespace android