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