diff options
Diffstat (limited to 'isoparser/src/main/java/com/googlecode/mp4parser/boxes/threegpp26244/SegmentIndexBox.java')
-rw-r--r-- | isoparser/src/main/java/com/googlecode/mp4parser/boxes/threegpp26244/SegmentIndexBox.java | 283 |
1 files changed, 283 insertions, 0 deletions
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/boxes/threegpp26244/SegmentIndexBox.java b/isoparser/src/main/java/com/googlecode/mp4parser/boxes/threegpp26244/SegmentIndexBox.java new file mode 100644 index 0000000..638a87b --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/boxes/threegpp26244/SegmentIndexBox.java @@ -0,0 +1,283 @@ +package com.googlecode.mp4parser.boxes.threegpp26244; + +import com.coremedia.iso.IsoTypeReader; +import com.coremedia.iso.IsoTypeWriter; +import com.googlecode.mp4parser.AbstractFullBox; +import com.googlecode.mp4parser.boxes.mp4.objectdescriptors.BitReaderBuffer; +import com.googlecode.mp4parser.boxes.mp4.objectdescriptors.BitWriterBuffer; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; + +/** + * <pre> + * aligned(8) class SegmentIndexBox extends FullBox(‘sidx’, version, 0) { + * unsigned int(32) reference_ID; + * unsigned int(32) timescale; + * if (version==0) + * { + * unsigned int(32) earliest_presentation_time; + * unsigned int(32) first_offset; + * } + * else + * { + * unsigned int(64) earliest_presentation_time; + * unsigned int(64) first_offset; + * } + * unsigned int(16) reserved = 0; + * unsigned int(16) reference_count; + * for(i=1; i <= reference_count; i++) + * { + * bit (1) reference_type; + * unsigned int(31) referenced_size; + * unsigned int(32) subsegment_duration; + * bit(1) starts_with_SAP; + * unsigned int(3) SAP_type; + * unsigned int(28) SAP_delta_time; + * } + * } + * </pre> + */ +public class SegmentIndexBox extends AbstractFullBox { + public static final String TYPE = "sidx"; + List<Entry> entries = new ArrayList<Entry>(); + + long referenceId; + long timeScale; + long earliestPresentationTime; + long firstOffset; + int reserved; + + + public SegmentIndexBox() { + super(TYPE); + } + + @Override + protected long getContentSize() { + long size = 4; + size += 4; + size += 4; + size += getVersion() == 0 ? 8 : 16; + size += 2; // reserved + size += 2; // reference count + + size += entries.size() * 12; + + return size; + } + + @Override + protected void getContent(ByteBuffer byteBuffer) { + writeVersionAndFlags(byteBuffer); + IsoTypeWriter.writeUInt32(byteBuffer, referenceId); + IsoTypeWriter.writeUInt32(byteBuffer, timeScale); + if (getVersion() == 0) { + IsoTypeWriter.writeUInt32(byteBuffer, earliestPresentationTime); + IsoTypeWriter.writeUInt32(byteBuffer, firstOffset); + } else { + IsoTypeWriter.writeUInt64(byteBuffer, earliestPresentationTime); + IsoTypeWriter.writeUInt64(byteBuffer, firstOffset); + } + IsoTypeWriter.writeUInt16(byteBuffer, reserved); + IsoTypeWriter.writeUInt16(byteBuffer, entries.size()); + for (Entry entry : entries) { + BitWriterBuffer b = new BitWriterBuffer(byteBuffer); + b.writeBits(entry.getReferenceType(), 1); + b.writeBits(entry.getReferencedSize(), 31); + IsoTypeWriter.writeUInt32(byteBuffer, entry.getSubsegmentDuration()); + b = new BitWriterBuffer(byteBuffer); + b.writeBits(entry.getStartsWithSap(), 1); + b.writeBits(entry.getSapType(), 3); + b.writeBits(entry.getSapDeltaTime(), 28); + } + + } + + @Override + protected void _parseDetails(ByteBuffer content) { + parseVersionAndFlags(content); + referenceId = IsoTypeReader.readUInt32(content); + timeScale = IsoTypeReader.readUInt32(content); + if (getVersion() == 0) { + earliestPresentationTime = IsoTypeReader.readUInt32(content); + firstOffset = IsoTypeReader.readUInt32(content); + } else { + earliestPresentationTime = IsoTypeReader.readUInt64(content); + firstOffset = IsoTypeReader.readUInt64(content); + } + reserved = IsoTypeReader.readUInt16(content); + int numEntries = IsoTypeReader.readUInt16(content); + for (int i = 0; i < numEntries; i++) { + BitReaderBuffer b = new BitReaderBuffer(content); + Entry e = new Entry(); + e.setReferenceType((byte) b.readBits(1)); + e.setReferencedSize(b.readBits(31)); + e.setSubsegmentDuration(IsoTypeReader.readUInt32(content)); + b = new BitReaderBuffer(content); + e.setStartsWithSap((byte) b.readBits(1)); + e.setSapType((byte) b.readBits(3)); + e.setSapDeltaTime(b.readBits(28)); + entries.add(e); + } + } + + + public List<Entry> getEntries() { + return entries; + } + + public void setEntries(List<Entry> entries) { + this.entries = entries; + } + + public long getReferenceId() { + return referenceId; + } + + public void setReferenceId(long referenceId) { + this.referenceId = referenceId; + } + + public long getTimeScale() { + return timeScale; + } + + public void setTimeScale(long timeScale) { + this.timeScale = timeScale; + } + + public long getEarliestPresentationTime() { + return earliestPresentationTime; + } + + public void setEarliestPresentationTime(long earliestPresentationTime) { + this.earliestPresentationTime = earliestPresentationTime; + } + + public long getFirstOffset() { + return firstOffset; + } + + public void setFirstOffset(long firstOffset) { + this.firstOffset = firstOffset; + } + + public int getReserved() { + return reserved; + } + + public void setReserved(int reserved) { + this.reserved = reserved; + } + + public static class Entry { + byte referenceType; + int referencedSize; + long subsegmentDuration; + byte startsWithSap; + byte sapType; + int sapDeltaTime; + + public Entry() { + } + + public Entry(byte referenceType, int referencedSize, long subsegmentDuration, byte startsWithSap, byte sapType, int sapDeltaTime) { + this.referenceType = referenceType; + this.referencedSize = referencedSize; + this.subsegmentDuration = subsegmentDuration; + this.startsWithSap = startsWithSap; + this.sapType = sapType; + this.sapDeltaTime = sapDeltaTime; + } + + public byte getReferenceType() { + return referenceType; + } + + public void setReferenceType(byte referenceType) { + this.referenceType = referenceType; + } + + public int getReferencedSize() { + return referencedSize; + } + + public void setReferencedSize(int referencedSize) { + this.referencedSize = referencedSize; + } + + public long getSubsegmentDuration() { + return subsegmentDuration; + } + + public void setSubsegmentDuration(long subsegmentDuration) { + this.subsegmentDuration = subsegmentDuration; + } + + public byte getStartsWithSap() { + return startsWithSap; + } + + public void setStartsWithSap(byte startsWithSap) { + this.startsWithSap = startsWithSap; + } + + public byte getSapType() { + return sapType; + } + + public void setSapType(byte sapType) { + this.sapType = sapType; + } + + public int getSapDeltaTime() { + return sapDeltaTime; + } + + public void setSapDeltaTime(int sapDeltaTime) { + this.sapDeltaTime = sapDeltaTime; + } + + @Override + public String toString() { + return "Entry{" + + "referenceType=" + referenceType + + ", referencedSize=" + referencedSize + + ", subsegmentDuration=" + subsegmentDuration + + ", startsWithSap=" + startsWithSap + + ", sapType=" + sapType + + ", sapDeltaTime=" + sapDeltaTime + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Entry entry = (Entry) o; + + if (referenceType != entry.referenceType) return false; + if (referencedSize != entry.referencedSize) return false; + if (sapDeltaTime != entry.sapDeltaTime) return false; + if (sapType != entry.sapType) return false; + if (startsWithSap != entry.startsWithSap) return false; + if (subsegmentDuration != entry.subsegmentDuration) return false; + + return true; + } + + @Override + public int hashCode() { + int result = (int) referenceType; + result = 31 * result + referencedSize; + result = 31 * result + (int) (subsegmentDuration ^ (subsegmentDuration >>> 32)); + result = 31 * result + (int) startsWithSap; + result = 31 * result + (int) sapType; + result = 31 * result + sapDeltaTime; + return result; + } + } +} |