Home | History | Annotate | Download | only in threegpp26244
      1 package com.googlecode.mp4parser.boxes.threegpp26244;
      2 
      3 import com.coremedia.iso.IsoTypeReader;
      4 import com.coremedia.iso.IsoTypeWriter;
      5 import com.googlecode.mp4parser.AbstractFullBox;
      6 import com.googlecode.mp4parser.boxes.mp4.objectdescriptors.BitReaderBuffer;
      7 import com.googlecode.mp4parser.boxes.mp4.objectdescriptors.BitWriterBuffer;
      8 
      9 import java.nio.ByteBuffer;
     10 import java.util.ArrayList;
     11 import java.util.List;
     12 
     13 /**
     14  * <pre>
     15  * aligned(8) class SegmentIndexBox extends FullBox(sidx, version, 0) {
     16  *  unsigned int(32) reference_ID;
     17  *  unsigned int(32) timescale;
     18  *  if (version==0)
     19  *  {
     20  *   unsigned int(32) earliest_presentation_time;
     21  *   unsigned int(32) first_offset;
     22  *  }
     23  *  else
     24  *  {
     25  *   unsigned int(64) earliest_presentation_time;
     26  *   unsigned int(64) first_offset;
     27  *  }
     28  *  unsigned int(16) reserved = 0;
     29  *  unsigned int(16) reference_count;
     30  *  for(i=1; i <= reference_count; i++)
     31  *  {
     32  *   bit (1)            reference_type;
     33  *   unsigned int(31)   referenced_size;
     34  *   unsigned int(32)   subsegment_duration;
     35  *   bit(1)             starts_with_SAP;
     36  *   unsigned int(3)    SAP_type;
     37  *   unsigned int(28)   SAP_delta_time;
     38  *  }
     39  * }
     40  * </pre>
     41  */
     42 public class SegmentIndexBox extends AbstractFullBox {
     43     public static final String TYPE = "sidx";
     44     List<Entry> entries = new ArrayList<Entry>();
     45 
     46     long referenceId;
     47     long timeScale;
     48     long earliestPresentationTime;
     49     long firstOffset;
     50     int reserved;
     51 
     52 
     53     public SegmentIndexBox() {
     54         super(TYPE);
     55     }
     56 
     57     @Override
     58     protected long getContentSize() {
     59         long size = 4;
     60         size += 4;
     61         size += 4;
     62         size += getVersion() == 0 ? 8 : 16;
     63         size += 2; // reserved
     64         size += 2; // reference count
     65 
     66         size += entries.size() * 12;
     67 
     68         return size;
     69     }
     70 
     71     @Override
     72     protected void getContent(ByteBuffer byteBuffer) {
     73         writeVersionAndFlags(byteBuffer);
     74         IsoTypeWriter.writeUInt32(byteBuffer, referenceId);
     75         IsoTypeWriter.writeUInt32(byteBuffer, timeScale);
     76         if (getVersion() == 0) {
     77             IsoTypeWriter.writeUInt32(byteBuffer, earliestPresentationTime);
     78             IsoTypeWriter.writeUInt32(byteBuffer, firstOffset);
     79         } else {
     80             IsoTypeWriter.writeUInt64(byteBuffer, earliestPresentationTime);
     81             IsoTypeWriter.writeUInt64(byteBuffer, firstOffset);
     82         }
     83         IsoTypeWriter.writeUInt16(byteBuffer, reserved);
     84         IsoTypeWriter.writeUInt16(byteBuffer, entries.size());
     85         for (Entry entry : entries) {
     86             BitWriterBuffer b = new BitWriterBuffer(byteBuffer);
     87             b.writeBits(entry.getReferenceType(), 1);
     88             b.writeBits(entry.getReferencedSize(), 31);
     89             IsoTypeWriter.writeUInt32(byteBuffer, entry.getSubsegmentDuration());
     90             b = new BitWriterBuffer(byteBuffer);
     91             b.writeBits(entry.getStartsWithSap(), 1);
     92             b.writeBits(entry.getSapType(), 3);
     93             b.writeBits(entry.getSapDeltaTime(), 28);
     94         }
     95 
     96     }
     97 
     98     @Override
     99     protected void _parseDetails(ByteBuffer content) {
    100         parseVersionAndFlags(content);
    101         referenceId = IsoTypeReader.readUInt32(content);
    102         timeScale = IsoTypeReader.readUInt32(content);
    103         if (getVersion() == 0) {
    104             earliestPresentationTime = IsoTypeReader.readUInt32(content);
    105             firstOffset = IsoTypeReader.readUInt32(content);
    106         } else {
    107             earliestPresentationTime = IsoTypeReader.readUInt64(content);
    108             firstOffset = IsoTypeReader.readUInt64(content);
    109         }
    110         reserved = IsoTypeReader.readUInt16(content);
    111         int numEntries = IsoTypeReader.readUInt16(content);
    112         for (int i = 0; i < numEntries; i++) {
    113             BitReaderBuffer b = new BitReaderBuffer(content);
    114             Entry e = new Entry();
    115             e.setReferenceType((byte) b.readBits(1));
    116             e.setReferencedSize(b.readBits(31));
    117             e.setSubsegmentDuration(IsoTypeReader.readUInt32(content));
    118             b = new BitReaderBuffer(content);
    119             e.setStartsWithSap((byte) b.readBits(1));
    120             e.setSapType((byte) b.readBits(3));
    121             e.setSapDeltaTime(b.readBits(28));
    122             entries.add(e);
    123         }
    124     }
    125 
    126 
    127     public List<Entry> getEntries() {
    128         return entries;
    129     }
    130 
    131     public void setEntries(List<Entry> entries) {
    132         this.entries = entries;
    133     }
    134 
    135     public long getReferenceId() {
    136         return referenceId;
    137     }
    138 
    139     public void setReferenceId(long referenceId) {
    140         this.referenceId = referenceId;
    141     }
    142 
    143     public long getTimeScale() {
    144         return timeScale;
    145     }
    146 
    147     public void setTimeScale(long timeScale) {
    148         this.timeScale = timeScale;
    149     }
    150 
    151     public long getEarliestPresentationTime() {
    152         return earliestPresentationTime;
    153     }
    154 
    155     public void setEarliestPresentationTime(long earliestPresentationTime) {
    156         this.earliestPresentationTime = earliestPresentationTime;
    157     }
    158 
    159     public long getFirstOffset() {
    160         return firstOffset;
    161     }
    162 
    163     public void setFirstOffset(long firstOffset) {
    164         this.firstOffset = firstOffset;
    165     }
    166 
    167     public int getReserved() {
    168         return reserved;
    169     }
    170 
    171     public void setReserved(int reserved) {
    172         this.reserved = reserved;
    173     }
    174 
    175     public static class Entry {
    176         byte referenceType;
    177         int referencedSize;
    178         long subsegmentDuration;
    179         byte startsWithSap;
    180         byte sapType;
    181         int sapDeltaTime;
    182 
    183         public Entry() {
    184         }
    185 
    186         public Entry(byte referenceType, int referencedSize, long subsegmentDuration, byte startsWithSap, byte sapType, int sapDeltaTime) {
    187             this.referenceType = referenceType;
    188             this.referencedSize = referencedSize;
    189             this.subsegmentDuration = subsegmentDuration;
    190             this.startsWithSap = startsWithSap;
    191             this.sapType = sapType;
    192             this.sapDeltaTime = sapDeltaTime;
    193         }
    194 
    195         public byte getReferenceType() {
    196             return referenceType;
    197         }
    198 
    199         public void setReferenceType(byte referenceType) {
    200             this.referenceType = referenceType;
    201         }
    202 
    203         public int getReferencedSize() {
    204             return referencedSize;
    205         }
    206 
    207         public void setReferencedSize(int referencedSize) {
    208             this.referencedSize = referencedSize;
    209         }
    210 
    211         public long getSubsegmentDuration() {
    212             return subsegmentDuration;
    213         }
    214 
    215         public void setSubsegmentDuration(long subsegmentDuration) {
    216             this.subsegmentDuration = subsegmentDuration;
    217         }
    218 
    219         public byte getStartsWithSap() {
    220             return startsWithSap;
    221         }
    222 
    223         public void setStartsWithSap(byte startsWithSap) {
    224             this.startsWithSap = startsWithSap;
    225         }
    226 
    227         public byte getSapType() {
    228             return sapType;
    229         }
    230 
    231         public void setSapType(byte sapType) {
    232             this.sapType = sapType;
    233         }
    234 
    235         public int getSapDeltaTime() {
    236             return sapDeltaTime;
    237         }
    238 
    239         public void setSapDeltaTime(int sapDeltaTime) {
    240             this.sapDeltaTime = sapDeltaTime;
    241         }
    242 
    243         @Override
    244         public String toString() {
    245             return "Entry{" +
    246                     "referenceType=" + referenceType +
    247                     ", referencedSize=" + referencedSize +
    248                     ", subsegmentDuration=" + subsegmentDuration +
    249                     ", startsWithSap=" + startsWithSap +
    250                     ", sapType=" + sapType +
    251                     ", sapDeltaTime=" + sapDeltaTime +
    252                     '}';
    253         }
    254 
    255         @Override
    256         public boolean equals(Object o) {
    257             if (this == o) return true;
    258             if (o == null || getClass() != o.getClass()) return false;
    259 
    260             Entry entry = (Entry) o;
    261 
    262             if (referenceType != entry.referenceType) return false;
    263             if (referencedSize != entry.referencedSize) return false;
    264             if (sapDeltaTime != entry.sapDeltaTime) return false;
    265             if (sapType != entry.sapType) return false;
    266             if (startsWithSap != entry.startsWithSap) return false;
    267             if (subsegmentDuration != entry.subsegmentDuration) return false;
    268 
    269             return true;
    270         }
    271 
    272         @Override
    273         public int hashCode() {
    274             int result = (int) referenceType;
    275             result = 31 * result + referencedSize;
    276             result = 31 * result + (int) (subsegmentDuration ^ (subsegmentDuration >>> 32));
    277             result = 31 * result + (int) startsWithSap;
    278             result = 31 * result + (int) sapType;
    279             result = 31 * result + sapDeltaTime;
    280             return result;
    281         }
    282     }
    283 }
    284