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