C2SoftAacDec.cpp revision 277b7295f317c6597fadb116b6aee5ca3be106c1
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 "C2SoftAac"
19#include <utils/Log.h>
20
21#include "C2SoftAac.h"
22
23#include <C2PlatformSupport.h>
24#include <SimpleInterfaceCommon.h>
25
26#include <cutils/properties.h>
27#include <media/stagefright/foundation/ADebug.h>
28#include <media/stagefright/foundation/MediaDefs.h>
29#include <media/stagefright/foundation/hexdump.h>
30#include <media/stagefright/MediaErrors.h>
31#include <utils/misc.h>
32
33#include <inttypes.h>
34#include <math.h>
35#include <numeric>
36
37#define FILEREAD_MAX_LAYERS 2
38
39#define DRC_DEFAULT_MOBILE_REF_LEVEL 64  /* 64*-0.25dB = -16 dB below full scale for mobile conf */
40#define DRC_DEFAULT_MOBILE_DRC_CUT   127 /* maximum compression of dynamic range for mobile conf */
41#define DRC_DEFAULT_MOBILE_DRC_BOOST 127 /* maximum compression of dynamic range for mobile conf */
42#define DRC_DEFAULT_MOBILE_DRC_HEAVY 1   /* switch for heavy compression for mobile conf */
43#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) */
44#define MAX_CHANNEL_COUNT            8  /* maximum number of audio channels that can be decoded */
45// names of properties that can be used to override the default DRC settings
46#define PROP_DRC_OVERRIDE_REF_LEVEL  "aac_drc_reference_level"
47#define PROP_DRC_OVERRIDE_CUT        "aac_drc_cut"
48#define PROP_DRC_OVERRIDE_BOOST      "aac_drc_boost"
49#define PROP_DRC_OVERRIDE_HEAVY      "aac_drc_heavy"
50#define PROP_DRC_OVERRIDE_ENC_LEVEL "aac_drc_enc_target_level"
51
52namespace android {
53
54class C2SoftAac::IntfImpl : public C2InterfaceHelper {
55public:
56    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
57        : C2InterfaceHelper(helper) {
58
59        setDerivedInstance(this);
60
61        addParameter(
62                DefineParam(mInputFormat, C2_NAME_INPUT_STREAM_FORMAT_SETTING)
63                .withConstValue(new C2StreamFormatConfig::input(0u, C2FormatCompressed))
64                .build());
65
66        addParameter(
67                DefineParam(mOutputFormat, C2_NAME_OUTPUT_STREAM_FORMAT_SETTING)
68                .withConstValue(new C2StreamFormatConfig::output(0u, C2FormatAudio))
69                .build());
70
71        addParameter(
72                DefineParam(mInputMediaType, C2_NAME_INPUT_PORT_MIME_SETTING)
73                .withConstValue(AllocSharedString<C2PortMimeConfig::input>(
74                        MEDIA_MIMETYPE_AUDIO_AAC))
75                .build());
76
77        addParameter(
78                DefineParam(mOutputMediaType, C2_NAME_OUTPUT_PORT_MIME_SETTING)
79                .withConstValue(AllocSharedString<C2PortMimeConfig::output>(
80                        MEDIA_MIMETYPE_AUDIO_RAW))
81                .build());
82
83        addParameter(
84                DefineParam(mSampleRate, C2_NAME_STREAM_SAMPLE_RATE_SETTING)
85                .withDefault(new C2StreamSampleRateInfo::output(0u, 44100))
86                .withFields({C2F(mSampleRate, value).oneOf({
87                    7350, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
88                })})
89                .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
90                .build());
91
92        addParameter(
93                DefineParam(mChannelCount, C2_NAME_STREAM_CHANNEL_COUNT_SETTING)
94                .withDefault(new C2StreamChannelCountInfo::output(0u, 1))
95                .withFields({C2F(mChannelCount, value).inRange(1, 8)})
96                .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
97                .build());
98
99        addParameter(
100                DefineParam(mBitrate, C2_NAME_STREAM_BITRATE_SETTING)
101                .withDefault(new C2BitrateTuning::input(0u, 64000))
102                .withFields({C2F(mBitrate, value).inRange(8000, 960000)})
103                .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
104                .build());
105
106        addParameter(
107                DefineParam(mAacFormat, C2_NAME_STREAM_BITRATE_SETTING)
108                .withDefault(new C2StreamAacFormatInfo::input(0u, C2AacStreamFormatRaw))
109                .withFields({C2F(mAacFormat, value).oneOf({
110                    C2AacStreamFormatRaw, C2AacStreamFormatAdts
111                })})
112                .withSetter(Setter<decltype(*mAacFormat)>::StrictValueWithNoDeps)
113                .build());
114    }
115
116    bool isAdts() const { return mAacFormat->value == C2AacStreamFormatAdts; }
117
118private:
119    std::shared_ptr<C2StreamFormatConfig::input> mInputFormat;
120    std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat;
121    std::shared_ptr<C2PortMimeConfig::input> mInputMediaType;
122    std::shared_ptr<C2PortMimeConfig::output> mOutputMediaType;
123    std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
124    std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
125    std::shared_ptr<C2BitrateTuning::input> mBitrate;
126
127    std::shared_ptr<C2StreamAacFormatInfo::input> mAacFormat;
128};
129
130constexpr char COMPONENT_NAME[] = "c2.google.aac.decoder";
131
132C2SoftAac::C2SoftAac(
133        const char *name,
134        c2_node_id_t id,
135        const std::shared_ptr<IntfImpl> &intfImpl)
136    : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
137      mAACDecoder(NULL),
138      mStreamInfo(NULL),
139      mSignalledError(false),
140      mOutputDelayRingBuffer(NULL) {
141}
142
143C2SoftAac::~C2SoftAac() {
144    onRelease();
145}
146
147c2_status_t C2SoftAac::onInit() {
148    status_t err = initDecoder();
149    return err == OK ? C2_OK : C2_CORRUPTED;
150}
151
152c2_status_t C2SoftAac::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
170void C2SoftAac::onReset() {
171    (void)onStop();
172}
173
174void C2SoftAac::onRelease() {
175    if (mAACDecoder) {
176        aacDecoder_Close(mAACDecoder);
177        mAACDecoder = NULL;
178    }
179    if (mOutputDelayRingBuffer) {
180        delete[] mOutputDelayRingBuffer;
181        mOutputDelayRingBuffer = NULL;
182    }
183}
184
185status_t C2SoftAac::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
269bool C2SoftAac::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 C2SoftAac::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
303int32_t C2SoftAac::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 C2SoftAac::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
341int32_t C2SoftAac::outputDelayRingBufferSamplesAvailable() {
342    return mOutputDelayRingBufferFilled;
343}
344
345int32_t C2SoftAac::outputDelayRingBufferSpaceLeft() {
346    return mOutputDelayRingBufferSize - outputDelayRingBufferSamplesAvailable();
347}
348
349void C2SoftAac::drainRingBuffer(
350        const std::unique_ptr<C2Work> &work,
351        const std::shared_ptr<C2BlockPool> &pool,
352        std::vector<std::unique_ptr<C2Param>> *configUpdate,
353        bool eos) {
354    while (!mBuffersInfo.empty() && outputDelayRingBufferSamplesAvailable()
355            >= mStreamInfo->frameSize * mStreamInfo->numChannels) {
356        Info &outInfo = mBuffersInfo.front();
357        ALOGV("outInfo.frameIndex = %" PRIu64, outInfo.frameIndex);
358        int samplesize = mStreamInfo->numChannels * sizeof(int16_t);
359
360        int available = outputDelayRingBufferSamplesAvailable();
361        int numFrames = outInfo.decodedSizes.size();
362        int numSamples = numFrames * (mStreamInfo->frameSize * mStreamInfo->numChannels);
363        if (available < numSamples) {
364            if (eos) {
365                numSamples = available;
366            } else {
367                break;
368            }
369        }
370        ALOGV("%d samples available (%d), or %d frames",
371                numSamples, available, numFrames);
372        ALOGV("getting %d from ringbuffer", numSamples);
373
374        std::shared_ptr<C2LinearBlock> block;
375        std::function<void(const std::unique_ptr<C2Work>&)> fillWork =
376            [&block, numSamples, pool, configUpdate, this]()
377                    -> std::function<void(const std::unique_ptr<C2Work>&)> {
378                auto fillEmptyWork = [configUpdate](
379                        const std::unique_ptr<C2Work> &work, c2_status_t err) {
380                    work->result = err;
381                    C2FrameData &output = work->worklets.front()->output;
382                    output.flags = work->input.flags;
383                    output.buffers.clear();
384                    output.ordinal = work->input.ordinal;
385                    while (configUpdate && !configUpdate->empty()) {
386                        output.configUpdate.push_back(std::move(configUpdate->front()));
387                    }
388
389                    work->workletsProcessed = 1u;
390                };
391
392                using namespace std::placeholders;
393                if (numSamples == 0) {
394                    return std::bind(fillEmptyWork, _1, C2_OK);
395                }
396
397                // TODO: error handling, proper usage, etc.
398                C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
399                c2_status_t err = pool->fetchLinearBlock(
400                        numSamples * sizeof(int16_t), usage, &block);
401                if (err != C2_OK) {
402                    ALOGD("failed to fetch a linear block (%d)", err);
403                    mSignalledError = true;
404                    return std::bind(fillEmptyWork, _1, C2_NO_MEMORY);
405                }
406                C2WriteView wView = block->map().get();
407                // TODO
408                INT_PCM *outBuffer = reinterpret_cast<INT_PCM *>(wView.data());
409                int32_t ns = outputDelayRingBufferGetSamples(outBuffer, numSamples);
410                if (ns != numSamples) {
411                    ALOGE("not a complete frame of samples available");
412                    mSignalledError = true;
413                    return std::bind(fillEmptyWork, _1, C2_CORRUPTED);
414                }
415                return [buffer = createLinearBuffer(block), configUpdate](
416                        const std::unique_ptr<C2Work> &work) {
417                    work->result = C2_OK;
418                    C2FrameData &output = work->worklets.front()->output;
419                    output.flags = work->input.flags;
420                    output.buffers.clear();
421                    output.buffers.push_back(buffer);
422                    output.ordinal = work->input.ordinal;
423                    while (configUpdate && !configUpdate->empty()) {
424                        output.configUpdate.push_back(std::move(configUpdate->front()));
425                    }
426                    work->workletsProcessed = 1u;
427                };
428            }();
429
430        if (work && work->input.ordinal.frameIndex == c2_cntr64_t(outInfo.frameIndex)) {
431            fillWork(work);
432        } else {
433            finish(outInfo.frameIndex, fillWork);
434        }
435
436        ALOGV("out timestamp %" PRIu64 " / %u", outInfo.timestamp, block ? block->capacity() : 0);
437        mBuffersInfo.pop_front();
438    }
439}
440
441void C2SoftAac::process(
442        const std::unique_ptr<C2Work> &work,
443        const std::shared_ptr<C2BlockPool> &pool) {
444    work->workletsProcessed = 0u;
445    work->result = C2_OK;
446    work->worklets.front()->output.configUpdate.clear();
447    if (mSignalledError) {
448        return;
449    }
450
451    UCHAR* inBuffer[FILEREAD_MAX_LAYERS];
452    UINT inBufferLength[FILEREAD_MAX_LAYERS] = {0};
453    UINT bytesValid[FILEREAD_MAX_LAYERS] = {0};
454
455    INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT];
456    C2ReadView view = work->input.buffers[0]->data().linearBlocks().front().map().get();
457    size_t offset = 0u;
458    size_t size = view.capacity();
459
460    bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
461    bool codecConfig = (work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0;
462
463    //TODO
464#if 0
465    if (mInputBufferCount == 0 && !codecConfig) {
466        ALOGW("first buffer should have FLAG_CODEC_CONFIG set");
467        codecConfig = true;
468    }
469#endif
470    if (codecConfig) {
471        // const_cast because of libAACdec method signature.
472        inBuffer[0] = const_cast<UCHAR *>(view.data() + offset);
473        inBufferLength[0] = size;
474
475        AAC_DECODER_ERROR decoderErr =
476            aacDecoder_ConfigRaw(mAACDecoder,
477                                 inBuffer,
478                                 inBufferLength);
479
480        if (decoderErr != AAC_DEC_OK) {
481            ALOGE("aacDecoder_ConfigRaw decoderErr = 0x%4.4x", decoderErr);
482            mSignalledError = true;
483            // TODO: error
484            return;
485        }
486
487        work->worklets.front()->output.ordinal = work->input.ordinal;
488        work->worklets.front()->output.buffers.clear();
489
490        return;
491    }
492
493    std::vector<std::unique_ptr<C2Param>> configUpdate{};
494    Info inInfo;
495    inInfo.frameIndex = work->input.ordinal.frameIndex.peeku();
496    inInfo.timestamp = work->input.ordinal.timestamp.peeku();
497    inInfo.bufferSize = size;
498    inInfo.decodedSizes.clear();
499    while (size > 0u) {
500        ALOGV("size = %zu", size);
501        if (mIntf->isAdts()) {
502            size_t adtsHeaderSize = 0;
503            // skip 30 bits, aac_frame_length follows.
504            // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
505
506            const uint8_t *adtsHeader = view.data() + offset;
507
508            bool signalError = false;
509            if (size < 7) {
510                ALOGE("Audio data too short to contain even the ADTS header. "
511                        "Got %zu bytes.", size);
512                hexdump(adtsHeader, size);
513                signalError = true;
514            } else {
515                bool protectionAbsent = (adtsHeader[1] & 1);
516
517                unsigned aac_frame_length =
518                    ((adtsHeader[3] & 3) << 11)
519                    | (adtsHeader[4] << 3)
520                    | (adtsHeader[5] >> 5);
521
522                if (size < aac_frame_length) {
523                    ALOGE("Not enough audio data for the complete frame. "
524                            "Got %zu bytes, frame size according to the ADTS "
525                            "header is %u bytes.",
526                            size, aac_frame_length);
527                    hexdump(adtsHeader, size);
528                    signalError = true;
529                } else {
530                    adtsHeaderSize = (protectionAbsent ? 7 : 9);
531                    if (aac_frame_length < adtsHeaderSize) {
532                        signalError = true;
533                    } else {
534                        // const_cast because of libAACdec method signature.
535                        inBuffer[0] = const_cast<UCHAR *>(adtsHeader + adtsHeaderSize);
536                        inBufferLength[0] = aac_frame_length - adtsHeaderSize;
537
538                        offset += adtsHeaderSize;
539                        size -= adtsHeaderSize;
540                    }
541                }
542            }
543
544            if (signalError) {
545                mSignalledError = true;
546                // TODO: notify(OMX_EventError, OMX_ErrorStreamCorrupt, ERROR_MALFORMED, NULL);
547                return;
548            }
549        } else {
550            // const_cast because of libAACdec method signature.
551            inBuffer[0] = const_cast<UCHAR *>(view.data() + offset);
552            inBufferLength[0] = size;
553        }
554
555        // Fill and decode
556        bytesValid[0] = inBufferLength[0];
557
558        INT prevSampleRate = mStreamInfo->sampleRate;
559        INT prevNumChannels = mStreamInfo->numChannels;
560
561        aacDecoder_Fill(mAACDecoder,
562                        inBuffer,
563                        inBufferLength,
564                        bytesValid);
565
566        // run DRC check
567        mDrcWrap.submitStreamData(mStreamInfo);
568        mDrcWrap.update();
569
570        UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0];
571        size -= inBufferUsedLength;
572        offset += inBufferUsedLength;
573
574        AAC_DECODER_ERROR decoderErr;
575        do {
576            if (outputDelayRingBufferSpaceLeft() <
577                    (mStreamInfo->frameSize * mStreamInfo->numChannels)) {
578                ALOGV("skipping decode: not enough space left in ringbuffer");
579                break;
580            }
581
582            int numConsumed = mStreamInfo->numTotalBytes;
583            decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
584                                       tmpOutBuffer,
585                                       2048 * MAX_CHANNEL_COUNT,
586                                       0 /* flags */);
587
588            numConsumed = mStreamInfo->numTotalBytes - numConsumed;
589
590            if (decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
591                break;
592            }
593            inInfo.decodedSizes.push_back(numConsumed);
594
595            if (decoderErr != AAC_DEC_OK) {
596                ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr);
597            }
598
599            if (bytesValid[0] != 0) {
600                ALOGE("bytesValid[0] != 0 should never happen");
601                mSignalledError = true;
602                // TODO: notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
603                return;
604            }
605
606            size_t numOutBytes =
607                mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels;
608
609            if (decoderErr == AAC_DEC_OK) {
610                if (!outputDelayRingBufferPutSamples(tmpOutBuffer,
611                        mStreamInfo->frameSize * mStreamInfo->numChannels)) {
612                    mSignalledError = true;
613                    // TODO: notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
614                    return;
615                }
616            } else {
617                ALOGW("AAC decoder returned error 0x%4.4x, substituting silence", decoderErr);
618
619                memset(tmpOutBuffer, 0, numOutBytes); // TODO: check for overflow
620
621                if (!outputDelayRingBufferPutSamples(tmpOutBuffer,
622                        mStreamInfo->frameSize * mStreamInfo->numChannels)) {
623                    mSignalledError = true;
624                    // TODO: notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
625                    return;
626                }
627
628                // Discard input buffer.
629                size = 0;
630
631                aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);
632
633                // After an error, replace bufferSize with the sum of the
634                // decodedSizes to resynchronize the in/out lists.
635                inInfo.decodedSizes.pop_back();
636                inInfo.bufferSize = std::accumulate(
637                        inInfo.decodedSizes.begin(), inInfo.decodedSizes.end(), 0);
638
639                // fall through
640            }
641
642            /*
643             * AAC+/eAAC+ streams can be signalled in two ways: either explicitly
644             * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual
645             * rate system and the sampling rate in the final output is actually
646             * doubled compared with the core AAC decoder sampling rate.
647             *
648             * Explicit signalling is done by explicitly defining SBR audio object
649             * type in the bitstream. Implicit signalling is done by embedding
650             * SBR content in AAC extension payload specific to SBR, and hence
651             * requires an AAC decoder to perform pre-checks on actual audio frames.
652             *
653             * Thus, we could not say for sure whether a stream is
654             * AAC+/eAAC+ until the first data frame is decoded.
655             */
656            if (!mStreamInfo->sampleRate || !mStreamInfo->numChannels) {
657                // if ((mInputBufferCount > 2) && (mOutputBufferCount <= 1)) {
658                    ALOGD("Invalid AAC stream");
659                    // TODO: notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
660                    // mSignalledError = true;
661                // }
662            } else if ((mStreamInfo->sampleRate != prevSampleRate) ||
663                       (mStreamInfo->numChannels != prevNumChannels)) {
664                ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels",
665                      prevSampleRate, mStreamInfo->sampleRate,
666                      prevNumChannels, mStreamInfo->numChannels);
667
668                C2StreamSampleRateInfo::output sampleRateInfo(0u, mStreamInfo->sampleRate);
669                C2StreamChannelCountInfo::output channelCountInfo(0u, mStreamInfo->numChannels);
670                std::vector<std::unique_ptr<C2SettingResult>> failures;
671                c2_status_t err = mIntf->config(
672                        { &sampleRateInfo, &channelCountInfo },
673                        C2_MAY_BLOCK,
674                        &failures);
675                if (err == OK) {
676                    // TODO: this does not handle the case where the values are
677                    //       altered during config.
678                    configUpdate.push_back(C2Param::Copy(sampleRateInfo));
679                    configUpdate.push_back(C2Param::Copy(channelCountInfo));
680                }
681                // TODO: error handling
682            }
683            ALOGV("size = %zu", size);
684        } while (decoderErr == AAC_DEC_OK);
685    }
686
687    int32_t outputDelay = mStreamInfo->outputDelay * mStreamInfo->numChannels;
688
689    mBuffersInfo.push_back(std::move(inInfo));
690
691    if (!eos && mOutputDelayCompensated < outputDelay) {
692        // discard outputDelay at the beginning
693        int32_t toCompensate = outputDelay - mOutputDelayCompensated;
694        int32_t discard = outputDelayRingBufferSamplesAvailable();
695        if (discard > toCompensate) {
696            discard = toCompensate;
697        }
698        int32_t discarded = outputDelayRingBufferGetSamples(0, discard);
699        mOutputDelayCompensated += discarded;
700        return;
701    }
702
703    if (eos) {
704        drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work, &configUpdate);
705    } else {
706        drainRingBuffer(work, pool, &configUpdate, false /* not EOS */);
707    }
708}
709
710c2_status_t C2SoftAac::drainInternal(
711        uint32_t drainMode,
712        const std::shared_ptr<C2BlockPool> &pool,
713        const std::unique_ptr<C2Work> &work,
714        std::vector<std::unique_ptr<C2Param>> *configUpdate) {
715    if (drainMode == NO_DRAIN) {
716        ALOGW("drain with NO_DRAIN: no-op");
717        return C2_OK;
718    }
719    if (drainMode == DRAIN_CHAIN) {
720        ALOGW("DRAIN_CHAIN not supported");
721        return C2_OMITTED;
722    }
723
724    bool eos = (drainMode == DRAIN_COMPONENT_WITH_EOS);
725
726    drainDecoder();
727    drainRingBuffer(work, pool, configUpdate, eos);
728
729    if (eos) {
730        auto fillEmptyWork = [](const std::unique_ptr<C2Work> &work) {
731            work->worklets.front()->output.flags = work->input.flags;
732            work->worklets.front()->output.buffers.clear();
733            work->worklets.front()->output.ordinal = work->input.ordinal;
734            work->workletsProcessed = 1u;
735        };
736        while (mBuffersInfo.size() > 1u) {
737            finish(mBuffersInfo.front().frameIndex, fillEmptyWork);
738            mBuffersInfo.pop_front();
739        }
740        if (work->workletsProcessed == 0u) {
741            fillEmptyWork(work);
742        }
743        mBuffersInfo.clear();
744    }
745
746    return C2_OK;
747}
748
749c2_status_t C2SoftAac::drain(
750        uint32_t drainMode,
751        const std::shared_ptr<C2BlockPool> &pool) {
752    return drainInternal(drainMode, pool, nullptr);
753}
754
755c2_status_t C2SoftAac::onFlush_sm() {
756    drainDecoder();
757    mBuffersInfo.clear();
758
759    int avail;
760    while ((avail = outputDelayRingBufferSamplesAvailable()) > 0) {
761        if (avail > mStreamInfo->frameSize * mStreamInfo->numChannels) {
762            avail = mStreamInfo->frameSize * mStreamInfo->numChannels;
763        }
764        int32_t ns = outputDelayRingBufferGetSamples(0, avail);
765        if (ns != avail) {
766            ALOGW("not a complete frame of samples available");
767            break;
768        }
769    }
770    mOutputDelayRingBufferReadPos = mOutputDelayRingBufferWritePos;
771
772    return C2_OK;
773}
774
775void C2SoftAac::drainDecoder() {
776    // flush decoder until outputDelay is compensated
777    while (mOutputDelayCompensated > 0) {
778        // a buffer big enough for MAX_CHANNEL_COUNT channels of decoded HE-AAC
779        INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT];
780
781        // run DRC check
782        mDrcWrap.submitStreamData(mStreamInfo);
783        mDrcWrap.update();
784
785        AAC_DECODER_ERROR decoderErr =
786            aacDecoder_DecodeFrame(mAACDecoder,
787                                   tmpOutBuffer,
788                                   2048 * MAX_CHANNEL_COUNT,
789                                   AACDEC_FLUSH);
790        if (decoderErr != AAC_DEC_OK) {
791            ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr);
792        }
793
794        int32_t tmpOutBufferSamples = mStreamInfo->frameSize * mStreamInfo->numChannels;
795        if (tmpOutBufferSamples > mOutputDelayCompensated) {
796            tmpOutBufferSamples = mOutputDelayCompensated;
797        }
798        outputDelayRingBufferPutSamples(tmpOutBuffer, tmpOutBufferSamples);
799
800        mOutputDelayCompensated -= tmpOutBufferSamples;
801    }
802}
803
804class C2SoftAacDecFactory : public C2ComponentFactory {
805public:
806    C2SoftAacDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
807            GetCodec2PlatformComponentStore()->getParamReflector())) {
808    }
809
810    virtual c2_status_t createComponent(
811            c2_node_id_t id,
812            std::shared_ptr<C2Component>* const component,
813            std::function<void(C2Component*)> deleter) override {
814        *component = std::shared_ptr<C2Component>(
815                new C2SoftAac(COMPONENT_NAME,
816                              id,
817                              std::make_shared<C2SoftAac::IntfImpl>(mHelper)),
818                deleter);
819        return C2_OK;
820    }
821
822    virtual c2_status_t createInterface(
823            c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface,
824            std::function<void(C2ComponentInterface*)> deleter) override {
825        *interface = std::shared_ptr<C2ComponentInterface>(
826                new SimpleInterface<C2SoftAac::IntfImpl>(
827                        COMPONENT_NAME, id, std::make_shared<C2SoftAac::IntfImpl>(mHelper)),
828                deleter);
829        return C2_OK;
830    }
831
832    virtual ~C2SoftAacDecFactory() override = default;
833
834private:
835    std::shared_ptr<C2ReflectorHelper> mHelper;
836};
837
838}  // namespace android
839
840extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
841    ALOGV("in %s", __func__);
842    return new ::android::C2SoftAacDecFactory();
843}
844
845extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
846    ALOGV("in %s", __func__);
847    delete factory;
848}
849