AacBqToPcmCbRenderer.cpp revision 0f92f48017588949daf7d24a339423e149bb2555
1/*
2 * Copyright (C) 2011 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 USE_LOG SLAndroidLogLevel_Debug
18
19#include "sles_allinclusive.h"
20#include "android/include/AacBqToPcmCbRenderer.h"
21#include <media/stagefright/foundation/ADebug.h>
22
23namespace android {
24
25// ADTS header size is 7, but frame size information ends on byte 6 (when counting from byte 1)
26#define ADTS_HEADER_SIZE_UP_TO_FRAMESIZE 6
27
28/**
29 * Returns the size of an AAC ADTS frame.
30 * Note that if the returned value + offset > size, it means that a partial frame starts at that
31 *   offset, but this function will still return the size of the full frame.
32 * @param data pointer to the compressed audio data
33 * @param offset offset in bytes relative to data of where the frame is supposed to start
34 * @param size the size in bytes of the data block starting at data
35 * @return the size in bytes of the AAC ADTS frame starting at the given offset of the given
36 *    memory address, 0 if the frame couldn't be parsed.
37 */
38static size_t getAdtsFrameSize(const uint8_t *data, off64_t offset, size_t size) {
39    size_t frameSize = 0;
40
41    if (!(offset + ADTS_HEADER_SIZE_UP_TO_FRAMESIZE < size)) {
42        SL_LOGE("AacBqToPcmCbRenderer::getAdtsFrameSize() returns 0 (can't read syncword or header)"
43                );
44        return 0;
45    }
46
47    const uint8_t *syncword = data + offset;
48    if ((syncword[0] != 0xff) || ((syncword[1] & 0xf6) != 0xf0)) {
49        SL_LOGE("AacBqToPcmCbRenderer::getAdtsFrameSize() returns 0 (wrong syncword)");
50        return 0;
51    }
52
53    const uint8_t protectionAbsent = data[offset+1] & 0x1;
54
55    const uint8_t* header = data + offset + 3;
56    frameSize = (header[0] & 0x3) << 11 | header[1] << 3 | header[2] >> 5;
57    // the frame size read already contains the size of the header, so no need to add it here
58    frameSize += protectionAbsent ? 0 : 2;
59
60    SL_LOGV("AacBqToPcmCbRenderer::getAdtsFrameSize() returns %u", frameSize);
61
62    return frameSize;
63}
64
65/**
66 * Returns whether a block of memory starts and ends on AAC ADTS frame boundaries
67 * @param data pointer to the compressed audio data
68 * @param size the size in bytes of the data block to validate
69 * @return SL_RESULT_SUCCESS if there is AAC ADTS data, and it starts and ends on frame boundaries,
70 *    or an appropriate error code otherwise:
71 *      SL_RESULT_PARAMETER_INVALID if not possible to attempt validation of even one frame
72 *      SL_RESULT_CONTENT_CORRUPTED if the frame contents are otherwise invalid
73 */
74SLresult AacBqToPcmCbRenderer::validateBufferStartEndOnFrameBoundaries(void* data, size_t size)
75{
76    off64_t offset = 0;
77    size_t frameSize = 0;
78
79    if ((NULL == data) || (size == 0)) {
80        SL_LOGE("No ADTS to validate");
81        return SL_RESULT_PARAMETER_INVALID;
82    }
83
84    while (offset < size) {
85        if ((frameSize = getAdtsFrameSize((uint8_t *)data, offset, size)) == 0) {
86            SL_LOGE("found ADTS frame of size 0 at offset %llu", offset);
87            return SL_RESULT_CONTENT_CORRUPTED;
88        }
89        //SL_LOGV("last good offset %llu", offset);
90        offset += frameSize;
91        if (offset > size) {
92            SL_LOGE("found incomplete ADTS frame at end of data");
93            return SL_RESULT_CONTENT_CORRUPTED;
94        }
95    }
96    if (offset != size) { SL_LOGE("ADTS parsing error: reached end of incomplete frame"); }
97    assert(offset == size);
98    return SL_RESULT_SUCCESS;
99}
100
101//--------------------------------------------------------------------------------------------------
102AacBqToPcmCbRenderer::AacBqToPcmCbRenderer(AudioPlayback_Parameters* params) :
103        AudioToCbRenderer(params),
104        mBqSource(0)
105{
106    SL_LOGD("AacBqToPcmCbRenderer::AacBqToPcmCbRenderer()");
107
108}
109
110
111AacBqToPcmCbRenderer::~AacBqToPcmCbRenderer() {
112    SL_LOGD("AacBqToPcmCbRenderer::~AacBqToPcmCbRenderer()");
113
114}
115
116
117//--------------------------------------------------
118void AacBqToPcmCbRenderer::registerSourceQueueCallback(
119        const void* user, void *context,  const void *caller) {
120    SL_LOGD("AacBqToPcmCbRenderer::registerQueueCallback");
121
122    Mutex::Autolock _l(mBqSourceLock);
123
124    mBqSource = new BufferQueueSource(user, context, caller);
125
126    CHECK(mBqSource != 0);
127    SL_LOGD("AacBqToPcmCbRenderer::registerSourceQueueCallback end");
128}
129
130
131//--------------------------------------------------
132// Event handlers
133void AacBqToPcmCbRenderer::onPrepare() {
134    SL_LOGD("AacBqToPcmCbRenderer::onPrepare()");
135    Mutex::Autolock _l(mBufferSourceLock);
136
137    // Initialize the PCM format info with the known parameters before the start of the decode
138    {
139        android::Mutex::Autolock autoLock(mPcmFormatLock);
140        mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_BITSPERSAMPLE] = SL_PCMSAMPLEFORMAT_FIXED_16;
141        mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_CONTAINERSIZE] = 16;
142        //FIXME not true on all platforms
143        mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_ENDIANNESS] = SL_BYTEORDER_LITTLEENDIAN;
144        //    initialization with the default values: they will be replaced by the actual values
145        //      once the decoder has figured them out
146        mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_NUMCHANNELS] = mChannelCount;
147        mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_SAMPLERATE] = mSampleRateHz;
148        mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_CHANNELMASK] = mChannelMask;
149    }
150
151    sp<DataSource> dataSource;
152    {
153        Mutex::Autolock _l(mBqSourceLock);
154        dataSource = mBqSource;
155    }
156    if (dataSource == 0) {
157        SL_LOGE("AacBqToPcmCbRenderer::onPrepare(): Error no data source");
158        notifyPrepared(MEDIA_ERROR_BASE);
159        return;
160    }
161
162    sp<MediaExtractor> extractor = new AacAdtsExtractor(dataSource);
163    if (extractor == 0) {
164        SL_LOGE("AacBqToPcmCbRenderer::onPrepare: Could not instantiate AAC extractor.");
165        notifyPrepared(ERROR_UNSUPPORTED);
166        return;
167    }
168
169    // only decoding a single track of data
170    const size_t kTrackToDecode = 0;
171
172    sp<MediaSource> source = extractor->getTrack(kTrackToDecode);
173    if (source == 0) {
174        SL_LOGE("AacBqToPcmCbRenderer::onPrepare: error getting source from extractor");
175        notifyPrepared(ERROR_UNSUPPORTED);
176        return;
177    }
178    sp<MetaData> meta = extractor->getTrackMetaData(kTrackToDecode);
179
180    // the audio content is not raw PCM, so we need a decoder
181    OMXClient client;
182    CHECK_EQ(client.connect(), (status_t)OK);
183
184    source = OMXCodec::Create(
185            client.interface(), meta, false /* createEncoder */,
186            source);
187
188    if (source == NULL) {
189        SL_LOGE("AudioSfDecoder::onPrepare: Could not instantiate decoder.");
190        notifyPrepared(ERROR_UNSUPPORTED);
191        return;
192    }
193
194    meta = source->getFormat();
195
196    SL_LOGD("AacBqToPcmCbRenderer::onPrepare() after instantiating decoder");
197
198    if (source->start() != OK) {
199        SL_LOGE("AacBqToPcmCbRenderer::onPrepare() Failed to start source/decoder.");
200        notifyPrepared(MEDIA_ERROR_BASE);
201        return;
202    }
203
204    //---------------------------------
205    CHECK(meta->findInt32(kKeyChannelCount, &mChannelCount));
206    int32_t sr;
207    CHECK(meta->findInt32(kKeySampleRate, &sr));
208    mSampleRateHz = (uint32_t) sr;
209    // FIXME similar to AudioSfDecoder::onPrepare()
210    mChannelMask = channelCountToMask(mChannelCount);
211
212    {
213            android::Mutex::Autolock autoLock(mPcmFormatLock);
214            mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_SAMPLERATE] = mSampleRateHz;
215            mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_NUMCHANNELS] = mChannelCount;
216            mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_CHANNELMASK] = mChannelMask;
217    }
218    SL_LOGV("AacBqToPcmCbRenderer::onPrepare() channel count=%d SR=%d",
219            mChannelCount, mSampleRateHz);
220
221    //---------------------------------
222    // The data source, and audio source (a decoder) are ready to be used
223    mDataSource = dataSource;
224    mAudioSource = source;
225    mAudioSourceStarted = true;
226
227    //-------------------------------------
228    // signal successful completion of prepare
229    mStateFlags |= kFlagPrepared;
230
231    GenericPlayer::onPrepare();
232
233    SL_LOGD("AacBqToPcmCbRenderer::onPrepare() done, mStateFlags=0x%x", mStateFlags);
234}
235
236} // namespace android
237