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> 27b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber#include <media/stagefright/foundation/hexdump.h> 28840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 29840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Hubernamespace android { 30840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 31cb1f88c684140ce0eb407049a78f889bc7d51be1Marco NelissenFragmentedMP4Parser::DynamicTrackFragment::DynamicTrackFragment() 32840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber : mComplete(false), 33840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleIndex(0) { 34840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 35840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 36cb1f88c684140ce0eb407049a78f889bc7d51be1Marco NelissenFragmentedMP4Parser::DynamicTrackFragment::~DynamicTrackFragment() { 37840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 38840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 39cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::DynamicTrackFragment::getSample(SampleInfo *info) { 40840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (mSampleIndex >= mSamples.size()) { 41840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return mComplete ? ERROR_END_OF_STREAM : -EWOULDBLOCK; 42840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 43840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 44840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber *info = mSamples.itemAt(mSampleIndex); 45840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 46840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 47840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 48840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 49cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenvoid FragmentedMP4Parser::DynamicTrackFragment::advance() { 50840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ++mSampleIndex; 51840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 52840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 53cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenvoid FragmentedMP4Parser::DynamicTrackFragment::addSample( 54840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber off64_t dataOffset, size_t sampleSize, 55840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t presentationTime, 56840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber size_t sampleDescIndex, 57840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t flags) { 58840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSamples.push(); 59840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber SampleInfo *sampleInfo = &mSamples.editItemAt(mSamples.size() - 1); 60840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 61840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleInfo->mOffset = dataOffset; 62840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleInfo->mSize = sampleSize; 63840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleInfo->mPresentationTime = presentationTime; 64840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleInfo->mSampleDescIndex = sampleDescIndex; 65840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleInfo->mFlags = flags; 66840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 67840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 68cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::DynamicTrackFragment::signalCompletion() { 69840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mComplete = true; 70840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 71840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 72840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 73840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 74cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenbool FragmentedMP4Parser::DynamicTrackFragment::complete() const { 75840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return mComplete; 76840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 77840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 78840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber//////////////////////////////////////////////////////////////////////////////// 79840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 80cb1f88c684140ce0eb407049a78f889bc7d51be1Marco NelissenFragmentedMP4Parser::StaticTrackFragment::StaticTrackFragment() 81840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber : mSampleIndex(0), 82840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleCount(0), 83b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber mChunkIndex(0), 84840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleToChunkIndex(-1), 85840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleToChunkRemaining(0), 86840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mPrevChunkIndex(0xffffffff), 87840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mNextSampleOffset(0) { 88840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 89840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 90cb1f88c684140ce0eb407049a78f889bc7d51be1Marco NelissenFragmentedMP4Parser::StaticTrackFragment::~StaticTrackFragment() { 91840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 92840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 93cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::StaticTrackFragment::getSample(SampleInfo *info) { 94840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (mSampleIndex >= mSampleCount) { 95840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_END_OF_STREAM; 96840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 97840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 98840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber *info = mSampleInfo; 99840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 100840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ALOGV("returning sample %d at [0x%08llx, 0x%08llx)", 101840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleIndex, 102840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber info->mOffset, info->mOffset + info->mSize); 103840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 104840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 105840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 106840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 107cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenvoid FragmentedMP4Parser::StaticTrackFragment::updateSampleInfo() { 108840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (mSampleIndex >= mSampleCount) { 109840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return; 110840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 111840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 112840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (mSampleSizes != NULL) { 113840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t defaultSampleSize = U32_AT(mSampleSizes->data() + 4); 114840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (defaultSampleSize > 0) { 115840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleInfo.mSize = defaultSampleSize; 116840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else { 117840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleInfo.mSize= U32_AT(mSampleSizes->data() + 12 + 4 * mSampleIndex); 118840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 119840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else { 120840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK(mCompactSampleSizes != NULL); 121840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 122840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t fieldSize = U32_AT(mCompactSampleSizes->data() + 4); 123840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 124840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber switch (fieldSize) { 125840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber case 4: 126840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { 127840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber unsigned byte = mCompactSampleSizes->data()[12 + mSampleIndex / 2]; 128840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleInfo.mSize = (mSampleIndex & 1) ? byte & 0x0f : byte >> 4; 129840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 130840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 131840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 132840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber case 8: 133840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { 134840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleInfo.mSize = mCompactSampleSizes->data()[12 + mSampleIndex]; 135840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 136840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 137840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 138840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber default: 139840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { 140840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK_EQ(fieldSize, 16); 141840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleInfo.mSize = 142840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber U16_AT(mCompactSampleSizes->data() + 12 + mSampleIndex * 2); 143840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 144840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 145840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 146840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 147840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 148840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK_GT(mSampleToChunkRemaining, 0); 149840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 150840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber // The sample desc index is 1-based... XXX 151840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleInfo.mSampleDescIndex = 152840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber U32_AT(mSampleToChunk->data() + 8 + 12 * mSampleToChunkIndex + 8); 153840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 154b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber if (mChunkIndex != mPrevChunkIndex) { 155b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber mPrevChunkIndex = mChunkIndex; 156840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 157840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (mChunkOffsets != NULL) { 158840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t entryCount = U32_AT(mChunkOffsets->data() + 4); 159840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 160b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber if (mChunkIndex >= entryCount) { 161840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleIndex = mSampleCount; 162840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return; 163840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 164840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 165840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mNextSampleOffset = 166b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber U32_AT(mChunkOffsets->data() + 8 + 4 * mChunkIndex); 167840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else { 168840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK(mChunkOffsets64 != NULL); 169840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 170840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t entryCount = U32_AT(mChunkOffsets64->data() + 4); 171840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 172b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber if (mChunkIndex >= entryCount) { 173840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleIndex = mSampleCount; 174840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return; 175840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 176840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 177840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mNextSampleOffset = 178b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber U64_AT(mChunkOffsets64->data() + 8 + 8 * mChunkIndex); 179840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 180840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 181840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 182840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleInfo.mOffset = mNextSampleOffset; 183840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 184840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleInfo.mPresentationTime = 0; 185840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleInfo.mFlags = 0; 186840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 187840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 188cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenvoid FragmentedMP4Parser::StaticTrackFragment::advance() { 189840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mNextSampleOffset += mSampleInfo.mSize; 190840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 191840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ++mSampleIndex; 192840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (--mSampleToChunkRemaining == 0) { 193b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber ++mChunkIndex; 194b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber 195840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t entryCount = U32_AT(mSampleToChunk->data() + 4); 196840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 197b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber // If this is the last entry in the sample to chunk table, we will 198b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber // stay on this entry. 199b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber if ((uint32_t)(mSampleToChunkIndex + 1) < entryCount) { 200b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber uint32_t nextChunkIndex = 201b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber U32_AT(mSampleToChunk->data() + 8 + 12 * (mSampleToChunkIndex + 1)); 202b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber 203b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber CHECK_GE(nextChunkIndex, 1u); 204b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber --nextChunkIndex; 205b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber 206b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber if (mChunkIndex >= nextChunkIndex) { 207b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber CHECK_EQ(mChunkIndex, nextChunkIndex); 208b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber ++mSampleToChunkIndex; 209b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber } 210840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 211840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 212840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleToChunkRemaining = 213840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber U32_AT(mSampleToChunk->data() + 8 + 12 * mSampleToChunkIndex + 4); 214840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 215840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 216840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber updateSampleInfo(); 217840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 218840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 219840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huberstatic void setU32At(uint8_t *ptr, uint32_t x) { 220840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ptr[0] = x >> 24; 221840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ptr[1] = (x >> 16) & 0xff; 222840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ptr[2] = (x >> 8) & 0xff; 223840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ptr[3] = x & 0xff; 224840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 225840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 226cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::StaticTrackFragment::signalCompletion() { 227840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleToChunkIndex = 0; 228840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 229b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber mSampleToChunkRemaining = 230b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber (mSampleToChunk == NULL) 231b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber ? 0 232b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber : U32_AT(mSampleToChunk->data() + 8 + 12 * mSampleToChunkIndex + 4); 233840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 234840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber updateSampleInfo(); 235840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 236840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 237840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 238840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 239cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenbool FragmentedMP4Parser::StaticTrackFragment::complete() const { 240840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return true; 241840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 242840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 243cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::StaticTrackFragment::parseSampleSizes( 244cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissen FragmentedMP4Parser *parser, uint32_t type, size_t offset, uint64_t size) { 245840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 12 > size) { 246840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 247840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 248840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 249840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (parser->readU32(offset) != 0) { 250840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 251840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 252840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 253840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t sampleSize = parser->readU32(offset + 4); 254840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t sampleCount = parser->readU32(offset + 8); 255840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 256840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (sampleSize == 0 && offset + 12 + sampleCount * 4 != size) { 257840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 258840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 259840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 260840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber parser->copyBuffer(&mSampleSizes, offset, size); 261840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 262840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleCount = sampleCount; 263840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 264840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 265840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 266840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 267cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::StaticTrackFragment::parseCompactSampleSizes( 268cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissen FragmentedMP4Parser *parser, uint32_t type, size_t offset, uint64_t size) { 269840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 12 > size) { 270840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 271840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 272840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 273840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (parser->readU32(offset) != 0) { 274840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 275840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 276840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 277840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t fieldSize = parser->readU32(offset + 4); 278840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 279840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (fieldSize != 4 && fieldSize != 8 && fieldSize != 16) { 280840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 281840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 282840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 283840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t sampleCount = parser->readU32(offset + 8); 284840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 285840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 12 + (sampleCount * fieldSize + 4) / 8 != size) { 286840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 287840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 288840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 289840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber parser->copyBuffer(&mCompactSampleSizes, offset, size); 290840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 291840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSampleCount = sampleCount; 292840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 293840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 294840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 295840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 296cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::StaticTrackFragment::parseSampleToChunk( 297cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissen FragmentedMP4Parser *parser, uint32_t type, size_t offset, uint64_t size) { 298840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 8 > size) { 299840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 300840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 301840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 302840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (parser->readU32(offset) != 0) { 303840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 304840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 305840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 306840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t entryCount = parser->readU32(offset + 4); 307840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 308b7e75cfd64893dde230dfc1c3b281a00ca1b4470Marco Nelissen if (entryCount == 0) { 309b7e75cfd64893dde230dfc1c3b281a00ca1b4470Marco Nelissen return OK; 310b7e75cfd64893dde230dfc1c3b281a00ca1b4470Marco Nelissen } 311b7e75cfd64893dde230dfc1c3b281a00ca1b4470Marco Nelissen 312b7e75cfd64893dde230dfc1c3b281a00ca1b4470Marco Nelissen if (offset + 8 + entryCount * 12 != size) { 313840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 314840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 315840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 316b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber parser->copyBuffer(&mSampleToChunk, offset, size); 317840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 318840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 319840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 320840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 321cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::StaticTrackFragment::parseChunkOffsets( 322cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissen FragmentedMP4Parser *parser, uint32_t type, size_t offset, uint64_t size) { 323840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 8 > size) { 324840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 325840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 326840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 327840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (parser->readU32(offset) != 0) { 328840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 329840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 330840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 331840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t entryCount = parser->readU32(offset + 4); 332840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 333840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 8 + entryCount * 4 != size) { 334840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 335840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 336840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 337840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber parser->copyBuffer(&mChunkOffsets, offset, size); 338840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 339840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 340840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 341840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 342cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::StaticTrackFragment::parseChunkOffsets64( 343cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissen FragmentedMP4Parser *parser, uint32_t type, size_t offset, uint64_t size) { 344840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 8 > size) { 345840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 346840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 347840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 348840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (parser->readU32(offset) != 0) { 349840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 350840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 351840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 352840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t entryCount = parser->readU32(offset + 4); 353840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 354840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 8 + entryCount * 8 != size) { 355840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 356840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 357840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 358840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber parser->copyBuffer(&mChunkOffsets64, offset, size); 359840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 360840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 361840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 362840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 363840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} // namespace android 364840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 365