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