package com.coremedia.iso.boxes;
import com.coremedia.iso.BoxParser;
import com.coremedia.iso.IsoBufferWrapper;
import com.coremedia.iso.IsoFile;
import com.coremedia.iso.IsoOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* aligned(8) class SubSampleInformationBox
* extends FullBox('subs', version, 0) {
* unsigned int(32) entry_count;
* int i,j;
* for (i=0; i < entry_count; i++) {
* unsigned int(32) sample_delta;
* unsigned int(16) subsample_count;
* if (subsample_count > 0) {
* for (j=0; j < subsample_count; j++) {
* if(version == 1)
* {
* unsigned int(32) subsample_size;
* }
* else
* {
* unsigned int(16) subsample_size;
* }
* unsigned int(8) subsample_priority;
* unsigned int(8) discardable;
* unsigned int(32) reserved = 0;
* }
* }
* }
* }
*/
public class SubSampleInformationBox extends AbstractFullBox {
public static final String TYPE = "subs";
private long entryCount;
private List<SampleEntry> sampleEntries = new ArrayList<SampleEntry>();
public SubSampleInformationBox() {
super(IsoFile.fourCCtoBytes(TYPE));
}
@Override
protected long getContentSize() {
long entries = 4 + ((4 + 2) * entryCount);
int subsampleEntries = 0;
for (SampleEntry sampleEntry : sampleEntries) {
subsampleEntries += sampleEntry.getSubsampleCount() * (((getVersion() == 1) ? 4 : 2) + 1 + 1 + 4);
}
return entries + subsampleEntries;
}
@Override
public void parse(IsoBufferWrapper in, long size, BoxParser boxParser, Box lastMovieFragmentBox) throws IOException {
super.parse(in, size, boxParser, lastMovieFragmentBox);
entryCount = in.readUInt32();
for (int i = 0; i < entryCount; i++) {
SampleEntry sampleEntry = new SampleEntry();
sampleEntry.setSampleDelta(in.readUInt32());
int subsampleCount = in.readUInt16();
sampleEntry.setSubsampleCount(subsampleCount);
for (int j = 0; j < subsampleCount; j++) {
SampleEntry.SubsampleEntry subsampleEntry = new SampleEntry.SubsampleEntry();
subsampleEntry.setSubsampleSize(getVersion() == 1 ? in.readUInt32() : in.readUInt16());
subsampleEntry.setSubsamplePriority(in.readUInt8());
subsampleEntry.setDiscardable(in.readUInt8());
subsampleEntry.setReserved(in.readUInt32());
sampleEntry.addSubsampleEntry(subsampleEntry);
}
sampleEntries.add(sampleEntry);
}
}
@Override
protected void getContent(IsoOutputStream os) throws IOException {
os.writeUInt32(entryCount);
for (SampleEntry sampleEntry : sampleEntries) {
os.writeUInt32(sampleEntry.getSampleDelta());
List<SampleEntry.SubsampleEntry> subsampleEntries = sampleEntry.getSubsampleEntries();
for (SampleEntry.SubsampleEntry subsampleEntry : subsampleEntries) {
if (getVersion() == 1) {
os.writeUInt32(subsampleEntry.getSubsampleSize());
} else {
os.writeUInt16((int) subsampleEntry.getSubsampleSize());
}
os.writeUInt8(subsampleEntry.getSubsamplePriority());
os.writeUInt8(subsampleEntry.getDiscardable());
os.writeUInt32(subsampleEntry.getReserved());
}
}
}
public static class SampleEntry {
private long sampleDelta;
private int subsampleCount;
private List<SubsampleEntry> subsampleEntries = new ArrayList<SubsampleEntry>();
public long getSampleDelta() {
return sampleDelta;
}
public void setSampleDelta(long sampleDelta) {
this.sampleDelta = sampleDelta;
}
public int getSubsampleCount() {
return subsampleCount;
}
public void setSubsampleCount(int subsampleCount) {
this.subsampleCount = subsampleCount;
}
public List<SubsampleEntry> getSubsampleEntries() {
return subsampleEntries;
}
public void addSubsampleEntry(SubsampleEntry subsampleEntry) {
subsampleEntries.add(subsampleEntry);
}
public static class SubsampleEntry {
private long subsampleSize;
private int subsamplePriority;
private int discardable;
private long reserved;
public long getSubsampleSize() {
return subsampleSize;
}
public void setSubsampleSize(long subsampleSize) {
this.subsampleSize = subsampleSize;
}
public int getSubsamplePriority() {
return subsamplePriority;
}
public void setSubsamplePriority(int subsamplePriority) {
this.subsamplePriority = subsamplePriority;
}
public int getDiscardable() {
return discardable;
}
public void setDiscardable(int discardable) {
this.discardable = discardable;
}
public long getReserved() {
return reserved;
}
public void setReserved(long reserved) {
this.reserved = reserved;
}
}
}
}