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