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