1033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim/*
2033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Copyright (C) 2017 The Android Open Source Project
3033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim *
4033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Licensed under the Apache License, Version 2.0 (the "License");
5033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * you may not use this file except in compliance with the License.
6033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * You may obtain a copy of the License at
7033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim *
8033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim *      http://www.apache.org/licenses/LICENSE-2.0
9033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim *
10033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Unless required by applicable law or agreed to in writing, software
11033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * distributed under the License is distributed on an "AS IS" BASIS,
12033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * See the License for the specific language governing permissions and
14033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * limitations under the License.
15033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */
16033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
17d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar//#define LOG_NDEBUG 0
1872dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnar#define LOG_TAG "C2SoftAacDec"
19d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar#include <log/log.h>
20033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
21d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar#include <inttypes.h>
22d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar#include <math.h>
23d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar#include <numeric>
24033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
25033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <cutils/properties.h>
26033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <media/stagefright/foundation/MediaDefs.h>
27033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <media/stagefright/foundation/hexdump.h>
28033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <media/stagefright/MediaErrors.h>
29033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <utils/misc.h>
30033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
31d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar#include <C2PlatformSupport.h>
32d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar#include <SimpleC2Interface.h>
33d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar
34d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar#include "C2SoftAacDec.h"
35033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
36033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define FILEREAD_MAX_LAYERS 2
37033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
38033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define DRC_DEFAULT_MOBILE_REF_LEVEL 64  /* 64*-0.25dB = -16 dB below full scale for mobile conf */
39033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define DRC_DEFAULT_MOBILE_DRC_CUT   127 /* maximum compression of dynamic range for mobile conf */
40033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define DRC_DEFAULT_MOBILE_DRC_BOOST 127 /* maximum compression of dynamic range for mobile conf */
41033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define DRC_DEFAULT_MOBILE_DRC_HEAVY 1   /* switch for heavy compression for mobile conf */
42033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#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) */
43033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define MAX_CHANNEL_COUNT            8  /* maximum number of audio channels that can be decoded */
44033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim// names of properties that can be used to override the default DRC settings
45033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define PROP_DRC_OVERRIDE_REF_LEVEL  "aac_drc_reference_level"
46033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define PROP_DRC_OVERRIDE_CUT        "aac_drc_cut"
47033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define PROP_DRC_OVERRIDE_BOOST      "aac_drc_boost"
48033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define PROP_DRC_OVERRIDE_HEAVY      "aac_drc_heavy"
49033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define PROP_DRC_OVERRIDE_ENC_LEVEL "aac_drc_enc_target_level"
50033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
51033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimnamespace android {
52033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
5372dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarclass C2SoftAacDec::IntfImpl : public C2InterfaceHelper {
54277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kimpublic:
55277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
56277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        : C2InterfaceHelper(helper) {
57277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
58277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        setDerivedInstance(this);
59277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
60277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        addParameter(
61277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                DefineParam(mInputFormat, C2_NAME_INPUT_STREAM_FORMAT_SETTING)
62277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withConstValue(new C2StreamFormatConfig::input(0u, C2FormatCompressed))
63277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .build());
64277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
65277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        addParameter(
66277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                DefineParam(mOutputFormat, C2_NAME_OUTPUT_STREAM_FORMAT_SETTING)
67277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withConstValue(new C2StreamFormatConfig::output(0u, C2FormatAudio))
68277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .build());
69277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
70277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        addParameter(
71277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                DefineParam(mInputMediaType, C2_NAME_INPUT_PORT_MIME_SETTING)
72277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withConstValue(AllocSharedString<C2PortMimeConfig::input>(
73277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                        MEDIA_MIMETYPE_AUDIO_AAC))
74277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .build());
75277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
76277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        addParameter(
77277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                DefineParam(mOutputMediaType, C2_NAME_OUTPUT_PORT_MIME_SETTING)
78277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withConstValue(AllocSharedString<C2PortMimeConfig::output>(
79277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                        MEDIA_MIMETYPE_AUDIO_RAW))
80277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .build());
81277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
82277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        addParameter(
83277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                DefineParam(mSampleRate, C2_NAME_STREAM_SAMPLE_RATE_SETTING)
84277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withDefault(new C2StreamSampleRateInfo::output(0u, 44100))
85277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withFields({C2F(mSampleRate, value).oneOf({
86277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    7350, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
87277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                })})
88fcb80244c30a69f0728c53027d08b94dcda12643Wonsik Kim                .withSetter(Setter<decltype(*mSampleRate)>::NonStrictValueWithNoDeps)
89277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .build());
90277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
91277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        addParameter(
92277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                DefineParam(mChannelCount, C2_NAME_STREAM_CHANNEL_COUNT_SETTING)
93277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withDefault(new C2StreamChannelCountInfo::output(0u, 1))
94277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withFields({C2F(mChannelCount, value).inRange(1, 8)})
95277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
96277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .build());
97277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
98277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        addParameter(
99277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                DefineParam(mBitrate, C2_NAME_STREAM_BITRATE_SETTING)
100277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withDefault(new C2BitrateTuning::input(0u, 64000))
101277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withFields({C2F(mBitrate, value).inRange(8000, 960000)})
102277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
103277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .build());
104277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
105277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        addParameter(
10660f1d71e3ae1f64f147b9c2fe3153eb5f477a24aHarish Mahendrakar                DefineParam(mAacFormat, C2_NAME_STREAM_AAC_FORMAT_SETTING)
107277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withDefault(new C2StreamAacFormatInfo::input(0u, C2AacStreamFormatRaw))
108277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withFields({C2F(mAacFormat, value).oneOf({
109277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    C2AacStreamFormatRaw, C2AacStreamFormatAdts
110277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                })})
111277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withSetter(Setter<decltype(*mAacFormat)>::StrictValueWithNoDeps)
112277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .build());
113277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    }
114277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
115277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    bool isAdts() const { return mAacFormat->value == C2AacStreamFormatAdts; }
116277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
117277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kimprivate:
118277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    std::shared_ptr<C2StreamFormatConfig::input> mInputFormat;
119277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat;
120277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    std::shared_ptr<C2PortMimeConfig::input> mInputMediaType;
121277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    std::shared_ptr<C2PortMimeConfig::output> mOutputMediaType;
122277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
123277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
124277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    std::shared_ptr<C2BitrateTuning::input> mBitrate;
125033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
126277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    std::shared_ptr<C2StreamAacFormatInfo::input> mAacFormat;
127277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim};
128277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
1295c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnarconstexpr char COMPONENT_NAME[] = "c2.android.aac.decoder";
130277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
13172dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos MolnarC2SoftAacDec::C2SoftAacDec(
132277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        const char *name,
133277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        c2_node_id_t id,
134277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        const std::shared_ptr<IntfImpl> &intfImpl)
135277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
136e15da79378e753bbd20f1c0f5c6858cc89bd4141Wonsik Kim      mIntf(intfImpl),
137033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim      mAACDecoder(NULL),
138033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim      mStreamInfo(NULL),
139033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim      mSignalledError(false),
140033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim      mOutputDelayRingBuffer(NULL) {
141033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
142033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
14372dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos MolnarC2SoftAacDec::~C2SoftAacDec() {
144033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    onRelease();
145033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
146033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
14772dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarc2_status_t C2SoftAacDec::onInit() {
148033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    status_t err = initDecoder();
149033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    return err == OK ? C2_OK : C2_CORRUPTED;
150033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
151033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
15272dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarc2_status_t C2SoftAacDec::onStop() {
153033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    drainDecoder();
154033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    // reset the "configured" state
155033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mOutputDelayCompensated = 0;
156033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mOutputDelayRingBufferWritePos = 0;
157033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mOutputDelayRingBufferReadPos = 0;
158033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mOutputDelayRingBufferFilled = 0;
159033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mBuffersInfo.clear();
160033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
161033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    // To make the codec behave the same before and after a reset, we need to invalidate the
162033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    // streaminfo struct. This does that:
163033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mStreamInfo->sampleRate = 0; // TODO: mStreamInfo is read only
164033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
165033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mSignalledError = false;
166033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
167033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    return C2_OK;
168033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
169033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
17072dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarvoid C2SoftAacDec::onReset() {
171033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    (void)onStop();
172033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
173033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
17472dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarvoid C2SoftAacDec::onRelease() {
175033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (mAACDecoder) {
176033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        aacDecoder_Close(mAACDecoder);
177033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mAACDecoder = NULL;
178033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
179033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (mOutputDelayRingBuffer) {
180033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        delete[] mOutputDelayRingBuffer;
181033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mOutputDelayRingBuffer = NULL;
182033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
183033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
184033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
18572dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarstatus_t C2SoftAacDec::initDecoder() {
186033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    ALOGV("initDecoder()");
187033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    status_t status = UNKNOWN_ERROR;
188033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mAACDecoder = aacDecoder_Open(TT_MP4_ADIF, /* num layers */ 1);
189033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (mAACDecoder != NULL) {
190033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mStreamInfo = aacDecoder_GetStreamInfo(mAACDecoder);
191033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        if (mStreamInfo != NULL) {
192033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            status = OK;
193033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
194033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
195033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
196033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mOutputDelayCompensated = 0;
197033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mOutputDelayRingBufferSize = 2048 * MAX_CHANNEL_COUNT * kNumDelayBlocksMax;
198033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mOutputDelayRingBuffer = new short[mOutputDelayRingBufferSize];
199033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mOutputDelayRingBufferWritePos = 0;
200033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mOutputDelayRingBufferReadPos = 0;
201033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mOutputDelayRingBufferFilled = 0;
202033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
203033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (mAACDecoder == NULL) {
204033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGE("AAC decoder is null. TODO: Can not call aacDecoder_SetParam in the following code");
205033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
206033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
207033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    //aacDecoder_SetParam(mAACDecoder, AAC_PCM_LIMITER_ENABLE, 0);
208033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
209033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    //init DRC wrapper
210033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mDrcWrap.setDecoderHandle(mAACDecoder);
211033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mDrcWrap.submitStreamData(mStreamInfo);
212033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
213033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    // for streams that contain metadata, use the mobile profile DRC settings unless overridden by platform properties
214033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    // TODO: change the DRC settings depending on audio output device type (HDMI, loadspeaker, headphone)
215033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    char value[PROPERTY_VALUE_MAX];
216033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    //  DRC_PRES_MODE_WRAP_DESIRED_TARGET
217033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (property_get(PROP_DRC_OVERRIDE_REF_LEVEL, value, NULL)) {
218033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        unsigned refLevel = atoi(value);
219033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGV("AAC decoder using desired DRC target reference level of %d instead of %d", refLevel,
220033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                DRC_DEFAULT_MOBILE_REF_LEVEL);
221033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_TARGET, refLevel);
222033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    } else {
223033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_TARGET, DRC_DEFAULT_MOBILE_REF_LEVEL);
224033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
225033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    //  DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR
226033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (property_get(PROP_DRC_OVERRIDE_CUT, value, NULL)) {
227033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        unsigned cut = atoi(value);
228033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGV("AAC decoder using desired DRC attenuation factor of %d instead of %d", cut,
229033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                DRC_DEFAULT_MOBILE_DRC_CUT);
230033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR, cut);
231033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    } else {
232033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR, DRC_DEFAULT_MOBILE_DRC_CUT);
233033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
234033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    //  DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR
235033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (property_get(PROP_DRC_OVERRIDE_BOOST, value, NULL)) {
236033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        unsigned boost = atoi(value);
237033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGV("AAC decoder using desired DRC boost factor of %d instead of %d", boost,
238033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                DRC_DEFAULT_MOBILE_DRC_BOOST);
239033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR, boost);
240033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    } else {
241033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR, DRC_DEFAULT_MOBILE_DRC_BOOST);
242033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
243033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    //  DRC_PRES_MODE_WRAP_DESIRED_HEAVY
244033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (property_get(PROP_DRC_OVERRIDE_HEAVY, value, NULL)) {
245033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        unsigned heavy = atoi(value);
246033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGV("AAC decoder using desried DRC heavy compression switch of %d instead of %d", heavy,
247033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                DRC_DEFAULT_MOBILE_DRC_HEAVY);
248033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_HEAVY, heavy);
249033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    } else {
250033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_HEAVY, DRC_DEFAULT_MOBILE_DRC_HEAVY);
251033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
252033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    // DRC_PRES_MODE_WRAP_ENCODER_TARGET
253033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (property_get(PROP_DRC_OVERRIDE_ENC_LEVEL, value, NULL)) {
254033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        unsigned encoderRefLevel = atoi(value);
255033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGV("AAC decoder using encoder-side DRC reference level of %d instead of %d",
256033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                encoderRefLevel, DRC_DEFAULT_MOBILE_ENC_LEVEL);
257033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_ENCODER_TARGET, encoderRefLevel);
258033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    } else {
259033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_ENCODER_TARGET, DRC_DEFAULT_MOBILE_ENC_LEVEL);
260033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
261033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
262033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    // By default, the decoder creates a 5.1 channel downmix signal.
263033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    // For seven and eight channel input streams, enable 6.1 and 7.1 channel output
264033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    aacDecoder_SetParam(mAACDecoder, AAC_PCM_MAX_OUTPUT_CHANNELS, -1);
265033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
266033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    return status;
267033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
268033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
26972dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarbool C2SoftAacDec::outputDelayRingBufferPutSamples(INT_PCM *samples, int32_t numSamples) {
270033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (numSamples == 0) {
271033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return true;
272033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
273033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (outputDelayRingBufferSpaceLeft() < numSamples) {
274033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGE("RING BUFFER WOULD OVERFLOW");
275033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return false;
276033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
277033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (mOutputDelayRingBufferWritePos + numSamples <= mOutputDelayRingBufferSize
278033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            && (mOutputDelayRingBufferReadPos <= mOutputDelayRingBufferWritePos
279033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    || mOutputDelayRingBufferReadPos > mOutputDelayRingBufferWritePos + numSamples)) {
280033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        // faster memcopy loop without checks, if the preconditions allow this
281033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        for (int32_t i = 0; i < numSamples; i++) {
282033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            mOutputDelayRingBuffer[mOutputDelayRingBufferWritePos++] = samples[i];
283033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
284033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
285033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        if (mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferSize) {
286033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            mOutputDelayRingBufferWritePos -= mOutputDelayRingBufferSize;
287033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
288033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    } else {
28972dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnar        ALOGV("slow C2SoftAacDec::outputDelayRingBufferPutSamples()");
290033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
291033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        for (int32_t i = 0; i < numSamples; i++) {
292033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            mOutputDelayRingBuffer[mOutputDelayRingBufferWritePos] = samples[i];
293033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            mOutputDelayRingBufferWritePos++;
294033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            if (mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferSize) {
295033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                mOutputDelayRingBufferWritePos -= mOutputDelayRingBufferSize;
296033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            }
297033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
298033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
299033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mOutputDelayRingBufferFilled += numSamples;
300033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    return true;
301033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
302033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
30372dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarint32_t C2SoftAacDec::outputDelayRingBufferGetSamples(INT_PCM *samples, int32_t numSamples) {
304033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
305033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (numSamples > mOutputDelayRingBufferFilled) {
306033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGE("RING BUFFER WOULD UNDERRUN");
307033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return -1;
308033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
309033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
310033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (mOutputDelayRingBufferReadPos + numSamples <= mOutputDelayRingBufferSize
311033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            && (mOutputDelayRingBufferWritePos < mOutputDelayRingBufferReadPos
312033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    || mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferReadPos + numSamples)) {
313033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        // faster memcopy loop without checks, if the preconditions allow this
314033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        if (samples != 0) {
315033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            for (int32_t i = 0; i < numSamples; i++) {
316033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                samples[i] = mOutputDelayRingBuffer[mOutputDelayRingBufferReadPos++];
317033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            }
318033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        } else {
319033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            mOutputDelayRingBufferReadPos += numSamples;
320033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
321033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        if (mOutputDelayRingBufferReadPos >= mOutputDelayRingBufferSize) {
322033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            mOutputDelayRingBufferReadPos -= mOutputDelayRingBufferSize;
323033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
324033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    } else {
32572dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnar        ALOGV("slow C2SoftAacDec::outputDelayRingBufferGetSamples()");
326033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
327033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        for (int32_t i = 0; i < numSamples; i++) {
328033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            if (samples != 0) {
329033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                samples[i] = mOutputDelayRingBuffer[mOutputDelayRingBufferReadPos];
330033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            }
331033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            mOutputDelayRingBufferReadPos++;
332033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            if (mOutputDelayRingBufferReadPos >= mOutputDelayRingBufferSize) {
333033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                mOutputDelayRingBufferReadPos -= mOutputDelayRingBufferSize;
334033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            }
335033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
336033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
337033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mOutputDelayRingBufferFilled -= numSamples;
338033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    return numSamples;
339033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
340033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
34172dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarint32_t C2SoftAacDec::outputDelayRingBufferSamplesAvailable() {
342033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    return mOutputDelayRingBufferFilled;
343033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
344033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
34572dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarint32_t C2SoftAacDec::outputDelayRingBufferSpaceLeft() {
346033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    return mOutputDelayRingBufferSize - outputDelayRingBufferSamplesAvailable();
347033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
348033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
34972dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarvoid C2SoftAacDec::drainRingBuffer(
350033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        const std::unique_ptr<C2Work> &work,
351033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        const std::shared_ptr<C2BlockPool> &pool,
352033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        bool eos) {
353033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    while (!mBuffersInfo.empty() && outputDelayRingBufferSamplesAvailable()
354033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            >= mStreamInfo->frameSize * mStreamInfo->numChannels) {
355033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        Info &outInfo = mBuffersInfo.front();
356033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGV("outInfo.frameIndex = %" PRIu64, outInfo.frameIndex);
357d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar        int samplesize __unused = mStreamInfo->numChannels * sizeof(int16_t);
358033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
359033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int available = outputDelayRingBufferSamplesAvailable();
360033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int numFrames = outInfo.decodedSizes.size();
361033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int numSamples = numFrames * (mStreamInfo->frameSize * mStreamInfo->numChannels);
362033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        if (available < numSamples) {
363033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            if (eos) {
364033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                numSamples = available;
365033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            } else {
366033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                break;
367033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            }
368033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
369033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGV("%d samples available (%d), or %d frames",
370033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                numSamples, available, numFrames);
371033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGV("getting %d from ringbuffer", numSamples);
372033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
373033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        std::shared_ptr<C2LinearBlock> block;
374033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        std::function<void(const std::unique_ptr<C2Work>&)> fillWork =
3758c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim            [&block, numSamples, pool, this]()
376033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    -> std::function<void(const std::unique_ptr<C2Work>&)> {
3778c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim                auto fillEmptyWork = [](
378277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                        const std::unique_ptr<C2Work> &work, c2_status_t err) {
379033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    work->result = err;
380277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    C2FrameData &output = work->worklets.front()->output;
381277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    output.flags = work->input.flags;
382277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    output.buffers.clear();
383277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    output.ordinal = work->input.ordinal;
384277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
385033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    work->workletsProcessed = 1u;
386033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                };
387033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
388033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                using namespace std::placeholders;
389033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                if (numSamples == 0) {
390033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    return std::bind(fillEmptyWork, _1, C2_OK);
391033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                }
392033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
393033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                // TODO: error handling, proper usage, etc.
394033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
395033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                c2_status_t err = pool->fetchLinearBlock(
396033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                        numSamples * sizeof(int16_t), usage, &block);
397033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                if (err != C2_OK) {
398033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    ALOGD("failed to fetch a linear block (%d)", err);
399033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    mSignalledError = true;
400033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    return std::bind(fillEmptyWork, _1, C2_NO_MEMORY);
401033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                }
402033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                C2WriteView wView = block->map().get();
403033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                // TODO
404033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                INT_PCM *outBuffer = reinterpret_cast<INT_PCM *>(wView.data());
405033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                int32_t ns = outputDelayRingBufferGetSamples(outBuffer, numSamples);
406033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                if (ns != numSamples) {
407033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    ALOGE("not a complete frame of samples available");
408033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    mSignalledError = true;
409033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    return std::bind(fillEmptyWork, _1, C2_CORRUPTED);
410033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                }
4118c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim                return [buffer = createLinearBuffer(block)](
412277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                        const std::unique_ptr<C2Work> &work) {
413033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    work->result = C2_OK;
414277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    C2FrameData &output = work->worklets.front()->output;
415277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    output.flags = work->input.flags;
416277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    output.buffers.clear();
417277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    output.buffers.push_back(buffer);
418277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    output.ordinal = work->input.ordinal;
419033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    work->workletsProcessed = 1u;
420033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                };
421033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            }();
422033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
423033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        if (work && work->input.ordinal.frameIndex == c2_cntr64_t(outInfo.frameIndex)) {
424033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            fillWork(work);
425033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        } else {
426033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            finish(outInfo.frameIndex, fillWork);
427033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
428033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
429033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGV("out timestamp %" PRIu64 " / %u", outInfo.timestamp, block ? block->capacity() : 0);
430033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mBuffersInfo.pop_front();
431033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
432033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
433033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
43472dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarvoid C2SoftAacDec::process(
435033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        const std::unique_ptr<C2Work> &work,
436033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        const std::shared_ptr<C2BlockPool> &pool) {
437033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    work->workletsProcessed = 0u;
438033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    work->result = C2_OK;
439277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    work->worklets.front()->output.configUpdate.clear();
440033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (mSignalledError) {
441033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return;
442033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
443033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
444033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    UCHAR* inBuffer[FILEREAD_MAX_LAYERS];
445033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    UINT inBufferLength[FILEREAD_MAX_LAYERS] = {0};
446033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    UINT bytesValid[FILEREAD_MAX_LAYERS] = {0};
447033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
448033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT];
44945c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim    C2ReadView view = mDummyReadView;
450033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    size_t offset = 0u;
45145c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim    size_t size = 0u;
45245c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim    if (!work->input.buffers.empty()) {
45345c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim        view = work->input.buffers[0]->data().linearBlocks().front().map().get();
45445c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim        size = view.capacity();
45545c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim    }
456033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
457033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
458033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    bool codecConfig = (work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0;
459033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
460033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    //TODO
461033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#if 0
462033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (mInputBufferCount == 0 && !codecConfig) {
463033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGW("first buffer should have FLAG_CODEC_CONFIG set");
464033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        codecConfig = true;
465033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
466033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#endif
46745c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim    if (codecConfig && size > 0u) {
468033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        // const_cast because of libAACdec method signature.
469033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        inBuffer[0] = const_cast<UCHAR *>(view.data() + offset);
470033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        inBufferLength[0] = size;
471033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
472033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        AAC_DECODER_ERROR decoderErr =
473033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            aacDecoder_ConfigRaw(mAACDecoder,
474033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                                 inBuffer,
475033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                                 inBufferLength);
476033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
477033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        if (decoderErr != AAC_DEC_OK) {
478033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            ALOGE("aacDecoder_ConfigRaw decoderErr = 0x%4.4x", decoderErr);
479033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            mSignalledError = true;
480033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            // TODO: error
481033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            return;
482033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
483033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
484033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        work->worklets.front()->output.ordinal = work->input.ordinal;
485033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        work->worklets.front()->output.buffers.clear();
486033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
487033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return;
488033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
489033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
490033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    Info inInfo;
491033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    inInfo.frameIndex = work->input.ordinal.frameIndex.peeku();
492033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    inInfo.timestamp = work->input.ordinal.timestamp.peeku();
493033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    inInfo.bufferSize = size;
494033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    inInfo.decodedSizes.clear();
495033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    while (size > 0u) {
496033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGV("size = %zu", size);
497277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        if (mIntf->isAdts()) {
498033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            size_t adtsHeaderSize = 0;
499033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            // skip 30 bits, aac_frame_length follows.
500033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
501033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
502033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            const uint8_t *adtsHeader = view.data() + offset;
503033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
504033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            bool signalError = false;
505033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            if (size < 7) {
506033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                ALOGE("Audio data too short to contain even the ADTS header. "
507033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                        "Got %zu bytes.", size);
508033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                hexdump(adtsHeader, size);
509033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                signalError = true;
510033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            } else {
511033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                bool protectionAbsent = (adtsHeader[1] & 1);
512033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
513033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                unsigned aac_frame_length =
514033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    ((adtsHeader[3] & 3) << 11)
515033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    | (adtsHeader[4] << 3)
516033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    | (adtsHeader[5] >> 5);
517033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
518033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                if (size < aac_frame_length) {
519033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    ALOGE("Not enough audio data for the complete frame. "
520033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                            "Got %zu bytes, frame size according to the ADTS "
521033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                            "header is %u bytes.",
522033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                            size, aac_frame_length);
523033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    hexdump(adtsHeader, size);
524033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    signalError = true;
525033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                } else {
526033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    adtsHeaderSize = (protectionAbsent ? 7 : 9);
527033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    if (aac_frame_length < adtsHeaderSize) {
528033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                        signalError = true;
529033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    } else {
530033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                        // const_cast because of libAACdec method signature.
531033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                        inBuffer[0] = const_cast<UCHAR *>(adtsHeader + adtsHeaderSize);
532033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                        inBufferLength[0] = aac_frame_length - adtsHeaderSize;
533033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
534033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                        offset += adtsHeaderSize;
535033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                        size -= adtsHeaderSize;
536033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    }
537033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                }
538033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            }
539033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
540033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            if (signalError) {
541033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                mSignalledError = true;
542033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                // TODO: notify(OMX_EventError, OMX_ErrorStreamCorrupt, ERROR_MALFORMED, NULL);
543033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                return;
544033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            }
545033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        } else {
546033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            // const_cast because of libAACdec method signature.
547033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            inBuffer[0] = const_cast<UCHAR *>(view.data() + offset);
548033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            inBufferLength[0] = size;
549033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
550033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
551033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        // Fill and decode
552033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        bytesValid[0] = inBufferLength[0];
553033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
554033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        INT prevSampleRate = mStreamInfo->sampleRate;
555033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        INT prevNumChannels = mStreamInfo->numChannels;
556033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
557033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        aacDecoder_Fill(mAACDecoder,
558033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                        inBuffer,
559033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                        inBufferLength,
560033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                        bytesValid);
561033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
562033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        // run DRC check
563033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mDrcWrap.submitStreamData(mStreamInfo);
564033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mDrcWrap.update();
565033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
566033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0];
567033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        size -= inBufferUsedLength;
568033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        offset += inBufferUsedLength;
569033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
570033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        AAC_DECODER_ERROR decoderErr;
571033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        do {
572033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            if (outputDelayRingBufferSpaceLeft() <
573033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    (mStreamInfo->frameSize * mStreamInfo->numChannels)) {
574033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                ALOGV("skipping decode: not enough space left in ringbuffer");
575033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                break;
576033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            }
577033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
578033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            int numConsumed = mStreamInfo->numTotalBytes;
579033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
580033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                                       tmpOutBuffer,
581033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                                       2048 * MAX_CHANNEL_COUNT,
582033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                                       0 /* flags */);
583033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
584033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            numConsumed = mStreamInfo->numTotalBytes - numConsumed;
585033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
586033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            if (decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
587033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                break;
588033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            }
589033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            inInfo.decodedSizes.push_back(numConsumed);
590033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
591033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            if (decoderErr != AAC_DEC_OK) {
592033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr);
593033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            }
594033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
595033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            if (bytesValid[0] != 0) {
596033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                ALOGE("bytesValid[0] != 0 should never happen");
597033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                mSignalledError = true;
598033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                // TODO: notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
599033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                return;
600033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            }
601033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
602033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            size_t numOutBytes =
603033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels;
604033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
605033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            if (decoderErr == AAC_DEC_OK) {
606033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                if (!outputDelayRingBufferPutSamples(tmpOutBuffer,
607033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                        mStreamInfo->frameSize * mStreamInfo->numChannels)) {
608033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    mSignalledError = true;
609033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    // TODO: notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
610033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    return;
611033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                }
612033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            } else {
613033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                ALOGW("AAC decoder returned error 0x%4.4x, substituting silence", decoderErr);
614033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
615033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                memset(tmpOutBuffer, 0, numOutBytes); // TODO: check for overflow
616033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
617033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                if (!outputDelayRingBufferPutSamples(tmpOutBuffer,
618033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                        mStreamInfo->frameSize * mStreamInfo->numChannels)) {
619033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    mSignalledError = true;
620033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    // TODO: notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
621033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    return;
622033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                }
623033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
624033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                // Discard input buffer.
625033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                size = 0;
626033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
627033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);
628033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
629033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                // After an error, replace bufferSize with the sum of the
630033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                // decodedSizes to resynchronize the in/out lists.
631033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                inInfo.decodedSizes.pop_back();
632033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                inInfo.bufferSize = std::accumulate(
633033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                        inInfo.decodedSizes.begin(), inInfo.decodedSizes.end(), 0);
634033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
635033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                // fall through
636033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            }
637033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
638033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            /*
639033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim             * AAC+/eAAC+ streams can be signalled in two ways: either explicitly
640033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim             * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual
641033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim             * rate system and the sampling rate in the final output is actually
642033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim             * doubled compared with the core AAC decoder sampling rate.
643033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim             *
644033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim             * Explicit signalling is done by explicitly defining SBR audio object
645033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim             * type in the bitstream. Implicit signalling is done by embedding
646033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim             * SBR content in AAC extension payload specific to SBR, and hence
647033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim             * requires an AAC decoder to perform pre-checks on actual audio frames.
648033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim             *
649033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim             * Thus, we could not say for sure whether a stream is
650033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim             * AAC+/eAAC+ until the first data frame is decoded.
651033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim             */
652033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            if (!mStreamInfo->sampleRate || !mStreamInfo->numChannels) {
653277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                // if ((mInputBufferCount > 2) && (mOutputBufferCount <= 1)) {
654277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    ALOGD("Invalid AAC stream");
655033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    // TODO: notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
656277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    // mSignalledError = true;
657277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                // }
658277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim            } else if ((mStreamInfo->sampleRate != prevSampleRate) ||
659277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                       (mStreamInfo->numChannels != prevNumChannels)) {
660277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels",
661277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                      prevSampleRate, mStreamInfo->sampleRate,
662277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                      prevNumChannels, mStreamInfo->numChannels);
663277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
664277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                C2StreamSampleRateInfo::output sampleRateInfo(0u, mStreamInfo->sampleRate);
665277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                C2StreamChannelCountInfo::output channelCountInfo(0u, mStreamInfo->numChannels);
666277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                std::vector<std::unique_ptr<C2SettingResult>> failures;
667277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                c2_status_t err = mIntf->config(
668277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                        { &sampleRateInfo, &channelCountInfo },
669277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                        C2_MAY_BLOCK,
670277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                        &failures);
671277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                if (err == OK) {
672277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    // TODO: this does not handle the case where the values are
673277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    //       altered during config.
6748c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim                    C2FrameData &output = work->worklets.front()->output;
6758c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim                    output.configUpdate.push_back(C2Param::Copy(sampleRateInfo));
6768c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim                    output.configUpdate.push_back(C2Param::Copy(channelCountInfo));
677033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                }
678277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                // TODO: error handling
679033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            }
680033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            ALOGV("size = %zu", size);
681033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        } while (decoderErr == AAC_DEC_OK);
682033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
683033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
684033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    int32_t outputDelay = mStreamInfo->outputDelay * mStreamInfo->numChannels;
685033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
686033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mBuffersInfo.push_back(std::move(inInfo));
687033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
688033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (!eos && mOutputDelayCompensated < outputDelay) {
689033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        // discard outputDelay at the beginning
690033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int32_t toCompensate = outputDelay - mOutputDelayCompensated;
691033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int32_t discard = outputDelayRingBufferSamplesAvailable();
692033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        if (discard > toCompensate) {
693033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            discard = toCompensate;
694033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
695033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int32_t discarded = outputDelayRingBufferGetSamples(0, discard);
696033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mOutputDelayCompensated += discarded;
697033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return;
698033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
699033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
700033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (eos) {
7018c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim        drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work);
702033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    } else {
7038c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim        drainRingBuffer(work, pool, false /* not EOS */);
704033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
705033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
706033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
70772dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarc2_status_t C2SoftAacDec::drainInternal(
708033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        uint32_t drainMode,
709033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        const std::shared_ptr<C2BlockPool> &pool,
7108c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim        const std::unique_ptr<C2Work> &work) {
711033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (drainMode == NO_DRAIN) {
712033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGW("drain with NO_DRAIN: no-op");
713033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return C2_OK;
714033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
715033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (drainMode == DRAIN_CHAIN) {
716033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGW("DRAIN_CHAIN not supported");
717033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return C2_OMITTED;
718033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
719033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
720033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    bool eos = (drainMode == DRAIN_COMPONENT_WITH_EOS);
721033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
722033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    drainDecoder();
7238c90d948d154ccf81c4a7113f3aefbe329ce6e8dWonsik Kim    drainRingBuffer(work, pool, eos);
724033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
725033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (eos) {
726033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        auto fillEmptyWork = [](const std::unique_ptr<C2Work> &work) {
727033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            work->worklets.front()->output.flags = work->input.flags;
728033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            work->worklets.front()->output.buffers.clear();
729033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            work->worklets.front()->output.ordinal = work->input.ordinal;
730033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            work->workletsProcessed = 1u;
731033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        };
732033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        while (mBuffersInfo.size() > 1u) {
733033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            finish(mBuffersInfo.front().frameIndex, fillEmptyWork);
734033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            mBuffersInfo.pop_front();
735033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
736fd7de566b96cd02944556c4ccec08df88bdbc0b2Harish Mahendrakar        if (work && work->workletsProcessed == 0u) {
737033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            fillEmptyWork(work);
738033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
739033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mBuffersInfo.clear();
740033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
741033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
742033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    return C2_OK;
743033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
744033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
74572dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarc2_status_t C2SoftAacDec::drain(
746033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        uint32_t drainMode,
747033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        const std::shared_ptr<C2BlockPool> &pool) {
748033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    return drainInternal(drainMode, pool, nullptr);
749033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
750033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
75172dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarc2_status_t C2SoftAacDec::onFlush_sm() {
752033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    drainDecoder();
753033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mBuffersInfo.clear();
754033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
755033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    int avail;
756033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    while ((avail = outputDelayRingBufferSamplesAvailable()) > 0) {
757033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        if (avail > mStreamInfo->frameSize * mStreamInfo->numChannels) {
758033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            avail = mStreamInfo->frameSize * mStreamInfo->numChannels;
759033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
760033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int32_t ns = outputDelayRingBufferGetSamples(0, avail);
761033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        if (ns != avail) {
762033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            ALOGW("not a complete frame of samples available");
763033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            break;
764033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
765033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
766033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mOutputDelayRingBufferReadPos = mOutputDelayRingBufferWritePos;
767033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
768033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    return C2_OK;
769033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
770033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
77172dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarvoid C2SoftAacDec::drainDecoder() {
772033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    // flush decoder until outputDelay is compensated
773033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    while (mOutputDelayCompensated > 0) {
774033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        // a buffer big enough for MAX_CHANNEL_COUNT channels of decoded HE-AAC
775033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT];
776033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
777033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        // run DRC check
778033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mDrcWrap.submitStreamData(mStreamInfo);
779033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mDrcWrap.update();
780033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
781033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        AAC_DECODER_ERROR decoderErr =
782033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            aacDecoder_DecodeFrame(mAACDecoder,
783033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                                   tmpOutBuffer,
784033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                                   2048 * MAX_CHANNEL_COUNT,
785033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                                   AACDEC_FLUSH);
786033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        if (decoderErr != AAC_DEC_OK) {
787033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr);
788033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
789033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
790033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int32_t tmpOutBufferSamples = mStreamInfo->frameSize * mStreamInfo->numChannels;
791033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        if (tmpOutBufferSamples > mOutputDelayCompensated) {
792033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            tmpOutBufferSamples = mOutputDelayCompensated;
793033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
794033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        outputDelayRingBufferPutSamples(tmpOutBuffer, tmpOutBufferSamples);
795033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
796033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mOutputDelayCompensated -= tmpOutBufferSamples;
797033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
798033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
799033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
800033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass C2SoftAacDecFactory : public C2ComponentFactory {
801033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic:
802277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    C2SoftAacDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
803277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim            GetCodec2PlatformComponentStore()->getParamReflector())) {
804277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    }
805277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
806033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    virtual c2_status_t createComponent(
807033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            c2_node_id_t id,
808033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            std::shared_ptr<C2Component>* const component,
809033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            std::function<void(C2Component*)> deleter) override {
810277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        *component = std::shared_ptr<C2Component>(
81172dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnar                new C2SoftAacDec(COMPONENT_NAME,
812277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                              id,
81372dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnar                              std::make_shared<C2SoftAacDec::IntfImpl>(mHelper)),
814277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                deleter);
815033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return C2_OK;
816033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
817033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
818033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    virtual c2_status_t createInterface(
819277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim            c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface,
820033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            std::function<void(C2ComponentInterface*)> deleter) override {
821277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        *interface = std::shared_ptr<C2ComponentInterface>(
82272dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnar                new SimpleInterface<C2SoftAacDec::IntfImpl>(
82372dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnar                        COMPONENT_NAME, id, std::make_shared<C2SoftAacDec::IntfImpl>(mHelper)),
824277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                deleter);
825033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return C2_OK;
826033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
827033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
828033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    virtual ~C2SoftAacDecFactory() override = default;
829277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
830277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kimprivate:
831277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    std::shared_ptr<C2ReflectorHelper> mHelper;
832033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim};
833033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
834033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}  // namespace android
835033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
836033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimextern "C" ::C2ComponentFactory* CreateCodec2Factory() {
837033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    ALOGV("in %s", __func__);
838033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    return new ::android::C2SoftAacDecFactory();
839033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
840033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
841033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimextern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
842033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    ALOGV("in %s", __func__);
843033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    delete factory;
844033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
845