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