/*
* 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;
}
}