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 LOG_NDEBUG 0 18#define LOG_TAG "AACExtractor" 19#include <utils/Log.h> 20 21#include "include/AACExtractor.h" 22#include "include/avc_utils.h" 23 24#include <media/stagefright/foundation/ABuffer.h> 25#include <media/stagefright/DataSource.h> 26#include <media/stagefright/MediaBufferGroup.h> 27#include <media/stagefright/MediaDebug.h> 28#include <media/stagefright/MediaDefs.h> 29#include <media/stagefright/MediaErrors.h> 30#include <media/stagefright/MediaSource.h> 31#include <media/stagefright/MetaData.h> 32#include <utils/String8.h> 33 34namespace android { 35 36class AACSource : public MediaSource { 37public: 38 AACSource(const sp<DataSource> &source, 39 const sp<MetaData> &meta, 40 const Vector<uint64_t> &offset_vector, 41 int64_t frame_duration_us); 42 43 virtual status_t start(MetaData *params = NULL); 44 virtual status_t stop(); 45 46 virtual sp<MetaData> getFormat(); 47 48 virtual status_t read( 49 MediaBuffer **buffer, const ReadOptions *options = NULL); 50 51protected: 52 virtual ~AACSource(); 53 54private: 55 static const size_t kMaxFrameSize; 56 sp<DataSource> mDataSource; 57 sp<MetaData> mMeta; 58 59 off64_t mOffset; 60 int64_t mCurrentTimeUs; 61 bool mStarted; 62 MediaBufferGroup *mGroup; 63 64 Vector<uint64_t> mOffsetVector; 65 int64_t mFrameDurationUs; 66 67 AACSource(const AACSource &); 68 AACSource &operator=(const AACSource &); 69}; 70 71//////////////////////////////////////////////////////////////////////////////// 72 73// Returns the sample rate based on the sampling frequency index 74uint32_t get_sample_rate(const uint8_t sf_index) 75{ 76 static const uint32_t sample_rates[] = 77 { 78 96000, 88200, 64000, 48000, 44100, 32000, 79 24000, 22050, 16000, 12000, 11025, 8000 80 }; 81 82 if (sf_index < sizeof(sample_rates) / sizeof(sample_rates[0])) { 83 return sample_rates[sf_index]; 84 } 85 86 return 0; 87} 88 89// Returns the frame length in bytes as described in an ADTS header starting at the given offset, 90// or 0 if the size can't be read due to an error in the header or a read failure. 91// The returned value is the AAC frame size with the ADTS header length (regardless of 92// the presence of the CRC). 93// If headerSize is non-NULL, it will be used to return the size of the header of this ADTS frame. 94static size_t getAdtsFrameLength(const sp<DataSource> &source, off64_t offset, size_t* headerSize) { 95 96 const size_t kAdtsHeaderLengthNoCrc = 7; 97 const size_t kAdtsHeaderLengthWithCrc = 9; 98 99 size_t frameSize = 0; 100 101 uint8_t syncword[2]; 102 if (source->readAt(offset, &syncword, 2) != 2) { 103 return 0; 104 } 105 if ((syncword[0] != 0xff) || ((syncword[1] & 0xf6) != 0xf0)) { 106 return 0; 107 } 108 109 uint8_t protectionAbsent; 110 if (source->readAt(offset + 1, &protectionAbsent, 1) < 1) { 111 return 0; 112 } 113 protectionAbsent &= 0x1; 114 115 uint8_t header[3]; 116 if (source->readAt(offset + 3, &header, 3) < 3) { 117 return 0; 118 } 119 120 frameSize = (header[0] & 0x3) << 11 | header[1] << 3 | header[2] >> 5; 121 122 // protectionAbsent is 0 if there is CRC 123 size_t headSize = protectionAbsent ? kAdtsHeaderLengthNoCrc : kAdtsHeaderLengthWithCrc; 124 if (headSize > frameSize) { 125 return 0; 126 } 127 if (headerSize != NULL) { 128 *headerSize = headSize; 129 } 130 131 return frameSize; 132} 133 134AACExtractor::AACExtractor(const sp<DataSource> &source) 135 : mDataSource(source), 136 mInitCheck(NO_INIT), 137 mFrameDurationUs(0) { 138 String8 mimeType; 139 float confidence; 140 if (!SniffAAC(mDataSource, &mimeType, &confidence, NULL)) { 141 return; 142 } 143 144 uint8_t profile, sf_index, channel, header[2]; 145 if (mDataSource->readAt(2, &header, 2) < 2) { 146 return; 147 } 148 149 profile = (header[0] >> 6) & 0x3; 150 sf_index = (header[0] >> 2) & 0xf; 151 uint32_t sr = get_sample_rate(sf_index); 152 if (sr == 0) { 153 return; 154 } 155 channel = (header[0] & 0x1) << 2 | (header[1] >> 6); 156 157 mMeta = MakeAACCodecSpecificData(profile, sf_index, channel); 158 159 off64_t offset = 0; 160 off64_t streamSize, numFrames = 0; 161 size_t frameSize = 0; 162 int64_t duration = 0; 163 164 if (mDataSource->getSize(&streamSize) == OK) { 165 while (offset < streamSize) { 166 if ((frameSize = getAdtsFrameLength(source, offset, NULL)) == 0) { 167 return; 168 } 169 170 mOffsetVector.push(offset); 171 172 offset += frameSize; 173 numFrames ++; 174 } 175 176 // Round up and get the duration 177 mFrameDurationUs = (1024 * 1000000ll + (sr - 1)) / sr; 178 duration = numFrames * mFrameDurationUs; 179 mMeta->setInt64(kKeyDuration, duration); 180 } 181 182 mInitCheck = OK; 183} 184 185AACExtractor::~AACExtractor() { 186} 187 188sp<MetaData> AACExtractor::getMetaData() { 189 sp<MetaData> meta = new MetaData; 190 191 if (mInitCheck != OK) { 192 return meta; 193 } 194 195 meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC_ADTS); 196 197 return meta; 198} 199 200size_t AACExtractor::countTracks() { 201 return mInitCheck == OK ? 1 : 0; 202} 203 204sp<MediaSource> AACExtractor::getTrack(size_t index) { 205 if (mInitCheck != OK || index != 0) { 206 return NULL; 207 } 208 209 return new AACSource(mDataSource, mMeta, mOffsetVector, mFrameDurationUs); 210} 211 212sp<MetaData> AACExtractor::getTrackMetaData(size_t index, uint32_t flags) { 213 if (mInitCheck != OK || index != 0) { 214 return NULL; 215 } 216 217 return mMeta; 218} 219 220//////////////////////////////////////////////////////////////////////////////// 221 222// 8192 = 2^13, 13bit AAC frame size (in bytes) 223const size_t AACSource::kMaxFrameSize = 8192; 224 225AACSource::AACSource( 226 const sp<DataSource> &source, const sp<MetaData> &meta, 227 const Vector<uint64_t> &offset_vector, 228 int64_t frame_duration_us) 229 : mDataSource(source), 230 mMeta(meta), 231 mOffset(0), 232 mCurrentTimeUs(0), 233 mStarted(false), 234 mGroup(NULL), 235 mOffsetVector(offset_vector), 236 mFrameDurationUs(frame_duration_us) { 237} 238 239AACSource::~AACSource() { 240 if (mStarted) { 241 stop(); 242 } 243} 244 245status_t AACSource::start(MetaData *params) { 246 CHECK(!mStarted); 247 248 mOffset = 0; 249 mCurrentTimeUs = 0; 250 mGroup = new MediaBufferGroup; 251 mGroup->add_buffer(new MediaBuffer(kMaxFrameSize)); 252 mStarted = true; 253 254 return OK; 255} 256 257status_t AACSource::stop() { 258 CHECK(mStarted); 259 260 delete mGroup; 261 mGroup = NULL; 262 263 mStarted = false; 264 return OK; 265} 266 267sp<MetaData> AACSource::getFormat() { 268 return mMeta; 269} 270 271status_t AACSource::read( 272 MediaBuffer **out, const ReadOptions *options) { 273 *out = NULL; 274 275 int64_t seekTimeUs; 276 ReadOptions::SeekMode mode; 277 if (options && options->getSeekTo(&seekTimeUs, &mode)) { 278 if (mFrameDurationUs > 0) { 279 int64_t seekFrame = seekTimeUs / mFrameDurationUs; 280 mCurrentTimeUs = seekFrame * mFrameDurationUs; 281 282 mOffset = mOffsetVector.itemAt(seekFrame); 283 } 284 } 285 286 size_t frameSize, frameSizeWithoutHeader, headerSize; 287 if ((frameSize = getAdtsFrameLength(mDataSource, mOffset, &headerSize)) == 0) { 288 return ERROR_END_OF_STREAM; 289 } 290 291 MediaBuffer *buffer; 292 status_t err = mGroup->acquire_buffer(&buffer); 293 if (err != OK) { 294 return err; 295 } 296 297 frameSizeWithoutHeader = frameSize - headerSize; 298 if (mDataSource->readAt(mOffset + headerSize, buffer->data(), 299 frameSizeWithoutHeader) != (ssize_t)frameSizeWithoutHeader) { 300 buffer->release(); 301 buffer = NULL; 302 303 return ERROR_IO; 304 } 305 306 buffer->set_range(0, frameSizeWithoutHeader); 307 buffer->meta_data()->setInt64(kKeyTime, mCurrentTimeUs); 308 buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 309 310 mOffset += frameSize; 311 mCurrentTimeUs += mFrameDurationUs; 312 313 *out = buffer; 314 return OK; 315} 316 317//////////////////////////////////////////////////////////////////////////////// 318 319bool SniffAAC( 320 const sp<DataSource> &source, String8 *mimeType, float *confidence, 321 sp<AMessage> *) { 322 uint8_t header[2]; 323 324 if (source->readAt(0, &header, 2) != 2) { 325 return false; 326 } 327 328 // ADTS syncword 329 if ((header[0] == 0xff) && ((header[1] & 0xf6) == 0xf0)) { 330 *mimeType = MEDIA_MIMETYPE_AUDIO_AAC_ADTS; 331 *confidence = 0.2; 332 return true; 333 } 334 335 return false; 336} 337 338} // namespace android 339