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) {
17750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang                return;
17850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang            }
17950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
18050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang            mOffsetVector.push(offset);
18150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
18250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang            offset += frameSize;
18350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang            numFrames ++;
18450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang        }
18550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
18650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang        // Round up and get the duration
18750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang        mFrameDurationUs = (1024 * 1000000ll + (sr - 1)) / sr;
18850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang        duration = numFrames * mFrameDurationUs;
18950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang        mMeta->setInt64(kKeyDuration, duration);
19050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    }
19150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
19250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    mInitCheck = OK;
19350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang}
19450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
19550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria WangAACExtractor::~AACExtractor() {
19650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang}
19750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
19850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wangsp<MetaData> AACExtractor::getMetaData() {
19950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    sp<MetaData> meta = new MetaData;
20050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
20150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    if (mInitCheck != OK) {
20250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang        return meta;
20350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    }
20450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
20550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC_ADTS);
20650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
20750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    return meta;
20850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang}
20950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
21050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wangsize_t AACExtractor::countTracks() {
21150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    return mInitCheck == OK ? 1 : 0;
21250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang}
21350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
214b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissensp<IMediaSource> AACExtractor::getTrack(size_t index) {
21550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    if (mInitCheck != OK || index != 0) {
21650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang        return NULL;
21750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    }
21850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
21950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    return new AACSource(mDataSource, mMeta, mOffsetVector, mFrameDurationUs);
22050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang}
22150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
22284333e0475bc911adc16417f4ca327c975cf6c36Andreas Hubersp<MetaData> AACExtractor::getTrackMetaData(size_t index, uint32_t /* flags */) {
22350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    if (mInitCheck != OK || index != 0) {
22450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang        return NULL;
22550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    }
22650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
22750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    return mMeta;
22850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang}
22950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
23050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang////////////////////////////////////////////////////////////////////////////////
23150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
23250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang// 8192 = 2^13, 13bit AAC frame size (in bytes)
23350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wangconst size_t AACSource::kMaxFrameSize = 8192;
23450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
23550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria WangAACSource::AACSource(
23650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang        const sp<DataSource> &source, const sp<MetaData> &meta,
23750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang        const Vector<uint64_t> &offset_vector,
23850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang        int64_t frame_duration_us)
23950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    : mDataSource(source),
24050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang      mMeta(meta),
24150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang      mOffset(0),
24250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang      mCurrentTimeUs(0),
24350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang      mStarted(false),
24450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang      mGroup(NULL),
24550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang      mOffsetVector(offset_vector),
24650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang      mFrameDurationUs(frame_duration_us) {
24750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang}
24850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
24950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria WangAACSource::~AACSource() {
25050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    if (mStarted) {
25150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang        stop();
25250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    }
25350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang}
25450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
25584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t AACSource::start(MetaData * /* params */) {
25650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    CHECK(!mStarted);
25750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
25814da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber    if (mOffsetVector.empty()) {
25914da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber        mOffset = 0;
26014da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber    } else {
26114da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber        mOffset = mOffsetVector.itemAt(0);
26214da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber    }
26314da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber
26450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    mCurrentTimeUs = 0;
26550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    mGroup = new MediaBufferGroup;
26650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    mGroup->add_buffer(new MediaBuffer(kMaxFrameSize));
26750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    mStarted = true;
26850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
26950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    return OK;
27050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang}
27150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
27250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wangstatus_t AACSource::stop() {
27350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    CHECK(mStarted);
27450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
27550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    delete mGroup;
27650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    mGroup = NULL;
27750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
27850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    mStarted = false;
27950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    return OK;
28050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang}
28150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
28250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wangsp<MetaData> AACSource::getFormat() {
28350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    return mMeta;
28450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang}
28550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
28650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wangstatus_t AACSource::read(
28750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang        MediaBuffer **out, const ReadOptions *options) {
28850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    *out = NULL;
28950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
29050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    int64_t seekTimeUs;
29150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    ReadOptions::SeekMode mode;
29250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    if (options && options->getSeekTo(&seekTimeUs, &mode)) {
29350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang        if (mFrameDurationUs > 0) {
29450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang            int64_t seekFrame = seekTimeUs / mFrameDurationUs;
29550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang            mCurrentTimeUs = seekFrame * mFrameDurationUs;
29650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
29750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang            mOffset = mOffsetVector.itemAt(seekFrame);
29850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang        }
29950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    }
30050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
301bf4c48bc678c8f531f39f0b48755967d844ad581Jean-Michel Trivi    size_t frameSize, frameSizeWithoutHeader, headerSize;
302bf4c48bc678c8f531f39f0b48755967d844ad581Jean-Michel Trivi    if ((frameSize = getAdtsFrameLength(mDataSource, mOffset, &headerSize)) == 0) {
30350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang        return ERROR_END_OF_STREAM;
30450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    }
30550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
30650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    MediaBuffer *buffer;
30750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    status_t err = mGroup->acquire_buffer(&buffer);
30850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    if (err != OK) {
30950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang        return err;
31050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    }
31150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
312bf4c48bc678c8f531f39f0b48755967d844ad581Jean-Michel Trivi    frameSizeWithoutHeader = frameSize - headerSize;
313bf4c48bc678c8f531f39f0b48755967d844ad581Jean-Michel Trivi    if (mDataSource->readAt(mOffset + headerSize, buffer->data(),
31450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang                frameSizeWithoutHeader) != (ssize_t)frameSizeWithoutHeader) {
31550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang        buffer->release();
31650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang        buffer = NULL;
31750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
31850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang        return ERROR_IO;
31950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    }
32050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
32150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    buffer->set_range(0, frameSizeWithoutHeader);
32250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    buffer->meta_data()->setInt64(kKeyTime, mCurrentTimeUs);
32350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
32450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
32550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    mOffset += frameSize;
32650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    mCurrentTimeUs += mFrameDurationUs;
32750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
32850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    *out = buffer;
32950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    return OK;
33050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang}
33150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
33250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang////////////////////////////////////////////////////////////////////////////////
33350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
33450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wangbool SniffAAC(
33550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang        const sp<DataSource> &source, String8 *mimeType, float *confidence,
33614da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber        sp<AMessage> *meta) {
33714da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber    off64_t pos = 0;
33814da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber
33914da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber    for (;;) {
34014da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber        uint8_t id3header[10];
34114da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber        if (source->readAt(pos, id3header, sizeof(id3header))
34214da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber                < (ssize_t)sizeof(id3header)) {
34314da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber            return false;
34414da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber        }
34514da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber
34614da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber        if (memcmp("ID3", id3header, 3)) {
34714da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber            break;
34814da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber        }
34914da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber
35014da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber        // Skip the ID3v2 header.
35114da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber
35214da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber        size_t len =
35314da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber            ((id3header[6] & 0x7f) << 21)
35414da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber            | ((id3header[7] & 0x7f) << 14)
35514da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber            | ((id3header[8] & 0x7f) << 7)
35614da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber            | (id3header[9] & 0x7f);
35714da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber
35814da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber        len += 10;
35914da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber
36014da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber        pos += len;
36114da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber
36214da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber        ALOGV("skipped ID3 tag, new starting offset is %lld (0x%016llx)",
363ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                (long long)pos, (long long)pos);
36414da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber    }
36514da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber
36650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    uint8_t header[2];
36750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
36814da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber    if (source->readAt(pos, &header, 2) != 2) {
36950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang        return false;
37050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    }
37150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
37250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    // ADTS syncword
37350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    if ((header[0] == 0xff) && ((header[1] & 0xf6) == 0xf0)) {
37450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang        *mimeType = MEDIA_MIMETYPE_AUDIO_AAC_ADTS;
37550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang        *confidence = 0.2;
37614da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber
37714da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber        *meta = new AMessage;
37814da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber        (*meta)->setInt64("offset", pos);
37914da736f1707a6dbefa52405e910ecb1b3bc2dd2Andreas Huber
38050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang        return true;
38150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    }
38250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
38350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang    return false;
38450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang}
38550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang
38650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang}  // namespace android
387