150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang/* 250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang * Copyright (C) 2011 The Android Open Source Project 350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang * 450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang * Licensed under the Apache License, Version 2.0 (the "License"); 550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang * you may not use this file except in compliance with the License. 650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang * You may obtain a copy of the License at 750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang * 850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang * http://www.apache.org/licenses/LICENSE-2.0 950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang * 1050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang * Unless required by applicable law or agreed to in writing, software 1150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang * distributed under the License is distributed on an "AS IS" BASIS, 1250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang * See the License for the specific language governing permissions and 1450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang * limitations under the License. 1550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang */ 1650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 1750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang//#define LOG_NDEBUG 0 1850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang#define LOG_TAG "AACExtractor" 1950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang#include <utils/Log.h> 2050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 2150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang#include "include/AACExtractor.h" 2250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang#include "include/avc_utils.h" 2350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 2450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang#include <media/stagefright/foundation/ABuffer.h> 2514da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber#include <media/stagefright/foundation/AMessage.h> 26f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h> 2750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang#include <media/stagefright/DataSource.h> 2850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang#include <media/stagefright/MediaBufferGroup.h> 2950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang#include <media/stagefright/MediaDefs.h> 3050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang#include <media/stagefright/MediaErrors.h> 3150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang#include <media/stagefright/MediaSource.h> 3250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang#include <media/stagefright/MetaData.h> 3350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang#include <utils/String8.h> 3450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 3550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wangnamespace android { 3650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 3750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wangclass AACSource : public MediaSource { 3850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wangpublic: 3950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang AACSource(const sp<DataSource> &source, 4050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang const sp<MetaData> &meta, 4150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang const Vector<uint64_t> &offset_vector, 4250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang int64_t frame_duration_us); 4350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 4450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang virtual status_t start(MetaData *params = NULL); 4550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang virtual status_t stop(); 4650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 4750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang virtual sp<MetaData> getFormat(); 4850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 4950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang virtual status_t read( 5050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang MediaBuffer **buffer, const ReadOptions *options = NULL); 5150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 5250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wangprotected: 5350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang virtual ~AACSource(); 5450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 5550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wangprivate: 5650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang static const size_t kMaxFrameSize; 5750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang sp<DataSource> mDataSource; 5850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang sp<MetaData> mMeta; 5950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 6050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang off64_t mOffset; 6150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang int64_t mCurrentTimeUs; 6250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang bool mStarted; 6350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang MediaBufferGroup *mGroup; 6450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 6550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang Vector<uint64_t> mOffsetVector; 6650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang int64_t mFrameDurationUs; 6750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 6850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang AACSource(const AACSource &); 6950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang AACSource &operator=(const AACSource &); 7050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang}; 7150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 7250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang//////////////////////////////////////////////////////////////////////////////// 7350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 7450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang// Returns the sample rate based on the sampling frequency index 7550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wanguint32_t get_sample_rate(const uint8_t sf_index) 7650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang{ 7750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang static const uint32_t sample_rates[] = 7850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang { 7950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 96000, 88200, 64000, 48000, 44100, 32000, 8050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 24000, 22050, 16000, 12000, 11025, 8000 8150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang }; 8250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 8350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang if (sf_index < sizeof(sample_rates) / sizeof(sample_rates[0])) { 8450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang return sample_rates[sf_index]; 8550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang } 8650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 8750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang return 0; 8850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang} 8950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 90bf4c48bc678c8f531f39f0b48755967d844ad581Jean-Michel Trivi// Returns the frame length in bytes as described in an ADTS header starting at the given offset, 91bf4c48bc678c8f531f39f0b48755967d844ad581Jean-Michel Trivi// or 0 if the size can't be read due to an error in the header or a read failure. 92bf4c48bc678c8f531f39f0b48755967d844ad581Jean-Michel Trivi// The returned value is the AAC frame size with the ADTS header length (regardless of 93bf4c48bc678c8f531f39f0b48755967d844ad581Jean-Michel Trivi// the presence of the CRC). 94bf4c48bc678c8f531f39f0b48755967d844ad581Jean-Michel Trivi// If headerSize is non-NULL, it will be used to return the size of the header of this ADTS frame. 95bf4c48bc678c8f531f39f0b48755967d844ad581Jean-Michel Trivistatic size_t getAdtsFrameLength(const sp<DataSource> &source, off64_t offset, size_t* headerSize) { 96bf4c48bc678c8f531f39f0b48755967d844ad581Jean-Michel Trivi 97bf4c48bc678c8f531f39f0b48755967d844ad581Jean-Michel Trivi const size_t kAdtsHeaderLengthNoCrc = 7; 98bf4c48bc678c8f531f39f0b48755967d844ad581Jean-Michel Trivi const size_t kAdtsHeaderLengthWithCrc = 9; 99bf4c48bc678c8f531f39f0b48755967d844ad581Jean-Michel Trivi 10050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang size_t frameSize = 0; 10150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 10250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang uint8_t syncword[2]; 103fdb04b61f91c45eed0edd28aa33d7085a5e6eb74Gloria Wang if (source->readAt(offset, &syncword, 2) != 2) { 10450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang return 0; 10550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang } 10650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang if ((syncword[0] != 0xff) || ((syncword[1] & 0xf6) != 0xf0)) { 10750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang return 0; 10850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang } 10950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 11050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang uint8_t protectionAbsent; 11150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang if (source->readAt(offset + 1, &protectionAbsent, 1) < 1) { 11250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang return 0; 11350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang } 11450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang protectionAbsent &= 0x1; 11550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 11650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang uint8_t header[3]; 11750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang if (source->readAt(offset + 3, &header, 3) < 3) { 11850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang return 0; 11950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang } 12050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 12150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang frameSize = (header[0] & 0x3) << 11 | header[1] << 3 | header[2] >> 5; 122bf4c48bc678c8f531f39f0b48755967d844ad581Jean-Michel Trivi 123bf4c48bc678c8f531f39f0b48755967d844ad581Jean-Michel Trivi // protectionAbsent is 0 if there is CRC 124bf4c48bc678c8f531f39f0b48755967d844ad581Jean-Michel Trivi size_t headSize = protectionAbsent ? kAdtsHeaderLengthNoCrc : kAdtsHeaderLengthWithCrc; 125bf4c48bc678c8f531f39f0b48755967d844ad581Jean-Michel Trivi if (headSize > frameSize) { 126bf4c48bc678c8f531f39f0b48755967d844ad581Jean-Michel Trivi return 0; 127bf4c48bc678c8f531f39f0b48755967d844ad581Jean-Michel Trivi } 128bf4c48bc678c8f531f39f0b48755967d844ad581Jean-Michel Trivi if (headerSize != NULL) { 129bf4c48bc678c8f531f39f0b48755967d844ad581Jean-Michel Trivi *headerSize = headSize; 130bf4c48bc678c8f531f39f0b48755967d844ad581Jean-Michel Trivi } 13150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 13250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang return frameSize; 13350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang} 13450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 13514da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas HuberAACExtractor::AACExtractor( 13614da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber const sp<DataSource> &source, const sp<AMessage> &_meta) 13750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang : mDataSource(source), 13850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang mInitCheck(NO_INIT), 13950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang mFrameDurationUs(0) { 14014da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber sp<AMessage> meta = _meta; 14114da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber 14214da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber if (meta == NULL) { 14314da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber String8 mimeType; 14414da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber float confidence; 14514da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber sp<AMessage> _meta; 14614da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber 14714da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber if (!SniffAAC(mDataSource, &mimeType, &confidence, &meta)) { 14814da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber return; 14914da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber } 15050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang } 15150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 15214da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber int64_t offset; 15314da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber CHECK(meta->findInt64("offset", &offset)); 15414da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber 15550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang uint8_t profile, sf_index, channel, header[2]; 15614da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber if (mDataSource->readAt(offset + 2, &header, 2) < 2) { 15750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang return; 15850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang } 15950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 16050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang profile = (header[0] >> 6) & 0x3; 16150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang sf_index = (header[0] >> 2) & 0xf; 16250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang uint32_t sr = get_sample_rate(sf_index); 16350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang if (sr == 0) { 16450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang return; 16550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang } 16650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang channel = (header[0] & 0x1) << 2 | (header[1] >> 6); 16750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 16850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang mMeta = MakeAACCodecSpecificData(profile, sf_index, channel); 16950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 17050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang off64_t streamSize, numFrames = 0; 17150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang size_t frameSize = 0; 17250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang int64_t duration = 0; 17350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 17450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang if (mDataSource->getSize(&streamSize) == OK) { 17550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang while (offset < streamSize) { 176bf4c48bc678c8f531f39f0b48755967d844ad581Jean-Michel Trivi if ((frameSize = getAdtsFrameLength(source, offset, NULL)) == 0) { 17740470735df028b2b9e73afe014ad59cf7b76ad4fWei Jia ALOGW("prematured AAC stream (%lld vs %lld)", 17840470735df028b2b9e73afe014ad59cf7b76ad4fWei Jia (long long)offset, (long long)streamSize); 17940470735df028b2b9e73afe014ad59cf7b76ad4fWei Jia break; 18050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang } 18150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 18250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang mOffsetVector.push(offset); 18350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 18450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang offset += frameSize; 18550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang numFrames ++; 18650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang } 18750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 18850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang // Round up and get the duration 18950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang mFrameDurationUs = (1024 * 1000000ll + (sr - 1)) / sr; 19050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang duration = numFrames * mFrameDurationUs; 19150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang mMeta->setInt64(kKeyDuration, duration); 19250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang } 19350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 19450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang mInitCheck = OK; 19550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang} 19650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 19750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria WangAACExtractor::~AACExtractor() { 19850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang} 19950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 20050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wangsp<MetaData> AACExtractor::getMetaData() { 20150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang sp<MetaData> meta = new MetaData; 20250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 20350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang if (mInitCheck != OK) { 20450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang return meta; 20550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang } 20650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 20750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC_ADTS); 20850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 20950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang return meta; 21050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang} 21150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 21250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wangsize_t AACExtractor::countTracks() { 21350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang return mInitCheck == OK ? 1 : 0; 21450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang} 21550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 216b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissensp<IMediaSource> AACExtractor::getTrack(size_t index) { 21750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang if (mInitCheck != OK || index != 0) { 21850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang return NULL; 21950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang } 22050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 22150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang return new AACSource(mDataSource, mMeta, mOffsetVector, mFrameDurationUs); 22250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang} 22350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 22484333e0475bc911adc16417f4ca327c975cf6c36Andreas Hubersp<MetaData> AACExtractor::getTrackMetaData(size_t index, uint32_t /* flags */) { 22550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang if (mInitCheck != OK || index != 0) { 22650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang return NULL; 22750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang } 22850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 22950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang return mMeta; 23050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang} 23150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 23250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang//////////////////////////////////////////////////////////////////////////////// 23350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 23450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang// 8192 = 2^13, 13bit AAC frame size (in bytes) 23550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wangconst size_t AACSource::kMaxFrameSize = 8192; 23650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 23750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria WangAACSource::AACSource( 23850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang const sp<DataSource> &source, const sp<MetaData> &meta, 23950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang const Vector<uint64_t> &offset_vector, 24050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang int64_t frame_duration_us) 24150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang : mDataSource(source), 24250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang mMeta(meta), 24350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang mOffset(0), 24450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang mCurrentTimeUs(0), 24550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang mStarted(false), 24650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang mGroup(NULL), 24750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang mOffsetVector(offset_vector), 24850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang mFrameDurationUs(frame_duration_us) { 24950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang} 25050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 25150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria WangAACSource::~AACSource() { 25250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang if (mStarted) { 25350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang stop(); 25450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang } 25550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang} 25650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 25784333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t AACSource::start(MetaData * /* params */) { 25850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang CHECK(!mStarted); 25950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 26014da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber if (mOffsetVector.empty()) { 26114da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber mOffset = 0; 26214da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber } else { 26314da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber mOffset = mOffsetVector.itemAt(0); 26414da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber } 26514da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber 26650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang mCurrentTimeUs = 0; 26750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang mGroup = new MediaBufferGroup; 26850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang mGroup->add_buffer(new MediaBuffer(kMaxFrameSize)); 26950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang mStarted = true; 27050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 27150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang return OK; 27250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang} 27350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 27450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wangstatus_t AACSource::stop() { 27550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang CHECK(mStarted); 27650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 27750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang delete mGroup; 27850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang mGroup = NULL; 27950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 28050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang mStarted = false; 28150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang return OK; 28250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang} 28350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 28450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wangsp<MetaData> AACSource::getFormat() { 28550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang return mMeta; 28650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang} 28750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 28850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wangstatus_t AACSource::read( 28950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang MediaBuffer **out, const ReadOptions *options) { 29050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang *out = NULL; 29150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 29250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang int64_t seekTimeUs; 29350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang ReadOptions::SeekMode mode; 29450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang if (options && options->getSeekTo(&seekTimeUs, &mode)) { 29550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang if (mFrameDurationUs > 0) { 29650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang int64_t seekFrame = seekTimeUs / mFrameDurationUs; 29750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang mCurrentTimeUs = seekFrame * mFrameDurationUs; 29850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 29950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang mOffset = mOffsetVector.itemAt(seekFrame); 30050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang } 30150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang } 30250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 303bf4c48bc678c8f531f39f0b48755967d844ad581Jean-Michel Trivi size_t frameSize, frameSizeWithoutHeader, headerSize; 304bf4c48bc678c8f531f39f0b48755967d844ad581Jean-Michel Trivi if ((frameSize = getAdtsFrameLength(mDataSource, mOffset, &headerSize)) == 0) { 30550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang return ERROR_END_OF_STREAM; 30650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang } 30750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 30850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang MediaBuffer *buffer; 30950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang status_t err = mGroup->acquire_buffer(&buffer); 31050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang if (err != OK) { 31150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang return err; 31250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang } 31350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 314bf4c48bc678c8f531f39f0b48755967d844ad581Jean-Michel Trivi frameSizeWithoutHeader = frameSize - headerSize; 315bf4c48bc678c8f531f39f0b48755967d844ad581Jean-Michel Trivi if (mDataSource->readAt(mOffset + headerSize, buffer->data(), 31650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang frameSizeWithoutHeader) != (ssize_t)frameSizeWithoutHeader) { 31750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang buffer->release(); 31850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang buffer = NULL; 31950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 32050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang return ERROR_IO; 32150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang } 32250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 32350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang buffer->set_range(0, frameSizeWithoutHeader); 32450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang buffer->meta_data()->setInt64(kKeyTime, mCurrentTimeUs); 32550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 32650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 32750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang mOffset += frameSize; 32850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang mCurrentTimeUs += mFrameDurationUs; 32950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 33050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang *out = buffer; 33150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang return OK; 33250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang} 33350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 33450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang//////////////////////////////////////////////////////////////////////////////// 33550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 33650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wangbool SniffAAC( 33750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang const sp<DataSource> &source, String8 *mimeType, float *confidence, 33814da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber sp<AMessage> *meta) { 33914da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber off64_t pos = 0; 34014da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber 34114da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber for (;;) { 34214da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber uint8_t id3header[10]; 34314da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber if (source->readAt(pos, id3header, sizeof(id3header)) 34414da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber < (ssize_t)sizeof(id3header)) { 34514da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber return false; 34614da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber } 34714da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber 34814da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber if (memcmp("ID3", id3header, 3)) { 34914da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber break; 35014da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber } 35114da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber 35214da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber // Skip the ID3v2 header. 35314da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber 35414da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber size_t len = 35514da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber ((id3header[6] & 0x7f) << 21) 35614da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber | ((id3header[7] & 0x7f) << 14) 35714da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber | ((id3header[8] & 0x7f) << 7) 35814da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber | (id3header[9] & 0x7f); 35914da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber 36014da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber len += 10; 36114da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber 36214da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber pos += len; 36314da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber 36414da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber ALOGV("skipped ID3 tag, new starting offset is %lld (0x%016llx)", 365ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar (long long)pos, (long long)pos); 36614da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber } 36714da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber 36850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang uint8_t header[2]; 36950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 37014da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber if (source->readAt(pos, &header, 2) != 2) { 37150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang return false; 37250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang } 37350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 37450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang // ADTS syncword 37550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang if ((header[0] == 0xff) && ((header[1] & 0xf6) == 0xf0)) { 37650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang *mimeType = MEDIA_MIMETYPE_AUDIO_AAC_ADTS; 37750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang *confidence = 0.2; 37814da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber 37914da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber *meta = new AMessage; 38014da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber (*meta)->setInt64("offset", pos); 38114da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber 38250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang return true; 38350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang } 38450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 38550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang return false; 38650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang} 38750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 38850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang} // namespace android 389