1 package com.coremedia.iso.boxes; 2 3 import com.coremedia.iso.IsoTypeReader; 4 import com.coremedia.iso.IsoTypeWriter; 5 import com.googlecode.mp4parser.AbstractFullBox; 6 7 import java.nio.ByteBuffer; 8 import java.util.ArrayList; 9 import java.util.List; 10 11 import static com.googlecode.mp4parser.util.CastUtils.l2i; 12 13 /** 14 * aligned(8) class SubSampleInformationBox 15 * extends FullBox('subs', version, 0) { 16 * unsigned int(32) entry_count; 17 * int i,j; 18 * for (i=0; i < entry_count; i++) { 19 * unsigned int(32) sample_delta; 20 * unsigned int(16) subsample_count; 21 * if (subsample_count > 0) { 22 * for (j=0; j < subsample_count; j++) { 23 * if(version == 1) 24 * { 25 * unsigned int(32) subsample_size; 26 * } 27 * else 28 * { 29 * unsigned int(16) subsample_size; 30 * } 31 * unsigned int(8) subsample_priority; 32 * unsigned int(8) discardable; 33 * unsigned int(32) reserved = 0; 34 * } 35 * } 36 * } 37 * } 38 */ 39 public class SubSampleInformationBox extends AbstractFullBox { 40 public static final String TYPE = "subs"; 41 42 private long entryCount; 43 private List<SampleEntry> entries = new ArrayList<SampleEntry>(); 44 SubSampleInformationBox()45 public SubSampleInformationBox() { 46 super(TYPE); 47 } 48 getEntries()49 public List<SampleEntry> getEntries() { 50 return entries; 51 } 52 setEntries(List<SampleEntry> entries)53 public void setEntries(List<SampleEntry> entries) { 54 this.entries = entries; 55 entryCount = entries.size(); 56 } 57 58 @Override getContentSize()59 protected long getContentSize() { 60 long entries = 8 + ((4 + 2) * entryCount); 61 int subsampleEntries = 0; 62 for (SampleEntry sampleEntry : this.entries) { 63 subsampleEntries += sampleEntry.getSubsampleCount() * (((getVersion() == 1) ? 4 : 2) + 1 + 1 + 4); 64 } 65 return entries + subsampleEntries; 66 } 67 68 @Override _parseDetails(ByteBuffer content)69 public void _parseDetails(ByteBuffer content) { 70 parseVersionAndFlags(content); 71 72 entryCount = IsoTypeReader.readUInt32(content); 73 74 for (int i = 0; i < entryCount; i++) { 75 SampleEntry sampleEntry = new SampleEntry(); 76 sampleEntry.setSampleDelta(IsoTypeReader.readUInt32(content)); 77 int subsampleCount = IsoTypeReader.readUInt16(content); 78 for (int j = 0; j < subsampleCount; j++) { 79 SampleEntry.SubsampleEntry subsampleEntry = new SampleEntry.SubsampleEntry(); 80 subsampleEntry.setSubsampleSize(getVersion() == 1 ? IsoTypeReader.readUInt32(content) : IsoTypeReader.readUInt16(content)); 81 subsampleEntry.setSubsamplePriority(IsoTypeReader.readUInt8(content)); 82 subsampleEntry.setDiscardable(IsoTypeReader.readUInt8(content)); 83 subsampleEntry.setReserved(IsoTypeReader.readUInt32(content)); 84 sampleEntry.addSubsampleEntry(subsampleEntry); 85 } 86 entries.add(sampleEntry); 87 } 88 89 } 90 91 @Override getContent(ByteBuffer byteBuffer)92 protected void getContent(ByteBuffer byteBuffer) { 93 writeVersionAndFlags(byteBuffer); 94 IsoTypeWriter.writeUInt32(byteBuffer, entries.size()); 95 for (SampleEntry sampleEntry : entries) { 96 IsoTypeWriter.writeUInt32(byteBuffer, sampleEntry.getSampleDelta()); 97 IsoTypeWriter.writeUInt16(byteBuffer, sampleEntry.getSubsampleCount()); 98 List<SampleEntry.SubsampleEntry> subsampleEntries = sampleEntry.getSubsampleEntries(); 99 for (SampleEntry.SubsampleEntry subsampleEntry : subsampleEntries) { 100 if (getVersion() == 1) { 101 IsoTypeWriter.writeUInt32(byteBuffer, subsampleEntry.getSubsampleSize()); 102 } else { 103 IsoTypeWriter.writeUInt16(byteBuffer, l2i(subsampleEntry.getSubsampleSize())); 104 } 105 IsoTypeWriter.writeUInt8(byteBuffer, subsampleEntry.getSubsamplePriority()); 106 IsoTypeWriter.writeUInt8(byteBuffer, subsampleEntry.getDiscardable()); 107 IsoTypeWriter.writeUInt32(byteBuffer, subsampleEntry.getReserved()); 108 } 109 } 110 } 111 112 @Override toString()113 public String toString() { 114 return "SubSampleInformationBox{" + 115 "entryCount=" + entryCount + 116 ", entries=" + entries + 117 '}'; 118 } 119 120 public static class SampleEntry { 121 private long sampleDelta; 122 private int subsampleCount; 123 private List<SubsampleEntry> subsampleEntries = new ArrayList<SubsampleEntry>(); 124 getSampleDelta()125 public long getSampleDelta() { 126 return sampleDelta; 127 } 128 setSampleDelta(long sampleDelta)129 public void setSampleDelta(long sampleDelta) { 130 this.sampleDelta = sampleDelta; 131 } 132 getSubsampleCount()133 public int getSubsampleCount() { 134 return subsampleCount; 135 } 136 setSubsampleCount(int subsampleCount)137 public void setSubsampleCount(int subsampleCount) { 138 this.subsampleCount = subsampleCount; 139 } 140 getSubsampleEntries()141 public List<SubsampleEntry> getSubsampleEntries() { 142 return subsampleEntries; 143 } 144 addSubsampleEntry(SubsampleEntry subsampleEntry)145 public void addSubsampleEntry(SubsampleEntry subsampleEntry) { 146 subsampleEntries.add(subsampleEntry); 147 subsampleCount++; 148 } 149 150 public static class SubsampleEntry { 151 private long subsampleSize; 152 private int subsamplePriority; 153 private int discardable; 154 private long reserved; 155 getSubsampleSize()156 public long getSubsampleSize() { 157 return subsampleSize; 158 } 159 setSubsampleSize(long subsampleSize)160 public void setSubsampleSize(long subsampleSize) { 161 this.subsampleSize = subsampleSize; 162 } 163 getSubsamplePriority()164 public int getSubsamplePriority() { 165 return subsamplePriority; 166 } 167 setSubsamplePriority(int subsamplePriority)168 public void setSubsamplePriority(int subsamplePriority) { 169 this.subsamplePriority = subsamplePriority; 170 } 171 getDiscardable()172 public int getDiscardable() { 173 return discardable; 174 } 175 setDiscardable(int discardable)176 public void setDiscardable(int discardable) { 177 this.discardable = discardable; 178 } 179 getReserved()180 public long getReserved() { 181 return reserved; 182 } 183 setReserved(long reserved)184 public void setReserved(long reserved) { 185 this.reserved = reserved; 186 } 187 188 @Override toString()189 public String toString() { 190 return "SubsampleEntry{" + 191 "subsampleSize=" + subsampleSize + 192 ", subsamplePriority=" + subsamplePriority + 193 ", discardable=" + discardable + 194 ", reserved=" + reserved + 195 '}'; 196 } 197 } 198 199 @Override toString()200 public String toString() { 201 return "SampleEntry{" + 202 "sampleDelta=" + sampleDelta + 203 ", subsampleCount=" + subsampleCount + 204 ", subsampleEntries=" + subsampleEntries + 205 '}'; 206 } 207 } 208 } 209