1f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia/*
2f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia * Copyright (C) 2017 The Android Open Source Project
3f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia *
4f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia * Licensed under the Apache License, Version 2.0 (the "License");
5f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia * you may not use this file except in compliance with the License.
6f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia * You may obtain a copy of the License at
7f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia *
8f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia *      http://www.apache.org/licenses/LICENSE-2.0
9f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia *
10f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia * Unless required by applicable law or agreed to in writing, software
11f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia * distributed under the License is distributed on an "AS IS" BASIS,
12f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia * See the License for the specific language governing permissions and
14f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia * limitations under the License.
15f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia */
16f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
17f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia//#define LOG_NDEBUG 0
18f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia#define LOG_TAG "SoftFlacDecoder"
19f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia#include <utils/Log.h>
20f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
21f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia#include "SoftFlacDecoder.h"
22f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia#include <OMX_AudioExt.h>
23f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia#include <OMX_IndexExt.h>
24f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
25f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia#include <cutils/properties.h>
26f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia#include <media/stagefright/foundation/ADebug.h>
27f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia#include <media/stagefright/MediaErrors.h>
28f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia#include <utils/misc.h>
29f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
30f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jianamespace android {
31f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
32f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jiatemplate<class T>
33f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jiastatic void InitOMXParams(T *params) {
34f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    params->nSize = sizeof(T);
35f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    params->nVersion.s.nVersionMajor = 1;
36f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    params->nVersion.s.nVersionMinor = 0;
37f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    params->nVersion.s.nRevision = 0;
38f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    params->nVersion.s.nStep = 0;
39f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia}
40f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
41f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei JiaSoftFlacDecoder::SoftFlacDecoder(
42f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        const char *name,
43f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        const OMX_CALLBACKTYPE *callbacks,
44f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        OMX_PTR appData,
45f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        OMX_COMPONENTTYPE **component)
46f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    : SimpleSoftOMXComponent(name, callbacks, appData, component),
47f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia      mFLACDecoder(NULL),
48f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia      mHasStreamInfo(false),
49f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia      mInputBufferCount(0),
50f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia      mSignalledError(false),
51f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia      mOutputPortSettingsChange(NONE) {
52f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    ALOGV("ctor:");
53f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    memset(&mStreamInfo, 0, sizeof(mStreamInfo));
54f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    initPorts();
55f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    initDecoder();
56f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia}
57f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
58f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei JiaSoftFlacDecoder::~SoftFlacDecoder() {
59f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    ALOGV("dtor:");
60f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia}
61f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
62f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jiavoid SoftFlacDecoder::initPorts() {
63f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    ALOGV("initPorts:");
64f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    OMX_PARAM_PORTDEFINITIONTYPE def;
65f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    InitOMXParams(&def);
66f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
67f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    def.nPortIndex = 0;
68f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    def.eDir = OMX_DirInput;
69f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    def.nBufferCountMin = kNumInputBuffers;
70f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    def.nBufferCountActual = def.nBufferCountMin;
71fd69fd3ee29bc61d2aee0161ce113dca7953d46fWei Jia    def.nBufferSize = 32768;
72f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    def.bEnabled = OMX_TRUE;
73f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    def.bPopulated = OMX_FALSE;
74f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    def.eDomain = OMX_PortDomainAudio;
75f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    def.bBuffersContiguous = OMX_FALSE;
76f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    def.nBufferAlignment = 1;
77f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
78f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    def.format.audio.cMIMEType = const_cast<char *>("audio/flac");
79f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    def.format.audio.pNativeRender = NULL;
80f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    def.format.audio.bFlagErrorConcealment = OMX_FALSE;
81f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    def.format.audio.eEncoding = OMX_AUDIO_CodingFLAC;
82f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
83f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    addPort(def);
84f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
85f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    def.nPortIndex = 1;
86f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    def.eDir = OMX_DirOutput;
87f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    def.nBufferCountMin = kNumOutputBuffers;
88f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    def.nBufferCountActual = def.nBufferCountMin;
89f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    def.nBufferSize = 4096 * FLACDecoder::kMaxChannels;
90f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    def.bEnabled = OMX_TRUE;
91f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    def.bPopulated = OMX_FALSE;
92f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    def.eDomain = OMX_PortDomainAudio;
93f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    def.bBuffersContiguous = OMX_FALSE;
94f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    def.nBufferAlignment = 2;
95f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
96f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
97f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    def.format.audio.pNativeRender = NULL;
98f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    def.format.audio.bFlagErrorConcealment = OMX_FALSE;
99f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
100f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
101f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    addPort(def);
102f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia}
103f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
104f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jiavoid SoftFlacDecoder::initDecoder() {
105f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    ALOGV("initDecoder:");
106f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    mFLACDecoder = FLACDecoder::Create();
107f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    if (mFLACDecoder == NULL) {
108f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        ALOGE("initDecoder: failed to create FLACDecoder");
109f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        mSignalledError = true;
110f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    }
111f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia}
112f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
113f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei JiaOMX_ERRORTYPE SoftFlacDecoder::initCheck() const {
114f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    if (mSignalledError) {
115f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        if (mFLACDecoder == NULL) {
116f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            ALOGE("initCheck: failed due to NULL encoder");
117f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            return OMX_ErrorDynamicResourcesUnavailable;
118f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        }
119f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        return OMX_ErrorUndefined;
120f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    }
121f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
122f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    return SimpleSoftOMXComponent::initCheck();
123f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia}
124f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
125f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei JiaOMX_ERRORTYPE SoftFlacDecoder::internalGetParameter(
126f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        OMX_INDEXTYPE index, OMX_PTR params) {
127f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    ALOGV("internalGetParameter: index(%x)", index);
128f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    switch ((OMX_U32)index) {
129148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa        case OMX_IndexParamAudioPortFormat:
130148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa        {
131148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa            OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
132148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa                (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
133148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa
134148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa            if (!isValidOMXParam(formatParams)) {
135148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa                return OMX_ErrorBadParameter;
136148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa            }
137148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa
138148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa            if (formatParams->nPortIndex > 1) {
139148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa                return OMX_ErrorUndefined;
140148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa            }
141148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa
142148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa            if (formatParams->nIndex > 0) {
143148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa                return OMX_ErrorNoMore;
144148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa            }
145148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa
146148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa            formatParams->eEncoding =
147148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa                (formatParams->nPortIndex == 0)
148148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa                    ? OMX_AUDIO_CodingFLAC : OMX_AUDIO_CodingPCM;
149148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa
150148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa            return OMX_ErrorNone;
151148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa        }
152f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        case OMX_IndexParamAudioFlac:
153f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        {
154f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            OMX_AUDIO_PARAM_FLACTYPE *flacParams =
155f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                (OMX_AUDIO_PARAM_FLACTYPE *)params;
156f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
157f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            if (!isValidOMXParam(flacParams)) {
158f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                ALOGE("internalGetParameter(OMX_IndexParamAudioFlac): invalid omx params");
159f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                return OMX_ErrorBadParameter;
160f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            }
161f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
162f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            if (flacParams->nPortIndex != 0) {
163f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                ALOGE("internalGetParameter(OMX_IndexParamAudioFlac): bad port index");
164f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                return OMX_ErrorBadPortIndex;
165f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            }
166f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
167f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            flacParams->nCompressionLevel = 0;
168f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
169f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            if (isConfigured()) {
170f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                flacParams->nChannels = mStreamInfo.channels;
171f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                flacParams->nSampleRate = mStreamInfo.sample_rate;
172f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            } else {
173f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                flacParams->nChannels = 1;
174f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                flacParams->nSampleRate = 44100;
175f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            }
176f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
177f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            return OMX_ErrorNone;
178f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        }
179f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
180f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        case OMX_IndexParamAudioPcm:
181f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        {
182f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
183f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
184f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
185f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            if (!isValidOMXParam(pcmParams)) {
186f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                ALOGE("internalGetParameter(OMX_IndexParamAudioPcm): invalid omx params");
187f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                return OMX_ErrorBadParameter;
188f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            }
189f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
190f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            if (pcmParams->nPortIndex != 1) {
191f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                ALOGE("internalGetParameter(OMX_IndexParamAudioPcm): bad port index");
192f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                return OMX_ErrorBadPortIndex;
193f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            }
194f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
195f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            pcmParams->eNumData = OMX_NumericalDataSigned;
196f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            pcmParams->eEndian = OMX_EndianBig;
197f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            pcmParams->bInterleaved = OMX_TRUE;
198f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            pcmParams->nBitPerSample = 16;
199f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
200f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
201f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
202f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            pcmParams->eChannelMapping[2] = OMX_AUDIO_ChannelCF;
203f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            pcmParams->eChannelMapping[3] = OMX_AUDIO_ChannelLFE;
204f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            pcmParams->eChannelMapping[4] = OMX_AUDIO_ChannelLS;
205f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            pcmParams->eChannelMapping[5] = OMX_AUDIO_ChannelRS;
206f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
207f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            if (isConfigured()) {
208f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                pcmParams->nChannels = mStreamInfo.channels;
209f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                pcmParams->nSamplingRate = mStreamInfo.sample_rate;
210f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            } else {
211f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                pcmParams->nChannels = 1;
212f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                pcmParams->nSamplingRate = 44100;
213f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            }
214f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
215f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            return OMX_ErrorNone;
216f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        }
217f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
218f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        default:
219f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            return SimpleSoftOMXComponent::internalGetParameter(index, params);
220f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    }
221f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia}
222f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
223f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei JiaOMX_ERRORTYPE SoftFlacDecoder::internalSetParameter(
224f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        OMX_INDEXTYPE index, const OMX_PTR params) {
225f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    ALOGV("internalSetParameter: index(%x)", (int)index);
226f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    switch ((int)index) {
227f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        case OMX_IndexParamStandardComponentRole:
228f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        {
229f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            const OMX_PARAM_COMPONENTROLETYPE *roleParams =
230f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                (const OMX_PARAM_COMPONENTROLETYPE *)params;
231f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
232f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            if (!isValidOMXParam(roleParams)) {
233f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                return OMX_ErrorBadParameter;
234f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            }
235f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
236f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            if (strncmp((const char *)roleParams->cRole,
237f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                        "audio_decoder.flac",
238f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                        OMX_MAX_STRINGNAME_SIZE - 1) != 0) {
239f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                return OMX_ErrorInvalidComponentName;
240f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            }
241f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
242f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            return OMX_ErrorNone;
243f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        }
244f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
245148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa        case OMX_IndexParamAudioPortFormat:
246148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa        {
247148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa            const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
248148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa                (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
249148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa
250148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa            if (!isValidOMXParam(formatParams)) {
251148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa                return OMX_ErrorBadParameter;
252148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa            }
253148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa
254148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa            if (formatParams->nPortIndex > 1) {
255148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa                return OMX_ErrorUndefined;
256148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa            }
257148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa
258148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa            if ((formatParams->nPortIndex == 0
259148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa                        && formatParams->eEncoding != OMX_AUDIO_CodingFLAC)
260148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa                || (formatParams->nPortIndex == 1
261148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa                        && formatParams->eEncoding != OMX_AUDIO_CodingPCM)) {
262148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa                return OMX_ErrorUndefined;
263148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa            }
264148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa
265148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa            return OMX_ErrorNone;
266148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa        }
267148fca5476052b2a99337a49516583b8976dd4e8Pawin Vongmasa
268f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        case OMX_IndexParamAudioPcm:
269f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        {
270f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
271f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
272f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
273f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            if (!isValidOMXParam(pcmParams)) {
274f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                return OMX_ErrorBadParameter;
275f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            }
276f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
277f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            if (pcmParams->nPortIndex != 1) {
278f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                return OMX_ErrorBadPortIndex;
279f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            }
280f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
281f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            return OMX_ErrorNone;
282f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        }
283f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
284f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        default:
285f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            return SimpleSoftOMXComponent::internalSetParameter(index, params);
286f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    }
287f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia}
288f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
289f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jiabool SoftFlacDecoder::isConfigured() const {
290f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    return mHasStreamInfo;
291f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia}
292f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
293f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jiavoid SoftFlacDecoder::onQueueFilled(OMX_U32 /* portIndex */) {
294f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    ALOGV("onQueueFilled:");
295f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    if (mSignalledError || mOutputPortSettingsChange != NONE) {
296f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        return;
297f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    }
298f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
299f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    List<BufferInfo *> &inQueue = getPortQueue(0);
300f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    List<BufferInfo *> &outQueue = getPortQueue(1);
301f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
302f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    while (!inQueue.empty() && !outQueue.empty()) {
303f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        BufferInfo *inInfo = *inQueue.begin();
304f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
30537b109667424ac0ec1a5a9db6c456fa9c48c0c4dRam Mohan        BufferInfo *outInfo = *outQueue.begin();
30637b109667424ac0ec1a5a9db6c456fa9c48c0c4dRam Mohan        OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
307f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        uint8_t* inBuffer = inHeader->pBuffer + inHeader->nOffset;
308f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        uint32_t inBufferLength = inHeader->nFilledLen;
309f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        bool endOfInput = (inHeader->nFlags & OMX_BUFFERFLAG_EOS) != 0;
310f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
31137b109667424ac0ec1a5a9db6c456fa9c48c0c4dRam Mohan        if (inHeader->nFilledLen == 0) {
31237b109667424ac0ec1a5a9db6c456fa9c48c0c4dRam Mohan            if (endOfInput) {
31337b109667424ac0ec1a5a9db6c456fa9c48c0c4dRam Mohan                outHeader->nFilledLen = 0;
31437b109667424ac0ec1a5a9db6c456fa9c48c0c4dRam Mohan                outHeader->nFlags = OMX_BUFFERFLAG_EOS;
31537b109667424ac0ec1a5a9db6c456fa9c48c0c4dRam Mohan                outInfo->mOwnedByUs = false;
31637b109667424ac0ec1a5a9db6c456fa9c48c0c4dRam Mohan                outQueue.erase(outQueue.begin());
31737b109667424ac0ec1a5a9db6c456fa9c48c0c4dRam Mohan                notifyFillBufferDone(outHeader);
31837b109667424ac0ec1a5a9db6c456fa9c48c0c4dRam Mohan            } else {
31937b109667424ac0ec1a5a9db6c456fa9c48c0c4dRam Mohan                ALOGE("onQueueFilled: emptyInputBuffer received");
32037b109667424ac0ec1a5a9db6c456fa9c48c0c4dRam Mohan            }
32137b109667424ac0ec1a5a9db6c456fa9c48c0c4dRam Mohan            inInfo->mOwnedByUs = false;
32237b109667424ac0ec1a5a9db6c456fa9c48c0c4dRam Mohan            inQueue.erase(inQueue.begin());
32337b109667424ac0ec1a5a9db6c456fa9c48c0c4dRam Mohan            notifyEmptyBufferDone(inHeader);
32437b109667424ac0ec1a5a9db6c456fa9c48c0c4dRam Mohan            return;
32537b109667424ac0ec1a5a9db6c456fa9c48c0c4dRam Mohan        }
326f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        if (mInputBufferCount == 0 && !(inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
327f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            ALOGE("onQueueFilled: first buffer should have OMX_BUFFERFLAG_CODECCONFIG set");
328f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            inHeader->nFlags |= OMX_BUFFERFLAG_CODECCONFIG;
329f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        }
330f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        if ((inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) != 0) {
331f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            status_t decoderErr = mFLACDecoder->parseMetadata(inBuffer, inBufferLength);
332f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            mInputBufferCount++;
333f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
334f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            if (decoderErr != OK && decoderErr != WOULD_BLOCK) {
335f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                ALOGE("onQueueFilled: FLACDecoder parseMetaData returns error %d", decoderErr);
336f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                mSignalledError = true;
337f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                notify(OMX_EventError, OMX_ErrorStreamCorrupt, decoderErr, NULL);
338f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                return;
339f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            }
340f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
341f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            inInfo->mOwnedByUs = false;
342f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            inQueue.erase(inQueue.begin());
343f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            notifyEmptyBufferDone(inHeader);
344f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
345f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            if (decoderErr == WOULD_BLOCK) {
346f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                continue;
347f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            }
348f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            mStreamInfo = mFLACDecoder->getStreamInfo();
349f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            mHasStreamInfo = true;
350f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
351f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            // Only send out port settings changed event if both sample rate
352f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            // and numChannels are valid.
353f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            if (mStreamInfo.sample_rate && mStreamInfo.channels) {
354f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                ALOGD("onQueueFilled: initially configuring decoder: %d Hz, %d channels",
355f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                    mStreamInfo.sample_rate, mStreamInfo.channels);
356f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
357f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
358f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                mOutputPortSettingsChange = AWAITING_DISABLED;
359f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            }
360f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            return;
361f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        }
362f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
363f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        short *outBuffer =
364f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                reinterpret_cast<short *>(outHeader->pBuffer + outHeader->nOffset);
365f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        size_t outBufferSize = outHeader->nAllocLen - outHeader->nOffset;
366f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
367f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        status_t decoderErr = mFLACDecoder->decodeOneFrame(
368f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                inBuffer, inBufferLength, outBuffer, &outBufferSize);
369f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        if (decoderErr != OK) {
370f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            ALOGE("onQueueFilled: FLACDecoder decodeOneFrame returns error %d", decoderErr);
371f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            mSignalledError = true;
372f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            notify(OMX_EventError, OMX_ErrorStreamCorrupt, decoderErr, NULL);
373f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            return;
374f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        }
375f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
376f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        mInputBufferCount++;
377f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        int64_t ts = inHeader->nTimeStamp;
378f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        inInfo->mOwnedByUs = false;
379f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        inQueue.erase(inQueue.begin());
380f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        notifyEmptyBufferDone(inHeader);
381f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
382f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        if (endOfInput) {
383f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            outHeader->nFlags = OMX_BUFFERFLAG_EOS;
384f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        } else if (outBufferSize == 0) {
385f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            continue;
386f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        } else {
387f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            outHeader->nFlags = 0;
388f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        }
389f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
390f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        outHeader->nFilledLen = outBufferSize;
391f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        outHeader->nTimeStamp = ts;
392f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
393f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        outInfo->mOwnedByUs = false;
394f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        outQueue.erase(outQueue.begin());
395f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        notifyFillBufferDone(outHeader);
396f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    }
397f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia}
398f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
399f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jiavoid SoftFlacDecoder::onPortFlushCompleted(OMX_U32 portIndex) {
400f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    ALOGV("onPortFlushCompleted: portIndex(%u)", portIndex);
401f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    if (portIndex == 0) {
402f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        drainDecoder();
403f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    }
404f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia}
405f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
406f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jiavoid SoftFlacDecoder::drainDecoder() {
407f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    mFLACDecoder->flush();
408f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia}
409f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
410f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jiavoid SoftFlacDecoder::onReset() {
411f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    drainDecoder();
412f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
413f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    memset(&mStreamInfo, 0, sizeof(mStreamInfo));
414f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    mHasStreamInfo = false;
415f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    mInputBufferCount = 0;
416f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    mSignalledError = false;
417f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    mOutputPortSettingsChange = NONE;
418f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia}
419f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
420f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jiavoid SoftFlacDecoder::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
421f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    ALOGV("onPortEnableCompleted: portIndex(%u), enabled(%d)", portIndex, enabled);
422f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    if (portIndex != 1) {
423f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        return;
424f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    }
425f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
426f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    switch (mOutputPortSettingsChange) {
427f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        case NONE:
428f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            break;
429f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
430f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        case AWAITING_DISABLED:
431f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        {
432f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            CHECK(!enabled);
433f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            mOutputPortSettingsChange = AWAITING_ENABLED;
434f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            PortInfo *info = editPortInfo(1 /* portIndex */);
435f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            if (!info->mDef.bEnabled) {
436f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia                info->mDef.nBufferSize = mStreamInfo.max_blocksize * mStreamInfo.channels * 2;
437f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            }
438f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            break;
439f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        }
440f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
441f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        default:
442f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        {
443f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
444f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            CHECK(enabled);
445f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            mOutputPortSettingsChange = NONE;
446f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia            break;
447f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        }
448f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    }
449f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia}
450f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
451f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia}  // namespace android
452f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia
453f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jiaandroid::SoftOMXComponent *createSoftOMXComponent(
454f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        const char *name, const OMX_CALLBACKTYPE *callbacks,
455f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia        OMX_PTR appData, OMX_COMPONENTTYPE **component) {
456f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    ALOGV("createSoftOMXComponent: flac decoder");
457f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia    return new android::SoftFlacDecoder(name, callbacks, appData, component);
458f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia}
459