1033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim/*
2033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Copyright (C) 2018 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 "C2SoftG711Dec"
19d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar#include <log/log.h>
20033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
21d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar#include <media/stagefright/foundation/MediaDefs.h>
22033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
23033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <C2PlatformSupport.h>
2472dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnar#include <SimpleC2Interface.h>
25033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
26d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar#include "C2SoftG711Dec.h"
27033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
28033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimnamespace android {
29033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
30033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#ifdef ALAW
31da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Sainiconstexpr char COMPONENT_NAME[] = "c2.android.g711.alaw.decoder";
32033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#else
33da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Sainiconstexpr char COMPONENT_NAME[] = "c2.android.g711.mlaw.decoder";
34033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#endif
35033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
3672dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarclass C2SoftG711Dec::IntfImpl : public C2InterfaceHelper {
37da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Sainipublic:
38da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
39da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini        : C2InterfaceHelper(helper) {
40da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini
41da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini        setDerivedInstance(this);
42da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini
43da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini        addParameter(
44da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                DefineParam(mInputFormat, C2_NAME_INPUT_STREAM_FORMAT_SETTING)
45da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                .withConstValue(new C2StreamFormatConfig::input(0u, C2FormatCompressed))
46da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                .build());
47da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini
48da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini        addParameter(
49da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                DefineParam(mOutputFormat, C2_NAME_OUTPUT_STREAM_FORMAT_SETTING)
50da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                .withConstValue(new C2StreamFormatConfig::output(0u, C2FormatAudio))
51da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                .build());
52da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini
53da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini        addParameter(
54da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                DefineParam(mInputMediaType, C2_NAME_INPUT_PORT_MIME_SETTING)
55da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                .withConstValue(AllocSharedString<C2PortMimeConfig::input>(
56033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#ifdef ALAW
57da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                        MEDIA_MIMETYPE_AUDIO_G711_ALAW
58033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#else
59da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                        MEDIA_MIMETYPE_AUDIO_G711_MLAW
60033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#endif
61da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                )).build());
62da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini
63da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini        addParameter(
64da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                DefineParam(mOutputMediaType, C2_NAME_OUTPUT_PORT_MIME_SETTING)
65da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                .withConstValue(AllocSharedString<C2PortMimeConfig::output>(
66da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                        MEDIA_MIMETYPE_AUDIO_RAW))
67da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                .build());
68da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini
69da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini        addParameter(
70da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                DefineParam(mSampleRate, C2_NAME_STREAM_SAMPLE_RATE_SETTING)
71da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                .withDefault(new C2StreamSampleRateInfo::output(0u, 8000))
72da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                .withFields({C2F(mSampleRate, value).inRange(8000, 48000)})
73da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
74da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                .build());
75da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini
76da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini        addParameter(
77da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                DefineParam(mChannelCount, C2_NAME_STREAM_CHANNEL_COUNT_SETTING)
78da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                .withDefault(new C2StreamChannelCountInfo::output(0u, 1))
79da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                .withFields({C2F(mChannelCount, value).equalTo(1)})
80da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
81da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                .build());
82da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini
83da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini        addParameter(
84da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                DefineParam(mBitrate, C2_NAME_STREAM_BITRATE_SETTING)
85da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                .withDefault(new C2BitrateTuning::input(0u, 64000))
86da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                .withFields({C2F(mBitrate, value).equalTo(64000)})
87da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
88da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                .build());
89da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini    }
90033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
91da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Sainiprivate:
92da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini    std::shared_ptr<C2StreamFormatConfig::input> mInputFormat;
93da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini    std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat;
94da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini    std::shared_ptr<C2PortMimeConfig::input> mInputMediaType;
95da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini    std::shared_ptr<C2PortMimeConfig::output> mOutputMediaType;
96da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini    std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
97da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini    std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
98da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini    std::shared_ptr<C2BitrateTuning::input> mBitrate;
99da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini};
100033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
10172dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos MolnarC2SoftG711Dec::C2SoftG711Dec(
102da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini        const char *name,
103da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini        c2_node_id_t id,
104da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini        const std::shared_ptr<IntfImpl> &intfImpl)
105da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini    : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
106da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini      mIntf(intfImpl) {
107033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
108033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
10972dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos MolnarC2SoftG711Dec::~C2SoftG711Dec() {
110033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    onRelease();
111033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
112033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
11372dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarc2_status_t C2SoftG711Dec::onInit() {
114033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mSignalledOutputEos = false;
115033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    return C2_OK;
116033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
117033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
11872dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarc2_status_t C2SoftG711Dec::onStop() {
119033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mSignalledOutputEos = false;
120033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    return C2_OK;
121033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
122033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
12372dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarvoid C2SoftG711Dec::onReset() {
124033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    (void)onStop();
125033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
126033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
12772dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarvoid C2SoftG711Dec::onRelease() {
128033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
129033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
13072dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarc2_status_t C2SoftG711Dec::onFlush_sm() {
131033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    return onStop();
132033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
133033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
13472dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarvoid C2SoftG711Dec::process(
135033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        const std::unique_ptr<C2Work> &work,
136033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        const std::shared_ptr<C2BlockPool> &pool) {
137033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    work->result = C2_OK;
138033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    work->workletsProcessed = 0u;
139033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (mSignalledOutputEos) {
140033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        work->result = C2_BAD_VALUE;
141033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return;
142033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
143033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
14445c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim    C2ReadView rView = mDummyReadView;
14545c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim    size_t inOffset = 0u;
14645c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim    size_t inSize = 0u;
14745c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim    if (!work->input.buffers.empty()) {
14845c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim        rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
14945c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim        inSize = rView.capacity();
15045c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim        if (inSize && rView.error()) {
15145c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim            ALOGE("read view map failed %d", rView.error());
15245c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim            work->result = C2_CORRUPTED;
15345c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim            return;
15445c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim        }
155033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
156033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
15745c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim    int outSize = inSize * sizeof(int16_t);
158033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
159033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d", inSize,
160033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim          (int)work->input.ordinal.timestamp.peeku(), (int)work->input.ordinal.frameIndex.peeku());
161033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
162033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (inSize == 0) {
163033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        work->worklets.front()->output.flags = work->input.flags;
164033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        work->worklets.front()->output.buffers.clear();
165033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        work->worklets.front()->output.ordinal = work->input.ordinal;
166033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        work->workletsProcessed = 1u;
167033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        if (eos) {
168033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            mSignalledOutputEos = true;
169033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            ALOGV("signalled EOS");
170033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
171033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return;
172033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
173033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
174033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    uint8_t *inputptr = const_cast<uint8_t *>(rView.data() + inOffset);
175033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
176033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    std::shared_ptr<C2LinearBlock> block;
177033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
178033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    c2_status_t err = pool->fetchLinearBlock(outSize, usage, &block);
179033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (err != C2_OK) {
180033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGE("fetchLinearBlock for Output failed with status %d", err);
181033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        work->result = C2_NO_MEMORY;
182033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return;
183033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
184033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    C2WriteView wView = block->map().get();
185033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (wView.error()) {
186033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGE("write view map failed %d", wView.error());
187033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        work->result = C2_CORRUPTED;
188033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return;
189033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
190033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    int16_t *outputptr = reinterpret_cast<int16_t *>(wView.data());
191033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
192033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#ifdef ALAW
193033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    DecodeALaw(outputptr, inputptr, inSize);
194033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#else
195033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    DecodeMLaw(outputptr, inputptr, inSize);
196033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#endif
197033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
198033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    work->worklets.front()->output.flags = work->input.flags;
199033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    work->worklets.front()->output.buffers.clear();
200033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    work->worklets.front()->output.buffers.push_back(createLinearBuffer(block));
201033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    work->worklets.front()->output.ordinal = work->input.ordinal;
202033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    work->workletsProcessed = 1u;
203033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
204033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (eos) {
205033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mSignalledOutputEos = true;
206033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGV("signalled EOS");
207033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
208033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
209033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
21072dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarc2_status_t C2SoftG711Dec::drain(
211033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        uint32_t drainMode,
212033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        const std::shared_ptr<C2BlockPool> &pool) {
213033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    (void) pool;
214033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (drainMode == NO_DRAIN) {
215033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGW("drain with NO_DRAIN: no-op");
216033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return C2_OK;
217033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
218033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (drainMode == DRAIN_CHAIN) {
219033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGW("DRAIN_CHAIN not supported");
220033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return C2_OMITTED;
221033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
222033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
223033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    return C2_OK;
224033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
225033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
226033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#ifdef ALAW
22772dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarvoid C2SoftG711Dec::DecodeALaw(
228033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int16_t *out, const uint8_t *in, size_t inSize) {
229033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    while (inSize > 0) {
230033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        inSize--;
231033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int32_t x = *in++;
232033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
233033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int32_t ix = x ^ 0x55;
234033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ix &= 0x7f;
235033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
236033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int32_t iexp = ix >> 4;
237033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int32_t mant = ix & 0x0f;
238033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
239033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        if (iexp > 0) {
240033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            mant += 16;
241033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
242033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
243033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mant = (mant << 4) + 8;
244033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
245033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        if (iexp > 1) {
246033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            mant = mant << (iexp - 1);
247033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
248033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
249033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        *out++ = (x > 127) ? mant : -mant;
250033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
251033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
252033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#else
25372dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarvoid C2SoftG711Dec::DecodeMLaw(
254033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int16_t *out, const uint8_t *in, size_t inSize) {
255033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    while (inSize > 0) {
256033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        inSize--;
257033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int32_t x = *in++;
258033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
259033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int32_t mantissa = ~x;
260033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int32_t exponent = (mantissa >> 4) & 7;
261033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int32_t segment = exponent + 1;
262033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mantissa &= 0x0f;
263033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
264033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int32_t step = 4 << segment;
265033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
266033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int32_t abs = (0x80l << exponent) + step * mantissa + step / 2 - 4 * 33;
267033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
268033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        *out++ = (x < 0x80) ? -abs : abs;
269033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
270033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
271033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#endif
272033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
273033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass C2SoftG711DecFactory : public C2ComponentFactory {
274033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic:
275da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini    C2SoftG711DecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
276da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini            GetCodec2PlatformComponentStore()->getParamReflector())) {
277da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini    }
278da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini
279033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    virtual c2_status_t createComponent(
280033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            c2_node_id_t id,
281033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            std::shared_ptr<C2Component>* const component,
282033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            std::function<void(C2Component*)> deleter) override {
283da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini        *component = std::shared_ptr<C2Component>(
28472dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnar                new C2SoftG711Dec(COMPONENT_NAME, id,
28572dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnar                               std::make_shared<C2SoftG711Dec::IntfImpl>(mHelper)),
286da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                deleter);
287033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return C2_OK;
288033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
289033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
290033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    virtual c2_status_t createInterface(
291033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface,
292033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            std::function<void(C2ComponentInterface*)> deleter) override {
293da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini        *interface = std::shared_ptr<C2ComponentInterface>(
29472dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnar                new SimpleInterface<C2SoftG711Dec::IntfImpl>(
29572dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnar                        COMPONENT_NAME, id, std::make_shared<C2SoftG711Dec::IntfImpl>(mHelper)),
296da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini                deleter);
297033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return C2_OK;
298033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
299033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
300033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    virtual ~C2SoftG711DecFactory() override = default;
301da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini
302da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Sainiprivate:
303da13a07c7efa59ebba9a5a24c5f9445c26a7d4bcUmang Saini    std::shared_ptr<C2ReflectorHelper> mHelper;
304033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim};
305033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
306033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}  // namespace android
307033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
308033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimextern "C" ::C2ComponentFactory* CreateCodec2Factory() {
309033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    ALOGV("in %s", __func__);
310033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    return new ::android::C2SoftG711DecFactory();
311033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
312033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
313033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimextern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
314033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    ALOGV("in %s", __func__);
315033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    delete factory;
316033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
317