blob: 1a923076c6fcbc998a0039f0399fb3096d0296ef [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
Songyue Hanad936af2024-10-14 23:53:58 +000029const Range<int32_t>& AudioCapabilities::getBitrateRange() const {
Songyue Han73d6d112024-06-05 17:39:06 +000030 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;
Songyue Han1f93c942024-07-30 19:15:13 +000081 mError = 0;
Songyue Han73d6d112024-06-05 17:39:06 +000082
83 initWithPlatformLimits();
84 applyLevelLimits();
85 parseFromInfo(format);
86}
87
88void AudioCapabilities::initWithPlatformLimits() {
Songyue Hanad936af2024-10-14 23:53:58 +000089 mBitrateRange = Range<int>(0, INT32_MAX);
Songyue Han73d6d112024-06-05 17:39:06 +000090 mInputChannelRanges.push_back(Range<int>(1, MAX_INPUT_CHANNEL_COUNT));
91
92 const int minSampleRate = base::GetIntProperty("ro.mediacodec.min_sample_rate", 7350);
93 const int maxSampleRate = base::GetIntProperty("ro.mediacodec.max_sample_rate", 192000);
94 mSampleRateRanges.push_back(Range<int>(minSampleRate, maxSampleRate));
95}
96
Songyue Han84ad37f2024-10-08 20:24:26 +000097bool AudioCapabilities::supports(std::optional<int> sampleRate,
98 std::optional<int> inputChannels) {
Songyue Han73d6d112024-06-05 17:39:06 +000099 // channels and sample rates are checked orthogonally
Songyue Han84ad37f2024-10-08 20:24:26 +0000100 if (inputChannels
Songyue Han73d6d112024-06-05 17:39:06 +0000101 && !std::any_of(mInputChannelRanges.begin(), mInputChannelRanges.end(),
Songyue Han84ad37f2024-10-08 20:24:26 +0000102 [inputChannels](const Range<int> &a) { return a.contains(inputChannels.value()); })) {
Songyue Han73d6d112024-06-05 17:39:06 +0000103 return false;
104 }
Songyue Han84ad37f2024-10-08 20:24:26 +0000105 if (sampleRate
Songyue Han73d6d112024-06-05 17:39:06 +0000106 && !std::any_of(mSampleRateRanges.begin(), mSampleRateRanges.end(),
Songyue Han84ad37f2024-10-08 20:24:26 +0000107 [sampleRate](const Range<int> &a) { return a.contains(sampleRate.value()); })) {
Songyue Han73d6d112024-06-05 17:39:06 +0000108 return false;
109 }
110 return true;
111}
112
113bool AudioCapabilities::isSampleRateSupported(int sampleRate) {
Songyue Han84ad37f2024-10-08 20:24:26 +0000114 return supports(std::make_optional<int>(sampleRate), std::nullopt);
Songyue Han73d6d112024-06-05 17:39:06 +0000115}
116
117void AudioCapabilities::limitSampleRates(std::vector<int> rates) {
118 std::vector<Range<int>> sampleRateRanges;
119 std::sort(rates.begin(), rates.end());
120 for (int rate : rates) {
Songyue Han84ad37f2024-10-08 20:24:26 +0000121 if (supports(std::make_optional<int>(rate), std::nullopt /* channels */)) {
Songyue Han73d6d112024-06-05 17:39:06 +0000122 sampleRateRanges.push_back(Range<int>(rate, rate));
123 }
124 }
125 mSampleRateRanges = intersectSortedDistinctRanges(mSampleRateRanges, sampleRateRanges);
126 createDiscreteSampleRates();
127}
128
129void AudioCapabilities::createDiscreteSampleRates() {
130 mSampleRates.clear();
131 for (int i = 0; i < mSampleRateRanges.size(); i++) {
132 mSampleRates.push_back(mSampleRateRanges[i].lower());
133 }
134}
135
136void AudioCapabilities::limitSampleRates(std::vector<Range<int>> rateRanges) {
137 sortDistinctRanges(&rateRanges);
138 mSampleRateRanges = intersectSortedDistinctRanges(mSampleRateRanges, rateRanges);
139 // check if all values are discrete
140 for (Range<int> range: mSampleRateRanges) {
141 if (range.lower() != range.upper()) {
142 mSampleRates.clear();
143 return;
144 }
145 }
146 createDiscreteSampleRates();
147}
148
149void AudioCapabilities::applyLevelLimits() {
150 std::vector<int> sampleRates;
151 std::optional<Range<int>> sampleRateRange;
152 std::optional<Range<int>> bitRates;
153 int maxChannels = MAX_INPUT_CHANNEL_COUNT;
154
155 // const char *mediaType = mMediaType.c_str();
156 if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_MPEG)) {
157 sampleRates = {
158 8000, 11025, 12000,
159 16000, 22050, 24000,
160 32000, 44100, 48000 };
161 bitRates = Range<int>(8000, 320000);
162 maxChannels = 2;
163 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_AMR_NB)) {
164 sampleRates = { 8000 };
165 bitRates = Range<int>(4750, 12200);
166 maxChannels = 1;
167 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_AMR_WB)) {
168 sampleRates = { 16000 };
169 bitRates = Range<int>(6600, 23850);
170 maxChannels = 1;
171 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_AAC)) {
172 sampleRates = {
173 7350, 8000,
174 11025, 12000, 16000,
175 22050, 24000, 32000,
176 44100, 48000, 64000,
177 88200, 96000 };
178 bitRates = Range<int>(8000, 510000);
179 maxChannels = 48;
180 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_VORBIS)) {
181 bitRates = Range<int>(32000, 500000);
182 sampleRateRange = Range<int>(8000, 192000);
183 maxChannels = 255;
184 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_OPUS)) {
185 bitRates = Range<int>(6000, 510000);
186 sampleRates = { 8000, 12000, 16000, 24000, 48000 };
187 maxChannels = 255;
188 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_RAW)) {
189 sampleRateRange = Range<int>(1, 192000);
190 bitRates = Range<int>(1, 10000000);
191 maxChannels = MAX_NUM_CHANNELS;
192 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_FLAC)) {
193 sampleRateRange = Range<int>(1, 655350);
194 // lossless codec, so bitrate is ignored
195 maxChannels = 255;
196 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_G711_ALAW)
197 || base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_G711_MLAW)) {
198 sampleRates = { 8000 };
199 bitRates = Range<int>(64000, 64000);
200 // platform allows multiple channels for this format
201 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_MSGSM)) {
202 sampleRates = { 8000 };
203 bitRates = Range<int>(13000, 13000);
204 maxChannels = 1;
205 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_AC3)) {
206 maxChannels = 6;
207 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_EAC3)) {
208 maxChannels = 16;
209 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_EAC3_JOC)) {
210 sampleRates = { 48000 };
211 bitRates = Range<int>(32000, 6144000);
212 maxChannels = 16;
213 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_AC4)) {
214 sampleRates = { 44100, 48000, 96000, 192000 };
215 bitRates = Range<int>(16000, 2688000);
216 maxChannels = 24;
217 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_DTS)) {
218 sampleRates = { 44100, 48000 };
219 bitRates = Range<int>(96000, 1524000);
220 maxChannels = 6;
221 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_DTS_HD)) {
222 for (ProfileLevel profileLevel: mProfileLevels) {
223 switch (profileLevel.mProfile) {
224 case DTS_HDProfileLBR:
225 sampleRates = { 22050, 24000, 44100, 48000 };
226 bitRates = Range<int>(32000, 768000);
227 break;
228 case DTS_HDProfileHRA:
229 case DTS_HDProfileMA:
230 sampleRates = { 44100, 48000, 88200, 96000, 176400, 192000 };
231 bitRates = Range<int>(96000, 24500000);
232 break;
233 default:
234 ALOGW("Unrecognized profile %d for %s", profileLevel.mProfile,
235 mMediaType.c_str());
236 mError |= ERROR_CAPABILITIES_UNRECOGNIZED;
237 sampleRates = { 44100, 48000, 88200, 96000, 176400, 192000 };
238 bitRates = Range<int>(96000, 24500000);
239 }
240 }
241 maxChannels = 8;
242 } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_AUDIO_DTS_UHD)) {
243 for (ProfileLevel profileLevel: mProfileLevels) {
244 switch (profileLevel.mProfile) {
245 case DTS_UHDProfileP2:
246 sampleRates = { 48000 };
247 bitRates = Range<int>(96000, 768000);
248 maxChannels = 10;
249 break;
250 case DTS_UHDProfileP1:
251 sampleRates = { 44100, 48000, 88200, 96000, 176400, 192000 };
252 bitRates = Range<int>(96000, 24500000);
253 maxChannels = 32;
254 break;
255 default:
256 ALOGW("Unrecognized profile %d for %s", profileLevel.mProfile,
257 mMediaType.c_str());
258 mError |= ERROR_CAPABILITIES_UNRECOGNIZED;
259 sampleRates = { 44100, 48000, 88200, 96000, 176400, 192000 };
260 bitRates = Range<int>(96000, 24500000);
261 maxChannels = 32;
262 }
263 }
264 } else {
265 ALOGW("Unsupported mediaType %s", mMediaType.c_str());
266 mError |= ERROR_CAPABILITIES_UNSUPPORTED;
267 }
268
269 // restrict ranges
270 if (!sampleRates.empty()) {
271 limitSampleRates(sampleRates);
272 } else if (sampleRateRange) {
273 std::vector<Range<int>> rateRanges = { sampleRateRange.value() };
274 limitSampleRates(rateRanges);
275 }
276
277 Range<int> channelRange = Range<int>(1, maxChannels);
278 std::vector<Range<int>> inputChannels = { channelRange };
279 applyLimits(inputChannels, bitRates);
280}
281
282void AudioCapabilities::applyLimits(
283 const std::vector<Range<int>> &inputChannels,
Songyue Hanad936af2024-10-14 23:53:58 +0000284 const std::optional<Range<int32_t>> &bitRates) {
Songyue Han73d6d112024-06-05 17:39:06 +0000285 // clamp & make a local copy
286 std::vector<Range<int>> inputChannelsCopy(inputChannels.size());
287 for (int i = 0; i < inputChannels.size(); i++) {
288 int lower = inputChannels[i].clamp(1);
289 int upper = inputChannels[i].clamp(MAX_INPUT_CHANNEL_COUNT);
290 inputChannelsCopy[i] = Range<int>(lower, upper);
291 }
292
293 // sort, intersect with existing, & save channel list
294 sortDistinctRanges(&inputChannelsCopy);
295 mInputChannelRanges = intersectSortedDistinctRanges(inputChannelsCopy, mInputChannelRanges);
296
297 if (bitRates) {
298 mBitrateRange = mBitrateRange.intersect(bitRates.value());
299 }
300}
301
302void AudioCapabilities::parseFromInfo(const sp<AMessage> &format) {
303 int maxInputChannels = MAX_INPUT_CHANNEL_COUNT;
304 std::vector<Range<int>> channels = { Range<int>(1, maxInputChannels) };
Songyue Hanad936af2024-10-14 23:53:58 +0000305 std::optional<Range<int32_t>> bitRates = POSITIVE_INT32;
Songyue Han73d6d112024-06-05 17:39:06 +0000306
307 AString rateAString;
308 if (format->findString("sample-rate-ranges", &rateAString)) {
309 std::vector<std::string> rateStrings = base::Split(std::string(rateAString.c_str()), ",");
310 std::vector<Range<int>> rateRanges;
311 for (std::string rateString : rateStrings) {
312 std::optional<Range<int>> rateRange = ParseIntRange(rateString);
313 if (!rateRange) {
314 continue;
315 }
316 rateRanges.push_back(rateRange.value());
317 }
318 limitSampleRates(rateRanges);
319 }
320
321 // we will prefer channel-ranges over max-channel-count
322 AString valueStr;
323 if (format->findString("channel-ranges", &valueStr)) {
324 std::vector<std::string> channelStrings = base::Split(std::string(valueStr.c_str()), ",");
325 std::vector<Range<int>> channelRanges;
326 for (std::string channelString : channelStrings) {
327 std::optional<Range<int>> channelRange = ParseIntRange(channelString);
328 if (!channelRange) {
329 continue;
330 }
331 channelRanges.push_back(channelRange.value());
332 }
333 channels = channelRanges;
334 } else if (format->findString("channel-range", &valueStr)) {
335 std::optional<Range<int>> oneRange = ParseIntRange(std::string(valueStr.c_str()));
336 if (oneRange) {
337 channels = { oneRange.value() };
338 }
339 } else if (format->findString("max-channel-count", &valueStr)) {
340 maxInputChannels = std::atoi(valueStr.c_str());
341 if (maxInputChannels == 0) {
342 channels = { Range<int>(0, 0) };
343 } else {
344 channels = { Range<int>(1, maxInputChannels) };
345 }
346 } else if ((mError & ERROR_CAPABILITIES_UNSUPPORTED) != 0) {
347 maxInputChannels = 0;
348 channels = { Range<int>(0, 0) };
349 }
350
351 if (format->findString("bitrate-range", &valueStr)) {
Songyue Hanad936af2024-10-14 23:53:58 +0000352 std::optional<Range<int32_t>> parsedBitrate = ParseIntRange(valueStr.c_str());
Songyue Han73d6d112024-06-05 17:39:06 +0000353 if (parsedBitrate) {
354 bitRates = bitRates.value().intersect(parsedBitrate.value());
355 }
356 }
357
358 applyLimits(channels, bitRates);
359}
360
361void AudioCapabilities::getDefaultFormat(sp<AMessage> &format) {
362 // report settings that have only a single choice
363 if (mBitrateRange.lower() == mBitrateRange.upper()) {
364 format->setInt32(KEY_BIT_RATE, mBitrateRange.lower());
365 }
366 if (getMaxInputChannelCount() == 1) {
367 // mono-only format
368 format->setInt32(KEY_CHANNEL_COUNT, 1);
369 }
370 if (!mSampleRates.empty() && mSampleRates.size() == 1) {
371 format->setInt32(KEY_SAMPLE_RATE, mSampleRates[0]);
372 }
373}
374
375bool AudioCapabilities::supportsFormat(const sp<AMessage> &format) {
Songyue Han84ad37f2024-10-08 20:24:26 +0000376 int32_t sampleRateValue;
377 std::optional<int> sampleRate = format->findInt32(KEY_SAMPLE_RATE, &sampleRateValue)
378 ? std::make_optional<int>(sampleRateValue) : std::nullopt;
379 int32_t channelsValue;
380 std::optional<int> channels = format->findInt32(KEY_CHANNEL_COUNT, &channelsValue)
381 ? std::make_optional<int>(channelsValue) : std::nullopt;
Songyue Han73d6d112024-06-05 17:39:06 +0000382
383 if (!supports(sampleRate, channels)) {
384 return false;
385 }
386
387 if (!CodecCapabilities::SupportsBitrate(mBitrateRange, format)) {
388 return false;
389 }
390
391 // nothing to do for:
392 // KEY_CHANNEL_MASK: codecs don't get this
393 // KEY_IS_ADTS: required feature for all AAC decoders
394 return true;
395}
396
397} // namespace android