/* * Copyright (C) 2011 in-somnia * * This file is part of JAAD. * * JAAD is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 3 of the * License, or (at your option) any later version. * * JAAD is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General * Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. * If not, see <http://www.gnu.org/licenses/>. */ package net.sourceforge.jaad.mp4.boxes.impl; import java.io.IOException; import net.sourceforge.jaad.mp4.MP4InputStream; import net.sourceforge.jaad.mp4.boxes.FullBox; /** * Within the Track Fragment Box, there are zero or more Track Run Boxes. If the * duration-is-empty flag is set in the track fragment box, there are no track * runs. A track run documents a contiguous set of samples for a track. * * If the data-offset is not present, then the data for this run starts * immediately after the data of the previous run, or at the base-data-offset * defined by the track fragment header if this is the first run in a track * fragment. * If the data-offset is present, it is relative to the base-data-offset * established in the track fragment header. * * @author in-somnia */ public class TrackFragmentRunBox extends FullBox { private int sampleCount; private boolean dataOffsetPresent, firstSampleFlagsPresent; private long dataOffset, firstSampleFlags; private boolean sampleDurationPresent, sampleSizePresent, sampleFlagsPresent, sampleCompositionTimeOffsetPresent; private long[] sampleDuration, sampleSize, sampleFlags, sampleCompositionTimeOffset; public TrackFragmentRunBox() { super("Track Fragment Run Box"); } @Override public void decode(MP4InputStream in) throws IOException { super.decode(in); sampleCount = (int) in.readBytes(4); //optional fields dataOffsetPresent = ((flags&1)==1); if(dataOffsetPresent) dataOffset = in.readBytes(4); firstSampleFlagsPresent = ((flags&4)==4); if(firstSampleFlagsPresent) firstSampleFlags = in.readBytes(4); //all fields are optional sampleDurationPresent = ((flags&0x100)==0x100); if(sampleDurationPresent) sampleDuration = new long[sampleCount]; sampleSizePresent = ((flags&0x200)==0x200); if(sampleSizePresent) sampleSize = new long[sampleCount]; sampleFlagsPresent = ((flags&0x400)==0x400); if(sampleFlagsPresent) sampleFlags = new long[sampleCount]; sampleCompositionTimeOffsetPresent = ((flags&0x800)==0x800); if(sampleCompositionTimeOffsetPresent) sampleCompositionTimeOffset = new long[sampleCount]; for(int i = 0; i<sampleCount&&getLeft(in)>0; i++) { if(sampleDurationPresent) sampleDuration[i] = in.readBytes(4); if(sampleSizePresent) sampleSize[i] = in.readBytes(4); if(sampleFlagsPresent) sampleFlags[i] = in.readBytes(4); if(sampleCompositionTimeOffsetPresent) sampleCompositionTimeOffset[i] = in.readBytes(4); } } public int getSampleCount() { return sampleCount; } public boolean isDataOffsetPresent() { return dataOffsetPresent; } public long getDataOffset() { return dataOffset; } public boolean isFirstSampleFlagsPresent() { return firstSampleFlagsPresent; } public long getFirstSampleFlags() { return firstSampleFlags; } public boolean isSampleDurationPresent() { return sampleDurationPresent; } public long[] getSampleDuration() { return sampleDuration; } public boolean isSampleSizePresent() { return sampleSizePresent; } public long[] getSampleSize() { return sampleSize; } public boolean isSampleFlagsPresent() { return sampleFlagsPresent; } public long[] getSampleFlags() { return sampleFlags; } public boolean isSampleCompositionTimeOffsetPresent() { return sampleCompositionTimeOffsetPresent; } public long[] getSampleCompositionTimeOffset() { return sampleCompositionTimeOffset; } }