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_ENC_LEVEL (-1) /* encoder target level; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */
43 #define MAX_CHANNEL_COUNT            8  /* maximum number of audio channels that can be decoded */
44 // names of properties that can be used to override the default DRC settings
45 #define PROP_DRC_OVERRIDE_REF_LEVEL  "aac_drc_reference_level"
46 #define PROP_DRC_OVERRIDE_CUT        "aac_drc_cut"
47 #define PROP_DRC_OVERRIDE_BOOST      "aac_drc_boost"
48 #define PROP_DRC_OVERRIDE_HEAVY      "aac_drc_heavy"
49 #define PROP_DRC_OVERRIDE_ENC_LEVEL "aac_drc_enc_target_level"
50 
51 namespace android {
52 
53 class C2SoftAacDec::IntfImpl : public C2InterfaceHelper {
54 public:
IntfImpl(const std::shared_ptr<C2ReflectorHelper> & helper)55     explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
56         : C2InterfaceHelper(helper) {
57 
58         setDerivedInstance(this);
59 
60         addParameter(
61                 DefineParam(mInputFormat, C2_NAME_INPUT_STREAM_FORMAT_SETTING)
62                 .withConstValue(new C2StreamFormatConfig::input(0u, C2FormatCompressed))
63                 .build());
64 
65         addParameter(
66                 DefineParam(mOutputFormat, C2_NAME_OUTPUT_STREAM_FORMAT_SETTING)
67                 .withConstValue(new C2StreamFormatConfig::output(0u, C2FormatAudio))
68                 .build());
69 
70         addParameter(
71                 DefineParam(mInputMediaType, C2_NAME_INPUT_PORT_MIME_SETTING)
72                 .withConstValue(AllocSharedString<C2PortMimeConfig::input>(
73                         MEDIA_MIMETYPE_AUDIO_AAC))
74                 .build());
75 
76         addParameter(
77                 DefineParam(mOutputMediaType, C2_NAME_OUTPUT_PORT_MIME_SETTING)
78                 .withConstValue(AllocSharedString<C2PortMimeConfig::output>(
79                         MEDIA_MIMETYPE_AUDIO_RAW))
80                 .build());
81 
82         addParameter(
83                 DefineParam(mSampleRate, C2_NAME_STREAM_SAMPLE_RATE_SETTING)
84                 .withDefault(new C2StreamSampleRateInfo::output(0u, 44100))
85                 .withFields({C2F(mSampleRate, value).oneOf({
86                     7350, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
87                 })})
88                 .withSetter(Setter<decltype(*mSampleRate)>::NonStrictValueWithNoDeps)
89                 .build());
90 
91         addParameter(
92                 DefineParam(mChannelCount, C2_NAME_STREAM_CHANNEL_COUNT_SETTING)
93                 .withDefault(new C2StreamChannelCountInfo::output(0u, 1))
94                 .withFields({C2F(mChannelCount, value).inRange(1, 8)})
95                 .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
96                 .build());
97 
98         addParameter(
99                 DefineParam(mBitrate, C2_NAME_STREAM_BITRATE_SETTING)
100                 .withDefault(new C2BitrateTuning::input(0u, 64000))
101                 .withFields({C2F(mBitrate, value).inRange(8000, 960000)})
102                 .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
103                 .build());
104 
105         addParameter(
106                 DefineParam(mAacFormat, C2_NAME_STREAM_AAC_FORMAT_SETTING)
107                 .withDefault(new C2StreamAacFormatInfo::input(0u, C2AacStreamFormatRaw))
108                 .withFields({C2F(mAacFormat, value).oneOf({
109                     C2AacStreamFormatRaw, C2AacStreamFormatAdts
110                 })})
111                 .withSetter(Setter<decltype(*mAacFormat)>::StrictValueWithNoDeps)
112                 .build());
113     }
114 
isAdts() const115     bool isAdts() const { return mAacFormat->value == C2AacStreamFormatAdts; }
116 
117 private:
118     std::shared_ptr<C2StreamFormatConfig::input> mInputFormat;
119     std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat;
120     std::shared_ptr<C2PortMimeConfig::input> mInputMediaType;
121     std::shared_ptr<C2PortMimeConfig::output> mOutputMediaType;
122     std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
123     std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
124     std::shared_ptr<C2BitrateTuning::input> mBitrate;
125 
126     std::shared_ptr<C2StreamAacFormatInfo::input> mAacFormat;
127 };
128 
129 constexpr char COMPONENT_NAME[] = "c2.android.aac.decoder";
130 
C2SoftAacDec(const char * name,c2_node_id_t id,const std::shared_ptr<IntfImpl> & intfImpl)131 C2SoftAacDec::C2SoftAacDec(
132         const char *name,
133         c2_node_id_t id,
134         const std::shared_ptr<IntfImpl> &intfImpl)
135     : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
136       mIntf(intfImpl),
137       mAACDecoder(NULL),
138       mStreamInfo(NULL),
139       mSignalledError(false),
140       mOutputDelayRingBuffer(NULL) {
141 }
142 
~C2SoftAacDec()143 C2SoftAacDec::~C2SoftAacDec() {
144     onRelease();
145 }
146 
onInit()147 c2_status_t C2SoftAacDec::onInit() {
148     status_t err = initDecoder();
149     return err == OK ? C2_OK : C2_CORRUPTED;
150 }
151 
onStop()152 c2_status_t C2SoftAacDec::onStop() {
153     drainDecoder();
154     // reset the "configured" state
155     mOutputDelayCompensated = 0;
156     mOutputDelayRingBufferWritePos = 0;
157     mOutputDelayRingBufferReadPos = 0;
158     mOutputDelayRingBufferFilled = 0;
159     mBuffersInfo.clear();
160 
161     // To make the codec behave the same before and after a reset, we need to invalidate the
162     // streaminfo struct. This does that:
163     mStreamInfo->sampleRate = 0; // TODO: mStreamInfo is read only
164 
165     mSignalledError = false;
166 
167     return C2_OK;
168 }
169 
onReset()170 void C2SoftAacDec::onReset() {
171     (void)onStop();
172 }
173 
onRelease()174 void C2SoftAacDec::onRelease() {
175     if (mAACDecoder) {
176         aacDecoder_Close(mAACDecoder);
177         mAACDecoder = NULL;
178     }
179     if (mOutputDelayRingBuffer) {
180         delete[] mOutputDelayRingBuffer;
181         mOutputDelayRingBuffer = NULL;
182     }
183 }
184 
initDecoder()185 status_t C2SoftAacDec::initDecoder() {
186     ALOGV("initDecoder()");
187     status_t status = UNKNOWN_ERROR;
188     mAACDecoder = aacDecoder_Open(TT_MP4_ADIF, /* num layers */ 1);
189     if (mAACDecoder != NULL) {
190         mStreamInfo = aacDecoder_GetStreamInfo(mAACDecoder);
191         if (mStreamInfo != NULL) {
192             status = OK;
193         }
194     }
195 
196     mOutputDelayCompensated = 0;
197     mOutputDelayRingBufferSize = 2048 * MAX_CHANNEL_COUNT * kNumDelayBlocksMax;
198     mOutputDelayRingBuffer = new short[mOutputDelayRingBufferSize];
199     mOutputDelayRingBufferWritePos = 0;
200     mOutputDelayRingBufferReadPos = 0;
201     mOutputDelayRingBufferFilled = 0;
202 
203     if (mAACDecoder == NULL) {
204         ALOGE("AAC decoder is null. TODO: Can not call aacDecoder_SetParam in the following code");
205     }
206 
207     //aacDecoder_SetParam(mAACDecoder, AAC_PCM_LIMITER_ENABLE, 0);
208 
209     //init DRC wrapper
210     mDrcWrap.setDecoderHandle(mAACDecoder);
211     mDrcWrap.submitStreamData(mStreamInfo);
212 
213     // for streams that contain metadata, use the mobile profile DRC settings unless overridden by platform properties
214     // TODO: change the DRC settings depending on audio output device type (HDMI, loadspeaker, headphone)
215     char value[PROPERTY_VALUE_MAX];
216     //  DRC_PRES_MODE_WRAP_DESIRED_TARGET
217     if (property_get(PROP_DRC_OVERRIDE_REF_LEVEL, value, NULL)) {
218         unsigned refLevel = atoi(value);
219         ALOGV("AAC decoder using desired DRC target reference level of %d instead of %d", refLevel,
220                 DRC_DEFAULT_MOBILE_REF_LEVEL);
221         mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_TARGET, refLevel);
222     } else {
223         mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_TARGET, DRC_DEFAULT_MOBILE_REF_LEVEL);
224     }
225     //  DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR
226     if (property_get(PROP_DRC_OVERRIDE_CUT, value, NULL)) {
227         unsigned cut = atoi(value);
228         ALOGV("AAC decoder using desired DRC attenuation factor of %d instead of %d", cut,
229                 DRC_DEFAULT_MOBILE_DRC_CUT);
230         mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR, cut);
231     } else {
232         mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR, DRC_DEFAULT_MOBILE_DRC_CUT);
233     }
234     //  DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR
235     if (property_get(PROP_DRC_OVERRIDE_BOOST, value, NULL)) {
236         unsigned boost = atoi(value);
237         ALOGV("AAC decoder using desired DRC boost factor of %d instead of %d", boost,
238                 DRC_DEFAULT_MOBILE_DRC_BOOST);
239         mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR, boost);
240     } else {
241         mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR, DRC_DEFAULT_MOBILE_DRC_BOOST);
242     }
243     //  DRC_PRES_MODE_WRAP_DESIRED_HEAVY
244     if (property_get(PROP_DRC_OVERRIDE_HEAVY, value, NULL)) {
245         unsigned heavy = atoi(value);
246         ALOGV("AAC decoder using desried DRC heavy compression switch of %d instead of %d", heavy,
247                 DRC_DEFAULT_MOBILE_DRC_HEAVY);
248         mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_HEAVY, heavy);
249     } else {
250         mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_HEAVY, DRC_DEFAULT_MOBILE_DRC_HEAVY);
251     }
252     // DRC_PRES_MODE_WRAP_ENCODER_TARGET
253     if (property_get(PROP_DRC_OVERRIDE_ENC_LEVEL, value, NULL)) {
254         unsigned encoderRefLevel = atoi(value);
255         ALOGV("AAC decoder using encoder-side DRC reference level of %d instead of %d",
256                 encoderRefLevel, DRC_DEFAULT_MOBILE_ENC_LEVEL);
257         mDrcWrap.setParam(DRC_PRES_MODE_WRAP_ENCODER_TARGET, encoderRefLevel);
258     } else {
259         mDrcWrap.setParam(DRC_PRES_MODE_WRAP_ENCODER_TARGET, DRC_DEFAULT_MOBILE_ENC_LEVEL);
260     }
261 
262     // By default, the decoder creates a 5.1 channel downmix signal.
263     // For seven and eight channel input streams, enable 6.1 and 7.1 channel output
264     aacDecoder_SetParam(mAACDecoder, AAC_PCM_MAX_OUTPUT_CHANNELS, -1);
265 
266     return status;
267 }
268 
outputDelayRingBufferPutSamples(INT_PCM * samples,int32_t numSamples)269 bool C2SoftAacDec::outputDelayRingBufferPutSamples(INT_PCM *samples, int32_t numSamples) {
270     if (numSamples == 0) {
271         return true;
272     }
273     if (outputDelayRingBufferSpaceLeft() < numSamples) {
274         ALOGE("RING BUFFER WOULD OVERFLOW");
275         return false;
276     }
277     if (mOutputDelayRingBufferWritePos + numSamples <= mOutputDelayRingBufferSize
278             && (mOutputDelayRingBufferReadPos <= mOutputDelayRingBufferWritePos
279                     || mOutputDelayRingBufferReadPos > mOutputDelayRingBufferWritePos + numSamples)) {
280         // faster memcopy loop without checks, if the preconditions allow this
281         for (int32_t i = 0; i < numSamples; i++) {
282             mOutputDelayRingBuffer[mOutputDelayRingBufferWritePos++] = samples[i];
283         }
284 
285         if (mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferSize) {
286             mOutputDelayRingBufferWritePos -= mOutputDelayRingBufferSize;
287         }
288     } else {
289         ALOGV("slow C2SoftAacDec::outputDelayRingBufferPutSamples()");
290 
291         for (int32_t i = 0; i < numSamples; i++) {
292             mOutputDelayRingBuffer[mOutputDelayRingBufferWritePos] = samples[i];
293             mOutputDelayRingBufferWritePos++;
294             if (mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferSize) {
295                 mOutputDelayRingBufferWritePos -= mOutputDelayRingBufferSize;
296             }
297         }
298     }
299     mOutputDelayRingBufferFilled += numSamples;
300     return true;
301 }
302 
outputDelayRingBufferGetSamples(INT_PCM * samples,int32_t numSamples)303 int32_t C2SoftAacDec::outputDelayRingBufferGetSamples(INT_PCM *samples, int32_t numSamples) {
304 
305     if (numSamples > mOutputDelayRingBufferFilled) {
306         ALOGE("RING BUFFER WOULD UNDERRUN");
307         return -1;
308     }
309 
310     if (mOutputDelayRingBufferReadPos + numSamples <= mOutputDelayRingBufferSize
311             && (mOutputDelayRingBufferWritePos < mOutputDelayRingBufferReadPos
312                     || mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferReadPos + numSamples)) {
313         // faster memcopy loop without checks, if the preconditions allow this
314         if (samples != 0) {
315             for (int32_t i = 0; i < numSamples; i++) {
316                 samples[i] = mOutputDelayRingBuffer[mOutputDelayRingBufferReadPos++];
317             }
318         } else {
319             mOutputDelayRingBufferReadPos += numSamples;
320         }
321         if (mOutputDelayRingBufferReadPos >= mOutputDelayRingBufferSize) {
322             mOutputDelayRingBufferReadPos -= mOutputDelayRingBufferSize;
323         }
324     } else {
325         ALOGV("slow C2SoftAacDec::outputDelayRingBufferGetSamples()");
326 
327         for (int32_t i = 0; i < numSamples; i++) {
328             if (samples != 0) {
329                 samples[i] = mOutputDelayRingBuffer[mOutputDelayRingBufferReadPos];
330             }
331             mOutputDelayRingBufferReadPos++;
332             if (mOutputDelayRingBufferReadPos >= mOutputDelayRingBufferSize) {
333                 mOutputDelayRingBufferReadPos -= mOutputDelayRingBufferSize;
334             }
335         }
336     }
337     mOutputDelayRingBufferFilled -= numSamples;
338     return numSamples;
339 }
340 
outputDelayRingBufferSamplesAvailable()341 int32_t C2SoftAacDec::outputDelayRingBufferSamplesAvailable() {
342     return mOutputDelayRingBufferFilled;
343 }
344 
outputDelayRingBufferSpaceLeft()345 int32_t C2SoftAacDec::outputDelayRingBufferSpaceLeft() {
346     return mOutputDelayRingBufferSize - outputDelayRingBufferSamplesAvailable();
347 }
348 
drainRingBuffer(const std::unique_ptr<C2Work> & work,const std::shared_ptr<C2BlockPool> & pool,bool eos)349 void C2SoftAacDec::drainRingBuffer(
350         const std::unique_ptr<C2Work> &work,
351         const std::shared_ptr<C2BlockPool> &pool,
352         bool eos) {
353     while (!mBuffersInfo.empty() && outputDelayRingBufferSamplesAvailable()
354             >= mStreamInfo->frameSize * mStreamInfo->numChannels) {
355         Info &outInfo = mBuffersInfo.front();
356         ALOGV("outInfo.frameIndex = %" PRIu64, outInfo.frameIndex);
357         int samplesize __unused = mStreamInfo->numChannels * sizeof(int16_t);
358 
359         int available = outputDelayRingBufferSamplesAvailable();
360         int numFrames = outInfo.decodedSizes.size();
361         int numSamples = numFrames * (mStreamInfo->frameSize * mStreamInfo->numChannels);
362         if (available < numSamples) {
363             if (eos) {
364                 numSamples = available;
365             } else {
366                 break;
367             }
368         }
369         ALOGV("%d samples available (%d), or %d frames",
370                 numSamples, available, numFrames);
371         ALOGV("getting %d from ringbuffer", numSamples);
372 
373         std::shared_ptr<C2LinearBlock> block;
374         std::function<void(const std::unique_ptr<C2Work>&)> fillWork =
375             [&block, numSamples, pool, this]()
376                     -> std::function<void(const std::unique_ptr<C2Work>&)> {
377                 auto fillEmptyWork = [](
378                         const std::unique_ptr<C2Work> &work, c2_status_t err) {
379                     work->result = err;
380                     C2FrameData &output = work->worklets.front()->output;
381                     output.flags = work->input.flags;
382                     output.buffers.clear();
383                     output.ordinal = work->input.ordinal;
384 
385                     work->workletsProcessed = 1u;
386                 };
387 
388                 using namespace std::placeholders;
389                 if (numSamples == 0) {
390                     return std::bind(fillEmptyWork, _1, C2_OK);
391                 }
392 
393                 // TODO: error handling, proper usage, etc.
394                 C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
395                 c2_status_t err = pool->fetchLinearBlock(
396                         numSamples * sizeof(int16_t), usage, &block);
397                 if (err != C2_OK) {
398                     ALOGD("failed to fetch a linear block (%d)", err);
399                     mSignalledError = true;
400                     return std::bind(fillEmptyWork, _1, C2_NO_MEMORY);
401                 }
402                 C2WriteView wView = block->map().get();
403                 // TODO
404                 INT_PCM *outBuffer = reinterpret_cast<INT_PCM *>(wView.data());
405                 int32_t ns = outputDelayRingBufferGetSamples(outBuffer, numSamples);
406                 if (ns != numSamples) {
407                     ALOGE("not a complete frame of samples available");
408                     mSignalledError = true;
409                     return std::bind(fillEmptyWork, _1, C2_CORRUPTED);
410                 }
411                 return [buffer = createLinearBuffer(block)](
412                         const std::unique_ptr<C2Work> &work) {
413                     work->result = C2_OK;
414                     C2FrameData &output = work->worklets.front()->output;
415                     output.flags = work->input.flags;
416                     output.buffers.clear();
417                     output.buffers.push_back(buffer);
418                     output.ordinal = work->input.ordinal;
419                     work->workletsProcessed = 1u;
420                 };
421             }();
422 
423         if (work && work->input.ordinal.frameIndex == c2_cntr64_t(outInfo.frameIndex)) {
424             fillWork(work);
425         } else {
426             finish(outInfo.frameIndex, fillWork);
427         }
428 
429         ALOGV("out timestamp %" PRIu64 " / %u", outInfo.timestamp, block ? block->capacity() : 0);
430         mBuffersInfo.pop_front();
431     }
432 }
433 
process(const std::unique_ptr<C2Work> & work,const std::shared_ptr<C2BlockPool> & pool)434 void C2SoftAacDec::process(
435         const std::unique_ptr<C2Work> &work,
436         const std::shared_ptr<C2BlockPool> &pool) {
437     work->workletsProcessed = 0u;
438     work->result = C2_OK;
439     work->worklets.front()->output.configUpdate.clear();
440     if (mSignalledError) {
441         return;
442     }
443 
444     UCHAR* inBuffer[FILEREAD_MAX_LAYERS];
445     UINT inBufferLength[FILEREAD_MAX_LAYERS] = {0};
446     UINT bytesValid[FILEREAD_MAX_LAYERS] = {0};
447 
448     INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT];
449     C2ReadView view = mDummyReadView;
450     size_t offset = 0u;
451     size_t size = 0u;
452     if (!work->input.buffers.empty()) {
453         view = work->input.buffers[0]->data().linearBlocks().front().map().get();
454         size = view.capacity();
455     }
456 
457     bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
458     bool codecConfig = (work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0;
459 
460     //TODO
461 #if 0
462     if (mInputBufferCount == 0 && !codecConfig) {
463         ALOGW("first buffer should have FLAG_CODEC_CONFIG set");
464         codecConfig = true;
465     }
466 #endif
467     if (codecConfig && size > 0u) {
468         // const_cast because of libAACdec method signature.
469         inBuffer[0] = const_cast<UCHAR *>(view.data() + offset);
470         inBufferLength[0] = size;
471 
472         AAC_DECODER_ERROR decoderErr =
473             aacDecoder_ConfigRaw(mAACDecoder,
474                                  inBuffer,
475                                  inBufferLength);
476 
477         if (decoderErr != AAC_DEC_OK) {
478             ALOGE("aacDecoder_ConfigRaw decoderErr = 0x%4.4x", decoderErr);
479             mSignalledError = true;
480             // TODO: error
481             return;
482         }
483 
484         work->worklets.front()->output.ordinal = work->input.ordinal;
485         work->worklets.front()->output.buffers.clear();
486 
487         return;
488     }
489 
490     Info inInfo;
491     inInfo.frameIndex = work->input.ordinal.frameIndex.peeku();
492     inInfo.timestamp = work->input.ordinal.timestamp.peeku();
493     inInfo.bufferSize = size;
494     inInfo.decodedSizes.clear();
495     while (size > 0u) {
496         ALOGV("size = %zu", size);
497         if (mIntf->isAdts()) {
498             size_t adtsHeaderSize = 0;
499             // skip 30 bits, aac_frame_length follows.
500             // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
501 
502             const uint8_t *adtsHeader = view.data() + offset;
503 
504             bool signalError = false;
505             if (size < 7) {
506                 ALOGE("Audio data too short to contain even the ADTS header. "
507                         "Got %zu bytes.", size);
508                 hexdump(adtsHeader, size);
509                 signalError = true;
510             } else {
511                 bool protectionAbsent = (adtsHeader[1] & 1);
512 
513                 unsigned aac_frame_length =
514                     ((adtsHeader[3] & 3) << 11)
515                     | (adtsHeader[4] << 3)
516                     | (adtsHeader[5] >> 5);
517 
518                 if (size < aac_frame_length) {
519                     ALOGE("Not enough audio data for the complete frame. "
520                             "Got %zu bytes, frame size according to the ADTS "
521                             "header is %u bytes.",
522                             size, aac_frame_length);
523                     hexdump(adtsHeader, size);
524                     signalError = true;
525                 } else {
526                     adtsHeaderSize = (protectionAbsent ? 7 : 9);
527                     if (aac_frame_length < adtsHeaderSize) {
528                         signalError = true;
529                     } else {
530                         // const_cast because of libAACdec method signature.
531                         inBuffer[0] = const_cast<UCHAR *>(adtsHeader + adtsHeaderSize);
532                         inBufferLength[0] = aac_frame_length - adtsHeaderSize;
533 
534                         offset += adtsHeaderSize;
535                         size -= adtsHeaderSize;
536                     }
537                 }
538             }
539 
540             if (signalError) {
541                 mSignalledError = true;
542                 // TODO: notify(OMX_EventError, OMX_ErrorStreamCorrupt, ERROR_MALFORMED, NULL);
543                 return;
544             }
545         } else {
546             // const_cast because of libAACdec method signature.
547             inBuffer[0] = const_cast<UCHAR *>(view.data() + offset);
548             inBufferLength[0] = size;
549         }
550 
551         // Fill and decode
552         bytesValid[0] = inBufferLength[0];
553 
554         INT prevSampleRate = mStreamInfo->sampleRate;
555         INT prevNumChannels = mStreamInfo->numChannels;
556 
557         aacDecoder_Fill(mAACDecoder,
558                         inBuffer,
559                         inBufferLength,
560                         bytesValid);
561 
562         // run DRC check
563         mDrcWrap.submitStreamData(mStreamInfo);
564         mDrcWrap.update();
565 
566         UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0];
567         size -= inBufferUsedLength;
568         offset += inBufferUsedLength;
569 
570         AAC_DECODER_ERROR decoderErr;
571         do {
572             if (outputDelayRingBufferSpaceLeft() <
573                     (mStreamInfo->frameSize * mStreamInfo->numChannels)) {
574                 ALOGV("skipping decode: not enough space left in ringbuffer");
575                 break;
576             }
577 
578             int numConsumed = mStreamInfo->numTotalBytes;
579             decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
580                                        tmpOutBuffer,
581                                        2048 * MAX_CHANNEL_COUNT,
582                                        0 /* flags */);
583 
584             numConsumed = mStreamInfo->numTotalBytes - numConsumed;
585 
586             if (decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
587                 break;
588             }
589             inInfo.decodedSizes.push_back(numConsumed);
590 
591             if (decoderErr != AAC_DEC_OK) {
592                 ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr);
593             }
594 
595             if (bytesValid[0] != 0) {
596                 ALOGE("bytesValid[0] != 0 should never happen");
597                 mSignalledError = true;
598                 // TODO: notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
599                 return;
600             }
601 
602             size_t numOutBytes =
603                 mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels;
604 
605             if (decoderErr == AAC_DEC_OK) {
606                 if (!outputDelayRingBufferPutSamples(tmpOutBuffer,
607                         mStreamInfo->frameSize * mStreamInfo->numChannels)) {
608                     mSignalledError = true;
609                     // TODO: notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
610                     return;
611                 }
612             } else {
613                 ALOGW("AAC decoder returned error 0x%4.4x, substituting silence", decoderErr);
614 
615                 memset(tmpOutBuffer, 0, numOutBytes); // TODO: check for overflow
616 
617                 if (!outputDelayRingBufferPutSamples(tmpOutBuffer,
618                         mStreamInfo->frameSize * mStreamInfo->numChannels)) {
619                     mSignalledError = true;
620                     // TODO: notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
621                     return;
622                 }
623 
624                 // Discard input buffer.
625                 size = 0;
626 
627                 aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);
628 
629                 // After an error, replace bufferSize with the sum of the
630                 // decodedSizes to resynchronize the in/out lists.
631                 inInfo.decodedSizes.pop_back();
632                 inInfo.bufferSize = std::accumulate(
633                         inInfo.decodedSizes.begin(), inInfo.decodedSizes.end(), 0);
634 
635                 // fall through
636             }
637 
638             /*
639              * AAC+/eAAC+ streams can be signalled in two ways: either explicitly
640              * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual
641              * rate system and the sampling rate in the final output is actually
642              * doubled compared with the core AAC decoder sampling rate.
643              *
644              * Explicit signalling is done by explicitly defining SBR audio object
645              * type in the bitstream. Implicit signalling is done by embedding
646              * SBR content in AAC extension payload specific to SBR, and hence
647              * requires an AAC decoder to perform pre-checks on actual audio frames.
648              *
649              * Thus, we could not say for sure whether a stream is
650              * AAC+/eAAC+ until the first data frame is decoded.
651              */
652             if (!mStreamInfo->sampleRate || !mStreamInfo->numChannels) {
653                 // if ((mInputBufferCount > 2) && (mOutputBufferCount <= 1)) {
654                     ALOGD("Invalid AAC stream");
655                     // TODO: notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
656                     // mSignalledError = true;
657                 // }
658             } else if ((mStreamInfo->sampleRate != prevSampleRate) ||
659                        (mStreamInfo->numChannels != prevNumChannels)) {
660                 ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels",
661                       prevSampleRate, mStreamInfo->sampleRate,
662                       prevNumChannels, mStreamInfo->numChannels);
663 
664                 C2StreamSampleRateInfo::output sampleRateInfo(0u, mStreamInfo->sampleRate);
665                 C2StreamChannelCountInfo::output channelCountInfo(0u, mStreamInfo->numChannels);
666                 std::vector<std::unique_ptr<C2SettingResult>> failures;
667                 c2_status_t err = mIntf->config(
668                         { &sampleRateInfo, &channelCountInfo },
669                         C2_MAY_BLOCK,
670                         &failures);
671                 if (err == OK) {
672                     // TODO: this does not handle the case where the values are
673                     //       altered during config.
674                     C2FrameData &output = work->worklets.front()->output;
675                     output.configUpdate.push_back(C2Param::Copy(sampleRateInfo));
676                     output.configUpdate.push_back(C2Param::Copy(channelCountInfo));
677                 }
678                 // TODO: error handling
679             }
680             ALOGV("size = %zu", size);
681         } while (decoderErr == AAC_DEC_OK);
682     }
683 
684     int32_t outputDelay = mStreamInfo->outputDelay * mStreamInfo->numChannels;
685 
686     mBuffersInfo.push_back(std::move(inInfo));
687 
688     if (!eos && mOutputDelayCompensated < outputDelay) {
689         // discard outputDelay at the beginning
690         int32_t toCompensate = outputDelay - mOutputDelayCompensated;
691         int32_t discard = outputDelayRingBufferSamplesAvailable();
692         if (discard > toCompensate) {
693             discard = toCompensate;
694         }
695         int32_t discarded = outputDelayRingBufferGetSamples(0, discard);
696         mOutputDelayCompensated += discarded;
697         return;
698     }
699 
700     if (eos) {
701         drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work);
702     } else {
703         drainRingBuffer(work, pool, false /* not EOS */);
704     }
705 }
706 
drainInternal(uint32_t drainMode,const std::shared_ptr<C2BlockPool> & pool,const std::unique_ptr<C2Work> & work)707 c2_status_t C2SoftAacDec::drainInternal(
708         uint32_t drainMode,
709         const std::shared_ptr<C2BlockPool> &pool,
710         const std::unique_ptr<C2Work> &work) {
711     if (drainMode == NO_DRAIN) {
712         ALOGW("drain with NO_DRAIN: no-op");
713         return C2_OK;
714     }
715     if (drainMode == DRAIN_CHAIN) {
716         ALOGW("DRAIN_CHAIN not supported");
717         return C2_OMITTED;
718     }
719 
720     bool eos = (drainMode == DRAIN_COMPONENT_WITH_EOS);
721 
722     drainDecoder();
723     drainRingBuffer(work, pool, eos);
724 
725     if (eos) {
726         auto fillEmptyWork = [](const std::unique_ptr<C2Work> &work) {
727             work->worklets.front()->output.flags = work->input.flags;
728             work->worklets.front()->output.buffers.clear();
729             work->worklets.front()->output.ordinal = work->input.ordinal;
730             work->workletsProcessed = 1u;
731         };
732         while (mBuffersInfo.size() > 1u) {
733             finish(mBuffersInfo.front().frameIndex, fillEmptyWork);
734             mBuffersInfo.pop_front();
735         }
736         if (work && work->workletsProcessed == 0u) {
737             fillEmptyWork(work);
738         }
739         mBuffersInfo.clear();
740     }
741 
742     return C2_OK;
743 }
744 
drain(uint32_t drainMode,const std::shared_ptr<C2BlockPool> & pool)745 c2_status_t C2SoftAacDec::drain(
746         uint32_t drainMode,
747         const std::shared_ptr<C2BlockPool> &pool) {
748     return drainInternal(drainMode, pool, nullptr);
749 }
750 
onFlush_sm()751 c2_status_t C2SoftAacDec::onFlush_sm() {
752     drainDecoder();
753     mBuffersInfo.clear();
754 
755     int avail;
756     while ((avail = outputDelayRingBufferSamplesAvailable()) > 0) {
757         if (avail > mStreamInfo->frameSize * mStreamInfo->numChannels) {
758             avail = mStreamInfo->frameSize * mStreamInfo->numChannels;
759         }
760         int32_t ns = outputDelayRingBufferGetSamples(0, avail);
761         if (ns != avail) {
762             ALOGW("not a complete frame of samples available");
763             break;
764         }
765     }
766     mOutputDelayRingBufferReadPos = mOutputDelayRingBufferWritePos;
767 
768     return C2_OK;
769 }
770 
drainDecoder()771 void C2SoftAacDec::drainDecoder() {
772     // flush decoder until outputDelay is compensated
773     while (mOutputDelayCompensated > 0) {
774         // a buffer big enough for MAX_CHANNEL_COUNT channels of decoded HE-AAC
775         INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT];
776 
777         // run DRC check
778         mDrcWrap.submitStreamData(mStreamInfo);
779         mDrcWrap.update();
780 
781         AAC_DECODER_ERROR decoderErr =
782             aacDecoder_DecodeFrame(mAACDecoder,
783                                    tmpOutBuffer,
784                                    2048 * MAX_CHANNEL_COUNT,
785                                    AACDEC_FLUSH);
786         if (decoderErr != AAC_DEC_OK) {
787             ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr);
788         }
789 
790         int32_t tmpOutBufferSamples = mStreamInfo->frameSize * mStreamInfo->numChannels;
791         if (tmpOutBufferSamples > mOutputDelayCompensated) {
792             tmpOutBufferSamples = mOutputDelayCompensated;
793         }
794         outputDelayRingBufferPutSamples(tmpOutBuffer, tmpOutBufferSamples);
795 
796         mOutputDelayCompensated -= tmpOutBufferSamples;
797     }
798 }
799 
800 class C2SoftAacDecFactory : public C2ComponentFactory {
801 public:
C2SoftAacDecFactory()802     C2SoftAacDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
803             GetCodec2PlatformComponentStore()->getParamReflector())) {
804     }
805 
createComponent(c2_node_id_t id,std::shared_ptr<C2Component> * const component,std::function<void (C2Component *)> deleter)806     virtual c2_status_t createComponent(
807             c2_node_id_t id,
808             std::shared_ptr<C2Component>* const component,
809             std::function<void(C2Component*)> deleter) override {
810         *component = std::shared_ptr<C2Component>(
811                 new C2SoftAacDec(COMPONENT_NAME,
812                               id,
813                               std::make_shared<C2SoftAacDec::IntfImpl>(mHelper)),
814                 deleter);
815         return C2_OK;
816     }
817 
createInterface(c2_node_id_t id,std::shared_ptr<C2ComponentInterface> * const interface,std::function<void (C2ComponentInterface *)> deleter)818     virtual c2_status_t createInterface(
819             c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface,
820             std::function<void(C2ComponentInterface*)> deleter) override {
821         *interface = std::shared_ptr<C2ComponentInterface>(
822                 new SimpleInterface<C2SoftAacDec::IntfImpl>(
823                         COMPONENT_NAME, id, std::make_shared<C2SoftAacDec::IntfImpl>(mHelper)),
824                 deleter);
825         return C2_OK;
826     }
827 
828     virtual ~C2SoftAacDecFactory() override = default;
829 
830 private:
831     std::shared_ptr<C2ReflectorHelper> mHelper;
832 };
833 
834 }  // namespace android
835 
CreateCodec2Factory()836 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
837     ALOGV("in %s", __func__);
838     return new ::android::C2SoftAacDecFactory();
839 }
840 
DestroyCodec2Factory(::C2ComponentFactory * factory)841 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
842     ALOGV("in %s", __func__);
843     delete factory;
844 }
845