1 /* 2 * Copyright (C) 2012 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 "FragmentedMP4Parser" 19 #include <utils/Log.h> 20 21 #include "include/avc_utils.h" 22 #include "include/ESDS.h" 23 #include "include/FragmentedMP4Parser.h" 24 #include "TrackFragment.h" 25 26 27 #include <media/stagefright/foundation/ABuffer.h> 28 #include <media/stagefright/foundation/ADebug.h> 29 #include <media/stagefright/foundation/AMessage.h> 30 #include <media/stagefright/foundation/hexdump.h> 31 #include <media/stagefright/MediaDefs.h> 32 #include <media/stagefright/MediaErrors.h> 33 #include <media/stagefright/Utils.h> 34 35 36 namespace android { 37 38 static const char *Fourcc2String(uint32_t fourcc) { 39 static char buffer[5]; 40 buffer[4] = '\0'; 41 buffer[0] = fourcc >> 24; 42 buffer[1] = (fourcc >> 16) & 0xff; 43 buffer[2] = (fourcc >> 8) & 0xff; 44 buffer[3] = fourcc & 0xff; 45 46 return buffer; 47 } 48 49 static const char *IndentString(size_t n) { 50 static const char kSpace[] = " "; 51 return kSpace + sizeof(kSpace) - 2 * n - 1; 52 } 53 54 // static 55 const FragmentedMP4Parser::DispatchEntry FragmentedMP4Parser::kDispatchTable[] = { 56 { FOURCC('m', 'o', 'o', 'v'), 0, NULL }, 57 { FOURCC('t', 'r', 'a', 'k'), FOURCC('m', 'o', 'o', 'v'), NULL }, 58 { FOURCC('u', 'd', 't', 'a'), FOURCC('t', 'r', 'a', 'k'), NULL }, 59 { FOURCC('u', 'd', 't', 'a'), FOURCC('m', 'o', 'o', 'v'), NULL }, 60 { FOURCC('m', 'e', 't', 'a'), FOURCC('u', 'd', 't', 'a'), NULL }, 61 { FOURCC('i', 'l', 's', 't'), FOURCC('m', 'e', 't', 'a'), NULL }, 62 63 { FOURCC('t', 'k', 'h', 'd'), FOURCC('t', 'r', 'a', 'k'), 64 &FragmentedMP4Parser::parseTrackHeader 65 }, 66 67 { FOURCC('m', 'v', 'e', 'x'), FOURCC('m', 'o', 'o', 'v'), NULL }, 68 69 { FOURCC('t', 'r', 'e', 'x'), FOURCC('m', 'v', 'e', 'x'), 70 &FragmentedMP4Parser::parseTrackExtends 71 }, 72 73 { FOURCC('e', 'd', 't', 's'), FOURCC('t', 'r', 'a', 'k'), NULL }, 74 { FOURCC('m', 'd', 'i', 'a'), FOURCC('t', 'r', 'a', 'k'), NULL }, 75 76 { FOURCC('m', 'd', 'h', 'd'), FOURCC('m', 'd', 'i', 'a'), 77 &FragmentedMP4Parser::parseMediaHeader 78 }, 79 80 { FOURCC('h', 'd', 'l', 'r'), FOURCC('m', 'd', 'i', 'a'), 81 &FragmentedMP4Parser::parseMediaHandler 82 }, 83 84 { FOURCC('m', 'i', 'n', 'f'), FOURCC('m', 'd', 'i', 'a'), NULL }, 85 { FOURCC('d', 'i', 'n', 'f'), FOURCC('m', 'i', 'n', 'f'), NULL }, 86 { FOURCC('s', 't', 'b', 'l'), FOURCC('m', 'i', 'n', 'f'), NULL }, 87 { FOURCC('s', 't', 's', 'd'), FOURCC('s', 't', 'b', 'l'), NULL }, 88 89 { FOURCC('s', 't', 's', 'z'), FOURCC('s', 't', 'b', 'l'), 90 &FragmentedMP4Parser::parseSampleSizes }, 91 92 { FOURCC('s', 't', 'z', '2'), FOURCC('s', 't', 'b', 'l'), 93 &FragmentedMP4Parser::parseCompactSampleSizes }, 94 95 { FOURCC('s', 't', 's', 'c'), FOURCC('s', 't', 'b', 'l'), 96 &FragmentedMP4Parser::parseSampleToChunk }, 97 98 { FOURCC('s', 't', 'c', 'o'), FOURCC('s', 't', 'b', 'l'), 99 &FragmentedMP4Parser::parseChunkOffsets }, 100 101 { FOURCC('c', 'o', '6', '4'), FOURCC('s', 't', 'b', 'l'), 102 &FragmentedMP4Parser::parseChunkOffsets64 }, 103 104 { FOURCC('a', 'v', 'c', 'C'), FOURCC('a', 'v', 'c', '1'), 105 &FragmentedMP4Parser::parseAVCCodecSpecificData }, 106 107 { FOURCC('e', 's', 'd', 's'), FOURCC('m', 'p', '4', 'a'), 108 &FragmentedMP4Parser::parseESDSCodecSpecificData }, 109 110 { FOURCC('e', 's', 'd', 's'), FOURCC('m', 'p', '4', 'v'), 111 &FragmentedMP4Parser::parseESDSCodecSpecificData }, 112 113 { FOURCC('m', 'd', 'a', 't'), 0, &FragmentedMP4Parser::parseMediaData }, 114 115 { FOURCC('m', 'o', 'o', 'f'), 0, NULL }, 116 { FOURCC('t', 'r', 'a', 'f'), FOURCC('m', 'o', 'o', 'f'), NULL }, 117 118 { FOURCC('t', 'f', 'h', 'd'), FOURCC('t', 'r', 'a', 'f'), 119 &FragmentedMP4Parser::parseTrackFragmentHeader 120 }, 121 { FOURCC('t', 'r', 'u', 'n'), FOURCC('t', 'r', 'a', 'f'), 122 &FragmentedMP4Parser::parseTrackFragmentRun 123 }, 124 125 { FOURCC('m', 'f', 'r', 'a'), 0, NULL }, 126 127 { FOURCC('s', 'i', 'd', 'x'), 0, &FragmentedMP4Parser::parseSegmentIndex }, 128 }; 129 130 struct FileSource : public FragmentedMP4Parser::Source { 131 FileSource(const char *filename) 132 : mFile(fopen(filename, "rb")) { 133 CHECK(mFile != NULL); 134 } 135 136 virtual ~FileSource() { 137 fclose(mFile); 138 } 139 140 virtual ssize_t readAt(off64_t offset, void *data, size_t size) { 141 fseek(mFile, offset, SEEK_SET); 142 return fread(data, 1, size, mFile); 143 } 144 145 virtual bool isSeekable() { 146 return true; 147 } 148 149 private: 150 FILE *mFile; 151 152 DISALLOW_EVIL_CONSTRUCTORS(FileSource); 153 }; 154 155 struct ReadTracker : public RefBase { 156 ReadTracker(off64_t size) { 157 allocSize = 1 + size / 8192; // 1 bit per kilobyte 158 bitmap = (char*) calloc(1, allocSize); 159 } 160 virtual ~ReadTracker() { 161 dumpToLog(); 162 free(bitmap); 163 } 164 void mark(off64_t offset, size_t size) { 165 int firstbit = offset / 1024; 166 int lastbit = (offset + size - 1) / 1024; 167 for (int i = firstbit; i <= lastbit; i++) { 168 bitmap[i/8] |= (0x80 >> (i & 7)); 169 } 170 } 171 172 private: 173 void dumpToLog() { 174 // 96 chars per line, each char represents one kilobyte, 1 kb per bit 175 int numlines = allocSize / 12; 176 char buf[97]; 177 char *cur = bitmap; 178 for (int i = 0; i < numlines; i++ && cur) { 179 for (int j = 0; j < 12; j++) { 180 for (int k = 0; k < 8; k++) { 181 buf[(j * 8) + k] = (*cur & (0x80 >> k)) ? 'X' : '.'; 182 } 183 cur++; 184 } 185 buf[96] = '\0'; 186 ALOGI("%5dk: %s", i * 96, buf); 187 } 188 } 189 190 size_t allocSize; 191 char *bitmap; 192 }; 193 194 struct DataSourceSource : public FragmentedMP4Parser::Source { 195 DataSourceSource(sp<DataSource> &source) 196 : mDataSource(source) { 197 CHECK(mDataSource != NULL); 198 #if 0 199 off64_t size; 200 if (source->getSize(&size) == OK) { 201 mReadTracker = new ReadTracker(size); 202 } else { 203 ALOGE("couldn't get data source size"); 204 } 205 #endif 206 } 207 208 virtual ssize_t readAt(off64_t offset, void *data, size_t size) { 209 if (mReadTracker != NULL) { 210 mReadTracker->mark(offset, size); 211 } 212 return mDataSource->readAt(offset, data, size); 213 } 214 215 virtual bool isSeekable() { 216 return true; 217 } 218 219 private: 220 sp<DataSource> mDataSource; 221 sp<ReadTracker> mReadTracker; 222 223 DISALLOW_EVIL_CONSTRUCTORS(DataSourceSource); 224 }; 225 226 FragmentedMP4Parser::FragmentedMP4Parser() 227 : mBufferPos(0), 228 mSuspended(false), 229 mDoneWithMoov(false), 230 mFirstMoofOffset(0), 231 mFinalResult(OK) { 232 } 233 234 FragmentedMP4Parser::~FragmentedMP4Parser() { 235 } 236 237 void FragmentedMP4Parser::start(const char *filename) { 238 sp<AMessage> msg = new AMessage(kWhatStart, id()); 239 msg->setObject("source", new FileSource(filename)); 240 msg->post(); 241 ALOGV("Parser::start(%s)", filename); 242 } 243 244 void FragmentedMP4Parser::start(const sp<Source> &source) { 245 sp<AMessage> msg = new AMessage(kWhatStart, id()); 246 msg->setObject("source", source); 247 msg->post(); 248 ALOGV("Parser::start(Source)"); 249 } 250 251 void FragmentedMP4Parser::start(sp<DataSource> &source) { 252 sp<AMessage> msg = new AMessage(kWhatStart, id()); 253 msg->setObject("source", new DataSourceSource(source)); 254 msg->post(); 255 ALOGV("Parser::start(DataSource)"); 256 } 257 258 sp<AMessage> FragmentedMP4Parser::getFormat(bool audio, bool synchronous) { 259 260 while (true) { 261 bool moovDone = mDoneWithMoov; 262 sp<AMessage> msg = new AMessage(kWhatGetFormat, id()); 263 msg->setInt32("audio", audio); 264 265 sp<AMessage> response; 266 status_t err = msg->postAndAwaitResponse(&response); 267 268 if (err != OK) { 269 ALOGV("getFormat post failed: %d", err); 270 return NULL; 271 } 272 273 if (response->findInt32("err", &err) && err != OK) { 274 if (synchronous && err == -EWOULDBLOCK && !moovDone) { 275 resumeIfNecessary(); 276 ALOGV("@getFormat parser not ready yet, retrying"); 277 usleep(10000); 278 continue; 279 } 280 ALOGV("getFormat failed: %d", err); 281 return NULL; 282 } 283 284 sp<AMessage> format; 285 CHECK(response->findMessage("format", &format)); 286 287 ALOGV("returning format %s", format->debugString().c_str()); 288 return format; 289 } 290 } 291 292 status_t FragmentedMP4Parser::seekTo(bool wantAudio, int64_t timeUs) { 293 sp<AMessage> msg = new AMessage(kWhatSeekTo, id()); 294 msg->setInt32("audio", wantAudio); 295 msg->setInt64("position", timeUs); 296 297 sp<AMessage> response; 298 status_t err = msg->postAndAwaitResponse(&response); 299 return err; 300 } 301 302 bool FragmentedMP4Parser::isSeekable() const { 303 while (mFirstMoofOffset == 0 && mFinalResult == OK) { 304 usleep(10000); 305 } 306 bool seekable = mSource->isSeekable(); 307 for (size_t i = 0; seekable && i < mTracks.size(); i++) { 308 const TrackInfo *info = &mTracks.valueAt(i); 309 seekable &= !info->mSidx.empty(); 310 } 311 return seekable; 312 } 313 314 status_t FragmentedMP4Parser::onSeekTo(bool wantAudio, int64_t position) { 315 status_t err = -EINVAL; 316 ssize_t trackIndex = findTrack(wantAudio); 317 if (trackIndex < 0) { 318 err = trackIndex; 319 } else { 320 TrackInfo *info = &mTracks.editValueAt(trackIndex); 321 322 int numSidxEntries = info->mSidx.size(); 323 int64_t totalTime = 0; 324 off_t totalOffset = mFirstMoofOffset; 325 for (int i = 0; i < numSidxEntries; i++) { 326 const SidxEntry *se = &info->mSidx[i]; 327 if (totalTime + se->mDurationUs > position) { 328 mBuffer->setRange(0,0); 329 mBufferPos = totalOffset; 330 if (mFinalResult == ERROR_END_OF_STREAM) { 331 mFinalResult = OK; 332 mSuspended = true; // force resume 333 resumeIfNecessary(); 334 } 335 info->mFragments.clear(); 336 info->mDecodingTime = totalTime * info->mMediaTimeScale / 1000000ll; 337 return OK; 338 } 339 totalTime += se->mDurationUs; 340 totalOffset += se->mSize; 341 } 342 } 343 ALOGV("seekTo out of range"); 344 return err; 345 } 346 347 status_t FragmentedMP4Parser::dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit, 348 bool synchronous) { 349 350 while (true) { 351 sp<AMessage> msg = new AMessage(kWhatDequeueAccessUnit, id()); 352 msg->setInt32("audio", audio); 353 354 sp<AMessage> response; 355 status_t err = msg->postAndAwaitResponse(&response); 356 357 if (err != OK) { 358 ALOGV("dequeue fail 1: %d", err); 359 return err; 360 } 361 362 if (response->findInt32("err", &err) && err != OK) { 363 if (synchronous && err == -EWOULDBLOCK) { 364 resumeIfNecessary(); 365 ALOGV("Parser not ready yet, retrying"); 366 usleep(10000); 367 continue; 368 } 369 ALOGV("dequeue fail 2: %d, %d", err, synchronous); 370 return err; 371 } 372 373 CHECK(response->findBuffer("accessUnit", accessUnit)); 374 375 return OK; 376 } 377 } 378 379 ssize_t FragmentedMP4Parser::findTrack(bool wantAudio) const { 380 for (size_t i = 0; i < mTracks.size(); ++i) { 381 const TrackInfo *info = &mTracks.valueAt(i); 382 383 bool isAudio = 384 info->mMediaHandlerType == FOURCC('s', 'o', 'u', 'n'); 385 386 bool isVideo = 387 info->mMediaHandlerType == FOURCC('v', 'i', 'd', 'e'); 388 389 if ((wantAudio && isAudio) || (!wantAudio && !isAudio)) { 390 if (info->mSampleDescs.empty()) { 391 break; 392 } 393 394 return i; 395 } 396 } 397 398 return -EWOULDBLOCK; 399 } 400 401 void FragmentedMP4Parser::onMessageReceived(const sp<AMessage> &msg) { 402 switch (msg->what()) { 403 case kWhatStart: 404 { 405 sp<RefBase> obj; 406 CHECK(msg->findObject("source", &obj)); 407 408 mSource = static_cast<Source *>(obj.get()); 409 410 mBuffer = new ABuffer(512 * 1024); 411 mBuffer->setRange(0, 0); 412 413 enter(0ll, 0, 0); 414 415 (new AMessage(kWhatProceed, id()))->post(); 416 break; 417 } 418 419 case kWhatProceed: 420 { 421 CHECK(!mSuspended); 422 423 status_t err = onProceed(); 424 425 if (err == OK) { 426 if (!mSuspended) { 427 msg->post(); 428 } 429 } else if (err != -EAGAIN) { 430 ALOGE("onProceed returned error %d", err); 431 } 432 433 break; 434 } 435 436 case kWhatReadMore: 437 { 438 size_t needed; 439 CHECK(msg->findSize("needed", &needed)); 440 441 memmove(mBuffer->base(), mBuffer->data(), mBuffer->size()); 442 mBufferPos += mBuffer->offset(); 443 mBuffer->setRange(0, mBuffer->size()); 444 445 size_t maxBytesToRead = mBuffer->capacity() - mBuffer->size(); 446 447 if (maxBytesToRead < needed) { 448 ALOGV("resizing buffer."); 449 450 sp<ABuffer> newBuffer = 451 new ABuffer((mBuffer->size() + needed + 1023) & ~1023); 452 memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size()); 453 newBuffer->setRange(0, mBuffer->size()); 454 455 mBuffer = newBuffer; 456 maxBytesToRead = mBuffer->capacity() - mBuffer->size(); 457 } 458 459 CHECK_GE(maxBytesToRead, needed); 460 461 ssize_t n = mSource->readAt( 462 mBufferPos + mBuffer->size(), 463 mBuffer->data() + mBuffer->size(), needed); 464 465 if (n < (ssize_t)needed) { 466 ALOGV("Reached EOF when reading %d @ %d + %d", needed, mBufferPos, mBuffer->size()); 467 if (n < 0) { 468 mFinalResult = n; 469 } else if (n == 0) { 470 mFinalResult = ERROR_END_OF_STREAM; 471 } else { 472 mFinalResult = ERROR_IO; 473 } 474 } else { 475 mBuffer->setRange(0, mBuffer->size() + n); 476 (new AMessage(kWhatProceed, id()))->post(); 477 } 478 479 break; 480 } 481 482 case kWhatGetFormat: 483 { 484 int32_t wantAudio; 485 CHECK(msg->findInt32("audio", &wantAudio)); 486 487 status_t err = -EWOULDBLOCK; 488 sp<AMessage> response = new AMessage; 489 490 ssize_t trackIndex = findTrack(wantAudio); 491 492 if (trackIndex < 0) { 493 err = trackIndex; 494 } else { 495 TrackInfo *info = &mTracks.editValueAt(trackIndex); 496 497 sp<AMessage> format = info->mSampleDescs.itemAt(0).mFormat; 498 if (info->mSidxDuration) { 499 format->setInt64("durationUs", info->mSidxDuration); 500 } else { 501 // this is probably going to be zero. Oh well... 502 format->setInt64("durationUs", 503 1000000ll * info->mDuration / info->mMediaTimeScale); 504 } 505 response->setMessage( 506 "format", format); 507 508 err = OK; 509 } 510 511 response->setInt32("err", err); 512 513 uint32_t replyID; 514 CHECK(msg->senderAwaitsResponse(&replyID)); 515 516 response->postReply(replyID); 517 break; 518 } 519 520 case kWhatDequeueAccessUnit: 521 { 522 int32_t wantAudio; 523 CHECK(msg->findInt32("audio", &wantAudio)); 524 525 status_t err = -EWOULDBLOCK; 526 sp<AMessage> response = new AMessage; 527 528 ssize_t trackIndex = findTrack(wantAudio); 529 530 if (trackIndex < 0) { 531 err = trackIndex; 532 } else { 533 sp<ABuffer> accessUnit; 534 err = onDequeueAccessUnit(trackIndex, &accessUnit); 535 536 if (err == OK) { 537 response->setBuffer("accessUnit", accessUnit); 538 } 539 } 540 541 response->setInt32("err", err); 542 543 uint32_t replyID; 544 CHECK(msg->senderAwaitsResponse(&replyID)); 545 546 response->postReply(replyID); 547 break; 548 } 549 550 case kWhatSeekTo: 551 { 552 ALOGV("kWhatSeekTo"); 553 int32_t wantAudio; 554 CHECK(msg->findInt32("audio", &wantAudio)); 555 int64_t position; 556 CHECK(msg->findInt64("position", &position)); 557 558 status_t err = -EWOULDBLOCK; 559 sp<AMessage> response = new AMessage; 560 561 ssize_t trackIndex = findTrack(wantAudio); 562 563 if (trackIndex < 0) { 564 err = trackIndex; 565 } else { 566 err = onSeekTo(wantAudio, position); 567 } 568 response->setInt32("err", err); 569 uint32_t replyID; 570 CHECK(msg->senderAwaitsResponse(&replyID)); 571 response->postReply(replyID); 572 break; 573 } 574 default: 575 TRESPASS(); 576 } 577 } 578 579 status_t FragmentedMP4Parser::onProceed() { 580 status_t err; 581 582 if ((err = need(8)) != OK) { 583 return err; 584 } 585 586 uint64_t size = readU32(0); 587 uint32_t type = readU32(4); 588 589 size_t offset = 8; 590 591 if (size == 1) { 592 if ((err = need(16)) != OK) { 593 return err; 594 } 595 596 size = readU64(offset); 597 offset += 8; 598 } 599 600 uint8_t userType[16]; 601 602 if (type == FOURCC('u', 'u', 'i', 'd')) { 603 if ((err = need(offset + 16)) != OK) { 604 return err; 605 } 606 607 memcpy(userType, mBuffer->data() + offset, 16); 608 offset += 16; 609 } 610 611 CHECK(!mStack.isEmpty()); 612 uint32_t ptype = mStack.itemAt(mStack.size() - 1).mType; 613 614 static const size_t kNumDispatchers = 615 sizeof(kDispatchTable) / sizeof(kDispatchTable[0]); 616 617 size_t i; 618 for (i = 0; i < kNumDispatchers; ++i) { 619 if (kDispatchTable[i].mType == type 620 && kDispatchTable[i].mParentType == ptype) { 621 break; 622 } 623 } 624 625 // SampleEntry boxes are container boxes that start with a variable 626 // amount of data depending on the media handler type. 627 // We don't look inside 'hint' type SampleEntry boxes. 628 629 bool isSampleEntryBox = 630 (ptype == FOURCC('s', 't', 's', 'd')) 631 && editTrack(mCurrentTrackID)->mMediaHandlerType 632 != FOURCC('h', 'i', 'n', 't'); 633 634 if ((i < kNumDispatchers && kDispatchTable[i].mHandler == 0) 635 || isSampleEntryBox || ptype == FOURCC('i', 'l', 's', 't')) { 636 // This is a container box. 637 if (type == FOURCC('m', 'o', 'o', 'f')) { 638 if (mFirstMoofOffset == 0) { 639 ALOGV("first moof @ %08x", mBufferPos + offset); 640 mFirstMoofOffset = mBufferPos + offset - 8; // point at the size 641 } 642 } 643 if (type == FOURCC('m', 'e', 't', 'a')) { 644 if ((err = need(offset + 4)) < OK) { 645 return err; 646 } 647 648 if (readU32(offset) != 0) { 649 return -EINVAL; 650 } 651 652 offset += 4; 653 } else if (type == FOURCC('s', 't', 's', 'd')) { 654 if ((err = need(offset + 8)) < OK) { 655 return err; 656 } 657 658 if (readU32(offset) != 0) { 659 return -EINVAL; 660 } 661 662 if (readU32(offset + 4) == 0) { 663 // We need at least some entries. 664 return -EINVAL; 665 } 666 667 offset += 8; 668 } else if (isSampleEntryBox) { 669 size_t headerSize; 670 671 switch (editTrack(mCurrentTrackID)->mMediaHandlerType) { 672 case FOURCC('v', 'i', 'd', 'e'): 673 { 674 // 8 bytes SampleEntry + 70 bytes VisualSampleEntry 675 headerSize = 78; 676 break; 677 } 678 679 case FOURCC('s', 'o', 'u', 'n'): 680 { 681 // 8 bytes SampleEntry + 20 bytes AudioSampleEntry 682 headerSize = 28; 683 break; 684 } 685 686 case FOURCC('m', 'e', 't', 'a'): 687 { 688 headerSize = 8; // 8 bytes SampleEntry 689 break; 690 } 691 692 default: 693 TRESPASS(); 694 } 695 696 if (offset + headerSize > size) { 697 return -EINVAL; 698 } 699 700 if ((err = need(offset + headerSize)) != OK) { 701 return err; 702 } 703 704 switch (editTrack(mCurrentTrackID)->mMediaHandlerType) { 705 case FOURCC('v', 'i', 'd', 'e'): 706 { 707 err = parseVisualSampleEntry( 708 type, offset, offset + headerSize); 709 break; 710 } 711 712 case FOURCC('s', 'o', 'u', 'n'): 713 { 714 err = parseAudioSampleEntry( 715 type, offset, offset + headerSize); 716 break; 717 } 718 719 case FOURCC('m', 'e', 't', 'a'): 720 { 721 err = OK; 722 break; 723 } 724 725 default: 726 TRESPASS(); 727 } 728 729 if (err != OK) { 730 return err; 731 } 732 733 offset += headerSize; 734 } 735 736 skip(offset); 737 738 ALOGV("%sentering box of type '%s'", 739 IndentString(mStack.size()), Fourcc2String(type)); 740 741 enter(mBufferPos - offset, type, size - offset); 742 } else { 743 if (!fitsContainer(size)) { 744 return -EINVAL; 745 } 746 747 if (i < kNumDispatchers && kDispatchTable[i].mHandler != 0) { 748 // We have a handler for this box type. 749 750 if ((err = need(size)) != OK) { 751 return err; 752 } 753 754 ALOGV("%sparsing box of type '%s'", 755 IndentString(mStack.size()), Fourcc2String(type)); 756 757 if ((err = (this->*kDispatchTable[i].mHandler)( 758 type, offset, size)) != OK) { 759 return err; 760 } 761 } else { 762 // Unknown box type 763 764 ALOGV("%sskipping box of type '%s', size %llu", 765 IndentString(mStack.size()), 766 Fourcc2String(type), size); 767 768 } 769 770 skip(size); 771 } 772 773 return OK; 774 } 775 776 // static 777 int FragmentedMP4Parser::CompareSampleLocation( 778 const SampleInfo &sample, const MediaDataInfo &mdatInfo) { 779 if (sample.mOffset + sample.mSize < mdatInfo.mOffset) { 780 return -1; 781 } 782 783 if (sample.mOffset >= mdatInfo.mOffset + mdatInfo.mBuffer->size()) { 784 return 1; 785 } 786 787 // Otherwise make sure the sample is completely contained within this 788 // media data block. 789 790 CHECK_GE(sample.mOffset, mdatInfo.mOffset); 791 792 CHECK_LE(sample.mOffset + sample.mSize, 793 mdatInfo.mOffset + mdatInfo.mBuffer->size()); 794 795 return 0; 796 } 797 798 void FragmentedMP4Parser::resumeIfNecessary() { 799 if (!mSuspended) { 800 return; 801 } 802 803 ALOGV("resuming."); 804 805 mSuspended = false; 806 (new AMessage(kWhatProceed, id()))->post(); 807 } 808 809 status_t FragmentedMP4Parser::getSample( 810 TrackInfo *info, sp<TrackFragment> *fragment, SampleInfo *sampleInfo) { 811 for (;;) { 812 if (info->mFragments.empty()) { 813 if (mFinalResult != OK) { 814 return mFinalResult; 815 } 816 817 resumeIfNecessary(); 818 return -EWOULDBLOCK; 819 } 820 821 *fragment = *info->mFragments.begin(); 822 823 status_t err = (*fragment)->getSample(sampleInfo); 824 825 if (err == OK) { 826 return OK; 827 } else if (err != ERROR_END_OF_STREAM) { 828 return err; 829 } 830 831 // Really, end of this fragment... 832 833 info->mFragments.erase(info->mFragments.begin()); 834 } 835 } 836 837 status_t FragmentedMP4Parser::onDequeueAccessUnit( 838 size_t trackIndex, sp<ABuffer> *accessUnit) { 839 TrackInfo *info = &mTracks.editValueAt(trackIndex); 840 841 sp<TrackFragment> fragment; 842 SampleInfo sampleInfo; 843 status_t err = getSample(info, &fragment, &sampleInfo); 844 845 if (err == -EWOULDBLOCK) { 846 resumeIfNecessary(); 847 return err; 848 } else if (err != OK) { 849 return err; 850 } 851 852 err = -EWOULDBLOCK; 853 854 bool checkDroppable = false; 855 856 for (size_t i = 0; i < mMediaData.size(); ++i) { 857 const MediaDataInfo &mdatInfo = mMediaData.itemAt(i); 858 859 int cmp = CompareSampleLocation(sampleInfo, mdatInfo); 860 861 if (cmp < 0 && !mSource->isSeekable()) { 862 return -EPIPE; 863 } else if (cmp == 0) { 864 if (i > 0) { 865 checkDroppable = true; 866 } 867 868 err = makeAccessUnit(info, sampleInfo, mdatInfo, accessUnit); 869 break; 870 } 871 } 872 873 if (err != OK) { 874 return err; 875 } 876 877 fragment->advance(); 878 879 if (!mMediaData.empty() && checkDroppable) { 880 size_t numDroppable = 0; 881 bool done = false; 882 883 // XXX FIXME: if one of the tracks is not advanced (e.g. if you play an audio+video 884 // file with sf2), then mMediaData will not be pruned and keeps growing 885 for (size_t i = 0; !done && i < mMediaData.size(); ++i) { 886 const MediaDataInfo &mdatInfo = mMediaData.itemAt(i); 887 888 for (size_t j = 0; j < mTracks.size(); ++j) { 889 TrackInfo *info = &mTracks.editValueAt(j); 890 891 sp<TrackFragment> fragment; 892 SampleInfo sampleInfo; 893 err = getSample(info, &fragment, &sampleInfo); 894 895 if (err != OK) { 896 done = true; 897 break; 898 } 899 900 int cmp = CompareSampleLocation(sampleInfo, mdatInfo); 901 902 if (cmp <= 0) { 903 done = true; 904 break; 905 } 906 } 907 908 if (!done) { 909 ++numDroppable; 910 } 911 } 912 913 if (numDroppable > 0) { 914 mMediaData.removeItemsAt(0, numDroppable); 915 916 if (mMediaData.size() < 5) { 917 resumeIfNecessary(); 918 } 919 } 920 } 921 922 return err; 923 } 924 925 static size_t parseNALSize(size_t nalLengthSize, const uint8_t *data) { 926 switch (nalLengthSize) { 927 case 1: 928 return *data; 929 case 2: 930 return U16_AT(data); 931 case 3: 932 return ((size_t)data[0] << 16) | U16_AT(&data[1]); 933 case 4: 934 return U32_AT(data); 935 } 936 937 // This cannot happen, mNALLengthSize springs to life by adding 1 to 938 // a 2-bit integer. 939 TRESPASS(); 940 941 return 0; 942 } 943 944 status_t FragmentedMP4Parser::makeAccessUnit( 945 TrackInfo *info, 946 const SampleInfo &sample, 947 const MediaDataInfo &mdatInfo, 948 sp<ABuffer> *accessUnit) { 949 if (sample.mSampleDescIndex < 1 950 || sample.mSampleDescIndex > info->mSampleDescs.size()) { 951 return ERROR_MALFORMED; 952 } 953 954 int64_t presentationTimeUs = 955 1000000ll * sample.mPresentationTime / info->mMediaTimeScale; 956 957 const SampleDescription &sampleDesc = 958 info->mSampleDescs.itemAt(sample.mSampleDescIndex - 1); 959 960 size_t nalLengthSize; 961 if (!sampleDesc.mFormat->findSize("nal-length-size", &nalLengthSize)) { 962 *accessUnit = new ABuffer(sample.mSize); 963 964 memcpy((*accessUnit)->data(), 965 mdatInfo.mBuffer->data() + (sample.mOffset - mdatInfo.mOffset), 966 sample.mSize); 967 968 (*accessUnit)->meta()->setInt64("timeUs", presentationTimeUs); 969 if (IsIDR(*accessUnit)) { 970 (*accessUnit)->meta()->setInt32("is-sync-frame", 1); 971 } 972 973 return OK; 974 } 975 976 const uint8_t *srcPtr = 977 mdatInfo.mBuffer->data() + (sample.mOffset - mdatInfo.mOffset); 978 979 for (int i = 0; i < 2 ; ++i) { 980 size_t srcOffset = 0; 981 size_t dstOffset = 0; 982 983 while (srcOffset < sample.mSize) { 984 if (srcOffset + nalLengthSize > sample.mSize) { 985 return ERROR_MALFORMED; 986 } 987 988 size_t nalSize = parseNALSize(nalLengthSize, &srcPtr[srcOffset]); 989 srcOffset += nalLengthSize; 990 991 if (srcOffset + nalSize > sample.mSize) { 992 return ERROR_MALFORMED; 993 } 994 995 if (i == 1) { 996 memcpy((*accessUnit)->data() + dstOffset, 997 "\x00\x00\x00\x01", 998 4); 999 1000 memcpy((*accessUnit)->data() + dstOffset + 4, 1001 srcPtr + srcOffset, 1002 nalSize); 1003 } 1004 1005 srcOffset += nalSize; 1006 dstOffset += nalSize + 4; 1007 } 1008 1009 if (i == 0) { 1010 (*accessUnit) = new ABuffer(dstOffset); 1011 (*accessUnit)->meta()->setInt64( 1012 "timeUs", presentationTimeUs); 1013 } 1014 } 1015 if (IsIDR(*accessUnit)) { 1016 (*accessUnit)->meta()->setInt32("is-sync-frame", 1); 1017 } 1018 1019 return OK; 1020 } 1021 1022 status_t FragmentedMP4Parser::need(size_t size) { 1023 if (!fitsContainer(size)) { 1024 return -EINVAL; 1025 } 1026 1027 if (size <= mBuffer->size()) { 1028 return OK; 1029 } 1030 1031 sp<AMessage> msg = new AMessage(kWhatReadMore, id()); 1032 msg->setSize("needed", size - mBuffer->size()); 1033 msg->post(); 1034 1035 // ALOGV("need(%d) returning -EAGAIN, only have %d", size, mBuffer->size()); 1036 1037 return -EAGAIN; 1038 } 1039 1040 void FragmentedMP4Parser::enter(off64_t offset, uint32_t type, uint64_t size) { 1041 Container container; 1042 container.mOffset = offset; 1043 container.mType = type; 1044 container.mExtendsToEOF = (size == 0); 1045 container.mBytesRemaining = size; 1046 1047 mStack.push(container); 1048 } 1049 1050 bool FragmentedMP4Parser::fitsContainer(uint64_t size) const { 1051 CHECK(!mStack.isEmpty()); 1052 const Container &container = mStack.itemAt(mStack.size() - 1); 1053 1054 return container.mExtendsToEOF || size <= container.mBytesRemaining; 1055 } 1056 1057 uint16_t FragmentedMP4Parser::readU16(size_t offset) { 1058 CHECK_LE(offset + 2, mBuffer->size()); 1059 1060 const uint8_t *ptr = mBuffer->data() + offset; 1061 return (ptr[0] << 8) | ptr[1]; 1062 } 1063 1064 uint32_t FragmentedMP4Parser::readU32(size_t offset) { 1065 CHECK_LE(offset + 4, mBuffer->size()); 1066 1067 const uint8_t *ptr = mBuffer->data() + offset; 1068 return (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3]; 1069 } 1070 1071 uint64_t FragmentedMP4Parser::readU64(size_t offset) { 1072 return (((uint64_t)readU32(offset)) << 32) | readU32(offset + 4); 1073 } 1074 1075 void FragmentedMP4Parser::skip(off_t distance) { 1076 CHECK(!mStack.isEmpty()); 1077 for (size_t i = mStack.size(); i-- > 0;) { 1078 Container *container = &mStack.editItemAt(i); 1079 if (!container->mExtendsToEOF) { 1080 CHECK_LE(distance, (off_t)container->mBytesRemaining); 1081 1082 container->mBytesRemaining -= distance; 1083 1084 if (container->mBytesRemaining == 0) { 1085 ALOGV("%sleaving box of type '%s'", 1086 IndentString(mStack.size() - 1), 1087 Fourcc2String(container->mType)); 1088 1089 #if 0 1090 if (container->mType == FOURCC('s', 't', 's', 'd')) { 1091 TrackInfo *trackInfo = editTrack(mCurrentTrackID); 1092 for (size_t i = 0; 1093 i < trackInfo->mSampleDescs.size(); ++i) { 1094 ALOGI("format #%d: %s", 1095 i, 1096 trackInfo->mSampleDescs.itemAt(i) 1097 .mFormat->debugString().c_str()); 1098 } 1099 } 1100 #endif 1101 1102 if (container->mType == FOURCC('s', 't', 'b', 'l')) { 1103 TrackInfo *trackInfo = editTrack(mCurrentTrackID); 1104 1105 trackInfo->mStaticFragment->signalCompletion(); 1106 1107 CHECK(trackInfo->mFragments.empty()); 1108 trackInfo->mFragments.push_back(trackInfo->mStaticFragment); 1109 trackInfo->mStaticFragment.clear(); 1110 } else if (container->mType == FOURCC('t', 'r', 'a', 'f')) { 1111 TrackInfo *trackInfo = 1112 editTrack(mTrackFragmentHeaderInfo.mTrackID); 1113 1114 const sp<TrackFragment> &fragment = 1115 *--trackInfo->mFragments.end(); 1116 1117 static_cast<DynamicTrackFragment *>( 1118 fragment.get())->signalCompletion(); 1119 } else if (container->mType == FOURCC('m', 'o', 'o', 'v')) { 1120 mDoneWithMoov = true; 1121 } 1122 1123 container = NULL; 1124 mStack.removeItemsAt(i); 1125 } 1126 } 1127 } 1128 1129 if (distance < (off_t)mBuffer->size()) { 1130 mBuffer->setRange(mBuffer->offset() + distance, mBuffer->size() - distance); 1131 mBufferPos += distance; 1132 return; 1133 } 1134 1135 mBuffer->setRange(0, 0); 1136 mBufferPos += distance; 1137 } 1138 1139 status_t FragmentedMP4Parser::parseTrackHeader( 1140 uint32_t type, size_t offset, uint64_t size) { 1141 if (offset + 4 > size) { 1142 return -EINVAL; 1143 } 1144 1145 uint32_t flags = readU32(offset); 1146 1147 uint32_t version = flags >> 24; 1148 flags &= 0xffffff; 1149 1150 uint32_t trackID; 1151 uint64_t duration; 1152 1153 if (version == 1) { 1154 if (offset + 36 > size) { 1155 return -EINVAL; 1156 } 1157 1158 trackID = readU32(offset + 20); 1159 duration = readU64(offset + 28); 1160 1161 offset += 36; 1162 } else if (version == 0) { 1163 if (offset + 24 > size) { 1164 return -EINVAL; 1165 } 1166 1167 trackID = readU32(offset + 12); 1168 duration = readU32(offset + 20); 1169 1170 offset += 24; 1171 } else { 1172 return -EINVAL; 1173 } 1174 1175 TrackInfo *info = editTrack(trackID, true /* createIfNecessary */); 1176 info->mFlags = flags; 1177 info->mDuration = duration; 1178 if (info->mDuration == 0xffffffff) { 1179 // ffmpeg sets this to -1, which is incorrect. 1180 info->mDuration = 0; 1181 } 1182 1183 info->mStaticFragment = new StaticTrackFragment; 1184 1185 mCurrentTrackID = trackID; 1186 1187 return OK; 1188 } 1189 1190 status_t FragmentedMP4Parser::parseMediaHeader( 1191 uint32_t type, size_t offset, uint64_t size) { 1192 if (offset + 4 > size) { 1193 return -EINVAL; 1194 } 1195 1196 uint32_t versionAndFlags = readU32(offset); 1197 1198 if (versionAndFlags & 0xffffff) { 1199 return ERROR_MALFORMED; 1200 } 1201 1202 uint32_t version = versionAndFlags >> 24; 1203 1204 TrackInfo *info = editTrack(mCurrentTrackID); 1205 1206 if (version == 1) { 1207 if (offset + 4 + 32 > size) { 1208 return -EINVAL; 1209 } 1210 info->mMediaTimeScale = U32_AT(mBuffer->data() + offset + 20); 1211 } else if (version == 0) { 1212 if (offset + 4 + 20 > size) { 1213 return -EINVAL; 1214 } 1215 info->mMediaTimeScale = U32_AT(mBuffer->data() + offset + 12); 1216 } else { 1217 return ERROR_MALFORMED; 1218 } 1219 1220 return OK; 1221 } 1222 1223 status_t FragmentedMP4Parser::parseMediaHandler( 1224 uint32_t type, size_t offset, uint64_t size) { 1225 if (offset + 12 > size) { 1226 return -EINVAL; 1227 } 1228 1229 if (readU32(offset) != 0) { 1230 return -EINVAL; 1231 } 1232 1233 uint32_t handlerType = readU32(offset + 8); 1234 1235 switch (handlerType) { 1236 case FOURCC('v', 'i', 'd', 'e'): 1237 case FOURCC('s', 'o', 'u', 'n'): 1238 case FOURCC('h', 'i', 'n', 't'): 1239 case FOURCC('m', 'e', 't', 'a'): 1240 break; 1241 1242 default: 1243 return -EINVAL; 1244 } 1245 1246 editTrack(mCurrentTrackID)->mMediaHandlerType = handlerType; 1247 1248 return OK; 1249 } 1250 1251 status_t FragmentedMP4Parser::parseVisualSampleEntry( 1252 uint32_t type, size_t offset, uint64_t size) { 1253 if (offset + 78 > size) { 1254 return -EINVAL; 1255 } 1256 1257 TrackInfo *trackInfo = editTrack(mCurrentTrackID); 1258 1259 trackInfo->mSampleDescs.push(); 1260 SampleDescription *sampleDesc = 1261 &trackInfo->mSampleDescs.editItemAt( 1262 trackInfo->mSampleDescs.size() - 1); 1263 1264 sampleDesc->mType = type; 1265 sampleDesc->mDataRefIndex = readU16(offset + 6); 1266 1267 sp<AMessage> format = new AMessage; 1268 1269 switch (type) { 1270 case FOURCC('a', 'v', 'c', '1'): 1271 format->setString("mime", MEDIA_MIMETYPE_VIDEO_AVC); 1272 break; 1273 case FOURCC('m', 'p', '4', 'v'): 1274 format->setString("mime", MEDIA_MIMETYPE_VIDEO_MPEG4); 1275 break; 1276 case FOURCC('s', '2', '6', '3'): 1277 case FOURCC('h', '2', '6', '3'): 1278 case FOURCC('H', '2', '6', '3'): 1279 format->setString("mime", MEDIA_MIMETYPE_VIDEO_H263); 1280 break; 1281 default: 1282 format->setString("mime", "application/octet-stream"); 1283 break; 1284 } 1285 1286 format->setInt32("width", readU16(offset + 8 + 16)); 1287 format->setInt32("height", readU16(offset + 8 + 18)); 1288 1289 sampleDesc->mFormat = format; 1290 1291 return OK; 1292 } 1293 1294 status_t FragmentedMP4Parser::parseAudioSampleEntry( 1295 uint32_t type, size_t offset, uint64_t size) { 1296 if (offset + 28 > size) { 1297 return -EINVAL; 1298 } 1299 1300 TrackInfo *trackInfo = editTrack(mCurrentTrackID); 1301 1302 trackInfo->mSampleDescs.push(); 1303 SampleDescription *sampleDesc = 1304 &trackInfo->mSampleDescs.editItemAt( 1305 trackInfo->mSampleDescs.size() - 1); 1306 1307 sampleDesc->mType = type; 1308 sampleDesc->mDataRefIndex = readU16(offset + 6); 1309 1310 sp<AMessage> format = new AMessage; 1311 1312 format->setInt32("channel-count", readU16(offset + 8 + 8)); 1313 format->setInt32("sample-size", readU16(offset + 8 + 10)); 1314 format->setInt32("sample-rate", readU32(offset + 8 + 16) / 65536.0f); 1315 1316 switch (type) { 1317 case FOURCC('m', 'p', '4', 'a'): 1318 format->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC); 1319 break; 1320 1321 case FOURCC('s', 'a', 'm', 'r'): 1322 format->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB); 1323 format->setInt32("channel-count", 1); 1324 format->setInt32("sample-rate", 8000); 1325 break; 1326 1327 case FOURCC('s', 'a', 'w', 'b'): 1328 format->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB); 1329 format->setInt32("channel-count", 1); 1330 format->setInt32("sample-rate", 16000); 1331 break; 1332 default: 1333 format->setString("mime", "application/octet-stream"); 1334 break; 1335 } 1336 1337 sampleDesc->mFormat = format; 1338 1339 return OK; 1340 } 1341 1342 static void addCodecSpecificData( 1343 const sp<AMessage> &format, int32_t index, 1344 const void *data, size_t size, 1345 bool insertStartCode = false) { 1346 sp<ABuffer> csd = new ABuffer(insertStartCode ? size + 4 : size); 1347 1348 memcpy(csd->data() + (insertStartCode ? 4 : 0), data, size); 1349 1350 if (insertStartCode) { 1351 memcpy(csd->data(), "\x00\x00\x00\x01", 4); 1352 } 1353 1354 csd->meta()->setInt32("csd", true); 1355 csd->meta()->setInt64("timeUs", 0ll); 1356 1357 format->setBuffer(StringPrintf("csd-%d", index).c_str(), csd); 1358 } 1359 1360 status_t FragmentedMP4Parser::parseSampleSizes( 1361 uint32_t type, size_t offset, uint64_t size) { 1362 return editTrack(mCurrentTrackID)->mStaticFragment->parseSampleSizes( 1363 this, type, offset, size); 1364 } 1365 1366 status_t FragmentedMP4Parser::parseCompactSampleSizes( 1367 uint32_t type, size_t offset, uint64_t size) { 1368 return editTrack(mCurrentTrackID)->mStaticFragment->parseCompactSampleSizes( 1369 this, type, offset, size); 1370 } 1371 1372 status_t FragmentedMP4Parser::parseSampleToChunk( 1373 uint32_t type, size_t offset, uint64_t size) { 1374 return editTrack(mCurrentTrackID)->mStaticFragment->parseSampleToChunk( 1375 this, type, offset, size); 1376 } 1377 1378 status_t FragmentedMP4Parser::parseChunkOffsets( 1379 uint32_t type, size_t offset, uint64_t size) { 1380 return editTrack(mCurrentTrackID)->mStaticFragment->parseChunkOffsets( 1381 this, type, offset, size); 1382 } 1383 1384 status_t FragmentedMP4Parser::parseChunkOffsets64( 1385 uint32_t type, size_t offset, uint64_t size) { 1386 return editTrack(mCurrentTrackID)->mStaticFragment->parseChunkOffsets64( 1387 this, type, offset, size); 1388 } 1389 1390 status_t FragmentedMP4Parser::parseAVCCodecSpecificData( 1391 uint32_t type, size_t offset, uint64_t size) { 1392 TrackInfo *trackInfo = editTrack(mCurrentTrackID); 1393 1394 SampleDescription *sampleDesc = 1395 &trackInfo->mSampleDescs.editItemAt( 1396 trackInfo->mSampleDescs.size() - 1); 1397 1398 if (sampleDesc->mType != FOURCC('a', 'v', 'c', '1')) { 1399 return -EINVAL; 1400 } 1401 1402 const uint8_t *ptr = mBuffer->data() + offset; 1403 1404 size -= offset; 1405 offset = 0; 1406 1407 if (size < 7 || ptr[0] != 0x01) { 1408 return ERROR_MALFORMED; 1409 } 1410 1411 sampleDesc->mFormat->setSize("nal-length-size", 1 + (ptr[4] & 3)); 1412 1413 size_t numSPS = ptr[5] & 31; 1414 1415 ptr += 6; 1416 size -= 6; 1417 1418 for (size_t i = 0; i < numSPS; ++i) { 1419 if (size < 2) { 1420 return ERROR_MALFORMED; 1421 } 1422 1423 size_t length = U16_AT(ptr); 1424 1425 ptr += 2; 1426 size -= 2; 1427 1428 if (size < length) { 1429 return ERROR_MALFORMED; 1430 } 1431 1432 addCodecSpecificData( 1433 sampleDesc->mFormat, i, ptr, length, 1434 true /* insertStartCode */); 1435 1436 ptr += length; 1437 size -= length; 1438 } 1439 1440 if (size < 1) { 1441 return ERROR_MALFORMED; 1442 } 1443 1444 size_t numPPS = *ptr; 1445 ++ptr; 1446 --size; 1447 1448 for (size_t i = 0; i < numPPS; ++i) { 1449 if (size < 2) { 1450 return ERROR_MALFORMED; 1451 } 1452 1453 size_t length = U16_AT(ptr); 1454 1455 ptr += 2; 1456 size -= 2; 1457 1458 if (size < length) { 1459 return ERROR_MALFORMED; 1460 } 1461 1462 addCodecSpecificData( 1463 sampleDesc->mFormat, numSPS + i, ptr, length, 1464 true /* insertStartCode */); 1465 1466 ptr += length; 1467 size -= length; 1468 } 1469 1470 return OK; 1471 } 1472 1473 status_t FragmentedMP4Parser::parseESDSCodecSpecificData( 1474 uint32_t type, size_t offset, uint64_t size) { 1475 TrackInfo *trackInfo = editTrack(mCurrentTrackID); 1476 1477 SampleDescription *sampleDesc = 1478 &trackInfo->mSampleDescs.editItemAt( 1479 trackInfo->mSampleDescs.size() - 1); 1480 1481 if (sampleDesc->mType != FOURCC('m', 'p', '4', 'a') 1482 && sampleDesc->mType != FOURCC('m', 'p', '4', 'v')) { 1483 return -EINVAL; 1484 } 1485 1486 const uint8_t *ptr = mBuffer->data() + offset; 1487 1488 size -= offset; 1489 offset = 0; 1490 1491 if (size < 4) { 1492 return -EINVAL; 1493 } 1494 1495 if (U32_AT(ptr) != 0) { 1496 return -EINVAL; 1497 } 1498 1499 ptr += 4; 1500 size -=4; 1501 1502 ESDS esds(ptr, size); 1503 1504 uint8_t objectTypeIndication; 1505 if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) { 1506 return ERROR_MALFORMED; 1507 } 1508 1509 const uint8_t *csd; 1510 size_t csd_size; 1511 if (esds.getCodecSpecificInfo( 1512 (const void **)&csd, &csd_size) != OK) { 1513 return ERROR_MALFORMED; 1514 } 1515 1516 addCodecSpecificData(sampleDesc->mFormat, 0, csd, csd_size); 1517 1518 if (sampleDesc->mType != FOURCC('m', 'p', '4', 'a')) { 1519 return OK; 1520 } 1521 1522 if (csd_size == 0) { 1523 // There's no further information, i.e. no codec specific data 1524 // Let's assume that the information provided in the mpeg4 headers 1525 // is accurate and hope for the best. 1526 1527 return OK; 1528 } 1529 1530 if (csd_size < 2) { 1531 return ERROR_MALFORMED; 1532 } 1533 1534 uint32_t objectType = csd[0] >> 3; 1535 1536 if (objectType == 31) { 1537 return ERROR_UNSUPPORTED; 1538 } 1539 1540 uint32_t freqIndex = (csd[0] & 7) << 1 | (csd[1] >> 7); 1541 int32_t sampleRate = 0; 1542 int32_t numChannels = 0; 1543 if (freqIndex == 15) { 1544 if (csd_size < 5) { 1545 return ERROR_MALFORMED; 1546 } 1547 1548 sampleRate = (csd[1] & 0x7f) << 17 1549 | csd[2] << 9 1550 | csd[3] << 1 1551 | (csd[4] >> 7); 1552 1553 numChannels = (csd[4] >> 3) & 15; 1554 } else { 1555 static uint32_t kSamplingRate[] = { 1556 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 1557 16000, 12000, 11025, 8000, 7350 1558 }; 1559 1560 if (freqIndex == 13 || freqIndex == 14) { 1561 return ERROR_MALFORMED; 1562 } 1563 1564 sampleRate = kSamplingRate[freqIndex]; 1565 numChannels = (csd[1] >> 3) & 15; 1566 } 1567 1568 if (numChannels == 0) { 1569 return ERROR_UNSUPPORTED; 1570 } 1571 1572 sampleDesc->mFormat->setInt32("sample-rate", sampleRate); 1573 sampleDesc->mFormat->setInt32("channel-count", numChannels); 1574 1575 return OK; 1576 } 1577 1578 status_t FragmentedMP4Parser::parseMediaData( 1579 uint32_t type, size_t offset, uint64_t size) { 1580 ALOGV("skipping 'mdat' chunk at offsets 0x%08lx-0x%08llx.", 1581 mBufferPos + offset, mBufferPos + size); 1582 1583 sp<ABuffer> buffer = new ABuffer(size - offset); 1584 memcpy(buffer->data(), mBuffer->data() + offset, size - offset); 1585 1586 mMediaData.push(); 1587 MediaDataInfo *info = &mMediaData.editItemAt(mMediaData.size() - 1); 1588 info->mBuffer = buffer; 1589 info->mOffset = mBufferPos + offset; 1590 1591 if (mMediaData.size() > 10) { 1592 ALOGV("suspending for now."); 1593 mSuspended = true; 1594 } 1595 1596 return OK; 1597 } 1598 1599 status_t FragmentedMP4Parser::parseSegmentIndex( 1600 uint32_t type, size_t offset, uint64_t size) { 1601 ALOGV("sidx box type %d, offset %d, size %d", type, int(offset), int(size)); 1602 // AString sidxstr; 1603 // hexdump(mBuffer->data() + offset, size, 0 /* indent */, &sidxstr); 1604 // ALOGV("raw sidx:"); 1605 // ALOGV("%s", sidxstr.c_str()); 1606 if (offset + 12 > size) { 1607 return -EINVAL; 1608 } 1609 1610 uint32_t flags = readU32(offset); 1611 1612 uint32_t version = flags >> 24; 1613 flags &= 0xffffff; 1614 1615 ALOGV("sidx version %d", version); 1616 1617 uint32_t referenceId = readU32(offset + 4); 1618 uint32_t timeScale = readU32(offset + 8); 1619 ALOGV("sidx refid/timescale: %d/%d", referenceId, timeScale); 1620 1621 uint64_t earliestPresentationTime; 1622 uint64_t firstOffset; 1623 1624 offset += 12; 1625 1626 if (version == 0) { 1627 if (offset + 8 > size) { 1628 return -EINVAL; 1629 } 1630 earliestPresentationTime = readU32(offset); 1631 firstOffset = readU32(offset + 4); 1632 offset += 8; 1633 } else { 1634 if (offset + 16 > size) { 1635 return -EINVAL; 1636 } 1637 earliestPresentationTime = readU64(offset); 1638 firstOffset = readU64(offset + 8); 1639 offset += 16; 1640 } 1641 ALOGV("sidx pres/off: %Ld/%Ld", earliestPresentationTime, firstOffset); 1642 1643 if (offset + 4 > size) { 1644 return -EINVAL; 1645 } 1646 if (readU16(offset) != 0) { // reserved 1647 return -EINVAL; 1648 } 1649 int32_t referenceCount = readU16(offset + 2); 1650 offset += 4; 1651 ALOGV("refcount: %d", referenceCount); 1652 1653 if (offset + referenceCount * 12 > size) { 1654 return -EINVAL; 1655 } 1656 1657 TrackInfo *info = editTrack(mCurrentTrackID); 1658 uint64_t total_duration = 0; 1659 for (int i = 0; i < referenceCount; i++) { 1660 uint32_t d1 = readU32(offset); 1661 uint32_t d2 = readU32(offset + 4); 1662 uint32_t d3 = readU32(offset + 8); 1663 1664 if (d1 & 0x80000000) { 1665 ALOGW("sub-sidx boxes not supported yet"); 1666 } 1667 bool sap = d3 & 0x80000000; 1668 bool saptype = d3 >> 28; 1669 if (!sap || saptype > 2) { 1670 ALOGW("not a stream access point, or unsupported type"); 1671 } 1672 total_duration += d2; 1673 offset += 12; 1674 ALOGV(" item %d, %08x %08x %08x", i, d1, d2, d3); 1675 SidxEntry se; 1676 se.mSize = d1 & 0x7fffffff; 1677 se.mDurationUs = 1000000LL * d2 / timeScale; 1678 info->mSidx.add(se); 1679 } 1680 1681 info->mSidxDuration = total_duration * 1000000 / timeScale; 1682 ALOGV("duration: %lld", info->mSidxDuration); 1683 return OK; 1684 } 1685 1686 status_t FragmentedMP4Parser::parseTrackExtends( 1687 uint32_t type, size_t offset, uint64_t size) { 1688 if (offset + 24 > size) { 1689 return -EINVAL; 1690 } 1691 1692 if (readU32(offset) != 0) { 1693 return -EINVAL; 1694 } 1695 1696 uint32_t trackID = readU32(offset + 4); 1697 1698 TrackInfo *info = editTrack(trackID, true /* createIfNecessary */); 1699 info->mDefaultSampleDescriptionIndex = readU32(offset + 8); 1700 info->mDefaultSampleDuration = readU32(offset + 12); 1701 info->mDefaultSampleSize = readU32(offset + 16); 1702 info->mDefaultSampleFlags = readU32(offset + 20); 1703 1704 return OK; 1705 } 1706 1707 FragmentedMP4Parser::TrackInfo *FragmentedMP4Parser::editTrack( 1708 uint32_t trackID, bool createIfNecessary) { 1709 ssize_t i = mTracks.indexOfKey(trackID); 1710 1711 if (i >= 0) { 1712 return &mTracks.editValueAt(i); 1713 } 1714 1715 if (!createIfNecessary) { 1716 return NULL; 1717 } 1718 1719 TrackInfo info; 1720 info.mTrackID = trackID; 1721 info.mFlags = 0; 1722 info.mDuration = 0xffffffff; 1723 info.mSidxDuration = 0; 1724 info.mMediaTimeScale = 0; 1725 info.mMediaHandlerType = 0; 1726 info.mDefaultSampleDescriptionIndex = 0; 1727 info.mDefaultSampleDuration = 0; 1728 info.mDefaultSampleSize = 0; 1729 info.mDefaultSampleFlags = 0; 1730 1731 info.mDecodingTime = 0; 1732 1733 mTracks.add(trackID, info); 1734 return &mTracks.editValueAt(mTracks.indexOfKey(trackID)); 1735 } 1736 1737 status_t FragmentedMP4Parser::parseTrackFragmentHeader( 1738 uint32_t type, size_t offset, uint64_t size) { 1739 if (offset + 8 > size) { 1740 return -EINVAL; 1741 } 1742 1743 uint32_t flags = readU32(offset); 1744 1745 if (flags & 0xff000000) { 1746 return -EINVAL; 1747 } 1748 1749 mTrackFragmentHeaderInfo.mFlags = flags; 1750 1751 mTrackFragmentHeaderInfo.mTrackID = readU32(offset + 4); 1752 offset += 8; 1753 1754 if (flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent) { 1755 if (offset + 8 > size) { 1756 return -EINVAL; 1757 } 1758 1759 mTrackFragmentHeaderInfo.mBaseDataOffset = readU64(offset); 1760 offset += 8; 1761 } 1762 1763 if (flags & TrackFragmentHeaderInfo::kSampleDescriptionIndexPresent) { 1764 if (offset + 4 > size) { 1765 return -EINVAL; 1766 } 1767 1768 mTrackFragmentHeaderInfo.mSampleDescriptionIndex = readU32(offset); 1769 offset += 4; 1770 } 1771 1772 if (flags & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) { 1773 if (offset + 4 > size) { 1774 return -EINVAL; 1775 } 1776 1777 mTrackFragmentHeaderInfo.mDefaultSampleDuration = readU32(offset); 1778 offset += 4; 1779 } 1780 1781 if (flags & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) { 1782 if (offset + 4 > size) { 1783 return -EINVAL; 1784 } 1785 1786 mTrackFragmentHeaderInfo.mDefaultSampleSize = readU32(offset); 1787 offset += 4; 1788 } 1789 1790 if (flags & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) { 1791 if (offset + 4 > size) { 1792 return -EINVAL; 1793 } 1794 1795 mTrackFragmentHeaderInfo.mDefaultSampleFlags = readU32(offset); 1796 offset += 4; 1797 } 1798 1799 if (!(flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent)) { 1800 // This should point to the position of the first byte of the 1801 // enclosing 'moof' container for the first track and 1802 // the end of the data of the preceding fragment for subsequent 1803 // tracks. 1804 1805 CHECK_GE(mStack.size(), 2u); 1806 1807 mTrackFragmentHeaderInfo.mBaseDataOffset = 1808 mStack.itemAt(mStack.size() - 2).mOffset; 1809 1810 // XXX TODO: This does not do the right thing for the 2nd and 1811 // subsequent tracks yet. 1812 } 1813 1814 mTrackFragmentHeaderInfo.mDataOffset = 1815 mTrackFragmentHeaderInfo.mBaseDataOffset; 1816 1817 TrackInfo *trackInfo = editTrack(mTrackFragmentHeaderInfo.mTrackID); 1818 1819 if (trackInfo->mFragments.empty() 1820 || (*trackInfo->mFragments.begin())->complete()) { 1821 trackInfo->mFragments.push_back(new DynamicTrackFragment); 1822 } 1823 1824 return OK; 1825 } 1826 1827 status_t FragmentedMP4Parser::parseTrackFragmentRun( 1828 uint32_t type, size_t offset, uint64_t size) { 1829 if (offset + 8 > size) { 1830 return -EINVAL; 1831 } 1832 1833 enum { 1834 kDataOffsetPresent = 0x01, 1835 kFirstSampleFlagsPresent = 0x04, 1836 kSampleDurationPresent = 0x100, 1837 kSampleSizePresent = 0x200, 1838 kSampleFlagsPresent = 0x400, 1839 kSampleCompositionTimeOffsetPresent = 0x800, 1840 }; 1841 1842 uint32_t flags = readU32(offset); 1843 1844 if (flags & 0xff000000) { 1845 return -EINVAL; 1846 } 1847 1848 if ((flags & kFirstSampleFlagsPresent) && (flags & kSampleFlagsPresent)) { 1849 // These two shall not be used together. 1850 return -EINVAL; 1851 } 1852 1853 uint32_t sampleCount = readU32(offset + 4); 1854 offset += 8; 1855 1856 uint64_t dataOffset = mTrackFragmentHeaderInfo.mDataOffset; 1857 1858 uint32_t firstSampleFlags = 0; 1859 1860 if (flags & kDataOffsetPresent) { 1861 if (offset + 4 > size) { 1862 return -EINVAL; 1863 } 1864 1865 int32_t dataOffsetDelta = (int32_t)readU32(offset); 1866 1867 dataOffset = mTrackFragmentHeaderInfo.mBaseDataOffset + dataOffsetDelta; 1868 1869 offset += 4; 1870 } 1871 1872 if (flags & kFirstSampleFlagsPresent) { 1873 if (offset + 4 > size) { 1874 return -EINVAL; 1875 } 1876 1877 firstSampleFlags = readU32(offset); 1878 offset += 4; 1879 } 1880 1881 TrackInfo *info = editTrack(mTrackFragmentHeaderInfo.mTrackID); 1882 1883 if (info == NULL) { 1884 return -EINVAL; 1885 } 1886 1887 uint32_t sampleDuration = 0, sampleSize = 0, sampleFlags = 0, 1888 sampleCtsOffset = 0; 1889 1890 size_t bytesPerSample = 0; 1891 if (flags & kSampleDurationPresent) { 1892 bytesPerSample += 4; 1893 } else if (mTrackFragmentHeaderInfo.mFlags 1894 & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) { 1895 sampleDuration = mTrackFragmentHeaderInfo.mDefaultSampleDuration; 1896 } else { 1897 sampleDuration = info->mDefaultSampleDuration; 1898 } 1899 1900 if (flags & kSampleSizePresent) { 1901 bytesPerSample += 4; 1902 } else if (mTrackFragmentHeaderInfo.mFlags 1903 & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) { 1904 sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize; 1905 } else { 1906 sampleSize = info->mDefaultSampleSize; 1907 } 1908 1909 if (flags & kSampleFlagsPresent) { 1910 bytesPerSample += 4; 1911 } else if (mTrackFragmentHeaderInfo.mFlags 1912 & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) { 1913 sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags; 1914 } else { 1915 sampleFlags = info->mDefaultSampleFlags; 1916 } 1917 1918 if (flags & kSampleCompositionTimeOffsetPresent) { 1919 bytesPerSample += 4; 1920 } else { 1921 sampleCtsOffset = 0; 1922 } 1923 1924 if (offset + sampleCount * bytesPerSample > size) { 1925 return -EINVAL; 1926 } 1927 1928 uint32_t sampleDescIndex = 1929 (mTrackFragmentHeaderInfo.mFlags 1930 & TrackFragmentHeaderInfo::kSampleDescriptionIndexPresent) 1931 ? mTrackFragmentHeaderInfo.mSampleDescriptionIndex 1932 : info->mDefaultSampleDescriptionIndex; 1933 1934 for (uint32_t i = 0; i < sampleCount; ++i) { 1935 if (flags & kSampleDurationPresent) { 1936 sampleDuration = readU32(offset); 1937 offset += 4; 1938 } 1939 1940 if (flags & kSampleSizePresent) { 1941 sampleSize = readU32(offset); 1942 offset += 4; 1943 } 1944 1945 if (flags & kSampleFlagsPresent) { 1946 sampleFlags = readU32(offset); 1947 offset += 4; 1948 } 1949 1950 if (flags & kSampleCompositionTimeOffsetPresent) { 1951 sampleCtsOffset = readU32(offset); 1952 offset += 4; 1953 } 1954 1955 ALOGV("adding sample at offset 0x%08llx, size %u, duration %u, " 1956 "sampleDescIndex=%u, flags 0x%08x", 1957 dataOffset, sampleSize, sampleDuration, 1958 sampleDescIndex, 1959 (flags & kFirstSampleFlagsPresent) && i == 0 1960 ? firstSampleFlags : sampleFlags); 1961 1962 const sp<TrackFragment> &fragment = *--info->mFragments.end(); 1963 1964 uint32_t decodingTime = info->mDecodingTime; 1965 info->mDecodingTime += sampleDuration; 1966 uint32_t presentationTime = decodingTime + sampleCtsOffset; 1967 1968 static_cast<DynamicTrackFragment *>( 1969 fragment.get())->addSample( 1970 dataOffset, 1971 sampleSize, 1972 presentationTime, 1973 sampleDescIndex, 1974 ((flags & kFirstSampleFlagsPresent) && i == 0) 1975 ? firstSampleFlags : sampleFlags); 1976 1977 dataOffset += sampleSize; 1978 } 1979 1980 mTrackFragmentHeaderInfo.mDataOffset = dataOffset; 1981 1982 return OK; 1983 } 1984 1985 void FragmentedMP4Parser::copyBuffer( 1986 sp<ABuffer> *dst, size_t offset, uint64_t size) const { 1987 sp<ABuffer> buf = new ABuffer(size); 1988 memcpy(buf->data(), mBuffer->data() + offset, size); 1989 1990 *dst = buf; 1991 } 1992 1993 } // namespace android 1994