diff options
Diffstat (limited to 'isoparser/src/main/java/com/coremedia/iso/boxes/CompositionTimeToSample.java')
-rw-r--r-- | isoparser/src/main/java/com/coremedia/iso/boxes/CompositionTimeToSample.java | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/isoparser/src/main/java/com/coremedia/iso/boxes/CompositionTimeToSample.java b/isoparser/src/main/java/com/coremedia/iso/boxes/CompositionTimeToSample.java new file mode 100644 index 0000000..411bfe9 --- /dev/null +++ b/isoparser/src/main/java/com/coremedia/iso/boxes/CompositionTimeToSample.java @@ -0,0 +1,150 @@ +package com.coremedia.iso.boxes; + +import com.coremedia.iso.IsoTypeReader; +import com.coremedia.iso.IsoTypeWriter; +import com.googlecode.mp4parser.AbstractFullBox; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static com.googlecode.mp4parser.util.CastUtils.l2i; + +/** + * <pre> + * aligned(8) class CompositionOffsetBox + * extends FullBox(‘ctts’, version = 0, 0) { + * unsigned int(32) entry_count; + * int i; + * if (version==0) { + * for (i=0; i < entry_count; i++) { + * unsigned int(32) sample_count; + * unsigned int(32) sample_offset; + * } + * } + * else if (version == 1) { + * for (i=0; i < entry_count; i++) { + * unsigned int(32) sample_count; + * signed int(32) sample_offset; + * } + * } + * } + * </pre> + * <p/> + * This box provides the offset between decoding time and composition time. + * In version 0 of this box the decoding time must be less than the composition time, and + * the offsets are expressed as unsigned numbers such that + * CT(n) = DT(n) + CTTS(n) where CTTS(n) is the (uncompressed) table entry for sample n. + * <p/> + * In version 1 of this box, the composition timeline and the decoding timeline are + * still derived from each other, but the offsets are signed. + * It is recommended that for the computed composition timestamps, there is + * exactly one with the value 0 (zero). + */ +public class CompositionTimeToSample extends AbstractFullBox { + public static final String TYPE = "ctts"; + + List<Entry> entries = Collections.emptyList(); + + public CompositionTimeToSample() { + super(TYPE); + } + + protected long getContentSize() { + return 8 + 8 * entries.size(); + } + + public List<Entry> getEntries() { + return entries; + } + + public void setEntries(List<Entry> entries) { + this.entries = entries; + } + + @Override + public void _parseDetails(ByteBuffer content) { + parseVersionAndFlags(content); + int numberOfEntries = l2i(IsoTypeReader.readUInt32(content)); + entries = new ArrayList<Entry>(numberOfEntries); + for (int i = 0; i < numberOfEntries; i++) { + Entry e = new Entry(l2i(IsoTypeReader.readUInt32(content)), content.getInt()); + entries.add(e); + } + } + + @Override + protected void getContent(ByteBuffer byteBuffer) { + writeVersionAndFlags(byteBuffer); + IsoTypeWriter.writeUInt32(byteBuffer, entries.size()); + + for (Entry entry : entries) { + IsoTypeWriter.writeUInt32(byteBuffer, entry.getCount()); + byteBuffer.putInt(entry.getOffset()); + } + + } + + + public static class Entry { + int count; + int offset; + + public Entry(int count, int offset) { + this.count = count; + this.offset = offset; + } + + public int getCount() { + return count; + } + + public int getOffset() { + return offset; + } + + public void setCount(int count) { + this.count = count; + } + + public void setOffset(int offset) { + this.offset = offset; + } + + @Override + public String toString() { + return "Entry{" + + "count=" + count + + ", offset=" + offset + + '}'; + } + } + + + /** + * Decompresses the list of entries and returns the list of composition times. + * + * @return decoding time per sample + */ + public static int[] blowupCompositionTimes(List<CompositionTimeToSample.Entry> entries) { + long numOfSamples = 0; + for (CompositionTimeToSample.Entry entry : entries) { + numOfSamples += entry.getCount(); + } + assert numOfSamples <= Integer.MAX_VALUE; + int[] decodingTime = new int[(int) numOfSamples]; + + int current = 0; + + + for (CompositionTimeToSample.Entry entry : entries) { + for (int i = 0; i < entry.getCount(); i++) { + decodingTime[current++] = entry.getOffset(); + } + } + + return decodingTime; + } + +} |