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