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