1dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu/* 2dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * Copyright 2009 castLabs GmbH, Berlin 3dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * 4dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * Licensed under the Apache License, Version 2.0 (the License); 5dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * you may not use this file except in compliance with the License. 6dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * You may obtain a copy of the License at 7dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * 8dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * http://www.apache.org/licenses/LICENSE-2.0 9dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * 10dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * Unless required by applicable law or agreed to in writing, software 11dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * distributed under the License is distributed on an AS IS BASIS, 12dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * See the License for the specific language governing permissions and 14dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * limitations under the License. 15dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu */ 16dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 17dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhupackage com.coremedia.iso.boxes.fragment; 18dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 19dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.coremedia.iso.IsoTypeReader; 20dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.coremedia.iso.IsoTypeWriter; 21dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.coremedia.iso.boxes.MovieBox; 22dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.googlecode.mp4parser.AbstractFullBox; 23dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 24dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.nio.ByteBuffer; 25dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.util.ArrayList; 26dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.util.List; 27dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 28dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport static com.googlecode.mp4parser.util.CastUtils.l2i; 29dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 30dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu/** 31dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * aligned(8) class TrackRunBox 32dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * extends FullBox('trun', 0, tr_flags) { 33dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * unsigned int(32) sample_count; 34dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * // the following are optional fields 35dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * signed int(32) data_offset; 36dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * unsigned int(32) first_sample_flags; 37dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * // all fields in the following array are optional 38dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * { 39dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * unsigned int(32) sample_duration; 40dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * unsigned int(32) sample_size; 41dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * unsigned int(32) sample_flags 42dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * unsigned int(32) sample_composition_time_offset; 43dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * }[ sample_count ] 44dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * } 45dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu */ 46dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 47dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhupublic class TrackRunBox extends AbstractFullBox { 48dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public static final String TYPE = "trun"; 49dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private int dataOffset; 50dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private SampleFlags firstSampleFlags; 51dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private List<Entry> entries = new ArrayList<Entry>(); 52dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 53dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 54dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public List<Entry> getEntries() { 55dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return entries; 56dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 57dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 58dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public static class Entry { 59dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private long sampleDuration; 60dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private long sampleSize; 61dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private SampleFlags sampleFlags; 62dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private int sampleCompositionTimeOffset; 63dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 64dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public Entry() { 65dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 66dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 67dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public Entry(long sampleDuration, long sampleSize, SampleFlags sampleFlags, int sampleCompositionTimeOffset) { 68dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu this.sampleDuration = sampleDuration; 69dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu this.sampleSize = sampleSize; 70dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu this.sampleFlags = sampleFlags; 71dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu this.sampleCompositionTimeOffset = sampleCompositionTimeOffset; 72dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 73dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 74dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public long getSampleDuration() { 75dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return sampleDuration; 76dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 77dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 78dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public long getSampleSize() { 79dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return sampleSize; 80dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 81dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 82dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public SampleFlags getSampleFlags() { 83dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return sampleFlags; 84dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 85dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 86dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public int getSampleCompositionTimeOffset() { 87dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return sampleCompositionTimeOffset; 88dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 89dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 90dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public void setSampleDuration(long sampleDuration) { 91dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu this.sampleDuration = sampleDuration; 92dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 93dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 94dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public void setSampleSize(long sampleSize) { 95dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu this.sampleSize = sampleSize; 96dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 97dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 98dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public void setSampleFlags(SampleFlags sampleFlags) { 99dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu this.sampleFlags = sampleFlags; 100dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 101dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 102dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public void setSampleCompositionTimeOffset(int sampleCompositionTimeOffset) { 103dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu this.sampleCompositionTimeOffset = sampleCompositionTimeOffset; 104dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 105dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 106dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu @Override 107dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public String toString() { 108dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return "Entry{" + 109dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu "sampleDuration=" + sampleDuration + 110dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ", sampleSize=" + sampleSize + 111dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ", sampleFlags=" + sampleFlags + 112dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ", sampleCompositionTimeOffset=" + sampleCompositionTimeOffset + 113dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu '}'; 114dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 115dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 116dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 117dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public void setDataOffset(int dataOffset) { 118dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (dataOffset == -1) { 119dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu setFlags(getFlags() & (0xFFFFFF ^ 1)); 120dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } else { 121dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu setFlags(getFlags() | 0x1); // turn on dataoffset 122dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 123dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu this.dataOffset = dataOffset; 124dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 125dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 126dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public long[] getSampleCompositionTimeOffsets() { 127dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (isSampleCompositionTimeOffsetPresent()) { 128dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu long[] result = new long[entries.size()]; 129dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 130dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu for (int i = 0; i < result.length; i++) { 131dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu result[i] = entries.get(i).getSampleCompositionTimeOffset(); 132dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 133dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return result; 134dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 135dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return null; 136dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 137dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 138dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public TrackExtendsBox getTrackExtendsBox() { 139dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu final TrackFragmentHeaderBox tfhd = ((TrackFragmentBox) getParent()).getTrackFragmentHeaderBox(); 140dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu final List<MovieBox> movieBoxes = tfhd.getIsoFile().getBoxes(MovieBox.class); 141dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (movieBoxes.size() == 0) { 142dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return null; 143dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 144dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 145dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu final List<TrackExtendsBox> trexBoxes = movieBoxes.get(0).getBoxes(TrackExtendsBox.class, true); 146dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu TrackExtendsBox trex = null; 147dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu for (TrackExtendsBox aTrex : trexBoxes) { 148dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (aTrex.getTrackId() == tfhd.getTrackId()) { 149dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu trex = aTrex; 150dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 151dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 152dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return trex; 153dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 154dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 155dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public TrackRunBox() { 156dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu super(TYPE); 157dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 158dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 159dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu protected long getContentSize() { 160dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu long size = 8; 161dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int flags = getFlags(); 162dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 163dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if ((flags & 0x1) == 0x1) { //dataOffsetPresent 164dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu size += 4; 165dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 166dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if ((flags & 0x4) == 0x4) { //firstSampleFlagsPresent 167dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu size += 4; 168dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 169dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 170dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu long entrySize = 0; 171dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if ((flags & 0x100) == 0x100) { //sampleDurationPresent 172dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu entrySize += 4; 173dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 174dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if ((flags & 0x200) == 0x200) { //sampleSizePresent 175dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu entrySize += 4; 176dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 177dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if ((flags & 0x400) == 0x400) { //sampleFlagsPresent 178dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu entrySize += 4; 179dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 180dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if ((flags & 0x800) == 0x800) { //sampleCompositionTimeOffsetPresent 181dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu entrySize += 4; 182dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 183dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu size += entrySize * entries.size(); 184dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return size; 185dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 186dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 187dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu protected void getContent(ByteBuffer byteBuffer) { 188dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu writeVersionAndFlags(byteBuffer); 189dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu IsoTypeWriter.writeUInt32(byteBuffer, entries.size()); 190dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int flags = getFlags(); 191dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 192dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if ((flags & 0x1) == 1) { //dataOffsetPresent 193dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu IsoTypeWriter.writeUInt32(byteBuffer, dataOffset); 194dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 195dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if ((flags & 0x4) == 0x4) { //firstSampleFlagsPresent 196dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu firstSampleFlags.getContent(byteBuffer); 197dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 198dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 199dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu for (Entry entry : entries) { 200dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if ((flags & 0x100) == 0x100) { //sampleDurationPresent 201dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu IsoTypeWriter.writeUInt32(byteBuffer, entry.sampleDuration); 202dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 203dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if ((flags & 0x200) == 0x200) { //sampleSizePresent 204dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu IsoTypeWriter.writeUInt32(byteBuffer, entry.sampleSize); 205dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 206dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if ((flags & 0x400) == 0x400) { //sampleFlagsPresent 207dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu entry.sampleFlags.getContent(byteBuffer); 208dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 209dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if ((flags & 0x800) == 0x800) { //sampleCompositionTimeOffsetPresent 210dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu byteBuffer.putInt(entry.sampleCompositionTimeOffset); 211dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 212dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 213dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 214dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 215dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu @Override 216dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public void _parseDetails(ByteBuffer content) { 217dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu parseVersionAndFlags(content); 218dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu long sampleCount = IsoTypeReader.readUInt32(content); 219dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 220dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if ((getFlags() & 0x1) == 1) { //dataOffsetPresent 221dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu dataOffset = l2i(IsoTypeReader.readUInt32(content)); 222dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } else { 223dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu dataOffset = -1; 224dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 225dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if ((getFlags() & 0x4) == 0x4) { //firstSampleFlagsPresent 226dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu firstSampleFlags = new SampleFlags(content); 227dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 228dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 229dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu for (int i = 0; i < sampleCount; i++) { 230dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu Entry entry = new Entry(); 231dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if ((getFlags() & 0x100) == 0x100) { //sampleDurationPresent 232dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu entry.sampleDuration = IsoTypeReader.readUInt32(content); 233dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 234dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if ((getFlags() & 0x200) == 0x200) { //sampleSizePresent 235dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu entry.sampleSize = IsoTypeReader.readUInt32(content); 236dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 237dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if ((getFlags() & 0x400) == 0x400) { //sampleFlagsPresent 238dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu entry.sampleFlags = new SampleFlags(content); 239dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 240dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if ((getFlags() & 0x800) == 0x800) { //sampleCompositionTimeOffsetPresent 241dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu entry.sampleCompositionTimeOffset = content.getInt(); 242dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 243dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu entries.add(entry); 244dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 245dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 246dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 247dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 248dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public long getSampleCount() { 249dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return entries.size(); 250dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 251dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 252dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public boolean isDataOffsetPresent() { 253dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return (getFlags() & 0x1) == 1; 254dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 255dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 256dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public boolean isFirstSampleFlagsPresent() { 257dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return (getFlags() & 0x4) == 0x4; 258dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 259dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 260dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 261dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public boolean isSampleSizePresent() { 262dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return (getFlags() & 0x200) == 0x200; 263dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 264dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 265dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public boolean isSampleDurationPresent() { 266dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return (getFlags() & 0x100) == 0x100; 267dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 268dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 269dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public boolean isSampleFlagsPresent() { 270dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return (getFlags() & 0x400) == 0x400; 271dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 272dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 273dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public boolean isSampleCompositionTimeOffsetPresent() { 274dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return (getFlags() & 0x800) == 0x800; 275dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 276dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 277dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public void setDataOffsetPresent(boolean v) { 278dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (v) { 279dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu setFlags(getFlags() | 0x01); 280dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } else { 281dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu setFlags(getFlags() & (0xFFFFFF ^ 0x1)); 282dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 283dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 284dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 285dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public void setSampleSizePresent(boolean v) { 286dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (v) { 287dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu setFlags(getFlags() | 0x200); 288dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } else { 289dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu setFlags(getFlags() & (0xFFFFFF ^ 0x200)); 290dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 291dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 292dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 293dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public void setSampleDurationPresent(boolean v) { 294dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 295dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (v) { 296dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu setFlags(getFlags() | 0x100); 297dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } else { 298dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu setFlags(getFlags() & (0xFFFFFF ^ 0x100)); 299dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 300dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 301dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 302dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public void setSampleFlagsPresent(boolean v) { 303dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (v) { 304dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu setFlags(getFlags() | 0x400); 305dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } else { 306dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu setFlags(getFlags() & (0xFFFFFF ^ 0x400)); 307dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 308dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 309dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 310dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public void setSampleCompositionTimeOffsetPresent(boolean v) { 311dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (v) { 312dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu setFlags(getFlags() | 0x800); 313dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } else { 314dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu setFlags(getFlags() & (0xFFFFFF ^ 0x800)); 315dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 316dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 317dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 318dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 319dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public int getDataOffset() { 320dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return dataOffset; 321dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 322dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 323dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public SampleFlags getFirstSampleFlags() { 324dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return firstSampleFlags; 325dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 326dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 327dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public void setFirstSampleFlags(SampleFlags firstSampleFlags) { 328dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (firstSampleFlags == null) { 329dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu setFlags(getFlags() & (0xFFFFFF ^ 0x4)); 330dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } else { 331dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu setFlags(getFlags() | 0x4); 332dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 333dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu this.firstSampleFlags = firstSampleFlags; 334dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 335dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 336dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu @Override 337dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public String toString() { 338dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu final StringBuilder sb = new StringBuilder(); 339dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sb.append("TrackRunBox"); 340dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sb.append("{sampleCount=").append(entries.size()); 341dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sb.append(", dataOffset=").append(dataOffset); 342dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sb.append(", dataOffsetPresent=").append(isDataOffsetPresent()); 343dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sb.append(", sampleSizePresent=").append(isSampleSizePresent()); 344dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sb.append(", sampleDurationPresent=").append(isSampleDurationPresent()); 345dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sb.append(", sampleFlagsPresentPresent=").append(isSampleFlagsPresent()); 346dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sb.append(", sampleCompositionTimeOffsetPresent=").append(isSampleCompositionTimeOffsetPresent()); 347dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sb.append(", firstSampleFlags=").append(firstSampleFlags); 348dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sb.append('}'); 349dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return sb.toString(); 350dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 351dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 352dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public void setEntries(List<Entry> entries) { 353dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu this.entries = entries; 354dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 355dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu} 356