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 "C2SoftVorbisDec"
19d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar#include <log/log.h>
20d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar
21d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar#include <media/stagefright/foundation/MediaDefs.h>
22033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
23033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <C2PlatformSupport.h>
2472dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnar#include <SimpleC2Interface.h>
25033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
2672dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnar#include "C2SoftVorbisDec.h"
27033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
28033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimextern "C" {
29033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    #include <Tremolo/codec_internal.h>
30033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
31033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb);
32033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb);
33033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb);
34033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
35033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
36033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimnamespace android {
37033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
38af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajooconstexpr char COMPONENT_NAME[] = "c2.android.vorbis.decoder";
39033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
4072dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarclass C2SoftVorbisDec::IntfImpl : public C2InterfaceHelper {
41af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoopublic:
42af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo    explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
43af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo        : C2InterfaceHelper(helper) {
44af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo
45af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo        setDerivedInstance(this);
46af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo
47af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo        addParameter(
48af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                DefineParam(mInputFormat, C2_NAME_INPUT_STREAM_FORMAT_SETTING)
49af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                .withConstValue(new C2StreamFormatConfig::input(0u, C2FormatCompressed))
50af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                .build());
51af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo
52af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo        addParameter(
53af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                DefineParam(mOutputFormat, C2_NAME_OUTPUT_STREAM_FORMAT_SETTING)
54af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                .withConstValue(new C2StreamFormatConfig::output(0u, C2FormatAudio))
55af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                .build());
56af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo
57af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo        addParameter(
58af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                DefineParam(mInputMediaType, C2_NAME_INPUT_PORT_MIME_SETTING)
59af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                .withConstValue(AllocSharedString<C2PortMimeConfig::input>(
60af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                        MEDIA_MIMETYPE_AUDIO_VORBIS))
61af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                .build());
62af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo
63af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo        addParameter(
64af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                DefineParam(mOutputMediaType, C2_NAME_OUTPUT_PORT_MIME_SETTING)
65af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                .withConstValue(AllocSharedString<C2PortMimeConfig::output>(
66af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                        MEDIA_MIMETYPE_AUDIO_RAW))
67af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                .build());
68af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo
69af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo        addParameter(
70af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                DefineParam(mSampleRate, C2_NAME_STREAM_SAMPLE_RATE_SETTING)
71af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                .withDefault(new C2StreamSampleRateInfo::output(0u, 48000))
72af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                .withFields({C2F(mSampleRate, value).inRange(8000, 96000)})
73af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
74af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                .build());
75af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo
76af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo        addParameter(
77af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                DefineParam(mChannelCount, C2_NAME_STREAM_CHANNEL_COUNT_SETTING)
78af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                .withDefault(new C2StreamChannelCountInfo::output(0u, 1))
79af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                .withFields({C2F(mChannelCount, value).inRange(1, 8)})
80af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
81af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                .build());
82af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo
83af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo        addParameter(
84af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                DefineParam(mBitrate, C2_NAME_STREAM_BITRATE_SETTING)
85af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                .withDefault(new C2BitrateTuning::input(0u, 64000))
86af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                .withFields({C2F(mBitrate, value).inRange(32000, 500000)})
87af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
88af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                .build());
89af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo    }
90af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo
91af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajooprivate:
92af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo    std::shared_ptr<C2StreamFormatConfig::input> mInputFormat;
93af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo    std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat;
94af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo    std::shared_ptr<C2PortMimeConfig::input> mInputMediaType;
95af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo    std::shared_ptr<C2PortMimeConfig::output> mOutputMediaType;
96af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo    std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
97af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo    std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
98af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo    std::shared_ptr<C2BitrateTuning::input> mBitrate;
99af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo};
100af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo
10172dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos MolnarC2SoftVorbisDec::C2SoftVorbisDec(
102af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo        const char *name,
103af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo        c2_node_id_t id,
104af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo        const std::shared_ptr<IntfImpl> &intfImpl)
105af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo    : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
106af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo      mIntf(intfImpl),
107033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim      mState(nullptr),
108033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim      mVi(nullptr) {
109033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
110033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
11172dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos MolnarC2SoftVorbisDec::~C2SoftVorbisDec() {
112033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    onRelease();
113033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
114033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
11572dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarc2_status_t C2SoftVorbisDec::onInit() {
116033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    status_t err = initDecoder();
117033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    return err == OK ? C2_OK : C2_NO_MEMORY;
118033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
119033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
12072dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarc2_status_t C2SoftVorbisDec::onStop() {
1215ee5b2e75edcbc873456a89c609ce5a2594cde01Wonsik Kim    if (mState) {
1225ee5b2e75edcbc873456a89c609ce5a2594cde01Wonsik Kim        vorbis_dsp_clear(mState);
1235ee5b2e75edcbc873456a89c609ce5a2594cde01Wonsik Kim        delete mState;
1245ee5b2e75edcbc873456a89c609ce5a2594cde01Wonsik Kim        mState = nullptr;
1255ee5b2e75edcbc873456a89c609ce5a2594cde01Wonsik Kim    }
1265ee5b2e75edcbc873456a89c609ce5a2594cde01Wonsik Kim
1275ee5b2e75edcbc873456a89c609ce5a2594cde01Wonsik Kim    if (mVi) {
1285ee5b2e75edcbc873456a89c609ce5a2594cde01Wonsik Kim        vorbis_info_clear(mVi);
1295ee5b2e75edcbc873456a89c609ce5a2594cde01Wonsik Kim        delete mVi;
1305ee5b2e75edcbc873456a89c609ce5a2594cde01Wonsik Kim        mVi = nullptr;
1315ee5b2e75edcbc873456a89c609ce5a2594cde01Wonsik Kim    }
132033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mNumFramesLeftOnPage = -1;
133033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mSignalledOutputEos = false;
134033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mSignalledError = false;
135033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
136eb9e329cc4df5a863edf428155896c67b9acb72dWonsik Kim    return (initDecoder() == OK ? C2_OK : C2_CORRUPTED);
137033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
138033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
13972dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarvoid C2SoftVorbisDec::onReset() {
140033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    (void)onStop();
141033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
142033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
14372dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarvoid C2SoftVorbisDec::onRelease() {
144033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (mState) {
145033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        vorbis_dsp_clear(mState);
146033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        delete mState;
147033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mState = nullptr;
148033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
149033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
150033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (mVi) {
151033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        vorbis_info_clear(mVi);
152033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        delete mVi;
153033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mVi = nullptr;
154033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
155033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
156033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
15772dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarstatus_t C2SoftVorbisDec::initDecoder() {
158033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mVi = new vorbis_info{};
159033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (!mVi) return NO_MEMORY;
160033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    vorbis_info_clear(mVi);
161033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
162033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mState = new vorbis_dsp_state{};
163033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (!mState) return NO_MEMORY;
164033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    vorbis_dsp_clear(mState);
165033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
166033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mNumFramesLeftOnPage = -1;
167033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mSignalledError = false;
168033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mSignalledOutputEos = false;
1692cf670b332f492453d560464fa6fb535f45d8e6cHarish Mahendrakar    mInfoUnpacked = false;
1702cf670b332f492453d560464fa6fb535f45d8e6cHarish Mahendrakar    mBooksUnpacked = false;
171033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    return OK;
172033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
173033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
17472dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarc2_status_t C2SoftVorbisDec::onFlush_sm() {
175033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mNumFramesLeftOnPage = -1;
176033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    mSignalledOutputEos = false;
177033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (mState) vorbis_dsp_restart(mState);
178033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
179033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    return C2_OK;
180033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
181033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
18272dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarc2_status_t C2SoftVorbisDec::drain(
183033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        uint32_t drainMode,
184033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        const std::shared_ptr<C2BlockPool> &pool) {
185033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    (void) pool;
186033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (drainMode == NO_DRAIN) {
187033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGW("drain with NO_DRAIN: no-op");
188033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return C2_OK;
189033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
190033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (drainMode == DRAIN_CHAIN) {
191033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGW("DRAIN_CHAIN not supported");
192033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return C2_OMITTED;
193033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
194033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
195033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    return C2_OK;
196033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
197033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
198033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimstatic void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
199033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    work->worklets.front()->output.flags = work->input.flags;
200033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    work->worklets.front()->output.buffers.clear();
201033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    work->worklets.front()->output.ordinal = work->input.ordinal;
202033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    work->workletsProcessed = 1u;
203033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
204033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
205033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimstatic void makeBitReader(
206033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        const void *data, size_t size,
207033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ogg_buffer *buf, ogg_reference *ref, oggpack_buffer *bits) {
208033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    buf->data = (uint8_t *)data;
209033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    buf->size = size;
210033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    buf->refcount = 1;
211033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    buf->ptr.owner = nullptr;
212033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
213033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    ref->buffer = buf;
214033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    ref->begin = 0;
215033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    ref->length = size;
216033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    ref->next = nullptr;
217033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
218033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    oggpack_readinit(bits, ref);
219033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
220033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
221033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim// (CHECK!) multiframe is tricky. decode call doesnt return the number of bytes
222033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim// consumed by the component. Also it is unclear why numPageFrames is being
223033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim// tagged at the end of input buffers for new pages. Refer lines 297-300 in
224033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim// SimpleDecodingSource.cpp
22572dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnarvoid C2SoftVorbisDec::process(
226033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        const std::unique_ptr<C2Work> &work,
227033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        const std::shared_ptr<C2BlockPool> &pool) {
228033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    work->result = C2_OK;
229033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    work->workletsProcessed = 0u;
230af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo    work->worklets.front()->output.configUpdate.clear();
231033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (mSignalledError || mSignalledOutputEos) {
232033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        work->result = C2_BAD_VALUE;
233033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return;
234033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
235033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
236033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
23745c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim    size_t inOffset = 0u;
23845c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim    size_t inSize = 0u;
23945c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim    C2ReadView rView = mDummyReadView;
24045c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim    if (!work->input.buffers.empty()) {
24145c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim        rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
24245c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim        inSize = rView.capacity();
24345c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim        if (inSize && rView.error()) {
24445c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim            ALOGE("read view map failed %d", rView.error());
24545c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim            work->result = rView.error();
24645c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim            return;
24745c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim        }
248033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
249033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
250033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (inSize == 0) {
251033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        fillEmptyWork(work);
252033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        if (eos) {
253033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            mSignalledOutputEos = true;
254033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            ALOGV("signalled EOS");
255033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
256033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return;
257033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
258033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
259033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    ALOGV("in buffer attr. size %zu timestamp %d frameindex %d", inSize,
260033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim          (int)work->input.ordinal.timestamp.peeku(), (int)work->input.ordinal.frameIndex.peeku());
261033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    const uint8_t *data = rView.data() + inOffset;
262af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo    int32_t numChannels  = mVi->channels;
263af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo    int32_t samplingRate = mVi->rate;
2642cf670b332f492453d560464fa6fb535f45d8e6cHarish Mahendrakar    if (inSize > 7 && !memcmp(&data[1], "vorbis", 6)) {
2652cf670b332f492453d560464fa6fb535f45d8e6cHarish Mahendrakar        if ((data[0] != 1) && (data[0] != 5)) {
2662cf670b332f492453d560464fa6fb535f45d8e6cHarish Mahendrakar            ALOGE("unexpected type received %d", data[0]);
267033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            mSignalledError = true;
268033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            work->result = C2_CORRUPTED;
269033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            return;
270033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
271033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
272033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ogg_buffer buf;
273033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ogg_reference ref;
274033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        oggpack_buffer bits;
275033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
276033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        // skip 7 <type + "vorbis"> bytes
277033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        makeBitReader((const uint8_t *)data + 7, inSize - 7, &buf, &ref, &bits);
2782cf670b332f492453d560464fa6fb535f45d8e6cHarish Mahendrakar        if (data[0] == 1) {
279033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            vorbis_info_init(mVi);
280033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            if (0 != _vorbis_unpack_info(mVi, &bits)) {
281033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                ALOGE("Encountered error while unpacking info");
282033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                mSignalledError = true;
283033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                work->result = C2_CORRUPTED;
284033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                return;
285033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            }
286af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo            if (mVi->rate != samplingRate ||
287af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                    mVi->channels != numChannels) {
288033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                ALOGV("vorbis: rate/channels changed: %ld/%d", mVi->rate, mVi->channels);
289af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                samplingRate = mVi->rate;
290af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                numChannels = mVi->channels;
291af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo
292af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                C2StreamSampleRateInfo::output sampleRateInfo(0u, samplingRate);
293af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                C2StreamChannelCountInfo::output channelCountInfo(0u, numChannels);
294af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                std::vector<std::unique_ptr<C2SettingResult>> failures;
295af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                c2_status_t err = mIntf->config(
296af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                        { &sampleRateInfo, &channelCountInfo },
297af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                        C2_MAY_BLOCK,
298af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                        &failures);
299af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                if (err == OK) {
300af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                    work->worklets.front()->output.configUpdate.push_back(C2Param::Copy(sampleRateInfo));
301af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                    work->worklets.front()->output.configUpdate.push_back(C2Param::Copy(channelCountInfo));
302af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                } else {
303af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                    ALOGE("Config Update failed");
304af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                    mSignalledError = true;
305af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                    work->result = C2_CORRUPTED;
306af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                    return;
307af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                }
308033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            }
3092cf670b332f492453d560464fa6fb535f45d8e6cHarish Mahendrakar            mInfoUnpacked = true;
310033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        } else {
3112cf670b332f492453d560464fa6fb535f45d8e6cHarish Mahendrakar            if (!mInfoUnpacked) {
3122cf670b332f492453d560464fa6fb535f45d8e6cHarish Mahendrakar                ALOGE("Data with type:5 sent before sending type:1");
313033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                mSignalledError = true;
314033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                work->result = C2_CORRUPTED;
315033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                return;
316033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            }
317033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            if (0 != _vorbis_unpack_books(mVi, &bits)) {
318033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                ALOGE("Encountered error while unpacking books");
319033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                mSignalledError = true;
320033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                work->result = C2_CORRUPTED;
321033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                return;
322033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            }
323033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            if (0 != vorbis_dsp_init(mState, mVi)) {
324033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                ALOGE("Encountered error while dsp init");
325033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                mSignalledError = true;
326033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                work->result = C2_CORRUPTED;
327033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                return;
328033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            }
3292cf670b332f492453d560464fa6fb535f45d8e6cHarish Mahendrakar            mBooksUnpacked = true;
330033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
331033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        fillEmptyWork(work);
332033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        if (eos) {
333033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            mSignalledOutputEos = true;
334033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            ALOGV("signalled EOS");
335033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
336033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return;
337033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
3382cf670b332f492453d560464fa6fb535f45d8e6cHarish Mahendrakar
3392cf670b332f492453d560464fa6fb535f45d8e6cHarish Mahendrakar    if (!mInfoUnpacked || !mBooksUnpacked) {
3402cf670b332f492453d560464fa6fb535f45d8e6cHarish Mahendrakar        ALOGE("Missing CODEC_CONFIG data mInfoUnpacked: %d mBooksUnpack %d", mInfoUnpacked, mBooksUnpacked);
3412cf670b332f492453d560464fa6fb535f45d8e6cHarish Mahendrakar        mSignalledError = true;
3422cf670b332f492453d560464fa6fb535f45d8e6cHarish Mahendrakar        work->result = C2_CORRUPTED;
3432cf670b332f492453d560464fa6fb535f45d8e6cHarish Mahendrakar        return;
3442cf670b332f492453d560464fa6fb535f45d8e6cHarish Mahendrakar    }
3452cf670b332f492453d560464fa6fb535f45d8e6cHarish Mahendrakar
346033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    int32_t numPageFrames = 0;
347033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (inSize < sizeof(numPageFrames)) {
348033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGE("input header has size %zu, expected %zu", inSize, sizeof(numPageFrames));
349033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mSignalledError = true;
350033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        work->result = C2_CORRUPTED;
351033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return;
352033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
353033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    memcpy(&numPageFrames, data + inSize - sizeof(numPageFrames), sizeof(numPageFrames));
354033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    inSize -= sizeof(numPageFrames);
355033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (numPageFrames >= 0) {
356033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mNumFramesLeftOnPage = numPageFrames;
357033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
358033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
359033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    ogg_buffer buf;
360033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    buf.data = const_cast<unsigned char*>(data);
361033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    buf.size = inSize;
362033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    buf.refcount = 1;
363033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    buf.ptr.owner = nullptr;
364033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
365033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    ogg_reference ref;
366033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    ref.buffer = &buf;
367033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    ref.begin = 0;
368033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    ref.length = buf.size;
369033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    ref.next = nullptr;
370033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
371033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    ogg_packet pack;
372033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    pack.packet = &ref;
373033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    pack.bytes = ref.length;
374033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    pack.b_o_s = 0;
375033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    pack.e_o_s = 0;
376033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    pack.granulepos = 0;
377033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    pack.packetno = 0;
378033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
379033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    size_t maxSamplesInBuffer = kMaxNumSamplesPerChannel * mVi->channels;
380033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    size_t outCapacity =  maxSamplesInBuffer * sizeof(int16_t);
381033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    std::shared_ptr<C2LinearBlock> block;
382033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
383033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    c2_status_t err = pool->fetchLinearBlock(outCapacity, usage, &block);
384033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (err != C2_OK) {
385033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGE("fetchLinearBlock for Output failed with status %d", err);
386033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        work->result = C2_NO_MEMORY;
387033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return;
388033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
389033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    C2WriteView wView = block->map().get();
390033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (wView.error()) {
391033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGE("write view map failed %d", wView.error());
392033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        work->result = wView.error();
393033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return;
394033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
395033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
396033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    int numFrames = 0;
397033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    int ret = vorbis_dsp_synthesis(mState, &pack, 1);
398033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (0 != ret) {
399033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGE("vorbis_dsp_synthesis returned %d", ret);
400033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mSignalledError = true;
401033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        work->result = C2_CORRUPTED;
402033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return;
403033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    } else {
404033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        numFrames = vorbis_dsp_pcmout(
405033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                mState,  reinterpret_cast<int16_t *> (wView.data()),
406033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim                kMaxNumSamplesPerChannel);
407033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        if (numFrames < 0) {
408033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            ALOGD("vorbis_dsp_pcmout returned %d", numFrames);
409033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            numFrames = 0;
410033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
411033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
412033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
413033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (mNumFramesLeftOnPage >= 0) {
414033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        if (numFrames > mNumFramesLeftOnPage) {
415033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            ALOGV("discarding %d frames at end of page", numFrames - mNumFramesLeftOnPage);
416033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            numFrames = mNumFramesLeftOnPage;
417033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        }
418033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mNumFramesLeftOnPage -= numFrames;
419033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
420033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
421033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (numFrames) {
422033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        int outSize = numFrames * sizeof(int16_t) * mVi->channels;
423033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
424033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        work->worklets.front()->output.flags = work->input.flags;
425033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        work->worklets.front()->output.buffers.clear();
426033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        work->worklets.front()->output.buffers.push_back(createLinearBuffer(block, 0, outSize));
427033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        work->worklets.front()->output.ordinal = work->input.ordinal;
428033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        work->workletsProcessed = 1u;
429033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    } else {
430033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        fillEmptyWork(work);
431033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        block.reset();
432033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
433033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    if (eos) {
434033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        mSignalledOutputEos = true;
435033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        ALOGV("signalled EOS");
436033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
437033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
438033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
439033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass C2SoftVorbisDecFactory : public C2ComponentFactory {
440033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic:
441af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo    C2SoftVorbisDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
442af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo            GetCodec2PlatformComponentStore()->getParamReflector())) {
443af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo    }
444af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo
445033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    virtual c2_status_t createComponent(
446033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            c2_node_id_t id,
447033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            std::shared_ptr<C2Component>* const component,
448033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            std::function<void(C2Component*)> deleter) override {
449af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo        *component = std::shared_ptr<C2Component>(
45072dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnar                new C2SoftVorbisDec(COMPONENT_NAME,
451af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                              id,
45272dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnar                              std::make_shared<C2SoftVorbisDec::IntfImpl>(mHelper)),
453af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                deleter);
454033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return C2_OK;
455033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
456033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
457033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    virtual c2_status_t createInterface(
458033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            c2_node_id_t id,
459033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            std::shared_ptr<C2ComponentInterface>* const interface,
460033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim            std::function<void(C2ComponentInterface*)> deleter) override {
461af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo        *interface = std::shared_ptr<C2ComponentInterface>(
46272dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnar                new SimpleInterface<C2SoftVorbisDec::IntfImpl>(
46372dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnar                        COMPONENT_NAME, id, std::make_shared<C2SoftVorbisDec::IntfImpl>(mHelper)),
464af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo                deleter);
465033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim        return C2_OK;
466033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    }
467033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
468033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    virtual ~C2SoftVorbisDecFactory() override = default;
469af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo
470af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajooprivate:
471af57a0e4fc1e3a5883b1b3cf77a966d462417c4dManisha Jajoo    std::shared_ptr<C2ReflectorHelper> mHelper;
472033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim};
473033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
474033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}  // namespace android
475033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
476033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimextern "C" ::C2ComponentFactory* CreateCodec2Factory() {
477033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    ALOGV("in %s", __func__);
478033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    return new ::android::C2SoftVorbisDecFactory();
479033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
480033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim
481033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimextern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
482033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    ALOGV("in %s", __func__);
483033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim    delete factory;
484033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}
485