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