Home | History | Annotate | Download | only in libstagefright
      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         // already set
    219         return ERROR_MALFORMED;
    220     }
    221 
    222     if (data_offset < 0) {
    223         return ERROR_MALFORMED;
    224     }
    225 
    226     mSampleToChunkOffset = data_offset;
    227 
    228     if (data_size < 8) {
    229         return ERROR_MALFORMED;
    230     }
    231 
    232     uint8_t header[8];
    233     if (mDataSource->readAt(
    234                 data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
    235         return ERROR_IO;
    236     }
    237 
    238     if (U32_AT(header) != 0) {
    239         // Expected version = 0, flags = 0.
    240         return ERROR_MALFORMED;
    241     }
    242 
    243     mNumSampleToChunkOffsets = U32_AT(&header[4]);
    244 
    245     if ((data_size - 8) / sizeof(SampleToChunkEntry) < mNumSampleToChunkOffsets) {
    246         return ERROR_MALFORMED;
    247     }
    248 
    249     if ((uint64_t)kMaxTotalSize / sizeof(SampleToChunkEntry) <=
    250             (uint64_t)mNumSampleToChunkOffsets) {
    251         ALOGE("Sample-to-chunk table size too large.");
    252         return ERROR_OUT_OF_RANGE;
    253     }
    254 
    255     mTotalSize += (uint64_t)mNumSampleToChunkOffsets *
    256             sizeof(SampleToChunkEntry);
    257     if (mTotalSize > kMaxTotalSize) {
    258         ALOGE("Sample-to-chunk table size would make sample table too large.\n"
    259               "    Requested sample-to-chunk table size = %llu\n"
    260               "    Eventual sample table size >= %llu\n"
    261               "    Allowed sample table size = %llu\n",
    262               (unsigned long long)mNumSampleToChunkOffsets *
    263                       sizeof(SampleToChunkEntry),
    264               (unsigned long long)mTotalSize,
    265               (unsigned long long)kMaxTotalSize);
    266         return ERROR_OUT_OF_RANGE;
    267     }
    268 
    269     mSampleToChunkEntries =
    270         new (std::nothrow) SampleToChunkEntry[mNumSampleToChunkOffsets];
    271     if (!mSampleToChunkEntries) {
    272         ALOGE("Cannot allocate sample-to-chunk table with %llu entries.",
    273                 (unsigned long long)mNumSampleToChunkOffsets);
    274         return ERROR_OUT_OF_RANGE;
    275     }
    276 
    277     if (mNumSampleToChunkOffsets == 0) {
    278         return OK;
    279     }
    280 
    281     if ((off64_t)(kMaxOffset - 8 -
    282             ((mNumSampleToChunkOffsets - 1) * sizeof(SampleToChunkEntry)))
    283             < mSampleToChunkOffset) {
    284         return ERROR_MALFORMED;
    285     }
    286 
    287     for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) {
    288         uint8_t buffer[sizeof(SampleToChunkEntry)];
    289 
    290         if (mDataSource->readAt(
    291                     mSampleToChunkOffset + 8 + i * sizeof(SampleToChunkEntry),
    292                     buffer,
    293                     sizeof(buffer))
    294                 != (ssize_t)sizeof(buffer)) {
    295             return ERROR_IO;
    296         }
    297         // chunk index is 1 based in the spec.
    298         if (U32_AT(buffer) < 1) {
    299             ALOGE("b/23534160");
    300             return ERROR_OUT_OF_RANGE;
    301         }
    302 
    303         // We want the chunk index to be 0-based.
    304         mSampleToChunkEntries[i].startChunk = U32_AT(buffer) - 1;
    305         mSampleToChunkEntries[i].samplesPerChunk = U32_AT(&buffer[4]);
    306         mSampleToChunkEntries[i].chunkDesc = U32_AT(&buffer[8]);
    307     }
    308 
    309     return OK;
    310 }
    311 
    312 status_t SampleTable::setSampleSizeParams(
    313         uint32_t type, off64_t data_offset, size_t data_size) {
    314     if (mSampleSizeOffset >= 0) {
    315         return ERROR_MALFORMED;
    316     }
    317 
    318     CHECK(type == kSampleSizeType32 || type == kSampleSizeTypeCompact);
    319 
    320     mSampleSizeOffset = data_offset;
    321 
    322     if (data_size < 12) {
    323         return ERROR_MALFORMED;
    324     }
    325 
    326     uint8_t header[12];
    327     if (mDataSource->readAt(
    328                 data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
    329         return ERROR_IO;
    330     }
    331 
    332     if (U32_AT(header) != 0) {
    333         // Expected version = 0, flags = 0.
    334         return ERROR_MALFORMED;
    335     }
    336 
    337     mDefaultSampleSize = U32_AT(&header[4]);
    338     mNumSampleSizes = U32_AT(&header[8]);
    339     if (mNumSampleSizes > (UINT32_MAX - 12) / 16) {
    340         ALOGE("b/23247055, mNumSampleSizes(%u)", mNumSampleSizes);
    341         return ERROR_MALFORMED;
    342     }
    343 
    344     if (type == kSampleSizeType32) {
    345         mSampleSizeFieldSize = 32;
    346 
    347         if (mDefaultSampleSize != 0) {
    348             return OK;
    349         }
    350 
    351         if (data_size < 12 + mNumSampleSizes * 4) {
    352             return ERROR_MALFORMED;
    353         }
    354     } else {
    355         if ((mDefaultSampleSize & 0xffffff00) != 0) {
    356             // The high 24 bits are reserved and must be 0.
    357             return ERROR_MALFORMED;
    358         }
    359 
    360         mSampleSizeFieldSize = mDefaultSampleSize & 0xff;
    361         mDefaultSampleSize = 0;
    362 
    363         if (mSampleSizeFieldSize != 4 && mSampleSizeFieldSize != 8
    364             && mSampleSizeFieldSize != 16) {
    365             return ERROR_MALFORMED;
    366         }
    367 
    368         if (data_size < 12 + (mNumSampleSizes * mSampleSizeFieldSize + 4) / 8) {
    369             return ERROR_MALFORMED;
    370         }
    371     }
    372 
    373     return OK;
    374 }
    375 
    376 status_t SampleTable::setTimeToSampleParams(
    377         off64_t data_offset, size_t data_size) {
    378     if (mHasTimeToSample || data_size < 8) {
    379         return ERROR_MALFORMED;
    380     }
    381 
    382     uint8_t header[8];
    383     if (mDataSource->readAt(
    384                 data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
    385         return ERROR_IO;
    386     }
    387 
    388     if (U32_AT(header) != 0) {
    389         // Expected version = 0, flags = 0.
    390         return ERROR_MALFORMED;
    391     }
    392 
    393     mTimeToSampleCount = U32_AT(&header[4]);
    394     if (mTimeToSampleCount > UINT32_MAX / (2 * sizeof(uint32_t))) {
    395         // Choose this bound because
    396         // 1) 2 * sizeof(uint32_t) is the amount of memory needed for one
    397         //    time-to-sample entry in the time-to-sample table.
    398         // 2) mTimeToSampleCount is the number of entries of the time-to-sample
    399         //    table.
    400         // 3) We hope that the table size does not exceed UINT32_MAX.
    401         ALOGE("Time-to-sample table size too large.");
    402         return ERROR_OUT_OF_RANGE;
    403     }
    404 
    405     // Note: At this point, we know that mTimeToSampleCount * 2 will not
    406     // overflow because of the above condition.
    407 
    408     uint64_t allocSize = (uint64_t)mTimeToSampleCount * 2 * sizeof(uint32_t);
    409     mTotalSize += allocSize;
    410     if (mTotalSize > kMaxTotalSize) {
    411         ALOGE("Time-to-sample table size would make sample table too large.\n"
    412               "    Requested time-to-sample table size = %llu\n"
    413               "    Eventual sample table size >= %llu\n"
    414               "    Allowed sample table size = %llu\n",
    415               (unsigned long long)allocSize,
    416               (unsigned long long)mTotalSize,
    417               (unsigned long long)kMaxTotalSize);
    418         return ERROR_OUT_OF_RANGE;
    419     }
    420 
    421     mTimeToSample = new (std::nothrow) uint32_t[mTimeToSampleCount * 2];
    422     if (!mTimeToSample) {
    423         ALOGE("Cannot allocate time-to-sample table with %llu entries.",
    424                 (unsigned long long)mTimeToSampleCount);
    425         return ERROR_OUT_OF_RANGE;
    426     }
    427 
    428     if (mDataSource->readAt(data_offset + 8, mTimeToSample,
    429             (size_t)allocSize) < (ssize_t)allocSize) {
    430         ALOGE("Incomplete data read for time-to-sample table.");
    431         return ERROR_IO;
    432     }
    433 
    434     for (size_t i = 0; i < mTimeToSampleCount * 2; ++i) {
    435         mTimeToSample[i] = ntohl(mTimeToSample[i]);
    436     }
    437 
    438     mHasTimeToSample = true;
    439     return OK;
    440 }
    441 
    442 // NOTE: per 14996-12, version 0 ctts contains unsigned values, while version 1
    443 // contains signed values, however some software creates version 0 files that
    444 // contain signed values, so we're always treating the values as signed,
    445 // regardless of version.
    446 status_t SampleTable::setCompositionTimeToSampleParams(
    447         off64_t data_offset, size_t data_size) {
    448     ALOGI("There are reordered frames present.");
    449 
    450     if (mCompositionTimeDeltaEntries != NULL || data_size < 8) {
    451         return ERROR_MALFORMED;
    452     }
    453 
    454     uint8_t header[8];
    455     if (mDataSource->readAt(
    456                 data_offset, header, sizeof(header))
    457             < (ssize_t)sizeof(header)) {
    458         return ERROR_IO;
    459     }
    460 
    461     uint32_t flags = U32_AT(header);
    462     uint32_t version = flags >> 24;
    463     flags &= 0xffffff;
    464 
    465     if ((version != 0 && version != 1) || flags != 0) {
    466         // Expected version = 0 or 1, flags = 0.
    467         return ERROR_MALFORMED;
    468     }
    469 
    470     size_t numEntries = U32_AT(&header[4]);
    471 
    472     if (((SIZE_MAX / 8) - 1 < numEntries) || (data_size != (numEntries + 1) * 8)) {
    473         return ERROR_MALFORMED;
    474     }
    475 
    476     mNumCompositionTimeDeltaEntries = numEntries;
    477     uint64_t allocSize = (uint64_t)numEntries * 2 * sizeof(int32_t);
    478     if (allocSize > kMaxTotalSize) {
    479         ALOGE("Composition-time-to-sample table size too large.");
    480         return ERROR_OUT_OF_RANGE;
    481     }
    482 
    483     mTotalSize += allocSize;
    484     if (mTotalSize > kMaxTotalSize) {
    485         ALOGE("Composition-time-to-sample table would make sample table too large.\n"
    486               "    Requested composition-time-to-sample table size = %llu\n"
    487               "    Eventual sample table size >= %llu\n"
    488               "    Allowed sample table size = %llu\n",
    489               (unsigned long long)allocSize,
    490               (unsigned long long)mTotalSize,
    491               (unsigned long long)kMaxTotalSize);
    492         return ERROR_OUT_OF_RANGE;
    493     }
    494 
    495     mCompositionTimeDeltaEntries = new (std::nothrow) int32_t[2 * numEntries];
    496     if (!mCompositionTimeDeltaEntries) {
    497         ALOGE("Cannot allocate composition-time-to-sample table with %llu "
    498                 "entries.", (unsigned long long)numEntries);
    499         return ERROR_OUT_OF_RANGE;
    500     }
    501 
    502     if (mDataSource->readAt(data_offset + 8, mCompositionTimeDeltaEntries,
    503             (size_t)allocSize) < (ssize_t)allocSize) {
    504         delete[] mCompositionTimeDeltaEntries;
    505         mCompositionTimeDeltaEntries = NULL;
    506 
    507         return ERROR_IO;
    508     }
    509 
    510     for (size_t i = 0; i < 2 * numEntries; ++i) {
    511         mCompositionTimeDeltaEntries[i] = ntohl(mCompositionTimeDeltaEntries[i]);
    512     }
    513 
    514     mCompositionDeltaLookup->setEntries(
    515             mCompositionTimeDeltaEntries, mNumCompositionTimeDeltaEntries);
    516 
    517     return OK;
    518 }
    519 
    520 status_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size) {
    521     if (mSyncSampleOffset >= 0 || data_size < 8) {
    522         return ERROR_MALFORMED;
    523     }
    524 
    525     uint8_t header[8];
    526     if (mDataSource->readAt(
    527                 data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
    528         return ERROR_IO;
    529     }
    530 
    531     if (U32_AT(header) != 0) {
    532         // Expected version = 0, flags = 0.
    533         return ERROR_MALFORMED;
    534     }
    535 
    536     uint32_t numSyncSamples = U32_AT(&header[4]);
    537 
    538     if (numSyncSamples < 2) {
    539         ALOGV("Table of sync samples is empty or has only a single entry!");
    540     }
    541 
    542     uint64_t allocSize = (uint64_t)numSyncSamples * sizeof(uint32_t);
    543     if (allocSize > kMaxTotalSize) {
    544         ALOGE("Sync sample table size too large.");
    545         return ERROR_OUT_OF_RANGE;
    546     }
    547 
    548     mTotalSize += allocSize;
    549     if (mTotalSize > kMaxTotalSize) {
    550         ALOGE("Sync sample table size would make sample table too large.\n"
    551               "    Requested sync sample table size = %llu\n"
    552               "    Eventual sample table size >= %llu\n"
    553               "    Allowed sample table size = %llu\n",
    554               (unsigned long long)allocSize,
    555               (unsigned long long)mTotalSize,
    556               (unsigned long long)kMaxTotalSize);
    557         return ERROR_OUT_OF_RANGE;
    558     }
    559 
    560     mSyncSamples = new (std::nothrow) uint32_t[numSyncSamples];
    561     if (!mSyncSamples) {
    562         ALOGE("Cannot allocate sync sample table with %llu entries.",
    563                 (unsigned long long)numSyncSamples);
    564         return ERROR_OUT_OF_RANGE;
    565     }
    566 
    567     if (mDataSource->readAt(data_offset + 8, mSyncSamples,
    568             (size_t)allocSize) != (ssize_t)allocSize) {
    569         delete[] mSyncSamples;
    570         mSyncSamples = NULL;
    571         return ERROR_IO;
    572     }
    573 
    574     for (size_t i = 0; i < numSyncSamples; ++i) {
    575         if (mSyncSamples[i] == 0) {
    576             ALOGE("b/32423862, unexpected zero value in stss");
    577             continue;
    578         }
    579         mSyncSamples[i] = ntohl(mSyncSamples[i]) - 1;
    580     }
    581 
    582     mSyncSampleOffset = data_offset;
    583     mNumSyncSamples = numSyncSamples;
    584 
    585     return OK;
    586 }
    587 
    588 uint32_t SampleTable::countChunkOffsets() const {
    589     return mNumChunkOffsets;
    590 }
    591 
    592 uint32_t SampleTable::countSamples() const {
    593     return mNumSampleSizes;
    594 }
    595 
    596 status_t SampleTable::getMaxSampleSize(size_t *max_size) {
    597     Mutex::Autolock autoLock(mLock);
    598 
    599     *max_size = 0;
    600 
    601     for (uint32_t i = 0; i < mNumSampleSizes; ++i) {
    602         size_t sample_size;
    603         status_t err = getSampleSize_l(i, &sample_size);
    604 
    605         if (err != OK) {
    606             return err;
    607         }
    608 
    609         if (sample_size > *max_size) {
    610             *max_size = sample_size;
    611         }
    612     }
    613 
    614     return OK;
    615 }
    616 
    617 uint32_t abs_difference(uint32_t time1, uint32_t time2) {
    618     return time1 > time2 ? time1 - time2 : time2 - time1;
    619 }
    620 
    621 // static
    622 int SampleTable::CompareIncreasingTime(const void *_a, const void *_b) {
    623     const SampleTimeEntry *a = (const SampleTimeEntry *)_a;
    624     const SampleTimeEntry *b = (const SampleTimeEntry *)_b;
    625 
    626     if (a->mCompositionTime < b->mCompositionTime) {
    627         return -1;
    628     } else if (a->mCompositionTime > b->mCompositionTime) {
    629         return 1;
    630     }
    631 
    632     return 0;
    633 }
    634 
    635 void SampleTable::buildSampleEntriesTable() {
    636     Mutex::Autolock autoLock(mLock);
    637 
    638     if (mSampleTimeEntries != NULL || mNumSampleSizes == 0) {
    639         if (mNumSampleSizes == 0) {
    640             ALOGE("b/23247055, mNumSampleSizes(%u)", mNumSampleSizes);
    641         }
    642         return;
    643     }
    644 
    645     mTotalSize += (uint64_t)mNumSampleSizes * sizeof(SampleTimeEntry);
    646     if (mTotalSize > kMaxTotalSize) {
    647         ALOGE("Sample entry table size would make sample table too large.\n"
    648               "    Requested sample entry table size = %llu\n"
    649               "    Eventual sample table size >= %llu\n"
    650               "    Allowed sample table size = %llu\n",
    651               (unsigned long long)mNumSampleSizes * sizeof(SampleTimeEntry),
    652               (unsigned long long)mTotalSize,
    653               (unsigned long long)kMaxTotalSize);
    654         return;
    655     }
    656 
    657     mSampleTimeEntries = new (std::nothrow) SampleTimeEntry[mNumSampleSizes];
    658     if (!mSampleTimeEntries) {
    659         ALOGE("Cannot allocate sample entry table with %llu entries.",
    660                 (unsigned long long)mNumSampleSizes);
    661         return;
    662     }
    663 
    664     uint32_t sampleIndex = 0;
    665     uint32_t sampleTime = 0;
    666 
    667     for (uint32_t i = 0; i < mTimeToSampleCount; ++i) {
    668         uint32_t n = mTimeToSample[2 * i];
    669         uint32_t delta = mTimeToSample[2 * i + 1];
    670 
    671         for (uint32_t j = 0; j < n; ++j) {
    672             if (sampleIndex < mNumSampleSizes) {
    673                 // Technically this should always be the case if the file
    674                 // is well-formed, but you know... there's (gasp) malformed
    675                 // content out there.
    676 
    677                 mSampleTimeEntries[sampleIndex].mSampleIndex = sampleIndex;
    678 
    679                 int32_t compTimeDelta =
    680                     mCompositionDeltaLookup->getCompositionTimeOffset(
    681                             sampleIndex);
    682 
    683                 if ((compTimeDelta < 0 && sampleTime <
    684                         (compTimeDelta == INT32_MIN ?
    685                                 INT32_MAX : uint32_t(-compTimeDelta)))
    686                         || (compTimeDelta > 0 &&
    687                                 sampleTime > UINT32_MAX - compTimeDelta)) {
    688                     ALOGE("%u + %d would overflow, clamping",
    689                             sampleTime, compTimeDelta);
    690                     if (compTimeDelta < 0) {
    691                         sampleTime = 0;
    692                     } else {
    693                         sampleTime = UINT32_MAX;
    694                     }
    695                     compTimeDelta = 0;
    696                 }
    697 
    698                 mSampleTimeEntries[sampleIndex].mCompositionTime =
    699                         compTimeDelta > 0 ? sampleTime + compTimeDelta:
    700                                 sampleTime - (-compTimeDelta);
    701             }
    702 
    703             ++sampleIndex;
    704             if (sampleTime > UINT32_MAX - delta) {
    705                 ALOGE("%u + %u would overflow, clamping",
    706                     sampleTime, delta);
    707                 sampleTime = UINT32_MAX;
    708             } else {
    709                 sampleTime += delta;
    710             }
    711         }
    712     }
    713 
    714     qsort(mSampleTimeEntries, mNumSampleSizes, sizeof(SampleTimeEntry),
    715           CompareIncreasingTime);
    716 }
    717 
    718 status_t SampleTable::findSampleAtTime(
    719         uint64_t req_time, uint64_t scale_num, uint64_t scale_den,
    720         uint32_t *sample_index, uint32_t flags) {
    721     buildSampleEntriesTable();
    722 
    723     if (mSampleTimeEntries == NULL) {
    724         return ERROR_OUT_OF_RANGE;
    725     }
    726 
    727     uint32_t left = 0;
    728     uint32_t right_plus_one = mNumSampleSizes;
    729     while (left < right_plus_one) {
    730         uint32_t center = left + (right_plus_one - left) / 2;
    731         uint64_t centerTime =
    732             getSampleTime(center, scale_num, scale_den);
    733 
    734         if (req_time < centerTime) {
    735             right_plus_one = center;
    736         } else if (req_time > centerTime) {
    737             left = center + 1;
    738         } else {
    739             *sample_index = mSampleTimeEntries[center].mSampleIndex;
    740             return OK;
    741         }
    742     }
    743 
    744     uint32_t closestIndex = left;
    745 
    746     if (closestIndex == mNumSampleSizes) {
    747         if (flags == kFlagAfter) {
    748             return ERROR_OUT_OF_RANGE;
    749         }
    750         flags = kFlagBefore;
    751     } else if (closestIndex == 0) {
    752         if (flags == kFlagBefore) {
    753             // normally we should return out of range, but that is
    754             // treated as end-of-stream.  instead return first sample
    755             //
    756             // return ERROR_OUT_OF_RANGE;
    757         }
    758         flags = kFlagAfter;
    759     }
    760 
    761     switch (flags) {
    762         case kFlagBefore:
    763         {
    764             --closestIndex;
    765             break;
    766         }
    767 
    768         case kFlagAfter:
    769         {
    770             // nothing to do
    771             break;
    772         }
    773 
    774         default:
    775         {
    776             CHECK(flags == kFlagClosest);
    777             // pick closest based on timestamp. use abs_difference for safety
    778             if (abs_difference(
    779                     getSampleTime(closestIndex, scale_num, scale_den), req_time) >
    780                 abs_difference(
    781                     req_time, getSampleTime(closestIndex - 1, scale_num, scale_den))) {
    782                 --closestIndex;
    783             }
    784             break;
    785         }
    786     }
    787 
    788     *sample_index = mSampleTimeEntries[closestIndex].mSampleIndex;
    789     return OK;
    790 }
    791 
    792 status_t SampleTable::findSyncSampleNear(
    793         uint32_t start_sample_index, uint32_t *sample_index, uint32_t flags) {
    794     Mutex::Autolock autoLock(mLock);
    795 
    796     *sample_index = 0;
    797 
    798     if (mSyncSampleOffset < 0) {
    799         // All samples are sync-samples.
    800         *sample_index = start_sample_index;
    801         return OK;
    802     }
    803 
    804     if (mNumSyncSamples == 0) {
    805         *sample_index = 0;
    806         return OK;
    807     }
    808 
    809     uint32_t left = 0;
    810     uint32_t right_plus_one = mNumSyncSamples;
    811     while (left < right_plus_one) {
    812         uint32_t center = left + (right_plus_one - left) / 2;
    813         uint32_t x = mSyncSamples[center];
    814 
    815         if (start_sample_index < x) {
    816             right_plus_one = center;
    817         } else if (start_sample_index > x) {
    818             left = center + 1;
    819         } else {
    820             *sample_index = x;
    821             return OK;
    822         }
    823     }
    824 
    825     if (left == mNumSyncSamples) {
    826         if (flags == kFlagAfter) {
    827             ALOGE("tried to find a sync frame after the last one: %d", left);
    828             return ERROR_OUT_OF_RANGE;
    829         }
    830         flags = kFlagBefore;
    831     }
    832     else if (left == 0) {
    833         if (flags == kFlagBefore) {
    834             ALOGE("tried to find a sync frame before the first one: %d", left);
    835 
    836             // normally we should return out of range, but that is
    837             // treated as end-of-stream.  instead seek to first sync
    838             //
    839             // return ERROR_OUT_OF_RANGE;
    840         }
    841         flags = kFlagAfter;
    842     }
    843 
    844     // Now ssi[left - 1] <(=) start_sample_index <= ssi[left]
    845     switch (flags) {
    846         case kFlagBefore:
    847         {
    848             --left;
    849             break;
    850         }
    851         case kFlagAfter:
    852         {
    853             // nothing to do
    854             break;
    855         }
    856         default:
    857         {
    858             // this route is not used, but implement it nonetheless
    859             CHECK(flags == kFlagClosest);
    860 
    861             status_t err = mSampleIterator->seekTo(start_sample_index);
    862             if (err != OK) {
    863                 return err;
    864             }
    865             uint32_t sample_time = mSampleIterator->getSampleTime();
    866 
    867             err = mSampleIterator->seekTo(mSyncSamples[left]);
    868             if (err != OK) {
    869                 return err;
    870             }
    871             uint32_t upper_time = mSampleIterator->getSampleTime();
    872 
    873             err = mSampleIterator->seekTo(mSyncSamples[left - 1]);
    874             if (err != OK) {
    875                 return err;
    876             }
    877             uint32_t lower_time = mSampleIterator->getSampleTime();
    878 
    879             // use abs_difference for safety
    880             if (abs_difference(upper_time, sample_time) >
    881                 abs_difference(sample_time, lower_time)) {
    882                 --left;
    883             }
    884             break;
    885         }
    886     }
    887 
    888     *sample_index = mSyncSamples[left];
    889     return OK;
    890 }
    891 
    892 status_t SampleTable::findThumbnailSample(uint32_t *sample_index) {
    893     Mutex::Autolock autoLock(mLock);
    894 
    895     if (mSyncSampleOffset < 0) {
    896         // All samples are sync-samples.
    897         *sample_index = 0;
    898         return OK;
    899     }
    900 
    901     uint32_t bestSampleIndex = 0;
    902     size_t maxSampleSize = 0;
    903 
    904     static const size_t kMaxNumSyncSamplesToScan = 20;
    905 
    906     // Consider the first kMaxNumSyncSamplesToScan sync samples and
    907     // pick the one with the largest (compressed) size as the thumbnail.
    908 
    909     size_t numSamplesToScan = mNumSyncSamples;
    910     if (numSamplesToScan > kMaxNumSyncSamplesToScan) {
    911         numSamplesToScan = kMaxNumSyncSamplesToScan;
    912     }
    913 
    914     for (size_t i = 0; i < numSamplesToScan; ++i) {
    915         uint32_t x = mSyncSamples[i];
    916 
    917         // Now x is a sample index.
    918         size_t sampleSize;
    919         status_t err = getSampleSize_l(x, &sampleSize);
    920         if (err != OK) {
    921             return err;
    922         }
    923 
    924         if (i == 0 || sampleSize > maxSampleSize) {
    925             bestSampleIndex = x;
    926             maxSampleSize = sampleSize;
    927         }
    928     }
    929 
    930     *sample_index = bestSampleIndex;
    931 
    932     return OK;
    933 }
    934 
    935 status_t SampleTable::getSampleSize_l(
    936         uint32_t sampleIndex, size_t *sampleSize) {
    937     return mSampleIterator->getSampleSizeDirect(
    938             sampleIndex, sampleSize);
    939 }
    940 
    941 status_t SampleTable::getMetaDataForSample(
    942         uint32_t sampleIndex,
    943         off64_t *offset,
    944         size_t *size,
    945         uint32_t *compositionTime,
    946         bool *isSyncSample,
    947         uint32_t *sampleDuration) {
    948     Mutex::Autolock autoLock(mLock);
    949 
    950     status_t err;
    951     if ((err = mSampleIterator->seekTo(sampleIndex)) != OK) {
    952         return err;
    953     }
    954 
    955     if (offset) {
    956         *offset = mSampleIterator->getSampleOffset();
    957     }
    958 
    959     if (size) {
    960         *size = mSampleIterator->getSampleSize();
    961     }
    962 
    963     if (compositionTime) {
    964         *compositionTime = mSampleIterator->getSampleTime();
    965     }
    966 
    967     if (isSyncSample) {
    968         *isSyncSample = false;
    969         if (mSyncSampleOffset < 0) {
    970             // Every sample is a sync sample.
    971             *isSyncSample = true;
    972         } else {
    973             size_t i = (mLastSyncSampleIndex < mNumSyncSamples)
    974                     && (mSyncSamples[mLastSyncSampleIndex] <= sampleIndex)
    975                 ? mLastSyncSampleIndex : 0;
    976 
    977             while (i < mNumSyncSamples && mSyncSamples[i] < sampleIndex) {
    978                 ++i;
    979             }
    980 
    981             if (i < mNumSyncSamples && mSyncSamples[i] == sampleIndex) {
    982                 *isSyncSample = true;
    983             }
    984 
    985             mLastSyncSampleIndex = i;
    986         }
    987     }
    988 
    989     if (sampleDuration) {
    990         *sampleDuration = mSampleIterator->getSampleDuration();
    991     }
    992 
    993     return OK;
    994 }
    995 
    996 int32_t SampleTable::getCompositionTimeOffset(uint32_t sampleIndex) {
    997     return mCompositionDeltaLookup->getCompositionTimeOffset(sampleIndex);
    998 }
    999 
   1000 }  // namespace android
   1001