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