MP3Extractor.cpp revision 3e0f2be7d6501b923d586512e86a1c205b162fd6
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
401d200e3b959f7562b21a6e9d94910ddd051cfe10Andreas Huber// protection, bitrate, padding, private bits, mode extension,
411d200e3b959f7562b21a6e9d94910ddd051cfe10Andreas Huber// copyright bit, original bit and emphasis.
421d200e3b959f7562b21a6e9d94910ddd051cfe10Andreas Huber// Yes ... there are things that must indeed match...
431d200e3b959f7562b21a6e9d94910ddd051cfe10Andreas Huberstatic const uint32_t kMask = 0xfffe0cc0;
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;
347e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    do {
3480d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber        if (pos >= *inout_pos + 128 * 1024) {
3490d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber            // Don't scan forever.
3500d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber            LOGV("giving up at offset %ld", pos);
3510d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber            break;
3520d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber        }
353e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
3540d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber        uint8_t tmp[4];
3550d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber        if (source->readAt(pos, tmp, 4) != 4) {
3560d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber            break;
357e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
358e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
3590d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber        uint32_t header = U32_AT(tmp);
360e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
361e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (match_header != 0 && (header & kMask) != (match_header & kMask)) {
3620d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber            ++pos;
363e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            continue;
364e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
365e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
366e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        size_t frame_size;
367e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        int sample_rate, num_channels, bitrate;
3682e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber        if (!get_mp3_frame_size(header, &frame_size,
369e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                               &sample_rate, &num_channels, &bitrate)) {
3700d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber            ++pos;
3712e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            continue;
3722e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber        }
373e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
3740d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber        LOGV("found possible 1st frame at %ld (header = 0x%08x)", pos, header);
375e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
3762e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber        // We found what looks like a valid frame,
3772e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber        // now find its successors.
378e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
3790d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber        off_t test_pos = pos + frame_size;
380e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
3812e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber        valid = true;
3822e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber        for (int j = 0; j < 3; ++j) {
3832e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            uint8_t tmp[4];
3849a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber            if (source->readAt(test_pos, tmp, 4) < 4) {
3852e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber                valid = false;
3862e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber                break;
3872e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            }
388b16e5543713cc557bdc7ceef7c0a5a8b61f3232dAndreas Huber
3892e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            uint32_t test_header = U32_AT(tmp);
390e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
3912e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            LOGV("subsequent header is %08x", test_header);
392e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
3932e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            if ((test_header & kMask) != (header & kMask)) {
3942e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber                valid = false;
3952e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber                break;
3962e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            }
397e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
3982e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            size_t test_frame_size;
3992e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            if (!get_mp3_frame_size(test_header, &test_frame_size)) {
4002e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber                valid = false;
4012e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber                break;
402e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
4032e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber
4042e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            LOGV("found subsequent frame #%d at %ld", j + 2, test_pos);
4052e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber
4062e337a4e4b5d36228619d426255f7aa500b5b4acAndreas Huber            test_pos += test_frame_size;
407e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
408e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
409e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (valid) {
4100d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber            *inout_pos = pos;
411e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
412e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (out_header != NULL) {
413e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                *out_header = header;
414e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
415e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        } else {
416e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            LOGV("no dice, no valid sequence of frames found.");
417e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
418e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
4190d34d8b4d5ad8695daef2e0db9e8316fab8942d4Andreas Huber        ++pos;
420e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    } while (!valid);
421e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
422e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return valid;
423e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
424e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
425e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberclass MP3Source : public MediaSource {
426e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberpublic:
427e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    MP3Source(
428be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber            const sp<MetaData> &meta, const sp<DataSource> &source,
4291ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            off_t first_frame_pos, uint32_t fixed_header,
4301ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            int32_t byte_number, const char *table_of_contents);
431e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
432e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    virtual status_t start(MetaData *params = NULL);
433e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    virtual status_t stop();
434e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
435e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    virtual sp<MetaData> getFormat();
436e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
437e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    virtual status_t read(
438e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            MediaBuffer **buffer, const ReadOptions *options = NULL);
439e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
440be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huberprotected:
441be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber    virtual ~MP3Source();
442be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber
443e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberprivate:
444e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    sp<MetaData> mMeta;
445be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber    sp<DataSource> mDataSource;
446e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    off_t mFirstFramePos;
447e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    uint32_t mFixedHeader;
448e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    off_t mCurrentPos;
449e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    int64_t mCurrentTimeUs;
450e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    bool mStarted;
4511ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    int32_t mByteNumber; // total number of bytes in this MP3
4521ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    // TOC entries in XING header. Skip the first one since it's always 0.
4531ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang    char mTableOfContents[99];
454e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    MediaBufferGroup *mGroup;
455e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
456e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    MP3Source(const MP3Source &);
457e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    MP3Source &operator=(const MP3Source &);
458e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber};
459e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
460efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas HuberMP3Extractor::MP3Extractor(
461efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber        const sp<DataSource> &source, const sp<AMessage> &meta)
4623e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    : mInitCheck(NO_INIT),
4633e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber      mDataSource(source),
464e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mFirstFramePos(-1),
4651ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang      mFixedHeader(0),
4661ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang      mByteNumber(0) {
467e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    off_t pos = 0;
468e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    uint32_t header;
469efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber    bool success;
470efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber
471efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber    int64_t meta_offset;
472efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber    uint32_t meta_header;
473efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber    if (meta != NULL
474efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber            && meta->findInt64("offset", &meta_offset)
475efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber            && meta->findInt32("header", (int32_t *)&meta_header)) {
476efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber        // The sniffer has already done all the hard work for us, simply
477efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber        // accept its judgement.
478efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber        pos = (off_t)meta_offset;
479efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber        header = meta_header;
480efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber
481efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber        success = true;
482efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber    } else {
483efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber        success = Resync(mDataSource, 0, &pos, &header);
484efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber    }
485e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
4863e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    if (!success) {
4873e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber        // mInitCheck will remain NO_INIT
4883e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber        return;
4893e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    }
490e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
4913e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    mFirstFramePos = pos;
4923e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    mFixedHeader = header;
493e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
4943e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    size_t frame_size;
4953e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    int sample_rate;
4963e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    int num_channels;
4973e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    int bitrate;
4983e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    get_mp3_frame_size(
4993e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber            header, &frame_size, &sample_rate, &num_channels, &bitrate);
5003e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber
5013e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    mMeta = new MetaData;
5023e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber
5033e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
5043e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    mMeta->setInt32(kKeySampleRate, sample_rate);
5053e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    mMeta->setInt32(kKeyBitRate, bitrate * 1000);
5063e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    mMeta->setInt32(kKeyChannelCount, num_channels);
5073e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber
5083e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    int64_t duration;
5093e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    parse_xing_header(
5103e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber            mDataSource, mFirstFramePos, NULL, &mByteNumber,
5113e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber            mTableOfContents, NULL, &duration);
5123e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    if (duration > 0) {
5133e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber        mMeta->setInt64(kKeyDuration, duration);
5143e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    } else {
5153e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber        off_t fileSize;
5163e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber        if (mDataSource->getSize(&fileSize) == OK) {
5173e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber            mMeta->setInt64(
5183e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber                    kKeyDuration,
5193e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber                    8000LL * (fileSize - mFirstFramePos) / bitrate);
520e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
521e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
522e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
5233e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    mInitCheck = OK;
524e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
525e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
526be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Hubersize_t MP3Extractor::countTracks() {
5273e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    return mInitCheck != OK ? 0 : 1;
528e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
529e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
530be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Hubersp<MediaSource> MP3Extractor::getTrack(size_t index) {
5313e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    if (mInitCheck != OK || index != 0) {
532be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber        return NULL;
533e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
534e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
535be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber    return new MP3Source(
5361ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            mMeta, mDataSource, mFirstFramePos, mFixedHeader,
5371ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            mByteNumber, mTableOfContents);
538e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
539e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
540e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Hubersp<MetaData> MP3Extractor::getTrackMetaData(size_t index, uint32_t flags) {
5413e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    if (mInitCheck != OK || index != 0) {
542e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return NULL;
543e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
544e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
545e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return mMeta;
546e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
547e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
548e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber////////////////////////////////////////////////////////////////////////////////
549e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
550e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMP3Source::MP3Source(
551be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber        const sp<MetaData> &meta, const sp<DataSource> &source,
5521ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        off_t first_frame_pos, uint32_t fixed_header,
5531ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        int32_t byte_number, const char *table_of_contents)
554e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    : mMeta(meta),
555e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mDataSource(source),
556e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mFirstFramePos(first_frame_pos),
557e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mFixedHeader(fixed_header),
558e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mCurrentPos(0),
559e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mCurrentTimeUs(0),
560e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mStarted(false),
5611ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang      mByteNumber(byte_number),
562e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mGroup(NULL) {
5635ebc8898d765321eafbbb7a12cfa529defcd484aAndreas Huber    memcpy (mTableOfContents, table_of_contents, sizeof(mTableOfContents));
564e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
565e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
566e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMP3Source::~MP3Source() {
567e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (mStarted) {
568e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        stop();
569e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
570e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
571e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
572e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MP3Source::start(MetaData *) {
573b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber    CHECK(!mStarted);
574e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
575e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mGroup = new MediaBufferGroup;
576e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
577e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    const size_t kMaxFrameSize = 32768;
578e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mGroup->add_buffer(new MediaBuffer(kMaxFrameSize));
579e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
580e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mCurrentPos = mFirstFramePos;
581e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mCurrentTimeUs = 0;
582e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
583e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mStarted = true;
584e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
585e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return OK;
586e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
587e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
588e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MP3Source::stop() {
589b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber    CHECK(mStarted);
590e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
591e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    delete mGroup;
592e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mGroup = NULL;
593e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
594e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mStarted = false;
595e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
596e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return OK;
597e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
598e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
599e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubersp<MetaData> MP3Source::getFormat() {
600e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return mMeta;
601e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
602e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
603e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MP3Source::read(
604e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        MediaBuffer **out, const ReadOptions *options) {
605e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    *out = NULL;
606e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
607e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    int64_t seekTimeUs;
6086624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber    ReadOptions::SeekMode mode;
6096624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber    if (options != NULL && options->getSeekTo(&seekTimeUs, &mode)) {
610e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        int32_t bitrate;
611e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (!mMeta->findInt32(kKeyBitRate, &bitrate)) {
612d49b526dd2009270cb15f7fe4e70b74673950608Andreas Huber            // bitrate is in bits/sec.
613e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            LOGI("no bitrate");
614e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
615e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            return ERROR_UNSUPPORTED;
616e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
617e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
618e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        mCurrentTimeUs = seekTimeUs;
6191ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        // interpolate in TOC to get file seek point in bytes
6201ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        int64_t duration;
6211ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        if ((mByteNumber > 0) && (mTableOfContents[0] > 0)
6221ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            && mMeta->findInt64(kKeyDuration, &duration)) {
6231ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            float percent = (float)seekTimeUs * 100 / duration;
6241ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            float fx;
6251ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            if( percent <= 0.0f ) {
6261ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                fx = 0.0f;
6271ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            } else if( percent >= 100.0f ) {
6281ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                fx = 256.0f;
6291ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            } else {
6301ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                int a = (int)percent;
6311ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                float fa, fb;
6321ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                if ( a == 0 ) {
6331ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                    fa = 0.0f;
6341ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                } else {
6351ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                    fa = (float)mTableOfContents[a-1];
6361ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                }
6371ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                if ( a < 99 ) {
6381ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                    fb = (float)mTableOfContents[a];
6391ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                } else {
6401ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                    fb = 256.0f;
6411ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                }
6421ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang                fx = fa + (fb-fa)*(percent-a);
6431ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            }
6441ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            mCurrentPos = mFirstFramePos + (int)((1.0f/256.0f)*fx*mByteNumber);
6451ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        } else {
6461ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang            mCurrentPos = mFirstFramePos + seekTimeUs * bitrate / 8000000;
6471ba307d3c5800705e3fda10fb6c809f811c0f275Gloria Wang        }
648e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
649e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
650e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    MediaBuffer *buffer;
651e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    status_t err = mGroup->acquire_buffer(&buffer);
652e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (err != OK) {
653e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return err;
654e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
655e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
656e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    size_t frame_size;
657b64af9a221c1df4853ab7c7766d5f956c61b8765Andreas Huber    int bitrate;
658e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    for (;;) {
6599a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber        ssize_t n = mDataSource->readAt(mCurrentPos, buffer->data(), 4);
660e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (n < 4) {
661e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            buffer->release();
662e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            buffer = NULL;
663e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
664e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            return ERROR_END_OF_STREAM;
665e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
666e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
667e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        uint32_t header = U32_AT((const uint8_t *)buffer->data());
668b16e5543713cc557bdc7ceef7c0a5a8b61f3232dAndreas Huber
669b16e5543713cc557bdc7ceef7c0a5a8b61f3232dAndreas Huber        if ((header & kMask) == (mFixedHeader & kMask)
670b64af9a221c1df4853ab7c7766d5f956c61b8765Andreas Huber            && get_mp3_frame_size(header, &frame_size, NULL, NULL, &bitrate)) {
671e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
672e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
673e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
674e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        // Lost sync.
6751d200e3b959f7562b21a6e9d94910ddd051cfe10Andreas Huber        LOGV("lost sync! header = 0x%08x, old header = 0x%08x\n", header, mFixedHeader);
676e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
677e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        off_t pos = mCurrentPos;
678e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (!Resync(mDataSource, mFixedHeader, &pos, NULL)) {
679e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            LOGE("Unable to resync. Signalling end of stream.");
680e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
681e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            buffer->release();
682e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            buffer = NULL;
683e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
684e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            return ERROR_END_OF_STREAM;
685e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
686e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
687e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        mCurrentPos = pos;
688e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
689e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        // Try again with the new position.
690e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
691e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
692b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber    CHECK(frame_size <= buffer->size());
693e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
6949a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber    ssize_t n = mDataSource->readAt(mCurrentPos, buffer->data(), frame_size);
695e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (n < (ssize_t)frame_size) {
696e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        buffer->release();
697e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        buffer = NULL;
698e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
699e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return ERROR_END_OF_STREAM;
700e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
701e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
702e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    buffer->set_range(0, frame_size);
703e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
704fa8de752507feaca695123911915070c1ce463b2Andreas Huber    buffer->meta_data()->setInt64(kKeyTime, mCurrentTimeUs);
705ad98d383a04fce08a147b200e23b12f12b2681a3Andreas Huber    buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
706e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
707e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mCurrentPos += frame_size;
708b64af9a221c1df4853ab7c7766d5f956c61b8765Andreas Huber    mCurrentTimeUs += frame_size * 8000ll / bitrate;
709e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
710e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    *out = buffer;
711e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
712e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return OK;
713e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
714e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
715aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Hubersp<MetaData> MP3Extractor::getMetaData() {
716aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    sp<MetaData> meta = new MetaData;
717aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
7183e0f2be7d6501b923d586512e86a1c205b162fd6Andreas Huber    if (mInitCheck != OK) {
7191cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber        return meta;
7201cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber    }
7211cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber
722aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    meta->setCString(kKeyMIMEType, "audio/mpeg");
723aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
724aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    ID3 id3(mDataSource);
725aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
726aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    if (!id3.isValid()) {
727aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        return meta;
728aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    }
729aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
730aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    struct Map {
731aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        int key;
732aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        const char *tag1;
733aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        const char *tag2;
734aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    };
735aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    static const Map kMap[] = {
736aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        { kKeyAlbum, "TALB", "TAL" },
737aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        { kKeyArtist, "TPE1", "TP1" },
738c5d5ee34d7c1026ca8d5cd8b186e5a73c5230247Marco Nelissen        { kKeyAlbumArtist, "TPE2", "TP2" },
739aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        { kKeyComposer, "TCOM", "TCM" },
740aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        { kKeyGenre, "TCON", "TCO" },
7413a3656ce8a34bf4a17e806c1db1073848de2728fAndreas Huber        { kKeyTitle, "TIT2", "TT2" },
742aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        { kKeyYear, "TYE", "TYER" },
7433a3656ce8a34bf4a17e806c1db1073848de2728fAndreas Huber        { kKeyAuthor, "TXT", "TEXT" },
7443a3656ce8a34bf4a17e806c1db1073848de2728fAndreas Huber        { kKeyCDTrackNumber, "TRK", "TRCK" },
745655306f8a80b3e9fc52daf458ef319a8ed8c564cMarco Nelissen        { kKeyDiscNumber, "TPA", "TPOS" },
746aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    };
747aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]);
748aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
749aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    for (size_t i = 0; i < kNumMapEntries; ++i) {
750aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        ID3::Iterator *it = new ID3::Iterator(id3, kMap[i].tag1);
751aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        if (it->done()) {
752aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber            delete it;
753aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber            it = new ID3::Iterator(id3, kMap[i].tag2);
754aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        }
755aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
756aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        if (it->done()) {
757aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber            delete it;
758aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber            continue;
759aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        }
760aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
761aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        String8 s;
762aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        it->getString(&s);
763aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        delete it;
764aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
765aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        meta->setCString(kMap[i].key, s);
766aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    }
767aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
768aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    size_t dataSize;
769aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    String8 mime;
770aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    const void *data = id3.getAlbumArt(&dataSize, &mime);
771aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
772aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    if (data) {
773aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        meta->setData(kKeyAlbumArt, MetaData::TYPE_NONE, data, dataSize);
774aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber        meta->setCString(kKeyAlbumArtMIME, mime.string());
775aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    }
776aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
777aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber    return meta;
778aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber}
779aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber
780be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huberbool SniffMP3(
781efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber        const sp<DataSource> &source, String8 *mimeType,
782efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber        float *confidence, sp<AMessage> *meta) {
783e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    off_t pos = 0;
784e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    uint32_t header;
785e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (!Resync(source, 0, &pos, &header)) {
786e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return false;
787e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
788e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
789efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber    *meta = new AMessage;
790efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber    (*meta)->setInt64("offset", pos);
791efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber    (*meta)->setInt32("header", header);
792efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber
793e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber    *mimeType = MEDIA_MIMETYPE_AUDIO_MPEG;
794efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber    *confidence = 0.2f;
795e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
796e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return true;
797e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
798e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
799e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}  // namespace android
800