TrackFragment.cpp revision b7e75cfd64893dde230dfc1c3b281a00ca1b4470
1840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber/* 2840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * Copyright (C) 2012 The Android Open Source Project 3840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * 4840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * you may not use this file except in compliance with the License. 6840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * You may obtain a copy of the License at 7840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * 8840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * 10840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * Unless required by applicable law or agreed to in writing, software 11840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * See the License for the specific language governing permissions and 14840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * limitations under the License. 15840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber */ 16840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 17840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber//#define LOG_NDEBUG 0 18840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#define LOG_TAG "TrackFragment" 19840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#include <utils/Log.h> 20840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 21840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#include "TrackFragment.h" 22840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 23840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#include <media/stagefright/MediaErrors.h> 24840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#include <media/stagefright/Utils.h> 25840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 26840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#include <media/stagefright/foundation/ADebug.h> 27840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 28840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Hubernamespace android { 29840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 30840667883fd09d44015716d79bc3ac4d60edc0f0Andreas HuberParser::DynamicTrackFragment::DynamicTrackFragment() 31840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber : mComplete(false), 32840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleIndex(0) { 33840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 34840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 35840667883fd09d44015716d79bc3ac4d60edc0f0Andreas HuberParser::DynamicTrackFragment::~DynamicTrackFragment() { 36840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 37840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 38840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huberstatus_t Parser::DynamicTrackFragment::getSample(SampleInfo *info) { 39840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (mSampleIndex >= mSamples.size()) { 40840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return mComplete ? ERROR_END_OF_STREAM : -EWOULDBLOCK; 41840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 42840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 43840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber *info = mSamples.itemAt(mSampleIndex); 44840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 45840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 46840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 47840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 48840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Hubervoid Parser::DynamicTrackFragment::advance() { 49840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ++mSampleIndex; 50840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 51840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 52840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Hubervoid Parser::DynamicTrackFragment::addSample( 53840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber off64_t dataOffset, size_t sampleSize, 54840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t presentationTime, 55840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber size_t sampleDescIndex, 56840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t flags) { 57840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSamples.push(); 58840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber SampleInfo *sampleInfo = &mSamples.editItemAt(mSamples.size() - 1); 59840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 60840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleInfo->mOffset = dataOffset; 61840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleInfo->mSize = sampleSize; 62840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleInfo->mPresentationTime = presentationTime; 63840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleInfo->mSampleDescIndex = sampleDescIndex; 64840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleInfo->mFlags = flags; 65840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 66840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 67840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huberstatus_t Parser::DynamicTrackFragment::signalCompletion() { 68840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mComplete = true; 69840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 70840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 71840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 72840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 73840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huberbool Parser::DynamicTrackFragment::complete() const { 74840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return mComplete; 75840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 76840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 77840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber//////////////////////////////////////////////////////////////////////////////// 78840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 79840667883fd09d44015716d79bc3ac4d60edc0f0Andreas HuberParser::StaticTrackFragment::StaticTrackFragment() 80840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber : mSampleIndex(0), 81840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleCount(0), 82840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleToChunkIndex(-1), 83840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleToChunkRemaining(0), 84840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mPrevChunkIndex(0xffffffff), 85840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mNextSampleOffset(0) { 86840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 87840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 88840667883fd09d44015716d79bc3ac4d60edc0f0Andreas HuberParser::StaticTrackFragment::~StaticTrackFragment() { 89840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 90840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 91840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huberstatus_t Parser::StaticTrackFragment::getSample(SampleInfo *info) { 92840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (mSampleIndex >= mSampleCount) { 93840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_END_OF_STREAM; 94840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 95840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 96840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber *info = mSampleInfo; 97840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 98840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ALOGV("returning sample %d at [0x%08llx, 0x%08llx)", 99840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleIndex, 100840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber info->mOffset, info->mOffset + info->mSize); 101840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 102840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 103840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 104840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 105840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Hubervoid Parser::StaticTrackFragment::updateSampleInfo() { 106840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (mSampleIndex >= mSampleCount) { 107840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return; 108840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 109840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 110840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (mSampleSizes != NULL) { 111840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t defaultSampleSize = U32_AT(mSampleSizes->data() + 4); 112840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (defaultSampleSize > 0) { 113840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleInfo.mSize = defaultSampleSize; 114840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else { 115840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleInfo.mSize= U32_AT(mSampleSizes->data() + 12 + 4 * mSampleIndex); 116840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 117840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else { 118840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK(mCompactSampleSizes != NULL); 119840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 120840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t fieldSize = U32_AT(mCompactSampleSizes->data() + 4); 121840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 122840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber switch (fieldSize) { 123840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber case 4: 124840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { 125840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber unsigned byte = mCompactSampleSizes->data()[12 + mSampleIndex / 2]; 126840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleInfo.mSize = (mSampleIndex & 1) ? byte & 0x0f : byte >> 4; 127840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 128840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 129840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 130840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber case 8: 131840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { 132840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleInfo.mSize = mCompactSampleSizes->data()[12 + mSampleIndex]; 133840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 134840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 135840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 136840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber default: 137840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { 138840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK_EQ(fieldSize, 16); 139840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleInfo.mSize = 140840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber U16_AT(mCompactSampleSizes->data() + 12 + mSampleIndex * 2); 141840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 142840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 143840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 144840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 145840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 146840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK_GT(mSampleToChunkRemaining, 0); 147840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 148840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber // The sample desc index is 1-based... XXX 149840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleInfo.mSampleDescIndex = 150840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber U32_AT(mSampleToChunk->data() + 8 + 12 * mSampleToChunkIndex + 8); 151840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 152840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t chunkIndex = 153840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber U32_AT(mSampleToChunk->data() + 8 + 12 * mSampleToChunkIndex); 154840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 155840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK_GE(chunkIndex, 1); 156840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber --chunkIndex; 157840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 158840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (chunkIndex != mPrevChunkIndex) { 159840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mPrevChunkIndex = chunkIndex; 160840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 161840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (mChunkOffsets != NULL) { 162840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t entryCount = U32_AT(mChunkOffsets->data() + 4); 163840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 164840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (chunkIndex >= entryCount) { 165840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleIndex = mSampleCount; 166840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return; 167840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 168840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 169840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mNextSampleOffset = 170840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber U32_AT(mChunkOffsets->data() + 8 + 4 * chunkIndex); 171840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else { 172840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK(mChunkOffsets64 != NULL); 173840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 174840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t entryCount = U32_AT(mChunkOffsets64->data() + 4); 175840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 176840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (chunkIndex >= entryCount) { 177840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleIndex = mSampleCount; 178840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return; 179840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 180840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 181840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mNextSampleOffset = 182840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber U64_AT(mChunkOffsets64->data() + 8 + 8 * chunkIndex); 183840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 184840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 185840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 186840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleInfo.mOffset = mNextSampleOffset; 187840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 188840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleInfo.mPresentationTime = 0; 189840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleInfo.mFlags = 0; 190840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 191840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 192840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Hubervoid Parser::StaticTrackFragment::advance() { 193840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mNextSampleOffset += mSampleInfo.mSize; 194840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 195840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ++mSampleIndex; 196840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (--mSampleToChunkRemaining == 0) { 197840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t entryCount = U32_AT(mSampleToChunk->data() + 4); 198840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 199840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if ((uint32_t)(mSampleToChunkIndex + 1) == entryCount) { 200840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleIndex = mSampleCount; // EOS. 201840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return; 202840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 203840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 204840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ++mSampleToChunkIndex; 205840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleToChunkRemaining = 206840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber U32_AT(mSampleToChunk->data() + 8 + 12 * mSampleToChunkIndex + 4); 207840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 208840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 209840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber updateSampleInfo(); 210840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 211840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 212840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huberstatic void setU32At(uint8_t *ptr, uint32_t x) { 213840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ptr[0] = x >> 24; 214840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ptr[1] = (x >> 16) & 0xff; 215840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ptr[2] = (x >> 8) & 0xff; 216840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ptr[3] = x & 0xff; 217840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 218840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 219840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Hubervoid Parser::StaticTrackFragment::fixSampleToChunkTableIfNecessary() { 220b7e75cfd64893dde230dfc1c3b281a00ca1b4470Marco Nelissen if (mSampleToChunk == NULL) { 221b7e75cfd64893dde230dfc1c3b281a00ca1b4470Marco Nelissen return; 222b7e75cfd64893dde230dfc1c3b281a00ca1b4470Marco Nelissen } 223840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t entryCount = U32_AT(mSampleToChunk->data() + 4); 224840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t totalSamples = 0; 225840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber for (uint32_t i = 0; i < entryCount; ++i) { 226840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber totalSamples += U32_AT(mSampleToChunk->data() + 8 + 12 * i + 4); 227840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 228840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 229840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (totalSamples < mSampleCount) { 230840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber // Some samples are not accounted for in the sample-to-chunk 231840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber // data. Fabricate an extra chunk adjacent to the last one 232840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber // in the table with the same sample desription index. 233840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 234840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ALOGW("Faking an extra sample-to-chunk entry for %d samples.", 235840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleCount - totalSamples); 236840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 237840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t lastChunkIndex = 238840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber U32_AT(mSampleToChunk->data() + 8 + 12 * (entryCount - 1)); 239840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 240840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t lastSampleDescriptionIndex = 241840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber U32_AT(mSampleToChunk->data() + 8 + 12 * (entryCount - 1) + 8); 242840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 243840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint8_t *ptr = mSampleToChunk->data() + 8 + 12 * entryCount; 244840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 245840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber setU32At(ptr, lastChunkIndex + 1); 246840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber setU32At(ptr + 4, mSampleCount - totalSamples); 247840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber setU32At(ptr + 8, lastSampleDescriptionIndex); 248840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber setU32At(mSampleToChunk->data() + 4, entryCount + 1); 249840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 250840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 251840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 252840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huberstatus_t Parser::StaticTrackFragment::signalCompletion() { 253840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber fixSampleToChunkTableIfNecessary(); 254840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 255840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleToChunkIndex = 0; 256840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 257b7e75cfd64893dde230dfc1c3b281a00ca1b4470Marco Nelissen mSampleToChunkRemaining = (mSampleToChunk == NULL) ? 0 : 258840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber U32_AT(mSampleToChunk->data() + 8 + 12 * mSampleToChunkIndex + 4); 259840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 260840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber updateSampleInfo(); 261840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 262840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 263840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 264840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 265840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huberbool Parser::StaticTrackFragment::complete() const { 266840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return true; 267840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 268840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 269840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huberstatus_t Parser::StaticTrackFragment::parseSampleSizes( 270840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber Parser *parser, uint32_t type, size_t offset, uint64_t size) { 271840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 12 > size) { 272840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 273840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 274840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 275840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (parser->readU32(offset) != 0) { 276840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 277840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 278840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 279840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t sampleSize = parser->readU32(offset + 4); 280840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t sampleCount = parser->readU32(offset + 8); 281840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 282840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (sampleSize == 0 && offset + 12 + sampleCount * 4 != size) { 283840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 284840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 285840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 286840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber parser->copyBuffer(&mSampleSizes, offset, size); 287840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 288840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleCount = sampleCount; 289840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 290840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 291840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 292840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 293840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huberstatus_t Parser::StaticTrackFragment::parseCompactSampleSizes( 294840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber Parser *parser, uint32_t type, size_t offset, uint64_t size) { 295840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 12 > size) { 296840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 297840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 298840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 299840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (parser->readU32(offset) != 0) { 300840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 301840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 302840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 303840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t fieldSize = parser->readU32(offset + 4); 304840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 305840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (fieldSize != 4 && fieldSize != 8 && fieldSize != 16) { 306840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 307840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 308840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 309840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t sampleCount = parser->readU32(offset + 8); 310840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 311840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 12 + (sampleCount * fieldSize + 4) / 8 != size) { 312840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 313840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 314840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 315840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber parser->copyBuffer(&mCompactSampleSizes, offset, size); 316840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 317840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleCount = sampleCount; 318840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 319840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 320840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 321840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 322840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huberstatus_t Parser::StaticTrackFragment::parseSampleToChunk( 323840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber Parser *parser, uint32_t type, size_t offset, uint64_t size) { 324840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 8 > size) { 325840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 326840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 327840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 328840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (parser->readU32(offset) != 0) { 329840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 330840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 331840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 332840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t entryCount = parser->readU32(offset + 4); 333840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 334b7e75cfd64893dde230dfc1c3b281a00ca1b4470Marco Nelissen if (entryCount == 0) { 335b7e75cfd64893dde230dfc1c3b281a00ca1b4470Marco Nelissen return OK; 336b7e75cfd64893dde230dfc1c3b281a00ca1b4470Marco Nelissen } 337b7e75cfd64893dde230dfc1c3b281a00ca1b4470Marco Nelissen 338b7e75cfd64893dde230dfc1c3b281a00ca1b4470Marco Nelissen if (offset + 8 + entryCount * 12 != size) { 339840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 340840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 341840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 342840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber parser->copyBuffer(&mSampleToChunk, offset, size, 12 /* extra */); 343840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 344840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 345840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 346840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 347840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huberstatus_t Parser::StaticTrackFragment::parseChunkOffsets( 348840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber Parser *parser, uint32_t type, size_t offset, uint64_t size) { 349840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 8 > size) { 350840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 351840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 352840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 353840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (parser->readU32(offset) != 0) { 354840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 355840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 356840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 357840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t entryCount = parser->readU32(offset + 4); 358840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 359840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 8 + entryCount * 4 != size) { 360840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 361840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 362840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 363840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber parser->copyBuffer(&mChunkOffsets, offset, size); 364840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 365840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 366840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 367840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 368840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huberstatus_t Parser::StaticTrackFragment::parseChunkOffsets64( 369840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber Parser *parser, uint32_t type, size_t offset, uint64_t size) { 370840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 8 > size) { 371840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 372840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 373840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 374840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (parser->readU32(offset) != 0) { 375840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 376840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 377840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 378840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t entryCount = parser->readU32(offset + 4); 379840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 380840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 8 + entryCount * 8 != size) { 381840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 382840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 383840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 384840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber parser->copyBuffer(&mChunkOffsets64, offset, size); 385840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 386840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 387840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 388840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 389840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} // namespace android 390840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 391