blob: d1b08bd0d7298594912534e97c2fc9f7b88e7e71 [file] [log] [blame]
Pawin Vongmasa36653902018-11-15 00:10:25 -08001/*
2 * Copyright (C) 2017 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 "C2SoftAacDec"
19#include <log/log.h>
20
21#include <inttypes.h>
22#include <math.h>
23#include <numeric>
24
25#include <cutils/properties.h>
26#include <media/stagefright/foundation/MediaDefs.h>
27#include <media/stagefright/foundation/hexdump.h>
28#include <media/stagefright/MediaErrors.h>
29#include <utils/misc.h>
30
31#include <C2PlatformSupport.h>
32#include <SimpleC2Interface.h>
33
34#include "C2SoftAacDec.h"
35
36#define FILEREAD_MAX_LAYERS 2
37
38#define DRC_DEFAULT_MOBILE_REF_LEVEL -16.0 /* 64*-0.25dB = -16 dB below full scale for mobile conf */
39#define DRC_DEFAULT_MOBILE_DRC_CUT 1.0 /* maximum compression of dynamic range for mobile conf */
40#define DRC_DEFAULT_MOBILE_DRC_BOOST 1.0 /* maximum compression of dynamic range for mobile conf */
41#define DRC_DEFAULT_MOBILE_DRC_HEAVY C2Config::DRC_COMPRESSION_HEAVY /* switch for heavy compression for mobile conf */
42#define DRC_DEFAULT_MOBILE_DRC_EFFECT 3 /* MPEG-D DRC effect type; 3 => Limited playback range */
Jean-Michel Trivi670b8fb2020-02-18 07:54:05 -080043#define DRC_DEFAULT_MOBILE_DRC_ALBUM 0 /* MPEG-D DRC album mode; 0 => album mode is disabled, 1 => album mode is enabled */
Jean-Michel Trivi4b936cc2020-02-17 16:29:47 -080044#define DRC_DEFAULT_MOBILE_OUTPUT_LOUDNESS (0.25) /* decoder output loudness; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */
Pawin Vongmasa36653902018-11-15 00:10:25 -080045#define DRC_DEFAULT_MOBILE_ENC_LEVEL (0.25) /* encoder target level; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */
46#define MAX_CHANNEL_COUNT 8 /* maximum number of audio channels that can be decoded */
47// names of properties that can be used to override the default DRC settings
48#define PROP_DRC_OVERRIDE_REF_LEVEL "aac_drc_reference_level"
49#define PROP_DRC_OVERRIDE_CUT "aac_drc_cut"
50#define PROP_DRC_OVERRIDE_BOOST "aac_drc_boost"
51#define PROP_DRC_OVERRIDE_HEAVY "aac_drc_heavy"
52#define PROP_DRC_OVERRIDE_ENC_LEVEL "aac_drc_enc_target_level"
53#define PROP_DRC_OVERRIDE_EFFECT "ro.aac_drc_effect_type"
54
55namespace android {
56
Wonsik Kimab34ed62019-01-31 15:28:46 -080057constexpr char COMPONENT_NAME[] = "c2.android.aac.decoder";
Harish Mahendrakar3c415ec2021-03-22 13:56:52 -070058constexpr size_t kDefaultOutputPortDelay = 2;
59constexpr size_t kMaxOutputPortDelay = 16;
Wonsik Kimab34ed62019-01-31 15:28:46 -080060
61class C2SoftAacDec::IntfImpl : public SimpleInterface<void>::BaseParams {
Pawin Vongmasa36653902018-11-15 00:10:25 -080062public:
63 explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
Wonsik Kimab34ed62019-01-31 15:28:46 -080064 : SimpleInterface<void>::BaseParams(
65 helper,
66 COMPONENT_NAME,
67 C2Component::KIND_DECODER,
68 C2Component::DOMAIN_AUDIO,
69 MEDIA_MIMETYPE_AUDIO_AAC) {
70 noPrivateBuffers();
71 noInputReferences();
72 noOutputReferences();
73 noInputLatency();
74 noTimeStretch();
Pawin Vongmasa36653902018-11-15 00:10:25 -080075
76 addParameter(
Wonsik Kimab34ed62019-01-31 15:28:46 -080077 DefineParam(mActualOutputDelay, C2_PARAMKEY_OUTPUT_DELAY)
Harish Mahendrakar3c415ec2021-03-22 13:56:52 -070078 .withDefault(new C2PortActualDelayTuning::output(kDefaultOutputPortDelay))
79 .withFields({C2F(mActualOutputDelay, value).inRange(0, kMaxOutputPortDelay)})
80 .withSetter(Setter<decltype(*mActualOutputDelay)>::StrictValueWithNoDeps)
Pawin Vongmasa36653902018-11-15 00:10:25 -080081 .build());
82
83 addParameter(
Lajos Molnar3bb81cd2019-02-20 15:10:30 -080084 DefineParam(mSampleRate, C2_PARAMKEY_SAMPLE_RATE)
Pawin Vongmasa36653902018-11-15 00:10:25 -080085 .withDefault(new C2StreamSampleRateInfo::output(0u, 44100))
86 .withFields({C2F(mSampleRate, value).oneOf({
Sungtak Leed7f88ee2019-11-14 16:04:25 -080087 7350, 8000, 11025, 12000, 16000, 22050, 24000, 32000,
88 44100, 48000, 64000, 88200, 96000
Pawin Vongmasa36653902018-11-15 00:10:25 -080089 })})
90 .withSetter(Setter<decltype(*mSampleRate)>::NonStrictValueWithNoDeps)
91 .build());
92
93 addParameter(
Lajos Molnar3bb81cd2019-02-20 15:10:30 -080094 DefineParam(mChannelCount, C2_PARAMKEY_CHANNEL_COUNT)
Pawin Vongmasa36653902018-11-15 00:10:25 -080095 .withDefault(new C2StreamChannelCountInfo::output(0u, 1))
Jean-Michel Trivieba54dc2020-06-10 18:21:56 -070096 .withFields({C2F(mChannelCount, value).inRange(1, MAX_CHANNEL_COUNT)})
Pawin Vongmasa36653902018-11-15 00:10:25 -080097 .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
98 .build());
99
100 addParameter(
Jean-Michel Trivieba54dc2020-06-10 18:21:56 -0700101 DefineParam(mMaxChannelCount, C2_PARAMKEY_MAX_CHANNEL_COUNT)
102 .withDefault(new C2StreamMaxChannelCountInfo::input(0u, MAX_CHANNEL_COUNT))
103 .withFields({C2F(mMaxChannelCount, value).inRange(1, MAX_CHANNEL_COUNT)})
104 .withSetter(Setter<decltype(*mMaxChannelCount)>::StrictValueWithNoDeps)
105 .build());
106
107 addParameter(
Lajos Molnar3bb81cd2019-02-20 15:10:30 -0800108 DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
109 .withDefault(new C2StreamBitrateInfo::input(0u, 64000))
Pawin Vongmasa36653902018-11-15 00:10:25 -0800110 .withFields({C2F(mBitrate, value).inRange(8000, 960000)})
111 .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
112 .build());
113
114 addParameter(
115 DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
116 .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 8192))
117 .build());
118
119 addParameter(
Lajos Molnar3bb81cd2019-02-20 15:10:30 -0800120 DefineParam(mAacFormat, C2_PARAMKEY_AAC_PACKAGING)
121 .withDefault(new C2StreamAacFormatInfo::input(0u, C2Config::AAC_PACKAGING_RAW))
Pawin Vongmasa36653902018-11-15 00:10:25 -0800122 .withFields({C2F(mAacFormat, value).oneOf({
Lajos Molnar3bb81cd2019-02-20 15:10:30 -0800123 C2Config::AAC_PACKAGING_RAW, C2Config::AAC_PACKAGING_ADTS
Pawin Vongmasa36653902018-11-15 00:10:25 -0800124 })})
125 .withSetter(Setter<decltype(*mAacFormat)>::StrictValueWithNoDeps)
126 .build());
127
128 addParameter(
129 DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
130 .withDefault(new C2StreamProfileLevelInfo::input(0u,
131 C2Config::PROFILE_AAC_LC, C2Config::LEVEL_UNUSED))
132 .withFields({
133 C2F(mProfileLevel, profile).oneOf({
134 C2Config::PROFILE_AAC_LC,
135 C2Config::PROFILE_AAC_HE,
136 C2Config::PROFILE_AAC_HE_PS,
137 C2Config::PROFILE_AAC_LD,
138 C2Config::PROFILE_AAC_ELD,
139 C2Config::PROFILE_AAC_ER_SCALABLE,
140 C2Config::PROFILE_AAC_XHE}),
141 C2F(mProfileLevel, level).oneOf({
142 C2Config::LEVEL_UNUSED
143 })
144 })
145 .withSetter(ProfileLevelSetter)
146 .build());
147
148 addParameter(
149 DefineParam(mDrcCompressMode, C2_PARAMKEY_DRC_COMPRESSION_MODE)
150 .withDefault(new C2StreamDrcCompressionModeTuning::input(0u, C2Config::DRC_COMPRESSION_HEAVY))
151 .withFields({
152 C2F(mDrcCompressMode, value).oneOf({
153 C2Config::DRC_COMPRESSION_ODM_DEFAULT,
154 C2Config::DRC_COMPRESSION_NONE,
155 C2Config::DRC_COMPRESSION_LIGHT,
156 C2Config::DRC_COMPRESSION_HEAVY})
157 })
158 .withSetter(Setter<decltype(*mDrcCompressMode)>::StrictValueWithNoDeps)
159 .build());
160
161 addParameter(
162 DefineParam(mDrcTargetRefLevel, C2_PARAMKEY_DRC_TARGET_REFERENCE_LEVEL)
163 .withDefault(new C2StreamDrcTargetReferenceLevelTuning::input(0u, DRC_DEFAULT_MOBILE_REF_LEVEL))
164 .withFields({C2F(mDrcTargetRefLevel, value).inRange(-31.75, 0.25)})
165 .withSetter(Setter<decltype(*mDrcTargetRefLevel)>::StrictValueWithNoDeps)
166 .build());
167
168 addParameter(
169 DefineParam(mDrcEncTargetLevel, C2_PARAMKEY_DRC_ENCODED_TARGET_LEVEL)
170 .withDefault(new C2StreamDrcEncodedTargetLevelTuning::input(0u, DRC_DEFAULT_MOBILE_ENC_LEVEL))
171 .withFields({C2F(mDrcEncTargetLevel, value).inRange(-31.75, 0.25)})
172 .withSetter(Setter<decltype(*mDrcEncTargetLevel)>::StrictValueWithNoDeps)
173 .build());
174
175 addParameter(
176 DefineParam(mDrcBoostFactor, C2_PARAMKEY_DRC_BOOST_FACTOR)
177 .withDefault(new C2StreamDrcBoostFactorTuning::input(0u, DRC_DEFAULT_MOBILE_DRC_BOOST))
178 .withFields({C2F(mDrcBoostFactor, value).inRange(0, 1.)})
179 .withSetter(Setter<decltype(*mDrcBoostFactor)>::StrictValueWithNoDeps)
180 .build());
181
182 addParameter(
183 DefineParam(mDrcAttenuationFactor, C2_PARAMKEY_DRC_ATTENUATION_FACTOR)
184 .withDefault(new C2StreamDrcAttenuationFactorTuning::input(0u, DRC_DEFAULT_MOBILE_DRC_CUT))
185 .withFields({C2F(mDrcAttenuationFactor, value).inRange(0, 1.)})
186 .withSetter(Setter<decltype(*mDrcAttenuationFactor)>::StrictValueWithNoDeps)
187 .build());
188
189 addParameter(
190 DefineParam(mDrcEffectType, C2_PARAMKEY_DRC_EFFECT_TYPE)
191 .withDefault(new C2StreamDrcEffectTypeTuning::input(0u, C2Config::DRC_EFFECT_LIMITED_PLAYBACK_RANGE))
192 .withFields({
193 C2F(mDrcEffectType, value).oneOf({
194 C2Config::DRC_EFFECT_ODM_DEFAULT,
195 C2Config::DRC_EFFECT_OFF,
196 C2Config::DRC_EFFECT_NONE,
197 C2Config::DRC_EFFECT_LATE_NIGHT,
198 C2Config::DRC_EFFECT_NOISY_ENVIRONMENT,
199 C2Config::DRC_EFFECT_LIMITED_PLAYBACK_RANGE,
200 C2Config::DRC_EFFECT_LOW_PLAYBACK_LEVEL,
201 C2Config::DRC_EFFECT_DIALOG_ENHANCEMENT,
202 C2Config::DRC_EFFECT_GENERAL_COMPRESSION})
203 })
204 .withSetter(Setter<decltype(*mDrcEffectType)>::StrictValueWithNoDeps)
205 .build());
Jean-Michel Trivi4b936cc2020-02-17 16:29:47 -0800206
207 addParameter(
Jean-Michel Trivi670b8fb2020-02-18 07:54:05 -0800208 DefineParam(mDrcAlbumMode, C2_PARAMKEY_DRC_ALBUM_MODE)
209 .withDefault(new C2StreamDrcAlbumModeTuning::input(0u, C2Config::DRC_ALBUM_MODE_OFF))
210 .withFields({
211 C2F(mDrcAlbumMode, value).oneOf({
212 C2Config::DRC_ALBUM_MODE_OFF,
213 C2Config::DRC_ALBUM_MODE_ON})
214 })
215 .withSetter(Setter<decltype(*mDrcAlbumMode)>::StrictValueWithNoDeps)
216 .build());
217
218 addParameter(
Jean-Michel Trivi4b936cc2020-02-17 16:29:47 -0800219 DefineParam(mDrcOutputLoudness, C2_PARAMKEY_DRC_OUTPUT_LOUDNESS)
220 .withDefault(new C2StreamDrcOutputLoudnessTuning::output(0u, DRC_DEFAULT_MOBILE_OUTPUT_LOUDNESS))
221 .withFields({C2F(mDrcOutputLoudness, value).inRange(-57.75, 0.25)})
222 .withSetter(Setter<decltype(*mDrcOutputLoudness)>::StrictValueWithNoDeps)
223 .build());
Jean-Michel Trivi3d476d12022-05-19 17:14:18 +0000224
225 addParameter(DefineParam(mChannelMask, C2_PARAMKEY_CHANNEL_MASK)
226 .withDefault(new C2StreamChannelMaskInfo::output(0u, 0))
227 .withFields({C2F(mChannelMask, value).inRange(0, 4294967292)})
228 .withSetter(Setter<decltype(*mChannelMask)>::StrictValueWithNoDeps)
229 .build());
Pawin Vongmasa36653902018-11-15 00:10:25 -0800230 }
231
Lajos Molnar3bb81cd2019-02-20 15:10:30 -0800232 bool isAdts() const { return mAacFormat->value == C2Config::AAC_PACKAGING_ADTS; }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800233 static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::input> &me) {
234 (void)mayBlock;
235 (void)me; // TODO: validate
236 return C2R::Ok();
237 }
238 int32_t getDrcCompressMode() const { return mDrcCompressMode->value == C2Config::DRC_COMPRESSION_HEAVY ? 1 : 0; }
239 int32_t getDrcTargetRefLevel() const { return (mDrcTargetRefLevel->value <= 0 ? -mDrcTargetRefLevel->value * 4. + 0.5 : -1); }
240 int32_t getDrcEncTargetLevel() const { return (mDrcEncTargetLevel->value <= 0 ? -mDrcEncTargetLevel->value * 4. + 0.5 : -1); }
241 int32_t getDrcBoostFactor() const { return mDrcBoostFactor->value * 127. + 0.5; }
242 int32_t getDrcAttenuationFactor() const { return mDrcAttenuationFactor->value * 127. + 0.5; }
243 int32_t getDrcEffectType() const { return mDrcEffectType->value; }
Jean-Michel Trivi670b8fb2020-02-18 07:54:05 -0800244 int32_t getDrcAlbumMode() const { return mDrcAlbumMode->value; }
Jean-Michel Trivieba54dc2020-06-10 18:21:56 -0700245 u_int32_t getMaxChannelCount() const { return mMaxChannelCount->value; }
Jean-Michel Trivi4b936cc2020-02-17 16:29:47 -0800246 int32_t getDrcOutputLoudness() const { return (mDrcOutputLoudness->value <= 0 ? -mDrcOutputLoudness->value * 4. + 0.5 : -1); }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800247
248private:
Pawin Vongmasa36653902018-11-15 00:10:25 -0800249 std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
250 std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
Lajos Molnar3bb81cd2019-02-20 15:10:30 -0800251 std::shared_ptr<C2StreamBitrateInfo::input> mBitrate;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800252 std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
253 std::shared_ptr<C2StreamAacFormatInfo::input> mAacFormat;
254 std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel;
255 std::shared_ptr<C2StreamDrcCompressionModeTuning::input> mDrcCompressMode;
256 std::shared_ptr<C2StreamDrcTargetReferenceLevelTuning::input> mDrcTargetRefLevel;
257 std::shared_ptr<C2StreamDrcEncodedTargetLevelTuning::input> mDrcEncTargetLevel;
258 std::shared_ptr<C2StreamDrcBoostFactorTuning::input> mDrcBoostFactor;
259 std::shared_ptr<C2StreamDrcAttenuationFactorTuning::input> mDrcAttenuationFactor;
260 std::shared_ptr<C2StreamDrcEffectTypeTuning::input> mDrcEffectType;
Jean-Michel Trivi670b8fb2020-02-18 07:54:05 -0800261 std::shared_ptr<C2StreamDrcAlbumModeTuning::input> mDrcAlbumMode;
Jean-Michel Trivieba54dc2020-06-10 18:21:56 -0700262 std::shared_ptr<C2StreamMaxChannelCountInfo::input> mMaxChannelCount;
Jean-Michel Trivi4b936cc2020-02-17 16:29:47 -0800263 std::shared_ptr<C2StreamDrcOutputLoudnessTuning::output> mDrcOutputLoudness;
Jean-Michel Trivi3d476d12022-05-19 17:14:18 +0000264 std::shared_ptr<C2StreamChannelMaskInfo::output> mChannelMask;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800265 // TODO Add : C2StreamAacSbrModeTuning
266};
267
Pawin Vongmasa36653902018-11-15 00:10:25 -0800268C2SoftAacDec::C2SoftAacDec(
269 const char *name,
270 c2_node_id_t id,
271 const std::shared_ptr<IntfImpl> &intfImpl)
272 : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
273 mIntf(intfImpl),
274 mAACDecoder(nullptr),
275 mStreamInfo(nullptr),
276 mSignalledError(false),
Harish Mahendrakar3c415ec2021-03-22 13:56:52 -0700277 mOutputPortDelay(kDefaultOutputPortDelay),
Cheng Li47c2b572022-08-30 18:22:02 -0600278 mOutputDelayRingBuffer(nullptr),
279 mDeviceApiLevel(android_get_device_api_level()) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800280}
281
282C2SoftAacDec::~C2SoftAacDec() {
283 onRelease();
284}
285
286c2_status_t C2SoftAacDec::onInit() {
287 status_t err = initDecoder();
288 return err == OK ? C2_OK : C2_CORRUPTED;
289}
290
291c2_status_t C2SoftAacDec::onStop() {
292 drainDecoder();
293 // reset the "configured" state
294 mOutputDelayCompensated = 0;
295 mOutputDelayRingBufferWritePos = 0;
296 mOutputDelayRingBufferReadPos = 0;
297 mOutputDelayRingBufferFilled = 0;
Wonsik Kim70982a62021-08-26 16:32:35 -0700298 mOutputDelayRingBuffer.reset();
Pawin Vongmasa36653902018-11-15 00:10:25 -0800299 mBuffersInfo.clear();
300
Rakesh Kumar87604ef2021-05-06 18:28:37 +0530301 status_t status = UNKNOWN_ERROR;
302 if (mAACDecoder) {
303 aacDecoder_Close(mAACDecoder);
304 status = initDecoder();
305 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800306 mSignalledError = false;
307
Rakesh Kumar87604ef2021-05-06 18:28:37 +0530308 return status == OK ? C2_OK : C2_CORRUPTED;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800309}
310
311void C2SoftAacDec::onReset() {
312 (void)onStop();
313}
314
315void C2SoftAacDec::onRelease() {
316 if (mAACDecoder) {
317 aacDecoder_Close(mAACDecoder);
318 mAACDecoder = nullptr;
319 }
Wonsik Kim70982a62021-08-26 16:32:35 -0700320 mOutputDelayRingBuffer.reset();
Pawin Vongmasa36653902018-11-15 00:10:25 -0800321}
322
323status_t C2SoftAacDec::initDecoder() {
324 ALOGV("initDecoder()");
325 status_t status = UNKNOWN_ERROR;
326 mAACDecoder = aacDecoder_Open(TT_MP4_ADIF, /* num layers */ 1);
327 if (mAACDecoder != nullptr) {
328 mStreamInfo = aacDecoder_GetStreamInfo(mAACDecoder);
329 if (mStreamInfo != nullptr) {
330 status = OK;
331 }
332 }
333
334 mOutputDelayCompensated = 0;
335 mOutputDelayRingBufferSize = 2048 * MAX_CHANNEL_COUNT * kNumDelayBlocksMax;
Wonsik Kim70982a62021-08-26 16:32:35 -0700336 mOutputDelayRingBuffer.reset(new short[mOutputDelayRingBufferSize]);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800337 mOutputDelayRingBufferWritePos = 0;
338 mOutputDelayRingBufferReadPos = 0;
339 mOutputDelayRingBufferFilled = 0;
340
341 if (mAACDecoder == nullptr) {
342 ALOGE("AAC decoder is null. TODO: Can not call aacDecoder_SetParam in the following code");
343 }
344
345 //aacDecoder_SetParam(mAACDecoder, AAC_PCM_LIMITER_ENABLE, 0);
346
347 //init DRC wrapper
348 mDrcWrap.setDecoderHandle(mAACDecoder);
349 mDrcWrap.submitStreamData(mStreamInfo);
350
351 // for streams that contain metadata, use the mobile profile DRC settings unless overridden by platform properties
352 // TODO: change the DRC settings depending on audio output device type (HDMI, loadspeaker, headphone)
353
354 // DRC_PRES_MODE_WRAP_DESIRED_TARGET
355 int32_t targetRefLevel = mIntf->getDrcTargetRefLevel();
356 ALOGV("AAC decoder using desired DRC target reference level of %d", targetRefLevel);
357 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_TARGET, (unsigned)targetRefLevel);
358
359 // DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR
360
361 int32_t attenuationFactor = mIntf->getDrcAttenuationFactor();
362 ALOGV("AAC decoder using desired DRC attenuation factor of %d", attenuationFactor);
363 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR, (unsigned)attenuationFactor);
364
365 // DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR
366 int32_t boostFactor = mIntf->getDrcBoostFactor();
367 ALOGV("AAC decoder using desired DRC boost factor of %d", boostFactor);
368 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR, (unsigned)boostFactor);
369
370 // DRC_PRES_MODE_WRAP_DESIRED_HEAVY
371 int32_t compressMode = mIntf->getDrcCompressMode();
Jean-Michel Triviedf942b2020-01-29 09:59:44 -0800372 ALOGV("AAC decoder using desired DRC heavy compression switch of %d", compressMode);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800373 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_HEAVY, (unsigned)compressMode);
374
375 // DRC_PRES_MODE_WRAP_ENCODER_TARGET
376 int32_t encTargetLevel = mIntf->getDrcEncTargetLevel();
377 ALOGV("AAC decoder using encoder-side DRC reference level of %d", encTargetLevel);
378 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_ENCODER_TARGET, (unsigned)encTargetLevel);
379
380 // AAC_UNIDRC_SET_EFFECT
381 int32_t effectType = mIntf->getDrcEffectType();
382 ALOGV("AAC decoder using MPEG-D DRC effect type %d", effectType);
383 aacDecoder_SetParam(mAACDecoder, AAC_UNIDRC_SET_EFFECT, effectType);
384
Jean-Michel Trivi670b8fb2020-02-18 07:54:05 -0800385 // AAC_UNIDRC_ALBUM_MODE
386 int32_t albumMode = mIntf->getDrcAlbumMode();
387 ALOGV("AAC decoder using MPEG-D DRC album mode %d", albumMode);
388 aacDecoder_SetParam(mAACDecoder, AAC_UNIDRC_ALBUM_MODE, albumMode);
389
Jean-Michel Trivieba54dc2020-06-10 18:21:56 -0700390 // AAC_PCM_MAX_OUTPUT_CHANNELS
391 u_int32_t maxChannelCount = mIntf->getMaxChannelCount();
392 ALOGV("AAC decoder using maximum output channel count %d", maxChannelCount);
393 aacDecoder_SetParam(mAACDecoder, AAC_PCM_MAX_OUTPUT_CHANNELS, maxChannelCount);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800394
395 return status;
396}
397
398bool C2SoftAacDec::outputDelayRingBufferPutSamples(INT_PCM *samples, int32_t numSamples) {
399 if (numSamples == 0) {
400 return true;
401 }
402 if (outputDelayRingBufferSpaceLeft() < numSamples) {
403 ALOGE("RING BUFFER WOULD OVERFLOW");
404 return false;
405 }
406 if (mOutputDelayRingBufferWritePos + numSamples <= mOutputDelayRingBufferSize
407 && (mOutputDelayRingBufferReadPos <= mOutputDelayRingBufferWritePos
408 || mOutputDelayRingBufferReadPos > mOutputDelayRingBufferWritePos + numSamples)) {
409 // faster memcopy loop without checks, if the preconditions allow this
410 for (int32_t i = 0; i < numSamples; i++) {
411 mOutputDelayRingBuffer[mOutputDelayRingBufferWritePos++] = samples[i];
412 }
413
414 if (mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferSize) {
415 mOutputDelayRingBufferWritePos -= mOutputDelayRingBufferSize;
416 }
417 } else {
418 ALOGV("slow C2SoftAacDec::outputDelayRingBufferPutSamples()");
419
420 for (int32_t i = 0; i < numSamples; i++) {
421 mOutputDelayRingBuffer[mOutputDelayRingBufferWritePos] = samples[i];
422 mOutputDelayRingBufferWritePos++;
423 if (mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferSize) {
424 mOutputDelayRingBufferWritePos -= mOutputDelayRingBufferSize;
425 }
426 }
427 }
428 mOutputDelayRingBufferFilled += numSamples;
429 return true;
430}
431
432int32_t C2SoftAacDec::outputDelayRingBufferGetSamples(INT_PCM *samples, int32_t numSamples) {
433
434 if (numSamples > mOutputDelayRingBufferFilled) {
435 ALOGE("RING BUFFER WOULD UNDERRUN");
436 return -1;
437 }
438
439 if (mOutputDelayRingBufferReadPos + numSamples <= mOutputDelayRingBufferSize
440 && (mOutputDelayRingBufferWritePos < mOutputDelayRingBufferReadPos
441 || mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferReadPos + numSamples)) {
442 // faster memcopy loop without checks, if the preconditions allow this
443 if (samples != nullptr) {
444 for (int32_t i = 0; i < numSamples; i++) {
445 samples[i] = mOutputDelayRingBuffer[mOutputDelayRingBufferReadPos++];
446 }
447 } else {
448 mOutputDelayRingBufferReadPos += numSamples;
449 }
450 if (mOutputDelayRingBufferReadPos >= mOutputDelayRingBufferSize) {
451 mOutputDelayRingBufferReadPos -= mOutputDelayRingBufferSize;
452 }
453 } else {
454 ALOGV("slow C2SoftAacDec::outputDelayRingBufferGetSamples()");
455
456 for (int32_t i = 0; i < numSamples; i++) {
457 if (samples != nullptr) {
458 samples[i] = mOutputDelayRingBuffer[mOutputDelayRingBufferReadPos];
459 }
460 mOutputDelayRingBufferReadPos++;
461 if (mOutputDelayRingBufferReadPos >= mOutputDelayRingBufferSize) {
462 mOutputDelayRingBufferReadPos -= mOutputDelayRingBufferSize;
463 }
464 }
465 }
466 mOutputDelayRingBufferFilled -= numSamples;
467 return numSamples;
468}
469
470int32_t C2SoftAacDec::outputDelayRingBufferSamplesAvailable() {
471 return mOutputDelayRingBufferFilled;
472}
473
474int32_t C2SoftAacDec::outputDelayRingBufferSpaceLeft() {
475 return mOutputDelayRingBufferSize - outputDelayRingBufferSamplesAvailable();
476}
477
478void C2SoftAacDec::drainRingBuffer(
479 const std::unique_ptr<C2Work> &work,
480 const std::shared_ptr<C2BlockPool> &pool,
481 bool eos) {
482 while (!mBuffersInfo.empty() && outputDelayRingBufferSamplesAvailable()
483 >= mStreamInfo->frameSize * mStreamInfo->numChannels) {
484 Info &outInfo = mBuffersInfo.front();
485 ALOGV("outInfo.frameIndex = %" PRIu64, outInfo.frameIndex);
486 int samplesize __unused = mStreamInfo->numChannels * sizeof(int16_t);
487
488 int available = outputDelayRingBufferSamplesAvailable();
489 int numFrames = outInfo.decodedSizes.size();
490 int numSamples = numFrames * (mStreamInfo->frameSize * mStreamInfo->numChannels);
491 if (available < numSamples) {
492 if (eos) {
493 numSamples = available;
494 } else {
495 break;
496 }
497 }
498 ALOGV("%d samples available (%d), or %d frames",
499 numSamples, available, numFrames);
500 ALOGV("getting %d from ringbuffer", numSamples);
501
502 std::shared_ptr<C2LinearBlock> block;
503 std::function<void(const std::unique_ptr<C2Work>&)> fillWork =
504 [&block, numSamples, pool, this]()
505 -> std::function<void(const std::unique_ptr<C2Work>&)> {
506 auto fillEmptyWork = [](
507 const std::unique_ptr<C2Work> &work, c2_status_t err) {
508 work->result = err;
509 C2FrameData &output = work->worklets.front()->output;
510 output.flags = work->input.flags;
511 output.buffers.clear();
512 output.ordinal = work->input.ordinal;
513
514 work->workletsProcessed = 1u;
515 };
516
517 using namespace std::placeholders;
518 if (numSamples == 0) {
519 return std::bind(fillEmptyWork, _1, C2_OK);
520 }
521
522 // TODO: error handling, proper usage, etc.
523 C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
Lajos Molnar268dac82021-06-09 16:25:07 -0700524 size_t bufferSize = numSamples * sizeof(int16_t);
525 c2_status_t err = pool->fetchLinearBlock(bufferSize, usage, &block);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800526 if (err != C2_OK) {
527 ALOGD("failed to fetch a linear block (%d)", err);
528 return std::bind(fillEmptyWork, _1, C2_NO_MEMORY);
529 }
530 C2WriteView wView = block->map().get();
531 // TODO
532 INT_PCM *outBuffer = reinterpret_cast<INT_PCM *>(wView.data());
533 int32_t ns = outputDelayRingBufferGetSamples(outBuffer, numSamples);
534 if (ns != numSamples) {
535 ALOGE("not a complete frame of samples available");
536 mSignalledError = true;
537 return std::bind(fillEmptyWork, _1, C2_CORRUPTED);
538 }
Lajos Molnar268dac82021-06-09 16:25:07 -0700539 return [buffer = createLinearBuffer(block, 0, bufferSize)](
Pawin Vongmasa36653902018-11-15 00:10:25 -0800540 const std::unique_ptr<C2Work> &work) {
541 work->result = C2_OK;
542 C2FrameData &output = work->worklets.front()->output;
543 output.flags = work->input.flags;
544 output.buffers.clear();
545 output.buffers.push_back(buffer);
546 output.ordinal = work->input.ordinal;
547 work->workletsProcessed = 1u;
548 };
549 }();
550
551 if (work && work->input.ordinal.frameIndex == c2_cntr64_t(outInfo.frameIndex)) {
552 fillWork(work);
553 } else {
554 finish(outInfo.frameIndex, fillWork);
555 }
556
557 ALOGV("out timestamp %" PRIu64 " / %u", outInfo.timestamp, block ? block->capacity() : 0);
558 mBuffersInfo.pop_front();
559 }
560}
561
562void C2SoftAacDec::process(
563 const std::unique_ptr<C2Work> &work,
564 const std::shared_ptr<C2BlockPool> &pool) {
565 // Initialize output work
566 work->result = C2_OK;
567 work->workletsProcessed = 1u;
568 work->worklets.front()->output.configUpdate.clear();
569 work->worklets.front()->output.flags = work->input.flags;
570
571 if (mSignalledError) {
572 return;
573 }
574
575 UCHAR* inBuffer[FILEREAD_MAX_LAYERS];
576 UINT inBufferLength[FILEREAD_MAX_LAYERS] = {0};
577 UINT bytesValid[FILEREAD_MAX_LAYERS] = {0};
578
579 INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT];
580 C2ReadView view = mDummyReadView;
581 size_t offset = 0u;
582 size_t size = 0u;
583 if (!work->input.buffers.empty()) {
584 view = work->input.buffers[0]->data().linearBlocks().front().map().get();
585 size = view.capacity();
586 }
587
588 bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
589 bool codecConfig = (work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0;
590
591 //TODO
592#if 0
593 if (mInputBufferCount == 0 && !codecConfig) {
594 ALOGW("first buffer should have FLAG_CODEC_CONFIG set");
595 codecConfig = true;
596 }
597#endif
598 if (codecConfig && size > 0u) {
599 // const_cast because of libAACdec method signature.
600 inBuffer[0] = const_cast<UCHAR *>(view.data() + offset);
601 inBufferLength[0] = size;
602
603 AAC_DECODER_ERROR decoderErr =
604 aacDecoder_ConfigRaw(mAACDecoder,
605 inBuffer,
606 inBufferLength);
607
608 if (decoderErr != AAC_DEC_OK) {
609 ALOGE("aacDecoder_ConfigRaw decoderErr = 0x%4.4x", decoderErr);
610 mSignalledError = true;
611 work->result = C2_CORRUPTED;
612 return;
613 }
614 work->worklets.front()->output.flags = work->input.flags;
615 work->worklets.front()->output.ordinal = work->input.ordinal;
616 work->worklets.front()->output.buffers.clear();
617 return;
618 }
619
620 Info inInfo;
621 inInfo.frameIndex = work->input.ordinal.frameIndex.peeku();
622 inInfo.timestamp = work->input.ordinal.timestamp.peeku();
623 inInfo.bufferSize = size;
624 inInfo.decodedSizes.clear();
625 while (size > 0u) {
626 ALOGV("size = %zu", size);
627 if (mIntf->isAdts()) {
628 size_t adtsHeaderSize = 0;
629 // skip 30 bits, aac_frame_length follows.
630 // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
631
632 const uint8_t *adtsHeader = view.data() + offset;
633
634 bool signalError = false;
635 if (size < 7) {
636 ALOGE("Audio data too short to contain even the ADTS header. "
637 "Got %zu bytes.", size);
638 hexdump(adtsHeader, size);
639 signalError = true;
640 } else {
641 bool protectionAbsent = (adtsHeader[1] & 1);
642
643 unsigned aac_frame_length =
644 ((adtsHeader[3] & 3) << 11)
645 | (adtsHeader[4] << 3)
646 | (adtsHeader[5] >> 5);
647
648 if (size < aac_frame_length) {
649 ALOGE("Not enough audio data for the complete frame. "
650 "Got %zu bytes, frame size according to the ADTS "
651 "header is %u bytes.",
652 size, aac_frame_length);
653 hexdump(adtsHeader, size);
654 signalError = true;
655 } else {
656 adtsHeaderSize = (protectionAbsent ? 7 : 9);
657 if (aac_frame_length < adtsHeaderSize) {
658 signalError = true;
659 } else {
660 // const_cast because of libAACdec method signature.
661 inBuffer[0] = const_cast<UCHAR *>(adtsHeader + adtsHeaderSize);
662 inBufferLength[0] = aac_frame_length - adtsHeaderSize;
663
664 offset += adtsHeaderSize;
665 size -= adtsHeaderSize;
666 }
667 }
668 }
669
670 if (signalError) {
671 mSignalledError = true;
672 work->result = C2_CORRUPTED;
673 return;
674 }
675 } else {
676 // const_cast because of libAACdec method signature.
677 inBuffer[0] = const_cast<UCHAR *>(view.data() + offset);
678 inBufferLength[0] = size;
679 }
680
681 // Fill and decode
682 bytesValid[0] = inBufferLength[0];
683
684 INT prevSampleRate = mStreamInfo->sampleRate;
685 INT prevNumChannels = mStreamInfo->numChannels;
Jean-Michel Trivi4b936cc2020-02-17 16:29:47 -0800686 INT prevOutLoudness = mStreamInfo->outputLoudness;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800687
688 aacDecoder_Fill(mAACDecoder,
689 inBuffer,
690 inBufferLength,
691 bytesValid);
692
693 // run DRC check
694 mDrcWrap.submitStreamData(mStreamInfo);
Jean-Michel Triviedf942b2020-01-29 09:59:44 -0800695
696 // apply runtime updates
697 // DRC_PRES_MODE_WRAP_DESIRED_TARGET
698 int32_t targetRefLevel = mIntf->getDrcTargetRefLevel();
699 ALOGV("AAC decoder using desired DRC target reference level of %d", targetRefLevel);
700 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_TARGET, (unsigned)targetRefLevel);
701
702 // DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR
703 int32_t attenuationFactor = mIntf->getDrcAttenuationFactor();
704 ALOGV("AAC decoder using desired DRC attenuation factor of %d", attenuationFactor);
705 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR, (unsigned)attenuationFactor);
706
707 // DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR
708 int32_t boostFactor = mIntf->getDrcBoostFactor();
709 ALOGV("AAC decoder using desired DRC boost factor of %d", boostFactor);
710 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR, (unsigned)boostFactor);
711
712 // DRC_PRES_MODE_WRAP_DESIRED_HEAVY
713 int32_t compressMode = mIntf->getDrcCompressMode();
714 ALOGV("AAC decoder using desried DRC heavy compression switch of %d", compressMode);
715 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_HEAVY, (unsigned)compressMode);
716
717 // DRC_PRES_MODE_WRAP_ENCODER_TARGET
718 int32_t encTargetLevel = mIntf->getDrcEncTargetLevel();
719 ALOGV("AAC decoder using encoder-side DRC reference level of %d", encTargetLevel);
720 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_ENCODER_TARGET, (unsigned)encTargetLevel);
721
722 // AAC_UNIDRC_SET_EFFECT
723 int32_t effectType = mIntf->getDrcEffectType();
724 ALOGV("AAC decoder using MPEG-D DRC effect type %d", effectType);
725 aacDecoder_SetParam(mAACDecoder, AAC_UNIDRC_SET_EFFECT, effectType);
726
Jean-Michel Trivi670b8fb2020-02-18 07:54:05 -0800727 // AAC_UNIDRC_ALBUM_MODE
728 int32_t albumMode = mIntf->getDrcAlbumMode();
729 ALOGV("AAC decoder using MPEG-D DRC album mode %d", albumMode);
730 aacDecoder_SetParam(mAACDecoder, AAC_UNIDRC_ALBUM_MODE, albumMode);
731
Jean-Michel Trivieba54dc2020-06-10 18:21:56 -0700732 // AAC_PCM_MAX_OUTPUT_CHANNELS
733 int32_t maxChannelCount = mIntf->getMaxChannelCount();
734 ALOGV("AAC decoder using maximum output channel count %d", maxChannelCount);
735 aacDecoder_SetParam(mAACDecoder, AAC_PCM_MAX_OUTPUT_CHANNELS, maxChannelCount);
736
Pawin Vongmasa36653902018-11-15 00:10:25 -0800737 mDrcWrap.update();
738
739 UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0];
740 size -= inBufferUsedLength;
741 offset += inBufferUsedLength;
742
743 AAC_DECODER_ERROR decoderErr;
744 do {
745 if (outputDelayRingBufferSpaceLeft() <
746 (mStreamInfo->frameSize * mStreamInfo->numChannels)) {
747 ALOGV("skipping decode: not enough space left in ringbuffer");
748 // discard buffer
749 size = 0;
750 break;
751 }
752
753 int numConsumed = mStreamInfo->numTotalBytes;
754 decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
755 tmpOutBuffer,
756 2048 * MAX_CHANNEL_COUNT,
757 0 /* flags */);
758
759 numConsumed = mStreamInfo->numTotalBytes - numConsumed;
760
761 if (decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
762 break;
763 }
764 inInfo.decodedSizes.push_back(numConsumed);
765
766 if (decoderErr != AAC_DEC_OK) {
767 ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr);
768 }
769
770 if (bytesValid[0] != 0) {
771 ALOGE("bytesValid[0] != 0 should never happen");
772 mSignalledError = true;
773 work->result = C2_CORRUPTED;
774 return;
775 }
776
777 size_t numOutBytes =
778 mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels;
779
780 if (decoderErr == AAC_DEC_OK) {
781 if (!outputDelayRingBufferPutSamples(tmpOutBuffer,
782 mStreamInfo->frameSize * mStreamInfo->numChannels)) {
783 mSignalledError = true;
784 work->result = C2_CORRUPTED;
785 return;
786 }
787 } else {
788 ALOGW("AAC decoder returned error 0x%4.4x, substituting silence", decoderErr);
789
790 memset(tmpOutBuffer, 0, numOutBytes); // TODO: check for overflow
791
792 if (!outputDelayRingBufferPutSamples(tmpOutBuffer,
793 mStreamInfo->frameSize * mStreamInfo->numChannels)) {
794 mSignalledError = true;
795 work->result = C2_CORRUPTED;
796 return;
797 }
798
799 // Discard input buffer.
800 size = 0;
801
802 aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);
803
804 // After an error, replace bufferSize with the sum of the
805 // decodedSizes to resynchronize the in/out lists.
Pawin Vongmasa36653902018-11-15 00:10:25 -0800806 inInfo.bufferSize = std::accumulate(
807 inInfo.decodedSizes.begin(), inInfo.decodedSizes.end(), 0);
808
809 // fall through
810 }
811
812 /*
813 * AAC+/eAAC+ streams can be signalled in two ways: either explicitly
814 * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual
815 * rate system and the sampling rate in the final output is actually
816 * doubled compared with the core AAC decoder sampling rate.
817 *
818 * Explicit signalling is done by explicitly defining SBR audio object
819 * type in the bitstream. Implicit signalling is done by embedding
820 * SBR content in AAC extension payload specific to SBR, and hence
821 * requires an AAC decoder to perform pre-checks on actual audio frames.
822 *
823 * Thus, we could not say for sure whether a stream is
824 * AAC+/eAAC+ until the first data frame is decoded.
825 */
826 if (!mStreamInfo->sampleRate || !mStreamInfo->numChannels) {
827 // if ((mInputBufferCount > 2) && (mOutputBufferCount <= 1)) {
828 ALOGD("Invalid AAC stream");
829 // TODO: notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
830 // mSignalledError = true;
831 // }
832 } else if ((mStreamInfo->sampleRate != prevSampleRate) ||
833 (mStreamInfo->numChannels != prevNumChannels)) {
834 ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels",
835 prevSampleRate, mStreamInfo->sampleRate,
836 prevNumChannels, mStreamInfo->numChannels);
837
838 C2StreamSampleRateInfo::output sampleRateInfo(0u, mStreamInfo->sampleRate);
839 C2StreamChannelCountInfo::output channelCountInfo(0u, mStreamInfo->numChannels);
Jean-Michel Trivi3d476d12022-05-19 17:14:18 +0000840 C2StreamChannelMaskInfo::output channelMaskInfo(0u,
841 maskFromCount(mStreamInfo->numChannels));
Pawin Vongmasa36653902018-11-15 00:10:25 -0800842 std::vector<std::unique_ptr<C2SettingResult>> failures;
843 c2_status_t err = mIntf->config(
Jean-Michel Trivi3d476d12022-05-19 17:14:18 +0000844 { &sampleRateInfo, &channelCountInfo, &channelMaskInfo },
Pawin Vongmasa36653902018-11-15 00:10:25 -0800845 C2_MAY_BLOCK,
846 &failures);
847 if (err == OK) {
848 // TODO: this does not handle the case where the values are
849 // altered during config.
850 C2FrameData &output = work->worklets.front()->output;
851 output.configUpdate.push_back(C2Param::Copy(sampleRateInfo));
852 output.configUpdate.push_back(C2Param::Copy(channelCountInfo));
Jean-Michel Trivi3d476d12022-05-19 17:14:18 +0000853 output.configUpdate.push_back(C2Param::Copy(channelMaskInfo));
Pawin Vongmasa36653902018-11-15 00:10:25 -0800854 } else {
855 ALOGE("Config Update failed");
856 mSignalledError = true;
857 work->result = C2_CORRUPTED;
858 return;
859 }
860 }
861 ALOGV("size = %zu", size);
Jean-Michel Trivi4b936cc2020-02-17 16:29:47 -0800862
863 if (mStreamInfo->outputLoudness != prevOutLoudness) {
864 C2StreamDrcOutputLoudnessTuning::output
865 drcOutLoudness(0u, (float) (mStreamInfo->outputLoudness*-0.25));
866
867 std::vector<std::unique_ptr<C2SettingResult>> failures;
868 c2_status_t err = mIntf->config(
869 { &drcOutLoudness },
870 C2_MAY_BLOCK,
871 &failures);
872 if (err == OK) {
873 work->worklets.front()->output.configUpdate.push_back(
874 C2Param::Copy(drcOutLoudness));
875 } else {
876 ALOGE("Getting output loudness failed");
877 }
878 }
Jean-Michel Trivi52ea7282020-06-05 09:54:38 -0700879
880 // update config with values used for decoding:
881 // Album mode, target reference level, DRC effect type, DRC attenuation and boost
882 // factor, DRC compression mode, encoder target level and max channel count
883 // with input values as they were not modified by decoder
884
885 C2StreamDrcAttenuationFactorTuning::input currentAttenuationFactor(0u,
886 (C2FloatValue) (attenuationFactor/127.));
887 work->worklets.front()->output.configUpdate.push_back(
888 C2Param::Copy(currentAttenuationFactor));
889
890 C2StreamDrcBoostFactorTuning::input currentBoostFactor(0u,
891 (C2FloatValue) (boostFactor/127.));
892 work->worklets.front()->output.configUpdate.push_back(
893 C2Param::Copy(currentBoostFactor));
894
Cheng Li47c2b572022-08-30 18:22:02 -0600895 if (mDeviceApiLevel < __ANDROID_API_S__) {
Wonsik Kim597435f2020-10-27 17:02:51 -0700896 // We used to report DRC compression mode in the output format
897 // in Q and R, but stopped doing that in S
898 C2StreamDrcCompressionModeTuning::input currentCompressMode(0u,
899 (C2Config::drc_compression_mode_t) compressMode);
900 work->worklets.front()->output.configUpdate.push_back(
901 C2Param::Copy(currentCompressMode));
902 }
Wonsik Kim8ec93ab2020-11-13 16:17:04 -0800903
Jean-Michel Trivi52ea7282020-06-05 09:54:38 -0700904 C2StreamDrcEncodedTargetLevelTuning::input currentEncodedTargetLevel(0u,
905 (C2FloatValue) (encTargetLevel*-0.25));
906 work->worklets.front()->output.configUpdate.push_back(
907 C2Param::Copy(currentEncodedTargetLevel));
908
909 C2StreamDrcAlbumModeTuning::input currentAlbumMode(0u,
910 (C2Config::drc_album_mode_t) albumMode);
911 work->worklets.front()->output.configUpdate.push_back(
912 C2Param::Copy(currentAlbumMode));
913
914 C2StreamDrcTargetReferenceLevelTuning::input currentTargetRefLevel(0u,
915 (float) (targetRefLevel*-0.25));
916 work->worklets.front()->output.configUpdate.push_back(
917 C2Param::Copy(currentTargetRefLevel));
918
919 C2StreamDrcEffectTypeTuning::input currentEffectype(0u,
920 (C2Config::drc_effect_type_t) effectType);
921 work->worklets.front()->output.configUpdate.push_back(
922 C2Param::Copy(currentEffectype));
923
924 C2StreamMaxChannelCountInfo::input currentMaxChannelCnt(0u, maxChannelCount);
925 work->worklets.front()->output.configUpdate.push_back(
926 C2Param::Copy(currentMaxChannelCnt));
927
Pawin Vongmasa36653902018-11-15 00:10:25 -0800928 } while (decoderErr == AAC_DEC_OK);
929 }
930
931 int32_t outputDelay = mStreamInfo->outputDelay * mStreamInfo->numChannels;
932
Harish Mahendrakar3c415ec2021-03-22 13:56:52 -0700933 size_t numSamplesInOutput = mStreamInfo->frameSize * mStreamInfo->numChannels;
934 if (numSamplesInOutput > 0) {
935 size_t actualOutputPortDelay = (outputDelay + numSamplesInOutput - 1) / numSamplesInOutput;
936 if (actualOutputPortDelay > mOutputPortDelay) {
937 mOutputPortDelay = actualOutputPortDelay;
938 ALOGV("New Output port delay %zu ", mOutputPortDelay);
939
940 C2PortActualDelayTuning::output outputPortDelay(mOutputPortDelay);
941 std::vector<std::unique_ptr<C2SettingResult>> failures;
942 c2_status_t err =
943 mIntf->config({&outputPortDelay}, C2_MAY_BLOCK, &failures);
944 if (err == OK) {
945 work->worklets.front()->output.configUpdate.push_back(
946 C2Param::Copy(outputPortDelay));
947 } else {
948 ALOGE("Cannot set output delay");
949 mSignalledError = true;
950 work->workletsProcessed = 1u;
951 work->result = C2_CORRUPTED;
952 return;
953 }
954 }
955 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800956 mBuffersInfo.push_back(std::move(inInfo));
957 work->workletsProcessed = 0u;
958 if (!eos && mOutputDelayCompensated < outputDelay) {
959 // discard outputDelay at the beginning
960 int32_t toCompensate = outputDelay - mOutputDelayCompensated;
961 int32_t discard = outputDelayRingBufferSamplesAvailable();
962 if (discard > toCompensate) {
963 discard = toCompensate;
964 }
965 int32_t discarded = outputDelayRingBufferGetSamples(nullptr, discard);
966 mOutputDelayCompensated += discarded;
967 return;
968 }
969
970 if (eos) {
971 drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work);
972 } else {
973 drainRingBuffer(work, pool, false /* not EOS */);
974 }
975}
976
977c2_status_t C2SoftAacDec::drainInternal(
978 uint32_t drainMode,
979 const std::shared_ptr<C2BlockPool> &pool,
980 const std::unique_ptr<C2Work> &work) {
981 if (drainMode == NO_DRAIN) {
982 ALOGW("drain with NO_DRAIN: no-op");
983 return C2_OK;
984 }
985 if (drainMode == DRAIN_CHAIN) {
986 ALOGW("DRAIN_CHAIN not supported");
987 return C2_OMITTED;
988 }
989
990 bool eos = (drainMode == DRAIN_COMPONENT_WITH_EOS);
991
992 drainDecoder();
993 drainRingBuffer(work, pool, eos);
994
995 if (eos) {
996 auto fillEmptyWork = [](const std::unique_ptr<C2Work> &work) {
997 work->worklets.front()->output.flags = work->input.flags;
998 work->worklets.front()->output.buffers.clear();
999 work->worklets.front()->output.ordinal = work->input.ordinal;
1000 work->workletsProcessed = 1u;
1001 };
1002 while (mBuffersInfo.size() > 1u) {
1003 finish(mBuffersInfo.front().frameIndex, fillEmptyWork);
1004 mBuffersInfo.pop_front();
1005 }
1006 if (work && work->workletsProcessed == 0u) {
1007 fillEmptyWork(work);
1008 }
1009 mBuffersInfo.clear();
1010 }
1011
1012 return C2_OK;
1013}
1014
1015c2_status_t C2SoftAacDec::drain(
1016 uint32_t drainMode,
1017 const std::shared_ptr<C2BlockPool> &pool) {
1018 return drainInternal(drainMode, pool, nullptr);
1019}
1020
1021c2_status_t C2SoftAacDec::onFlush_sm() {
1022 drainDecoder();
1023 mBuffersInfo.clear();
1024
1025 int avail;
1026 while ((avail = outputDelayRingBufferSamplesAvailable()) > 0) {
1027 if (avail > mStreamInfo->frameSize * mStreamInfo->numChannels) {
1028 avail = mStreamInfo->frameSize * mStreamInfo->numChannels;
1029 }
1030 int32_t ns = outputDelayRingBufferGetSamples(nullptr, avail);
1031 if (ns != avail) {
1032 ALOGW("not a complete frame of samples available");
1033 break;
1034 }
1035 }
1036 mOutputDelayRingBufferReadPos = mOutputDelayRingBufferWritePos;
1037
1038 return C2_OK;
1039}
1040
1041void C2SoftAacDec::drainDecoder() {
1042 // flush decoder until outputDelay is compensated
1043 while (mOutputDelayCompensated > 0) {
1044 // a buffer big enough for MAX_CHANNEL_COUNT channels of decoded HE-AAC
1045 INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT];
1046
1047 // run DRC check
1048 mDrcWrap.submitStreamData(mStreamInfo);
1049 mDrcWrap.update();
1050
1051 AAC_DECODER_ERROR decoderErr =
1052 aacDecoder_DecodeFrame(mAACDecoder,
1053 tmpOutBuffer,
1054 2048 * MAX_CHANNEL_COUNT,
1055 AACDEC_FLUSH);
1056 if (decoderErr != AAC_DEC_OK) {
1057 ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr);
1058 }
1059
1060 int32_t tmpOutBufferSamples = mStreamInfo->frameSize * mStreamInfo->numChannels;
1061 if (tmpOutBufferSamples > mOutputDelayCompensated) {
1062 tmpOutBufferSamples = mOutputDelayCompensated;
1063 }
1064 outputDelayRingBufferPutSamples(tmpOutBuffer, tmpOutBufferSamples);
1065
1066 mOutputDelayCompensated -= tmpOutBufferSamples;
1067 }
1068}
1069
Jean-Michel Trivi3d476d12022-05-19 17:14:18 +00001070// definitions based on android.media.AudioFormat.CHANNEL_OUT_*
1071#define CHANNEL_OUT_FL 0x4
1072#define CHANNEL_OUT_FR 0x8
1073#define CHANNEL_OUT_FC 0x10
1074#define CHANNEL_OUT_LFE 0x20
1075#define CHANNEL_OUT_BL 0x40
1076#define CHANNEL_OUT_BR 0x80
1077#define CHANNEL_OUT_SL 0x800
1078#define CHANNEL_OUT_SR 0x1000
1079
1080uint32_t C2SoftAacDec::maskFromCount(uint32_t channelCount) {
1081 // KEY_CHANNEL_MASK expects masks formatted according to Java android.media.AudioFormat
1082 // where the two left-most bits are 0 for output channel mask
1083 switch (channelCount) {
1084 case 1: // mono is front left
1085 return (CHANNEL_OUT_FL);
1086 case 2: // stereo
1087 return (CHANNEL_OUT_FL | CHANNEL_OUT_FR);
1088 case 4: // 4.0 = stereo with backs
1089 return (CHANNEL_OUT_FL | CHANNEL_OUT_FC
1090 | CHANNEL_OUT_BL | CHANNEL_OUT_BR);
1091 case 5: // 5.0
1092 return (CHANNEL_OUT_FL | CHANNEL_OUT_FC | CHANNEL_OUT_FR
1093 | CHANNEL_OUT_BL | CHANNEL_OUT_BR);
1094 case 6: // 5.1 = 5.0 + LFE
1095 return (CHANNEL_OUT_FL | CHANNEL_OUT_FC | CHANNEL_OUT_FR
1096 | CHANNEL_OUT_BL | CHANNEL_OUT_BR
1097 | CHANNEL_OUT_LFE);
1098 case 7: // 7.0 = 5.0 + Sides
1099 return (CHANNEL_OUT_FL | CHANNEL_OUT_FC | CHANNEL_OUT_FR
1100 | CHANNEL_OUT_BL | CHANNEL_OUT_BR
1101 | CHANNEL_OUT_SL | CHANNEL_OUT_SR);
1102 case 8: // 7.1 = 7.0 + LFE
1103 return (CHANNEL_OUT_FL | CHANNEL_OUT_FC | CHANNEL_OUT_FR
1104 | CHANNEL_OUT_BL | CHANNEL_OUT_BR | CHANNEL_OUT_SL | CHANNEL_OUT_SR
1105 | CHANNEL_OUT_LFE);
1106 default:
1107 return 0;
1108 }
1109}
1110
Pawin Vongmasa36653902018-11-15 00:10:25 -08001111class C2SoftAacDecFactory : public C2ComponentFactory {
1112public:
1113 C2SoftAacDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
1114 GetCodec2PlatformComponentStore()->getParamReflector())) {
1115 }
1116
1117 virtual c2_status_t createComponent(
1118 c2_node_id_t id,
1119 std::shared_ptr<C2Component>* const component,
1120 std::function<void(C2Component*)> deleter) override {
1121 *component = std::shared_ptr<C2Component>(
1122 new C2SoftAacDec(COMPONENT_NAME,
1123 id,
1124 std::make_shared<C2SoftAacDec::IntfImpl>(mHelper)),
1125 deleter);
1126 return C2_OK;
1127 }
1128
1129 virtual c2_status_t createInterface(
1130 c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface,
1131 std::function<void(C2ComponentInterface*)> deleter) override {
1132 *interface = std::shared_ptr<C2ComponentInterface>(
1133 new SimpleInterface<C2SoftAacDec::IntfImpl>(
1134 COMPONENT_NAME, id, std::make_shared<C2SoftAacDec::IntfImpl>(mHelper)),
1135 deleter);
1136 return C2_OK;
1137 }
1138
1139 virtual ~C2SoftAacDecFactory() override = default;
1140
1141private:
1142 std::shared_ptr<C2ReflectorHelper> mHelper;
1143};
1144
1145} // namespace android
1146
Cindy Zhouf6c0c3c2020-12-02 10:53:40 -08001147__attribute__((cfi_canonical_jump_table))
Pawin Vongmasa36653902018-11-15 00:10:25 -08001148extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
1149 ALOGV("in %s", __func__);
1150 return new ::android::C2SoftAacDecFactory();
1151}
1152
Cindy Zhouf6c0c3c2020-12-02 10:53:40 -08001153__attribute__((cfi_canonical_jump_table))
Pawin Vongmasa36653902018-11-15 00:10:25 -08001154extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
1155 ALOGV("in %s", __func__);
1156 delete factory;
1157}