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_TAG "SampleTable" 18 //#define LOG_NDEBUG 0 19 #include <utils/Log.h> 20 21 #include <limits> 22 23 #include "include/SampleTable.h" 24 #include "include/SampleIterator.h" 25 26 #include <arpa/inet.h> 27 28 #include <media/stagefright/foundation/ADebug.h> 29 #include <media/stagefright/DataSource.h> 30 #include <media/stagefright/Utils.h> 31 32 /* TODO: remove after being merged into other branches */ 33 #ifndef UINT32_MAX 34 #define UINT32_MAX (4294967295U) 35 #endif 36 37 namespace android { 38 39 // static 40 const uint32_t SampleTable::kChunkOffsetType32 = FOURCC('s', 't', 'c', 'o'); 41 // static 42 const uint32_t SampleTable::kChunkOffsetType64 = FOURCC('c', 'o', '6', '4'); 43 // static 44 const uint32_t SampleTable::kSampleSizeType32 = FOURCC('s', 't', 's', 'z'); 45 // static 46 const uint32_t SampleTable::kSampleSizeTypeCompact = FOURCC('s', 't', 'z', '2'); 47 48 //////////////////////////////////////////////////////////////////////////////// 49 50 const off64_t kMaxOffset = std::numeric_limits<off64_t>::max(); 51 52 struct SampleTable::CompositionDeltaLookup { 53 CompositionDeltaLookup(); 54 55 void setEntries( 56 const int32_t *deltaEntries, size_t numDeltaEntries); 57 58 int32_t getCompositionTimeOffset(uint32_t sampleIndex); 59 60 private: 61 Mutex mLock; 62 63 const int32_t *mDeltaEntries; 64 size_t mNumDeltaEntries; 65 66 size_t mCurrentDeltaEntry; 67 size_t mCurrentEntrySampleIndex; 68 69 DISALLOW_EVIL_CONSTRUCTORS(CompositionDeltaLookup); 70 }; 71 72 SampleTable::CompositionDeltaLookup::CompositionDeltaLookup() 73 : mDeltaEntries(NULL), 74 mNumDeltaEntries(0), 75 mCurrentDeltaEntry(0), 76 mCurrentEntrySampleIndex(0) { 77 } 78 79 void SampleTable::CompositionDeltaLookup::setEntries( 80 const int32_t *deltaEntries, size_t numDeltaEntries) { 81 Mutex::Autolock autolock(mLock); 82 83 mDeltaEntries = deltaEntries; 84 mNumDeltaEntries = numDeltaEntries; 85 mCurrentDeltaEntry = 0; 86 mCurrentEntrySampleIndex = 0; 87 } 88 89 int32_t SampleTable::CompositionDeltaLookup::getCompositionTimeOffset( 90 uint32_t sampleIndex) { 91 Mutex::Autolock autolock(mLock); 92 93 if (mDeltaEntries == NULL) { 94 return 0; 95 } 96 97 if (sampleIndex < mCurrentEntrySampleIndex) { 98 mCurrentDeltaEntry = 0; 99 mCurrentEntrySampleIndex = 0; 100 } 101 102 while (mCurrentDeltaEntry < mNumDeltaEntries) { 103 uint32_t sampleCount = mDeltaEntries[2 * mCurrentDeltaEntry]; 104 if (sampleIndex < mCurrentEntrySampleIndex + sampleCount) { 105 return mDeltaEntries[2 * mCurrentDeltaEntry + 1]; 106 } 107 108 mCurrentEntrySampleIndex += sampleCount; 109 ++mCurrentDeltaEntry; 110 } 111 112 return 0; 113 } 114 115 //////////////////////////////////////////////////////////////////////////////// 116 117 SampleTable::SampleTable(const sp<DataSource> &source) 118 : mDataSource(source), 119 mChunkOffsetOffset(-1), 120 mChunkOffsetType(0), 121 mNumChunkOffsets(0), 122 mSampleToChunkOffset(-1), 123 mNumSampleToChunkOffsets(0), 124 mSampleSizeOffset(-1), 125 mSampleSizeFieldSize(0), 126 mDefaultSampleSize(0), 127 mNumSampleSizes(0), 128 mHasTimeToSample(false), 129 mTimeToSampleCount(0), 130 mTimeToSample(NULL), 131 mSampleTimeEntries(NULL), 132 mCompositionTimeDeltaEntries(NULL), 133 mNumCompositionTimeDeltaEntries(0), 134 mCompositionDeltaLookup(new CompositionDeltaLookup), 135 mSyncSampleOffset(-1), 136 mNumSyncSamples(0), 137 mSyncSamples(NULL), 138 mLastSyncSampleIndex(0), 139 mSampleToChunkEntries(NULL), 140 mTotalSize(0) { 141 mSampleIterator = new SampleIterator(this); 142 } 143 144 SampleTable::~SampleTable() { 145 delete[] mSampleToChunkEntries; 146 mSampleToChunkEntries = NULL; 147 148 delete[] mSyncSamples; 149 mSyncSamples = NULL; 150 151 delete[] mTimeToSample; 152 mTimeToSample = NULL; 153 154 delete mCompositionDeltaLookup; 155 mCompositionDeltaLookup = NULL; 156 157 delete[] mCompositionTimeDeltaEntries; 158 mCompositionTimeDeltaEntries = NULL; 159 160 delete[] mSampleTimeEntries; 161 mSampleTimeEntries = NULL; 162 163 delete mSampleIterator; 164 mSampleIterator = NULL; 165 } 166 167 bool SampleTable::isValid() const { 168 return mChunkOffsetOffset >= 0 169 && mSampleToChunkOffset >= 0 170 && mSampleSizeOffset >= 0 171 && mHasTimeToSample; 172 } 173 174 status_t SampleTable::setChunkOffsetParams( 175 uint32_t type, off64_t data_offset, size_t data_size) { 176 if (mChunkOffsetOffset >= 0) { 177 return ERROR_MALFORMED; 178 } 179 180 CHECK(type == kChunkOffsetType32 || type == kChunkOffsetType64); 181 182 mChunkOffsetOffset = data_offset; 183 mChunkOffsetType = type; 184 185 if (data_size < 8) { 186 return ERROR_MALFORMED; 187 } 188 189 uint8_t header[8]; 190 if (mDataSource->readAt( 191 data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 192 return ERROR_IO; 193 } 194 195 if (U32_AT(header) != 0) { 196 // Expected version = 0, flags = 0. 197 return ERROR_MALFORMED; 198 } 199 200 mNumChunkOffsets = U32_AT(&header[4]); 201 202 if (mChunkOffsetType == kChunkOffsetType32) { 203 if ((data_size - 8) / 4 < mNumChunkOffsets) { 204 return ERROR_MALFORMED; 205 } 206 } else { 207 if ((data_size - 8) / 8 < mNumChunkOffsets) { 208 return ERROR_MALFORMED; 209 } 210 } 211 212 return OK; 213 } 214 215 status_t SampleTable::setSampleToChunkParams( 216 off64_t data_offset, size_t data_size) { 217 if (mSampleToChunkOffset >= 0) { 218 return ERROR_MALFORMED; 219 } 220 221 mSampleToChunkOffset = data_offset; 222 223 if (data_size < 8) { 224 return ERROR_MALFORMED; 225 } 226 227 uint8_t header[8]; 228 if (mDataSource->readAt( 229 data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 230 return ERROR_IO; 231 } 232 233 if (U32_AT(header) != 0) { 234 // Expected version = 0, flags = 0. 235 return ERROR_MALFORMED; 236 } 237 238 mNumSampleToChunkOffsets = U32_AT(&header[4]); 239 240 if ((data_size - 8) / sizeof(SampleToChunkEntry) < mNumSampleToChunkOffsets) { 241 return ERROR_MALFORMED; 242 } 243 244 if ((uint64_t)kMaxTotalSize / sizeof(SampleToChunkEntry) <= 245 (uint64_t)mNumSampleToChunkOffsets) { 246 ALOGE("Sample-to-chunk table size too large."); 247 return ERROR_OUT_OF_RANGE; 248 } 249 250 mTotalSize += (uint64_t)mNumSampleToChunkOffsets * 251 sizeof(SampleToChunkEntry); 252 if (mTotalSize > kMaxTotalSize) { 253 ALOGE("Sample-to-chunk table size would make sample table too large.\n" 254 " Requested sample-to-chunk table size = %llu\n" 255 " Eventual sample table size >= %llu\n" 256 " Allowed sample table size = %llu\n", 257 (unsigned long long)mNumSampleToChunkOffsets * 258 sizeof(SampleToChunkEntry), 259 (unsigned long long)mTotalSize, 260 (unsigned long long)kMaxTotalSize); 261 return ERROR_OUT_OF_RANGE; 262 } 263 264 mSampleToChunkEntries = 265 new (std::nothrow) SampleToChunkEntry[mNumSampleToChunkOffsets]; 266 if (!mSampleToChunkEntries) { 267 ALOGE("Cannot allocate sample-to-chunk table with %llu entries.", 268 (unsigned long long)mNumSampleToChunkOffsets); 269 return ERROR_OUT_OF_RANGE; 270 } 271 272 if (mNumSampleToChunkOffsets == 0) { 273 return OK; 274 } 275 276 if ((off64_t)(kMaxOffset - 8 - 277 ((mNumSampleToChunkOffsets - 1) * sizeof(SampleToChunkEntry))) 278 < mSampleToChunkOffset) { 279 return ERROR_MALFORMED; 280 } 281 282 for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) { 283 uint8_t buffer[sizeof(SampleToChunkEntry)]; 284 285 if (mDataSource->readAt( 286 mSampleToChunkOffset + 8 + i * sizeof(SampleToChunkEntry), 287 buffer, 288 sizeof(buffer)) 289 != (ssize_t)sizeof(buffer)) { 290 return ERROR_IO; 291 } 292 // chunk index is 1 based in the spec. 293 if (U32_AT(buffer) < 1) { 294 ALOGE("b/23534160"); 295 return ERROR_OUT_OF_RANGE; 296 } 297 298 // We want the chunk index to be 0-based. 299 mSampleToChunkEntries[i].startChunk = U32_AT(buffer) - 1; 300 mSampleToChunkEntries[i].samplesPerChunk = U32_AT(&buffer[4]); 301 mSampleToChunkEntries[i].chunkDesc = U32_AT(&buffer[8]); 302 } 303 304 return OK; 305 } 306 307 status_t SampleTable::setSampleSizeParams( 308 uint32_t type, off64_t data_offset, size_t data_size) { 309 if (mSampleSizeOffset >= 0) { 310 return ERROR_MALFORMED; 311 } 312 313 CHECK(type == kSampleSizeType32 || type == kSampleSizeTypeCompact); 314 315 mSampleSizeOffset = data_offset; 316 317 if (data_size < 12) { 318 return ERROR_MALFORMED; 319 } 320 321 uint8_t header[12]; 322 if (mDataSource->readAt( 323 data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 324 return ERROR_IO; 325 } 326 327 if (U32_AT(header) != 0) { 328 // Expected version = 0, flags = 0. 329 return ERROR_MALFORMED; 330 } 331 332 mDefaultSampleSize = U32_AT(&header[4]); 333 mNumSampleSizes = U32_AT(&header[8]); 334 if (mNumSampleSizes > (UINT32_MAX - 12) / 16) { 335 ALOGE("b/23247055, mNumSampleSizes(%u)", mNumSampleSizes); 336 return ERROR_MALFORMED; 337 } 338 339 if (type == kSampleSizeType32) { 340 mSampleSizeFieldSize = 32; 341 342 if (mDefaultSampleSize != 0) { 343 return OK; 344 } 345 346 if (data_size < 12 + mNumSampleSizes * 4) { 347 return ERROR_MALFORMED; 348 } 349 } else { 350 if ((mDefaultSampleSize & 0xffffff00) != 0) { 351 // The high 24 bits are reserved and must be 0. 352 return ERROR_MALFORMED; 353 } 354 355 mSampleSizeFieldSize = mDefaultSampleSize & 0xff; 356 mDefaultSampleSize = 0; 357 358 if (mSampleSizeFieldSize != 4 && mSampleSizeFieldSize != 8 359 && mSampleSizeFieldSize != 16) { 360 return ERROR_MALFORMED; 361 } 362 363 if (data_size < 12 + (mNumSampleSizes * mSampleSizeFieldSize + 4) / 8) { 364 return ERROR_MALFORMED; 365 } 366 } 367 368 return OK; 369 } 370 371 status_t SampleTable::setTimeToSampleParams( 372 off64_t data_offset, size_t data_size) { 373 if (mHasTimeToSample || data_size < 8) { 374 return ERROR_MALFORMED; 375 } 376 377 uint8_t header[8]; 378 if (mDataSource->readAt( 379 data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 380 return ERROR_IO; 381 } 382 383 if (U32_AT(header) != 0) { 384 // Expected version = 0, flags = 0. 385 return ERROR_MALFORMED; 386 } 387 388 mTimeToSampleCount = U32_AT(&header[4]); 389 if (mTimeToSampleCount > UINT32_MAX / (2 * sizeof(uint32_t))) { 390 // Choose this bound because 391 // 1) 2 * sizeof(uint32_t) is the amount of memory needed for one 392 // time-to-sample entry in the time-to-sample table. 393 // 2) mTimeToSampleCount is the number of entries of the time-to-sample 394 // table. 395 // 3) We hope that the table size does not exceed UINT32_MAX. 396 ALOGE("Time-to-sample table size too large."); 397 return ERROR_OUT_OF_RANGE; 398 } 399 400 // Note: At this point, we know that mTimeToSampleCount * 2 will not 401 // overflow because of the above condition. 402 403 uint64_t allocSize = (uint64_t)mTimeToSampleCount * 2 * sizeof(uint32_t); 404 mTotalSize += allocSize; 405 if (mTotalSize > kMaxTotalSize) { 406 ALOGE("Time-to-sample table size would make sample table too large.\n" 407 " Requested time-to-sample table size = %llu\n" 408 " Eventual sample table size >= %llu\n" 409 " Allowed sample table size = %llu\n", 410 (unsigned long long)allocSize, 411 (unsigned long long)mTotalSize, 412 (unsigned long long)kMaxTotalSize); 413 return ERROR_OUT_OF_RANGE; 414 } 415 416 mTimeToSample = new (std::nothrow) uint32_t[mTimeToSampleCount * 2]; 417 if (!mTimeToSample) { 418 ALOGE("Cannot allocate time-to-sample table with %llu entries.", 419 (unsigned long long)mTimeToSampleCount); 420 return ERROR_OUT_OF_RANGE; 421 } 422 423 if (mDataSource->readAt(data_offset + 8, mTimeToSample, 424 (size_t)allocSize) < (ssize_t)allocSize) { 425 ALOGE("Incomplete data read for time-to-sample table."); 426 return ERROR_IO; 427 } 428 429 for (size_t i = 0; i < mTimeToSampleCount * 2; ++i) { 430 mTimeToSample[i] = ntohl(mTimeToSample[i]); 431 } 432 433 mHasTimeToSample = true; 434 return OK; 435 } 436 437 // NOTE: per 14996-12, version 0 ctts contains unsigned values, while version 1 438 // contains signed values, however some software creates version 0 files that 439 // contain signed values, so we're always treating the values as signed, 440 // regardless of version. 441 status_t SampleTable::setCompositionTimeToSampleParams( 442 off64_t data_offset, size_t data_size) { 443 ALOGI("There are reordered frames present."); 444 445 if (mCompositionTimeDeltaEntries != NULL || data_size < 8) { 446 return ERROR_MALFORMED; 447 } 448 449 uint8_t header[8]; 450 if (mDataSource->readAt( 451 data_offset, header, sizeof(header)) 452 < (ssize_t)sizeof(header)) { 453 return ERROR_IO; 454 } 455 456 uint32_t flags = U32_AT(header); 457 uint32_t version = flags >> 24; 458 flags &= 0xffffff; 459 460 if ((version != 0 && version != 1) || flags != 0) { 461 // Expected version = 0 or 1, flags = 0. 462 return ERROR_MALFORMED; 463 } 464 465 size_t numEntries = U32_AT(&header[4]); 466 467 if (((SIZE_MAX / 8) - 1 < numEntries) || (data_size != (numEntries + 1) * 8)) { 468 return ERROR_MALFORMED; 469 } 470 471 mNumCompositionTimeDeltaEntries = numEntries; 472 uint64_t allocSize = (uint64_t)numEntries * 2 * sizeof(int32_t); 473 if (allocSize > kMaxTotalSize) { 474 ALOGE("Composition-time-to-sample table size too large."); 475 return ERROR_OUT_OF_RANGE; 476 } 477 478 mTotalSize += allocSize; 479 if (mTotalSize > kMaxTotalSize) { 480 ALOGE("Composition-time-to-sample table would make sample table too large.\n" 481 " Requested composition-time-to-sample table size = %llu\n" 482 " Eventual sample table size >= %llu\n" 483 " Allowed sample table size = %llu\n", 484 (unsigned long long)allocSize, 485 (unsigned long long)mTotalSize, 486 (unsigned long long)kMaxTotalSize); 487 return ERROR_OUT_OF_RANGE; 488 } 489 490 mCompositionTimeDeltaEntries = new (std::nothrow) int32_t[2 * numEntries]; 491 if (!mCompositionTimeDeltaEntries) { 492 ALOGE("Cannot allocate composition-time-to-sample table with %llu " 493 "entries.", (unsigned long long)numEntries); 494 return ERROR_OUT_OF_RANGE; 495 } 496 497 if (mDataSource->readAt(data_offset + 8, mCompositionTimeDeltaEntries, 498 (size_t)allocSize) < (ssize_t)allocSize) { 499 delete[] mCompositionTimeDeltaEntries; 500 mCompositionTimeDeltaEntries = NULL; 501 502 return ERROR_IO; 503 } 504 505 for (size_t i = 0; i < 2 * numEntries; ++i) { 506 mCompositionTimeDeltaEntries[i] = ntohl(mCompositionTimeDeltaEntries[i]); 507 } 508 509 mCompositionDeltaLookup->setEntries( 510 mCompositionTimeDeltaEntries, mNumCompositionTimeDeltaEntries); 511 512 return OK; 513 } 514 515 status_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size) { 516 if (mSyncSampleOffset >= 0 || data_size < 8) { 517 return ERROR_MALFORMED; 518 } 519 520 mSyncSampleOffset = data_offset; 521 522 uint8_t header[8]; 523 if (mDataSource->readAt( 524 data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 525 return ERROR_IO; 526 } 527 528 if (U32_AT(header) != 0) { 529 // Expected version = 0, flags = 0. 530 return ERROR_MALFORMED; 531 } 532 533 mNumSyncSamples = U32_AT(&header[4]); 534 535 if (mNumSyncSamples < 2) { 536 ALOGV("Table of sync samples is empty or has only a single entry!"); 537 } 538 539 uint64_t allocSize = (uint64_t)mNumSyncSamples * sizeof(uint32_t); 540 if (allocSize > kMaxTotalSize) { 541 ALOGE("Sync sample table size too large."); 542 return ERROR_OUT_OF_RANGE; 543 } 544 545 mTotalSize += allocSize; 546 if (mTotalSize > kMaxTotalSize) { 547 ALOGE("Sync sample table size would make sample table too large.\n" 548 " Requested sync sample table size = %llu\n" 549 " Eventual sample table size >= %llu\n" 550 " Allowed sample table size = %llu\n", 551 (unsigned long long)allocSize, 552 (unsigned long long)mTotalSize, 553 (unsigned long long)kMaxTotalSize); 554 return ERROR_OUT_OF_RANGE; 555 } 556 557 mSyncSamples = new (std::nothrow) uint32_t[mNumSyncSamples]; 558 if (!mSyncSamples) { 559 ALOGE("Cannot allocate sync sample table with %llu entries.", 560 (unsigned long long)mNumSyncSamples); 561 return ERROR_OUT_OF_RANGE; 562 } 563 564 if (mDataSource->readAt(mSyncSampleOffset + 8, mSyncSamples, 565 (size_t)allocSize) != (ssize_t)allocSize) { 566 return ERROR_IO; 567 } 568 569 for (size_t i = 0; i < mNumSyncSamples; ++i) { 570 mSyncSamples[i] = ntohl(mSyncSamples[i]) - 1; 571 } 572 573 return OK; 574 } 575 576 uint32_t SampleTable::countChunkOffsets() const { 577 return mNumChunkOffsets; 578 } 579 580 uint32_t SampleTable::countSamples() const { 581 return mNumSampleSizes; 582 } 583 584 status_t SampleTable::getMaxSampleSize(size_t *max_size) { 585 Mutex::Autolock autoLock(mLock); 586 587 *max_size = 0; 588 589 for (uint32_t i = 0; i < mNumSampleSizes; ++i) { 590 size_t sample_size; 591 status_t err = getSampleSize_l(i, &sample_size); 592 593 if (err != OK) { 594 return err; 595 } 596 597 if (sample_size > *max_size) { 598 *max_size = sample_size; 599 } 600 } 601 602 return OK; 603 } 604 605 uint32_t abs_difference(uint32_t time1, uint32_t time2) { 606 return time1 > time2 ? time1 - time2 : time2 - time1; 607 } 608 609 // static 610 int SampleTable::CompareIncreasingTime(const void *_a, const void *_b) { 611 const SampleTimeEntry *a = (const SampleTimeEntry *)_a; 612 const SampleTimeEntry *b = (const SampleTimeEntry *)_b; 613 614 if (a->mCompositionTime < b->mCompositionTime) { 615 return -1; 616 } else if (a->mCompositionTime > b->mCompositionTime) { 617 return 1; 618 } 619 620 return 0; 621 } 622 623 void SampleTable::buildSampleEntriesTable() { 624 Mutex::Autolock autoLock(mLock); 625 626 if (mSampleTimeEntries != NULL || mNumSampleSizes == 0) { 627 if (mNumSampleSizes == 0) { 628 ALOGE("b/23247055, mNumSampleSizes(%u)", mNumSampleSizes); 629 } 630 return; 631 } 632 633 mTotalSize += (uint64_t)mNumSampleSizes * sizeof(SampleTimeEntry); 634 if (mTotalSize > kMaxTotalSize) { 635 ALOGE("Sample entry table size would make sample table too large.\n" 636 " Requested sample entry table size = %llu\n" 637 " Eventual sample table size >= %llu\n" 638 " Allowed sample table size = %llu\n", 639 (unsigned long long)mNumSampleSizes * sizeof(SampleTimeEntry), 640 (unsigned long long)mTotalSize, 641 (unsigned long long)kMaxTotalSize); 642 return; 643 } 644 645 mSampleTimeEntries = new (std::nothrow) SampleTimeEntry[mNumSampleSizes]; 646 if (!mSampleTimeEntries) { 647 ALOGE("Cannot allocate sample entry table with %llu entries.", 648 (unsigned long long)mNumSampleSizes); 649 return; 650 } 651 652 uint32_t sampleIndex = 0; 653 uint32_t sampleTime = 0; 654 655 for (uint32_t i = 0; i < mTimeToSampleCount; ++i) { 656 uint32_t n = mTimeToSample[2 * i]; 657 uint32_t delta = mTimeToSample[2 * i + 1]; 658 659 for (uint32_t j = 0; j < n; ++j) { 660 if (sampleIndex < mNumSampleSizes) { 661 // Technically this should always be the case if the file 662 // is well-formed, but you know... there's (gasp) malformed 663 // content out there. 664 665 mSampleTimeEntries[sampleIndex].mSampleIndex = sampleIndex; 666 667 int32_t compTimeDelta = 668 mCompositionDeltaLookup->getCompositionTimeOffset( 669 sampleIndex); 670 671 if ((compTimeDelta < 0 && sampleTime < 672 (compTimeDelta == INT32_MIN ? 673 INT32_MAX : uint32_t(-compTimeDelta))) 674 || (compTimeDelta > 0 && 675 sampleTime > UINT32_MAX - compTimeDelta)) { 676 ALOGE("%u + %d would overflow, clamping", 677 sampleTime, compTimeDelta); 678 if (compTimeDelta < 0) { 679 sampleTime = 0; 680 } else { 681 sampleTime = UINT32_MAX; 682 } 683 compTimeDelta = 0; 684 } 685 686 mSampleTimeEntries[sampleIndex].mCompositionTime = 687 compTimeDelta > 0 ? sampleTime + compTimeDelta: 688 sampleTime - (-compTimeDelta); 689 } 690 691 ++sampleIndex; 692 sampleTime += delta; 693 } 694 } 695 696 qsort(mSampleTimeEntries, mNumSampleSizes, sizeof(SampleTimeEntry), 697 CompareIncreasingTime); 698 } 699 700 status_t SampleTable::findSampleAtTime( 701 uint64_t req_time, uint64_t scale_num, uint64_t scale_den, 702 uint32_t *sample_index, uint32_t flags) { 703 buildSampleEntriesTable(); 704 705 if (mSampleTimeEntries == NULL) { 706 return ERROR_OUT_OF_RANGE; 707 } 708 709 uint32_t left = 0; 710 uint32_t right_plus_one = mNumSampleSizes; 711 while (left < right_plus_one) { 712 uint32_t center = left + (right_plus_one - left) / 2; 713 uint64_t centerTime = 714 getSampleTime(center, scale_num, scale_den); 715 716 if (req_time < centerTime) { 717 right_plus_one = center; 718 } else if (req_time > centerTime) { 719 left = center + 1; 720 } else { 721 *sample_index = mSampleTimeEntries[center].mSampleIndex; 722 return OK; 723 } 724 } 725 726 uint32_t closestIndex = left; 727 728 if (closestIndex == mNumSampleSizes) { 729 if (flags == kFlagAfter) { 730 return ERROR_OUT_OF_RANGE; 731 } 732 flags = kFlagBefore; 733 } else if (closestIndex == 0) { 734 if (flags == kFlagBefore) { 735 // normally we should return out of range, but that is 736 // treated as end-of-stream. instead return first sample 737 // 738 // return ERROR_OUT_OF_RANGE; 739 } 740 flags = kFlagAfter; 741 } 742 743 switch (flags) { 744 case kFlagBefore: 745 { 746 --closestIndex; 747 break; 748 } 749 750 case kFlagAfter: 751 { 752 // nothing to do 753 break; 754 } 755 756 default: 757 { 758 CHECK(flags == kFlagClosest); 759 // pick closest based on timestamp. use abs_difference for safety 760 if (abs_difference( 761 getSampleTime(closestIndex, scale_num, scale_den), req_time) > 762 abs_difference( 763 req_time, getSampleTime(closestIndex - 1, scale_num, scale_den))) { 764 --closestIndex; 765 } 766 break; 767 } 768 } 769 770 *sample_index = mSampleTimeEntries[closestIndex].mSampleIndex; 771 return OK; 772 } 773 774 status_t SampleTable::findSyncSampleNear( 775 uint32_t start_sample_index, uint32_t *sample_index, uint32_t flags) { 776 Mutex::Autolock autoLock(mLock); 777 778 *sample_index = 0; 779 780 if (mSyncSampleOffset < 0) { 781 // All samples are sync-samples. 782 *sample_index = start_sample_index; 783 return OK; 784 } 785 786 if (mNumSyncSamples == 0) { 787 *sample_index = 0; 788 return OK; 789 } 790 791 uint32_t left = 0; 792 uint32_t right_plus_one = mNumSyncSamples; 793 while (left < right_plus_one) { 794 uint32_t center = left + (right_plus_one - left) / 2; 795 uint32_t x = mSyncSamples[center]; 796 797 if (start_sample_index < x) { 798 right_plus_one = center; 799 } else if (start_sample_index > x) { 800 left = center + 1; 801 } else { 802 *sample_index = x; 803 return OK; 804 } 805 } 806 807 if (left == mNumSyncSamples) { 808 if (flags == kFlagAfter) { 809 ALOGE("tried to find a sync frame after the last one: %d", left); 810 return ERROR_OUT_OF_RANGE; 811 } 812 flags = kFlagBefore; 813 } 814 else if (left == 0) { 815 if (flags == kFlagBefore) { 816 ALOGE("tried to find a sync frame before the first one: %d", left); 817 818 // normally we should return out of range, but that is 819 // treated as end-of-stream. instead seek to first sync 820 // 821 // return ERROR_OUT_OF_RANGE; 822 } 823 flags = kFlagAfter; 824 } 825 826 // Now ssi[left - 1] <(=) start_sample_index <= ssi[left] 827 switch (flags) { 828 case kFlagBefore: 829 { 830 --left; 831 break; 832 } 833 case kFlagAfter: 834 { 835 // nothing to do 836 break; 837 } 838 default: 839 { 840 // this route is not used, but implement it nonetheless 841 CHECK(flags == kFlagClosest); 842 843 status_t err = mSampleIterator->seekTo(start_sample_index); 844 if (err != OK) { 845 return err; 846 } 847 uint32_t sample_time = mSampleIterator->getSampleTime(); 848 849 err = mSampleIterator->seekTo(mSyncSamples[left]); 850 if (err != OK) { 851 return err; 852 } 853 uint32_t upper_time = mSampleIterator->getSampleTime(); 854 855 err = mSampleIterator->seekTo(mSyncSamples[left - 1]); 856 if (err != OK) { 857 return err; 858 } 859 uint32_t lower_time = mSampleIterator->getSampleTime(); 860 861 // use abs_difference for safety 862 if (abs_difference(upper_time, sample_time) > 863 abs_difference(sample_time, lower_time)) { 864 --left; 865 } 866 break; 867 } 868 } 869 870 *sample_index = mSyncSamples[left]; 871 return OK; 872 } 873 874 status_t SampleTable::findThumbnailSample(uint32_t *sample_index) { 875 Mutex::Autolock autoLock(mLock); 876 877 if (mSyncSampleOffset < 0) { 878 // All samples are sync-samples. 879 *sample_index = 0; 880 return OK; 881 } 882 883 uint32_t bestSampleIndex = 0; 884 size_t maxSampleSize = 0; 885 886 static const size_t kMaxNumSyncSamplesToScan = 20; 887 888 // Consider the first kMaxNumSyncSamplesToScan sync samples and 889 // pick the one with the largest (compressed) size as the thumbnail. 890 891 size_t numSamplesToScan = mNumSyncSamples; 892 if (numSamplesToScan > kMaxNumSyncSamplesToScan) { 893 numSamplesToScan = kMaxNumSyncSamplesToScan; 894 } 895 896 for (size_t i = 0; i < numSamplesToScan; ++i) { 897 uint32_t x = mSyncSamples[i]; 898 899 // Now x is a sample index. 900 size_t sampleSize; 901 status_t err = getSampleSize_l(x, &sampleSize); 902 if (err != OK) { 903 return err; 904 } 905 906 if (i == 0 || sampleSize > maxSampleSize) { 907 bestSampleIndex = x; 908 maxSampleSize = sampleSize; 909 } 910 } 911 912 *sample_index = bestSampleIndex; 913 914 return OK; 915 } 916 917 status_t SampleTable::getSampleSize_l( 918 uint32_t sampleIndex, size_t *sampleSize) { 919 return mSampleIterator->getSampleSizeDirect( 920 sampleIndex, sampleSize); 921 } 922 923 status_t SampleTable::getMetaDataForSample( 924 uint32_t sampleIndex, 925 off64_t *offset, 926 size_t *size, 927 uint32_t *compositionTime, 928 bool *isSyncSample, 929 uint32_t *sampleDuration) { 930 Mutex::Autolock autoLock(mLock); 931 932 status_t err; 933 if ((err = mSampleIterator->seekTo(sampleIndex)) != OK) { 934 return err; 935 } 936 937 if (offset) { 938 *offset = mSampleIterator->getSampleOffset(); 939 } 940 941 if (size) { 942 *size = mSampleIterator->getSampleSize(); 943 } 944 945 if (compositionTime) { 946 *compositionTime = mSampleIterator->getSampleTime(); 947 } 948 949 if (isSyncSample) { 950 *isSyncSample = false; 951 if (mSyncSampleOffset < 0) { 952 // Every sample is a sync sample. 953 *isSyncSample = true; 954 } else { 955 size_t i = (mLastSyncSampleIndex < mNumSyncSamples) 956 && (mSyncSamples[mLastSyncSampleIndex] <= sampleIndex) 957 ? mLastSyncSampleIndex : 0; 958 959 while (i < mNumSyncSamples && mSyncSamples[i] < sampleIndex) { 960 ++i; 961 } 962 963 if (i < mNumSyncSamples && mSyncSamples[i] == sampleIndex) { 964 *isSyncSample = true; 965 } 966 967 mLastSyncSampleIndex = i; 968 } 969 } 970 971 if (sampleDuration) { 972 *sampleDuration = mSampleIterator->getSampleDuration(); 973 } 974 975 return OK; 976 } 977 978 int32_t SampleTable::getCompositionTimeOffset(uint32_t sampleIndex) { 979 return mCompositionDeltaLookup->getCompositionTimeOffset(sampleIndex); 980 } 981 982 } // namespace android 983 984