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