AacBqToPcmCbRenderer.cpp revision bb832e853d4afb11b0a3287b2eb0cad87696d631
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 true if there is AAC ADTS data, and it starts and ends on frame boundaries, 70 * false otherwise 71 */ 72bool AacBqToPcmCbRenderer::validateBufferStartEndOnFrameBoundaries(void* data, size_t size) 73{ 74 off64_t offset = 0; 75 size_t frameSize = 0; 76 77 if ((NULL == data) || (size == 0)) { 78 SL_LOGE("No ADTS to validate"); 79 return false; 80 } 81 82 while (offset < size) { 83 if ((frameSize = getAdtsFrameSize((uint8_t *)data, offset, size)) == 0) { 84 SL_LOGE("found ADTS frame of size 0 at offset %llu", offset); 85 return false; 86 } 87 //SL_LOGV("last good offset %llu", offset); 88 offset += frameSize; 89 if (offset > size) { 90 SL_LOGE("found incomplete ADTS frame at end of data"); 91 return false; 92 } 93 } 94 if (offset != size) { SL_LOGE("ADTS parsing error: reached end of incomplete frame"); } 95 assert(offset == size); 96 return true; 97} 98 99//-------------------------------------------------------------------------------------------------- 100AacBqToPcmCbRenderer::AacBqToPcmCbRenderer(AudioPlayback_Parameters* params) : 101 AudioToCbRenderer(params), 102 mBqSource(0) 103{ 104 SL_LOGD("AacBqToPcmCbRenderer::AacBqToPcmCbRenderer()"); 105 106} 107 108 109AacBqToPcmCbRenderer::~AacBqToPcmCbRenderer() { 110 SL_LOGD("AacBqToPcmCbRenderer::~AacBqToPcmCbRenderer()"); 111 112} 113 114 115//-------------------------------------------------- 116void AacBqToPcmCbRenderer::registerSourceQueueCallback( 117 const void* user, void *context, const void *caller) { 118 SL_LOGD("AacBqToPcmCbRenderer::registerQueueCallback"); 119 120 Mutex::Autolock _l(mBqSourceLock); 121 122 mBqSource = new BufferQueueSource(user, context, caller); 123 124 CHECK(mBqSource != 0); 125 SL_LOGD("AacBqToPcmCbRenderer::registerSourceQueueCallback end"); 126} 127 128 129//-------------------------------------------------- 130// Event handlers 131void AacBqToPcmCbRenderer::onPrepare() { 132 SL_LOGD("AacBqToPcmCbRenderer::onPrepare()"); 133 Mutex::Autolock _l(mBufferSourceLock); 134 135 // Initialize the PCM format info with the known parameters before the start of the decode 136 { 137 android::Mutex::Autolock autoLock(mPcmFormatLock); 138 mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_BITSPERSAMPLE] = SL_PCMSAMPLEFORMAT_FIXED_16; 139 mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_CONTAINERSIZE] = 16; 140 //FIXME not true on all platforms 141 mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_ENDIANNESS] = SL_BYTEORDER_LITTLEENDIAN; 142 mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_CHANNELMASK] = 0; 143 // initialization with the default values: they will be replaced by the actual values 144 // once the decoder has figured them out 145 mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_NUMCHANNELS] = mChannelCount; 146 mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_SAMPLESPERSEC] = mSampleRateHz; 147 } 148 149 sp<DataSource> dataSource; 150 { 151 Mutex::Autolock _l(mBqSourceLock); 152 dataSource = mBqSource; 153 } 154 if (dataSource == 0) { 155 SL_LOGE("AacBqToPcmCbRenderer::onPrepare(): Error no data source"); 156 notifyPrepared(MEDIA_ERROR_BASE); 157 return; 158 } 159 160 sp<MediaExtractor> extractor = new AacAdtsExtractor(dataSource); 161 if (extractor == 0) { 162 SL_LOGE("AacBqToPcmCbRenderer::onPrepare: Could not instantiate AAC extractor."); 163 notifyPrepared(ERROR_UNSUPPORTED); 164 return; 165 } 166 167 // only decoding a single track of data 168 const size_t kTrackToDecode = 0; 169 170 sp<MediaSource> source = extractor->getTrack(kTrackToDecode); 171 if (source == 0) { 172 SL_LOGE("AacBqToPcmCbRenderer::onPrepare: error getting source from extractor"); 173 notifyPrepared(ERROR_UNSUPPORTED); 174 return; 175 } 176 sp<MetaData> meta = extractor->getTrackMetaData(kTrackToDecode); 177 178 // the audio content is not raw PCM, so we need a decoder 179 OMXClient client; 180 CHECK_EQ(client.connect(), (status_t)OK); 181 182 source = OMXCodec::Create( 183 client.interface(), meta, false /* createEncoder */, 184 source); 185 186 if (source == NULL) { 187 SL_LOGE("AudioSfDecoder::onPrepare: Could not instantiate decoder."); 188 notifyPrepared(ERROR_UNSUPPORTED); 189 return; 190 } 191 192 meta = source->getFormat(); 193 194 SL_LOGD("AacBqToPcmCbRenderer::onPrepare() after instantiating decoder"); 195 196 if (source->start() != OK) { 197 SL_LOGE("AacBqToPcmCbRenderer::onPrepare() Failed to start source/decoder."); 198 notifyPrepared(MEDIA_ERROR_BASE); 199 return; 200 } 201 202 //--------------------------------- 203 CHECK(meta->findInt32(kKeyChannelCount, &mChannelCount)); 204 int32_t sr; 205 CHECK(meta->findInt32(kKeySampleRate, &sr)); 206 mSampleRateHz = (uint32_t) sr; 207 { 208 android::Mutex::Autolock autoLock(mPcmFormatLock); 209 mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_SAMPLESPERSEC] = mSampleRateHz; 210 mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_NUMCHANNELS] = mChannelCount; 211 } 212 SL_LOGV("AacBqToPcmCbRenderer::onPrepare() channel count=%d SR=%d", 213 mChannelCount, mSampleRateHz); 214 215 //--------------------------------- 216 // The data source, and audio source (a decoder) are ready to be used 217 mDataSource = dataSource; 218 mAudioSource = source; 219 mAudioSourceStarted = true; 220 221 //------------------------------------- 222 // signal successful completion of prepare 223 mStateFlags |= kFlagPrepared; 224 225 GenericPlayer::onPrepare(); 226 227 SL_LOGD("AacBqToPcmCbRenderer::onPrepare() done, mStateFlags=0x%x", mStateFlags); 228} 229 230} // namespace android 231