MP3Extractor.cpp revision 1ba307d3c5800705e3fda10fb6c809f811c0f275
1e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber/*
2e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * Copyright (C) 2009 The Android Open Source Project
3e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *
4e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * you may not use this file except in compliance with the License.
6e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * You may obtain a copy of the License at
7e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *
8e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *
10e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * Unless required by applicable law or agreed to in writing, software
11e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * See the License for the specific language governing permissions and
14e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * limitations under the License.
15e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber */
16e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
17e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber//#define LOG_NDEBUG 0
18e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#define LOG_TAG "MP3Extractor"
19e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <utils/Log.h>
20e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
2157515f334bcc1f66f95e342bfcaa13bf9ca802adAndreas Huber#include "include/MP3Extractor.h"
2257515f334bcc1f66f95e342bfcaa13bf9ca802adAndreas Huber
23e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/DataSource.h>
24e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MediaBuffer.h>
25e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MediaBufferGroup.h>
26b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber#include <media/stagefright/MediaDebug.h>
27e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber#include <media/stagefright/MediaDefs.h>
28e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MediaErrors.h>
29e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MediaSource.h>
30e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MetaData.h>
31e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/Utils.h>
32e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <utils/String8.h>
33e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
34e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubernamespace android {
35e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
36b16e5543713cc557bdc7ceef7c0a5a8b61f3232dAndreas Huber// Everything must match except for
37b16e5543713cc557bdc7ceef7c0a5a8b61f3232dAndreas Huber// protection, bitrate, padding, private bits and mode extension.
38b16e5543713cc557bdc7ceef7c0a5a8b61f3232dAndreas Huberstatic const uint32_t kMask = 0xfffe0ccf;
39b16e5543713cc557bdc7ceef7c0a5a8b61f3232dAndreas Huber
40e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatic bool get_mp3_frame_size(
41e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        uint32_t header, size_t *frame_size,
42e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        int *out_sampling_rate = NULL, int *out_channels = NULL,
43e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        int *out_bitrate = NULL) {
44e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    *frame_size = 0;
45e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
46e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (out_sampling_rate) {
47e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        *out_sampling_rate = 0;
48e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
49e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
50e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (out_channels) {
51e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        *out_channels = 0;
52e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
53e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
54e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (out_bitrate) {
55e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        *out_bitrate = 0;
56e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
57e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
58e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if ((header & 0xffe00000) != 0xffe00000) {
59e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return false;
60e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
61e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
62e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    unsigned version = (header >> 19) & 3;
63e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
64e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (version == 0x01) {
65e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return false;
66e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
67b16e5543713cc557bdc7ceef7c0a5a8b61f3232dAndreas Huber
68e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    unsigned layer = (header >> 17) & 3;
69e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
70e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (layer == 0x00) {
71e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return false;
72e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
73e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
74e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    unsigned protection = (header >> 16) & 1;
75e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
76e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    unsigned bitrate_index = (header >> 12) & 0x0f;
77e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
78e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (bitrate_index == 0 || bitrate_index == 0x0f) {
79e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        // Disallow "free" bitrate.
80e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return false;
81e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
82e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
83e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    unsigned sampling_rate_index = (header >> 10) & 3;
84e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
85e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (sampling_rate_index == 3) {
86e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return false;
87e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
88e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
89e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    static const int kSamplingRateV1[] = { 44100, 48000, 32000 };
90e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    int sampling_rate = kSamplingRateV1[sampling_rate_index];
91e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (version == 2 /* V2 */) {
92e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        sampling_rate /= 2;
93e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    } else if (version == 0 /* V2.5 */) {
94e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        sampling_rate /= 4;
95e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
96e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
97e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    unsigned padding = (header >> 9) & 1;
98e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
99e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (layer == 3) {
100e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        // layer I
101e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
102e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        static const int kBitrateV1[] = {
103e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            32, 64, 96, 128, 160, 192, 224, 256,
104e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            288, 320, 352, 384, 416, 448
105e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        };
106e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
107e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        static const int kBitrateV2[] = {
108e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            32, 48, 56, 64, 80, 96, 112, 128,
109e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            144, 160, 176, 192, 224, 256
110e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        };
111e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
112e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        int bitrate =
113e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            (version == 3 /* V1 */)
114e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                ? kBitrateV1[bitrate_index - 1]
115e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                : kBitrateV2[bitrate_index - 1];
116e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
117e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (out_bitrate) {
118e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *out_bitrate = bitrate;
119e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
120e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
121e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        *frame_size = (12000 * bitrate / sampling_rate + padding) * 4;
122e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    } else {
123e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        // layer II or III
124e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
125e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        static const int kBitrateV1L2[] = {
126e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            32, 48, 56, 64, 80, 96, 112, 128,
127e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            160, 192, 224, 256, 320, 384
128e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        };
129e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
130e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        static const int kBitrateV1L3[] = {
131e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            32, 40, 48, 56, 64, 80, 96, 112,
132e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            128, 160, 192, 224, 256, 320
133e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        };
134e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
135e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        static const int kBitrateV2[] = {
136e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            8, 16, 24, 32, 40, 48, 56, 64,
137e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            80, 96, 112, 128, 144, 160
138e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        };
139e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
140e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        int bitrate;
141e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (version == 3 /* V1 */) {
142e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            bitrate = (layer == 2 /* L2 */)
143e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                ? kBitrateV1L2[bitrate_index - 1]
144e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                : kBitrateV1L3[bitrate_index - 1];
145e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        } else {
146e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            // V2 (or 2.5)
147e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
148e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            bitrate = kBitrateV2[bitrate_index - 1];
149e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
150e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
151e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (out_bitrate) {
152e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *out_bitrate = bitrate;
153e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
154e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
15563f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber        if (version == 3 /* V1 */) {
15663f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber            *frame_size = 144000 * bitrate / sampling_rate + padding;
15763f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber        } else {
15863f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber            // V2 or V2.5
15963f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber            *frame_size = 72000 * bitrate / sampling_rate + padding;
16063f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber        }
161e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
162e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
163e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (out_sampling_rate) {
164e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        *out_sampling_rate = sampling_rate;
165e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
166e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
167e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (out_channels) {
168e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        int channel_mode = (header >> 6) & 3;
169e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
170e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        *out_channels = (channel_mode == 3) ? 1 : 2;
171e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
172e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
173e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return true;
174e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
175e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1761ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wangstatic bool parse_xing_header(
1771ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        const sp<DataSource> &source, off_t first_frame_pos,
1781ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        int32_t *frame_number = NULL, int32_t *byte_number = NULL,
1791ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        char *table_of_contents = NULL, int32_t *quality_indicator = NULL,
1801ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        int64_t *duration = NULL) {
1811ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang
1821ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (frame_number) {
1831ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        *frame_number = 0;
1841ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
1851ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (byte_number) {
1861ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        *byte_number = 0;
1871ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
1881ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (table_of_contents) {
1891ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        table_of_contents[0] = 0;
1901ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
1911ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (quality_indicator) {
1921ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        *quality_indicator = 0;
1931ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
1941ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (duration) {
1951ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        *duration = 0;
1961ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
1971ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang
1981ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    uint8_t buffer[4];
1991ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    int offset = first_frame_pos;
2001ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (source->readAt(offset, &buffer, 4) < 4) { // get header
2011ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        return false;
2021ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
2031ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    offset += 4;
2041ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang
2051ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    uint8_t id, layer, sr_index, mode;
2061ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    layer = (buffer[1] >> 1) & 3;
2071ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    id = (buffer[1] >> 3) & 3;
2081ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    sr_index = (buffer[2] >> 2) & 3;
2091ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    mode = (buffer[3] >> 6) & 3;
2101ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (layer == 0) {
2111ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        return false;
2121ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
2131ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (id == 1) {
2141ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        return false;
2151ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
2161ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (sr_index == 3) {
2171ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        return false;
2181ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
2191ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    // determine offset of XING header
2201ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if(id&1) { // mpeg1
2211ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        if (mode != 3) offset += 32;
2221ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        else offset += 17;
2231ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    } else { // mpeg2
2241ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        if (mode != 3) offset += 17;
2251ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        else offset += 9;
2261ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
2271ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang
2281ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (source->readAt(offset, &buffer, 4) < 4) { // XING header ID
2291ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        return false;
2301ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
2311ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    offset += 4;
2321ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    // Check XING ID
2331ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if ((buffer[0] != 'X') || (buffer[1] != 'i')
2341ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                || (buffer[2] != 'n') || (buffer[3] != 'g')) {
2351ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        if ((buffer[0] != 'I') || (buffer[1] != 'n')
2361ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                    || (buffer[2] != 'f') || (buffer[3] != 'o')) {
2371ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            return false;
2381ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        }
2391ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
2401ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang
2411ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (source->readAt(offset, &buffer, 4) < 4) { // flags
2421ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        return false;
2431ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
2441ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    offset += 4;
2451ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    uint32_t flags = U32_AT(buffer);
2461ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang
2471ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (flags & 0x0001) {  // Frames field is present
2481ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        if (source->readAt(offset, buffer, 4) < 4) {
2491ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang             return false;
2501ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        }
2511ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        if (frame_number) {
2521ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang           *frame_number = U32_AT(buffer);
2531ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        }
2541ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        int32_t frame = U32_AT(buffer);
2551ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        // Samples per Frame: 1. index = MPEG Version ID, 2. index = Layer
2561ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        const int samplesPerFrames[2][3] =
2571ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        {
2581ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            { 384, 1152, 576  }, // MPEG 2, 2.5: layer1, layer2, layer3
2591ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            { 384, 1152, 1152 }, // MPEG 1: layer1, layer2, layer3
2601ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        };
2611ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        // sampling rates in hertz: 1. index = MPEG Version ID, 2. index = sampling rate index
2621ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        const int samplingRates[4][3] =
2631ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        {
2641ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            { 11025, 12000, 8000,  },    // MPEG 2.5
2651ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            { 0,     0,     0,     },    // reserved
2661ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            { 22050, 24000, 16000, },    // MPEG 2
2671ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            { 44100, 48000, 32000, }     // MPEG 1
2681ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        };
2691ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        if (duration) {
2701ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            *duration = (int64_t)frame * samplesPerFrames[id&1][3-layer] * 1000000LL
2711ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                / samplingRates[id][sr_index];
2721ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        }
2731ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        offset += 4;
2741ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
2751ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (flags & 0x0002) {  // Bytes field is present
2761ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        if (byte_number) {
2771ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            if (source->readAt(offset, buffer, 4) < 4) {
2781ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                return false;
2791ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            }
2801ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            *byte_number = U32_AT(buffer);
2811ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        }
2821ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        offset += 4;
2831ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
2841ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (flags & 0x0004) {  // TOC field is present
2851ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang       if (table_of_contents) {
2861ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            if (source->readAt(offset + 1, table_of_contents, 99) < 99) {
2871ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                return false;
2881ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            }
2891ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        }
2901ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        offset += 100;
2911ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
2921ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (flags & 0x0008) {  // Quality indicator field is present
2931ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        if (quality_indicator) {
2941ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            if (source->readAt(offset, buffer, 4) < 4) {
2951ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                return false;
2961ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            }
2971ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            *quality_indicator = U32_AT(buffer);
2981ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        }
2991ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
3001ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    return true;
3011ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang}
3021ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang
303e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatic bool Resync(
304be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber        const sp<DataSource> &source, uint32_t match_header,
305e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        off_t *inout_pos, uint32_t *out_header) {
30663f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber    if (*inout_pos == 0) {
30763f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber        // Skip an optional ID3 header if syncing at the very beginning
30863f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber        // of the datasource.
30963f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber
31063f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber        uint8_t id3header[10];
3119a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber        if (source->readAt(0, id3header, sizeof(id3header))
31263f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber                < (ssize_t)sizeof(id3header)) {
31363f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber            // If we can't even read these 10 bytes, we might as well bail out,
31463f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber            // even if there _were_ 10 bytes of valid mp3 audio data...
31563f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber            return false;
31663f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber        }
31763f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber
31863f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber        if (id3header[0] == 'I' && id3header[1] == 'D' && id3header[2] == '3') {
31963f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber            // Skip the ID3v2 header.
32063f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber
32163f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber            size_t len =
32263f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber                ((id3header[6] & 0x7f) << 21)
32363f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber                | ((id3header[7] & 0x7f) << 14)
32463f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber                | ((id3header[8] & 0x7f) << 7)
32563f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber                | (id3header[9] & 0x7f);
32663f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber
32763f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber            len += 10;
32863f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber
32963f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber            *inout_pos += len;
33063f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber        }
33163f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber    }
33263f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber
333e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    const size_t kMaxFrameSize = 4096;
334e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    uint8_t *buffer = new uint8_t[kMaxFrameSize];
335b16e5543713cc557bdc7ceef7c0a5a8b61f3232dAndreas Huber
3362e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber    off_t pos = *inout_pos - kMaxFrameSize;
337e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    size_t buffer_offset = kMaxFrameSize;
338e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    size_t buffer_length = kMaxFrameSize;
339e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    bool valid = false;
340e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    do {
341e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (buffer_offset + 3 >= buffer_length) {
342e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (buffer_length < kMaxFrameSize) {
343e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                break;
344e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
345e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
3462e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            pos += buffer_offset;
347e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
348e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (pos >= *inout_pos + 128 * 1024) {
349e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                // Don't scan forever.
350e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                LOGV("giving up at offset %ld", pos);
351e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                break;
352e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
353e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
354e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            memmove(buffer, &buffer[buffer_offset], buffer_length - buffer_offset);
355e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            buffer_length = buffer_length - buffer_offset;
356e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            buffer_offset = 0;
357e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
3589a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber            ssize_t n = source->readAt(
359e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                    pos, &buffer[buffer_length], kMaxFrameSize - buffer_length);
360e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
361e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (n <= 0) {
362e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                break;
363e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
364e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
365e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            buffer_length += (size_t)n;
366e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
367e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            continue;
368e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
369e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
370e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        uint32_t header = U32_AT(&buffer[buffer_offset]);
371e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
372e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (match_header != 0 && (header & kMask) != (match_header & kMask)) {
373e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            ++buffer_offset;
374e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            continue;
375e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
376e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
377e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        size_t frame_size;
378e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        int sample_rate, num_channels, bitrate;
3792e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber        if (!get_mp3_frame_size(header, &frame_size,
380e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                               &sample_rate, &num_channels, &bitrate)) {
3812e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            ++buffer_offset;
3822e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            continue;
3832e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber        }
384e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
3852e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber        LOGV("found possible 1st frame at %ld", pos + buffer_offset);
386e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
3872e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber        // We found what looks like a valid frame,
3882e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber        // now find its successors.
389e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
3902e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber        off_t test_pos = pos + buffer_offset + frame_size;
391e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
3922e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber        valid = true;
3932e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber        for (int j = 0; j < 3; ++j) {
3942e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            uint8_t tmp[4];
3959a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber            if (source->readAt(test_pos, tmp, 4) < 4) {
3962e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber                valid = false;
3972e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber                break;
3982e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            }
399b16e5543713cc557bdc7ceef7c0a5a8b61f3232dAndreas Huber
4002e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            uint32_t test_header = U32_AT(tmp);
401e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
4022e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            LOGV("subsequent header is %08x", test_header);
403e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
4042e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            if ((test_header & kMask) != (header & kMask)) {
4052e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber                valid = false;
4062e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber                break;
4072e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            }
408e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
4092e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            size_t test_frame_size;
4102e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            if (!get_mp3_frame_size(test_header, &test_frame_size)) {
4112e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber                valid = false;
4122e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber                break;
413e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
4142e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber
4152e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            LOGV("found subsequent frame #%d at %ld", j + 2, test_pos);
4162e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber
4172e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            test_pos += test_frame_size;
418e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
419e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
420e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (valid) {
421e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *inout_pos = pos + buffer_offset;
422e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
423e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (out_header != NULL) {
424e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                *out_header = header;
425e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
426e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        } else {
427e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            LOGV("no dice, no valid sequence of frames found.");
428e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
429e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
430e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        ++buffer_offset;
431e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
432e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    } while (!valid);
433e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
434e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    delete[] buffer;
435e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    buffer = NULL;
436e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
437e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return valid;
438e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
439e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
440e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberclass MP3Source : public MediaSource {
441e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberpublic:
442e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    MP3Source(
443be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber            const sp<MetaData> &meta, const sp<DataSource> &source,
4441ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            off_t first_frame_pos, uint32_t fixed_header,
4451ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            int32_t byte_number, const char *table_of_contents);
446e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
447e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    virtual status_t start(MetaData *params = NULL);
448e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    virtual status_t stop();
449e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
450e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    virtual sp<MetaData> getFormat();
451e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
452e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    virtual status_t read(
453e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            MediaBuffer **buffer, const ReadOptions *options = NULL);
454e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
455be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huberprotected:
456be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber    virtual ~MP3Source();
457be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber
458e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberprivate:
459e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    sp<MetaData> mMeta;
460be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber    sp<DataSource> mDataSource;
461e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    off_t mFirstFramePos;
462e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    uint32_t mFixedHeader;
463e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    off_t mCurrentPos;
464e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    int64_t mCurrentTimeUs;
465e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    bool mStarted;
4661ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    int32_t mByteNumber; // total number of bytes in this MP3
4671ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    // TOC entries in XING header. Skip the first one since it's always 0.
4681ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    char mTableOfContents[99];
469e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    MediaBufferGroup *mGroup;
470e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
471e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    MP3Source(const MP3Source &);
472e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    MP3Source &operator=(const MP3Source &);
473e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber};
474e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
475be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas HuberMP3Extractor::MP3Extractor(const sp<DataSource> &source)
476e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    : mDataSource(source),
477e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mFirstFramePos(-1),
4781ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang      mFixedHeader(0),
4791ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang      mByteNumber(0) {
480e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    off_t pos = 0;
481e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    uint32_t header;
482e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    bool success = Resync(mDataSource, 0, &pos, &header);
483b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber    CHECK(success);
484e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
485e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (success) {
486e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        mFirstFramePos = pos;
487e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        mFixedHeader = header;
488e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
489e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        size_t frame_size;
490e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        int sample_rate;
491e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        int num_channels;
492e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        int bitrate;
493e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        get_mp3_frame_size(
494e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                header, &frame_size, &sample_rate, &num_channels, &bitrate);
495e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
496e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        mMeta = new MetaData;
497e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
498e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber        mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
499e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        mMeta->setInt32(kKeySampleRate, sample_rate);
500d49b526dd2009270cb15f7fe4e70b74673950608Andreas Huber        mMeta->setInt32(kKeyBitRate, bitrate * 1000);
501e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        mMeta->setInt32(kKeyChannelCount, num_channels);
502e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
5031ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        int64_t duration;
5041ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        parse_xing_header(
5051ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                mDataSource, mFirstFramePos, NULL, &mByteNumber,
5061ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                mTableOfContents, NULL, &duration);
5071ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        if (duration > 0) {
5081ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            mMeta->setInt64(kKeyDuration, duration);
5091ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        } else {
5101ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            off_t fileSize;
5111ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            if (mDataSource->getSize(&fileSize) == OK) {
5121ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                mMeta->setInt64(
5131ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                        kKeyDuration,
5141ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                        8000LL * (fileSize - mFirstFramePos) / bitrate);
5151ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            }
516e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
517e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
518e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
519e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
520e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMP3Extractor::~MP3Extractor() {
521e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
522e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
523be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Hubersize_t MP3Extractor::countTracks() {
524be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber    return (mFirstFramePos < 0) ? 0 : 1;
525e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
526e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
527be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Hubersp<MediaSource> MP3Extractor::getTrack(size_t index) {
528e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (mFirstFramePos < 0 || index != 0) {
529be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber        return NULL;
530e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
531e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
532be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber    return new MP3Source(
5331ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            mMeta, mDataSource, mFirstFramePos, mFixedHeader,
5341ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            mByteNumber, mTableOfContents);
535e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
536e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
537e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Hubersp<MetaData> MP3Extractor::getTrackMetaData(size_t index, uint32_t flags) {
538e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (mFirstFramePos < 0 || index != 0) {
539e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return NULL;
540e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
541e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
542e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return mMeta;
543e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
544e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
545e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber////////////////////////////////////////////////////////////////////////////////
546e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
547e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMP3Source::MP3Source(
548be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber        const sp<MetaData> &meta, const sp<DataSource> &source,
5491ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        off_t first_frame_pos, uint32_t fixed_header,
5501ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        int32_t byte_number, const char *table_of_contents)
551e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    : mMeta(meta),
552e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mDataSource(source),
553e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mFirstFramePos(first_frame_pos),
554e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mFixedHeader(fixed_header),
555e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mCurrentPos(0),
556e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mCurrentTimeUs(0),
557e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mStarted(false),
5581ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang      mByteNumber(byte_number),
559e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mGroup(NULL) {
5601ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    memcpy (mTableOfContents, table_of_contents, strlen(table_of_contents));
561e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
562e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
563e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMP3Source::~MP3Source() {
564e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (mStarted) {
565e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        stop();
566e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
567e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
568e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
569e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MP3Source::start(MetaData *) {
570b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber    CHECK(!mStarted);
571e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
572e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mGroup = new MediaBufferGroup;
573e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
574e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    const size_t kMaxFrameSize = 32768;
575e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mGroup->add_buffer(new MediaBuffer(kMaxFrameSize));
576e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
577e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mCurrentPos = mFirstFramePos;
578e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mCurrentTimeUs = 0;
579e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
580e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mStarted = true;
581e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
582e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return OK;
583e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
584e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
585e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MP3Source::stop() {
586b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber    CHECK(mStarted);
587e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
588e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    delete mGroup;
589e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mGroup = NULL;
590e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
591e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mStarted = false;
592e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
593e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return OK;
594e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
595e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
596e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubersp<MetaData> MP3Source::getFormat() {
597e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return mMeta;
598e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
599e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
600e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MP3Source::read(
601e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        MediaBuffer **out, const ReadOptions *options) {
602e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    *out = NULL;
603e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
604e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    int64_t seekTimeUs;
605e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (options != NULL && options->getSeekTo(&seekTimeUs)) {
606e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        int32_t bitrate;
607e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (!mMeta->findInt32(kKeyBitRate, &bitrate)) {
608d49b526dd2009270cb15f7fe4e70b74673950608Andreas Huber            // bitrate is in bits/sec.
609e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            LOGI("no bitrate");
610e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
611e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            return ERROR_UNSUPPORTED;
612e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
613e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
614e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        mCurrentTimeUs = seekTimeUs;
6151ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        // interpolate in TOC to get file seek point in bytes
6161ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        int64_t duration;
6171ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        if ((mByteNumber > 0) && (mTableOfContents[0] > 0)
6181ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            && mMeta->findInt64(kKeyDuration, &duration)) {
6191ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            float percent = (float)seekTimeUs * 100 / duration;
6201ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            float fx;
6211ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            if( percent <= 0.0f ) {
6221ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                fx = 0.0f;
6231ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            } else if( percent >= 100.0f ) {
6241ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                fx = 256.0f;
6251ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            } else {
6261ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                int a = (int)percent;
6271ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                float fa, fb;
6281ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                if ( a == 0 ) {
6291ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                    fa = 0.0f;
6301ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                } else {
6311ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                    fa = (float)mTableOfContents[a-1];
6321ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                }
6331ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                if ( a < 99 ) {
6341ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                    fb = (float)mTableOfContents[a];
6351ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                } else {
6361ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                    fb = 256.0f;
6371ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                }
6381ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                fx = fa + (fb-fa)*(percent-a);
6391ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            }
6401ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            mCurrentPos = mFirstFramePos + (int)((1.0f/256.0f)*fx*mByteNumber);
6411ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        } else {
6421ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            mCurrentPos = mFirstFramePos + seekTimeUs * bitrate / 8000000;
6431ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        }
644e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
645e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
646e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    MediaBuffer *buffer;
647e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    status_t err = mGroup->acquire_buffer(&buffer);
648e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (err != OK) {
649e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return err;
650e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
651e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
652e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    size_t frame_size;
653e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    for (;;) {
6549a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber        ssize_t n = mDataSource->readAt(mCurrentPos, buffer->data(), 4);
655e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (n < 4) {
656e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            buffer->release();
657e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            buffer = NULL;
658e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
659e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            return ERROR_END_OF_STREAM;
660e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
661e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
662e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        uint32_t header = U32_AT((const uint8_t *)buffer->data());
663b16e5543713cc557bdc7ceef7c0a5a8b61f3232dAndreas Huber
664b16e5543713cc557bdc7ceef7c0a5a8b61f3232dAndreas Huber        if ((header & kMask) == (mFixedHeader & kMask)
665b16e5543713cc557bdc7ceef7c0a5a8b61f3232dAndreas Huber            && get_mp3_frame_size(header, &frame_size)) {
666e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
667e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
668e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
669e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        // Lost sync.
670e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        LOGW("lost sync!\n");
671e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
672e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        off_t pos = mCurrentPos;
673e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (!Resync(mDataSource, mFixedHeader, &pos, NULL)) {
674e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            LOGE("Unable to resync. Signalling end of stream.");
675e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
676e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            buffer->release();
677e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            buffer = NULL;
678e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
679e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            return ERROR_END_OF_STREAM;
680e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
681e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
682e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        mCurrentPos = pos;
683e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
684e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        // Try again with the new position.
685e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
686e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
687b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber    CHECK(frame_size <= buffer->size());
688e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
6899a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber    ssize_t n = mDataSource->readAt(mCurrentPos, buffer->data(), frame_size);
690e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (n < (ssize_t)frame_size) {
691e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        buffer->release();
692e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        buffer = NULL;
693e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
694e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return ERROR_END_OF_STREAM;
695e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
696e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
697e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    buffer->set_range(0, frame_size);
698e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
699fa8de752507feaca695123911915070c1ce463b2Andreas Huber    buffer->meta_data()->setInt64(kKeyTime, mCurrentTimeUs);
700e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
701e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mCurrentPos += frame_size;
702e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mCurrentTimeUs += 1152 * 1000000 / 44100;
703e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
704e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    *out = buffer;
705e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
706e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return OK;
707e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
708e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
709be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huberbool SniffMP3(
710be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber        const sp<DataSource> &source, String8 *mimeType, float *confidence) {
711e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    off_t pos = 0;
712e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    uint32_t header;
713e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (!Resync(source, 0, &pos, &header)) {
714e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return false;
715e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
716e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
717e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber    *mimeType = MEDIA_MIMETYPE_AUDIO_MPEG;
718e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    *confidence = 0.3f;
719e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
720e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return true;
721e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
722e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
723e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}  // namespace android
724