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