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 23 namespace 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 */ 38 static 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 59 // protectionAbsent is 0 if there is CRC 60 static const size_t kAdtsHeaderLengthNoCrc = 7; 61 static const size_t kAdtsHeaderLengthWithCrc = 9; 62 size_t headSize = protectionAbsent ? kAdtsHeaderLengthNoCrc : kAdtsHeaderLengthWithCrc; 63 if (headSize > frameSize) { 64 SL_LOGE("AacBqToPcmCbRenderer::getAdtsFrameSize() returns 0 (frameSize %u < headSize %u)", 65 frameSize, headSize); 66 return 0; 67 } 68 69 SL_LOGV("AacBqToPcmCbRenderer::getAdtsFrameSize() returns %u", frameSize); 70 71 return frameSize; 72 } 73 74 /** 75 * Returns whether a block of memory starts and ends on AAC ADTS frame boundaries 76 * @param data pointer to the compressed audio data 77 * @param size the size in bytes of the data block to validate 78 * @return SL_RESULT_SUCCESS if there is AAC ADTS data, and it starts and ends on frame boundaries, 79 * or an appropriate error code otherwise: 80 * SL_RESULT_PARAMETER_INVALID if not possible to attempt validation of even one frame 81 * SL_RESULT_CONTENT_CORRUPTED if the frame contents are otherwise invalid 82 */ 83 SLresult AacBqToPcmCbRenderer::validateBufferStartEndOnFrameBoundaries(void* data, size_t size) 84 { 85 off64_t offset = 0; 86 size_t frameSize = 0; 87 88 if ((NULL == data) || (size == 0)) { 89 SL_LOGE("No ADTS to validate"); 90 return SL_RESULT_PARAMETER_INVALID; 91 } 92 93 while (offset < size) { 94 if ((frameSize = getAdtsFrameSize((uint8_t *)data, offset, size)) == 0) { 95 SL_LOGE("found ADTS frame of size 0 at offset %llu", offset); 96 return SL_RESULT_CONTENT_CORRUPTED; 97 } 98 //SL_LOGV("last good offset %llu", offset); 99 offset += frameSize; 100 if (offset > size) { 101 SL_LOGE("found incomplete ADTS frame at end of data"); 102 return SL_RESULT_CONTENT_CORRUPTED; 103 } 104 } 105 if (offset != size) { SL_LOGE("ADTS parsing error: reached end of incomplete frame"); } 106 assert(offset == size); 107 return SL_RESULT_SUCCESS; 108 } 109 110 //-------------------------------------------------------------------------------------------------- 111 AacBqToPcmCbRenderer::AacBqToPcmCbRenderer(const AudioPlayback_Parameters* params, 112 IAndroidBufferQueue *androidBufferQueue) : 113 AudioToCbRenderer(params), 114 mBqSource(new BufferQueueSource(androidBufferQueue)) 115 { 116 SL_LOGD("AacBqToPcmCbRenderer::AacBqToPcmCbRenderer()"); 117 } 118 119 120 AacBqToPcmCbRenderer::~AacBqToPcmCbRenderer() { 121 SL_LOGD("AacBqToPcmCbRenderer::~AacBqToPcmCbRenderer()"); 122 123 } 124 125 126 //-------------------------------------------------- 127 // Event handlers 128 void AacBqToPcmCbRenderer::onPrepare() { 129 SL_LOGD("AacBqToPcmCbRenderer::onPrepare()"); 130 Mutex::Autolock _l(mBufferSourceLock); 131 132 // Initialize the PCM format info with the known parameters before the start of the decode 133 { 134 android::Mutex::Autolock autoLock(mPcmFormatLock); 135 mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_BITSPERSAMPLE] = SL_PCMSAMPLEFORMAT_FIXED_16; 136 mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_CONTAINERSIZE] = 16; 137 //FIXME not true on all platforms 138 mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_ENDIANNESS] = SL_BYTEORDER_LITTLEENDIAN; 139 // initialization with the default values: they will be replaced by the actual values 140 // once the decoder has figured them out 141 mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_NUMCHANNELS] = UNKNOWN_NUMCHANNELS; 142 mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_SAMPLERATE] = UNKNOWN_SAMPLERATE; 143 mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_CHANNELMASK] = UNKNOWN_CHANNELMASK; 144 } 145 146 sp<MediaExtractor> extractor = new AacAdtsExtractor(mBqSource); 147 148 // only decoding a single track of data 149 const size_t kTrackToDecode = 0; 150 151 sp<MediaSource> source = extractor->getTrack(kTrackToDecode); 152 if (source == 0) { 153 SL_LOGE("AacBqToPcmCbRenderer::onPrepare: error getting source from extractor"); 154 notifyPrepared(ERROR_UNSUPPORTED); 155 return; 156 } 157 sp<MetaData> meta = extractor->getTrackMetaData(kTrackToDecode); 158 159 // the audio content is not raw PCM, so we need a decoder 160 OMXClient client; 161 CHECK_EQ(client.connect(), (status_t)OK); 162 163 source = OMXCodec::Create( 164 client.interface(), meta, false /* createEncoder */, 165 source); 166 167 if (source == NULL) { 168 SL_LOGE("AacBqToPcmCbRenderer::onPrepare: Could not instantiate decoder."); 169 notifyPrepared(ERROR_UNSUPPORTED); 170 return; 171 } 172 173 meta = source->getFormat(); 174 175 SL_LOGD("AacBqToPcmCbRenderer::onPrepare() after instantiating decoder"); 176 177 if (source->start() != OK) { 178 SL_LOGE("AacBqToPcmCbRenderer::onPrepare() Failed to start source/decoder."); 179 notifyPrepared(MEDIA_ERROR_BASE); 180 return; 181 } 182 183 //--------------------------------- 184 int32_t channelCount; 185 CHECK(meta->findInt32(kKeyChannelCount, &channelCount)); 186 int32_t sr; 187 CHECK(meta->findInt32(kKeySampleRate, &sr)); 188 // FIXME similar to AudioSfDecoder::onPrepare() 189 190 // already "good to go" (compare to AudioSfDecoder::onPrepare) 191 mCacheStatus = kStatusHigh; 192 mCacheFill = 1000; 193 notifyStatus(); 194 notifyCacheFill(); 195 196 { 197 android::Mutex::Autolock autoLock(mPcmFormatLock); 198 mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_SAMPLERATE] = sr; 199 mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_NUMCHANNELS] = channelCount; 200 mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_CHANNELMASK] = 201 channelCountToMask(channelCount); 202 } 203 SL_LOGV("AacBqToPcmCbRenderer::onPrepare() channel count=%d SR=%d", 204 channelCount, sr); 205 206 //--------------------------------- 207 // The data source, and audio source (a decoder) are ready to be used 208 mDataSource = mBqSource; 209 mAudioSource = source; 210 mAudioSourceStarted = true; 211 212 //------------------------------------- 213 // signal successful completion of prepare 214 mStateFlags |= kFlagPrepared; 215 216 // skipping past AudioToCbRenderer and AudioSfDecoder 217 GenericPlayer::onPrepare(); 218 219 SL_LOGD("AacBqToPcmCbRenderer::onPrepare() done, mStateFlags=0x%x", mStateFlags); 220 } 221 222 } // namespace android 223