MP3Extractor.cpp revision c8d6c8bdd84464e0c7e511241ede2299cf38fda4
1/* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17//#define LOG_NDEBUG 0 18#define LOG_TAG "MP3Extractor" 19#include <utils/Log.h> 20 21#undef NDEBUG 22#include <assert.h> 23 24#include <media/stagefright/DataSource.h> 25#include <media/stagefright/MP3Extractor.h> 26#include <media/stagefright/MediaBuffer.h> 27#include <media/stagefright/MediaBufferGroup.h> 28#include <media/stagefright/MediaErrors.h> 29#include <media/stagefright/MediaSource.h> 30#include <media/stagefright/MetaData.h> 31#include <media/stagefright/Utils.h> 32#include <utils/String8.h> 33 34namespace android { 35 36static bool get_mp3_frame_size( 37 uint32_t header, size_t *frame_size, 38 int *out_sampling_rate = NULL, int *out_channels = NULL, 39 int *out_bitrate = NULL) { 40 *frame_size = 0; 41 42 if (out_sampling_rate) { 43 *out_sampling_rate = 0; 44 } 45 46 if (out_channels) { 47 *out_channels = 0; 48 } 49 50 if (out_bitrate) { 51 *out_bitrate = 0; 52 } 53 54 if ((header & 0xffe00000) != 0xffe00000) { 55 return false; 56 } 57 58 unsigned version = (header >> 19) & 3; 59 60 if (version == 0x01) { 61 return false; 62 } 63 64 unsigned layer = (header >> 17) & 3; 65 66 if (layer == 0x00) { 67 return false; 68 } 69 70 unsigned protection = (header >> 16) & 1; 71 72 unsigned bitrate_index = (header >> 12) & 0x0f; 73 74 if (bitrate_index == 0 || bitrate_index == 0x0f) { 75 // Disallow "free" bitrate. 76 77 LOGE("We disallow 'free' bitrate for now."); 78 return false; 79 } 80 81 unsigned sampling_rate_index = (header >> 10) & 3; 82 83 if (sampling_rate_index == 3) { 84 return false; 85 } 86 87 static const int kSamplingRateV1[] = { 44100, 48000, 32000 }; 88 int sampling_rate = kSamplingRateV1[sampling_rate_index]; 89 if (version == 2 /* V2 */) { 90 sampling_rate /= 2; 91 } else if (version == 0 /* V2.5 */) { 92 sampling_rate /= 4; 93 } 94 95 unsigned padding = (header >> 9) & 1; 96 97 if (layer == 3) { 98 // layer I 99 100 static const int kBitrateV1[] = { 101 32, 64, 96, 128, 160, 192, 224, 256, 102 288, 320, 352, 384, 416, 448 103 }; 104 105 static const int kBitrateV2[] = { 106 32, 48, 56, 64, 80, 96, 112, 128, 107 144, 160, 176, 192, 224, 256 108 }; 109 110 int bitrate = 111 (version == 3 /* V1 */) 112 ? kBitrateV1[bitrate_index - 1] 113 : kBitrateV2[bitrate_index - 1]; 114 115 if (out_bitrate) { 116 *out_bitrate = bitrate; 117 } 118 119 *frame_size = (12000 * bitrate / sampling_rate + padding) * 4; 120 } else { 121 // layer II or III 122 123 static const int kBitrateV1L2[] = { 124 32, 48, 56, 64, 80, 96, 112, 128, 125 160, 192, 224, 256, 320, 384 126 }; 127 128 static const int kBitrateV1L3[] = { 129 32, 40, 48, 56, 64, 80, 96, 112, 130 128, 160, 192, 224, 256, 320 131 }; 132 133 static const int kBitrateV2[] = { 134 8, 16, 24, 32, 40, 48, 56, 64, 135 80, 96, 112, 128, 144, 160 136 }; 137 138 int bitrate; 139 if (version == 3 /* V1 */) { 140 bitrate = (layer == 2 /* L2 */) 141 ? kBitrateV1L2[bitrate_index - 1] 142 : kBitrateV1L3[bitrate_index - 1]; 143 } else { 144 // V2 (or 2.5) 145 146 bitrate = kBitrateV2[bitrate_index - 1]; 147 } 148 149 if (out_bitrate) { 150 *out_bitrate = bitrate; 151 } 152 153 *frame_size = 144000 * bitrate / sampling_rate + padding; 154 } 155 156 if (out_sampling_rate) { 157 *out_sampling_rate = sampling_rate; 158 } 159 160 if (out_channels) { 161 int channel_mode = (header >> 6) & 3; 162 163 *out_channels = (channel_mode == 3) ? 1 : 2; 164 } 165 166 return true; 167} 168 169static bool Resync( 170 DataSource *source, uint32_t match_header, 171 off_t *inout_pos, uint32_t *out_header) { 172 // Everything must match except for 173 // protection, bitrate, padding, private bits and mode extension. 174 const uint32_t kMask = 0xfffe0ccf; 175 176 const size_t kMaxFrameSize = 4096; 177 uint8_t *buffer = new uint8_t[kMaxFrameSize]; 178 179 off_t pos = *inout_pos - kMaxFrameSize; 180 size_t buffer_offset = kMaxFrameSize; 181 size_t buffer_length = kMaxFrameSize; 182 bool valid = false; 183 do { 184 if (buffer_offset + 3 >= buffer_length) { 185 if (buffer_length < kMaxFrameSize) { 186 break; 187 } 188 189 pos += buffer_offset; 190 191 if (pos >= *inout_pos + 128 * 1024) { 192 // Don't scan forever. 193 LOGV("giving up at offset %ld", pos); 194 break; 195 } 196 197 memmove(buffer, &buffer[buffer_offset], buffer_length - buffer_offset); 198 buffer_length = buffer_length - buffer_offset; 199 buffer_offset = 0; 200 201 ssize_t n = source->read_at( 202 pos, &buffer[buffer_length], kMaxFrameSize - buffer_length); 203 204 if (n <= 0) { 205 break; 206 } 207 208 buffer_length += (size_t)n; 209 210 continue; 211 } 212 213 uint32_t header = U32_AT(&buffer[buffer_offset]); 214 215 if (match_header != 0 && (header & kMask) != (match_header & kMask)) { 216 ++buffer_offset; 217 continue; 218 } 219 220 size_t frame_size; 221 int sample_rate, num_channels, bitrate; 222 if (!get_mp3_frame_size(header, &frame_size, 223 &sample_rate, &num_channels, &bitrate)) { 224 ++buffer_offset; 225 continue; 226 } 227 228 LOGV("found possible 1st frame at %ld", pos + buffer_offset); 229 230 // We found what looks like a valid frame, 231 // now find its successors. 232 233 off_t test_pos = pos + buffer_offset + frame_size; 234 235 valid = true; 236 for (int j = 0; j < 3; ++j) { 237 uint8_t tmp[4]; 238 if (source->read_at(test_pos, tmp, 4) < 4) { 239 valid = false; 240 break; 241 } 242 243 uint32_t test_header = U32_AT(tmp); 244 245 LOGV("subsequent header is %08x", test_header); 246 247 if ((test_header & kMask) != (header & kMask)) { 248 valid = false; 249 break; 250 } 251 252 size_t test_frame_size; 253 if (!get_mp3_frame_size(test_header, &test_frame_size)) { 254 valid = false; 255 break; 256 } 257 258 LOGV("found subsequent frame #%d at %ld", j + 2, test_pos); 259 260 test_pos += test_frame_size; 261 } 262 263 if (valid) { 264 *inout_pos = pos + buffer_offset; 265 266 if (out_header != NULL) { 267 *out_header = header; 268 } 269 } else { 270 LOGV("no dice, no valid sequence of frames found."); 271 } 272 273 ++buffer_offset; 274 275 } while (!valid); 276 277 delete[] buffer; 278 buffer = NULL; 279 280 return valid; 281} 282 283class MP3Source : public MediaSource { 284public: 285 MP3Source( 286 const sp<MetaData> &meta, DataSource *source, 287 off_t first_frame_pos, uint32_t fixed_header); 288 289 virtual ~MP3Source(); 290 291 virtual status_t start(MetaData *params = NULL); 292 virtual status_t stop(); 293 294 virtual sp<MetaData> getFormat(); 295 296 virtual status_t read( 297 MediaBuffer **buffer, const ReadOptions *options = NULL); 298 299private: 300 sp<MetaData> mMeta; 301 DataSource *mDataSource; 302 off_t mFirstFramePos; 303 uint32_t mFixedHeader; 304 off_t mCurrentPos; 305 int64_t mCurrentTimeUs; 306 bool mStarted; 307 308 MediaBufferGroup *mGroup; 309 310 MP3Source(const MP3Source &); 311 MP3Source &operator=(const MP3Source &); 312}; 313 314MP3Extractor::MP3Extractor(DataSource *source) 315 : mDataSource(source), 316 mFirstFramePos(-1), 317 mFixedHeader(0) { 318 off_t pos = 0; 319 uint32_t header; 320 bool success = Resync(mDataSource, 0, &pos, &header); 321 assert(success); 322 323 if (success) { 324 mFirstFramePos = pos; 325 mFixedHeader = header; 326 327 size_t frame_size; 328 int sample_rate; 329 int num_channels; 330 int bitrate; 331 get_mp3_frame_size( 332 header, &frame_size, &sample_rate, &num_channels, &bitrate); 333 334 mMeta = new MetaData; 335 336 mMeta->setCString(kKeyMIMEType, "audio/mpeg"); 337 mMeta->setInt32(kKeySampleRate, sample_rate); 338 mMeta->setInt32(kKeyBitRate, bitrate); 339 mMeta->setInt32(kKeyChannelCount, num_channels); 340 341 off_t fileSize; 342 if (mDataSource->getSize(&fileSize) == OK) { 343 mMeta->setInt32( 344 kKeyDuration, 345 8 * (fileSize - mFirstFramePos) / bitrate); 346 mMeta->setInt32(kKeyTimeScale, 1000); 347 } 348 } 349} 350 351MP3Extractor::~MP3Extractor() { 352 delete mDataSource; 353 mDataSource = NULL; 354} 355 356status_t MP3Extractor::countTracks(int *num_tracks) { 357 *num_tracks = mFirstFramePos < 0 ? 0 : 1; 358 359 return OK; 360} 361 362status_t MP3Extractor::getTrack(int index, MediaSource **source) { 363 if (mFirstFramePos < 0 || index != 0) { 364 return ERROR_OUT_OF_RANGE; 365 } 366 367 *source = new MP3Source( 368 mMeta, mDataSource, mFirstFramePos, mFixedHeader); 369 370 return OK; 371} 372 373sp<MetaData> MP3Extractor::getTrackMetaData(int index) { 374 if (mFirstFramePos < 0 || index != 0) { 375 return NULL; 376 } 377 378 return mMeta; 379} 380 381//////////////////////////////////////////////////////////////////////////////// 382 383MP3Source::MP3Source( 384 const sp<MetaData> &meta, DataSource *source, 385 off_t first_frame_pos, uint32_t fixed_header) 386 : mMeta(meta), 387 mDataSource(source), 388 mFirstFramePos(first_frame_pos), 389 mFixedHeader(fixed_header), 390 mCurrentPos(0), 391 mCurrentTimeUs(0), 392 mStarted(false), 393 mGroup(NULL) { 394} 395 396MP3Source::~MP3Source() { 397 if (mStarted) { 398 stop(); 399 } 400} 401 402status_t MP3Source::start(MetaData *) { 403 assert(!mStarted); 404 405 mGroup = new MediaBufferGroup; 406 407 const size_t kMaxFrameSize = 32768; 408 mGroup->add_buffer(new MediaBuffer(kMaxFrameSize)); 409 410 mCurrentPos = mFirstFramePos; 411 mCurrentTimeUs = 0; 412 413 mStarted = true; 414 415 return OK; 416} 417 418status_t MP3Source::stop() { 419 assert(mStarted); 420 421 delete mGroup; 422 mGroup = NULL; 423 424 mStarted = false; 425 426 return OK; 427} 428 429sp<MetaData> MP3Source::getFormat() { 430 return mMeta; 431} 432 433status_t MP3Source::read( 434 MediaBuffer **out, const ReadOptions *options) { 435 *out = NULL; 436 437 int64_t seekTimeUs; 438 if (options != NULL && options->getSeekTo(&seekTimeUs)) { 439 int32_t bitrate; 440 if (!mMeta->findInt32(kKeyBitRate, &bitrate)) { 441 // bitrate is in kbits/sec. 442 LOGI("no bitrate"); 443 444 return ERROR_UNSUPPORTED; 445 } 446 447 mCurrentTimeUs = seekTimeUs; 448 mCurrentPos = mFirstFramePos + seekTimeUs * bitrate / 1000000 * 125; 449 } 450 451 MediaBuffer *buffer; 452 status_t err = mGroup->acquire_buffer(&buffer); 453 if (err != OK) { 454 return err; 455 } 456 457 size_t frame_size; 458 for (;;) { 459 ssize_t n = mDataSource->read_at(mCurrentPos, buffer->data(), 4); 460 if (n < 4) { 461 buffer->release(); 462 buffer = NULL; 463 464 return ERROR_END_OF_STREAM; 465 } 466 467 uint32_t header = U32_AT((const uint8_t *)buffer->data()); 468 469 if (get_mp3_frame_size(header, &frame_size)) { 470 break; 471 } 472 473 // Lost sync. 474 LOGW("lost sync!\n"); 475 476 off_t pos = mCurrentPos; 477 if (!Resync(mDataSource, mFixedHeader, &pos, NULL)) { 478 LOGE("Unable to resync. Signalling end of stream."); 479 480 buffer->release(); 481 buffer = NULL; 482 483 return ERROR_END_OF_STREAM; 484 } 485 486 mCurrentPos = pos; 487 488 // Try again with the new position. 489 } 490 491 assert(frame_size <= buffer->size()); 492 493 ssize_t n = mDataSource->read_at(mCurrentPos, buffer->data(), frame_size); 494 if (n < (ssize_t)frame_size) { 495 buffer->release(); 496 buffer = NULL; 497 498 return ERROR_END_OF_STREAM; 499 } 500 501 buffer->set_range(0, frame_size); 502 503 buffer->meta_data()->setInt32(kKeyTimeUnits, mCurrentTimeUs / 1000); 504 buffer->meta_data()->setInt32(kKeyTimeScale, 1000); 505 506 mCurrentPos += frame_size; 507 mCurrentTimeUs += 1152 * 1000000 / 44100; 508 509 *out = buffer; 510 511 return OK; 512} 513 514bool SniffMP3(DataSource *source, String8 *mimeType, float *confidence) { 515 off_t pos = 0; 516 uint32_t header; 517 if (!Resync(source, 0, &pos, &header)) { 518 return false; 519 } 520 521 *mimeType = "audio/mpeg"; 522 *confidence = 0.3f; 523 524 return true; 525} 526 527} // namespace android 528