summaryrefslogtreecommitdiff
path: root/isoparser/src/main/java/com/googlecode/mp4parser/boxes/mp4/samplegrouping/SampleGroupDescriptionBox.java
diff options
context:
space:
mode:
Diffstat (limited to 'isoparser/src/main/java/com/googlecode/mp4parser/boxes/mp4/samplegrouping/SampleGroupDescriptionBox.java')
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/boxes/mp4/samplegrouping/SampleGroupDescriptionBox.java200
1 files changed, 200 insertions, 0 deletions
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/boxes/mp4/samplegrouping/SampleGroupDescriptionBox.java b/isoparser/src/main/java/com/googlecode/mp4parser/boxes/mp4/samplegrouping/SampleGroupDescriptionBox.java
new file mode 100644
index 0000000..df4a96f
--- /dev/null
+++ b/isoparser/src/main/java/com/googlecode/mp4parser/boxes/mp4/samplegrouping/SampleGroupDescriptionBox.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2012 castLabs, Berlin
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.googlecode.mp4parser.boxes.mp4.samplegrouping;
+
+import com.coremedia.iso.IsoTypeReader;
+import com.coremedia.iso.IsoTypeWriter;
+import com.googlecode.mp4parser.AbstractFullBox;
+
+import java.nio.ByteBuffer;
+import java.util.LinkedList;
+import java.util.List;
+
+import static com.googlecode.mp4parser.util.CastUtils.l2i;
+
+/**
+ * This description table gives information about the characteristics of sample groups. The descriptive
+ * information is any other information needed to define or characterize the sample group.
+ * <p/>
+ * There may be multiple instances of this box if there is more than one sample grouping for the samples in a
+ * track. Each instance of the SampleGroupDescription box has a type code that distinguishes different
+ * sample groupings. Within a track, there shall be at most one instance of this box with a particular grouping
+ * type. The associated SampleToGroup shall indicate the same value for the grouping type.
+ * <p/>
+ * The information is stored in the sample group description box after the entry-count. An abstract entry type is
+ * defined and sample groupings shall define derived types to represent the description of each sample group.
+ * For video tracks, an abstract VisualSampleGroupEntry is used with similar types for audio and hint tracks.
+ */
+public class SampleGroupDescriptionBox extends AbstractFullBox {
+ public static final String TYPE = "sgpd";
+
+ private String groupingType;
+ private int defaultLength;
+ private List<GroupEntry> groupEntries = new LinkedList<GroupEntry>();
+ private int descriptionLength;
+
+ public SampleGroupDescriptionBox() {
+ super(TYPE);
+ }
+
+ @Override
+ protected long getContentSize() {
+ long size = 8;
+ if (getVersion() == 1) {
+ size += 4;
+ }
+ size += 4; // entryCount
+ for (GroupEntry groupEntry : groupEntries) {
+ if (getVersion() == 1 && defaultLength == 0) {
+ size += 4;
+ }
+ size += groupEntry.size();
+ }
+ return size;
+ }
+
+ @Override
+ protected void getContent(ByteBuffer byteBuffer) {
+ writeVersionAndFlags(byteBuffer);
+ byteBuffer.put(groupingType.getBytes());
+ if (this.getVersion() == 1) {
+ IsoTypeWriter.writeUInt32(byteBuffer, defaultLength);
+ }
+ IsoTypeWriter.writeUInt32(byteBuffer, this.groupEntries.size());
+ for (GroupEntry entry : groupEntries) {
+ if (this.getVersion() == 1 && defaultLength == 0) {
+ IsoTypeWriter.writeUInt32(byteBuffer, entry.get().limit());
+ }
+ byteBuffer.put(entry.get());
+ }
+ }
+
+ @Override
+ protected void _parseDetails(ByteBuffer content) {
+ parseVersionAndFlags(content);
+ if (this.getVersion() != 1) {
+ throw new RuntimeException("SampleGroupDescriptionBox are only supported in version 1");
+ }
+ groupingType = IsoTypeReader.read4cc(content);
+ if (this.getVersion() == 1) {
+ defaultLength = l2i(IsoTypeReader.readUInt32(content));
+ }
+ long entryCount = IsoTypeReader.readUInt32(content);
+ while (entryCount-- > 0) {
+ int length = defaultLength;
+ if (this.getVersion() == 1) {
+ if (defaultLength == 0) {
+ descriptionLength = l2i(IsoTypeReader.readUInt32(content));
+ length = descriptionLength;
+ }
+ } else {
+ throw new RuntimeException("This should be implemented");
+ }
+ int finalPos = content.position() + length;
+ ByteBuffer parseMe = content.slice();
+ parseMe.limit(length);
+ groupEntries.add(parseGroupEntry(parseMe, groupingType));
+ content.position(finalPos);
+ }
+
+ }
+
+ private GroupEntry parseGroupEntry(ByteBuffer content, String groupingType) {
+ GroupEntry groupEntry;
+ if (RollRecoveryEntry.TYPE.equals(groupingType)) {
+ groupEntry = new RollRecoveryEntry();
+ } else if (RateShareEntry.TYPE.equals(groupingType)) {
+ groupEntry = new RateShareEntry();
+ } else if (CencSampleEncryptionInformationGroupEntry.TYPE.equals(groupingType)) {
+ groupEntry = new CencSampleEncryptionInformationGroupEntry();
+ } else if (VisualRandomAccessEntry.TYPE.equals(groupingType)) {
+ groupEntry = new VisualRandomAccessEntry();
+ } else if (TemporalLevelEntry.TYPE.equals(groupingType)) {
+ groupEntry = new TemporalLevelEntry();
+ } else {
+ groupEntry = new UnknownEntry();
+ }
+ groupEntry.parse(content);
+ return groupEntry;
+ }
+
+
+ public String getGroupingType() {
+ return groupingType;
+ }
+
+ public void setGroupingType(String groupingType) {
+ this.groupingType = groupingType;
+ }
+
+ public int getDefaultLength() {
+ return defaultLength;
+ }
+
+ public void setDefaultLength(int defaultLength) {
+ this.defaultLength = defaultLength;
+ }
+
+ public List<GroupEntry> getGroupEntries() {
+ return groupEntries;
+ }
+
+ public void setGroupEntries(List<GroupEntry> groupEntries) {
+ this.groupEntries = groupEntries;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ SampleGroupDescriptionBox that = (SampleGroupDescriptionBox) o;
+
+ if (defaultLength != that.defaultLength) {
+ return false;
+ }
+ if (groupEntries != null ? !groupEntries.equals(that.groupEntries) : that.groupEntries != null) {
+ return false;
+ }
+ if (groupingType != null ? !groupingType.equals(that.groupingType) : that.groupingType != null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = groupingType != null ? groupingType.hashCode() : 0;
+ result = 31 * result + defaultLength;
+ result = 31 * result + (groupEntries != null ? groupEntries.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "SampleGroupDescriptionBox{" +
+ "groupingType='" + groupingType + '\'' +
+ ", defaultLength=" + defaultLength +
+ ", groupEntries=" + groupEntries +
+ '}';
+ }
+}