MP3Extractor.cpp revision 48c948b1137e7bbdb161b51908657ab72ac5e2da
1/*
2 * Copyright (C) 2009 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 "MP3Extractor"
19#include <utils/Log.h>
20
21#include <media/stagefright/DataSource.h>
22#include <media/stagefright/MP3Extractor.h>
23#include <media/stagefright/MediaBuffer.h>
24#include <media/stagefright/MediaBufferGroup.h>
25#include <media/stagefright/MediaDebug.h>
26#include <media/stagefright/MediaDefs.h>
27#include <media/stagefright/MediaErrors.h>
28#include <media/stagefright/MediaSource.h>
29#include <media/stagefright/MetaData.h>
30#include <media/stagefright/Utils.h>
31#include <utils/String8.h>
32
33namespace android {
34
35static bool get_mp3_frame_size(
36        uint32_t header, size_t *frame_size,
37        int *out_sampling_rate = NULL, int *out_channels = NULL,
38        int *out_bitrate = NULL) {
39    *frame_size = 0;
40
41    if (out_sampling_rate) {
42        *out_sampling_rate = 0;
43    }
44
45    if (out_channels) {
46        *out_channels = 0;
47    }
48
49    if (out_bitrate) {
50        *out_bitrate = 0;
51    }
52
53    if ((header & 0xffe00000) != 0xffe00000) {
54        return false;
55    }
56
57    unsigned version = (header >> 19) & 3;
58
59    if (version == 0x01) {
60        return false;
61    }
62
63    unsigned layer = (header >> 17) & 3;
64
65    if (layer == 0x00) {
66        return false;
67    }
68
69    unsigned protection = (header >> 16) & 1;
70
71    unsigned bitrate_index = (header >> 12) & 0x0f;
72
73    if (bitrate_index == 0 || bitrate_index == 0x0f) {
74        // Disallow "free" bitrate.
75        return false;
76    }
77
78    unsigned sampling_rate_index = (header >> 10) & 3;
79
80    if (sampling_rate_index == 3) {
81        return false;
82    }
83
84    static const int kSamplingRateV1[] = { 44100, 48000, 32000 };
85    int sampling_rate = kSamplingRateV1[sampling_rate_index];
86    if (version == 2 /* V2 */) {
87        sampling_rate /= 2;
88    } else if (version == 0 /* V2.5 */) {
89        sampling_rate /= 4;
90    }
91
92    unsigned padding = (header >> 9) & 1;
93
94    if (layer == 3) {
95        // layer I
96
97        static const int kBitrateV1[] = {
98            32, 64, 96, 128, 160, 192, 224, 256,
99            288, 320, 352, 384, 416, 448
100        };
101
102        static const int kBitrateV2[] = {
103            32, 48, 56, 64, 80, 96, 112, 128,
104            144, 160, 176, 192, 224, 256
105        };
106
107        int bitrate =
108            (version == 3 /* V1 */)
109                ? kBitrateV1[bitrate_index - 1]
110                : kBitrateV2[bitrate_index - 1];
111
112        if (out_bitrate) {
113            *out_bitrate = bitrate;
114        }
115
116        *frame_size = (12000 * bitrate / sampling_rate + padding) * 4;
117    } else {
118        // layer II or III
119
120        static const int kBitrateV1L2[] = {
121            32, 48, 56, 64, 80, 96, 112, 128,
122            160, 192, 224, 256, 320, 384
123        };
124
125        static const int kBitrateV1L3[] = {
126            32, 40, 48, 56, 64, 80, 96, 112,
127            128, 160, 192, 224, 256, 320
128        };
129
130        static const int kBitrateV2[] = {
131            8, 16, 24, 32, 40, 48, 56, 64,
132            80, 96, 112, 128, 144, 160
133        };
134
135        int bitrate;
136        if (version == 3 /* V1 */) {
137            bitrate = (layer == 2 /* L2 */)
138                ? kBitrateV1L2[bitrate_index - 1]
139                : kBitrateV1L3[bitrate_index - 1];
140        } else {
141            // V2 (or 2.5)
142
143            bitrate = kBitrateV2[bitrate_index - 1];
144        }
145
146        if (out_bitrate) {
147            *out_bitrate = bitrate;
148        }
149
150        *frame_size = 144000 * bitrate / sampling_rate + padding;
151    }
152
153    if (out_sampling_rate) {
154        *out_sampling_rate = sampling_rate;
155    }
156
157    if (out_channels) {
158        int channel_mode = (header >> 6) & 3;
159
160        *out_channels = (channel_mode == 3) ? 1 : 2;
161    }
162
163    return true;
164}
165
166static bool Resync(
167        const sp<DataSource> &source, uint32_t match_header,
168        off_t *inout_pos, uint32_t *out_header) {
169    // Everything must match except for
170    // protection, bitrate, padding, private bits and mode extension.
171    const uint32_t kMask = 0xfffe0ccf;
172
173    const size_t kMaxFrameSize = 4096;
174    uint8_t *buffer = new uint8_t[kMaxFrameSize];
175
176    off_t pos = *inout_pos - kMaxFrameSize;
177    size_t buffer_offset = kMaxFrameSize;
178    size_t buffer_length = kMaxFrameSize;
179    bool valid = false;
180    do {
181        if (buffer_offset + 3 >= buffer_length) {
182            if (buffer_length < kMaxFrameSize) {
183                break;
184            }
185
186            pos += buffer_offset;
187
188            if (pos >= *inout_pos + 128 * 1024) {
189                // Don't scan forever.
190                LOGV("giving up at offset %ld", pos);
191                break;
192            }
193
194            memmove(buffer, &buffer[buffer_offset], buffer_length - buffer_offset);
195            buffer_length = buffer_length - buffer_offset;
196            buffer_offset = 0;
197
198            ssize_t n = source->read_at(
199                    pos, &buffer[buffer_length], kMaxFrameSize - buffer_length);
200
201            if (n <= 0) {
202                break;
203            }
204
205            buffer_length += (size_t)n;
206
207            continue;
208        }
209
210        uint32_t header = U32_AT(&buffer[buffer_offset]);
211
212        if (match_header != 0 && (header & kMask) != (match_header & kMask)) {
213            ++buffer_offset;
214            continue;
215        }
216
217        size_t frame_size;
218        int sample_rate, num_channels, bitrate;
219        if (!get_mp3_frame_size(header, &frame_size,
220                               &sample_rate, &num_channels, &bitrate)) {
221            ++buffer_offset;
222            continue;
223        }
224
225        LOGV("found possible 1st frame at %ld", pos + buffer_offset);
226
227        // We found what looks like a valid frame,
228        // now find its successors.
229
230        off_t test_pos = pos + buffer_offset + frame_size;
231
232        valid = true;
233        for (int j = 0; j < 3; ++j) {
234            uint8_t tmp[4];
235            if (source->read_at(test_pos, tmp, 4) < 4) {
236                valid = false;
237                break;
238            }
239
240            uint32_t test_header = U32_AT(tmp);
241
242            LOGV("subsequent header is %08x", test_header);
243
244            if ((test_header & kMask) != (header & kMask)) {
245                valid = false;
246                break;
247            }
248
249            size_t test_frame_size;
250            if (!get_mp3_frame_size(test_header, &test_frame_size)) {
251                valid = false;
252                break;
253            }
254
255            LOGV("found subsequent frame #%d at %ld", j + 2, test_pos);
256
257            test_pos += test_frame_size;
258        }
259
260        if (valid) {
261            *inout_pos = pos + buffer_offset;
262
263            if (out_header != NULL) {
264                *out_header = header;
265            }
266        } else {
267            LOGV("no dice, no valid sequence of frames found.");
268        }
269
270        ++buffer_offset;
271
272    } while (!valid);
273
274    delete[] buffer;
275    buffer = NULL;
276
277    return valid;
278}
279
280class MP3Source : public MediaSource {
281public:
282    MP3Source(
283            const sp<MetaData> &meta, const sp<DataSource> &source,
284            off_t first_frame_pos, uint32_t fixed_header);
285
286    virtual status_t start(MetaData *params = NULL);
287    virtual status_t stop();
288
289    virtual sp<MetaData> getFormat();
290
291    virtual status_t read(
292            MediaBuffer **buffer, const ReadOptions *options = NULL);
293
294protected:
295    virtual ~MP3Source();
296
297private:
298    sp<MetaData> mMeta;
299    sp<DataSource> mDataSource;
300    off_t mFirstFramePos;
301    uint32_t mFixedHeader;
302    off_t mCurrentPos;
303    int64_t mCurrentTimeUs;
304    bool mStarted;
305
306    MediaBufferGroup *mGroup;
307
308    MP3Source(const MP3Source &);
309    MP3Source &operator=(const MP3Source &);
310};
311
312MP3Extractor::MP3Extractor(const sp<DataSource> &source)
313    : mDataSource(source),
314      mFirstFramePos(-1),
315      mFixedHeader(0) {
316    off_t pos = 0;
317    uint32_t header;
318    bool success = Resync(mDataSource, 0, &pos, &header);
319    CHECK(success);
320
321    if (success) {
322        mFirstFramePos = pos;
323        mFixedHeader = header;
324
325        size_t frame_size;
326        int sample_rate;
327        int num_channels;
328        int bitrate;
329        get_mp3_frame_size(
330                header, &frame_size, &sample_rate, &num_channels, &bitrate);
331
332        mMeta = new MetaData;
333
334        mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
335        mMeta->setInt32(kKeySampleRate, sample_rate);
336        mMeta->setInt32(kKeyBitRate, bitrate);
337        mMeta->setInt32(kKeyChannelCount, num_channels);
338
339        off_t fileSize;
340        if (mDataSource->getSize(&fileSize) == OK) {
341            mMeta->setInt64(
342                    kKeyDuration,
343                    8000 * (fileSize - mFirstFramePos) / bitrate);
344        }
345    }
346}
347
348MP3Extractor::~MP3Extractor() {
349}
350
351size_t MP3Extractor::countTracks() {
352    return (mFirstFramePos < 0) ? 0 : 1;
353}
354
355sp<MediaSource> MP3Extractor::getTrack(size_t index) {
356    if (mFirstFramePos < 0 || index != 0) {
357        return NULL;
358    }
359
360    return new MP3Source(
361            mMeta, mDataSource, mFirstFramePos, mFixedHeader);
362}
363
364sp<MetaData> MP3Extractor::getTrackMetaData(size_t index) {
365    if (mFirstFramePos < 0 || index != 0) {
366        return NULL;
367    }
368
369    return mMeta;
370}
371
372////////////////////////////////////////////////////////////////////////////////
373
374MP3Source::MP3Source(
375        const sp<MetaData> &meta, const sp<DataSource> &source,
376        off_t first_frame_pos, uint32_t fixed_header)
377    : mMeta(meta),
378      mDataSource(source),
379      mFirstFramePos(first_frame_pos),
380      mFixedHeader(fixed_header),
381      mCurrentPos(0),
382      mCurrentTimeUs(0),
383      mStarted(false),
384      mGroup(NULL) {
385}
386
387MP3Source::~MP3Source() {
388    if (mStarted) {
389        stop();
390    }
391}
392
393status_t MP3Source::start(MetaData *) {
394    CHECK(!mStarted);
395
396    mGroup = new MediaBufferGroup;
397
398    const size_t kMaxFrameSize = 32768;
399    mGroup->add_buffer(new MediaBuffer(kMaxFrameSize));
400
401    mCurrentPos = mFirstFramePos;
402    mCurrentTimeUs = 0;
403
404    mStarted = true;
405
406    return OK;
407}
408
409status_t MP3Source::stop() {
410    CHECK(mStarted);
411
412    delete mGroup;
413    mGroup = NULL;
414
415    mStarted = false;
416
417    return OK;
418}
419
420sp<MetaData> MP3Source::getFormat() {
421    return mMeta;
422}
423
424status_t MP3Source::read(
425        MediaBuffer **out, const ReadOptions *options) {
426    *out = NULL;
427
428    int64_t seekTimeUs;
429    if (options != NULL && options->getSeekTo(&seekTimeUs)) {
430        int32_t bitrate;
431        if (!mMeta->findInt32(kKeyBitRate, &bitrate)) {
432            // bitrate is in kbits/sec.
433            LOGI("no bitrate");
434
435            return ERROR_UNSUPPORTED;
436        }
437
438        mCurrentTimeUs = seekTimeUs;
439        mCurrentPos = mFirstFramePos + seekTimeUs * bitrate / 1000000 * 125;
440    }
441
442    MediaBuffer *buffer;
443    status_t err = mGroup->acquire_buffer(&buffer);
444    if (err != OK) {
445        return err;
446    }
447
448    size_t frame_size;
449    for (;;) {
450        ssize_t n = mDataSource->read_at(mCurrentPos, buffer->data(), 4);
451        if (n < 4) {
452            buffer->release();
453            buffer = NULL;
454
455            return ERROR_END_OF_STREAM;
456        }
457
458        uint32_t header = U32_AT((const uint8_t *)buffer->data());
459
460        if (get_mp3_frame_size(header, &frame_size)) {
461            break;
462        }
463
464        // Lost sync.
465        LOGW("lost sync!\n");
466
467        off_t pos = mCurrentPos;
468        if (!Resync(mDataSource, mFixedHeader, &pos, NULL)) {
469            LOGE("Unable to resync. Signalling end of stream.");
470
471            buffer->release();
472            buffer = NULL;
473
474            return ERROR_END_OF_STREAM;
475        }
476
477        mCurrentPos = pos;
478
479        // Try again with the new position.
480    }
481
482    CHECK(frame_size <= buffer->size());
483
484    ssize_t n = mDataSource->read_at(mCurrentPos, buffer->data(), frame_size);
485    if (n < (ssize_t)frame_size) {
486        buffer->release();
487        buffer = NULL;
488
489        return ERROR_END_OF_STREAM;
490    }
491
492    buffer->set_range(0, frame_size);
493
494    buffer->meta_data()->setInt64(kKeyTime, mCurrentTimeUs);
495
496    mCurrentPos += frame_size;
497    mCurrentTimeUs += 1152 * 1000000 / 44100;
498
499    *out = buffer;
500
501    return OK;
502}
503
504bool SniffMP3(
505        const sp<DataSource> &source, String8 *mimeType, float *confidence) {
506    off_t pos = 0;
507    uint32_t header;
508    if (!Resync(source, 0, &pos, &header)) {
509        return false;
510    }
511
512    *mimeType = MEDIA_MIMETYPE_AUDIO_MPEG;
513    *confidence = 0.3f;
514
515    return true;
516}
517
518}  // namespace android
519