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