SoftAAC2.cpp revision 6b7b8227cc8753fde4094ca8af2d381c2740826f
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_TAG "SoftAAC2"
18#include <utils/Log.h>
19
20#include "SoftAAC2.h"
21
22#include <media/stagefright/foundation/ADebug.h>
23#include <media/stagefright/foundation/hexdump.h>
24
25#define FILEREAD_MAX_LAYERS 2
26
27namespace android {
28
29template<class T>
30static void InitOMXParams(T *params) {
31    params->nSize = sizeof(T);
32    params->nVersion.s.nVersionMajor = 1;
33    params->nVersion.s.nVersionMinor = 0;
34    params->nVersion.s.nRevision = 0;
35    params->nVersion.s.nStep = 0;
36}
37
38SoftAAC2::SoftAAC2(
39        const char *name,
40        const OMX_CALLBACKTYPE *callbacks,
41        OMX_PTR appData,
42        OMX_COMPONENTTYPE **component)
43    : SimpleSoftOMXComponent(name, callbacks, appData, component),
44      mAACDecoder(NULL),
45      mStreamInfo(NULL),
46      mIsADTS(false),
47      mInputBufferCount(0),
48      mSignalledError(false),
49      mInputDiscontinuity(false),
50      mAnchorTimeUs(0),
51      mNumSamplesOutput(0),
52      mOutputPortSettingsChange(NONE) {
53    initPorts();
54    CHECK_EQ(initDecoder(), (status_t)OK);
55}
56
57SoftAAC2::~SoftAAC2() {
58    aacDecoder_Close(mAACDecoder);
59}
60
61void SoftAAC2::initPorts() {
62    OMX_PARAM_PORTDEFINITIONTYPE def;
63    InitOMXParams(&def);
64
65    def.nPortIndex = 0;
66    def.eDir = OMX_DirInput;
67    def.nBufferCountMin = kNumBuffers;
68    def.nBufferCountActual = def.nBufferCountMin;
69    def.nBufferSize = 8192;
70    def.bEnabled = OMX_TRUE;
71    def.bPopulated = OMX_FALSE;
72    def.eDomain = OMX_PortDomainAudio;
73    def.bBuffersContiguous = OMX_FALSE;
74    def.nBufferAlignment = 1;
75
76    def.format.audio.cMIMEType = const_cast<char *>("audio/aac");
77    def.format.audio.pNativeRender = NULL;
78    def.format.audio.bFlagErrorConcealment = OMX_FALSE;
79    def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
80
81    addPort(def);
82
83    def.nPortIndex = 1;
84    def.eDir = OMX_DirOutput;
85    def.nBufferCountMin = kNumBuffers;
86    def.nBufferCountActual = def.nBufferCountMin;
87    def.nBufferSize = 8192 * 2;
88    def.bEnabled = OMX_TRUE;
89    def.bPopulated = OMX_FALSE;
90    def.eDomain = OMX_PortDomainAudio;
91    def.bBuffersContiguous = OMX_FALSE;
92    def.nBufferAlignment = 2;
93
94    def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
95    def.format.audio.pNativeRender = NULL;
96    def.format.audio.bFlagErrorConcealment = OMX_FALSE;
97    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
98
99    addPort(def);
100}
101
102status_t SoftAAC2::initDecoder() {
103    status_t status = UNKNOWN_ERROR;
104    mAACDecoder = aacDecoder_Open(TT_MP4_RAW, /* num layers */ 1);
105    if (mAACDecoder != NULL) {
106        mStreamInfo = aacDecoder_GetStreamInfo(mAACDecoder);
107        if (mStreamInfo != NULL) {
108            status = OK;
109        }
110    }
111    return status;
112}
113
114OMX_ERRORTYPE SoftAAC2::internalGetParameter(
115        OMX_INDEXTYPE index, OMX_PTR params) {
116    switch (index) {
117        case OMX_IndexParamAudioAac:
118        {
119            OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
120                (OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
121
122            if (aacParams->nPortIndex != 0) {
123                return OMX_ErrorUndefined;
124            }
125
126            aacParams->nBitRate = 0;
127            aacParams->nAudioBandWidth = 0;
128            aacParams->nAACtools = 0;
129            aacParams->nAACERtools = 0;
130            aacParams->eAACProfile = OMX_AUDIO_AACObjectMain;
131
132            aacParams->eAACStreamFormat =
133                mIsADTS
134                    ? OMX_AUDIO_AACStreamFormatMP4ADTS
135                    : OMX_AUDIO_AACStreamFormatMP4FF;
136
137            aacParams->eChannelMode = OMX_AUDIO_ChannelModeStereo;
138
139            if (!isConfigured()) {
140                aacParams->nChannels = 1;
141                aacParams->nSampleRate = 44100;
142                aacParams->nFrameLength = 0;
143            } else {
144                aacParams->nChannels = mStreamInfo->channelConfig;
145                aacParams->nSampleRate = mStreamInfo->aacSampleRate;
146                aacParams->nFrameLength = mStreamInfo->aacSamplesPerFrame;
147            }
148
149            return OMX_ErrorNone;
150        }
151
152        case OMX_IndexParamAudioPcm:
153        {
154            OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
155                (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
156
157            if (pcmParams->nPortIndex != 1) {
158                return OMX_ErrorUndefined;
159            }
160
161            pcmParams->eNumData = OMX_NumericalDataSigned;
162            pcmParams->eEndian = OMX_EndianBig;
163            pcmParams->bInterleaved = OMX_TRUE;
164            pcmParams->nBitPerSample = 16;
165            pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
166            pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
167            pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
168            pcmParams->eChannelMapping[2] = OMX_AUDIO_ChannelCF;
169            pcmParams->eChannelMapping[3] = OMX_AUDIO_ChannelLFE;
170            pcmParams->eChannelMapping[4] = OMX_AUDIO_ChannelLS;
171            pcmParams->eChannelMapping[5] = OMX_AUDIO_ChannelRS;
172
173            if (!isConfigured()) {
174                pcmParams->nChannels = 1;
175                pcmParams->nSamplingRate = 44100;
176            } else {
177                pcmParams->nChannels = mStreamInfo->channelConfig;
178                pcmParams->nSamplingRate = mStreamInfo->sampleRate;
179            }
180
181            return OMX_ErrorNone;
182        }
183
184        default:
185            return SimpleSoftOMXComponent::internalGetParameter(index, params);
186    }
187}
188
189OMX_ERRORTYPE SoftAAC2::internalSetParameter(
190        OMX_INDEXTYPE index, const OMX_PTR params) {
191    switch (index) {
192        case OMX_IndexParamStandardComponentRole:
193        {
194            const OMX_PARAM_COMPONENTROLETYPE *roleParams =
195                (const OMX_PARAM_COMPONENTROLETYPE *)params;
196
197            if (strncmp((const char *)roleParams->cRole,
198                        "audio_decoder.aac",
199                        OMX_MAX_STRINGNAME_SIZE - 1)) {
200                return OMX_ErrorUndefined;
201            }
202
203            return OMX_ErrorNone;
204        }
205
206        case OMX_IndexParamAudioAac:
207        {
208            const OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
209                (const OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
210
211            if (aacParams->nPortIndex != 0) {
212                return OMX_ErrorUndefined;
213            }
214
215            if (aacParams->eAACStreamFormat == OMX_AUDIO_AACStreamFormatMP4FF) {
216                mIsADTS = false;
217            } else if (aacParams->eAACStreamFormat
218                        == OMX_AUDIO_AACStreamFormatMP4ADTS) {
219                mIsADTS = true;
220            } else {
221                return OMX_ErrorUndefined;
222            }
223
224            return OMX_ErrorNone;
225        }
226
227        case OMX_IndexParamAudioPcm:
228        {
229            const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
230                (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
231
232            if (pcmParams->nPortIndex != 1) {
233                return OMX_ErrorUndefined;
234            }
235
236            return OMX_ErrorNone;
237        }
238
239        default:
240            return SimpleSoftOMXComponent::internalSetParameter(index, params);
241    }
242}
243
244bool SoftAAC2::isConfigured() const {
245    return mInputBufferCount > 0;
246}
247
248void SoftAAC2::onQueueFilled(OMX_U32 portIndex) {
249    if (mSignalledError || mOutputPortSettingsChange != NONE) {
250        return;
251    }
252
253    UCHAR* inBuffer[FILEREAD_MAX_LAYERS];
254    UINT inBufferLength[FILEREAD_MAX_LAYERS] = {0};
255    UINT bytesValid[FILEREAD_MAX_LAYERS] = {0};
256    AAC_DECODER_ERROR decoderErr;
257
258    List<BufferInfo *> &inQueue = getPortQueue(0);
259    List<BufferInfo *> &outQueue = getPortQueue(1);
260
261    if (portIndex == 0 && mInputBufferCount == 0) {
262        ++mInputBufferCount;
263        BufferInfo *info = *inQueue.begin();
264        OMX_BUFFERHEADERTYPE *header = info->mHeader;
265
266        inBuffer[0] = header->pBuffer + header->nOffset;
267        inBufferLength[0] = header->nFilledLen;
268
269        AAC_DECODER_ERROR decoderErr =
270            aacDecoder_ConfigRaw(mAACDecoder,
271                                 inBuffer,
272                                 inBufferLength);
273
274        if (decoderErr != AAC_DEC_OK) {
275            mSignalledError = true;
276            notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
277            return;
278        }
279
280        inQueue.erase(inQueue.begin());
281        info->mOwnedByUs = false;
282        notifyEmptyBufferDone(header);
283
284        notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
285        mOutputPortSettingsChange = AWAITING_DISABLED;
286        return;
287    }
288
289    while (!inQueue.empty() && !outQueue.empty()) {
290        BufferInfo *inInfo = *inQueue.begin();
291        OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
292
293        BufferInfo *outInfo = *outQueue.begin();
294        OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
295
296        if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
297            inQueue.erase(inQueue.begin());
298            inInfo->mOwnedByUs = false;
299            notifyEmptyBufferDone(inHeader);
300
301            outHeader->nFilledLen = 0;
302            outHeader->nFlags = OMX_BUFFERFLAG_EOS;
303
304            outQueue.erase(outQueue.begin());
305            outInfo->mOwnedByUs = false;
306            notifyFillBufferDone(outHeader);
307            return;
308        }
309
310        if (inHeader->nOffset == 0) {
311            mAnchorTimeUs = inHeader->nTimeStamp;
312            mNumSamplesOutput = 0;
313        }
314
315        size_t adtsHeaderSize = 0;
316        if (mIsADTS) {
317            // skip 30 bits, aac_frame_length follows.
318            // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
319
320            const uint8_t *adtsHeader = inHeader->pBuffer + inHeader->nOffset;
321
322            CHECK_GE(inHeader->nFilledLen, 7);
323
324            bool protectionAbsent = (adtsHeader[1] & 1);
325
326            unsigned aac_frame_length =
327                ((adtsHeader[3] & 3) << 11)
328                | (adtsHeader[4] << 3)
329                | (adtsHeader[5] >> 5);
330
331            CHECK_GE(inHeader->nFilledLen, aac_frame_length);
332
333            adtsHeaderSize = (protectionAbsent ? 7 : 9);
334
335            inBuffer[0] = (UCHAR *)adtsHeader + adtsHeaderSize;
336            inBufferLength[0] = aac_frame_length - adtsHeaderSize;
337
338            inHeader->nOffset += adtsHeaderSize;
339            inHeader->nFilledLen -= adtsHeaderSize;
340        } else {
341            inBuffer[0] = inHeader->pBuffer + inHeader->nOffset;
342            inBufferLength[0] = inHeader->nFilledLen;
343        }
344
345
346        // Fill and decode
347        INT_PCM *outBuffer = reinterpret_cast<INT_PCM *>(outHeader->pBuffer + outHeader->nOffset);
348        bytesValid[0] = inBufferLength[0];
349
350        int flags = mInputDiscontinuity ? AACDEC_INTR : 0;
351        int prevSampleRate = mStreamInfo->sampleRate;
352        decoderErr = aacDecoder_Fill(mAACDecoder,
353                                     inBuffer,
354                                     inBufferLength,
355                                     bytesValid);
356
357        decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
358                                            outBuffer,
359                                            outHeader->nAllocLen,
360                                            flags);
361
362        mInputDiscontinuity = false;
363
364        /*
365         * AAC+/eAAC+ streams can be signalled in two ways: either explicitly
366         * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual
367         * rate system and the sampling rate in the final output is actually
368         * doubled compared with the core AAC decoder sampling rate.
369         *
370         * Explicit signalling is done by explicitly defining SBR audio object
371         * type in the bitstream. Implicit signalling is done by embedding
372         * SBR content in AAC extension payload specific to SBR, and hence
373         * requires an AAC decoder to perform pre-checks on actual audio frames.
374         *
375         * Thus, we could not say for sure whether a stream is
376         * AAC+/eAAC+ until the first data frame is decoded.
377         */
378        if (decoderErr == AAC_DEC_OK && mInputBufferCount <= 2) {
379            if (mStreamInfo->sampleRate != prevSampleRate) {
380                // We're going to want to revisit this input buffer, but
381                // may have already advanced the offset. Undo that if
382                // necessary.
383                inHeader->nOffset -= adtsHeaderSize;
384                inHeader->nFilledLen += adtsHeaderSize;
385
386                notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
387                mOutputPortSettingsChange = AWAITING_DISABLED;
388                return;
389            }
390        }
391
392        size_t numOutBytes =
393            mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels;
394
395        if (decoderErr == AAC_DEC_OK) {
396            UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0];
397            inHeader->nFilledLen -= inBufferUsedLength;
398            inHeader->nOffset += inBufferUsedLength;
399        } else {
400            ALOGW("AAC decoder returned error %d, substituting silence",
401                  decoderErr);
402
403            memset(outHeader->pBuffer + outHeader->nOffset, 0, numOutBytes);
404
405            // Discard input buffer.
406            inHeader->nFilledLen = 0;
407
408            // fall through
409        }
410
411        if (decoderErr == AAC_DEC_OK || mNumSamplesOutput > 0) {
412            // We'll only output data if we successfully decoded it or
413            // we've previously decoded valid data, in the latter case
414            // (decode failed) we'll output a silent frame.
415            outHeader->nFilledLen = numOutBytes;
416            outHeader->nFlags = 0;
417
418            outHeader->nTimeStamp =
419                mAnchorTimeUs
420                    + (mNumSamplesOutput * 1000000ll) / mStreamInfo->sampleRate;
421
422            mNumSamplesOutput += mStreamInfo->frameSize;
423
424            outInfo->mOwnedByUs = false;
425            outQueue.erase(outQueue.begin());
426            outInfo = NULL;
427            notifyFillBufferDone(outHeader);
428            outHeader = NULL;
429        }
430
431        if (inHeader->nFilledLen == 0) {
432            inInfo->mOwnedByUs = false;
433            inQueue.erase(inQueue.begin());
434            inInfo = NULL;
435            notifyEmptyBufferDone(inHeader);
436            inHeader = NULL;
437        }
438
439        if (decoderErr == AAC_DEC_OK) {
440            ++mInputBufferCount;
441        }
442    }
443}
444
445void SoftAAC2::onPortFlushCompleted(OMX_U32 portIndex) {
446    if (portIndex == 0) {
447        // Make sure that the next buffer output does not still
448        // depend on fragments from the last one decoded.
449        mInputDiscontinuity = true;
450    }
451}
452
453void SoftAAC2::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
454    if (portIndex != 1) {
455        return;
456    }
457
458    switch (mOutputPortSettingsChange) {
459        case NONE:
460            break;
461
462        case AWAITING_DISABLED:
463        {
464            CHECK(!enabled);
465            mOutputPortSettingsChange = AWAITING_ENABLED;
466            break;
467        }
468
469        default:
470        {
471            CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
472            CHECK(enabled);
473            mOutputPortSettingsChange = NONE;
474            break;
475        }
476    }
477}
478
479}  // namespace android
480
481android::SoftOMXComponent *createSoftOMXComponent(
482        const char *name, const OMX_CALLBACKTYPE *callbacks,
483        OMX_PTR appData, OMX_COMPONENTTYPE **component) {
484    return new android::SoftAAC2(name, callbacks, appData, component);
485}
486