SampleTable.cpp revision 170056540e9ce65261b45efd15f67e72e2df1bed
1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (C) 2009 The Android Open Source Project 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Licensed under the Apache License, Version 2.0 (the "License"); 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * you may not use this file except in compliance with the License. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * You may obtain a copy of the License at 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * 85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * http://www.apache.org/licenses/LICENSE-2.0 95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * Unless required by applicable law or agreed to in writing, software 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * distributed under the License is distributed on an "AS IS" BASIS, 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * See the License for the specific language governing permissions and 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * limitations under the License. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LOG_TAG "SampleTable" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//#define LOG_NDEBUG 0 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utils/Log.h> 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "include/SampleTable.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "include/SampleIterator.h" 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <arpa/inet.h> 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <media/stagefright/foundation/ADebug.h> 274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <media/stagefright/DataSource.h> 284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <media/stagefright/Utils.h> 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace android { 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static 334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const uint32_t SampleTable::kChunkOffsetType32 = FOURCC('s', 't', 'c', 'o'); 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// static 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const uint32_t SampleTable::kChunkOffsetType64 = FOURCC('c', 'o', '6', '4'); 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// static 378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const uint32_t SampleTable::kSampleSizeType32 = FOURCC('s', 't', 's', 'z'); 388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// static 398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const uint32_t SampleTable::kSampleSizeTypeCompact = FOURCC('s', 't', 'z', '2'); 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)struct SampleTable::CompositionDeltaLookup { 448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) CompositionDeltaLookup(); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void setEntries( 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint32_t *deltaEntries, size_t numDeltaEntries); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t getCompositionTimeOffset(uint32_t sampleIndex); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)private: 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Mutex mLock; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint32_t *mDeltaEntries; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t mNumDeltaEntries; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t mCurrentDeltaEntry; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t mCurrentEntrySampleIndex; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_EVIL_CONSTRUCTORS(CompositionDeltaLookup); 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SampleTable::CompositionDeltaLookup::CompositionDeltaLookup() 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : mDeltaEntries(NULL), 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mNumDeltaEntries(0), 667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch mCurrentDeltaEntry(0), 677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch mCurrentEntrySampleIndex(0) { 687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SampleTable::CompositionDeltaLookup::setEntries( 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint32_t *deltaEntries, size_t numDeltaEntries) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Mutex::Autolock autolock(mLock); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mDeltaEntries = deltaEntries; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mNumDeltaEntries = numDeltaEntries; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mCurrentDeltaEntry = 0; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mCurrentEntrySampleIndex = 0; 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32_t SampleTable::CompositionDeltaLookup::getCompositionTimeOffset( 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t sampleIndex) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Mutex::Autolock autolock(mLock); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mDeltaEntries == NULL) { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sampleIndex < mCurrentEntrySampleIndex) { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mCurrentDeltaEntry = 0; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mCurrentEntrySampleIndex = 0; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (mCurrentDeltaEntry < mNumDeltaEntries) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t sampleCount = mDeltaEntries[2 * mCurrentDeltaEntry]; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sampleIndex < mCurrentEntrySampleIndex + sampleCount) { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return mDeltaEntries[2 * mCurrentDeltaEntry + 1]; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mCurrentEntrySampleIndex += sampleCount; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++mCurrentDeltaEntry; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)SampleTable::SampleTable(const sp<DataSource> &source) 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : mDataSource(source), 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mChunkOffsetOffset(-1), 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mChunkOffsetType(0), 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mNumChunkOffsets(0), 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mSampleToChunkOffset(-1), 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mNumSampleToChunkOffsets(0), 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mSampleSizeOffset(-1), 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mSampleSizeFieldSize(0), 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mDefaultSampleSize(0), 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mNumSampleSizes(0), 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mTimeToSampleCount(0), 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mTimeToSample(NULL), 1218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) mSampleTimeEntries(NULL), 1228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) mCompositionTimeDeltaEntries(NULL), 1238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) mNumCompositionTimeDeltaEntries(0), 1248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) mCompositionDeltaLookup(new CompositionDeltaLookup), 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mSyncSampleOffset(-1), 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mNumSyncSamples(0), 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mSyncSamples(NULL), 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mLastSyncSampleIndex(0), 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mSampleToChunkEntries(NULL) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mSampleIterator = new SampleIterator(this); 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SampleTable::~SampleTable() { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete[] mSampleToChunkEntries; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mSampleToChunkEntries = NULL; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete[] mSyncSamples; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mSyncSamples = NULL; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete mCompositionDeltaLookup; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mCompositionDeltaLookup = NULL; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete[] mCompositionTimeDeltaEntries; 1448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) mCompositionTimeDeltaEntries = NULL; 1458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) delete[] mSampleTimeEntries; 1478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) mSampleTimeEntries = NULL; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) delete[] mTimeToSample; 1508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) mTimeToSample = NULL; 1518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) delete mSampleIterator; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mSampleIterator = NULL; 1548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool SampleTable::isValid() const { 157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return mChunkOffsetOffset >= 0 158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) && mSampleToChunkOffset >= 0 159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) && mSampleSizeOffset >= 0 160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) && mTimeToSample != NULL; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)status_t SampleTable::setChunkOffsetParams( 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t type, off64_t data_offset, size_t data_size) { 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mChunkOffsetOffset >= 0) { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERROR_MALFORMED; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(type == kChunkOffsetType32 || type == kChunkOffsetType64); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mChunkOffsetOffset = data_offset; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mChunkOffsetType = type; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data_size < 8) { 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERROR_MALFORMED; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8_t header[8]; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mDataSource->readAt( 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERROR_IO; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (U32_AT(header) != 0) { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Expected version = 0, flags = 0. 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERROR_MALFORMED; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mNumChunkOffsets = U32_AT(&header[4]); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (mChunkOffsetType == kChunkOffsetType32) { 192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (data_size < 8 + mNumChunkOffsets * 4) { 193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return ERROR_MALFORMED; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data_size < 8 + mNumChunkOffsets * 8) { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERROR_MALFORMED; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)status_t SampleTable::setSampleToChunkParams( 2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci off64_t data_offset, size_t data_size) { 206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (mSampleToChunkOffset >= 0) { 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERROR_MALFORMED; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mSampleToChunkOffset = data_offset; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (data_size < 8) { 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERROR_MALFORMED; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8_t header[8]; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mDataSource->readAt( 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERROR_IO; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (U32_AT(header) != 0) { 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Expected version = 0, flags = 0. 224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return ERROR_MALFORMED; 225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mNumSampleToChunkOffsets = U32_AT(&header[4]); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data_size < 8 + mNumSampleToChunkOffsets * 12) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERROR_MALFORMED; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mSampleToChunkEntries = 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new SampleToChunkEntry[mNumSampleToChunkOffsets]; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) { 2377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch uint8_t buffer[12]; 2387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (mDataSource->readAt( 2397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch mSampleToChunkOffset + 8 + i * 12, buffer, sizeof(buffer)) 2407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch != (ssize_t)sizeof(buffer)) { 2417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return ERROR_IO; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(U32_AT(buffer) >= 1); // chunk index is 1 based in the spec. 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We want the chunk index to be 0-based. 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mSampleToChunkEntries[i].startChunk = U32_AT(buffer) - 1; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mSampleToChunkEntries[i].samplesPerChunk = U32_AT(&buffer[4]); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mSampleToChunkEntries[i].chunkDesc = U32_AT(&buffer[8]); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)status_t SampleTable::setSampleSizeParams( 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t type, off64_t data_offset, size_t data_size) { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mSampleSizeOffset >= 0) { 258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return ERROR_MALFORMED; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(type == kSampleSizeType32 || type == kSampleSizeTypeCompact); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mSampleSizeOffset = data_offset; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (data_size < 12) { 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERROR_MALFORMED; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8_t header[12]; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mDataSource->readAt( 2717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return ERROR_IO; 273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (U32_AT(header) != 0) { 2767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Expected version = 0, flags = 0. 2778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return ERROR_MALFORMED; 2787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch mDefaultSampleSize = U32_AT(&header[4]); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mNumSampleSizes = U32_AT(&header[8]); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type == kSampleSizeType32) { 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mSampleSizeFieldSize = 32; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mDefaultSampleSize != 0) { 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data_size < 12 + mNumSampleSizes * 4) { 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERROR_MALFORMED; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((mDefaultSampleSize & 0xffffff00) != 0) { 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The high 24 bits are reserved and must be 0. 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERROR_MALFORMED; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mSampleSizeFieldSize = mDefaultSampleSize & 0xff; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mDefaultSampleSize = 0; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mSampleSizeFieldSize != 4 && mSampleSizeFieldSize != 8 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && mSampleSizeFieldSize != 16) { 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERROR_MALFORMED; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (data_size < 12 + (mNumSampleSizes * mSampleSizeFieldSize + 4) / 8) { 3085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return ERROR_MALFORMED; 3095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return OK; 3135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 3145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)status_t SampleTable::setTimeToSampleParams( 3165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) off64_t data_offset, size_t data_size) { 3175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (mTimeToSample != NULL || data_size < 8) { 3185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return ERROR_MALFORMED; 3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) uint8_t header[8]; 3225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (mDataSource->readAt( 3235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 3245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return ERROR_IO; 3255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (U32_AT(header) != 0) { 3285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Expected version = 0, flags = 0. 3295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return ERROR_MALFORMED; 3305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) mTimeToSampleCount = U32_AT(&header[4]); 3335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) mTimeToSample = new uint32_t[mTimeToSampleCount * 2]; 3345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t size = sizeof(uint32_t) * mTimeToSampleCount * 2; 3365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (mDataSource->readAt( 3374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) data_offset + 8, mTimeToSample, size) < (ssize_t)size) { 3384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return ERROR_IO; 3394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 3404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 341a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (uint32_t i = 0; i < mTimeToSampleCount * 2; ++i) { 3424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) mTimeToSample[i] = ntohl(mTimeToSample[i]); 3438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 3448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return OK; 3468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 3478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)status_t SampleTable::setCompositionTimeToSampleParams( 349a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) off64_t data_offset, size_t data_size) { 3508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ALOGI("There are reordered frames present."); 351a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 3528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (mCompositionTimeDeltaEntries != NULL || data_size < 8) { 3538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return ERROR_MALFORMED; 3548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 355a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 3568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) uint8_t header[8]; 357a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (mDataSource->readAt( 3584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) data_offset, header, sizeof(header)) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) < (ssize_t)sizeof(header)) { 360 return ERROR_IO; 361 } 362 363 if (U32_AT(header) != 0) { 364 // Expected version = 0, flags = 0. 365 return ERROR_MALFORMED; 366 } 367 368 size_t numEntries = U32_AT(&header[4]); 369 370 if (data_size != (numEntries + 1) * 8) { 371 return ERROR_MALFORMED; 372 } 373 374 mNumCompositionTimeDeltaEntries = numEntries; 375 mCompositionTimeDeltaEntries = new uint32_t[2 * numEntries]; 376 377 if (mDataSource->readAt( 378 data_offset + 8, mCompositionTimeDeltaEntries, numEntries * 8) 379 < (ssize_t)numEntries * 8) { 380 delete[] mCompositionTimeDeltaEntries; 381 mCompositionTimeDeltaEntries = NULL; 382 383 return ERROR_IO; 384 } 385 386 for (size_t i = 0; i < 2 * numEntries; ++i) { 387 mCompositionTimeDeltaEntries[i] = ntohl(mCompositionTimeDeltaEntries[i]); 388 } 389 390 mCompositionDeltaLookup->setEntries( 391 mCompositionTimeDeltaEntries, mNumCompositionTimeDeltaEntries); 392 393 return OK; 394} 395 396status_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size) { 397 if (mSyncSampleOffset >= 0 || data_size < 8) { 398 return ERROR_MALFORMED; 399 } 400 401 mSyncSampleOffset = data_offset; 402 403 uint8_t header[8]; 404 if (mDataSource->readAt( 405 data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 406 return ERROR_IO; 407 } 408 409 if (U32_AT(header) != 0) { 410 // Expected version = 0, flags = 0. 411 return ERROR_MALFORMED; 412 } 413 414 mNumSyncSamples = U32_AT(&header[4]); 415 416 if (mNumSyncSamples < 2) { 417 ALOGV("Table of sync samples is empty or has only a single entry!"); 418 } 419 420 mSyncSamples = new uint32_t[mNumSyncSamples]; 421 size_t size = mNumSyncSamples * sizeof(uint32_t); 422 if (mDataSource->readAt(mSyncSampleOffset + 8, mSyncSamples, size) 423 != (ssize_t)size) { 424 return ERROR_IO; 425 } 426 427 for (size_t i = 0; i < mNumSyncSamples; ++i) { 428 mSyncSamples[i] = ntohl(mSyncSamples[i]) - 1; 429 } 430 431 return OK; 432} 433 434uint32_t SampleTable::countChunkOffsets() const { 435 return mNumChunkOffsets; 436} 437 438uint32_t SampleTable::countSamples() const { 439 return mNumSampleSizes; 440} 441 442status_t SampleTable::getMaxSampleSize(size_t *max_size) { 443 Mutex::Autolock autoLock(mLock); 444 445 *max_size = 0; 446 447 for (uint32_t i = 0; i < mNumSampleSizes; ++i) { 448 size_t sample_size; 449 status_t err = getSampleSize_l(i, &sample_size); 450 451 if (err != OK) { 452 return err; 453 } 454 455 if (sample_size > *max_size) { 456 *max_size = sample_size; 457 } 458 } 459 460 return OK; 461} 462 463uint32_t abs_difference(uint32_t time1, uint32_t time2) { 464 return time1 > time2 ? time1 - time2 : time2 - time1; 465} 466 467// static 468int SampleTable::CompareIncreasingTime(const void *_a, const void *_b) { 469 const SampleTimeEntry *a = (const SampleTimeEntry *)_a; 470 const SampleTimeEntry *b = (const SampleTimeEntry *)_b; 471 472 if (a->mCompositionTime < b->mCompositionTime) { 473 return -1; 474 } else if (a->mCompositionTime > b->mCompositionTime) { 475 return 1; 476 } 477 478 return 0; 479} 480 481void SampleTable::buildSampleEntriesTable() { 482 Mutex::Autolock autoLock(mLock); 483 484 if (mSampleTimeEntries != NULL) { 485 return; 486 } 487 488 mSampleTimeEntries = new SampleTimeEntry[mNumSampleSizes]; 489 490 uint32_t sampleIndex = 0; 491 uint32_t sampleTime = 0; 492 493 for (uint32_t i = 0; i < mTimeToSampleCount; ++i) { 494 uint32_t n = mTimeToSample[2 * i]; 495 uint32_t delta = mTimeToSample[2 * i + 1]; 496 497 for (uint32_t j = 0; j < n; ++j) { 498 if (sampleIndex < mNumSampleSizes) { 499 // Technically this should always be the case if the file 500 // is well-formed, but you know... there's (gasp) malformed 501 // content out there. 502 503 mSampleTimeEntries[sampleIndex].mSampleIndex = sampleIndex; 504 505 uint32_t compTimeDelta = 506 mCompositionDeltaLookup->getCompositionTimeOffset( 507 sampleIndex); 508 509 mSampleTimeEntries[sampleIndex].mCompositionTime = 510 sampleTime + compTimeDelta; 511 } 512 513 ++sampleIndex; 514 sampleTime += delta; 515 } 516 } 517 518 qsort(mSampleTimeEntries, mNumSampleSizes, sizeof(SampleTimeEntry), 519 CompareIncreasingTime); 520} 521 522status_t SampleTable::findSampleAtTime( 523 uint32_t req_time, uint32_t *sample_index, uint32_t flags) { 524 buildSampleEntriesTable(); 525 526 uint32_t left = 0; 527 uint32_t right = mNumSampleSizes; 528 while (left < right) { 529 uint32_t center = (left + right) / 2; 530 uint32_t centerTime = mSampleTimeEntries[center].mCompositionTime; 531 532 if (req_time < centerTime) { 533 right = center; 534 } else if (req_time > centerTime) { 535 left = center + 1; 536 } else { 537 left = center; 538 break; 539 } 540 } 541 542 if (left == mNumSampleSizes) { 543 if (flags == kFlagAfter) { 544 return ERROR_OUT_OF_RANGE; 545 } 546 547 --left; 548 } 549 550 uint32_t closestIndex = left; 551 552 switch (flags) { 553 case kFlagBefore: 554 { 555 while (closestIndex > 0 556 && mSampleTimeEntries[closestIndex].mCompositionTime 557 > req_time) { 558 --closestIndex; 559 } 560 break; 561 } 562 563 case kFlagAfter: 564 { 565 while (closestIndex + 1 < mNumSampleSizes 566 && mSampleTimeEntries[closestIndex].mCompositionTime 567 < req_time) { 568 ++closestIndex; 569 } 570 break; 571 } 572 573 default: 574 { 575 CHECK(flags == kFlagClosest); 576 577 if (closestIndex > 0) { 578 // Check left neighbour and pick closest. 579 uint32_t absdiff1 = 580 abs_difference( 581 mSampleTimeEntries[closestIndex].mCompositionTime, 582 req_time); 583 584 uint32_t absdiff2 = 585 abs_difference( 586 mSampleTimeEntries[closestIndex - 1].mCompositionTime, 587 req_time); 588 589 if (absdiff1 > absdiff2) { 590 closestIndex = closestIndex - 1; 591 } 592 } 593 594 break; 595 } 596 } 597 598 *sample_index = mSampleTimeEntries[closestIndex].mSampleIndex; 599 600 return OK; 601} 602 603status_t SampleTable::findSyncSampleNear( 604 uint32_t start_sample_index, uint32_t *sample_index, uint32_t flags) { 605 Mutex::Autolock autoLock(mLock); 606 607 *sample_index = 0; 608 609 if (mSyncSampleOffset < 0) { 610 // All samples are sync-samples. 611 *sample_index = start_sample_index; 612 return OK; 613 } 614 615 if (mNumSyncSamples == 0) { 616 *sample_index = 0; 617 return OK; 618 } 619 620 uint32_t left = 0; 621 uint32_t right = mNumSyncSamples; 622 while (left < right) { 623 uint32_t center = left + (right - left) / 2; 624 uint32_t x = mSyncSamples[center]; 625 626 if (start_sample_index < x) { 627 right = center; 628 } else if (start_sample_index > x) { 629 left = center + 1; 630 } else { 631 left = center; 632 break; 633 } 634 } 635 if (left == mNumSyncSamples) { 636 if (flags == kFlagAfter) { 637 ALOGE("tried to find a sync frame after the last one: %d", left); 638 return ERROR_OUT_OF_RANGE; 639 } 640 left = left - 1; 641 } 642 643 // Now ssi[left] is the sync sample index just before (or at) 644 // start_sample_index. 645 // Also start_sample_index < ssi[left + 1], if left + 1 < mNumSyncSamples. 646 647 uint32_t x = mSyncSamples[left]; 648 649 if (left + 1 < mNumSyncSamples) { 650 uint32_t y = mSyncSamples[left + 1]; 651 652 // our sample lies between sync samples x and y. 653 654 status_t err = mSampleIterator->seekTo(start_sample_index); 655 if (err != OK) { 656 return err; 657 } 658 659 uint32_t sample_time = mSampleIterator->getSampleTime(); 660 661 err = mSampleIterator->seekTo(x); 662 if (err != OK) { 663 return err; 664 } 665 uint32_t x_time = mSampleIterator->getSampleTime(); 666 667 err = mSampleIterator->seekTo(y); 668 if (err != OK) { 669 return err; 670 } 671 672 uint32_t y_time = mSampleIterator->getSampleTime(); 673 674 if (abs_difference(x_time, sample_time) 675 > abs_difference(y_time, sample_time)) { 676 // Pick the sync sample closest (timewise) to the start-sample. 677 x = y; 678 ++left; 679 } 680 } 681 682 switch (flags) { 683 case kFlagBefore: 684 { 685 if (x > start_sample_index) { 686 CHECK(left > 0); 687 688 x = mSyncSamples[left - 1]; 689 690 if (x > start_sample_index) { 691 // The table of sync sample indices was not sorted 692 // properly. 693 return ERROR_MALFORMED; 694 } 695 } 696 break; 697 } 698 699 case kFlagAfter: 700 { 701 if (x < start_sample_index) { 702 if (left + 1 >= mNumSyncSamples) { 703 return ERROR_OUT_OF_RANGE; 704 } 705 706 x = mSyncSamples[left + 1]; 707 708 if (x < start_sample_index) { 709 // The table of sync sample indices was not sorted 710 // properly. 711 return ERROR_MALFORMED; 712 } 713 } 714 715 break; 716 } 717 718 default: 719 break; 720 } 721 722 *sample_index = x; 723 724 return OK; 725} 726 727status_t SampleTable::findThumbnailSample(uint32_t *sample_index) { 728 Mutex::Autolock autoLock(mLock); 729 730 if (mSyncSampleOffset < 0) { 731 // All samples are sync-samples. 732 *sample_index = 0; 733 return OK; 734 } 735 736 uint32_t bestSampleIndex = 0; 737 size_t maxSampleSize = 0; 738 739 static const size_t kMaxNumSyncSamplesToScan = 20; 740 741 // Consider the first kMaxNumSyncSamplesToScan sync samples and 742 // pick the one with the largest (compressed) size as the thumbnail. 743 744 size_t numSamplesToScan = mNumSyncSamples; 745 if (numSamplesToScan > kMaxNumSyncSamplesToScan) { 746 numSamplesToScan = kMaxNumSyncSamplesToScan; 747 } 748 749 for (size_t i = 0; i < numSamplesToScan; ++i) { 750 uint32_t x = mSyncSamples[i]; 751 752 // Now x is a sample index. 753 size_t sampleSize; 754 status_t err = getSampleSize_l(x, &sampleSize); 755 if (err != OK) { 756 return err; 757 } 758 759 if (i == 0 || sampleSize > maxSampleSize) { 760 bestSampleIndex = x; 761 maxSampleSize = sampleSize; 762 } 763 } 764 765 *sample_index = bestSampleIndex; 766 767 return OK; 768} 769 770status_t SampleTable::getSampleSize_l( 771 uint32_t sampleIndex, size_t *sampleSize) { 772 return mSampleIterator->getSampleSizeDirect( 773 sampleIndex, sampleSize); 774} 775 776status_t SampleTable::getMetaDataForSample( 777 uint32_t sampleIndex, 778 off64_t *offset, 779 size_t *size, 780 uint32_t *compositionTime, 781 bool *isSyncSample, 782 uint32_t *sampleDuration) { 783 Mutex::Autolock autoLock(mLock); 784 785 status_t err; 786 if ((err = mSampleIterator->seekTo(sampleIndex)) != OK) { 787 return err; 788 } 789 790 if (offset) { 791 *offset = mSampleIterator->getSampleOffset(); 792 } 793 794 if (size) { 795 *size = mSampleIterator->getSampleSize(); 796 } 797 798 if (compositionTime) { 799 *compositionTime = mSampleIterator->getSampleTime(); 800 } 801 802 if (isSyncSample) { 803 *isSyncSample = false; 804 if (mSyncSampleOffset < 0) { 805 // Every sample is a sync sample. 806 *isSyncSample = true; 807 } else { 808 size_t i = (mLastSyncSampleIndex < mNumSyncSamples) 809 && (mSyncSamples[mLastSyncSampleIndex] <= sampleIndex) 810 ? mLastSyncSampleIndex : 0; 811 812 while (i < mNumSyncSamples && mSyncSamples[i] < sampleIndex) { 813 ++i; 814 } 815 816 if (i < mNumSyncSamples && mSyncSamples[i] == sampleIndex) { 817 *isSyncSample = true; 818 } 819 820 mLastSyncSampleIndex = i; 821 } 822 } 823 824 if (sampleDuration) { 825 *sampleDuration = mSampleIterator->getSampleDuration(); 826 } 827 828 return OK; 829} 830 831uint32_t SampleTable::getCompositionTimeOffset(uint32_t sampleIndex) { 832 return mCompositionDeltaLookup->getCompositionTimeOffset(sampleIndex); 833} 834 835} // namespace android 836 837