summaryrefslogtreecommitdiff
path: root/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry
diff options
context:
space:
mode:
Diffstat (limited to 'isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry')
-rw-r--r--isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/all-wcprops53
-rw-r--r--isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/entries300
-rw-r--r--isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/AmrSpecificBox.java.svn-base101
-rw-r--r--isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/AudioSampleEntry.java.svn-base278
-rw-r--r--isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/MpegSampleEntry.java.svn-base43
-rw-r--r--isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/Ovc1VisualSampleEntryImpl.java.svn-base45
-rw-r--r--isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/SampleEntry.java.svn-base159
-rw-r--r--isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/SubtitleSampleEntry.java.svn-base76
-rw-r--r--isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/TextSampleEntry.java.svn-base305
-rw-r--r--isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/VisualSampleEntry.java.svn-base213
-rw-r--r--isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/AmrSpecificBox.java101
-rw-r--r--isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/AudioSampleEntry.java278
-rw-r--r--isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/MpegSampleEntry.java43
-rw-r--r--isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/Ovc1VisualSampleEntryImpl.java45
-rw-r--r--isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/SampleEntry.java159
-rw-r--r--isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/SubtitleSampleEntry.java76
-rw-r--r--isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/TextSampleEntry.java305
-rw-r--r--isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/VisualSampleEntry.java213
18 files changed, 2793 insertions, 0 deletions
diff --git a/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/all-wcprops b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/all-wcprops
new file mode 100644
index 0000000..8a5b647
--- /dev/null
+++ b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/all-wcprops
@@ -0,0 +1,53 @@
+K 25
+svn:wc:ra_dav:version-url
+V 83
+/svn/!svn/ver/757/trunk/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry
+END
+SubtitleSampleEntry.java
+K 25
+svn:wc:ra_dav:version-url
+V 108
+/svn/!svn/ver/507/trunk/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/SubtitleSampleEntry.java
+END
+Ovc1VisualSampleEntryImpl.java
+K 25
+svn:wc:ra_dav:version-url
+V 114
+/svn/!svn/ver/507/trunk/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/Ovc1VisualSampleEntryImpl.java
+END
+SampleEntry.java
+K 25
+svn:wc:ra_dav:version-url
+V 100
+/svn/!svn/ver/745/trunk/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/SampleEntry.java
+END
+AudioSampleEntry.java
+K 25
+svn:wc:ra_dav:version-url
+V 105
+/svn/!svn/ver/757/trunk/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/AudioSampleEntry.java
+END
+VisualSampleEntry.java
+K 25
+svn:wc:ra_dav:version-url
+V 106
+/svn/!svn/ver/745/trunk/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/VisualSampleEntry.java
+END
+TextSampleEntry.java
+K 25
+svn:wc:ra_dav:version-url
+V 104
+/svn/!svn/ver/507/trunk/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/TextSampleEntry.java
+END
+MpegSampleEntry.java
+K 25
+svn:wc:ra_dav:version-url
+V 104
+/svn/!svn/ver/507/trunk/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/MpegSampleEntry.java
+END
+AmrSpecificBox.java
+K 25
+svn:wc:ra_dav:version-url
+V 103
+/svn/!svn/ver/507/trunk/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/AmrSpecificBox.java
+END
diff --git a/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/entries b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/entries
new file mode 100644
index 0000000..3891d06
--- /dev/null
+++ b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/entries
@@ -0,0 +1,300 @@
+10
+
+dir
+778
+http://mp4parser.googlecode.com/svn/trunk/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry
+http://mp4parser.googlecode.com/svn
+
+
+
+2012-08-17T05:55:12.215481Z
+757
+michael.stattmann@gmail.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7decde4b-c250-0410-a0da-51896bc88be6
+
+SubtitleSampleEntry.java
+file
+
+
+
+
+2012-09-14T17:27:52.647249Z
+a1d02883384ec405c3d62e1a4d157b5e
+2012-04-21T22:05:38.425329Z
+507
+Sebastian.Annies@gmail.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2055
+
+Ovc1VisualSampleEntryImpl.java
+file
+
+
+
+
+2012-09-14T17:27:52.647249Z
+c92067b340193f4ffa776fd1e449dcf5
+2012-04-21T22:05:38.425329Z
+507
+Sebastian.Annies@gmail.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1018
+
+SampleEntry.java
+file
+
+
+
+
+2012-09-14T17:27:52.647249Z
+8d726941a0af28eaa7b3cc9abcf4bd55
+2012-08-14T19:18:50.777750Z
+745
+Sebastian.Annies@gmail.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5020
+
+AudioSampleEntry.java
+file
+
+
+
+
+2012-09-14T17:27:52.647249Z
+3ee1365e9bd772c4e77c3011765ae58a
+2012-08-17T05:55:12.215481Z
+757
+michael.stattmann@gmail.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+8585
+
+VisualSampleEntry.java
+file
+
+
+
+
+2012-09-14T17:27:52.647249Z
+5616cce8d163f57f4e105fd3dbf34e61
+2012-08-14T19:18:50.777750Z
+745
+Sebastian.Annies@gmail.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6899
+
+TextSampleEntry.java
+file
+
+
+
+
+2012-09-14T17:27:52.647249Z
+96794e77ef63fbcc1cb861b25ddbb784
+2012-04-21T22:05:38.425329Z
+507
+Sebastian.Annies@gmail.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+9126
+
+MpegSampleEntry.java
+file
+
+
+
+
+2012-09-14T17:27:52.647249Z
+97170f2c4511a4f03915f73d5690cb4d
+2012-04-21T22:05:38.425329Z
+507
+Sebastian.Annies@gmail.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1079
+
+AmrSpecificBox.java
+file
+
+
+
+
+2012-09-14T17:27:52.647249Z
+c306ac7445479a0a2642022bb8428d8f
+2012-04-21T22:05:38.425329Z
+507
+Sebastian.Annies@gmail.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2974
+
diff --git a/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/AmrSpecificBox.java.svn-base b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/AmrSpecificBox.java.svn-base
new file mode 100644
index 0000000..f69de7b
--- /dev/null
+++ b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/AmrSpecificBox.java.svn-base
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2008 CoreMedia AG, Hamburg
+ *
+ * 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.coremedia.iso.boxes.sampleentry;
+
+
+import com.coremedia.iso.IsoFile;
+import com.coremedia.iso.IsoTypeReader;
+import com.coremedia.iso.IsoTypeWriter;
+import com.googlecode.mp4parser.AbstractBox;
+
+import java.nio.ByteBuffer;
+
+/**
+ * AMR audio format specific subbox of an audio sample entry.
+ *
+ * @see com.coremedia.iso.boxes.sampleentry.AudioSampleEntry
+ */
+public class AmrSpecificBox extends AbstractBox {
+ public static final String TYPE = "damr";
+
+ private String vendor;
+ private int decoderVersion;
+ private int modeSet;
+ private int modeChangePeriod;
+ private int framesPerSample;
+
+ public AmrSpecificBox() {
+ super(TYPE);
+ }
+
+ public String getVendor() {
+ return vendor;
+ }
+
+ public int getDecoderVersion() {
+ return decoderVersion;
+ }
+
+ public int getModeSet() {
+ return modeSet;
+ }
+
+ public int getModeChangePeriod() {
+ return modeChangePeriod;
+ }
+
+ public int getFramesPerSample() {
+ return framesPerSample;
+ }
+
+ protected long getContentSize() {
+ return 9;
+ }
+
+ @Override
+ public void _parseDetails(ByteBuffer content) {
+ byte[] v = new byte[4];
+ content.get(v);
+ vendor = IsoFile.bytesToFourCC(v);
+
+ decoderVersion = IsoTypeReader.readUInt8(content);
+ modeSet = IsoTypeReader.readUInt16(content);
+ modeChangePeriod = IsoTypeReader.readUInt8(content);
+ framesPerSample = IsoTypeReader.readUInt8(content);
+
+ }
+
+
+ public void getContent(ByteBuffer byteBuffer) {
+ byteBuffer.put(IsoFile.fourCCtoBytes(vendor));
+ IsoTypeWriter.writeUInt8(byteBuffer, decoderVersion);
+ IsoTypeWriter.writeUInt16(byteBuffer, modeSet);
+ IsoTypeWriter.writeUInt8(byteBuffer, modeChangePeriod);
+ IsoTypeWriter.writeUInt8(byteBuffer, framesPerSample);
+ }
+
+ public String toString() {
+ StringBuilder buffer = new StringBuilder();
+ buffer.append("AmrSpecificBox[vendor=").append(getVendor());
+ buffer.append(";decoderVersion=").append(getDecoderVersion());
+ buffer.append(";modeSet=").append(getModeSet());
+ buffer.append(";modeChangePeriod=").append(getModeChangePeriod());
+ buffer.append(";framesPerSample=").append(getFramesPerSample());
+ buffer.append("]");
+ return buffer.toString();
+ }
+}
diff --git a/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/AudioSampleEntry.java.svn-base b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/AudioSampleEntry.java.svn-base
new file mode 100644
index 0000000..69aeb79
--- /dev/null
+++ b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/AudioSampleEntry.java.svn-base
@@ -0,0 +1,278 @@
+/*
+ * Copyright 2008 CoreMedia AG, Hamburg
+ *
+ * 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.coremedia.iso.boxes.sampleentry;
+
+import com.coremedia.iso.BoxParser;
+import com.coremedia.iso.IsoTypeReader;
+import com.coremedia.iso.IsoTypeWriter;
+import com.coremedia.iso.boxes.Box;
+import com.coremedia.iso.boxes.ContainerBox;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Contains basic information about the audio samples in this track. Format-specific information
+ * is appened as boxes after the data described in ISO/IEC 14496-12 chapter 8.16.2.
+ */
+public class AudioSampleEntry extends SampleEntry implements ContainerBox {
+
+ public static final String TYPE1 = "samr";
+ public static final String TYPE2 = "sawb";
+ public static final String TYPE3 = "mp4a";
+ public static final String TYPE4 = "drms";
+ public static final String TYPE5 = "alac";
+ public static final String TYPE7 = "owma";
+ public static final String TYPE8 = "ac-3"; /* ETSI TS 102 366 1.2.1 Annex F */
+ public static final String TYPE9 = "ec-3"; /* ETSI TS 102 366 1.2.1 Annex F */
+ public static final String TYPE10 = "mlpa";
+ public static final String TYPE11 = "dtsl";
+ public static final String TYPE12 = "dtsh";
+ public static final String TYPE13 = "dtse";
+
+ /**
+ * Identifier for an encrypted audio track.
+ *
+ * @see com.coremedia.iso.boxes.ProtectionSchemeInformationBox
+ */
+ public static final String TYPE_ENCRYPTED = "enca";
+
+ private int channelCount;
+ private int sampleSize;
+ private long sampleRate;
+ private int soundVersion;
+ private int compressionId;
+ private int packetSize;
+ private long samplesPerPacket;
+ private long bytesPerPacket;
+ private long bytesPerFrame;
+ private long bytesPerSample;
+
+ private int reserved1;
+ private long reserved2;
+ private byte[] soundVersion2Data;
+ private BoxParser boxParser;
+
+ public AudioSampleEntry(String type) {
+ super(type);
+ }
+
+ public int getChannelCount() {
+ return channelCount;
+ }
+
+ public int getSampleSize() {
+ return sampleSize;
+ }
+
+ public long getSampleRate() {
+ return sampleRate;
+ }
+
+ public int getSoundVersion() {
+ return soundVersion;
+ }
+
+ public int getCompressionId() {
+ return compressionId;
+ }
+
+ public int getPacketSize() {
+ return packetSize;
+ }
+
+ public long getSamplesPerPacket() {
+ return samplesPerPacket;
+ }
+
+ public long getBytesPerPacket() {
+ return bytesPerPacket;
+ }
+
+ public long getBytesPerFrame() {
+ return bytesPerFrame;
+ }
+
+ public long getBytesPerSample() {
+ return bytesPerSample;
+ }
+
+ public byte[] getSoundVersion2Data() {
+ return soundVersion2Data;
+ }
+
+ public int getReserved1() {
+ return reserved1;
+ }
+
+ public long getReserved2() {
+ return reserved2;
+ }
+
+ public void setChannelCount(int channelCount) {
+ this.channelCount = channelCount;
+ }
+
+ public void setSampleSize(int sampleSize) {
+ this.sampleSize = sampleSize;
+ }
+
+ public void setSampleRate(long sampleRate) {
+ this.sampleRate = sampleRate;
+ }
+
+ public void setSoundVersion(int soundVersion) {
+ this.soundVersion = soundVersion;
+ }
+
+ public void setCompressionId(int compressionId) {
+ this.compressionId = compressionId;
+ }
+
+ public void setPacketSize(int packetSize) {
+ this.packetSize = packetSize;
+ }
+
+ public void setSamplesPerPacket(long samplesPerPacket) {
+ this.samplesPerPacket = samplesPerPacket;
+ }
+
+ public void setBytesPerPacket(long bytesPerPacket) {
+ this.bytesPerPacket = bytesPerPacket;
+ }
+
+ public void setBytesPerFrame(long bytesPerFrame) {
+ this.bytesPerFrame = bytesPerFrame;
+ }
+
+ public void setBytesPerSample(long bytesPerSample) {
+ this.bytesPerSample = bytesPerSample;
+ }
+
+ public void setReserved1(int reserved1) {
+ this.reserved1 = reserved1;
+ }
+
+ public void setReserved2(long reserved2) {
+ this.reserved2 = reserved2;
+ }
+
+ public void setSoundVersion2Data(byte[] soundVersion2Data) {
+ this.soundVersion2Data = soundVersion2Data;
+ }
+
+ public void setBoxParser(BoxParser boxParser) {
+ this.boxParser = boxParser;
+ }
+
+ @Override
+ public void _parseDetails(ByteBuffer content) {
+ _parseReservedAndDataReferenceIndex(content); //parses the six reserved bytes and dataReferenceIndex
+ // 8 bytes already parsed
+ //reserved bits - used by qt
+ soundVersion = IsoTypeReader.readUInt16(content);
+
+ //reserved
+ reserved1 = IsoTypeReader.readUInt16(content);
+ reserved2 = IsoTypeReader.readUInt32(content);
+
+ channelCount = IsoTypeReader.readUInt16(content);
+ sampleSize = IsoTypeReader.readUInt16(content);
+ //reserved bits - used by qt
+ compressionId = IsoTypeReader.readUInt16(content);
+ //reserved bits - used by qt
+ packetSize = IsoTypeReader.readUInt16(content);
+ //sampleRate = in.readFixedPoint1616();
+ sampleRate = IsoTypeReader.readUInt32(content);
+ if (!type.equals("mlpa")) {
+ sampleRate = sampleRate >>> 16;
+ }
+
+ //more qt stuff - see http://mp4v2.googlecode.com/svn-history/r388/trunk/src/atom_sound.cpp
+ if (soundVersion > 0) {
+ samplesPerPacket = IsoTypeReader.readUInt32(content);
+ bytesPerPacket = IsoTypeReader.readUInt32(content);
+ bytesPerFrame = IsoTypeReader.readUInt32(content);
+ bytesPerSample = IsoTypeReader.readUInt32(content);
+ }
+ if (soundVersion == 2) {
+
+ soundVersion2Data = new byte[20];
+ content.get(20);
+ }
+ _parseChildBoxes(content);
+
+ }
+
+
+ @Override
+ protected long getContentSize() {
+ long contentSize = 28;
+ contentSize += soundVersion > 0 ? 16 : 0;
+ contentSize += soundVersion == 2 ? 20 : 0;
+ for (Box boxe : boxes) {
+ contentSize += boxe.getSize();
+ }
+ return contentSize;
+ }
+
+ @Override
+ public String toString() {
+ return "AudioSampleEntry{" +
+ "bytesPerSample=" + bytesPerSample +
+ ", bytesPerFrame=" + bytesPerFrame +
+ ", bytesPerPacket=" + bytesPerPacket +
+ ", samplesPerPacket=" + samplesPerPacket +
+ ", packetSize=" + packetSize +
+ ", compressionId=" + compressionId +
+ ", soundVersion=" + soundVersion +
+ ", sampleRate=" + sampleRate +
+ ", sampleSize=" + sampleSize +
+ ", channelCount=" + channelCount +
+ ", boxes=" + getBoxes() +
+ '}';
+ }
+
+ @Override
+ protected void getContent(ByteBuffer byteBuffer) {
+ _writeReservedAndDataReferenceIndex(byteBuffer);
+ IsoTypeWriter.writeUInt16(byteBuffer, soundVersion);
+ IsoTypeWriter.writeUInt16(byteBuffer, reserved1);
+ IsoTypeWriter.writeUInt32(byteBuffer, reserved2);
+ IsoTypeWriter.writeUInt16(byteBuffer, channelCount);
+ IsoTypeWriter.writeUInt16(byteBuffer, sampleSize);
+ IsoTypeWriter.writeUInt16(byteBuffer, compressionId);
+ IsoTypeWriter.writeUInt16(byteBuffer, packetSize);
+ //isos.writeFixedPont1616(getSampleRate());
+ if (type.equals("mlpa")) {
+ IsoTypeWriter.writeUInt32(byteBuffer, getSampleRate());
+ } else {
+ IsoTypeWriter.writeUInt32(byteBuffer, getSampleRate() << 16);
+ }
+
+ if (soundVersion > 0) {
+ IsoTypeWriter.writeUInt32(byteBuffer, samplesPerPacket);
+ IsoTypeWriter.writeUInt32(byteBuffer, bytesPerPacket);
+ IsoTypeWriter.writeUInt32(byteBuffer, bytesPerFrame);
+ IsoTypeWriter.writeUInt32(byteBuffer, bytesPerSample);
+ }
+
+ if (soundVersion == 2) {
+ byteBuffer.put(soundVersion2Data);
+ }
+ _writeChildBoxes(byteBuffer);
+ }
+}
diff --git a/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/MpegSampleEntry.java.svn-base b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/MpegSampleEntry.java.svn-base
new file mode 100644
index 0000000..e4a33dc
--- /dev/null
+++ b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/MpegSampleEntry.java.svn-base
@@ -0,0 +1,43 @@
+package com.coremedia.iso.boxes.sampleentry;
+
+import com.coremedia.iso.BoxParser;
+import com.coremedia.iso.boxes.Box;
+import com.coremedia.iso.boxes.ContainerBox;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+public class MpegSampleEntry extends SampleEntry implements ContainerBox {
+
+ private BoxParser boxParser;
+
+ public MpegSampleEntry(String type) {
+ super(type);
+ }
+
+ @Override
+ public void _parseDetails(ByteBuffer content) {
+ _parseReservedAndDataReferenceIndex(content);
+ _parseChildBoxes(content);
+
+ }
+
+ @Override
+ protected long getContentSize() {
+ long contentSize = 8;
+ for (Box boxe : boxes) {
+ contentSize += boxe.getSize();
+ }
+ return contentSize;
+ }
+
+ public String toString() {
+ return "MpegSampleEntry" + Arrays.asList(getBoxes());
+ }
+
+ @Override
+ protected void getContent(ByteBuffer byteBuffer) {
+ _writeReservedAndDataReferenceIndex(byteBuffer);
+ _writeChildBoxes(byteBuffer);
+ }
+}
diff --git a/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/Ovc1VisualSampleEntryImpl.java.svn-base b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/Ovc1VisualSampleEntryImpl.java.svn-base
new file mode 100644
index 0000000..56b8adb
--- /dev/null
+++ b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/Ovc1VisualSampleEntryImpl.java.svn-base
@@ -0,0 +1,45 @@
+package com.coremedia.iso.boxes.sampleentry;
+
+import com.coremedia.iso.IsoTypeWriter;
+import com.coremedia.iso.boxes.Box;
+
+import java.nio.ByteBuffer;
+
+
+public class Ovc1VisualSampleEntryImpl extends SampleEntry {
+ private byte[] vc1Content;
+ public static final String TYPE = "ovc1";
+
+
+ @Override
+ protected long getContentSize() {
+ long size = 8;
+
+ for (Box box : boxes) {
+ size += box.getSize();
+ }
+ size += vc1Content.length;
+ return size;
+ }
+
+ @Override
+ public void _parseDetails(ByteBuffer content) {
+ _parseReservedAndDataReferenceIndex(content);
+ vc1Content = new byte[content.remaining()];
+ content.get(vc1Content);
+
+ }
+
+ @Override
+ protected void getContent(ByteBuffer byteBuffer) {
+ byteBuffer.put(new byte[6]);
+ IsoTypeWriter.writeUInt16(byteBuffer, getDataReferenceIndex());
+ byteBuffer.put(vc1Content);
+ }
+
+
+ protected Ovc1VisualSampleEntryImpl() {
+ super(TYPE);
+ }
+
+}
diff --git a/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/SampleEntry.java.svn-base b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/SampleEntry.java.svn-base
new file mode 100644
index 0000000..a1a5486
--- /dev/null
+++ b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/SampleEntry.java.svn-base
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2008 CoreMedia AG, Hamburg
+ *
+ * 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.coremedia.iso.boxes.sampleentry;
+
+import com.coremedia.iso.BoxParser;
+import com.coremedia.iso.IsoTypeReader;
+import com.coremedia.iso.IsoTypeWriter;
+import com.googlecode.mp4parser.AbstractBox;
+import com.coremedia.iso.boxes.Box;
+import com.coremedia.iso.boxes.ContainerBox;
+import com.googlecode.mp4parser.util.ByteBufferByteChannel;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.channels.WritableByteChannel;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Abstract base class for all sample entries.
+ *
+ * @see com.coremedia.iso.boxes.sampleentry.AudioSampleEntry
+ * @see com.coremedia.iso.boxes.sampleentry.VisualSampleEntry
+ * @see com.coremedia.iso.boxes.sampleentry.TextSampleEntry
+ */
+public abstract class SampleEntry extends AbstractBox implements ContainerBox {
+
+
+ private int dataReferenceIndex = 1;
+ protected List<Box> boxes = new LinkedList<Box>();
+ private BoxParser boxParser;
+
+
+ protected SampleEntry(String type) {
+ super(type);
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public int getDataReferenceIndex() {
+ return dataReferenceIndex;
+ }
+
+ public void setDataReferenceIndex(int dataReferenceIndex) {
+ this.dataReferenceIndex = dataReferenceIndex;
+ }
+
+ public void setBoxes(List<Box> boxes) {
+ this.boxes = new LinkedList<Box>(boxes);
+ }
+
+ public void addBox(Box b) {
+ b.setParent(this);
+ boxes.add(b);
+ }
+
+ public boolean removeBox(Box b) {
+ b.setParent(this);
+ return boxes.remove(b);
+ }
+
+ public List<Box> getBoxes() {
+ return boxes;
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T extends Box> List<T> getBoxes(Class<T> clazz, boolean recursive) {
+ List<T> boxesToBeReturned = new ArrayList<T>(2);
+ for (Box boxe : boxes) { //clazz.isInstance(boxe) / clazz == boxe.getClass()?
+ if (clazz == boxe.getClass()) {
+ boxesToBeReturned.add((T) boxe);
+ }
+
+ if (recursive && boxe instanceof ContainerBox) {
+ boxesToBeReturned.addAll(((ContainerBox) boxe).getBoxes(clazz, recursive));
+ }
+ }
+ // Optimize here! Spare object creation work on arrays directly! System.arrayCopy
+ return boxesToBeReturned;
+ //return (T[]) boxesToBeReturned.toArray();
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T extends Box> List<T> getBoxes(Class<T> clazz) {
+ return getBoxes(clazz, false);
+ }
+
+ @Override
+ public void parse(ReadableByteChannel readableByteChannel, ByteBuffer header, long contentSize, BoxParser boxParser) throws IOException {
+ super.parse(readableByteChannel, header, contentSize, boxParser);
+ this.boxParser = boxParser;
+ }
+
+
+ public void _parseReservedAndDataReferenceIndex(ByteBuffer content) {
+ content.get(new byte[6]); // ignore 6 reserved bytes;
+ dataReferenceIndex = IsoTypeReader.readUInt16(content);
+ }
+
+ public void _parseChildBoxes(ByteBuffer content) {
+ while (content.remaining() > 8) {
+ try {
+ boxes.add(boxParser.parseBox(new ByteBufferByteChannel(content), this));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+ setDeadBytes(content.slice());
+ }
+
+ public void _writeReservedAndDataReferenceIndex(ByteBuffer bb) {
+ bb.put(new byte[6]);
+ IsoTypeWriter.writeUInt16(bb, dataReferenceIndex);
+ }
+
+ public void _writeChildBoxes(ByteBuffer bb) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ WritableByteChannel wbc = Channels.newChannel(baos);
+ try {
+ for (Box box : boxes) {
+ box.getBox(wbc);
+ }
+ wbc.close();
+ } catch (IOException e) {
+ throw new RuntimeException("Cannot happen. Everything should be in memory and therefore no exceptions.");
+ }
+ bb.put(baos.toByteArray());
+ }
+
+ public long getNumOfBytesToFirstChild() {
+ long sizeOfChildren = 0;
+ for (Box box : boxes) {
+ sizeOfChildren += box.getSize();
+ }
+ return getSize() - sizeOfChildren;
+ }
+
+}
diff --git a/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/SubtitleSampleEntry.java.svn-base b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/SubtitleSampleEntry.java.svn-base
new file mode 100644
index 0000000..21d0cc4
--- /dev/null
+++ b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/SubtitleSampleEntry.java.svn-base
@@ -0,0 +1,76 @@
+package com.coremedia.iso.boxes.sampleentry;
+
+import com.coremedia.iso.IsoTypeReader;
+import com.coremedia.iso.IsoTypeWriter;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: magnus
+ * Date: 2012-03-08
+ * Time: 11:36
+ * To change this template use File | Settings | File Templates.
+ */
+public class SubtitleSampleEntry extends SampleEntry {
+
+ public static final String TYPE1 = "stpp";
+
+ public static final String TYPE_ENCRYPTED = ""; // This is not known!
+
+ private String namespace;
+ private String schemaLocation;
+ private String imageMimeType;
+
+ public SubtitleSampleEntry(String type) {
+ super(type);
+ }
+
+ @Override
+ protected long getContentSize() {
+ long contentSize = 8 + namespace.length() + schemaLocation.length() + imageMimeType.length() + 3;
+ return contentSize;
+ }
+
+ @Override
+ public void _parseDetails(ByteBuffer content) {
+ _parseReservedAndDataReferenceIndex(content);
+ namespace = IsoTypeReader.readString(content);
+ schemaLocation = IsoTypeReader.readString(content);
+ imageMimeType = IsoTypeReader.readString(content);
+ _parseChildBoxes(content);
+ }
+
+ @Override
+ protected void getContent(ByteBuffer byteBuffer) {
+ _writeReservedAndDataReferenceIndex(byteBuffer);
+ IsoTypeWriter.writeUtf8String(byteBuffer, namespace);
+ IsoTypeWriter.writeUtf8String(byteBuffer, schemaLocation);
+ IsoTypeWriter.writeUtf8String(byteBuffer, imageMimeType);
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public void setNamespace(String namespace) {
+ this.namespace = namespace;
+ }
+
+ public String getSchemaLocation() {
+ return schemaLocation;
+ }
+
+ public void setSchemaLocation(String schemaLocation) {
+ this.schemaLocation = schemaLocation;
+ }
+
+ public String getImageMimeType() {
+ return imageMimeType;
+ }
+
+ public void setImageMimeType(String imageMimeType) {
+ this.imageMimeType = imageMimeType;
+ }
+}
+
diff --git a/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/TextSampleEntry.java.svn-base b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/TextSampleEntry.java.svn-base
new file mode 100644
index 0000000..3a0b83a
--- /dev/null
+++ b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/TextSampleEntry.java.svn-base
@@ -0,0 +1,305 @@
+/*
+ * Copyright 2008 CoreMedia AG, Hamburg
+ *
+ * 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.coremedia.iso.boxes.sampleentry;
+
+import com.coremedia.iso.IsoTypeReader;
+import com.coremedia.iso.IsoTypeWriter;
+import com.coremedia.iso.boxes.Box;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * Entry type for timed text samples defined in the timed text specification (ISO/IEC 14496-17).
+ */
+public class TextSampleEntry extends SampleEntry {
+
+ public static final String TYPE1 = "tx3g";
+
+ public static final String TYPE_ENCRYPTED = "enct";
+
+/* class TextSampleEntry() extends SampleEntry ('tx3g') {
+ unsigned int(32) displayFlags;
+ signed int(8) horizontal-justification;
+ signed int(8) vertical-justification;
+ unsigned int(8) background-color-rgba[4];
+ BoxRecord default-text-box;
+ StyleRecord default-style;
+ FontTableBox font-table;
+ }
+ */
+
+ private long displayFlags; // 32 bits
+ private int horizontalJustification; // 8 bit
+ private int verticalJustification; // 8 bit
+ private int[] backgroundColorRgba = new int[4]; // 4 bytes
+ private BoxRecord boxRecord = new BoxRecord();
+ private StyleRecord styleRecord = new StyleRecord();
+
+ public TextSampleEntry(String type) {
+ super(type);
+ }
+
+ @Override
+ public void _parseDetails(ByteBuffer content) {
+ _parseReservedAndDataReferenceIndex(content);
+ displayFlags = IsoTypeReader.readUInt32(content);
+ horizontalJustification = IsoTypeReader.readUInt8(content);
+ verticalJustification = IsoTypeReader.readUInt8(content);
+ backgroundColorRgba = new int[4];
+ backgroundColorRgba[0] = IsoTypeReader.readUInt8(content);
+ backgroundColorRgba[1] = IsoTypeReader.readUInt8(content);
+ backgroundColorRgba[2] = IsoTypeReader.readUInt8(content);
+ backgroundColorRgba[3] = IsoTypeReader.readUInt8(content);
+ boxRecord = new BoxRecord();
+ boxRecord.parse(content);
+
+ styleRecord = new StyleRecord();
+ styleRecord.parse(content);
+ _parseChildBoxes(content);
+ }
+
+
+ protected long getContentSize() {
+ long contentSize = 18;
+ contentSize += boxRecord.getSize();
+ contentSize += styleRecord.getSize();
+ for (Box boxe : boxes) {
+ contentSize += boxe.getSize();
+ }
+ return contentSize;
+ }
+
+ public String toString() {
+ return "TextSampleEntry";
+ }
+
+ @Override
+ protected void getContent(ByteBuffer byteBuffer) {
+ _writeReservedAndDataReferenceIndex(byteBuffer);
+ IsoTypeWriter.writeUInt32(byteBuffer, displayFlags);
+ IsoTypeWriter.writeUInt8(byteBuffer, horizontalJustification);
+ IsoTypeWriter.writeUInt8(byteBuffer, verticalJustification);
+ IsoTypeWriter.writeUInt8(byteBuffer, backgroundColorRgba[0]);
+ IsoTypeWriter.writeUInt8(byteBuffer, backgroundColorRgba[1]);
+ IsoTypeWriter.writeUInt8(byteBuffer, backgroundColorRgba[2]);
+ IsoTypeWriter.writeUInt8(byteBuffer, backgroundColorRgba[3]);
+ boxRecord.getContent(byteBuffer);
+ styleRecord.getContent(byteBuffer);
+
+ _writeChildBoxes(byteBuffer);
+ }
+
+ public BoxRecord getBoxRecord() {
+ return boxRecord;
+ }
+
+ public void setBoxRecord(BoxRecord boxRecord) {
+ this.boxRecord = boxRecord;
+ }
+
+ public StyleRecord getStyleRecord() {
+ return styleRecord;
+ }
+
+ public void setStyleRecord(StyleRecord styleRecord) {
+ this.styleRecord = styleRecord;
+ }
+
+ public boolean isScrollIn() {
+ return (displayFlags & 0x00000020) == 0x00000020;
+ }
+
+ public void setScrollIn(boolean scrollIn) {
+ if (scrollIn) {
+ displayFlags |= 0x00000020;
+ } else {
+ displayFlags &= ~0x00000020;
+ }
+ }
+
+ public boolean isScrollOut() {
+ return (displayFlags & 0x00000040) == 0x00000040;
+ }
+
+ public void setScrollOut(boolean scrollOutIn) {
+ if (scrollOutIn) {
+ displayFlags |= 0x00000040;
+ } else {
+ displayFlags &= ~0x00000040;
+ }
+ }
+
+ public boolean isScrollDirection() {
+ return (displayFlags & 0x00000180) == 0x00000180;
+ }
+
+ public void setScrollDirection(boolean scrollOutIn) {
+ if (scrollOutIn) {
+ displayFlags |= 0x00000180;
+ } else {
+ displayFlags &= ~0x00000180;
+ }
+ }
+
+ public boolean isContinuousKaraoke() {
+ return (displayFlags & 0x00000800) == 0x00000800;
+ }
+
+ public void setContinuousKaraoke(boolean continuousKaraoke) {
+ if (continuousKaraoke) {
+ displayFlags |= 0x00000800;
+ } else {
+ displayFlags &= ~0x00000800;
+ }
+ }
+
+ public boolean isWriteTextVertically() {
+ return (displayFlags & 0x00020000) == 0x00020000;
+ }
+
+ public void setWriteTextVertically(boolean writeTextVertically) {
+ if (writeTextVertically) {
+ displayFlags |= 0x00020000;
+ } else {
+ displayFlags &= ~0x00020000;
+ }
+ }
+
+
+ public boolean isFillTextRegion() {
+ return (displayFlags & 0x00040000) == 0x00040000;
+ }
+
+ public void setFillTextRegion(boolean fillTextRegion) {
+ if (fillTextRegion) {
+ displayFlags |= 0x00040000;
+ } else {
+ displayFlags &= ~0x00040000;
+ }
+ }
+
+
+ public int getHorizontalJustification() {
+ return horizontalJustification;
+ }
+
+ public void setHorizontalJustification(int horizontalJustification) {
+ this.horizontalJustification = horizontalJustification;
+ }
+
+ public int getVerticalJustification() {
+ return verticalJustification;
+ }
+
+ public void setVerticalJustification(int verticalJustification) {
+ this.verticalJustification = verticalJustification;
+ }
+
+ public int[] getBackgroundColorRgba() {
+ return backgroundColorRgba;
+ }
+
+ public void setBackgroundColorRgba(int[] backgroundColorRgba) {
+ this.backgroundColorRgba = backgroundColorRgba;
+ }
+
+ public static class BoxRecord {
+ int top;
+ int left;
+ int bottom;
+ int right;
+
+ public void parse(ByteBuffer in) {
+ top = IsoTypeReader.readUInt16(in);
+ left = IsoTypeReader.readUInt16(in);
+ bottom = IsoTypeReader.readUInt16(in);
+ right = IsoTypeReader.readUInt16(in);
+ }
+
+ public void getContent(ByteBuffer bb) {
+ IsoTypeWriter.writeUInt16(bb, top);
+ IsoTypeWriter.writeUInt16(bb, left);
+ IsoTypeWriter.writeUInt16(bb, bottom);
+ IsoTypeWriter.writeUInt16(bb, right);
+ }
+
+ public int getSize() {
+ return 8;
+ }
+ }
+
+ /*
+ class FontRecord {
+ unsigned int(16) font-ID;
+ unsigned int(8) font-name-length;
+ unsigned int(8) font[font-name-length];
+}
+ */
+
+
+ /*
+ aligned(8) class StyleRecord {
+ unsigned int(16) startChar;
+ unsigned int(16) endChar;
+ unsigned int(16) font-ID;
+ unsigned int(8) face-style-flags;
+ unsigned int(8) font-size;
+ unsigned int(8) text-color-rgba[4];
+}
+ */
+ public static class StyleRecord {
+ int startChar;
+ int endChar;
+ int fontId;
+ int faceStyleFlags;
+ int fontSize;
+ int[] textColor = new int[]{0xff, 0xff, 0xff, 0xff};
+
+ public void parse(ByteBuffer in) {
+ startChar = IsoTypeReader.readUInt16(in);
+ endChar = IsoTypeReader.readUInt16(in);
+ fontId = IsoTypeReader.readUInt16(in);
+ faceStyleFlags = IsoTypeReader.readUInt8(in);
+ fontSize = IsoTypeReader.readUInt8(in);
+ textColor = new int[4];
+ textColor[0] = IsoTypeReader.readUInt8(in);
+ textColor[1] = IsoTypeReader.readUInt8(in);
+ textColor[2] = IsoTypeReader.readUInt8(in);
+ textColor[3] = IsoTypeReader.readUInt8(in);
+ }
+
+
+ public void getContent(ByteBuffer bb) {
+ IsoTypeWriter.writeUInt16(bb, startChar);
+ IsoTypeWriter.writeUInt16(bb, endChar);
+ IsoTypeWriter.writeUInt16(bb, fontId);
+ IsoTypeWriter.writeUInt8(bb, faceStyleFlags);
+ IsoTypeWriter.writeUInt8(bb, fontSize);
+ IsoTypeWriter.writeUInt8(bb, textColor[0]);
+ IsoTypeWriter.writeUInt8(bb, textColor[1]);
+ IsoTypeWriter.writeUInt8(bb, textColor[2]);
+ IsoTypeWriter.writeUInt8(bb, textColor[3]);
+ }
+
+ public int getSize() {
+ return 12;
+ }
+ }
+
+
+}
diff --git a/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/VisualSampleEntry.java.svn-base b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/VisualSampleEntry.java.svn-base
new file mode 100644
index 0000000..407e79f
--- /dev/null
+++ b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/.svn/text-base/VisualSampleEntry.java.svn-base
@@ -0,0 +1,213 @@
+/*
+ * Copyright 2008 CoreMedia AG, Hamburg
+ *
+ * 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.coremedia.iso.boxes.sampleentry;
+
+import com.coremedia.iso.IsoTypeReader;
+import com.coremedia.iso.IsoTypeWriter;
+import com.coremedia.iso.Utf8;
+import com.coremedia.iso.boxes.Box;
+import com.coremedia.iso.boxes.ContainerBox;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Contains information common to all visual tracks.
+ * <code>
+ * <pre>
+ * class VisualSampleEntry(codingname) extends SampleEntry (codingname){
+ * unsigned int(16) pre_defined = 0;
+ * const unsigned int(16) reserved = 0;
+ * unsigned int(32)[3] pre_defined = 0;
+ * unsigned int(16) width;
+ * unsigned int(16) height;
+ * template unsigned int(32) horizresolution = 0x00480000; // 72 dpi
+ * template unsigned int(32) vertresolution = 0x00480000; // 72 dpi
+ * const unsigned int(32) reserved = 0;
+ * template unsigned int(16) frame_count = 1;
+ * string[32] compressorname;
+ * template unsigned int(16) depth = 0x0018;
+ * int(16) pre_defined = -1;
+ * }<br>
+ * </pre>
+ * </code>
+ * <p/>
+ * Format-specific informationis appened as boxes after the data described in ISO/IEC 14496-12 chapter 8.16.2.
+ */
+public class VisualSampleEntry extends SampleEntry implements ContainerBox {
+ public static final String TYPE1 = "mp4v";
+ public static final String TYPE2 = "s263";
+ public static final String TYPE3 = "avc1";
+
+
+ /**
+ * Identifier for an encrypted video track.
+ *
+ * @see com.coremedia.iso.boxes.ProtectionSchemeInformationBox
+ */
+ public static final String TYPE_ENCRYPTED = "encv";
+
+
+ private int width;
+ private int height;
+ private double horizresolution = 72;
+ private double vertresolution = 72;
+ private int frameCount = 1;
+ private String compressorname;
+ private int depth = 24;
+
+ private long[] predefined = new long[3];
+
+ public VisualSampleEntry(String type) {
+ super(type);
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ public double getHorizresolution() {
+ return horizresolution;
+ }
+
+ public double getVertresolution() {
+ return vertresolution;
+ }
+
+ public int getFrameCount() {
+ return frameCount;
+ }
+
+ public String getCompressorname() {
+ return compressorname;
+ }
+
+ public int getDepth() {
+ return depth;
+ }
+
+ public void setCompressorname(String compressorname) {
+ this.compressorname = compressorname;
+ }
+
+ public void setWidth(int width) {
+ this.width = width;
+ }
+
+ public void setHeight(int height) {
+ this.height = height;
+ }
+
+ public void setHorizresolution(double horizresolution) {
+ this.horizresolution = horizresolution;
+ }
+
+ public void setVertresolution(double vertresolution) {
+ this.vertresolution = vertresolution;
+ }
+
+ public void setFrameCount(int frameCount) {
+ this.frameCount = frameCount;
+ }
+
+ public void setDepth(int depth) {
+ this.depth = depth;
+ }
+
+ @Override
+ public void _parseDetails(ByteBuffer content) {
+ _parseReservedAndDataReferenceIndex(content);
+ long tmp = IsoTypeReader.readUInt16(content);
+ assert 0 == tmp : "reserved byte not 0";
+ tmp = IsoTypeReader.readUInt16(content);
+ assert 0 == tmp : "reserved byte not 0";
+ predefined[0] = IsoTypeReader.readUInt32(content); // should be zero
+ predefined[1] = IsoTypeReader.readUInt32(content); // should be zero
+ predefined[2] = IsoTypeReader.readUInt32(content); // should be zero
+ width = IsoTypeReader.readUInt16(content);
+ height = IsoTypeReader.readUInt16(content);
+ horizresolution = IsoTypeReader.readFixedPoint1616(content);
+ vertresolution = IsoTypeReader.readFixedPoint1616(content);
+ tmp = IsoTypeReader.readUInt32(content);
+ assert 0 == tmp : "reserved byte not 0";
+ frameCount = IsoTypeReader.readUInt16(content);
+ int compressornameDisplayAbleData = IsoTypeReader.readUInt8(content);
+ if (compressornameDisplayAbleData > 31) {
+ System.out.println("invalid compressor name displayable data: " + compressornameDisplayAbleData);
+ compressornameDisplayAbleData = 31;
+ }
+ byte[] bytes = new byte[compressornameDisplayAbleData];
+ content.get(bytes);
+ compressorname = Utf8.convert(bytes);
+ if (compressornameDisplayAbleData < 31) {
+ byte[] zeros = new byte[31 - compressornameDisplayAbleData];
+ content.get(zeros);
+ //assert Arrays.equals(zeros, new byte[zeros.length]) : "The compressor name length was not filled up with zeros";
+ }
+ depth = IsoTypeReader.readUInt16(content);
+ tmp = IsoTypeReader.readUInt16(content);
+ assert 0xFFFF == tmp;
+
+ _parseChildBoxes(content);
+
+ }
+
+
+ protected long getContentSize() {
+ long contentSize = 78;
+ for (Box boxe : boxes) {
+ contentSize += boxe.getSize();
+ }
+ return contentSize;
+ }
+
+ @Override
+ protected void getContent(ByteBuffer byteBuffer) {
+ _writeReservedAndDataReferenceIndex(byteBuffer);
+ IsoTypeWriter.writeUInt16(byteBuffer, 0);
+ IsoTypeWriter.writeUInt16(byteBuffer, 0);
+ IsoTypeWriter.writeUInt32(byteBuffer, predefined[0]);
+ IsoTypeWriter.writeUInt32(byteBuffer, predefined[1]);
+ IsoTypeWriter.writeUInt32(byteBuffer, predefined[2]);
+
+ IsoTypeWriter.writeUInt16(byteBuffer, getWidth());
+ IsoTypeWriter.writeUInt16(byteBuffer, getHeight());
+
+ IsoTypeWriter.writeFixedPont1616(byteBuffer, getHorizresolution());
+ IsoTypeWriter.writeFixedPont1616(byteBuffer, getVertresolution());
+
+
+ IsoTypeWriter.writeUInt32(byteBuffer, 0);
+ IsoTypeWriter.writeUInt16(byteBuffer, getFrameCount());
+ IsoTypeWriter.writeUInt8(byteBuffer, Utf8.utf8StringLengthInBytes(getCompressorname()));
+ byteBuffer.put(Utf8.convert(getCompressorname()));
+ int a = Utf8.utf8StringLengthInBytes(getCompressorname());
+ while (a < 31) {
+ a++;
+ byteBuffer.put((byte) 0);
+ }
+ IsoTypeWriter.writeUInt16(byteBuffer, getDepth());
+ IsoTypeWriter.writeUInt16(byteBuffer, 0xFFFF);
+
+ _writeChildBoxes(byteBuffer);
+
+ }
+
+}
diff --git a/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/AmrSpecificBox.java b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/AmrSpecificBox.java
new file mode 100644
index 0000000..f69de7b
--- /dev/null
+++ b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/AmrSpecificBox.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2008 CoreMedia AG, Hamburg
+ *
+ * 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.coremedia.iso.boxes.sampleentry;
+
+
+import com.coremedia.iso.IsoFile;
+import com.coremedia.iso.IsoTypeReader;
+import com.coremedia.iso.IsoTypeWriter;
+import com.googlecode.mp4parser.AbstractBox;
+
+import java.nio.ByteBuffer;
+
+/**
+ * AMR audio format specific subbox of an audio sample entry.
+ *
+ * @see com.coremedia.iso.boxes.sampleentry.AudioSampleEntry
+ */
+public class AmrSpecificBox extends AbstractBox {
+ public static final String TYPE = "damr";
+
+ private String vendor;
+ private int decoderVersion;
+ private int modeSet;
+ private int modeChangePeriod;
+ private int framesPerSample;
+
+ public AmrSpecificBox() {
+ super(TYPE);
+ }
+
+ public String getVendor() {
+ return vendor;
+ }
+
+ public int getDecoderVersion() {
+ return decoderVersion;
+ }
+
+ public int getModeSet() {
+ return modeSet;
+ }
+
+ public int getModeChangePeriod() {
+ return modeChangePeriod;
+ }
+
+ public int getFramesPerSample() {
+ return framesPerSample;
+ }
+
+ protected long getContentSize() {
+ return 9;
+ }
+
+ @Override
+ public void _parseDetails(ByteBuffer content) {
+ byte[] v = new byte[4];
+ content.get(v);
+ vendor = IsoFile.bytesToFourCC(v);
+
+ decoderVersion = IsoTypeReader.readUInt8(content);
+ modeSet = IsoTypeReader.readUInt16(content);
+ modeChangePeriod = IsoTypeReader.readUInt8(content);
+ framesPerSample = IsoTypeReader.readUInt8(content);
+
+ }
+
+
+ public void getContent(ByteBuffer byteBuffer) {
+ byteBuffer.put(IsoFile.fourCCtoBytes(vendor));
+ IsoTypeWriter.writeUInt8(byteBuffer, decoderVersion);
+ IsoTypeWriter.writeUInt16(byteBuffer, modeSet);
+ IsoTypeWriter.writeUInt8(byteBuffer, modeChangePeriod);
+ IsoTypeWriter.writeUInt8(byteBuffer, framesPerSample);
+ }
+
+ public String toString() {
+ StringBuilder buffer = new StringBuilder();
+ buffer.append("AmrSpecificBox[vendor=").append(getVendor());
+ buffer.append(";decoderVersion=").append(getDecoderVersion());
+ buffer.append(";modeSet=").append(getModeSet());
+ buffer.append(";modeChangePeriod=").append(getModeChangePeriod());
+ buffer.append(";framesPerSample=").append(getFramesPerSample());
+ buffer.append("]");
+ return buffer.toString();
+ }
+}
diff --git a/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/AudioSampleEntry.java b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/AudioSampleEntry.java
new file mode 100644
index 0000000..69aeb79
--- /dev/null
+++ b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/AudioSampleEntry.java
@@ -0,0 +1,278 @@
+/*
+ * Copyright 2008 CoreMedia AG, Hamburg
+ *
+ * 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.coremedia.iso.boxes.sampleentry;
+
+import com.coremedia.iso.BoxParser;
+import com.coremedia.iso.IsoTypeReader;
+import com.coremedia.iso.IsoTypeWriter;
+import com.coremedia.iso.boxes.Box;
+import com.coremedia.iso.boxes.ContainerBox;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Contains basic information about the audio samples in this track. Format-specific information
+ * is appened as boxes after the data described in ISO/IEC 14496-12 chapter 8.16.2.
+ */
+public class AudioSampleEntry extends SampleEntry implements ContainerBox {
+
+ public static final String TYPE1 = "samr";
+ public static final String TYPE2 = "sawb";
+ public static final String TYPE3 = "mp4a";
+ public static final String TYPE4 = "drms";
+ public static final String TYPE5 = "alac";
+ public static final String TYPE7 = "owma";
+ public static final String TYPE8 = "ac-3"; /* ETSI TS 102 366 1.2.1 Annex F */
+ public static final String TYPE9 = "ec-3"; /* ETSI TS 102 366 1.2.1 Annex F */
+ public static final String TYPE10 = "mlpa";
+ public static final String TYPE11 = "dtsl";
+ public static final String TYPE12 = "dtsh";
+ public static final String TYPE13 = "dtse";
+
+ /**
+ * Identifier for an encrypted audio track.
+ *
+ * @see com.coremedia.iso.boxes.ProtectionSchemeInformationBox
+ */
+ public static final String TYPE_ENCRYPTED = "enca";
+
+ private int channelCount;
+ private int sampleSize;
+ private long sampleRate;
+ private int soundVersion;
+ private int compressionId;
+ private int packetSize;
+ private long samplesPerPacket;
+ private long bytesPerPacket;
+ private long bytesPerFrame;
+ private long bytesPerSample;
+
+ private int reserved1;
+ private long reserved2;
+ private byte[] soundVersion2Data;
+ private BoxParser boxParser;
+
+ public AudioSampleEntry(String type) {
+ super(type);
+ }
+
+ public int getChannelCount() {
+ return channelCount;
+ }
+
+ public int getSampleSize() {
+ return sampleSize;
+ }
+
+ public long getSampleRate() {
+ return sampleRate;
+ }
+
+ public int getSoundVersion() {
+ return soundVersion;
+ }
+
+ public int getCompressionId() {
+ return compressionId;
+ }
+
+ public int getPacketSize() {
+ return packetSize;
+ }
+
+ public long getSamplesPerPacket() {
+ return samplesPerPacket;
+ }
+
+ public long getBytesPerPacket() {
+ return bytesPerPacket;
+ }
+
+ public long getBytesPerFrame() {
+ return bytesPerFrame;
+ }
+
+ public long getBytesPerSample() {
+ return bytesPerSample;
+ }
+
+ public byte[] getSoundVersion2Data() {
+ return soundVersion2Data;
+ }
+
+ public int getReserved1() {
+ return reserved1;
+ }
+
+ public long getReserved2() {
+ return reserved2;
+ }
+
+ public void setChannelCount(int channelCount) {
+ this.channelCount = channelCount;
+ }
+
+ public void setSampleSize(int sampleSize) {
+ this.sampleSize = sampleSize;
+ }
+
+ public void setSampleRate(long sampleRate) {
+ this.sampleRate = sampleRate;
+ }
+
+ public void setSoundVersion(int soundVersion) {
+ this.soundVersion = soundVersion;
+ }
+
+ public void setCompressionId(int compressionId) {
+ this.compressionId = compressionId;
+ }
+
+ public void setPacketSize(int packetSize) {
+ this.packetSize = packetSize;
+ }
+
+ public void setSamplesPerPacket(long samplesPerPacket) {
+ this.samplesPerPacket = samplesPerPacket;
+ }
+
+ public void setBytesPerPacket(long bytesPerPacket) {
+ this.bytesPerPacket = bytesPerPacket;
+ }
+
+ public void setBytesPerFrame(long bytesPerFrame) {
+ this.bytesPerFrame = bytesPerFrame;
+ }
+
+ public void setBytesPerSample(long bytesPerSample) {
+ this.bytesPerSample = bytesPerSample;
+ }
+
+ public void setReserved1(int reserved1) {
+ this.reserved1 = reserved1;
+ }
+
+ public void setReserved2(long reserved2) {
+ this.reserved2 = reserved2;
+ }
+
+ public void setSoundVersion2Data(byte[] soundVersion2Data) {
+ this.soundVersion2Data = soundVersion2Data;
+ }
+
+ public void setBoxParser(BoxParser boxParser) {
+ this.boxParser = boxParser;
+ }
+
+ @Override
+ public void _parseDetails(ByteBuffer content) {
+ _parseReservedAndDataReferenceIndex(content); //parses the six reserved bytes and dataReferenceIndex
+ // 8 bytes already parsed
+ //reserved bits - used by qt
+ soundVersion = IsoTypeReader.readUInt16(content);
+
+ //reserved
+ reserved1 = IsoTypeReader.readUInt16(content);
+ reserved2 = IsoTypeReader.readUInt32(content);
+
+ channelCount = IsoTypeReader.readUInt16(content);
+ sampleSize = IsoTypeReader.readUInt16(content);
+ //reserved bits - used by qt
+ compressionId = IsoTypeReader.readUInt16(content);
+ //reserved bits - used by qt
+ packetSize = IsoTypeReader.readUInt16(content);
+ //sampleRate = in.readFixedPoint1616();
+ sampleRate = IsoTypeReader.readUInt32(content);
+ if (!type.equals("mlpa")) {
+ sampleRate = sampleRate >>> 16;
+ }
+
+ //more qt stuff - see http://mp4v2.googlecode.com/svn-history/r388/trunk/src/atom_sound.cpp
+ if (soundVersion > 0) {
+ samplesPerPacket = IsoTypeReader.readUInt32(content);
+ bytesPerPacket = IsoTypeReader.readUInt32(content);
+ bytesPerFrame = IsoTypeReader.readUInt32(content);
+ bytesPerSample = IsoTypeReader.readUInt32(content);
+ }
+ if (soundVersion == 2) {
+
+ soundVersion2Data = new byte[20];
+ content.get(20);
+ }
+ _parseChildBoxes(content);
+
+ }
+
+
+ @Override
+ protected long getContentSize() {
+ long contentSize = 28;
+ contentSize += soundVersion > 0 ? 16 : 0;
+ contentSize += soundVersion == 2 ? 20 : 0;
+ for (Box boxe : boxes) {
+ contentSize += boxe.getSize();
+ }
+ return contentSize;
+ }
+
+ @Override
+ public String toString() {
+ return "AudioSampleEntry{" +
+ "bytesPerSample=" + bytesPerSample +
+ ", bytesPerFrame=" + bytesPerFrame +
+ ", bytesPerPacket=" + bytesPerPacket +
+ ", samplesPerPacket=" + samplesPerPacket +
+ ", packetSize=" + packetSize +
+ ", compressionId=" + compressionId +
+ ", soundVersion=" + soundVersion +
+ ", sampleRate=" + sampleRate +
+ ", sampleSize=" + sampleSize +
+ ", channelCount=" + channelCount +
+ ", boxes=" + getBoxes() +
+ '}';
+ }
+
+ @Override
+ protected void getContent(ByteBuffer byteBuffer) {
+ _writeReservedAndDataReferenceIndex(byteBuffer);
+ IsoTypeWriter.writeUInt16(byteBuffer, soundVersion);
+ IsoTypeWriter.writeUInt16(byteBuffer, reserved1);
+ IsoTypeWriter.writeUInt32(byteBuffer, reserved2);
+ IsoTypeWriter.writeUInt16(byteBuffer, channelCount);
+ IsoTypeWriter.writeUInt16(byteBuffer, sampleSize);
+ IsoTypeWriter.writeUInt16(byteBuffer, compressionId);
+ IsoTypeWriter.writeUInt16(byteBuffer, packetSize);
+ //isos.writeFixedPont1616(getSampleRate());
+ if (type.equals("mlpa")) {
+ IsoTypeWriter.writeUInt32(byteBuffer, getSampleRate());
+ } else {
+ IsoTypeWriter.writeUInt32(byteBuffer, getSampleRate() << 16);
+ }
+
+ if (soundVersion > 0) {
+ IsoTypeWriter.writeUInt32(byteBuffer, samplesPerPacket);
+ IsoTypeWriter.writeUInt32(byteBuffer, bytesPerPacket);
+ IsoTypeWriter.writeUInt32(byteBuffer, bytesPerFrame);
+ IsoTypeWriter.writeUInt32(byteBuffer, bytesPerSample);
+ }
+
+ if (soundVersion == 2) {
+ byteBuffer.put(soundVersion2Data);
+ }
+ _writeChildBoxes(byteBuffer);
+ }
+}
diff --git a/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/MpegSampleEntry.java b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/MpegSampleEntry.java
new file mode 100644
index 0000000..e4a33dc
--- /dev/null
+++ b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/MpegSampleEntry.java
@@ -0,0 +1,43 @@
+package com.coremedia.iso.boxes.sampleentry;
+
+import com.coremedia.iso.BoxParser;
+import com.coremedia.iso.boxes.Box;
+import com.coremedia.iso.boxes.ContainerBox;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+public class MpegSampleEntry extends SampleEntry implements ContainerBox {
+
+ private BoxParser boxParser;
+
+ public MpegSampleEntry(String type) {
+ super(type);
+ }
+
+ @Override
+ public void _parseDetails(ByteBuffer content) {
+ _parseReservedAndDataReferenceIndex(content);
+ _parseChildBoxes(content);
+
+ }
+
+ @Override
+ protected long getContentSize() {
+ long contentSize = 8;
+ for (Box boxe : boxes) {
+ contentSize += boxe.getSize();
+ }
+ return contentSize;
+ }
+
+ public String toString() {
+ return "MpegSampleEntry" + Arrays.asList(getBoxes());
+ }
+
+ @Override
+ protected void getContent(ByteBuffer byteBuffer) {
+ _writeReservedAndDataReferenceIndex(byteBuffer);
+ _writeChildBoxes(byteBuffer);
+ }
+}
diff --git a/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/Ovc1VisualSampleEntryImpl.java b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/Ovc1VisualSampleEntryImpl.java
new file mode 100644
index 0000000..56b8adb
--- /dev/null
+++ b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/Ovc1VisualSampleEntryImpl.java
@@ -0,0 +1,45 @@
+package com.coremedia.iso.boxes.sampleentry;
+
+import com.coremedia.iso.IsoTypeWriter;
+import com.coremedia.iso.boxes.Box;
+
+import java.nio.ByteBuffer;
+
+
+public class Ovc1VisualSampleEntryImpl extends SampleEntry {
+ private byte[] vc1Content;
+ public static final String TYPE = "ovc1";
+
+
+ @Override
+ protected long getContentSize() {
+ long size = 8;
+
+ for (Box box : boxes) {
+ size += box.getSize();
+ }
+ size += vc1Content.length;
+ return size;
+ }
+
+ @Override
+ public void _parseDetails(ByteBuffer content) {
+ _parseReservedAndDataReferenceIndex(content);
+ vc1Content = new byte[content.remaining()];
+ content.get(vc1Content);
+
+ }
+
+ @Override
+ protected void getContent(ByteBuffer byteBuffer) {
+ byteBuffer.put(new byte[6]);
+ IsoTypeWriter.writeUInt16(byteBuffer, getDataReferenceIndex());
+ byteBuffer.put(vc1Content);
+ }
+
+
+ protected Ovc1VisualSampleEntryImpl() {
+ super(TYPE);
+ }
+
+}
diff --git a/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/SampleEntry.java b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/SampleEntry.java
new file mode 100644
index 0000000..a1a5486
--- /dev/null
+++ b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/SampleEntry.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2008 CoreMedia AG, Hamburg
+ *
+ * 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.coremedia.iso.boxes.sampleentry;
+
+import com.coremedia.iso.BoxParser;
+import com.coremedia.iso.IsoTypeReader;
+import com.coremedia.iso.IsoTypeWriter;
+import com.googlecode.mp4parser.AbstractBox;
+import com.coremedia.iso.boxes.Box;
+import com.coremedia.iso.boxes.ContainerBox;
+import com.googlecode.mp4parser.util.ByteBufferByteChannel;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.channels.WritableByteChannel;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Abstract base class for all sample entries.
+ *
+ * @see com.coremedia.iso.boxes.sampleentry.AudioSampleEntry
+ * @see com.coremedia.iso.boxes.sampleentry.VisualSampleEntry
+ * @see com.coremedia.iso.boxes.sampleentry.TextSampleEntry
+ */
+public abstract class SampleEntry extends AbstractBox implements ContainerBox {
+
+
+ private int dataReferenceIndex = 1;
+ protected List<Box> boxes = new LinkedList<Box>();
+ private BoxParser boxParser;
+
+
+ protected SampleEntry(String type) {
+ super(type);
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public int getDataReferenceIndex() {
+ return dataReferenceIndex;
+ }
+
+ public void setDataReferenceIndex(int dataReferenceIndex) {
+ this.dataReferenceIndex = dataReferenceIndex;
+ }
+
+ public void setBoxes(List<Box> boxes) {
+ this.boxes = new LinkedList<Box>(boxes);
+ }
+
+ public void addBox(Box b) {
+ b.setParent(this);
+ boxes.add(b);
+ }
+
+ public boolean removeBox(Box b) {
+ b.setParent(this);
+ return boxes.remove(b);
+ }
+
+ public List<Box> getBoxes() {
+ return boxes;
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T extends Box> List<T> getBoxes(Class<T> clazz, boolean recursive) {
+ List<T> boxesToBeReturned = new ArrayList<T>(2);
+ for (Box boxe : boxes) { //clazz.isInstance(boxe) / clazz == boxe.getClass()?
+ if (clazz == boxe.getClass()) {
+ boxesToBeReturned.add((T) boxe);
+ }
+
+ if (recursive && boxe instanceof ContainerBox) {
+ boxesToBeReturned.addAll(((ContainerBox) boxe).getBoxes(clazz, recursive));
+ }
+ }
+ // Optimize here! Spare object creation work on arrays directly! System.arrayCopy
+ return boxesToBeReturned;
+ //return (T[]) boxesToBeReturned.toArray();
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T extends Box> List<T> getBoxes(Class<T> clazz) {
+ return getBoxes(clazz, false);
+ }
+
+ @Override
+ public void parse(ReadableByteChannel readableByteChannel, ByteBuffer header, long contentSize, BoxParser boxParser) throws IOException {
+ super.parse(readableByteChannel, header, contentSize, boxParser);
+ this.boxParser = boxParser;
+ }
+
+
+ public void _parseReservedAndDataReferenceIndex(ByteBuffer content) {
+ content.get(new byte[6]); // ignore 6 reserved bytes;
+ dataReferenceIndex = IsoTypeReader.readUInt16(content);
+ }
+
+ public void _parseChildBoxes(ByteBuffer content) {
+ while (content.remaining() > 8) {
+ try {
+ boxes.add(boxParser.parseBox(new ByteBufferByteChannel(content), this));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+ setDeadBytes(content.slice());
+ }
+
+ public void _writeReservedAndDataReferenceIndex(ByteBuffer bb) {
+ bb.put(new byte[6]);
+ IsoTypeWriter.writeUInt16(bb, dataReferenceIndex);
+ }
+
+ public void _writeChildBoxes(ByteBuffer bb) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ WritableByteChannel wbc = Channels.newChannel(baos);
+ try {
+ for (Box box : boxes) {
+ box.getBox(wbc);
+ }
+ wbc.close();
+ } catch (IOException e) {
+ throw new RuntimeException("Cannot happen. Everything should be in memory and therefore no exceptions.");
+ }
+ bb.put(baos.toByteArray());
+ }
+
+ public long getNumOfBytesToFirstChild() {
+ long sizeOfChildren = 0;
+ for (Box box : boxes) {
+ sizeOfChildren += box.getSize();
+ }
+ return getSize() - sizeOfChildren;
+ }
+
+}
diff --git a/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/SubtitleSampleEntry.java b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/SubtitleSampleEntry.java
new file mode 100644
index 0000000..21d0cc4
--- /dev/null
+++ b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/SubtitleSampleEntry.java
@@ -0,0 +1,76 @@
+package com.coremedia.iso.boxes.sampleentry;
+
+import com.coremedia.iso.IsoTypeReader;
+import com.coremedia.iso.IsoTypeWriter;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: magnus
+ * Date: 2012-03-08
+ * Time: 11:36
+ * To change this template use File | Settings | File Templates.
+ */
+public class SubtitleSampleEntry extends SampleEntry {
+
+ public static final String TYPE1 = "stpp";
+
+ public static final String TYPE_ENCRYPTED = ""; // This is not known!
+
+ private String namespace;
+ private String schemaLocation;
+ private String imageMimeType;
+
+ public SubtitleSampleEntry(String type) {
+ super(type);
+ }
+
+ @Override
+ protected long getContentSize() {
+ long contentSize = 8 + namespace.length() + schemaLocation.length() + imageMimeType.length() + 3;
+ return contentSize;
+ }
+
+ @Override
+ public void _parseDetails(ByteBuffer content) {
+ _parseReservedAndDataReferenceIndex(content);
+ namespace = IsoTypeReader.readString(content);
+ schemaLocation = IsoTypeReader.readString(content);
+ imageMimeType = IsoTypeReader.readString(content);
+ _parseChildBoxes(content);
+ }
+
+ @Override
+ protected void getContent(ByteBuffer byteBuffer) {
+ _writeReservedAndDataReferenceIndex(byteBuffer);
+ IsoTypeWriter.writeUtf8String(byteBuffer, namespace);
+ IsoTypeWriter.writeUtf8String(byteBuffer, schemaLocation);
+ IsoTypeWriter.writeUtf8String(byteBuffer, imageMimeType);
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public void setNamespace(String namespace) {
+ this.namespace = namespace;
+ }
+
+ public String getSchemaLocation() {
+ return schemaLocation;
+ }
+
+ public void setSchemaLocation(String schemaLocation) {
+ this.schemaLocation = schemaLocation;
+ }
+
+ public String getImageMimeType() {
+ return imageMimeType;
+ }
+
+ public void setImageMimeType(String imageMimeType) {
+ this.imageMimeType = imageMimeType;
+ }
+}
+
diff --git a/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/TextSampleEntry.java b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/TextSampleEntry.java
new file mode 100644
index 0000000..3a0b83a
--- /dev/null
+++ b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/TextSampleEntry.java
@@ -0,0 +1,305 @@
+/*
+ * Copyright 2008 CoreMedia AG, Hamburg
+ *
+ * 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.coremedia.iso.boxes.sampleentry;
+
+import com.coremedia.iso.IsoTypeReader;
+import com.coremedia.iso.IsoTypeWriter;
+import com.coremedia.iso.boxes.Box;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * Entry type for timed text samples defined in the timed text specification (ISO/IEC 14496-17).
+ */
+public class TextSampleEntry extends SampleEntry {
+
+ public static final String TYPE1 = "tx3g";
+
+ public static final String TYPE_ENCRYPTED = "enct";
+
+/* class TextSampleEntry() extends SampleEntry ('tx3g') {
+ unsigned int(32) displayFlags;
+ signed int(8) horizontal-justification;
+ signed int(8) vertical-justification;
+ unsigned int(8) background-color-rgba[4];
+ BoxRecord default-text-box;
+ StyleRecord default-style;
+ FontTableBox font-table;
+ }
+ */
+
+ private long displayFlags; // 32 bits
+ private int horizontalJustification; // 8 bit
+ private int verticalJustification; // 8 bit
+ private int[] backgroundColorRgba = new int[4]; // 4 bytes
+ private BoxRecord boxRecord = new BoxRecord();
+ private StyleRecord styleRecord = new StyleRecord();
+
+ public TextSampleEntry(String type) {
+ super(type);
+ }
+
+ @Override
+ public void _parseDetails(ByteBuffer content) {
+ _parseReservedAndDataReferenceIndex(content);
+ displayFlags = IsoTypeReader.readUInt32(content);
+ horizontalJustification = IsoTypeReader.readUInt8(content);
+ verticalJustification = IsoTypeReader.readUInt8(content);
+ backgroundColorRgba = new int[4];
+ backgroundColorRgba[0] = IsoTypeReader.readUInt8(content);
+ backgroundColorRgba[1] = IsoTypeReader.readUInt8(content);
+ backgroundColorRgba[2] = IsoTypeReader.readUInt8(content);
+ backgroundColorRgba[3] = IsoTypeReader.readUInt8(content);
+ boxRecord = new BoxRecord();
+ boxRecord.parse(content);
+
+ styleRecord = new StyleRecord();
+ styleRecord.parse(content);
+ _parseChildBoxes(content);
+ }
+
+
+ protected long getContentSize() {
+ long contentSize = 18;
+ contentSize += boxRecord.getSize();
+ contentSize += styleRecord.getSize();
+ for (Box boxe : boxes) {
+ contentSize += boxe.getSize();
+ }
+ return contentSize;
+ }
+
+ public String toString() {
+ return "TextSampleEntry";
+ }
+
+ @Override
+ protected void getContent(ByteBuffer byteBuffer) {
+ _writeReservedAndDataReferenceIndex(byteBuffer);
+ IsoTypeWriter.writeUInt32(byteBuffer, displayFlags);
+ IsoTypeWriter.writeUInt8(byteBuffer, horizontalJustification);
+ IsoTypeWriter.writeUInt8(byteBuffer, verticalJustification);
+ IsoTypeWriter.writeUInt8(byteBuffer, backgroundColorRgba[0]);
+ IsoTypeWriter.writeUInt8(byteBuffer, backgroundColorRgba[1]);
+ IsoTypeWriter.writeUInt8(byteBuffer, backgroundColorRgba[2]);
+ IsoTypeWriter.writeUInt8(byteBuffer, backgroundColorRgba[3]);
+ boxRecord.getContent(byteBuffer);
+ styleRecord.getContent(byteBuffer);
+
+ _writeChildBoxes(byteBuffer);
+ }
+
+ public BoxRecord getBoxRecord() {
+ return boxRecord;
+ }
+
+ public void setBoxRecord(BoxRecord boxRecord) {
+ this.boxRecord = boxRecord;
+ }
+
+ public StyleRecord getStyleRecord() {
+ return styleRecord;
+ }
+
+ public void setStyleRecord(StyleRecord styleRecord) {
+ this.styleRecord = styleRecord;
+ }
+
+ public boolean isScrollIn() {
+ return (displayFlags & 0x00000020) == 0x00000020;
+ }
+
+ public void setScrollIn(boolean scrollIn) {
+ if (scrollIn) {
+ displayFlags |= 0x00000020;
+ } else {
+ displayFlags &= ~0x00000020;
+ }
+ }
+
+ public boolean isScrollOut() {
+ return (displayFlags & 0x00000040) == 0x00000040;
+ }
+
+ public void setScrollOut(boolean scrollOutIn) {
+ if (scrollOutIn) {
+ displayFlags |= 0x00000040;
+ } else {
+ displayFlags &= ~0x00000040;
+ }
+ }
+
+ public boolean isScrollDirection() {
+ return (displayFlags & 0x00000180) == 0x00000180;
+ }
+
+ public void setScrollDirection(boolean scrollOutIn) {
+ if (scrollOutIn) {
+ displayFlags |= 0x00000180;
+ } else {
+ displayFlags &= ~0x00000180;
+ }
+ }
+
+ public boolean isContinuousKaraoke() {
+ return (displayFlags & 0x00000800) == 0x00000800;
+ }
+
+ public void setContinuousKaraoke(boolean continuousKaraoke) {
+ if (continuousKaraoke) {
+ displayFlags |= 0x00000800;
+ } else {
+ displayFlags &= ~0x00000800;
+ }
+ }
+
+ public boolean isWriteTextVertically() {
+ return (displayFlags & 0x00020000) == 0x00020000;
+ }
+
+ public void setWriteTextVertically(boolean writeTextVertically) {
+ if (writeTextVertically) {
+ displayFlags |= 0x00020000;
+ } else {
+ displayFlags &= ~0x00020000;
+ }
+ }
+
+
+ public boolean isFillTextRegion() {
+ return (displayFlags & 0x00040000) == 0x00040000;
+ }
+
+ public void setFillTextRegion(boolean fillTextRegion) {
+ if (fillTextRegion) {
+ displayFlags |= 0x00040000;
+ } else {
+ displayFlags &= ~0x00040000;
+ }
+ }
+
+
+ public int getHorizontalJustification() {
+ return horizontalJustification;
+ }
+
+ public void setHorizontalJustification(int horizontalJustification) {
+ this.horizontalJustification = horizontalJustification;
+ }
+
+ public int getVerticalJustification() {
+ return verticalJustification;
+ }
+
+ public void setVerticalJustification(int verticalJustification) {
+ this.verticalJustification = verticalJustification;
+ }
+
+ public int[] getBackgroundColorRgba() {
+ return backgroundColorRgba;
+ }
+
+ public void setBackgroundColorRgba(int[] backgroundColorRgba) {
+ this.backgroundColorRgba = backgroundColorRgba;
+ }
+
+ public static class BoxRecord {
+ int top;
+ int left;
+ int bottom;
+ int right;
+
+ public void parse(ByteBuffer in) {
+ top = IsoTypeReader.readUInt16(in);
+ left = IsoTypeReader.readUInt16(in);
+ bottom = IsoTypeReader.readUInt16(in);
+ right = IsoTypeReader.readUInt16(in);
+ }
+
+ public void getContent(ByteBuffer bb) {
+ IsoTypeWriter.writeUInt16(bb, top);
+ IsoTypeWriter.writeUInt16(bb, left);
+ IsoTypeWriter.writeUInt16(bb, bottom);
+ IsoTypeWriter.writeUInt16(bb, right);
+ }
+
+ public int getSize() {
+ return 8;
+ }
+ }
+
+ /*
+ class FontRecord {
+ unsigned int(16) font-ID;
+ unsigned int(8) font-name-length;
+ unsigned int(8) font[font-name-length];
+}
+ */
+
+
+ /*
+ aligned(8) class StyleRecord {
+ unsigned int(16) startChar;
+ unsigned int(16) endChar;
+ unsigned int(16) font-ID;
+ unsigned int(8) face-style-flags;
+ unsigned int(8) font-size;
+ unsigned int(8) text-color-rgba[4];
+}
+ */
+ public static class StyleRecord {
+ int startChar;
+ int endChar;
+ int fontId;
+ int faceStyleFlags;
+ int fontSize;
+ int[] textColor = new int[]{0xff, 0xff, 0xff, 0xff};
+
+ public void parse(ByteBuffer in) {
+ startChar = IsoTypeReader.readUInt16(in);
+ endChar = IsoTypeReader.readUInt16(in);
+ fontId = IsoTypeReader.readUInt16(in);
+ faceStyleFlags = IsoTypeReader.readUInt8(in);
+ fontSize = IsoTypeReader.readUInt8(in);
+ textColor = new int[4];
+ textColor[0] = IsoTypeReader.readUInt8(in);
+ textColor[1] = IsoTypeReader.readUInt8(in);
+ textColor[2] = IsoTypeReader.readUInt8(in);
+ textColor[3] = IsoTypeReader.readUInt8(in);
+ }
+
+
+ public void getContent(ByteBuffer bb) {
+ IsoTypeWriter.writeUInt16(bb, startChar);
+ IsoTypeWriter.writeUInt16(bb, endChar);
+ IsoTypeWriter.writeUInt16(bb, fontId);
+ IsoTypeWriter.writeUInt8(bb, faceStyleFlags);
+ IsoTypeWriter.writeUInt8(bb, fontSize);
+ IsoTypeWriter.writeUInt8(bb, textColor[0]);
+ IsoTypeWriter.writeUInt8(bb, textColor[1]);
+ IsoTypeWriter.writeUInt8(bb, textColor[2]);
+ IsoTypeWriter.writeUInt8(bb, textColor[3]);
+ }
+
+ public int getSize() {
+ return 12;
+ }
+ }
+
+
+}
diff --git a/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/VisualSampleEntry.java b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/VisualSampleEntry.java
new file mode 100644
index 0000000..407e79f
--- /dev/null
+++ b/isoparser/src/main/java/com/coremedia/iso/boxes/sampleentry/VisualSampleEntry.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright 2008 CoreMedia AG, Hamburg
+ *
+ * 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.coremedia.iso.boxes.sampleentry;
+
+import com.coremedia.iso.IsoTypeReader;
+import com.coremedia.iso.IsoTypeWriter;
+import com.coremedia.iso.Utf8;
+import com.coremedia.iso.boxes.Box;
+import com.coremedia.iso.boxes.ContainerBox;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Contains information common to all visual tracks.
+ * <code>
+ * <pre>
+ * class VisualSampleEntry(codingname) extends SampleEntry (codingname){
+ * unsigned int(16) pre_defined = 0;
+ * const unsigned int(16) reserved = 0;
+ * unsigned int(32)[3] pre_defined = 0;
+ * unsigned int(16) width;
+ * unsigned int(16) height;
+ * template unsigned int(32) horizresolution = 0x00480000; // 72 dpi
+ * template unsigned int(32) vertresolution = 0x00480000; // 72 dpi
+ * const unsigned int(32) reserved = 0;
+ * template unsigned int(16) frame_count = 1;
+ * string[32] compressorname;
+ * template unsigned int(16) depth = 0x0018;
+ * int(16) pre_defined = -1;
+ * }<br>
+ * </pre>
+ * </code>
+ * <p/>
+ * Format-specific informationis appened as boxes after the data described in ISO/IEC 14496-12 chapter 8.16.2.
+ */
+public class VisualSampleEntry extends SampleEntry implements ContainerBox {
+ public static final String TYPE1 = "mp4v";
+ public static final String TYPE2 = "s263";
+ public static final String TYPE3 = "avc1";
+
+
+ /**
+ * Identifier for an encrypted video track.
+ *
+ * @see com.coremedia.iso.boxes.ProtectionSchemeInformationBox
+ */
+ public static final String TYPE_ENCRYPTED = "encv";
+
+
+ private int width;
+ private int height;
+ private double horizresolution = 72;
+ private double vertresolution = 72;
+ private int frameCount = 1;
+ private String compressorname;
+ private int depth = 24;
+
+ private long[] predefined = new long[3];
+
+ public VisualSampleEntry(String type) {
+ super(type);
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ public double getHorizresolution() {
+ return horizresolution;
+ }
+
+ public double getVertresolution() {
+ return vertresolution;
+ }
+
+ public int getFrameCount() {
+ return frameCount;
+ }
+
+ public String getCompressorname() {
+ return compressorname;
+ }
+
+ public int getDepth() {
+ return depth;
+ }
+
+ public void setCompressorname(String compressorname) {
+ this.compressorname = compressorname;
+ }
+
+ public void setWidth(int width) {
+ this.width = width;
+ }
+
+ public void setHeight(int height) {
+ this.height = height;
+ }
+
+ public void setHorizresolution(double horizresolution) {
+ this.horizresolution = horizresolution;
+ }
+
+ public void setVertresolution(double vertresolution) {
+ this.vertresolution = vertresolution;
+ }
+
+ public void setFrameCount(int frameCount) {
+ this.frameCount = frameCount;
+ }
+
+ public void setDepth(int depth) {
+ this.depth = depth;
+ }
+
+ @Override
+ public void _parseDetails(ByteBuffer content) {
+ _parseReservedAndDataReferenceIndex(content);
+ long tmp = IsoTypeReader.readUInt16(content);
+ assert 0 == tmp : "reserved byte not 0";
+ tmp = IsoTypeReader.readUInt16(content);
+ assert 0 == tmp : "reserved byte not 0";
+ predefined[0] = IsoTypeReader.readUInt32(content); // should be zero
+ predefined[1] = IsoTypeReader.readUInt32(content); // should be zero
+ predefined[2] = IsoTypeReader.readUInt32(content); // should be zero
+ width = IsoTypeReader.readUInt16(content);
+ height = IsoTypeReader.readUInt16(content);
+ horizresolution = IsoTypeReader.readFixedPoint1616(content);
+ vertresolution = IsoTypeReader.readFixedPoint1616(content);
+ tmp = IsoTypeReader.readUInt32(content);
+ assert 0 == tmp : "reserved byte not 0";
+ frameCount = IsoTypeReader.readUInt16(content);
+ int compressornameDisplayAbleData = IsoTypeReader.readUInt8(content);
+ if (compressornameDisplayAbleData > 31) {
+ System.out.println("invalid compressor name displayable data: " + compressornameDisplayAbleData);
+ compressornameDisplayAbleData = 31;
+ }
+ byte[] bytes = new byte[compressornameDisplayAbleData];
+ content.get(bytes);
+ compressorname = Utf8.convert(bytes);
+ if (compressornameDisplayAbleData < 31) {
+ byte[] zeros = new byte[31 - compressornameDisplayAbleData];
+ content.get(zeros);
+ //assert Arrays.equals(zeros, new byte[zeros.length]) : "The compressor name length was not filled up with zeros";
+ }
+ depth = IsoTypeReader.readUInt16(content);
+ tmp = IsoTypeReader.readUInt16(content);
+ assert 0xFFFF == tmp;
+
+ _parseChildBoxes(content);
+
+ }
+
+
+ protected long getContentSize() {
+ long contentSize = 78;
+ for (Box boxe : boxes) {
+ contentSize += boxe.getSize();
+ }
+ return contentSize;
+ }
+
+ @Override
+ protected void getContent(ByteBuffer byteBuffer) {
+ _writeReservedAndDataReferenceIndex(byteBuffer);
+ IsoTypeWriter.writeUInt16(byteBuffer, 0);
+ IsoTypeWriter.writeUInt16(byteBuffer, 0);
+ IsoTypeWriter.writeUInt32(byteBuffer, predefined[0]);
+ IsoTypeWriter.writeUInt32(byteBuffer, predefined[1]);
+ IsoTypeWriter.writeUInt32(byteBuffer, predefined[2]);
+
+ IsoTypeWriter.writeUInt16(byteBuffer, getWidth());
+ IsoTypeWriter.writeUInt16(byteBuffer, getHeight());
+
+ IsoTypeWriter.writeFixedPont1616(byteBuffer, getHorizresolution());
+ IsoTypeWriter.writeFixedPont1616(byteBuffer, getVertresolution());
+
+
+ IsoTypeWriter.writeUInt32(byteBuffer, 0);
+ IsoTypeWriter.writeUInt16(byteBuffer, getFrameCount());
+ IsoTypeWriter.writeUInt8(byteBuffer, Utf8.utf8StringLengthInBytes(getCompressorname()));
+ byteBuffer.put(Utf8.convert(getCompressorname()));
+ int a = Utf8.utf8StringLengthInBytes(getCompressorname());
+ while (a < 31) {
+ a++;
+ byteBuffer.put((byte) 0);
+ }
+ IsoTypeWriter.writeUInt16(byteBuffer, getDepth());
+ IsoTypeWriter.writeUInt16(byteBuffer, 0xFFFF);
+
+ _writeChildBoxes(byteBuffer);
+
+ }
+
+}