SampleTable.cpp revision 835c7ec015c72c8a7ab13db341525363da91ce7a
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 37namespace android { 38 39// static 40const uint32_t SampleTable::kChunkOffsetType32 = FOURCC('s', 't', 'c', 'o'); 41// static 42const uint32_t SampleTable::kChunkOffsetType64 = FOURCC('c', 'o', '6', '4'); 43// static 44const uint32_t SampleTable::kSampleSizeType32 = FOURCC('s', 't', 's', 'z'); 45// static 46const uint32_t SampleTable::kSampleSizeTypeCompact = FOURCC('s', 't', 'z', '2'); 47 48//////////////////////////////////////////////////////////////////////////////// 49 50const off64_t kMaxOffset = std::numeric_limits<off64_t>::max(); 51 52struct 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 60private: 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 72SampleTable::CompositionDeltaLookup::CompositionDeltaLookup() 73 : mDeltaEntries(NULL), 74 mNumDeltaEntries(0), 75 mCurrentDeltaEntry(0), 76 mCurrentEntrySampleIndex(0) { 77} 78 79void 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 89int32_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 117SampleTable::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 144SampleTable::~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 167bool SampleTable::isValid() const { 168 return mChunkOffsetOffset >= 0 169 && mSampleToChunkOffset >= 0 170 && mSampleSizeOffset >= 0 171 && mHasTimeToSample; 172} 173 174status_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 215status_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 307status_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 371status_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. 441status_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 515status_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 uint8_t header[8]; 521 if (mDataSource->readAt( 522 data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 523 return ERROR_IO; 524 } 525 526 if (U32_AT(header) != 0) { 527 // Expected version = 0, flags = 0. 528 return ERROR_MALFORMED; 529 } 530 531 uint32_t numSyncSamples = U32_AT(&header[4]); 532 533 if (numSyncSamples < 2) { 534 ALOGV("Table of sync samples is empty or has only a single entry!"); 535 } 536 537 uint64_t allocSize = (uint64_t)numSyncSamples * sizeof(uint32_t); 538 if (allocSize > kMaxTotalSize) { 539 ALOGE("Sync sample table size too large."); 540 return ERROR_OUT_OF_RANGE; 541 } 542 543 mTotalSize += allocSize; 544 if (mTotalSize > kMaxTotalSize) { 545 ALOGE("Sync sample table size would make sample table too large.\n" 546 " Requested sync sample table size = %llu\n" 547 " Eventual sample table size >= %llu\n" 548 " Allowed sample table size = %llu\n", 549 (unsigned long long)allocSize, 550 (unsigned long long)mTotalSize, 551 (unsigned long long)kMaxTotalSize); 552 return ERROR_OUT_OF_RANGE; 553 } 554 555 mSyncSamples = new (std::nothrow) uint32_t[numSyncSamples]; 556 if (!mSyncSamples) { 557 ALOGE("Cannot allocate sync sample table with %llu entries.", 558 (unsigned long long)numSyncSamples); 559 return ERROR_OUT_OF_RANGE; 560 } 561 562 if (mDataSource->readAt(data_offset + 8, mSyncSamples, 563 (size_t)allocSize) != (ssize_t)allocSize) { 564 delete mSyncSamples; 565 mSyncSamples = NULL; 566 return ERROR_IO; 567 } 568 569 for (size_t i = 0; i < numSyncSamples; ++i) { 570 mSyncSamples[i] = ntohl(mSyncSamples[i]) - 1; 571 } 572 573 mSyncSampleOffset = data_offset; 574 mNumSyncSamples = numSyncSamples; 575 576 return OK; 577} 578 579uint32_t SampleTable::countChunkOffsets() const { 580 return mNumChunkOffsets; 581} 582 583uint32_t SampleTable::countSamples() const { 584 return mNumSampleSizes; 585} 586 587status_t SampleTable::getMaxSampleSize(size_t *max_size) { 588 Mutex::Autolock autoLock(mLock); 589 590 *max_size = 0; 591 592 for (uint32_t i = 0; i < mNumSampleSizes; ++i) { 593 size_t sample_size; 594 status_t err = getSampleSize_l(i, &sample_size); 595 596 if (err != OK) { 597 return err; 598 } 599 600 if (sample_size > *max_size) { 601 *max_size = sample_size; 602 } 603 } 604 605 return OK; 606} 607 608uint32_t abs_difference(uint32_t time1, uint32_t time2) { 609 return time1 > time2 ? time1 - time2 : time2 - time1; 610} 611 612// static 613int SampleTable::CompareIncreasingTime(const void *_a, const void *_b) { 614 const SampleTimeEntry *a = (const SampleTimeEntry *)_a; 615 const SampleTimeEntry *b = (const SampleTimeEntry *)_b; 616 617 if (a->mCompositionTime < b->mCompositionTime) { 618 return -1; 619 } else if (a->mCompositionTime > b->mCompositionTime) { 620 return 1; 621 } 622 623 return 0; 624} 625 626void SampleTable::buildSampleEntriesTable() { 627 Mutex::Autolock autoLock(mLock); 628 629 if (mSampleTimeEntries != NULL || mNumSampleSizes == 0) { 630 if (mNumSampleSizes == 0) { 631 ALOGE("b/23247055, mNumSampleSizes(%u)", mNumSampleSizes); 632 } 633 return; 634 } 635 636 mTotalSize += (uint64_t)mNumSampleSizes * sizeof(SampleTimeEntry); 637 if (mTotalSize > kMaxTotalSize) { 638 ALOGE("Sample entry table size would make sample table too large.\n" 639 " Requested sample entry table size = %llu\n" 640 " Eventual sample table size >= %llu\n" 641 " Allowed sample table size = %llu\n", 642 (unsigned long long)mNumSampleSizes * sizeof(SampleTimeEntry), 643 (unsigned long long)mTotalSize, 644 (unsigned long long)kMaxTotalSize); 645 return; 646 } 647 648 mSampleTimeEntries = new (std::nothrow) SampleTimeEntry[mNumSampleSizes]; 649 if (!mSampleTimeEntries) { 650 ALOGE("Cannot allocate sample entry table with %llu entries.", 651 (unsigned long long)mNumSampleSizes); 652 return; 653 } 654 655 uint32_t sampleIndex = 0; 656 uint32_t sampleTime = 0; 657 658 for (uint32_t i = 0; i < mTimeToSampleCount; ++i) { 659 uint32_t n = mTimeToSample[2 * i]; 660 uint32_t delta = mTimeToSample[2 * i + 1]; 661 662 for (uint32_t j = 0; j < n; ++j) { 663 if (sampleIndex < mNumSampleSizes) { 664 // Technically this should always be the case if the file 665 // is well-formed, but you know... there's (gasp) malformed 666 // content out there. 667 668 mSampleTimeEntries[sampleIndex].mSampleIndex = sampleIndex; 669 670 int32_t compTimeDelta = 671 mCompositionDeltaLookup->getCompositionTimeOffset( 672 sampleIndex); 673 674 if ((compTimeDelta < 0 && sampleTime < 675 (compTimeDelta == INT32_MIN ? 676 INT32_MAX : uint32_t(-compTimeDelta))) 677 || (compTimeDelta > 0 && 678 sampleTime > UINT32_MAX - compTimeDelta)) { 679 ALOGE("%u + %d would overflow, clamping", 680 sampleTime, compTimeDelta); 681 if (compTimeDelta < 0) { 682 sampleTime = 0; 683 } else { 684 sampleTime = UINT32_MAX; 685 } 686 compTimeDelta = 0; 687 } 688 689 mSampleTimeEntries[sampleIndex].mCompositionTime = 690 compTimeDelta > 0 ? sampleTime + compTimeDelta: 691 sampleTime - (-compTimeDelta); 692 } 693 694 ++sampleIndex; 695 sampleTime += delta; 696 } 697 } 698 699 qsort(mSampleTimeEntries, mNumSampleSizes, sizeof(SampleTimeEntry), 700 CompareIncreasingTime); 701} 702 703status_t SampleTable::findSampleAtTime( 704 uint64_t req_time, uint64_t scale_num, uint64_t scale_den, 705 uint32_t *sample_index, uint32_t flags) { 706 buildSampleEntriesTable(); 707 708 if (mSampleTimeEntries == NULL) { 709 return ERROR_OUT_OF_RANGE; 710 } 711 712 uint32_t left = 0; 713 uint32_t right_plus_one = mNumSampleSizes; 714 while (left < right_plus_one) { 715 uint32_t center = left + (right_plus_one - left) / 2; 716 uint64_t centerTime = 717 getSampleTime(center, scale_num, scale_den); 718 719 if (req_time < centerTime) { 720 right_plus_one = center; 721 } else if (req_time > centerTime) { 722 left = center + 1; 723 } else { 724 *sample_index = mSampleTimeEntries[center].mSampleIndex; 725 return OK; 726 } 727 } 728 729 uint32_t closestIndex = left; 730 731 if (closestIndex == mNumSampleSizes) { 732 if (flags == kFlagAfter) { 733 return ERROR_OUT_OF_RANGE; 734 } 735 flags = kFlagBefore; 736 } else if (closestIndex == 0) { 737 if (flags == kFlagBefore) { 738 // normally we should return out of range, but that is 739 // treated as end-of-stream. instead return first sample 740 // 741 // return ERROR_OUT_OF_RANGE; 742 } 743 flags = kFlagAfter; 744 } 745 746 switch (flags) { 747 case kFlagBefore: 748 { 749 --closestIndex; 750 break; 751 } 752 753 case kFlagAfter: 754 { 755 // nothing to do 756 break; 757 } 758 759 default: 760 { 761 CHECK(flags == kFlagClosest); 762 // pick closest based on timestamp. use abs_difference for safety 763 if (abs_difference( 764 getSampleTime(closestIndex, scale_num, scale_den), req_time) > 765 abs_difference( 766 req_time, getSampleTime(closestIndex - 1, scale_num, scale_den))) { 767 --closestIndex; 768 } 769 break; 770 } 771 } 772 773 *sample_index = mSampleTimeEntries[closestIndex].mSampleIndex; 774 return OK; 775} 776 777status_t SampleTable::findSyncSampleNear( 778 uint32_t start_sample_index, uint32_t *sample_index, uint32_t flags) { 779 Mutex::Autolock autoLock(mLock); 780 781 *sample_index = 0; 782 783 if (mSyncSampleOffset < 0) { 784 // All samples are sync-samples. 785 *sample_index = start_sample_index; 786 return OK; 787 } 788 789 if (mNumSyncSamples == 0) { 790 *sample_index = 0; 791 return OK; 792 } 793 794 uint32_t left = 0; 795 uint32_t right_plus_one = mNumSyncSamples; 796 while (left < right_plus_one) { 797 uint32_t center = left + (right_plus_one - left) / 2; 798 uint32_t x = mSyncSamples[center]; 799 800 if (start_sample_index < x) { 801 right_plus_one = center; 802 } else if (start_sample_index > x) { 803 left = center + 1; 804 } else { 805 *sample_index = x; 806 return OK; 807 } 808 } 809 810 if (left == mNumSyncSamples) { 811 if (flags == kFlagAfter) { 812 ALOGE("tried to find a sync frame after the last one: %d", left); 813 return ERROR_OUT_OF_RANGE; 814 } 815 flags = kFlagBefore; 816 } 817 else if (left == 0) { 818 if (flags == kFlagBefore) { 819 ALOGE("tried to find a sync frame before the first one: %d", left); 820 821 // normally we should return out of range, but that is 822 // treated as end-of-stream. instead seek to first sync 823 // 824 // return ERROR_OUT_OF_RANGE; 825 } 826 flags = kFlagAfter; 827 } 828 829 // Now ssi[left - 1] <(=) start_sample_index <= ssi[left] 830 switch (flags) { 831 case kFlagBefore: 832 { 833 --left; 834 break; 835 } 836 case kFlagAfter: 837 { 838 // nothing to do 839 break; 840 } 841 default: 842 { 843 // this route is not used, but implement it nonetheless 844 CHECK(flags == kFlagClosest); 845 846 status_t err = mSampleIterator->seekTo(start_sample_index); 847 if (err != OK) { 848 return err; 849 } 850 uint32_t sample_time = mSampleIterator->getSampleTime(); 851 852 err = mSampleIterator->seekTo(mSyncSamples[left]); 853 if (err != OK) { 854 return err; 855 } 856 uint32_t upper_time = mSampleIterator->getSampleTime(); 857 858 err = mSampleIterator->seekTo(mSyncSamples[left - 1]); 859 if (err != OK) { 860 return err; 861 } 862 uint32_t lower_time = mSampleIterator->getSampleTime(); 863 864 // use abs_difference for safety 865 if (abs_difference(upper_time, sample_time) > 866 abs_difference(sample_time, lower_time)) { 867 --left; 868 } 869 break; 870 } 871 } 872 873 *sample_index = mSyncSamples[left]; 874 return OK; 875} 876 877status_t SampleTable::findThumbnailSample(uint32_t *sample_index) { 878 Mutex::Autolock autoLock(mLock); 879 880 if (mSyncSampleOffset < 0) { 881 // All samples are sync-samples. 882 *sample_index = 0; 883 return OK; 884 } 885 886 uint32_t bestSampleIndex = 0; 887 size_t maxSampleSize = 0; 888 889 static const size_t kMaxNumSyncSamplesToScan = 20; 890 891 // Consider the first kMaxNumSyncSamplesToScan sync samples and 892 // pick the one with the largest (compressed) size as the thumbnail. 893 894 size_t numSamplesToScan = mNumSyncSamples; 895 if (numSamplesToScan > kMaxNumSyncSamplesToScan) { 896 numSamplesToScan = kMaxNumSyncSamplesToScan; 897 } 898 899 for (size_t i = 0; i < numSamplesToScan; ++i) { 900 uint32_t x = mSyncSamples[i]; 901 902 // Now x is a sample index. 903 size_t sampleSize; 904 status_t err = getSampleSize_l(x, &sampleSize); 905 if (err != OK) { 906 return err; 907 } 908 909 if (i == 0 || sampleSize > maxSampleSize) { 910 bestSampleIndex = x; 911 maxSampleSize = sampleSize; 912 } 913 } 914 915 *sample_index = bestSampleIndex; 916 917 return OK; 918} 919 920status_t SampleTable::getSampleSize_l( 921 uint32_t sampleIndex, size_t *sampleSize) { 922 return mSampleIterator->getSampleSizeDirect( 923 sampleIndex, sampleSize); 924} 925 926status_t SampleTable::getMetaDataForSample( 927 uint32_t sampleIndex, 928 off64_t *offset, 929 size_t *size, 930 uint32_t *compositionTime, 931 bool *isSyncSample, 932 uint32_t *sampleDuration) { 933 Mutex::Autolock autoLock(mLock); 934 935 status_t err; 936 if ((err = mSampleIterator->seekTo(sampleIndex)) != OK) { 937 return err; 938 } 939 940 if (offset) { 941 *offset = mSampleIterator->getSampleOffset(); 942 } 943 944 if (size) { 945 *size = mSampleIterator->getSampleSize(); 946 } 947 948 if (compositionTime) { 949 *compositionTime = mSampleIterator->getSampleTime(); 950 } 951 952 if (isSyncSample) { 953 *isSyncSample = false; 954 if (mSyncSampleOffset < 0) { 955 // Every sample is a sync sample. 956 *isSyncSample = true; 957 } else { 958 size_t i = (mLastSyncSampleIndex < mNumSyncSamples) 959 && (mSyncSamples[mLastSyncSampleIndex] <= sampleIndex) 960 ? mLastSyncSampleIndex : 0; 961 962 while (i < mNumSyncSamples && mSyncSamples[i] < sampleIndex) { 963 ++i; 964 } 965 966 if (i < mNumSyncSamples && mSyncSamples[i] == sampleIndex) { 967 *isSyncSample = true; 968 } 969 970 mLastSyncSampleIndex = i; 971 } 972 } 973 974 if (sampleDuration) { 975 *sampleDuration = mSampleIterator->getSampleDuration(); 976 } 977 978 return OK; 979} 980 981int32_t SampleTable::getCompositionTimeOffset(uint32_t sampleIndex) { 982 return mCompositionDeltaLookup->getCompositionTimeOffset(sampleIndex); 983} 984 985} // namespace android 986 987