C2SoftAacDec.cpp revision 277b7295f317c6597fadb116b6aee5ca3be106c1
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
17033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define LOG_NDEBUG 0
18033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define LOG_TAG "C2SoftAac"
19033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <utils/Log.h>
20033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
21033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include "C2SoftAac.h"
22033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
23033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <C2PlatformSupport.h>
24277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim#include <SimpleInterfaceCommon.h>
25033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
26033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <cutils/properties.h>
27033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <media/stagefright/foundation/ADebug.h>
28033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <media/stagefright/foundation/MediaDefs.h>
29033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <media/stagefright/foundation/hexdump.h>
30033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <media/stagefright/MediaErrors.h>
31033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <utils/misc.h>
32033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
33033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <inttypes.h>
34033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <math.h>
35033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <numeric>
36033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
37033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define FILEREAD_MAX_LAYERS 2
38033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
39033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define DRC_DEFAULT_MOBILE_REF_LEVEL 64  /* 64*-0.25dB = -16 dB below full scale for mobile conf */
40033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define DRC_DEFAULT_MOBILE_DRC_CUT   127 /* maximum compression of dynamic range for mobile conf */
41033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define DRC_DEFAULT_MOBILE_DRC_BOOST 127 /* maximum compression of dynamic range for mobile conf */
42033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define DRC_DEFAULT_MOBILE_DRC_HEAVY 1   /* switch for heavy compression for mobile conf */
43033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik 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) */
44033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define MAX_CHANNEL_COUNT            8  /* maximum number of audio channels that can be decoded */
45033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim// names of properties that can be used to override the default DRC settings
46033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define PROP_DRC_OVERRIDE_REF_LEVEL  "aac_drc_reference_level"
47033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define PROP_DRC_OVERRIDE_CUT        "aac_drc_cut"
48033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define PROP_DRC_OVERRIDE_BOOST      "aac_drc_boost"
49033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define PROP_DRC_OVERRIDE_HEAVY      "aac_drc_heavy"
50033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#define PROP_DRC_OVERRIDE_ENC_LEVEL "aac_drc_enc_target_level"
51033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
52033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimnamespace android {
53033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
54277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kimclass C2SoftAac::IntfImpl : public C2InterfaceHelper {
55277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kimpublic:
56277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
57277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        : C2InterfaceHelper(helper) {
58277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
59277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        setDerivedInstance(this);
60277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
61277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        addParameter(
62277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                DefineParam(mInputFormat, C2_NAME_INPUT_STREAM_FORMAT_SETTING)
63277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withConstValue(new C2StreamFormatConfig::input(0u, C2FormatCompressed))
64277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .build());
65277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
66277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        addParameter(
67277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                DefineParam(mOutputFormat, C2_NAME_OUTPUT_STREAM_FORMAT_SETTING)
68277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withConstValue(new C2StreamFormatConfig::output(0u, C2FormatAudio))
69277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .build());
70277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
71277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        addParameter(
72277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                DefineParam(mInputMediaType, C2_NAME_INPUT_PORT_MIME_SETTING)
73277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withConstValue(AllocSharedString<C2PortMimeConfig::input>(
74277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                        MEDIA_MIMETYPE_AUDIO_AAC))
75277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .build());
76277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
77277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        addParameter(
78277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                DefineParam(mOutputMediaType, C2_NAME_OUTPUT_PORT_MIME_SETTING)
79277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withConstValue(AllocSharedString<C2PortMimeConfig::output>(
80277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                        MEDIA_MIMETYPE_AUDIO_RAW))
81277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .build());
82277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
83277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        addParameter(
84277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                DefineParam(mSampleRate, C2_NAME_STREAM_SAMPLE_RATE_SETTING)
85277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withDefault(new C2StreamSampleRateInfo::output(0u, 44100))
86277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withFields({C2F(mSampleRate, value).oneOf({
87277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    7350, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
88277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                })})
89277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
90277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .build());
91277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
92277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        addParameter(
93277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                DefineParam(mChannelCount, C2_NAME_STREAM_CHANNEL_COUNT_SETTING)
94277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withDefault(new C2StreamChannelCountInfo::output(0u, 1))
95277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withFields({C2F(mChannelCount, value).inRange(1, 8)})
96277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
97277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .build());
98277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
99277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        addParameter(
100277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                DefineParam(mBitrate, C2_NAME_STREAM_BITRATE_SETTING)
101277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withDefault(new C2BitrateTuning::input(0u, 64000))
102277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withFields({C2F(mBitrate, value).inRange(8000, 960000)})
103277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
104277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .build());
105277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
106277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        addParameter(
107277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                DefineParam(mAacFormat, C2_NAME_STREAM_BITRATE_SETTING)
108277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withDefault(new C2StreamAacFormatInfo::input(0u, C2AacStreamFormatRaw))
109277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withFields({C2F(mAacFormat, value).oneOf({
110277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    C2AacStreamFormatRaw, C2AacStreamFormatAdts
111277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                })})
112277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .withSetter(Setter<decltype(*mAacFormat)>::StrictValueWithNoDeps)
113277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                .build());
114277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    }
115277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
116277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    bool isAdts() const { return mAacFormat->value == C2AacStreamFormatAdts; }
117277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
118277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kimprivate:
119277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    std::shared_ptr<C2StreamFormatConfig::input> mInputFormat;
120277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat;
121277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    std::shared_ptr<C2PortMimeConfig::input> mInputMediaType;
122277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    std::shared_ptr<C2PortMimeConfig::output> mOutputMediaType;
123277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
124277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
125277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    std::shared_ptr<C2BitrateTuning::input> mBitrate;
126033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
127277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    std::shared_ptr<C2StreamAacFormatInfo::input> mAacFormat;
128277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim};
129277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
130277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kimconstexpr char COMPONENT_NAME[] = "c2.google.aac.decoder";
131277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
132277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik KimC2SoftAac::C2SoftAac(
133277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        const char *name,
134277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        c2_node_id_t id,
135277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        const std::shared_ptr<IntfImpl> &intfImpl)
136277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
137033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim      mAACDecoder(NULL),
138033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim      mStreamInfo(NULL),
139033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim      mSignalledError(false),
140033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim      mOutputDelayRingBuffer(NULL) {
141033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
142033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
143033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik KimC2SoftAac::~C2SoftAac() {
144033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    onRelease();
145033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
146033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
147033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimc2_status_t C2SoftAac::onInit() {
148033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    status_t err = initDecoder();
149033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    return err == OK ? C2_OK : C2_CORRUPTED;
150033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
151033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
152033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimc2_status_t C2SoftAac::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
170033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid C2SoftAac::onReset() {
171033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    (void)onStop();
172033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
173033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
174033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid C2SoftAac::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
185033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimstatus_t C2SoftAac::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
269033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimbool C2SoftAac::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 {
289033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGV("slow C2SoftAac::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
303033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimint32_t C2SoftAac::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 {
325033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGV("slow C2SoftAac::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
341033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimint32_t C2SoftAac::outputDelayRingBufferSamplesAvailable() {
342033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    return mOutputDelayRingBufferFilled;
343033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
344033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
345033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimint32_t C2SoftAac::outputDelayRingBufferSpaceLeft() {
346033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    return mOutputDelayRingBufferSize - outputDelayRingBufferSamplesAvailable();
347033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
348033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
349033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid C2SoftAac::drainRingBuffer(
350033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        const std::unique_ptr<C2Work> &work,
351033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        const std::shared_ptr<C2BlockPool> &pool,
352277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        std::vector<std::unique_ptr<C2Param>> *configUpdate,
353033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        bool eos) {
354033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    while (!mBuffersInfo.empty() && outputDelayRingBufferSamplesAvailable()
355033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            >= mStreamInfo->frameSize * mStreamInfo->numChannels) {
356033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        Info &outInfo = mBuffersInfo.front();
357033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGV("outInfo.frameIndex = %" PRIu64, outInfo.frameIndex);
358033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int samplesize = mStreamInfo->numChannels * sizeof(int16_t);
359033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
360033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int available = outputDelayRingBufferSamplesAvailable();
361033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int numFrames = outInfo.decodedSizes.size();
362033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int numSamples = numFrames * (mStreamInfo->frameSize * mStreamInfo->numChannels);
363033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        if (available < numSamples) {
364033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            if (eos) {
365033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                numSamples = available;
366033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            } else {
367033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                break;
368033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            }
369033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
370033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGV("%d samples available (%d), or %d frames",
371033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                numSamples, available, numFrames);
372033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGV("getting %d from ringbuffer", numSamples);
373033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
374033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        std::shared_ptr<C2LinearBlock> block;
375033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        std::function<void(const std::unique_ptr<C2Work>&)> fillWork =
376277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim            [&block, numSamples, pool, configUpdate, this]()
377033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    -> std::function<void(const std::unique_ptr<C2Work>&)> {
378277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                auto fillEmptyWork = [configUpdate](
379277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                        const std::unique_ptr<C2Work> &work, c2_status_t err) {
380033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    work->result = err;
381277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    C2FrameData &output = work->worklets.front()->output;
382277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    output.flags = work->input.flags;
383277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    output.buffers.clear();
384277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    output.ordinal = work->input.ordinal;
385277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    while (configUpdate && !configUpdate->empty()) {
386277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                        output.configUpdate.push_back(std::move(configUpdate->front()));
387277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    }
388277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
389033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    work->workletsProcessed = 1u;
390033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                };
391033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
392033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                using namespace std::placeholders;
393033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                if (numSamples == 0) {
394033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    return std::bind(fillEmptyWork, _1, C2_OK);
395033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                }
396033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
397033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                // TODO: error handling, proper usage, etc.
398033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
399033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                c2_status_t err = pool->fetchLinearBlock(
400033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                        numSamples * sizeof(int16_t), usage, &block);
401033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                if (err != C2_OK) {
402033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    ALOGD("failed to fetch a linear block (%d)", err);
403033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    mSignalledError = true;
404033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    return std::bind(fillEmptyWork, _1, C2_NO_MEMORY);
405033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                }
406033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                C2WriteView wView = block->map().get();
407033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                // TODO
408033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                INT_PCM *outBuffer = reinterpret_cast<INT_PCM *>(wView.data());
409033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                int32_t ns = outputDelayRingBufferGetSamples(outBuffer, numSamples);
410033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                if (ns != numSamples) {
411033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    ALOGE("not a complete frame of samples available");
412033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    mSignalledError = true;
413033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    return std::bind(fillEmptyWork, _1, C2_CORRUPTED);
414033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                }
415277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                return [buffer = createLinearBuffer(block), configUpdate](
416277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                        const std::unique_ptr<C2Work> &work) {
417033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    work->result = C2_OK;
418277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    C2FrameData &output = work->worklets.front()->output;
419277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    output.flags = work->input.flags;
420277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    output.buffers.clear();
421277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    output.buffers.push_back(buffer);
422277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    output.ordinal = work->input.ordinal;
423277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    while (configUpdate && !configUpdate->empty()) {
424277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                        output.configUpdate.push_back(std::move(configUpdate->front()));
425277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    }
426033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    work->workletsProcessed = 1u;
427033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                };
428033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            }();
429033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
430033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        if (work && work->input.ordinal.frameIndex == c2_cntr64_t(outInfo.frameIndex)) {
431033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            fillWork(work);
432033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        } else {
433033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            finish(outInfo.frameIndex, fillWork);
434033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
435033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
436033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGV("out timestamp %" PRIu64 " / %u", outInfo.timestamp, block ? block->capacity() : 0);
437033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mBuffersInfo.pop_front();
438033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
439033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
440033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
441033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid C2SoftAac::process(
442033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        const std::unique_ptr<C2Work> &work,
443033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        const std::shared_ptr<C2BlockPool> &pool) {
444033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    work->workletsProcessed = 0u;
445033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    work->result = C2_OK;
446277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    work->worklets.front()->output.configUpdate.clear();
447033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (mSignalledError) {
448033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return;
449033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
450033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
451033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    UCHAR* inBuffer[FILEREAD_MAX_LAYERS];
452033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    UINT inBufferLength[FILEREAD_MAX_LAYERS] = {0};
453033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    UINT bytesValid[FILEREAD_MAX_LAYERS] = {0};
454033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
455033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT];
456033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    C2ReadView view = work->input.buffers[0]->data().linearBlocks().front().map().get();
457033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    size_t offset = 0u;
458033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    size_t size = view.capacity();
459033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
460033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
461033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    bool codecConfig = (work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0;
462033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
463033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    //TODO
464033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#if 0
465033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (mInputBufferCount == 0 && !codecConfig) {
466033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGW("first buffer should have FLAG_CODEC_CONFIG set");
467033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        codecConfig = true;
468033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
469033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#endif
470033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (codecConfig) {
471033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        // const_cast because of libAACdec method signature.
472033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        inBuffer[0] = const_cast<UCHAR *>(view.data() + offset);
473033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        inBufferLength[0] = size;
474033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
475033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        AAC_DECODER_ERROR decoderErr =
476033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            aacDecoder_ConfigRaw(mAACDecoder,
477033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                                 inBuffer,
478033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                                 inBufferLength);
479033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
480033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        if (decoderErr != AAC_DEC_OK) {
481033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            ALOGE("aacDecoder_ConfigRaw decoderErr = 0x%4.4x", decoderErr);
482033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            mSignalledError = true;
483033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            // TODO: error
484033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            return;
485033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
486033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
487033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        work->worklets.front()->output.ordinal = work->input.ordinal;
488033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        work->worklets.front()->output.buffers.clear();
489033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
490033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return;
491033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
492033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
493277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    std::vector<std::unique_ptr<C2Param>> configUpdate{};
494033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    Info inInfo;
495033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    inInfo.frameIndex = work->input.ordinal.frameIndex.peeku();
496033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    inInfo.timestamp = work->input.ordinal.timestamp.peeku();
497033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    inInfo.bufferSize = size;
498033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    inInfo.decodedSizes.clear();
499033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    while (size > 0u) {
500033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGV("size = %zu", size);
501277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        if (mIntf->isAdts()) {
502033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            size_t adtsHeaderSize = 0;
503033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            // skip 30 bits, aac_frame_length follows.
504033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
505033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
506033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            const uint8_t *adtsHeader = view.data() + offset;
507033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
508033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            bool signalError = false;
509033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            if (size < 7) {
510033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                ALOGE("Audio data too short to contain even the ADTS header. "
511033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                        "Got %zu bytes.", size);
512033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                hexdump(adtsHeader, size);
513033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                signalError = true;
514033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            } else {
515033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                bool protectionAbsent = (adtsHeader[1] & 1);
516033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
517033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                unsigned aac_frame_length =
518033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    ((adtsHeader[3] & 3) << 11)
519033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    | (adtsHeader[4] << 3)
520033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    | (adtsHeader[5] >> 5);
521033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
522033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                if (size < aac_frame_length) {
523033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    ALOGE("Not enough audio data for the complete frame. "
524033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                            "Got %zu bytes, frame size according to the ADTS "
525033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                            "header is %u bytes.",
526033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                            size, aac_frame_length);
527033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    hexdump(adtsHeader, size);
528033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    signalError = true;
529033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                } else {
530033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    adtsHeaderSize = (protectionAbsent ? 7 : 9);
531033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    if (aac_frame_length < adtsHeaderSize) {
532033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                        signalError = true;
533033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    } else {
534033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                        // const_cast because of libAACdec method signature.
535033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                        inBuffer[0] = const_cast<UCHAR *>(adtsHeader + adtsHeaderSize);
536033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                        inBufferLength[0] = aac_frame_length - adtsHeaderSize;
537033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
538033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                        offset += adtsHeaderSize;
539033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                        size -= adtsHeaderSize;
540033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    }
541033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                }
542033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            }
543033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
544033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            if (signalError) {
545033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                mSignalledError = true;
546033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                // TODO: notify(OMX_EventError, OMX_ErrorStreamCorrupt, ERROR_MALFORMED, NULL);
547033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                return;
548033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            }
549033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        } else {
550033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            // const_cast because of libAACdec method signature.
551033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            inBuffer[0] = const_cast<UCHAR *>(view.data() + offset);
552033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            inBufferLength[0] = size;
553033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
554033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
555033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        // Fill and decode
556033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        bytesValid[0] = inBufferLength[0];
557033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
558033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        INT prevSampleRate = mStreamInfo->sampleRate;
559033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        INT prevNumChannels = mStreamInfo->numChannels;
560033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
561033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        aacDecoder_Fill(mAACDecoder,
562033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                        inBuffer,
563033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                        inBufferLength,
564033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                        bytesValid);
565033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
566033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        // run DRC check
567033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mDrcWrap.submitStreamData(mStreamInfo);
568033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mDrcWrap.update();
569033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
570033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0];
571033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        size -= inBufferUsedLength;
572033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        offset += inBufferUsedLength;
573033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
574033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        AAC_DECODER_ERROR decoderErr;
575033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        do {
576033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            if (outputDelayRingBufferSpaceLeft() <
577033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    (mStreamInfo->frameSize * mStreamInfo->numChannels)) {
578033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                ALOGV("skipping decode: not enough space left in ringbuffer");
579033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                break;
580033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            }
581033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
582033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            int numConsumed = mStreamInfo->numTotalBytes;
583033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
584033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                                       tmpOutBuffer,
585033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                                       2048 * MAX_CHANNEL_COUNT,
586033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                                       0 /* flags */);
587033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
588033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            numConsumed = mStreamInfo->numTotalBytes - numConsumed;
589033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
590033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            if (decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
591033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                break;
592033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            }
593033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            inInfo.decodedSizes.push_back(numConsumed);
594033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
595033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            if (decoderErr != AAC_DEC_OK) {
596033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr);
597033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            }
598033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
599033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            if (bytesValid[0] != 0) {
600033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                ALOGE("bytesValid[0] != 0 should never happen");
601033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                mSignalledError = true;
602033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                // TODO: notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
603033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                return;
604033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            }
605033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
606033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            size_t numOutBytes =
607033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels;
608033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
609033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            if (decoderErr == AAC_DEC_OK) {
610033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                if (!outputDelayRingBufferPutSamples(tmpOutBuffer,
611033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                        mStreamInfo->frameSize * mStreamInfo->numChannels)) {
612033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    mSignalledError = true;
613033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    // TODO: notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
614033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    return;
615033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                }
616033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            } else {
617033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                ALOGW("AAC decoder returned error 0x%4.4x, substituting silence", decoderErr);
618033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
619033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                memset(tmpOutBuffer, 0, numOutBytes); // TODO: check for overflow
620033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
621033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                if (!outputDelayRingBufferPutSamples(tmpOutBuffer,
622033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                        mStreamInfo->frameSize * mStreamInfo->numChannels)) {
623033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    mSignalledError = true;
624033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    // TODO: notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
625033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    return;
626033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                }
627033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
628033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                // Discard input buffer.
629033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                size = 0;
630033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
631033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);
632033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
633033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                // After an error, replace bufferSize with the sum of the
634033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                // decodedSizes to resynchronize the in/out lists.
635033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                inInfo.decodedSizes.pop_back();
636033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                inInfo.bufferSize = std::accumulate(
637033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                        inInfo.decodedSizes.begin(), inInfo.decodedSizes.end(), 0);
638033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
639033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                // fall through
640033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            }
641033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
642033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            /*
643033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim             * AAC+/eAAC+ streams can be signalled in two ways: either explicitly
644033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim             * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual
645033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim             * rate system and the sampling rate in the final output is actually
646033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim             * doubled compared with the core AAC decoder sampling rate.
647033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim             *
648033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim             * Explicit signalling is done by explicitly defining SBR audio object
649033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim             * type in the bitstream. Implicit signalling is done by embedding
650033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim             * SBR content in AAC extension payload specific to SBR, and hence
651033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim             * requires an AAC decoder to perform pre-checks on actual audio frames.
652033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim             *
653033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim             * Thus, we could not say for sure whether a stream is
654033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim             * AAC+/eAAC+ until the first data frame is decoded.
655033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim             */
656033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            if (!mStreamInfo->sampleRate || !mStreamInfo->numChannels) {
657277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                // if ((mInputBufferCount > 2) && (mOutputBufferCount <= 1)) {
658277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    ALOGD("Invalid AAC stream");
659033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                    // TODO: notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
660277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    // mSignalledError = true;
661277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                // }
662277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim            } else if ((mStreamInfo->sampleRate != prevSampleRate) ||
663277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                       (mStreamInfo->numChannels != prevNumChannels)) {
664277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels",
665277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                      prevSampleRate, mStreamInfo->sampleRate,
666277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                      prevNumChannels, mStreamInfo->numChannels);
667277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
668277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                C2StreamSampleRateInfo::output sampleRateInfo(0u, mStreamInfo->sampleRate);
669277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                C2StreamChannelCountInfo::output channelCountInfo(0u, mStreamInfo->numChannels);
670277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                std::vector<std::unique_ptr<C2SettingResult>> failures;
671277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                c2_status_t err = mIntf->config(
672277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                        { &sampleRateInfo, &channelCountInfo },
673277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                        C2_MAY_BLOCK,
674277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                        &failures);
675277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                if (err == OK) {
676277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    // TODO: this does not handle the case where the values are
677277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    //       altered during config.
678277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    configUpdate.push_back(C2Param::Copy(sampleRateInfo));
679277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                    configUpdate.push_back(C2Param::Copy(channelCountInfo));
680033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                }
681277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                // TODO: error handling
682033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            }
683033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            ALOGV("size = %zu", size);
684033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        } while (decoderErr == AAC_DEC_OK);
685033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
686033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
687033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    int32_t outputDelay = mStreamInfo->outputDelay * mStreamInfo->numChannels;
688033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
689033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mBuffersInfo.push_back(std::move(inInfo));
690033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
691033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (!eos && mOutputDelayCompensated < outputDelay) {
692033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        // discard outputDelay at the beginning
693033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int32_t toCompensate = outputDelay - mOutputDelayCompensated;
694033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int32_t discard = outputDelayRingBufferSamplesAvailable();
695033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        if (discard > toCompensate) {
696033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            discard = toCompensate;
697033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
698033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int32_t discarded = outputDelayRingBufferGetSamples(0, discard);
699033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mOutputDelayCompensated += discarded;
700033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return;
701033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
702033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
703033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (eos) {
704277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work, &configUpdate);
705033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    } else {
706277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        drainRingBuffer(work, pool, &configUpdate, false /* not EOS */);
707033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
708033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
709033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
710033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimc2_status_t C2SoftAac::drainInternal(
711033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        uint32_t drainMode,
712033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        const std::shared_ptr<C2BlockPool> &pool,
713277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        const std::unique_ptr<C2Work> &work,
714277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        std::vector<std::unique_ptr<C2Param>> *configUpdate) {
715033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (drainMode == NO_DRAIN) {
716033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGW("drain with NO_DRAIN: no-op");
717033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return C2_OK;
718033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
719033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (drainMode == DRAIN_CHAIN) {
720033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGW("DRAIN_CHAIN not supported");
721033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return C2_OMITTED;
722033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
723033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
724033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    bool eos = (drainMode == DRAIN_COMPONENT_WITH_EOS);
725033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
726033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    drainDecoder();
727277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    drainRingBuffer(work, pool, configUpdate, eos);
728033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
729033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (eos) {
730033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        auto fillEmptyWork = [](const std::unique_ptr<C2Work> &work) {
731033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            work->worklets.front()->output.flags = work->input.flags;
732033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            work->worklets.front()->output.buffers.clear();
733033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            work->worklets.front()->output.ordinal = work->input.ordinal;
734033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            work->workletsProcessed = 1u;
735033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        };
736033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        while (mBuffersInfo.size() > 1u) {
737033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            finish(mBuffersInfo.front().frameIndex, fillEmptyWork);
738033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            mBuffersInfo.pop_front();
739033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
740033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        if (work->workletsProcessed == 0u) {
741033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            fillEmptyWork(work);
742033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
743033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mBuffersInfo.clear();
744033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
745033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
746033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    return C2_OK;
747033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
748033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
749033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimc2_status_t C2SoftAac::drain(
750033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        uint32_t drainMode,
751033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        const std::shared_ptr<C2BlockPool> &pool) {
752033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    return drainInternal(drainMode, pool, nullptr);
753033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
754033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
755033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimc2_status_t C2SoftAac::onFlush_sm() {
756033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    drainDecoder();
757033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mBuffersInfo.clear();
758033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
759033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    int avail;
760033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    while ((avail = outputDelayRingBufferSamplesAvailable()) > 0) {
761033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        if (avail > mStreamInfo->frameSize * mStreamInfo->numChannels) {
762033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            avail = mStreamInfo->frameSize * mStreamInfo->numChannels;
763033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
764033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int32_t ns = outputDelayRingBufferGetSamples(0, avail);
765033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        if (ns != avail) {
766033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            ALOGW("not a complete frame of samples available");
767033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            break;
768033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
769033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
770033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mOutputDelayRingBufferReadPos = mOutputDelayRingBufferWritePos;
771033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
772033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    return C2_OK;
773033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
774033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
775033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid C2SoftAac::drainDecoder() {
776033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    // flush decoder until outputDelay is compensated
777033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    while (mOutputDelayCompensated > 0) {
778033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        // a buffer big enough for MAX_CHANNEL_COUNT channels of decoded HE-AAC
779033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT];
780033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
781033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        // run DRC check
782033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mDrcWrap.submitStreamData(mStreamInfo);
783033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mDrcWrap.update();
784033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
785033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        AAC_DECODER_ERROR decoderErr =
786033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            aacDecoder_DecodeFrame(mAACDecoder,
787033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                                   tmpOutBuffer,
788033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                                   2048 * MAX_CHANNEL_COUNT,
789033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                                   AACDEC_FLUSH);
790033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        if (decoderErr != AAC_DEC_OK) {
791033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr);
792033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
793033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
794033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int32_t tmpOutBufferSamples = mStreamInfo->frameSize * mStreamInfo->numChannels;
795033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        if (tmpOutBufferSamples > mOutputDelayCompensated) {
796033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            tmpOutBufferSamples = mOutputDelayCompensated;
797033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
798033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        outputDelayRingBufferPutSamples(tmpOutBuffer, tmpOutBufferSamples);
799033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
800033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mOutputDelayCompensated -= tmpOutBufferSamples;
801033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
802033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
803033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
804033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass C2SoftAacDecFactory : public C2ComponentFactory {
805033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic:
806277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    C2SoftAacDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
807277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim            GetCodec2PlatformComponentStore()->getParamReflector())) {
808277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    }
809277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
810033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    virtual c2_status_t createComponent(
811033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            c2_node_id_t id,
812033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            std::shared_ptr<C2Component>* const component,
813033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            std::function<void(C2Component*)> deleter) override {
814277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        *component = std::shared_ptr<C2Component>(
815277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                new C2SoftAac(COMPONENT_NAME,
816277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                              id,
817277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                              std::make_shared<C2SoftAac::IntfImpl>(mHelper)),
818277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                deleter);
819033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return C2_OK;
820033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
821033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
822033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    virtual c2_status_t createInterface(
823277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim            c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface,
824033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            std::function<void(C2ComponentInterface*)> deleter) override {
825277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim        *interface = std::shared_ptr<C2ComponentInterface>(
826277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                new SimpleInterface<C2SoftAac::IntfImpl>(
827277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                        COMPONENT_NAME, id, std::make_shared<C2SoftAac::IntfImpl>(mHelper)),
828277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim                deleter);
829033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return C2_OK;
830033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
831033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
832033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    virtual ~C2SoftAacDecFactory() override = default;
833277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim
834277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kimprivate:
835277b7295f317c6597fadb116b6aee5ca3be106c1Wonsik Kim    std::shared_ptr<C2ReflectorHelper> mHelper;
836033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim};
837033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
838033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}  // namespace android
839033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
840033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimextern "C" ::C2ComponentFactory* CreateCodec2Factory() {
841033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    ALOGV("in %s", __func__);
842033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    return new ::android::C2SoftAacDecFactory();
843033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
844033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
845033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimextern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
846033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    ALOGV("in %s", __func__);
847033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    delete factory;
848033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
849