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