SampleTable.cpp revision 8f76ebf90d0391a4baa8a921ed6e291dfc7891da
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2009 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "SampleTable" 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//#define LOG_NDEBUG 0 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Log.h> 209b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "include/SampleTable.h" 229b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li#include "include/SampleIterator.h" 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <arpa/inet.h> 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <media/stagefright/foundation/ADebug.h> 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <media/stagefright/DataSource.h> 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <media/stagefright/Utils.h> 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// static 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst uint32_t SampleTable::kChunkOffsetType32 = FOURCC('s', 't', 'c', 'o'); 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// static 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst uint32_t SampleTable::kChunkOffsetType64 = FOURCC('c', 'o', '6', '4'); 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// static 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst uint32_t SampleTable::kSampleSizeType32 = FOURCC('s', 't', 's', 'z'); 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// static 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst uint32_t SampleTable::kSampleSizeTypeCompact = FOURCC('s', 't', 'z', '2'); 40df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main 417478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li//////////////////////////////////////////////////////////////////////////////// 427478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li 43df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Mainstruct SampleTable::CompositionDeltaLookup { 44df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main CompositionDeltaLookup(); 457478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li 467478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li void setEntries( 47df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main const uint32_t *deltaEntries, size_t numDeltaEntries); 48df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main 49df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main uint32_t getCompositionTimeOffset(uint32_t sampleIndex); 50df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main 51df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Mainprivate: 52df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main Mutex mLock; 53df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main 54df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main const uint32_t *mDeltaEntries; 557478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li size_t mNumDeltaEntries; 56df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t mCurrentDeltaEntry; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t mCurrentEntrySampleIndex; 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 609b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li DISALLOW_EVIL_CONSTRUCTORS(CompositionDeltaLookup); 61c62f9bd13327937aa2d2f20b44215397120634c1Dave Sparks}; 62da83f4674a564007baac03db062a289c8158d940Benny Wong 63da83f4674a564007baac03db062a289c8158d940Benny WongSampleTable::CompositionDeltaLookup::CompositionDeltaLookup() 64da83f4674a564007baac03db062a289c8158d940Benny Wong : mDeltaEntries(NULL), 65da83f4674a564007baac03db062a289c8158d940Benny Wong mNumDeltaEntries(0), 66da83f4674a564007baac03db062a289c8158d940Benny Wong mCurrentDeltaEntry(0), 67da83f4674a564007baac03db062a289c8158d940Benny Wong mCurrentEntrySampleIndex(0) { 68da83f4674a564007baac03db062a289c8158d940Benny Wong} 69da83f4674a564007baac03db062a289c8158d940Benny Wong 70da83f4674a564007baac03db062a289c8158d940Benny Wongvoid SampleTable::CompositionDeltaLookup::setEntries( 71da83f4674a564007baac03db062a289c8158d940Benny Wong const uint32_t *deltaEntries, size_t numDeltaEntries) { 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock autolock(mLock); 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDeltaEntries = deltaEntries; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNumDeltaEntries = numDeltaEntries; 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrentDeltaEntry = 0; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrentEntrySampleIndex = 0; 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 79e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t SampleTable::CompositionDeltaLookup::getCompositionTimeOffset( 81e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks uint32_t sampleIndex) { 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock autolock(mLock); 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8494927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp if (mDeltaEntries == NULL) { 859b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li return 0; 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sampleIndex < mCurrentEntrySampleIndex) { 899b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li mCurrentDeltaEntry = 0; 909b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li mCurrentEntrySampleIndex = 0; 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (mCurrentDeltaEntry < mNumDeltaEntries) { 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t sampleCount = mDeltaEntries[2 * mCurrentDeltaEntry]; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sampleIndex < mCurrentEntrySampleIndex + sampleCount) { 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDeltaEntries[2 * mCurrentDeltaEntry + 1]; 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 98e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks 99e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks mCurrentEntrySampleIndex += sampleCount; 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ++mCurrentDeltaEntry; 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectSampleTable::SampleTable(const sp<DataSource> &source) 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mDataSource(source), 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChunkOffsetOffset(-1), 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChunkOffsetType(0), 1129b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li mNumChunkOffsets(0), 1139b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li mSampleToChunkOffset(-1), 1149b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li mNumSampleToChunkOffsets(0), 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSampleSizeOffset(-1), 1169b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li mSampleSizeFieldSize(0), 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDefaultSampleSize(0), 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNumSampleSizes(0), 1199b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li mTimeToSampleCount(0), 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTimeToSample(NULL), 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSampleTimeEntries(NULL), 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCompositionTimeDeltaEntries(NULL), 1239b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li mNumCompositionTimeDeltaEntries(0), 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCompositionDeltaLookup(new CompositionDeltaLookup), 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSyncSampleOffset(-1), 1269b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li mNumSyncSamples(0), 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSyncSamples(NULL), 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastSyncSampleIndex(0), 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSampleToChunkEntries(NULL) { 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSampleIterator = new SampleIterator(this); 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1339b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng LiSampleTable::~SampleTable() { 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete[] mSampleToChunkEntries; 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSampleToChunkEntries = NULL; 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1379b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li delete[] mSyncSamples; 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSyncSamples = NULL; 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete mCompositionDeltaLookup; 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCompositionDeltaLookup = NULL; 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete[] mCompositionTimeDeltaEntries; 1449b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li mCompositionTimeDeltaEntries = NULL; 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete[] mSampleTimeEntries; 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSampleTimeEntries = NULL; 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete[] mTimeToSample; 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTimeToSample = NULL; 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete mSampleIterator; 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSampleIterator = NULL; 154ffe1cf251a4f8469695b8acfa37270684dc1b70cWu-cheng Li} 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 156ffe1cf251a4f8469695b8acfa37270684dc1b70cWu-cheng Libool SampleTable::isValid() const { 1579b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li return mChunkOffsetOffset >= 0 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && mSampleToChunkOffset >= 0 1599b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li && mSampleSizeOffset >= 0 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && mTimeToSample != NULL; 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t SampleTable::setChunkOffsetParams( 164ffe1cf251a4f8469695b8acfa37270684dc1b70cWu-cheng Li uint32_t type, off64_t data_offset, size_t data_size) { 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mChunkOffsetOffset >= 0) { 166ffe1cf251a4f8469695b8acfa37270684dc1b70cWu-cheng Li return ERROR_MALFORMED; 1679b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CHECK(type == kChunkOffsetType32 || type == kChunkOffsetType64); 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChunkOffsetOffset = data_offset; 1729b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li mChunkOffsetType = type; 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (data_size < 8) { 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_MALFORMED; 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 177b8a10fe45657f2dcc50cae8a06805f8438a6937eWu-cheng Li 178b8a10fe45657f2dcc50cae8a06805f8438a6937eWu-cheng Li uint8_t header[8]; 179b8a10fe45657f2dcc50cae8a06805f8438a6937eWu-cheng Li if (mDataSource->readAt( 180b8a10fe45657f2dcc50cae8a06805f8438a6937eWu-cheng Li data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 181b8a10fe45657f2dcc50cae8a06805f8438a6937eWu-cheng Li return ERROR_IO; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (U32_AT(header) != 0) { 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Expected version = 0, flags = 0. 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_MALFORMED; 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNumChunkOffsets = U32_AT(&header[4]); 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mChunkOffsetType == kChunkOffsetType32) { 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (data_size < 8 + mNumChunkOffsets * 4) { 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_MALFORMED; 194df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main } 1957478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li } else { 196df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main if (data_size < 8 + mNumChunkOffsets * 8) { 197da0a56df963353a1f1bd1914fa31f870d982dd5aScott Main return ERROR_MALFORMED; 1989b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 1999b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return OK; 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2049b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Listatus_t SampleTable::setSampleToChunkParams( 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project off64_t data_offset, size_t data_size) { 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mSampleToChunkOffset >= 0) { 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_MALFORMED; 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2099b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSampleToChunkOffset = data_offset; 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (data_size < 8) { 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_MALFORMED; 2149b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint8_t header[8]; 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDataSource->readAt( 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_IO; 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2229b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (U32_AT(header) != 0) { 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Expected version = 0, flags = 0. 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_MALFORMED; 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNumSampleToChunkOffsets = U32_AT(&header[4]); 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (data_size < 8 + mNumSampleToChunkOffsets * 12) { 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_MALFORMED; 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23394927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp mSampleToChunkEntries = 234a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks new SampleToChunkEntry[mNumSampleToChunkOffsets]; 235a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks 23694927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) { 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint8_t buffer[12]; 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDataSource->readAt( 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSampleToChunkOffset + 8 + i * 12, buffer, sizeof(buffer)) 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != (ssize_t)sizeof(buffer)) { 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_IO; 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CHECK(U32_AT(buffer) >= 1); // chunk index is 1 based in the spec. 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24694927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp // We want the chunk index to be 0-based. 24794927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp mSampleToChunkEntries[i].startChunk = U32_AT(buffer) - 1; 24894927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp mSampleToChunkEntries[i].samplesPerChunk = U32_AT(&buffer[4]); 24994927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp mSampleToChunkEntries[i].chunkDesc = U32_AT(&buffer[8]); 25094927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp } 25194927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp 25294927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp return OK; 25394927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp} 25494927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp 25594927dffce1626898b59579dfc5af53b5de8cef6Andrew Harpstatus_t SampleTable::setSampleSizeParams( 25694927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp uint32_t type, off64_t data_offset, size_t data_size) { 25794927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp if (mSampleSizeOffset >= 0) { 25894927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp return ERROR_MALFORMED; 25994927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp } 26094927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp 26194927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp CHECK(type == kSampleSizeType32 || type == kSampleSizeTypeCompact); 26294927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp 26394927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp mSampleSizeOffset = data_offset; 26494927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp 26594927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp if (data_size < 12) { 26694927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp return ERROR_MALFORMED; 26794927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp } 26894927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp 26994927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp uint8_t header[12]; 27094927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp if (mDataSource->readAt( 27194927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 27294927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp return ERROR_IO; 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27594927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp if (U32_AT(header) != 0) { 27694927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp // Expected version = 0, flags = 0. 27794927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp return ERROR_MALFORMED; 27894927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp } 27994927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp 28094927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp mDefaultSampleSize = U32_AT(&header[4]); 28194927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp mNumSampleSizes = U32_AT(&header[8]); 28294927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp 28394927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp if (type == kSampleSizeType32) { 28494927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp mSampleSizeFieldSize = 32; 28594927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp 28694927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp if (mDefaultSampleSize != 0) { 28794927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp return OK; 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (data_size < 12 + mNumSampleSizes * 4) { 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_MALFORMED; 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mDefaultSampleSize & 0xffffff00) != 0) { 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The high 24 bits are reserved and must be 0. 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_MALFORMED; 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSampleSizeFieldSize = mDefaultSampleSize & 0xff; 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDefaultSampleSize = 0; 301c62f9bd13327937aa2d2f20b44215397120634c1Dave Sparks 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mSampleSizeFieldSize != 4 && mSampleSizeFieldSize != 8 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && mSampleSizeFieldSize != 16) { 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_MALFORMED; 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 306c62f9bd13327937aa2d2f20b44215397120634c1Dave Sparks 307c62f9bd13327937aa2d2f20b44215397120634c1Dave Sparks if (data_size < 12 + (mNumSampleSizes * mSampleSizeFieldSize + 4) / 8) { 308e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks return ERROR_MALFORMED; 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 310e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks } 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return OK; 313c62f9bd13327937aa2d2f20b44215397120634c1Dave Sparks} 314e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t SampleTable::setTimeToSampleParams( 316e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks off64_t data_offset, size_t data_size) { 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTimeToSample != NULL || data_size < 8) { 3189b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li return ERROR_MALFORMED; 319c62f9bd13327937aa2d2f20b44215397120634c1Dave Sparks } 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 321a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks uint8_t header[8]; 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDataSource->readAt( 323a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 324a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks return ERROR_IO; 325a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks } 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32794927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp if (U32_AT(header) != 0) { 328a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks // Expected version = 0, flags = 0. 329a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks return ERROR_MALFORMED; 330a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks } 33194927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTimeToSampleCount = U32_AT(&header[4]); 333a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks mTimeToSample = new uint32_t[mTimeToSampleCount * 2]; 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t size = sizeof(uint32_t) * mTimeToSampleCount * 2; 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDataSource->readAt( 337e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks data_offset + 8, mTimeToSample, size) < (ssize_t)size) { 338e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks return ERROR_IO; 339e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks } 340e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks 341e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks for (uint32_t i = 0; i < mTimeToSampleCount * 2; ++i) { 342e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks mTimeToSample[i] = ntohl(mTimeToSample[i]); 343c62f9bd13327937aa2d2f20b44215397120634c1Dave Sparks } 344e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return OK; 346e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks} 347e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks 348e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparksstatus_t SampleTable::setCompositionTimeToSampleParams( 349e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks off64_t data_offset, size_t data_size) { 350e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks LOGI("There are reordered frames present."); 35136f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li 352e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks if (mCompositionTimeDeltaEntries != NULL || data_size < 8) { 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_MALFORMED; 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 355c62f9bd13327937aa2d2f20b44215397120634c1Dave Sparks 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint8_t header[8]; 357e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks if (mDataSource->readAt( 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data_offset, header, sizeof(header)) 359e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks < (ssize_t)sizeof(header)) { 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_IO; 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (U32_AT(header) != 0) { 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Expected version = 0, flags = 0. 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_MALFORMED; 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t numEntries = U32_AT(&header[4]); 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (data_size != (numEntries + 1) * 8) { 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_MALFORMED; 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNumCompositionTimeDeltaEntries = numEntries; 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCompositionTimeDeltaEntries = new uint32_t[2 * numEntries]; 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDataSource->readAt( 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data_offset + 8, mCompositionTimeDeltaEntries, numEntries * 8) 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project < (ssize_t)numEntries * 8) { 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete[] mCompositionTimeDeltaEntries; 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCompositionTimeDeltaEntries = NULL; 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_IO; 3847478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li } 3857478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li 386df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main for (size_t i = 0; i < 2 * numEntries; ++i) { 387df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main mCompositionTimeDeltaEntries[i] = ntohl(mCompositionTimeDeltaEntries[i]); 3887478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li } 389df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main 390df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main mCompositionDeltaLookup->setEntries( 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCompositionTimeDeltaEntries, mNumCompositionTimeDeltaEntries); 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return OK; 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3959b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 3969b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Listatus_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size) { 3979b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (mSyncSampleOffset >= 0 || data_size < 8) { 3989b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li return ERROR_MALFORMED; 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSyncSampleOffset = data_offset; 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint8_t header[8]; 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDataSource->readAt( 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 4069b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li return ERROR_IO; 40736322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li } 40836322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li 40936322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li if (U32_AT(header) != 0) { 41036322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li // Expected version = 0, flags = 0. 41136322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li return ERROR_MALFORMED; 41236322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li } 413da0a56df963353a1f1bd1914fa31f870d982dd5aScott Main 4147478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li mNumSyncSamples = U32_AT(&header[4]); 4157478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li 416df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main if (mNumSyncSamples < 2) { 417df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main ALOGV("Table of sync samples is empty or has only a single entry!"); 418068ef42c3ffe1eccec10f97f08541304f679fe67Wu-cheng Li } 419068ef42c3ffe1eccec10f97f08541304f679fe67Wu-cheng Li 420068ef42c3ffe1eccec10f97f08541304f679fe67Wu-cheng Li mSyncSamples = new uint32_t[mNumSyncSamples]; 4217478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li size_t size = mNumSyncSamples * sizeof(uint32_t); 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDataSource->readAt(mSyncSampleOffset + 8, mSyncSamples, size) 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != (ssize_t)size) { 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_IO; 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i = 0; i < mNumSyncSamples; ++i) { 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSyncSamples[i] = ntohl(mSyncSamples[i]) - 1; 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return OK; 432244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang} 433244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang 434244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Changuint32_t SampleTable::countChunkOffsets() const { 435244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang return mNumChunkOffsets; 436244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang} 437244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang 438244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Changuint32_t SampleTable::countSamples() const { 439244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang return mNumSampleSizes; 440244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang} 441244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang 442244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Changstatus_t SampleTable::getMaxSampleSize(size_t *max_size) { 443244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang Mutex::Autolock autoLock(mLock); 444244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *max_size = 0; 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (uint32_t i = 0; i < mNumSampleSizes; ++i) { 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t sample_size; 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = getSampleSize_l(i, &sample_size); 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != OK) { 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return err; 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sample_size > *max_size) { 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *max_size = sample_size; 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return OK; 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4629b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t abs_difference(uint32_t time1, uint32_t time2) { 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return time1 > time2 ? time1 - time2 : time2 - time1; 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// static 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint SampleTable::CompareIncreasingTime(const void *_a, const void *_b) { 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const SampleTimeEntry *a = (const SampleTimeEntry *)_a; 4709b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li const SampleTimeEntry *b = (const SampleTimeEntry *)_b; 4719b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 4729b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (a->mCompositionTime < b->mCompositionTime) { 4739b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li return -1; 4749b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } else if (a->mCompositionTime > b->mCompositionTime) { 4759b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li return 1; 4769b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 4779b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 4789b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li return 0; 4799b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li} 48040057ce749c8c4d274db0352a2af4344bda92dbaWu-cheng Li 48140057ce749c8c4d274db0352a2af4344bda92dbaWu-cheng Livoid SampleTable::buildSampleEntriesTable() { 48240057ce749c8c4d274db0352a2af4344bda92dbaWu-cheng Li Mutex::Autolock autoLock(mLock); 48340057ce749c8c4d274db0352a2af4344bda92dbaWu-cheng Li 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mSampleTimeEntries != NULL) { 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSampleTimeEntries = new SampleTimeEntry[mNumSampleSizes]; 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 490e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks uint32_t sampleIndex = 0; 491e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks uint32_t sampleTime = 0; 492e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks 493e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks for (uint32_t i = 0; i < mTimeToSampleCount; ++i) { 494e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks uint32_t n = mTimeToSample[2 * i]; 4959b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li uint32_t delta = mTimeToSample[2 * i + 1]; 4969b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 4979b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li for (uint32_t j = 0; j < n; ++j) { 4989b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (sampleIndex < mNumSampleSizes) { 4999b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li // Technically this should always be the case if the file 5009b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li // is well-formed, but you know... there's (gasp) malformed 5019b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li // content out there. 5029b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 5039b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li mSampleTimeEntries[sampleIndex].mSampleIndex = sampleIndex; 5049b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 5059b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li uint32_t compTimeDelta = 506e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks mCompositionDeltaLookup->getCompositionTimeOffset( 50740057ce749c8c4d274db0352a2af4344bda92dbaWu-cheng Li sampleIndex); 50840057ce749c8c4d274db0352a2af4344bda92dbaWu-cheng Li 50940057ce749c8c4d274db0352a2af4344bda92dbaWu-cheng Li mSampleTimeEntries[sampleIndex].mCompositionTime = 51040057ce749c8c4d274db0352a2af4344bda92dbaWu-cheng Li sampleTime + compTimeDelta; 511e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks } 512e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks 513e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks ++sampleIndex; 514e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks sampleTime += delta; 515e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks } 516e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks } 517e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project qsort(mSampleTimeEntries, mNumSampleSizes, sizeof(SampleTimeEntry), 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CompareIncreasingTime); 520e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks} 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t SampleTable::findSampleAtTime( 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t req_time, uint32_t *sample_index, uint32_t flags) { 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buildSampleEntriesTable(); 525e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks 52636f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li uint32_t left = 0; 52736f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li uint32_t right = mNumSampleSizes; 52836f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li while (left < right) { 52936f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li uint32_t center = (left + right) / 2; 53036f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li uint32_t centerTime = mSampleTimeEntries[center].mCompositionTime; 53136f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li 53236f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li if (req_time < centerTime) { 53336f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li right = center; 53436f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li } else if (req_time > centerTime) { 53536f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li left = center + 1; 53636f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li } else { 53736f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li left = center; 53836f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li break; 53936f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li } 54036f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li } 54136f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li 54236f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li if (left == mNumSampleSizes) { 54336f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li if (flags == kFlagAfter) { 54436f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li return ERROR_OUT_OF_RANGE; 54536f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li } 546d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang 547d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang --left; 548d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang } 549d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang 550d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang uint32_t closestIndex = left; 551d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang 552d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang switch (flags) { 553d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang case kFlagBefore: 554d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang { 555e7bd22a9d9441916aa9c67d80ee9f02a2d3e10e5Chih-Chung Chang while (closestIndex > 0 556e7bd22a9d9441916aa9c67d80ee9f02a2d3e10e5Chih-Chung Chang && mSampleTimeEntries[closestIndex].mCompositionTime 557d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang > req_time) { 558d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang --closestIndex; 559d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang } 560d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang break; 561e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks } 56277153ee04e4172cb0e123cadaa1e76671dbd840eWu-cheng Li 56377153ee04e4172cb0e123cadaa1e76671dbd840eWu-cheng Li case kFlagAfter: 564e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks { 565e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks while (closestIndex + 1 < mNumSampleSizes 566e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks && mSampleTimeEntries[closestIndex].mCompositionTime 567e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks < req_time) { 568e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks ++closestIndex; 56936f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li } 57036f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li break; 57136f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li } 57236f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li 57336f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li default: 57436f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li { 575e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks CHECK(flags == kFlagClosest); 57636f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li 577e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks if (closestIndex > 0) { 57836f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li // Check left neighbour and pick closest. 579e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks uint32_t absdiff1 = 580e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks abs_difference( 581e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks mSampleTimeEntries[closestIndex].mCompositionTime, 58236f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li req_time); 58336f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li 584e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks uint32_t absdiff2 = 58577153ee04e4172cb0e123cadaa1e76671dbd840eWu-cheng Li abs_difference( 586e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks mSampleTimeEntries[closestIndex - 1].mCompositionTime, 587e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks req_time); 588e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks 589e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks if (absdiff1 > absdiff2) { 590e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks closestIndex = closestIndex - 1; 5919b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 592a1b653d41df9a7999e1dba2a508295671ff6771dJames Dong } 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5989b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li *sample_index = mSampleTimeEntries[closestIndex].mSampleIndex; 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return OK; 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t SampleTable::findSyncSampleNear( 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t start_sample_index, uint32_t *sample_index, uint32_t flags) { 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock autoLock(mLock); 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *sample_index = 0; 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mSyncSampleOffset < 0) { 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // All samples are sync-samples. 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *sample_index = start_sample_index; 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return OK; 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNumSyncSamples == 0) { 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *sample_index = 0; 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return OK; 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t left = 0; 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t right = mNumSyncSamples; 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (left < right) { 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t center = left + (right - left) / 2; 6249b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li uint32_t x = mSyncSamples[center]; 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (start_sample_index < x) { 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project right = center; 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (start_sample_index > x) { 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project left = center + 1; 6309b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } else { 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project left = center; 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Now ssi[left] is the sync sample index just before (or at) 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // start_sample_index. 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Also start_sample_index < ssi[left + 1], if left + 1 < mNumSyncSamples. 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t x = mSyncSamples[left]; 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (left + 1 < mNumSyncSamples) { 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t y = mSyncSamples[left + 1]; 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // our sample lies between sync samples x and y. 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = mSampleIterator->seekTo(start_sample_index); 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != OK) { 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return err; 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t sample_time = mSampleIterator->getSampleTime(); 6539b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = mSampleIterator->seekTo(x); 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != OK) { 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return err; 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t x_time = mSampleIterator->getSampleTime(); 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = mSampleIterator->seekTo(y); 6614c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li if (err != OK) { 6624c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li return err; 6634c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li } 6644c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li 6654c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li uint32_t y_time = mSampleIterator->getSampleTime(); 6664c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li 6674c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li if (abs_difference(x_time, sample_time) 6684c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li > abs_difference(y_time, sample_time)) { 6694c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li // Pick the sync sample closest (timewise) to the start-sample. 6704c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li x = y; 6714c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li ++left; 6724c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li } 6734c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li } 6744c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li 6754c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li switch (flags) { 6764c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li case kFlagBefore: 6774c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li { 6784c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li if (x > start_sample_index) { 6794c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li CHECK(left > 0); 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x = mSyncSamples[left - 1]; 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (x > start_sample_index) { 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The table of sync sample indices was not sorted 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // properly. 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_MALFORMED; 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6889b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 6899b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li break; 6909b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 6919b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 6929b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li case kFlagAfter: 6939b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li { 6949b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (x < start_sample_index) { 6959b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (left + 1 >= mNumSyncSamples) { 6969b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li return ERROR_OUT_OF_RANGE; 6979b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 6989b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x = mSyncSamples[left + 1]; 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7019b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (x < start_sample_index) { 7029b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li // The table of sync sample indices was not sorted 7039b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li // properly. 7049b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li return ERROR_MALFORMED; 7059b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 7069b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 7074c4300c71229638183d814ab8374e09f722910f5Wu-cheng Li 7089b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li break; 7099b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 7109b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 7119b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li default: 7129b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li break; 7139b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 7149b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 7159b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li *sample_index = x; 7169b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 7179b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li return OK; 7189b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li} 7199b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 7209b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Listatus_t SampleTable::findThumbnailSample(uint32_t *sample_index) { 7219b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li Mutex::Autolock autoLock(mLock); 72236322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li 7236c8d2760736a0753dad96b4bb8f98c7d075e6d54Wu-cheng Li if (mSyncSampleOffset < 0) { 7246c8d2760736a0753dad96b4bb8f98c7d075e6d54Wu-cheng Li // All samples are sync-samples. 7256c8d2760736a0753dad96b4bb8f98c7d075e6d54Wu-cheng Li *sample_index = 0; 726ff723b6c43d5a8fd0ae0e0732f5d47012d74e01dWu-cheng Li return OK; 7279b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 7289b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 7299b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li uint32_t bestSampleIndex = 0; 7309b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li size_t maxSampleSize = 0; 7319b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 7329b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li static const size_t kMaxNumSyncSamplesToScan = 20; 7339b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 7349b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li // Consider the first kMaxNumSyncSamplesToScan sync samples and 7359b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li // pick the one with the largest (compressed) size as the thumbnail. 7369b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 7379b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li size_t numSamplesToScan = mNumSyncSamples; 7389b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (numSamplesToScan > kMaxNumSyncSamplesToScan) { 7399b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li numSamplesToScan = kMaxNumSyncSamplesToScan; 7409b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 7419b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 7429b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li for (size_t i = 0; i < numSamplesToScan; ++i) { 7439b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li uint32_t x = mSyncSamples[i]; 7449b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 7459b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li // Now x is a sample index. 7469b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li size_t sampleSize; 7479b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li status_t err = getSampleSize_l(x, &sampleSize); 7489b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (err != OK) { 7499b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li return err; 7509b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 7519b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 7529b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (i == 0 || sampleSize > maxSampleSize) { 7539b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li bestSampleIndex = x; 7549b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li maxSampleSize = sampleSize; 7559b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 7569b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 7579b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 7589b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li *sample_index = bestSampleIndex; 7599b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 7609b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li return OK; 7619b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li} 76236f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li 7639b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Listatus_t SampleTable::getSampleSize_l( 764068ef42c3ffe1eccec10f97f08541304f679fe67Wu-cheng Li uint32_t sampleIndex, size_t *sampleSize) { 765068ef42c3ffe1eccec10f97f08541304f679fe67Wu-cheng Li return mSampleIterator->getSampleSizeDirect( 7669b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li sampleIndex, sampleSize); 7679b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li} 76836f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li 7699b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Listatus_t SampleTable::getMetaDataForSample( 770068ef42c3ffe1eccec10f97f08541304f679fe67Wu-cheng Li uint32_t sampleIndex, 771068ef42c3ffe1eccec10f97f08541304f679fe67Wu-cheng Li off64_t *offset, 7729b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li size_t *size, 7739b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li uint32_t *compositionTime, 77436f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li bool *isSyncSample) { 7759b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li Mutex::Autolock autoLock(mLock); 7769b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 7779b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li status_t err; 7789b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if ((err = mSampleIterator->seekTo(sampleIndex)) != OK) { 77936f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li return err; 78036322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li } 781068ef42c3ffe1eccec10f97f08541304f679fe67Wu-cheng Li 782068ef42c3ffe1eccec10f97f08541304f679fe67Wu-cheng Li if (offset) { 78336322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li *offset = mSampleIterator->getSampleOffset(); 784068ef42c3ffe1eccec10f97f08541304f679fe67Wu-cheng Li } 7859b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 7869b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (size) { 7879b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li *size = mSampleIterator->getSampleSize(); 7889b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 7899b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 7909b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (compositionTime) { 7919b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li *compositionTime = mSampleIterator->getSampleTime(); 7929b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } 7939b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 7949b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (isSyncSample) { 7959b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li *isSyncSample = false; 7969b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li if (mSyncSampleOffset < 0) { 7979b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li // Every sample is a sync sample. 7989b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li *isSyncSample = true; 7999b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li } else { 8009b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li size_t i = (mLastSyncSampleIndex < mNumSyncSamples) 8019b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li && (mSyncSamples[mLastSyncSampleIndex] <= sampleIndex) 8029b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li ? mLastSyncSampleIndex : 0; 80336322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li 80436322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li while (i < mNumSyncSamples && mSyncSamples[i] < sampleIndex) { 80536322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li ++i; 80636322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li } 80736322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li 80836f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li if (i < mNumSyncSamples && mSyncSamples[i] == sampleIndex) { 80936322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li *isSyncSample = true; 81036322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li } 81136322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li 81236322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li mLastSyncSampleIndex = i; 81336322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li } 81436322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li } 81536f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li 81636322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li return OK; 81736322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li} 81836322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li 81936322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Liuint32_t SampleTable::getCompositionTimeOffset(uint32_t sampleIndex) { 82036322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li return mCompositionDeltaLookup->getCompositionTimeOffset(sampleIndex); 82136322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li} 82236322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li 82336322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li} // namespace android 8249b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li 8259b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li