MP3Extractor.cpp revision fc9ba09e3bb368f823d473f5e2bb9aa32dba6289
120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/* 220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project 320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License. 620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at 720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software 1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and 1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License. 1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */ 1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber//#define LOG_NDEBUG 0 1820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#define LOG_TAG "MP3Extractor" 1920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/Log.h> 2020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2166326a5ee0869f1ee4d136a477e6effba428b3cbAndreas Huber#include "include/MP3Extractor.h" 2266326a5ee0869f1ee4d136a477e6effba428b3cbAndreas Huber 23fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#include "include/ID3.h" 24fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/DataSource.h> 2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBuffer.h> 2720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBufferGroup.h> 280c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber#include <media/stagefright/MediaDebug.h> 2918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h> 3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaErrors.h> 3120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaSource.h> 3220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h> 3320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/Utils.h> 3420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/String8.h> 3520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3620111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 3720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 38541962997b4076da11546619f082467ffd9bcd1fAndreas Huber// Everything must match except for 39541962997b4076da11546619f082467ffd9bcd1fAndreas Huber// protection, bitrate, padding, private bits and mode extension. 40541962997b4076da11546619f082467ffd9bcd1fAndreas Huberstatic const uint32_t kMask = 0xfffe0ccf; 41541962997b4076da11546619f082467ffd9bcd1fAndreas Huber 4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic bool get_mp3_frame_size( 4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t header, size_t *frame_size, 4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int *out_sampling_rate = NULL, int *out_channels = NULL, 4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int *out_bitrate = NULL) { 4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *frame_size = 0; 4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (out_sampling_rate) { 4920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out_sampling_rate = 0; 5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (out_channels) { 5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out_channels = 0; 5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 5520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (out_bitrate) { 5720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out_bitrate = 0; 5820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 5920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((header & 0xffe00000) != 0xffe00000) { 6120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 6220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 6320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber unsigned version = (header >> 19) & 3; 6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 0x01) { 6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 6820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 69541962997b4076da11546619f082467ffd9bcd1fAndreas Huber 7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber unsigned layer = (header >> 17) & 3; 7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (layer == 0x00) { 7320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber unsigned protection = (header >> 16) & 1; 7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber unsigned bitrate_index = (header >> 12) & 0x0f; 7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (bitrate_index == 0 || bitrate_index == 0x0f) { 8120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Disallow "free" bitrate. 8220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 8320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 8420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber unsigned sampling_rate_index = (header >> 10) & 3; 8620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (sampling_rate_index == 3) { 8820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 8920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 9020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber static const int kSamplingRateV1[] = { 44100, 48000, 32000 }; 9220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int sampling_rate = kSamplingRateV1[sampling_rate_index]; 9320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 2 /* V2 */) { 9420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sampling_rate /= 2; 9520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0 /* V2.5 */) { 9620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sampling_rate /= 4; 9720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 9820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber unsigned padding = (header >> 9) & 1; 10020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (layer == 3) { 10220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // layer I 10320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber static const int kBitrateV1[] = { 10520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32, 64, 96, 128, 160, 192, 224, 256, 10620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 288, 320, 352, 384, 416, 448 10720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber }; 10820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber static const int kBitrateV2[] = { 11020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32, 48, 56, 64, 80, 96, 112, 128, 11120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 144, 160, 176, 192, 224, 256 11220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber }; 11320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int bitrate = 11520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber (version == 3 /* V1 */) 11620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ? kBitrateV1[bitrate_index - 1] 11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : kBitrateV2[bitrate_index - 1]; 11820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (out_bitrate) { 12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out_bitrate = bitrate; 12120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *frame_size = (12000 * bitrate / sampling_rate + padding) * 4; 12420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 12520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // layer II or III 12620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber static const int kBitrateV1L2[] = { 12820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32, 48, 56, 64, 80, 96, 112, 128, 12920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 160, 192, 224, 256, 320, 384 13020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber }; 13120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber static const int kBitrateV1L3[] = { 13320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32, 40, 48, 56, 64, 80, 96, 112, 13420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 128, 160, 192, 224, 256, 320 13520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber }; 13620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber static const int kBitrateV2[] = { 13820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8, 16, 24, 32, 40, 48, 56, 64, 13920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80, 96, 112, 128, 144, 160 14020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber }; 14120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int bitrate; 14320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 3 /* V1 */) { 14420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bitrate = (layer == 2 /* L2 */) 14520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ? kBitrateV1L2[bitrate_index - 1] 14620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : kBitrateV1L3[bitrate_index - 1]; 14720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 14820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // V2 (or 2.5) 14920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bitrate = kBitrateV2[bitrate_index - 1]; 15120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 15220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (out_bitrate) { 15420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out_bitrate = bitrate; 15520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 15620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1570bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber if (version == 3 /* V1 */) { 1580bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber *frame_size = 144000 * bitrate / sampling_rate + padding; 1590bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber } else { 1600bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber // V2 or V2.5 1610bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber *frame_size = 72000 * bitrate / sampling_rate + padding; 1620bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber } 16320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 16420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 16520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (out_sampling_rate) { 16620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out_sampling_rate = sampling_rate; 16720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 16820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 16920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (out_channels) { 17020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int channel_mode = (header >> 6) & 3; 17120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out_channels = (channel_mode == 3) ? 1 : 2; 17320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 17420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return true; 17620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 17720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 178ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wangstatic bool parse_xing_header( 179ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang const sp<DataSource> &source, off_t first_frame_pos, 180ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang int32_t *frame_number = NULL, int32_t *byte_number = NULL, 181ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang char *table_of_contents = NULL, int32_t *quality_indicator = NULL, 182ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang int64_t *duration = NULL) { 183ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang 184ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if (frame_number) { 185ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang *frame_number = 0; 186ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 187ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if (byte_number) { 188ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang *byte_number = 0; 189ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 190ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if (table_of_contents) { 191ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang table_of_contents[0] = 0; 192ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 193ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if (quality_indicator) { 194ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang *quality_indicator = 0; 195ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 196ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if (duration) { 197ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang *duration = 0; 198ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 199ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang 200ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang uint8_t buffer[4]; 201ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang int offset = first_frame_pos; 202ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if (source->readAt(offset, &buffer, 4) < 4) { // get header 203ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang return false; 204ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 205ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang offset += 4; 206ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang 207ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang uint8_t id, layer, sr_index, mode; 208ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang layer = (buffer[1] >> 1) & 3; 209ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang id = (buffer[1] >> 3) & 3; 210ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang sr_index = (buffer[2] >> 2) & 3; 211ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang mode = (buffer[3] >> 6) & 3; 212ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if (layer == 0) { 213ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang return false; 214ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 215ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if (id == 1) { 216ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang return false; 217ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 218ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if (sr_index == 3) { 219ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang return false; 220ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 221ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang // determine offset of XING header 222ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if(id&1) { // mpeg1 223ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if (mode != 3) offset += 32; 224ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang else offset += 17; 225ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } else { // mpeg2 226ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if (mode != 3) offset += 17; 227ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang else offset += 9; 228ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 229ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang 230ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if (source->readAt(offset, &buffer, 4) < 4) { // XING header ID 231ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang return false; 232ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 233ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang offset += 4; 234ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang // Check XING ID 235ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if ((buffer[0] != 'X') || (buffer[1] != 'i') 236ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang || (buffer[2] != 'n') || (buffer[3] != 'g')) { 237ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if ((buffer[0] != 'I') || (buffer[1] != 'n') 238ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang || (buffer[2] != 'f') || (buffer[3] != 'o')) { 239ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang return false; 240ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 241ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 242ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang 243ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if (source->readAt(offset, &buffer, 4) < 4) { // flags 244ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang return false; 245ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 246ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang offset += 4; 247ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang uint32_t flags = U32_AT(buffer); 248ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang 249ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if (flags & 0x0001) { // Frames field is present 250ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if (source->readAt(offset, buffer, 4) < 4) { 251ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang return false; 252ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 253ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if (frame_number) { 254ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang *frame_number = U32_AT(buffer); 255ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 256ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang int32_t frame = U32_AT(buffer); 257ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang // Samples per Frame: 1. index = MPEG Version ID, 2. index = Layer 258ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang const int samplesPerFrames[2][3] = 259ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang { 260ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang { 384, 1152, 576 }, // MPEG 2, 2.5: layer1, layer2, layer3 261ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang { 384, 1152, 1152 }, // MPEG 1: layer1, layer2, layer3 262ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang }; 263ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang // sampling rates in hertz: 1. index = MPEG Version ID, 2. index = sampling rate index 264ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang const int samplingRates[4][3] = 265ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang { 266ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang { 11025, 12000, 8000, }, // MPEG 2.5 267ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang { 0, 0, 0, }, // reserved 268ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang { 22050, 24000, 16000, }, // MPEG 2 269ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang { 44100, 48000, 32000, } // MPEG 1 270ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang }; 271ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if (duration) { 272ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang *duration = (int64_t)frame * samplesPerFrames[id&1][3-layer] * 1000000LL 273ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang / samplingRates[id][sr_index]; 274ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 275ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang offset += 4; 276ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 277ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if (flags & 0x0002) { // Bytes field is present 278ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if (byte_number) { 279ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if (source->readAt(offset, buffer, 4) < 4) { 280ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang return false; 281ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 282ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang *byte_number = U32_AT(buffer); 283ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 284ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang offset += 4; 285ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 286ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if (flags & 0x0004) { // TOC field is present 287ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if (table_of_contents) { 288ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if (source->readAt(offset + 1, table_of_contents, 99) < 99) { 289ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang return false; 290ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 291ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 292ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang offset += 100; 293ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 294ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if (flags & 0x0008) { // Quality indicator field is present 295ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if (quality_indicator) { 296ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if (source->readAt(offset, buffer, 4) < 4) { 297ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang return false; 298ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 299ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang *quality_indicator = U32_AT(buffer); 300ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 301ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 302ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang return true; 303ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang} 304ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang 30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic bool Resync( 306693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &source, uint32_t match_header, 30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t *inout_pos, uint32_t *out_header) { 3080bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber if (*inout_pos == 0) { 3090bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber // Skip an optional ID3 header if syncing at the very beginning 3100bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber // of the datasource. 3110bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber 3120bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber uint8_t id3header[10]; 31334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (source->readAt(0, id3header, sizeof(id3header)) 3140bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber < (ssize_t)sizeof(id3header)) { 3150bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber // If we can't even read these 10 bytes, we might as well bail out, 3160bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber // even if there _were_ 10 bytes of valid mp3 audio data... 3170bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber return false; 3180bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber } 3190bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber 3200bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber if (id3header[0] == 'I' && id3header[1] == 'D' && id3header[2] == '3') { 3210bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber // Skip the ID3v2 header. 3220bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber 3230bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber size_t len = 3240bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber ((id3header[6] & 0x7f) << 21) 3250bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber | ((id3header[7] & 0x7f) << 14) 3260bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber | ((id3header[8] & 0x7f) << 7) 3270bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber | (id3header[9] & 0x7f); 3280bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber 3290bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber len += 10; 3300bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber 3310bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber *inout_pos += len; 3320bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber } 3330bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber } 3340bf3921522461b1c7d321d0c667c1020ab3110bcAndreas Huber 33520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const size_t kMaxFrameSize = 4096; 33620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t *buffer = new uint8_t[kMaxFrameSize]; 337541962997b4076da11546619f082467ffd9bcd1fAndreas Huber 338c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber off_t pos = *inout_pos - kMaxFrameSize; 33920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t buffer_offset = kMaxFrameSize; 34020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t buffer_length = kMaxFrameSize; 34120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool valid = false; 34220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber do { 34320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (buffer_offset + 3 >= buffer_length) { 34420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (buffer_length < kMaxFrameSize) { 34520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 34620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 34720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 348c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber pos += buffer_offset; 34920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (pos >= *inout_pos + 128 * 1024) { 35120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Don't scan forever. 35220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber LOGV("giving up at offset %ld", pos); 35320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 35420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 35520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber memmove(buffer, &buffer[buffer_offset], buffer_length - buffer_offset); 35720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber buffer_length = buffer_length - buffer_offset; 35820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber buffer_offset = 0; 35920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 36034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber ssize_t n = source->readAt( 36120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber pos, &buffer[buffer_length], kMaxFrameSize - buffer_length); 36220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 36320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n <= 0) { 36420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 36520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 36620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 36720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber buffer_length += (size_t)n; 36820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 36920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber continue; 37020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 37120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t header = U32_AT(&buffer[buffer_offset]); 37320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (match_header != 0 && (header & kMask) != (match_header & kMask)) { 37520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ++buffer_offset; 37620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber continue; 37720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 37820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t frame_size; 38020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int sample_rate, num_channels, bitrate; 381c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber if (!get_mp3_frame_size(header, &frame_size, 38220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber &sample_rate, &num_channels, &bitrate)) { 383c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber ++buffer_offset; 384c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber continue; 385c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber } 38620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 387c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber LOGV("found possible 1st frame at %ld", pos + buffer_offset); 38820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 389c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber // We found what looks like a valid frame, 390c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber // now find its successors. 39120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 392c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber off_t test_pos = pos + buffer_offset + frame_size; 39320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 394c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber valid = true; 395c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber for (int j = 0; j < 3; ++j) { 396c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber uint8_t tmp[4]; 39734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (source->readAt(test_pos, tmp, 4) < 4) { 398c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber valid = false; 399c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber break; 400c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber } 401541962997b4076da11546619f082467ffd9bcd1fAndreas Huber 402c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber uint32_t test_header = U32_AT(tmp); 40320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 404c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber LOGV("subsequent header is %08x", test_header); 40520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 406c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber if ((test_header & kMask) != (header & kMask)) { 407c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber valid = false; 408c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber break; 409c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber } 41020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 411c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber size_t test_frame_size; 412c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber if (!get_mp3_frame_size(test_header, &test_frame_size)) { 413c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber valid = false; 414c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber break; 41520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 416c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber 417c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber LOGV("found subsequent frame #%d at %ld", j + 2, test_pos); 418c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber 419c8d6c8bdd84464e0c7e511241ede2299cf38fda4Andreas Huber test_pos += test_frame_size; 42020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 42120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 42220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (valid) { 42320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *inout_pos = pos + buffer_offset; 42420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 42520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (out_header != NULL) { 42620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out_header = header; 42720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 42820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 42920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber LOGV("no dice, no valid sequence of frames found."); 43020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ++buffer_offset; 43320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } while (!valid); 43520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete[] buffer; 43720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber buffer = NULL; 43820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return valid; 44020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 44120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberclass MP3Source : public MediaSource { 44320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberpublic: 44420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MP3Source( 445693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<MetaData> &meta, const sp<DataSource> &source, 446ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang off_t first_frame_pos, uint32_t fixed_header, 447ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang int32_t byte_number, const char *table_of_contents); 44820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t start(MetaData *params = NULL); 45020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t stop(); 45120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 45220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual sp<MetaData> getFormat(); 45320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 45420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t read( 45520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **buffer, const ReadOptions *options = NULL); 45620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 457693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprotected: 458693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber virtual ~MP3Source(); 459693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 46020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate: 46120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<MetaData> mMeta; 462693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<DataSource> mDataSource; 46320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t mFirstFramePos; 46420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t mFixedHeader; 46520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t mCurrentPos; 46620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t mCurrentTimeUs; 46720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mStarted; 468ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang int32_t mByteNumber; // total number of bytes in this MP3 469ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang // TOC entries in XING header. Skip the first one since it's always 0. 470ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang char mTableOfContents[99]; 47120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBufferGroup *mGroup; 47220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 47320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MP3Source(const MP3Source &); 47420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MP3Source &operator=(const MP3Source &); 47520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}; 47620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 477693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberMP3Extractor::MP3Extractor(const sp<DataSource> &source) 47820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mDataSource(source), 47920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstFramePos(-1), 480ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang mFixedHeader(0), 481ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang mByteNumber(0) { 48220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t pos = 0; 48320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t header; 48420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool success = Resync(mDataSource, 0, &pos, &header); 4850c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK(success); 48620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 48720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (success) { 48820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstFramePos = pos; 48920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFixedHeader = header; 49020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 49120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t frame_size; 49220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int sample_rate; 49320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int num_channels; 49420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int bitrate; 49520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber get_mp3_frame_size( 49620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber header, &frame_size, &sample_rate, &num_channels, &bitrate); 49720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 49820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mMeta = new MetaData; 49920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 50018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG); 50120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mMeta->setInt32(kKeySampleRate, sample_rate); 502b841f14f8e51f2365945281fbfa54ef6a1b1b5a6Andreas Huber mMeta->setInt32(kKeyBitRate, bitrate * 1000); 50320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mMeta->setInt32(kKeyChannelCount, num_channels); 50420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 505ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang int64_t duration; 506ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang parse_xing_header( 507ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang mDataSource, mFirstFramePos, NULL, &mByteNumber, 508ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang mTableOfContents, NULL, &duration); 509ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if (duration > 0) { 510ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang mMeta->setInt64(kKeyDuration, duration); 511ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } else { 512ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang off_t fileSize; 513ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if (mDataSource->getSize(&fileSize) == OK) { 514ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang mMeta->setInt64( 515ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang kKeyDuration, 516ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang 8000LL * (fileSize - mFirstFramePos) / bitrate); 517ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 51820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 51920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 52020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 52120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 52220111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMP3Extractor::~MP3Extractor() { 52320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 52420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 525693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersize_t MP3Extractor::countTracks() { 526693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return (mFirstFramePos < 0) ? 0 : 1; 52720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 52820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 529693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersp<MediaSource> MP3Extractor::getTrack(size_t index) { 53020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mFirstFramePos < 0 || index != 0) { 531693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 53220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 53320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 534693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return new MP3Source( 535ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang mMeta, mDataSource, mFirstFramePos, mFixedHeader, 536ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang mByteNumber, mTableOfContents); 53720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 53820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5397e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Hubersp<MetaData> MP3Extractor::getTrackMetaData(size_t index, uint32_t flags) { 54020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mFirstFramePos < 0 || index != 0) { 54120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 54220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 54320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 54420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mMeta; 54520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 54620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 54720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber//////////////////////////////////////////////////////////////////////////////// 54820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 54920111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMP3Source::MP3Source( 550693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<MetaData> &meta, const sp<DataSource> &source, 551ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang off_t first_frame_pos, uint32_t fixed_header, 552ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang int32_t byte_number, const char *table_of_contents) 55320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mMeta(meta), 55420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDataSource(source), 55520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstFramePos(first_frame_pos), 55620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFixedHeader(fixed_header), 55720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentPos(0), 55820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentTimeUs(0), 55920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted(false), 560ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang mByteNumber(byte_number), 56120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup(NULL) { 562db74495dbf653a72018396607fae63946bed44ecAndreas Huber memcpy (mTableOfContents, table_of_contents, sizeof(mTableOfContents)); 56320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 56420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 56520111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMP3Source::~MP3Source() { 56620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 56720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber stop(); 56820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 56920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 57020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 57120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MP3Source::start(MetaData *) { 5720c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK(!mStarted); 57320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 57420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = new MediaBufferGroup; 57520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 57620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const size_t kMaxFrameSize = 32768; 57720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup->add_buffer(new MediaBuffer(kMaxFrameSize)); 57820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 57920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentPos = mFirstFramePos; 58020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentTimeUs = 0; 58120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 58220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = true; 58320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 58420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 58520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 58620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 58720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MP3Source::stop() { 5880c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK(mStarted); 58920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 59020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete mGroup; 59120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = NULL; 59220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 59320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = false; 59420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 59520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 59620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 59720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 59820111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MP3Source::getFormat() { 59920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mMeta; 60020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 60120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 60220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MP3Source::read( 60320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **out, const ReadOptions *options) { 60420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = NULL; 60520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 60620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 60720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (options != NULL && options->getSeekTo(&seekTimeUs)) { 60820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t bitrate; 60920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (!mMeta->findInt32(kKeyBitRate, &bitrate)) { 610b841f14f8e51f2365945281fbfa54ef6a1b1b5a6Andreas Huber // bitrate is in bits/sec. 61120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber LOGI("no bitrate"); 61220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 61320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_UNSUPPORTED; 61420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 61520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 61620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentTimeUs = seekTimeUs; 617ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang // interpolate in TOC to get file seek point in bytes 618ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang int64_t duration; 619ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if ((mByteNumber > 0) && (mTableOfContents[0] > 0) 620ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang && mMeta->findInt64(kKeyDuration, &duration)) { 621ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang float percent = (float)seekTimeUs * 100 / duration; 622ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang float fx; 623ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if( percent <= 0.0f ) { 624ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang fx = 0.0f; 625ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } else if( percent >= 100.0f ) { 626ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang fx = 256.0f; 627ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } else { 628ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang int a = (int)percent; 629ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang float fa, fb; 630ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if ( a == 0 ) { 631ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang fa = 0.0f; 632ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } else { 633ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang fa = (float)mTableOfContents[a-1]; 634ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 635ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang if ( a < 99 ) { 636ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang fb = (float)mTableOfContents[a]; 637ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } else { 638ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang fb = 256.0f; 639ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 640ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang fx = fa + (fb-fa)*(percent-a); 641ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 642ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang mCurrentPos = mFirstFramePos + (int)((1.0f/256.0f)*fx*mByteNumber); 643ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } else { 644ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang mCurrentPos = mFirstFramePos + seekTimeUs * bitrate / 8000000; 645ac6e6569f08911df9d5c96285cf15325cbbf0340Gloria Wang } 64620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 64720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 64820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer *buffer; 64920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = mGroup->acquire_buffer(&buffer); 65020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 65120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 65220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 65320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 65420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t frame_size; 65520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (;;) { 65634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber ssize_t n = mDataSource->readAt(mCurrentPos, buffer->data(), 4); 65720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n < 4) { 65820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber buffer->release(); 65920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber buffer = NULL; 66020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 66120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_END_OF_STREAM; 66220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 66320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 66420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t header = U32_AT((const uint8_t *)buffer->data()); 665541962997b4076da11546619f082467ffd9bcd1fAndreas Huber 666541962997b4076da11546619f082467ffd9bcd1fAndreas Huber if ((header & kMask) == (mFixedHeader & kMask) 667541962997b4076da11546619f082467ffd9bcd1fAndreas Huber && get_mp3_frame_size(header, &frame_size)) { 66820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 66920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 67020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 67120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Lost sync. 672fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber LOGV("lost sync!\n"); 67320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 67420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t pos = mCurrentPos; 67520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (!Resync(mDataSource, mFixedHeader, &pos, NULL)) { 67620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber LOGE("Unable to resync. Signalling end of stream."); 67720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 67820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber buffer->release(); 67920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber buffer = NULL; 68020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 68120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_END_OF_STREAM; 68220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 68320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 68420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentPos = pos; 68520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 68620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Try again with the new position. 68720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 68820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6890c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK(frame_size <= buffer->size()); 69020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 69134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber ssize_t n = mDataSource->readAt(mCurrentPos, buffer->data(), frame_size); 69220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n < (ssize_t)frame_size) { 69320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber buffer->release(); 69420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber buffer = NULL; 69520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 69620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_END_OF_STREAM; 69720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 69820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 69920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber buffer->set_range(0, frame_size); 70020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 70148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber buffer->meta_data()->setInt64(kKeyTime, mCurrentTimeUs); 70220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 70320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentPos += frame_size; 70420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentTimeUs += 1152 * 1000000 / 44100; 70520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 70620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = buffer; 70720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 70820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 70920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 71020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 711fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubersp<MetaData> MP3Extractor::getMetaData() { 712fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber sp<MetaData> meta = new MetaData; 713fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 714fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber meta->setCString(kKeyMIMEType, "audio/mpeg"); 715fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 716fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber ID3 id3(mDataSource); 717fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 718fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!id3.isValid()) { 719fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return meta; 720fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 721fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 722fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber struct Map { 723fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber int key; 724fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber const char *tag1; 725fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber const char *tag2; 726fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber }; 727fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber static const Map kMap[] = { 728fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber { kKeyAlbum, "TALB", "TAL" }, 729fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber { kKeyArtist, "TPE1", "TP1" }, 730fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber { kKeyComposer, "TCOM", "TCM" }, 731fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber { kKeyGenre, "TCON", "TCO" }, 732fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber { kKeyTitle, "TALB", "TAL" }, 733fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber { kKeyYear, "TYE", "TYER" }, 734fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber }; 735fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]); 736fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 737fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber for (size_t i = 0; i < kNumMapEntries; ++i) { 738fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber ID3::Iterator *it = new ID3::Iterator(id3, kMap[i].tag1); 739fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (it->done()) { 740fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber delete it; 741fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber it = new ID3::Iterator(id3, kMap[i].tag2); 742fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 743fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 744fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (it->done()) { 745fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber delete it; 746fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber continue; 747fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 748fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 749fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber String8 s; 750fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber it->getString(&s); 751fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber delete it; 752fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 753fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber meta->setCString(kMap[i].key, s); 754fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 755fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 756fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t dataSize; 757fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber String8 mime; 758fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber const void *data = id3.getAlbumArt(&dataSize, &mime); 759fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 760fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (data) { 761fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber meta->setData(kKeyAlbumArt, MetaData::TYPE_NONE, data, dataSize); 762fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber meta->setCString(kKeyAlbumArtMIME, mime.string()); 763fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 764fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 765fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return meta; 766fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 767fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 768693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberbool SniffMP3( 769693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 77020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t pos = 0; 77120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t header; 77220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (!Resync(source, 0, &pos, &header)) { 77320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 77420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 77520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 77618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber *mimeType = MEDIA_MIMETYPE_AUDIO_MPEG; 77720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *confidence = 0.3f; 77820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 77920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return true; 78020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 78120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 783