MP3Extractor.cpp revision 070b2e1a5c63b4f5421a0d222e975652e33795bb
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
23aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber#include "include/ID3.h"
24aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
25efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber#include <media/stagefright/foundation/AMessage.h>
26e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/DataSource.h>
27e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MediaBuffer.h>
28e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MediaBufferGroup.h>
29b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber#include <media/stagefright/MediaDebug.h>
30e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber#include <media/stagefright/MediaDefs.h>
31e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MediaErrors.h>
32e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MediaSource.h>
33e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MetaData.h>
34e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/Utils.h>
35e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <utils/String8.h>
36e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
37e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubernamespace android {
38e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
39b16e5543713cc557bdc7ceef7c0a5a8b61f3232dAndreas Huber// Everything must match except for
40070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong// protection, bitrate, padding, private bits, mode, mode extension,
411d200e3b959f7562b21a6e9d94910ddd051cfe10Andreas Huber// copyright bit, original bit and emphasis.
421d200e3b959f7562b21a6e9d94910ddd051cfe10Andreas Huber// Yes ... there are things that must indeed match...
43070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dongstatic const uint32_t kMask = 0xfffe0c00;
44b16e5543713cc557bdc7ceef7c0a5a8b61f3232dAndreas Huber
45e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatic bool get_mp3_frame_size(
46e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        uint32_t header, size_t *frame_size,
47e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        int *out_sampling_rate = NULL, int *out_channels = NULL,
48e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        int *out_bitrate = NULL) {
49e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    *frame_size = 0;
50e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
51e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (out_sampling_rate) {
52e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        *out_sampling_rate = 0;
53e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
54e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
55e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (out_channels) {
56e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        *out_channels = 0;
57e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
58e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
59e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (out_bitrate) {
60e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        *out_bitrate = 0;
61e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
62e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
63e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if ((header & 0xffe00000) != 0xffe00000) {
64e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return false;
65e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
66e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
67e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    unsigned version = (header >> 19) & 3;
68e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
69e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (version == 0x01) {
70e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return false;
71e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
72b16e5543713cc557bdc7ceef7c0a5a8b61f3232dAndreas Huber
73e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    unsigned layer = (header >> 17) & 3;
74e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
75e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (layer == 0x00) {
76e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return false;
77e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
78e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
79e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    unsigned protection = (header >> 16) & 1;
80e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
81e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    unsigned bitrate_index = (header >> 12) & 0x0f;
82e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
83e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (bitrate_index == 0 || bitrate_index == 0x0f) {
84e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        // Disallow "free" bitrate.
85e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return false;
86e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
87e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
88e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    unsigned sampling_rate_index = (header >> 10) & 3;
89e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
90e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (sampling_rate_index == 3) {
91e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return false;
92e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
93e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
94e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    static const int kSamplingRateV1[] = { 44100, 48000, 32000 };
95e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    int sampling_rate = kSamplingRateV1[sampling_rate_index];
96e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (version == 2 /* V2 */) {
97e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        sampling_rate /= 2;
98e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    } else if (version == 0 /* V2.5 */) {
99e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        sampling_rate /= 4;
100e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
101e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
102e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    unsigned padding = (header >> 9) & 1;
103e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
104e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (layer == 3) {
105e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        // layer I
106e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
107e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        static const int kBitrateV1[] = {
108e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            32, 64, 96, 128, 160, 192, 224, 256,
109e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            288, 320, 352, 384, 416, 448
110e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        };
111e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
112e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        static const int kBitrateV2[] = {
113e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            32, 48, 56, 64, 80, 96, 112, 128,
114e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            144, 160, 176, 192, 224, 256
115e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        };
116e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
117e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        int bitrate =
118e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            (version == 3 /* V1 */)
119e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                ? kBitrateV1[bitrate_index - 1]
120e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                : kBitrateV2[bitrate_index - 1];
121e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
122e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (out_bitrate) {
123e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *out_bitrate = bitrate;
124e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
125e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
126e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        *frame_size = (12000 * bitrate / sampling_rate + padding) * 4;
127e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    } else {
128e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        // layer II or III
129e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
130e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        static const int kBitrateV1L2[] = {
131e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            32, 48, 56, 64, 80, 96, 112, 128,
132e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            160, 192, 224, 256, 320, 384
133e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        };
134e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
135e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        static const int kBitrateV1L3[] = {
136e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            32, 40, 48, 56, 64, 80, 96, 112,
137e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            128, 160, 192, 224, 256, 320
138e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        };
139e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
140e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        static const int kBitrateV2[] = {
141e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            8, 16, 24, 32, 40, 48, 56, 64,
142e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            80, 96, 112, 128, 144, 160
143e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        };
144e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
145e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        int bitrate;
146e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (version == 3 /* V1 */) {
147e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            bitrate = (layer == 2 /* L2 */)
148e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                ? kBitrateV1L2[bitrate_index - 1]
149e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                : kBitrateV1L3[bitrate_index - 1];
150e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        } else {
151e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            // V2 (or 2.5)
152e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
153e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            bitrate = kBitrateV2[bitrate_index - 1];
154e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
155e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
156e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (out_bitrate) {
157e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *out_bitrate = bitrate;
158e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
159e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
16063f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber        if (version == 3 /* V1 */) {
16163f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber            *frame_size = 144000 * bitrate / sampling_rate + padding;
16263f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber        } else {
16363f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber            // V2 or V2.5
16463f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber            *frame_size = 72000 * bitrate / sampling_rate + padding;
16563f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber        }
166e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
167e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
168e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (out_sampling_rate) {
169e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        *out_sampling_rate = sampling_rate;
170e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
171e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
172e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (out_channels) {
173e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        int channel_mode = (header >> 6) & 3;
174e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
175e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        *out_channels = (channel_mode == 3) ? 1 : 2;
176e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
177e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
178e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return true;
179e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
180e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1811ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wangstatic bool parse_xing_header(
1821ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        const sp<DataSource> &source, off_t first_frame_pos,
1831ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        int32_t *frame_number = NULL, int32_t *byte_number = NULL,
1841ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        char *table_of_contents = NULL, int32_t *quality_indicator = NULL,
1851ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        int64_t *duration = NULL) {
1861ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang
1871ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (frame_number) {
1881ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        *frame_number = 0;
1891ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
1901ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (byte_number) {
1911ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        *byte_number = 0;
1921ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
1931ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (table_of_contents) {
1941ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        table_of_contents[0] = 0;
1951ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
1961ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (quality_indicator) {
1971ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        *quality_indicator = 0;
1981ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
1991ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (duration) {
2001ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        *duration = 0;
2011ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
2021ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang
2031ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    uint8_t buffer[4];
2041ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    int offset = first_frame_pos;
2051ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (source->readAt(offset, &buffer, 4) < 4) { // get header
2061ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        return false;
2071ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
2081ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    offset += 4;
2091ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang
2101ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    uint8_t id, layer, sr_index, mode;
2111ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    layer = (buffer[1] >> 1) & 3;
2121ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    id = (buffer[1] >> 3) & 3;
2131ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    sr_index = (buffer[2] >> 2) & 3;
2141ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    mode = (buffer[3] >> 6) & 3;
2151ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (layer == 0) {
2161ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        return false;
2171ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
2181ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (id == 1) {
2191ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        return false;
2201ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
2211ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (sr_index == 3) {
2221ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        return false;
2231ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
2241ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    // determine offset of XING header
2251ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if(id&1) { // mpeg1
2261ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        if (mode != 3) offset += 32;
2271ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        else offset += 17;
2281ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    } else { // mpeg2
2291ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        if (mode != 3) offset += 17;
2301ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        else offset += 9;
2311ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
2321ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang
2331ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (source->readAt(offset, &buffer, 4) < 4) { // XING header ID
2341ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        return false;
2351ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
2361ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    offset += 4;
2371ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    // Check XING ID
2381ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if ((buffer[0] != 'X') || (buffer[1] != 'i')
2391ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                || (buffer[2] != 'n') || (buffer[3] != 'g')) {
2401ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        if ((buffer[0] != 'I') || (buffer[1] != 'n')
2411ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                    || (buffer[2] != 'f') || (buffer[3] != 'o')) {
2421ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            return false;
2431ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        }
2441ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
2451ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang
2461ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (source->readAt(offset, &buffer, 4) < 4) { // flags
2471ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        return false;
2481ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
2491ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    offset += 4;
2501ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    uint32_t flags = U32_AT(buffer);
2511ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang
2521ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (flags & 0x0001) {  // Frames field is present
2531ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        if (source->readAt(offset, buffer, 4) < 4) {
2541ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang             return false;
2551ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        }
2561ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        if (frame_number) {
2571ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang           *frame_number = U32_AT(buffer);
2581ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        }
2591ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        int32_t frame = U32_AT(buffer);
2601ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        // Samples per Frame: 1. index = MPEG Version ID, 2. index = Layer
2611ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        const int samplesPerFrames[2][3] =
2621ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        {
2631ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            { 384, 1152, 576  }, // MPEG 2, 2.5: layer1, layer2, layer3
2641ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            { 384, 1152, 1152 }, // MPEG 1: layer1, layer2, layer3
2651ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        };
2661ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        // sampling rates in hertz: 1. index = MPEG Version ID, 2. index = sampling rate index
2671ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        const int samplingRates[4][3] =
2681ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        {
2691ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            { 11025, 12000, 8000,  },    // MPEG 2.5
2701ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            { 0,     0,     0,     },    // reserved
2711ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            { 22050, 24000, 16000, },    // MPEG 2
2721ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            { 44100, 48000, 32000, }     // MPEG 1
2731ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        };
2741ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        if (duration) {
2751ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            *duration = (int64_t)frame * samplesPerFrames[id&1][3-layer] * 1000000LL
2761ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                / samplingRates[id][sr_index];
2771ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        }
2781ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        offset += 4;
2791ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
2801ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (flags & 0x0002) {  // Bytes field is present
2811ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        if (byte_number) {
2821ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            if (source->readAt(offset, buffer, 4) < 4) {
2831ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                return false;
2841ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            }
2851ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            *byte_number = U32_AT(buffer);
2861ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        }
2871ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        offset += 4;
2881ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
2891ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (flags & 0x0004) {  // TOC field is present
2901ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang       if (table_of_contents) {
2911ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            if (source->readAt(offset + 1, table_of_contents, 99) < 99) {
2921ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                return false;
2931ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            }
2941ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        }
2951ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        offset += 100;
2961ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
2971ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    if (flags & 0x0008) {  // Quality indicator field is present
2981ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        if (quality_indicator) {
2991ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            if (source->readAt(offset, buffer, 4) < 4) {
3001ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                return false;
3011ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            }
3021ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            *quality_indicator = U32_AT(buffer);
3031ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        }
3041ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    }
3051ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    return true;
3061ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang}
3071ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang
308e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatic bool Resync(
309be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber        const sp<DataSource> &source, uint32_t match_header,
310e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        off_t *inout_pos, uint32_t *out_header) {
31163f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber    if (*inout_pos == 0) {
31263f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber        // Skip an optional ID3 header if syncing at the very beginning
31363f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber        // of the datasource.
31463f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber
3150d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber        for (;;) {
3160d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber            uint8_t id3header[10];
3170d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber            if (source->readAt(*inout_pos, id3header, sizeof(id3header))
3180d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber                    < (ssize_t)sizeof(id3header)) {
3190d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber                // If we can't even read these 10 bytes, we might as well bail
3200d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber                // out, even if there _were_ 10 bytes of valid mp3 audio data...
3210d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber                return false;
3220d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber            }
3230d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber
3240d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber            if (memcmp("ID3", id3header, 3)) {
3250d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber                break;
3260d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber            }
32763f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber
32863f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber            // Skip the ID3v2 header.
32963f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber
33063f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber            size_t len =
33163f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber                ((id3header[6] & 0x7f) << 21)
33263f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber                | ((id3header[7] & 0x7f) << 14)
33363f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber                | ((id3header[8] & 0x7f) << 7)
33463f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber                | (id3header[9] & 0x7f);
33563f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber
33663f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber            len += 10;
33763f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber
33863f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber            *inout_pos += len;
3390d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber
3400d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber            LOGV("skipped ID3 tag, new starting offset is %ld (0x%08lx)",
3410d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber                 *inout_pos, *inout_pos);
34263f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber        }
34363f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber    }
34463f20ec1a8d31c85261056c6c171140b93bcde0aAndreas Huber
3450d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber    off_t pos = *inout_pos;
346e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    bool valid = false;
347070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong
348070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong    const size_t kMaxReadBytes = 1024;
349070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong    const off_t kMaxBytesChecked = 128 * 1024;
350070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong    uint8_t buf[kMaxReadBytes];
351070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong    ssize_t bytesToRead = kMaxReadBytes;
352070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong    ssize_t totalBytesRead = 0;
353070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong    ssize_t remainingBytes = 0;
354070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong    bool reachEOS = false;
355070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong    uint8_t *tmp = buf;
356070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong
357e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    do {
358070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong        if (pos >= *inout_pos + kMaxBytesChecked) {
3590d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber            // Don't scan forever.
3600d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber            LOGV("giving up at offset %ld", pos);
3610d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber            break;
3620d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber        }
363e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
364070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong        if (remainingBytes < 4) {
365070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong            if (reachEOS) {
366070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong                break;
367070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong            } else {
368070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong                memcpy(buf, tmp, remainingBytes);
369070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong                bytesToRead = kMaxReadBytes - remainingBytes;
370070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong
371070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong                /*
372070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong                 * The next read position should start from the end of
373070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong                 * the last buffer, and thus should include the remaining
374070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong                 * bytes in the buffer.
375070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong                 */
376070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong                totalBytesRead = source->readAt(pos + remainingBytes,
377070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong                                                buf + remainingBytes,
378070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong                                                bytesToRead);
379070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong                if (totalBytesRead <= 0) {
380070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong                    break;
381070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong                }
382070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong                reachEOS = (totalBytesRead != bytesToRead);
383070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong                totalBytesRead += remainingBytes;
384070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong                remainingBytes = totalBytesRead;
385070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong                tmp = buf;
386070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong                continue;
387070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong            }
388e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
389e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
3900d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber        uint32_t header = U32_AT(tmp);
391e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
392e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (match_header != 0 && (header & kMask) != (match_header & kMask)) {
3930d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber            ++pos;
394070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong            ++tmp;
395070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong            --remainingBytes;
396e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            continue;
397e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
398e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
399e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        size_t frame_size;
400e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        int sample_rate, num_channels, bitrate;
4012e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber        if (!get_mp3_frame_size(header, &frame_size,
402e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                               &sample_rate, &num_channels, &bitrate)) {
4030d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber            ++pos;
404070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong            ++tmp;
405070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong            --remainingBytes;
4062e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            continue;
4072e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber        }
408e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
4090d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber        LOGV("found possible 1st frame at %ld (header = 0x%08x)", pos, header);
410e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
4112e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber        // We found what looks like a valid frame,
4122e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber        // now find its successors.
413e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
4140d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber        off_t test_pos = pos + frame_size;
415e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
4162e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber        valid = true;
4172e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber        for (int j = 0; j < 3; ++j) {
4182e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            uint8_t tmp[4];
4199a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber            if (source->readAt(test_pos, tmp, 4) < 4) {
4202e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber                valid = false;
4212e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber                break;
4222e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            }
423b16e5543713cc557bdc7ceef7c0a5a8b61f3232dAndreas Huber
4242e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            uint32_t test_header = U32_AT(tmp);
425e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
4262e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            LOGV("subsequent header is %08x", test_header);
427e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
4282e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            if ((test_header & kMask) != (header & kMask)) {
4292e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber                valid = false;
4302e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber                break;
4312e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            }
432e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
4332e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            size_t test_frame_size;
4342e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            if (!get_mp3_frame_size(test_header, &test_frame_size)) {
4352e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber                valid = false;
4362e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber                break;
437e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
4382e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber
4392e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            LOGV("found subsequent frame #%d at %ld", j + 2, test_pos);
4402e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber
4412e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            test_pos += test_frame_size;
442e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
443e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
444e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (valid) {
4450d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber            *inout_pos = pos;
446e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
447e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (out_header != NULL) {
448e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                *out_header = header;
449e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
450e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        } else {
451e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            LOGV("no dice, no valid sequence of frames found.");
452e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
453e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
4540d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber        ++pos;
455070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong        ++tmp;
456070b2e1a5c63b4f5421a0d222e975652e33795bbJames Dong        --remainingBytes;
457e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    } while (!valid);
458e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
459e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return valid;
460e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
461e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
462e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberclass MP3Source : public MediaSource {
463e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberpublic:
464e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    MP3Source(
465be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber            const sp<MetaData> &meta, const sp<DataSource> &source,
4661ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            off_t first_frame_pos, uint32_t fixed_header,
4671ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            int32_t byte_number, const char *table_of_contents);
468e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
469e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    virtual status_t start(MetaData *params = NULL);
470e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    virtual status_t stop();
471e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
472e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    virtual sp<MetaData> getFormat();
473e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
474e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    virtual status_t read(
475e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            MediaBuffer **buffer, const ReadOptions *options = NULL);
476e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
477be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huberprotected:
478be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber    virtual ~MP3Source();
479be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber
480e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberprivate:
481e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    sp<MetaData> mMeta;
482be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber    sp<DataSource> mDataSource;
483e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    off_t mFirstFramePos;
484e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    uint32_t mFixedHeader;
485e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    off_t mCurrentPos;
486e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    int64_t mCurrentTimeUs;
487e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    bool mStarted;
4881ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    int32_t mByteNumber; // total number of bytes in this MP3
4891ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    // TOC entries in XING header. Skip the first one since it's always 0.
4901ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    char mTableOfContents[99];
491e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    MediaBufferGroup *mGroup;
492e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
493e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    MP3Source(const MP3Source &);
494e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    MP3Source &operator=(const MP3Source &);
495e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber};
496e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
497efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas HuberMP3Extractor::MP3Extractor(
498efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber        const sp<DataSource> &source, const sp<AMessage> &meta)
4993e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    : mInitCheck(NO_INIT),
5003e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber      mDataSource(source),
501e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mFirstFramePos(-1),
5021ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang      mFixedHeader(0),
5031ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang      mByteNumber(0) {
504e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    off_t pos = 0;
505e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    uint32_t header;
506efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber    bool success;
507efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber
508efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber    int64_t meta_offset;
509efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber    uint32_t meta_header;
510efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber    if (meta != NULL
511efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber            && meta->findInt64("offset", &meta_offset)
512efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber            && meta->findInt32("header", (int32_t *)&meta_header)) {
513efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber        // The sniffer has already done all the hard work for us, simply
514efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber        // accept its judgement.
515efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber        pos = (off_t)meta_offset;
516efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber        header = meta_header;
517efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber
518efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber        success = true;
519efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber    } else {
520efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber        success = Resync(mDataSource, 0, &pos, &header);
521efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber    }
522e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
5233e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    if (!success) {
5243e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber        // mInitCheck will remain NO_INIT
5253e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber        return;
5263e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    }
527e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
5283e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    mFirstFramePos = pos;
5293e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    mFixedHeader = header;
530e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
5313e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    size_t frame_size;
5323e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    int sample_rate;
5333e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    int num_channels;
5343e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    int bitrate;
5353e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    get_mp3_frame_size(
5363e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber            header, &frame_size, &sample_rate, &num_channels, &bitrate);
5373e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber
5383e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    mMeta = new MetaData;
5393e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber
5403e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
5413e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    mMeta->setInt32(kKeySampleRate, sample_rate);
5423e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    mMeta->setInt32(kKeyBitRate, bitrate * 1000);
5433e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    mMeta->setInt32(kKeyChannelCount, num_channels);
5443e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber
5453e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    int64_t duration;
5463e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    parse_xing_header(
5473e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber            mDataSource, mFirstFramePos, NULL, &mByteNumber,
5483e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber            mTableOfContents, NULL, &duration);
5493e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    if (duration > 0) {
5503e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber        mMeta->setInt64(kKeyDuration, duration);
5513e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    } else {
5523e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber        off_t fileSize;
5533e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber        if (mDataSource->getSize(&fileSize) == OK) {
5543e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber            mMeta->setInt64(
5553e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber                    kKeyDuration,
5563e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber                    8000LL * (fileSize - mFirstFramePos) / bitrate);
557e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
558e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
559e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
5603e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    mInitCheck = OK;
561e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
562e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
563be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Hubersize_t MP3Extractor::countTracks() {
5643e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    return mInitCheck != OK ? 0 : 1;
565e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
566e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
567be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Hubersp<MediaSource> MP3Extractor::getTrack(size_t index) {
5683e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    if (mInitCheck != OK || index != 0) {
569be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber        return NULL;
570e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
571e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
572be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber    return new MP3Source(
5731ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            mMeta, mDataSource, mFirstFramePos, mFixedHeader,
5741ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            mByteNumber, mTableOfContents);
575e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
576e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
577e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Hubersp<MetaData> MP3Extractor::getTrackMetaData(size_t index, uint32_t flags) {
5783e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    if (mInitCheck != OK || index != 0) {
579e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return NULL;
580e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
581e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
582e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return mMeta;
583e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
584e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
585e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber////////////////////////////////////////////////////////////////////////////////
586e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
587e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMP3Source::MP3Source(
588be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber        const sp<MetaData> &meta, const sp<DataSource> &source,
5891ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        off_t first_frame_pos, uint32_t fixed_header,
5901ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        int32_t byte_number, const char *table_of_contents)
591e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    : mMeta(meta),
592e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mDataSource(source),
593e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mFirstFramePos(first_frame_pos),
594e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mFixedHeader(fixed_header),
595e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mCurrentPos(0),
596e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mCurrentTimeUs(0),
597e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mStarted(false),
5981ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang      mByteNumber(byte_number),
599e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mGroup(NULL) {
6005ebc8898d765321eafbbb7a12cfa529defcd484aAndreas Huber    memcpy (mTableOfContents, table_of_contents, sizeof(mTableOfContents));
601e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
602e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
603e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMP3Source::~MP3Source() {
604e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (mStarted) {
605e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        stop();
606e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
607e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
608e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
609e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MP3Source::start(MetaData *) {
610b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber    CHECK(!mStarted);
611e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
612e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mGroup = new MediaBufferGroup;
613e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
614e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    const size_t kMaxFrameSize = 32768;
615e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mGroup->add_buffer(new MediaBuffer(kMaxFrameSize));
616e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
617e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mCurrentPos = mFirstFramePos;
618e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mCurrentTimeUs = 0;
619e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
620e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mStarted = true;
621e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
622e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return OK;
623e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
624e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
625e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MP3Source::stop() {
626b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber    CHECK(mStarted);
627e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
628e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    delete mGroup;
629e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mGroup = NULL;
630e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
631e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mStarted = false;
632e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
633e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return OK;
634e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
635e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
636e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubersp<MetaData> MP3Source::getFormat() {
637e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return mMeta;
638e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
639e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
640e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MP3Source::read(
641e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        MediaBuffer **out, const ReadOptions *options) {
642e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    *out = NULL;
643e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
644e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    int64_t seekTimeUs;
6456624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber    ReadOptions::SeekMode mode;
6466624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber    if (options != NULL && options->getSeekTo(&seekTimeUs, &mode)) {
647e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        int32_t bitrate;
648e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (!mMeta->findInt32(kKeyBitRate, &bitrate)) {
649d49b526dd2009270cb15f7fe4e70b74673950608Andreas Huber            // bitrate is in bits/sec.
650e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            LOGI("no bitrate");
651e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
652e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            return ERROR_UNSUPPORTED;
653e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
654e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
655e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        mCurrentTimeUs = seekTimeUs;
6561ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        // interpolate in TOC to get file seek point in bytes
6571ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        int64_t duration;
6581ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        if ((mByteNumber > 0) && (mTableOfContents[0] > 0)
6591ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            && mMeta->findInt64(kKeyDuration, &duration)) {
6601ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            float percent = (float)seekTimeUs * 100 / duration;
6611ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            float fx;
6621ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            if( percent <= 0.0f ) {
6631ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                fx = 0.0f;
6641ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            } else if( percent >= 100.0f ) {
6651ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                fx = 256.0f;
6661ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            } else {
6671ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                int a = (int)percent;
6681ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                float fa, fb;
6691ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                if ( a == 0 ) {
6701ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                    fa = 0.0f;
6711ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                } else {
6721ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                    fa = (float)mTableOfContents[a-1];
6731ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                }
6741ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                if ( a < 99 ) {
6751ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                    fb = (float)mTableOfContents[a];
6761ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                } else {
6771ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                    fb = 256.0f;
6781ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                }
6791ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                fx = fa + (fb-fa)*(percent-a);
6801ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            }
6811ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            mCurrentPos = mFirstFramePos + (int)((1.0f/256.0f)*fx*mByteNumber);
6821ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        } else {
6831ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            mCurrentPos = mFirstFramePos + seekTimeUs * bitrate / 8000000;
6841ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        }
685e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
686e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
687e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    MediaBuffer *buffer;
688e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    status_t err = mGroup->acquire_buffer(&buffer);
689e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (err != OK) {
690e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return err;
691e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
692e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
693e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    size_t frame_size;
694b64af9a221c1df4853ab7c7766d5f956c61b8765Andreas Huber    int bitrate;
695e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    for (;;) {
6969a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber        ssize_t n = mDataSource->readAt(mCurrentPos, buffer->data(), 4);
697e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (n < 4) {
698e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            buffer->release();
699e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            buffer = NULL;
700e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
701e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            return ERROR_END_OF_STREAM;
702e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
703e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
704e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        uint32_t header = U32_AT((const uint8_t *)buffer->data());
705b16e5543713cc557bdc7ceef7c0a5a8b61f3232dAndreas Huber
706b16e5543713cc557bdc7ceef7c0a5a8b61f3232dAndreas Huber        if ((header & kMask) == (mFixedHeader & kMask)
707b64af9a221c1df4853ab7c7766d5f956c61b8765Andreas Huber            && get_mp3_frame_size(header, &frame_size, NULL, NULL, &bitrate)) {
708e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
709e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
710e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
711e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        // Lost sync.
7121d200e3b959f7562b21a6e9d94910ddd051cfe10Andreas Huber        LOGV("lost sync! header = 0x%08x, old header = 0x%08x\n", header, mFixedHeader);
713e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
714e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        off_t pos = mCurrentPos;
715e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (!Resync(mDataSource, mFixedHeader, &pos, NULL)) {
716e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            LOGE("Unable to resync. Signalling end of stream.");
717e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
718e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            buffer->release();
719e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            buffer = NULL;
720e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
721e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            return ERROR_END_OF_STREAM;
722e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
723e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
724e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        mCurrentPos = pos;
725e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
726e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        // Try again with the new position.
727e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
728e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
729b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber    CHECK(frame_size <= buffer->size());
730e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
7319a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber    ssize_t n = mDataSource->readAt(mCurrentPos, buffer->data(), frame_size);
732e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (n < (ssize_t)frame_size) {
733e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        buffer->release();
734e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        buffer = NULL;
735e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
736e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return ERROR_END_OF_STREAM;
737e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
738e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
739e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    buffer->set_range(0, frame_size);
740e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
741fa8de752507feaca695123911915070c1ce463b2Andreas Huber    buffer->meta_data()->setInt64(kKeyTime, mCurrentTimeUs);
742ad98d383a04fce08a147b200e23b12f12b2681a3Andreas Huber    buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
743e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
744e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mCurrentPos += frame_size;
745b64af9a221c1df4853ab7c7766d5f956c61b8765Andreas Huber    mCurrentTimeUs += frame_size * 8000ll / bitrate;
746e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
747e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    *out = buffer;
748e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
749e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return OK;
750e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
751e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
752aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Hubersp<MetaData> MP3Extractor::getMetaData() {
753aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    sp<MetaData> meta = new MetaData;
754aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
7553e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    if (mInitCheck != OK) {
7561cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber        return meta;
7571cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber    }
7581cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber
759aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    meta->setCString(kKeyMIMEType, "audio/mpeg");
760aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
761aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    ID3 id3(mDataSource);
762aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
763aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    if (!id3.isValid()) {
764aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        return meta;
765aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    }
766aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
767aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    struct Map {
768aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        int key;
769aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        const char *tag1;
770aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        const char *tag2;
771aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    };
772aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    static const Map kMap[] = {
773aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        { kKeyAlbum, "TALB", "TAL" },
774aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        { kKeyArtist, "TPE1", "TP1" },
775c5d5ee34d7c1026ca8d5cd8b186e5a73c5230247Marco Nelissen        { kKeyAlbumArtist, "TPE2", "TP2" },
776aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        { kKeyComposer, "TCOM", "TCM" },
777aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        { kKeyGenre, "TCON", "TCO" },
7783a3656ce8a34bf4a17e806c1db1073848de2728fAndreas Huber        { kKeyTitle, "TIT2", "TT2" },
779aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        { kKeyYear, "TYE", "TYER" },
7803a3656ce8a34bf4a17e806c1db1073848de2728fAndreas Huber        { kKeyAuthor, "TXT", "TEXT" },
7813a3656ce8a34bf4a17e806c1db1073848de2728fAndreas Huber        { kKeyCDTrackNumber, "TRK", "TRCK" },
782655306f8a80b3e9fc52daf458ef319a8ed8c564cMarco Nelissen        { kKeyDiscNumber, "TPA", "TPOS" },
783ba77a3f9cb1d68b2ed4813aaae856444578e3a75Marco Nelissen        { kKeyCompilation, "TCP", "TCMP" },
784aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    };
785aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]);
786aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
787aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    for (size_t i = 0; i < kNumMapEntries; ++i) {
788aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        ID3::Iterator *it = new ID3::Iterator(id3, kMap[i].tag1);
789aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        if (it->done()) {
790aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber            delete it;
791aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber            it = new ID3::Iterator(id3, kMap[i].tag2);
792aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        }
793aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
794aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        if (it->done()) {
795aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber            delete it;
796aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber            continue;
797aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        }
798aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
799aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        String8 s;
800aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        it->getString(&s);
801aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        delete it;
802aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
803aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        meta->setCString(kMap[i].key, s);
804aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    }
805aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
806aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    size_t dataSize;
807aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    String8 mime;
808aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    const void *data = id3.getAlbumArt(&dataSize, &mime);
809aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
810aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    if (data) {
811aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        meta->setData(kKeyAlbumArt, MetaData::TYPE_NONE, data, dataSize);
812aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        meta->setCString(kKeyAlbumArtMIME, mime.string());
813aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    }
814aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
815aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    return meta;
816aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber}
817aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
818be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huberbool SniffMP3(
819efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber        const sp<DataSource> &source, String8 *mimeType,
820efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber        float *confidence, sp<AMessage> *meta) {
821e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    off_t pos = 0;
822e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    uint32_t header;
823e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (!Resync(source, 0, &pos, &header)) {
824e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return false;
825e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
826e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
827efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber    *meta = new AMessage;
828efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber    (*meta)->setInt64("offset", pos);
829efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber    (*meta)->setInt32("header", header);
830efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber
831e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber    *mimeType = MEDIA_MIMETYPE_AUDIO_MPEG;
832efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber    *confidence = 0.2f;
833e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
834e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return true;
835e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
836e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
837e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}  // namespace android
838