SoftRaw.cpp revision d411b4ca2945cd8974a3a78199fce94646950128
1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "SoftRaw"
19#include <utils/Log.h>
20
21#include "SoftRaw.h"
22
23#include <media/stagefright/foundation/ADebug.h>
24#include <media/stagefright/foundation/hexdump.h>
25
26namespace android {
27
28template<class T>
29static void InitOMXParams(T *params) {
30    params->nSize = sizeof(T);
31    params->nVersion.s.nVersionMajor = 1;
32    params->nVersion.s.nVersionMinor = 0;
33    params->nVersion.s.nRevision = 0;
34    params->nVersion.s.nStep = 0;
35}
36
37SoftRaw::SoftRaw(
38        const char *name,
39        const OMX_CALLBACKTYPE *callbacks,
40        OMX_PTR appData,
41        OMX_COMPONENTTYPE **component)
42    : SimpleSoftOMXComponent(name, callbacks, appData, component),
43      mSignalledError(false),
44      mChannelCount(2),
45      mSampleRate(44100) {
46    initPorts();
47    CHECK_EQ(initDecoder(), (status_t)OK);
48}
49
50SoftRaw::~SoftRaw() {
51}
52
53void SoftRaw::initPorts() {
54    OMX_PARAM_PORTDEFINITIONTYPE def;
55    InitOMXParams(&def);
56
57    def.nPortIndex = 0;
58    def.eDir = OMX_DirInput;
59    def.nBufferCountMin = kNumBuffers;
60    def.nBufferCountActual = def.nBufferCountMin;
61    def.nBufferSize = 32 * 1024;
62    def.bEnabled = OMX_TRUE;
63    def.bPopulated = OMX_FALSE;
64    def.eDomain = OMX_PortDomainAudio;
65    def.bBuffersContiguous = OMX_FALSE;
66    def.nBufferAlignment = 1;
67
68    def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
69    def.format.audio.pNativeRender = NULL;
70    def.format.audio.bFlagErrorConcealment = OMX_FALSE;
71    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
72
73    addPort(def);
74
75    def.nPortIndex = 1;
76    def.eDir = OMX_DirOutput;
77    def.nBufferCountMin = kNumBuffers;
78    def.nBufferCountActual = def.nBufferCountMin;
79    def.nBufferSize = 32 * 1024;
80    def.bEnabled = OMX_TRUE;
81    def.bPopulated = OMX_FALSE;
82    def.eDomain = OMX_PortDomainAudio;
83    def.bBuffersContiguous = OMX_FALSE;
84    def.nBufferAlignment = 2;
85
86    def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
87    def.format.audio.pNativeRender = NULL;
88    def.format.audio.bFlagErrorConcealment = OMX_FALSE;
89    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
90
91    addPort(def);
92}
93
94status_t SoftRaw::initDecoder() {
95    return OK;
96}
97
98OMX_ERRORTYPE SoftRaw::internalGetParameter(
99        OMX_INDEXTYPE index, OMX_PTR params) {
100    switch (index) {
101        case OMX_IndexParamAudioPcm:
102        {
103            OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
104                (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
105
106            if (pcmParams->nPortIndex != 0 && pcmParams->nPortIndex != 1) {
107                return OMX_ErrorUndefined;
108            }
109
110            pcmParams->eNumData = OMX_NumericalDataSigned;
111            pcmParams->eEndian = OMX_EndianBig;
112            pcmParams->bInterleaved = OMX_TRUE;
113            pcmParams->nBitPerSample = 16;
114            pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
115            pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
116            pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
117
118            pcmParams->nChannels = mChannelCount;
119            pcmParams->nSamplingRate = mSampleRate;
120
121            return OMX_ErrorNone;
122        }
123
124        default:
125            return SimpleSoftOMXComponent::internalGetParameter(index, params);
126    }
127}
128
129OMX_ERRORTYPE SoftRaw::internalSetParameter(
130        OMX_INDEXTYPE index, const OMX_PTR params) {
131    switch (index) {
132        case OMX_IndexParamStandardComponentRole:
133        {
134            const OMX_PARAM_COMPONENTROLETYPE *roleParams =
135                (const OMX_PARAM_COMPONENTROLETYPE *)params;
136
137            if (strncmp((const char *)roleParams->cRole,
138                        "audio_decoder.raw",
139                        OMX_MAX_STRINGNAME_SIZE - 1)) {
140                return OMX_ErrorUndefined;
141            }
142
143            return OMX_ErrorNone;
144        }
145
146        case OMX_IndexParamAudioPcm:
147        {
148            const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
149                (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
150
151            if (pcmParams->nPortIndex != 0) {
152                return OMX_ErrorUndefined;
153            }
154
155            mChannelCount = pcmParams->nChannels;
156            mSampleRate = pcmParams->nSamplingRate;
157
158            return OMX_ErrorNone;
159        }
160
161        default:
162            return SimpleSoftOMXComponent::internalSetParameter(index, params);
163    }
164}
165
166void SoftRaw::onQueueFilled(OMX_U32 /* portIndex */) {
167    if (mSignalledError) {
168        return;
169    }
170
171    List<BufferInfo *> &inQueue = getPortQueue(0);
172    List<BufferInfo *> &outQueue = getPortQueue(1);
173
174    while (!inQueue.empty() && !outQueue.empty()) {
175        BufferInfo *inInfo = *inQueue.begin();
176        OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
177
178        BufferInfo *outInfo = *outQueue.begin();
179        OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
180
181        CHECK_GE(outHeader->nAllocLen, inHeader->nFilledLen);
182        memcpy(outHeader->pBuffer,
183               inHeader->pBuffer + inHeader->nOffset,
184               inHeader->nFilledLen);
185
186        outHeader->nFlags = inHeader->nFlags;
187        outHeader->nOffset = 0;
188        outHeader->nFilledLen = inHeader->nFilledLen;
189        outHeader->nTimeStamp = inHeader->nTimeStamp;
190
191        bool sawEOS = (inHeader->nFlags & OMX_BUFFERFLAG_EOS) != 0;
192
193        inQueue.erase(inQueue.begin());
194        inInfo->mOwnedByUs = false;
195        notifyEmptyBufferDone(inHeader);
196
197        outQueue.erase(outQueue.begin());
198        outInfo->mOwnedByUs = false;
199        notifyFillBufferDone(outHeader);
200
201        if (sawEOS) {
202            break;
203        }
204    }
205}
206
207}  // namespace android
208
209android::SoftOMXComponent *createSoftOMXComponent(
210        const char *name, const OMX_CALLBACKTYPE *callbacks,
211        OMX_PTR appData, OMX_COMPONENTTYPE **component) {
212    return new android::SoftRaw(name, callbacks, appData, component);
213}
214