constructorObject;
try {
if (param.length > 0) {
constructorObject = clazz.getConstructor(constructorArgsClazz);
} else {
constructorObject = clazz.getConstructor();
}
return constructorObject.newInstance(constructorArgs);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
private class FourCcToBox {
private String type;
private byte[] userType;
private String parent;
private String clazzName;
private String[] param;
public FourCcToBox(String type, byte[] userType, String parent) {
this.type = type;
this.parent = parent;
this.userType = userType;
}
public String getClazzName() {
return clazzName;
}
public String[] getParam() {
return param;
}
public FourCcToBox invoke() {
String constructor;
if (userType != null) {
if (!"uuid".equals((type))) {
throw new RuntimeException("we have a userType but no uuid box type. Something's wrong");
}
constructor = mapping.getProperty((parent) + "-uuid[" + Hex.encodeHex(userType).toUpperCase() + "]");
if (constructor == null) {
constructor = mapping.getProperty("uuid[" + Hex.encodeHex(userType).toUpperCase() + "]");
}
if (constructor == null) {
constructor = mapping.getProperty("uuid");
}
} else {
constructor = mapping.getProperty((parent) + "-" + (type));
if (constructor == null) {
constructor = mapping.getProperty((type));
}
}
if (constructor == null) {
constructor = mapping.getProperty("default");
}
if (constructor == null) {
throw new RuntimeException("No box object found for " + type);
}
Matcher m = p.matcher(constructor);
boolean matches = m.matches();
if (!matches) {
throw new RuntimeException("Cannot work with that constructor: " + constructor);
}
clazzName = m.group(1);
param = m.group(2).split(",");
return this;
}
}
}
================================================
FILE: src/com/coremedia/iso/Utf8.java
================================================
/*
* Copyright 2012 Sebastian Annies, 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;
import java.io.UnsupportedEncodingException;
/**
* Converts byte[] -> String and vice versa.
*/
public final class Utf8 {
public static byte[] convert(String s) {
try {
if (s != null) {
return s.getBytes("UTF-8");
} else {
return null;
}
} catch (UnsupportedEncodingException e) {
throw new Error(e);
}
}
public static String convert(byte[] b) {
try {
if (b != null) {
return new String(b, "UTF-8");
} else {
return null;
}
} catch (UnsupportedEncodingException e) {
throw new Error(e);
}
}
public static int utf8StringLengthInBytes(String utf8) {
try {
if (utf8 != null) {
return utf8.getBytes("UTF-8").length;
} else {
return 0;
}
} catch (UnsupportedEncodingException e) {
throw new RuntimeException();
}
}
}
================================================
FILE: src/com/coremedia/iso/boxes/AbstractMediaHeaderBox.java
================================================
/*
* Copyright 2011 Sebastian Annies, Hamburg, Germany
*
* 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;
import com.googlecode.mp4parser.AbstractFullBox;
/**
* A common superclass for all MediaInformationHeaderBoxes. E.g.
* VideoMediaHeaderBox, SoundMediaHeaderBox & HintMediaHeaderBox
*/
public abstract class AbstractMediaHeaderBox extends AbstractFullBox {
protected AbstractMediaHeaderBox(String type) {
super(type);
}
}
================================================
FILE: src/com/coremedia/iso/boxes/AlbumBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.coremedia.iso.Utf8;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
/**
* Meta information in a 'udta' box about a track.
* Defined in 3GPP 26.244.
*
* @see com.coremedia.iso.boxes.UserDataBox
*/
public class AlbumBox extends AbstractFullBox {
public static final String TYPE = "albm";
private String language;
private String albumTitle;
private int trackNumber;
public AlbumBox() {
super(TYPE);
}
/**
* Declares the language code for the {@link #getAlbumTitle()} return value. See ISO 639-2/T for the set of three
* character codes.Each character is packed as the difference between its ASCII value and 0x60. The code is
* confined to being three lower-case letters, so these values are strictly positive.
*
* @return the language code
*/
public String getLanguage() {
return language;
}
public String getAlbumTitle() {
return albumTitle;
}
public int getTrackNumber() {
return trackNumber;
}
public void setLanguage(String language) {
this.language = language;
}
public void setAlbumTitle(String albumTitle) {
this.albumTitle = albumTitle;
}
public void setTrackNumber(int trackNumber) {
this.trackNumber = trackNumber;
}
protected long getContentSize() {
return 6 + Utf8.utf8StringLengthInBytes(albumTitle) + 1 + (trackNumber == -1 ? 0 : 1);
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
language = IsoTypeReader.readIso639(content);
albumTitle = IsoTypeReader.readString(content);
if (content.remaining() > 0) {
trackNumber = IsoTypeReader.readUInt8(content);
} else {
trackNumber = -1;
}
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeIso639(byteBuffer, language);
byteBuffer.put(Utf8.convert(albumTitle));
byteBuffer.put((byte) 0);
if (trackNumber != -1) {
IsoTypeWriter.writeUInt8(byteBuffer, trackNumber);
}
}
public String toString() {
StringBuilder buffer = new StringBuilder();
buffer.append("AlbumBox[language=").append(getLanguage()).append(";");
buffer.append("albumTitle=").append(getAlbumTitle());
if (trackNumber >= 0) {
buffer.append(";trackNumber=").append(getTrackNumber());
}
buffer.append("]");
return buffer.toString();
}
}
================================================
FILE: src/com/coremedia/iso/boxes/AuthorBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.coremedia.iso.Utf8;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
/**
* Meta information in a 'udta' box about a track.
* Defined in 3GPP 26.244.
*
* @see com.coremedia.iso.boxes.UserDataBox
*/
public class AuthorBox extends AbstractFullBox {
public static final String TYPE = "auth";
private String language;
private String author;
public AuthorBox() {
super(TYPE);
}
/**
* Declares the language code for the {@link #getAuthor()} return value. See ISO 639-2/T for the set of three
* character codes.Each character is packed as the difference between its ASCII value and 0x60. The code is
* confined to being three lower-case letters, so these values are strictly positive.
*
* @return the language code
*/
public String getLanguage() {
return language;
}
/**
* Author information.
*
* @return the author
*/
public String getAuthor() {
return author;
}
public void setLanguage(String language) {
this.language = language;
}
public void setAuthor(String author) {
this.author = author;
}
protected long getContentSize() {
return 7 + Utf8.utf8StringLengthInBytes(author);
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
language = IsoTypeReader.readIso639(content);
author = IsoTypeReader.readString(content);
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeIso639(byteBuffer, language);
byteBuffer.put(Utf8.convert(author));
byteBuffer.put((byte) 0);
}
public String toString() {
return "AuthorBox[language=" + getLanguage() + ";author=" + getAuthor() + "]";
}
}
================================================
FILE: src/com/coremedia/iso/boxes/BitRateBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.googlecode.mp4parser.AbstractBox;
import java.nio.ByteBuffer;
/**
* class BitRateBox extends Box('btrt') {
* unsigned int(32) bufferSizeDB;
* // gives the size of the decoding buffer for
* // the elementary stream in bytes.
* unsigned int(32) maxBitrate;
* // gives the maximum rate in bits/second
* // over any window of one second.
* unsigned int(32) avgBitrate;
* // avgBitrate gives the average rate in
* // bits/second over the entire presentation.
* }
*/
public final class BitRateBox extends AbstractBox {
public static final String TYPE = "btrt";
private long bufferSizeDb;
private long maxBitrate;
private long avgBitrate;
public BitRateBox() {
super(TYPE);
}
protected long getContentSize() {
return 12;
}
@Override
public void _parseDetails(ByteBuffer content) {
bufferSizeDb = IsoTypeReader.readUInt32(content);
maxBitrate = IsoTypeReader.readUInt32(content);
avgBitrate = IsoTypeReader.readUInt32(content);
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
IsoTypeWriter.writeUInt32(byteBuffer, bufferSizeDb);
IsoTypeWriter.writeUInt32(byteBuffer, maxBitrate);
IsoTypeWriter.writeUInt32(byteBuffer, avgBitrate);
}
public long getBufferSizeDb() {
return bufferSizeDb;
}
public void setBufferSizeDb(long bufferSizeDb) {
this.bufferSizeDb = bufferSizeDb;
}
public long getMaxBitrate() {
return maxBitrate;
}
public void setMaxBitrate(long maxBitrate) {
this.maxBitrate = maxBitrate;
}
public long getAvgBitrate() {
return avgBitrate;
}
public void setAvgBitrate(long avgBitrate) {
this.avgBitrate = avgBitrate;
}
}
================================================
FILE: src/com/coremedia/iso/boxes/Box.java
================================================
/*
* 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;
import com.coremedia.iso.BoxParser;
import com.coremedia.iso.boxes.ContainerBox;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
/**
* Defines basic interaction possibilities for any ISO box. Each box has a parent box and a type.
*/
public interface Box {
ContainerBox getParent();
void setParent(ContainerBox parent);
long getSize();
/**
* The box's 4-cc type.
* @return the 4 character type of the box
*/
String getType();
/**
* Writes the complete box - size | 4-cc | content - to the given writableByteChannel.
* @param writableByteChannel the box's sink
* @throws IOException in case of problems with the Channel
*/
void getBox(WritableByteChannel writableByteChannel) throws IOException;
void parse(ReadableByteChannel readableByteChannel, ByteBuffer header, long contentSize, BoxParser boxParser) throws IOException;
}
================================================
FILE: src/com/coremedia/iso/boxes/ChunkOffset64BitBox.java
================================================
package com.coremedia.iso.boxes;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import java.nio.ByteBuffer;
import static com.googlecode.mp4parser.util.CastUtils.l2i;
/**
* Abstract Chunk Offset Box
*/
public class ChunkOffset64BitBox extends ChunkOffsetBox {
public static final String TYPE = "co64";
private long[] chunkOffsets;
public ChunkOffset64BitBox() {
super(TYPE);
}
@Override
public long[] getChunkOffsets() {
return chunkOffsets;
}
@Override
protected long getContentSize() {
return 8 + 8 * chunkOffsets.length;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
int entryCount = l2i(IsoTypeReader.readUInt32(content));
chunkOffsets = new long[entryCount];
for (int i = 0; i < entryCount; i++) {
chunkOffsets[i] = IsoTypeReader.readUInt64(content);
}
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeUInt32(byteBuffer, chunkOffsets.length);
for (long chunkOffset : chunkOffsets) {
IsoTypeWriter.writeUInt64(byteBuffer, chunkOffset);
}
}
}
================================================
FILE: src/com/coremedia/iso/boxes/ChunkOffsetBox.java
================================================
package com.coremedia.iso.boxes;
import com.googlecode.mp4parser.AbstractFullBox;
/**
* Abstract Chunk Offset Box
*/
public abstract class ChunkOffsetBox extends AbstractFullBox {
public ChunkOffsetBox(String type) {
super(type);
}
public abstract long[] getChunkOffsets();
public String toString() {
return this.getClass().getSimpleName() + "[entryCount=" + getChunkOffsets().length + "]";
}
}
================================================
FILE: src/com/coremedia/iso/boxes/ClassificationBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoFile;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.coremedia.iso.Utf8;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
/**
* Classification of the media according to 3GPP 26.244.
*/
public class ClassificationBox extends AbstractFullBox {
public static final String TYPE = "clsf";
private String classificationEntity;
private int classificationTableIndex;
private String language;
private String classificationInfo;
public ClassificationBox() {
super(TYPE);
}
public String getLanguage() {
return language;
}
public String getClassificationEntity() {
return classificationEntity;
}
public int getClassificationTableIndex() {
return classificationTableIndex;
}
public String getClassificationInfo() {
return classificationInfo;
}
public void setClassificationEntity(String classificationEntity) {
this.classificationEntity = classificationEntity;
}
public void setClassificationTableIndex(int classificationTableIndex) {
this.classificationTableIndex = classificationTableIndex;
}
public void setLanguage(String language) {
this.language = language;
}
public void setClassificationInfo(String classificationInfo) {
this.classificationInfo = classificationInfo;
}
protected long getContentSize() {
return 4 + 2 + 2 + Utf8.utf8StringLengthInBytes(classificationInfo) + 1;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
byte[] cE = new byte[4];
content.get(cE);
classificationEntity = IsoFile.bytesToFourCC(cE);
classificationTableIndex = IsoTypeReader.readUInt16(content);
language = IsoTypeReader.readIso639(content);
classificationInfo = IsoTypeReader.readString(content);
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
byteBuffer.put(IsoFile.fourCCtoBytes(classificationEntity));
IsoTypeWriter.writeUInt16(byteBuffer, classificationTableIndex);
IsoTypeWriter.writeIso639(byteBuffer, language);
byteBuffer.put(Utf8.convert(classificationInfo));
byteBuffer.put((byte) 0);
}
public String toString() {
StringBuilder buffer = new StringBuilder();
buffer.append("ClassificationBox[language=").append(getLanguage());
buffer.append("classificationEntity=").append(getClassificationEntity());
buffer.append(";classificationTableIndex=").append(getClassificationTableIndex());
buffer.append(";language=").append(getLanguage());
buffer.append(";classificationInfo=").append(getClassificationInfo());
buffer.append("]");
return buffer.toString();
}
}
================================================
FILE: src/com/coremedia/iso/boxes/CompositionShiftLeastGreatestAtom.java
================================================
package com.coremedia.iso.boxes;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
/**
* The optional composition shift least greatest atom summarizes the calculated
* minimum and maximum offsets between decode and composition time, as well as
* the start and end times, for all samples. This allows a reader to determine
* the minimum required time for decode to obtain proper presentation order without
* needing to scan the sample table for the range of offsets. The type of the
* composition shift least greatest atom is ‘cslg’.
*/
public class CompositionShiftLeastGreatestAtom extends AbstractFullBox {
public CompositionShiftLeastGreatestAtom() {
super("cslg");
}
// A 32-bit unsigned integer that specifies the calculated value.
int compositionOffsetToDisplayOffsetShift;
// A 32-bit signed integer that specifies the calculated value.
int leastDisplayOffset;
// A 32-bit signed integer that specifies the calculated value.
int greatestDisplayOffset;
//A 32-bit signed integer that specifies the calculated value.
int displayStartTime;
//A 32-bit signed integer that specifies the calculated value.
int displayEndTime;
@Override
protected long getContentSize() {
return 24;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
compositionOffsetToDisplayOffsetShift = content.getInt();
leastDisplayOffset = content.getInt();
greatestDisplayOffset = content.getInt();
displayStartTime = content.getInt();
displayEndTime = content.getInt();
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
byteBuffer.putInt(compositionOffsetToDisplayOffsetShift);
byteBuffer.putInt(leastDisplayOffset);
byteBuffer.putInt(greatestDisplayOffset);
byteBuffer.putInt(displayStartTime);
byteBuffer.putInt(displayEndTime);
}
public int getCompositionOffsetToDisplayOffsetShift() {
return compositionOffsetToDisplayOffsetShift;
}
public void setCompositionOffsetToDisplayOffsetShift(int compositionOffsetToDisplayOffsetShift) {
this.compositionOffsetToDisplayOffsetShift = compositionOffsetToDisplayOffsetShift;
}
public int getLeastDisplayOffset() {
return leastDisplayOffset;
}
public void setLeastDisplayOffset(int leastDisplayOffset) {
this.leastDisplayOffset = leastDisplayOffset;
}
public int getGreatestDisplayOffset() {
return greatestDisplayOffset;
}
public void setGreatestDisplayOffset(int greatestDisplayOffset) {
this.greatestDisplayOffset = greatestDisplayOffset;
}
public int getDisplayStartTime() {
return displayStartTime;
}
public void setDisplayStartTime(int displayStartTime) {
this.displayStartTime = displayStartTime;
}
public int getDisplayEndTime() {
return displayEndTime;
}
public void setDisplayEndTime(int displayEndTime) {
this.displayEndTime = displayEndTime;
}
}
================================================
FILE: src/com/coremedia/iso/boxes/CompositionTimeToSample.java
================================================
package com.coremedia.iso.boxes;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static com.googlecode.mp4parser.util.CastUtils.l2i;
/**
*
* aligned(8) class CompositionOffsetBox
* extends FullBox(‘ctts’, version = 0, 0) {
* unsigned int(32) entry_count;
* int i;
* if (version==0) {
* for (i=0; i < entry_count; i++) {
* unsigned int(32) sample_count;
* unsigned int(32) sample_offset;
* }
* }
* else if (version == 1) {
* for (i=0; i < entry_count; i++) {
* unsigned int(32) sample_count;
* signed int(32) sample_offset;
* }
* }
* }
*
*
* This box provides the offset between decoding time and composition time.
* In version 0 of this box the decoding time must be less than the composition time, and
* the offsets are expressed as unsigned numbers such that
* CT(n) = DT(n) + CTTS(n) where CTTS(n) is the (uncompressed) table entry for sample n.
*
* In version 1 of this box, the composition timeline and the decoding timeline are
* still derived from each other, but the offsets are signed.
* It is recommended that for the computed composition timestamps, there is
* exactly one with the value 0 (zero).
*/
public class CompositionTimeToSample extends AbstractFullBox {
public static final String TYPE = "ctts";
List entries = Collections.emptyList();
public CompositionTimeToSample() {
super(TYPE);
}
protected long getContentSize() {
return 8 + 8 * entries.size();
}
public List getEntries() {
return entries;
}
public void setEntries(List entries) {
this.entries = entries;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
int numberOfEntries = l2i(IsoTypeReader.readUInt32(content));
entries = new ArrayList(numberOfEntries);
for (int i = 0; i < numberOfEntries; i++) {
Entry e = new Entry(l2i(IsoTypeReader.readUInt32(content)), content.getInt());
entries.add(e);
}
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeUInt32(byteBuffer, entries.size());
for (Entry entry : entries) {
IsoTypeWriter.writeUInt32(byteBuffer, entry.getCount());
byteBuffer.putInt(entry.getOffset());
}
}
public static class Entry {
int count;
int offset;
public Entry(int count, int offset) {
this.count = count;
this.offset = offset;
}
public int getCount() {
return count;
}
public int getOffset() {
return offset;
}
public void setCount(int count) {
this.count = count;
}
public void setOffset(int offset) {
this.offset = offset;
}
@Override
public String toString() {
return "Entry{" +
"count=" + count +
", offset=" + offset +
'}';
}
}
/**
* Decompresses the list of entries and returns the list of composition times.
*
* @return decoding time per sample
*/
public static int[] blowupCompositionTimes(List entries) {
long numOfSamples = 0;
for (CompositionTimeToSample.Entry entry : entries) {
numOfSamples += entry.getCount();
}
assert numOfSamples <= Integer.MAX_VALUE;
int[] decodingTime = new int[(int) numOfSamples];
int current = 0;
for (CompositionTimeToSample.Entry entry : entries) {
for (int i = 0; i < entry.getCount(); i++) {
decodingTime[current++] = entry.getOffset();
}
}
return decodingTime;
}
}
================================================
FILE: src/com/coremedia/iso/boxes/ContainerBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoFile;
import java.util.List;
/**
* Interface for all ISO boxes that may contain other boxes.
*/
public interface ContainerBox extends Box {
/**
* Gets all child boxes. May not return null.
*
* @return an array of boxes, empty array in case of no children.
*/
List getBoxes();
/**
* Sets all boxes and removes all previous child boxes.
* @param boxes the new list of children
*/
void setBoxes(List boxes);
/**
* Gets all child boxes of the given type. May not return null.
*
* @param clazz child box's type
* @return an array of boxes, empty array in case of no children.
*/
List getBoxes(Class clazz);
/**
* Gets all child boxes of the given type. May not return null.
*
* @param clazz child box's type
* @param recursive step down the tree
* @return an array of boxes, empty array in case of no children.
*/
List getBoxes(Class clazz, boolean recursive);
/**
* Gets the parent box. May be null in case of the
* {@link com.coremedia.iso.IsoFile} itself.
*
* @return a ContainerBox that contains this
*/
ContainerBox getParent();
/**
* Returns the number of bytes from the start of the box to start of the first child.
*
* @return offset of first child from box start
*/
long getNumOfBytesToFirstChild();
IsoFile getIsoFile();
}
================================================
FILE: src/com/coremedia/iso/boxes/CopyrightBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.coremedia.iso.Utf8;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
/**
* The copyright box contains a copyright declaration which applies to the entire presentation, when contained
* within the MovieBox, or, when contained in a track, to that entire track. There may be multple boxes using
* different language codes.
*
* @see MovieBox
* @see TrackBox
*/
public class CopyrightBox extends AbstractFullBox {
public static final String TYPE = "cprt";
private String language;
private String copyright;
public CopyrightBox() {
super(TYPE);
}
public String getLanguage() {
return language;
}
public String getCopyright() {
return copyright;
}
public void setLanguage(String language) {
this.language = language;
}
public void setCopyright(String copyright) {
this.copyright = copyright;
}
protected long getContentSize() {
return 7 + Utf8.utf8StringLengthInBytes(copyright);
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
language = IsoTypeReader.readIso639(content);
copyright = IsoTypeReader.readString(content);
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeIso639(byteBuffer, language);
byteBuffer.put(Utf8.convert(copyright));
byteBuffer.put((byte) 0);
}
public String toString() {
return "CopyrightBox[language=" + getLanguage() + ";copyright=" + getCopyright() + "]";
}
}
================================================
FILE: src/com/coremedia/iso/boxes/DataEntryUrlBox.java
================================================
/*
* 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;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
/**
* Only used within the DataReferenceBox. Find more information there.
*
* @see com.coremedia.iso.boxes.DataReferenceBox
*/
public class DataEntryUrlBox extends AbstractFullBox {
public static final String TYPE = "url ";
public DataEntryUrlBox() {
super(TYPE);
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
}
protected long getContentSize() {
return 4;
}
public String toString() {
return "DataEntryUrlBox[]";
}
}
================================================
FILE: src/com/coremedia/iso/boxes/DataEntryUrnBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.Utf8;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
/**
* Only used within the DataReferenceBox. Find more information there.
*
* @see com.coremedia.iso.boxes.DataReferenceBox
*/
public class DataEntryUrnBox extends AbstractFullBox {
private String name;
private String location;
public static final String TYPE = "urn ";
public DataEntryUrnBox() {
super(TYPE);
}
public String getName() {
return name;
}
public String getLocation() {
return location;
}
protected long getContentSize() {
return Utf8.utf8StringLengthInBytes(name) + 1 + Utf8.utf8StringLengthInBytes(location) + 1;
}
@Override
public void _parseDetails(ByteBuffer content) {
name = IsoTypeReader.readString(content);
location = IsoTypeReader.readString(content);
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
byteBuffer.put(Utf8.convert(name));
byteBuffer.put((byte) 0);
byteBuffer.put(Utf8.convert(location));
byteBuffer.put((byte) 0);
}
public String toString() {
return "DataEntryUrlBox[name=" + getName() + ";location=" + getLocation() + "]";
}
}
================================================
FILE: src/com/coremedia/iso/boxes/DataInformationBox.java
================================================
/*
* 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;
import com.googlecode.mp4parser.AbstractContainerBox;
/**
*
* Box Type: 'dinf'
* Container: {@link com.coremedia.iso.boxes.MediaInformationBox} ('minf')
* Mandatory: Yes
* Quantity: Exactly one
* The data information box contains objects that declare the location of the media information in a track.
*/
public class DataInformationBox extends AbstractContainerBox {
public static final String TYPE = "dinf";
public DataInformationBox() {
super(TYPE);
}
}
================================================
FILE: src/com/coremedia/iso/boxes/DataReferenceBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoTypeWriter;
import com.googlecode.mp4parser.FullContainerBox;
import java.nio.ByteBuffer;
/**
* The data reference object contains a table of data references (normally URLs) that declare the location(s) of
* the media data used within the presentation. The data reference index in the sample description ties entries in
* this table to the samples in the track. A track may be split over several sources in this way.
* If the flag is set indicating that the data is in the same file as this box, then no string (not even an empty one)
* shall be supplied in the entry field.
* The DataEntryBox within the DataReferenceBox shall be either a DataEntryUrnBox or a DataEntryUrlBox.
*
* @see com.coremedia.iso.boxes.DataEntryUrlBox
* @see com.coremedia.iso.boxes.DataEntryUrnBox
*/
public class DataReferenceBox extends FullContainerBox {
public static final String TYPE = "dref";
public DataReferenceBox() {
super(TYPE);
}
@Override
protected long getContentSize() {
return super.getContentSize() + 4;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
content.get(new byte[4]); // basically a skip of 4 bytes signaling the number of child boxes
parseChildBoxes(content);
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeUInt32(byteBuffer, getBoxes().size());
writeChildBoxes(byteBuffer);
}
}
================================================
FILE: src/com/coremedia/iso/boxes/DescriptionBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.coremedia.iso.Utf8;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
/**
* Gives a language dependent description of the media contained in the ISO file.
*/
public class DescriptionBox extends AbstractFullBox {
public static final String TYPE = "dscp";
private String language;
private String description;
public DescriptionBox() {
super(TYPE);
}
public String getLanguage() {
return language;
}
public String getDescription() {
return description;
}
protected long getContentSize() {
return 7 + Utf8.utf8StringLengthInBytes(description);
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
language = IsoTypeReader.readIso639(content);
description = IsoTypeReader.readString(content);
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeIso639(byteBuffer, language);
byteBuffer.put(Utf8.convert(description));
byteBuffer.put((byte) 0);
}
public String toString() {
return "DescriptionBox[language=" + getLanguage() + ";description=" + getDescription() + "]";
}
public void setLanguage(String language) {
this.language = language;
}
public void setDescription(String description) {
this.description = description;
}
}
================================================
FILE: src/com/coremedia/iso/boxes/EditBox.java
================================================
/*
* 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;
import com.googlecode.mp4parser.AbstractContainerBox;
/**
* An Edit Box maps the presentation time-line to the media time-line as it is stored in the file.
* The Edit Box is a container fpr the edit lists. Defined in ISO/IEC 14496-12.
*
* @see EditListBox
*/
public class EditBox extends AbstractContainerBox {
public static final String TYPE = "edts";
public EditBox() {
super(TYPE);
}
}
================================================
FILE: src/com/coremedia/iso/boxes/EditListBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.googlecode.mp4parser.AbstractFullBox;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.LinkedList;
import java.util.List;
import static com.googlecode.mp4parser.util.CastUtils.l2i;
/**
*
* Box Type : 'elst'
* Container: {@link EditBox}('edts')
* Mandatory: No
* Quantity : Zero or one
* This box contains an explicit timeline map. Each entry defines part of the track time-line: by mapping part of
* the media time-line, or by indicating 'empty' time, or by defining a 'dwell', where a single time-point in the
* media is held for a period.
* Note that edits are not restricted to fall on sample times. This means that when entering an edit, it can be
* necessary to (a) back up to a sync point, and pre-roll from there and then (b) be careful about the duration of
* the first sample - it might have been truncated if the edit enters it during its normal duration. If this is audio,
* that frame might need to be decoded, and then the final slicing done. Likewise, the duration of the last sample
* in an edit might need slicing.
* Starting offsets for tracks (streams) are represented by an initial empty edit. For example, to play a track from
* its start for 30 seconds, but at 10 seconds into the presentation, we have the following edit list:
*
* Entry-count = 2
* Segment-duration = 10 seconds
* Media-Time = -1
* Media-Rate = 1
* Segment-duration = 30 seconds (could be the length of the whole track)
* Media-Time = 0 seconds
* Media-Rate = 1
*/
public class EditListBox extends AbstractFullBox {
private List entries = new LinkedList();
public static final String TYPE = "elst";
public EditListBox() {
super(TYPE);
}
public List getEntries() {
return entries;
}
public void setEntries(List entries) {
this.entries = entries;
}
protected long getContentSize() {
long contentSize = 8;
if (getVersion() == 1) {
contentSize += entries.size() * 20;
} else {
contentSize += entries.size() * 12;
}
return contentSize;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
int entryCount = l2i(IsoTypeReader.readUInt32(content));
entries = new LinkedList();
for (int i = 0; i < entryCount; i++) {
entries.add(new Entry(this, content));
}
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeUInt32(byteBuffer, entries.size());
for (Entry entry : entries) {
entry.getContent(byteBuffer);
}
}
@Override
public String toString() {
return "EditListBox{" +
"entries=" + entries +
'}';
}
public static class Entry {
private long segmentDuration;
private long mediaTime;
private double mediaRate;
EditListBox editListBox;
/**
* Creates a new Entry with all values set.
*
* @param segmentDuration duration in movie timescale
* @param mediaTime starting time
* @param mediaRate relative play rate
*/
public Entry(EditListBox editListBox, long segmentDuration, long mediaTime, double mediaRate) {
this.segmentDuration = segmentDuration;
this.mediaTime = mediaTime;
this.mediaRate = mediaRate;
this.editListBox = editListBox;
}
public Entry(EditListBox editListBox, ByteBuffer bb) {
if (editListBox.getVersion() == 1) {
segmentDuration = IsoTypeReader.readUInt64(bb);
mediaTime = IsoTypeReader.readUInt64(bb);
mediaRate = IsoTypeReader.readFixedPoint1616(bb);
} else {
segmentDuration = IsoTypeReader.readUInt32(bb);
mediaTime = IsoTypeReader.readUInt32(bb);
mediaRate = IsoTypeReader.readFixedPoint1616(bb);
}
this.editListBox = editListBox;
}
/**
* The segment duration is an integer that specifies the duration
* of this edit segment in units of the timescale in the Movie
* Header Box
*
* @return segment duration in movie timescale
*/
public long getSegmentDuration() {
return segmentDuration;
}
/**
* The segment duration is an integer that specifies the duration
* of this edit segment in units of the timescale in the Movie
* Header Box
*
* @param segmentDuration new segment duration in movie timescale
*/
public void setSegmentDuration(long segmentDuration) {
this.segmentDuration = segmentDuration;
}
/**
* The media time is an integer containing the starting time
* within the media of a specific edit segment(in media time
* scale units, in composition time)
*
* @return starting time
*/
public long getMediaTime() {
return mediaTime;
}
/**
* The media time is an integer containing the starting time
* within the media of a specific edit segment(in media time
* scale units, in composition time)
*
* @param mediaTime starting time
*/
public void setMediaTime(long mediaTime) {
this.mediaTime = mediaTime;
}
/**
* The media rate specifies the relative rate at which to play the
* media corresponding to a specific edit segment.
*
* @return relative play rate
*/
public double getMediaRate() {
return mediaRate;
}
/**
* The media rate specifies the relative rate at which to play the
* media corresponding to a specific edit segment.
*
* @param mediaRate new relative play rate
*/
public void setMediaRate(double mediaRate) {
this.mediaRate = mediaRate;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Entry entry = (Entry) o;
if (mediaTime != entry.mediaTime) return false;
if (segmentDuration != entry.segmentDuration) return false;
return true;
}
@Override
public int hashCode() {
int result = (int) (segmentDuration ^ (segmentDuration >>> 32));
result = 31 * result + (int) (mediaTime ^ (mediaTime >>> 32));
return result;
}
public void getContent(ByteBuffer bb) {
if (editListBox.getVersion() == 1) {
IsoTypeWriter.writeUInt64(bb, segmentDuration);
IsoTypeWriter.writeUInt64(bb, mediaTime);
} else {
IsoTypeWriter.writeUInt32(bb, l2i(segmentDuration));
bb.putInt(l2i(mediaTime));
}
IsoTypeWriter.writeFixedPont1616(bb, mediaRate);
}
@Override
public String toString() {
return "Entry{" +
"segmentDuration=" + segmentDuration +
", mediaTime=" + mediaTime +
", mediaRate=" + mediaRate +
'}';
}
}
}
================================================
FILE: src/com/coremedia/iso/boxes/FileTypeBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoFile;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.googlecode.mp4parser.AbstractBox;
import com.googlecode.mp4parser.annotations.DoNotParseDetail;
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
/**
* This box identifies the specifications to which this file complies.
* Each brand is a printable four-character code, registered with ISO, that
* identifies a precise specification.
*/
public class FileTypeBox extends AbstractBox {
public static final String TYPE = "ftyp";
private String majorBrand;
private long minorVersion;
private List compatibleBrands = Collections.emptyList();
public FileTypeBox() {
super(TYPE);
}
public FileTypeBox(String majorBrand, long minorVersion, List compatibleBrands) {
super(TYPE);
this.majorBrand = majorBrand;
this.minorVersion = minorVersion;
this.compatibleBrands = compatibleBrands;
}
protected long getContentSize() {
return 8 + compatibleBrands.size() * 4;
}
@Override
public void _parseDetails(ByteBuffer content) {
majorBrand = IsoTypeReader.read4cc(content);
minorVersion = IsoTypeReader.readUInt32(content);
int compatibleBrandsCount = content.remaining() / 4;
compatibleBrands = new LinkedList();
for (int i = 0; i < compatibleBrandsCount; i++) {
compatibleBrands.add(IsoTypeReader.read4cc(content));
}
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
byteBuffer.put(IsoFile.fourCCtoBytes(majorBrand));
IsoTypeWriter.writeUInt32(byteBuffer, minorVersion);
for (String compatibleBrand : compatibleBrands) {
byteBuffer.put(IsoFile.fourCCtoBytes(compatibleBrand));
}
}
/**
* Gets the brand identifier.
*
* @return the brand identifier
*/
public String getMajorBrand() {
return majorBrand;
}
/**
* Sets the major brand of the file used to determine an appropriate reader.
*
* @param majorBrand the new major brand
*/
public void setMajorBrand(String majorBrand) {
this.majorBrand = majorBrand;
}
/**
* Sets the "informative integer for the minor version of the major brand".
*
* @param minorVersion the version number of the major brand
*/
public void setMinorVersion(int minorVersion) {
this.minorVersion = minorVersion;
}
/**
* Gets an informative integer for the minor version of the major brand.
*
* @return an informative integer
* @see FileTypeBox#getMajorBrand()
*/
public long getMinorVersion() {
return minorVersion;
}
/**
* Gets an array of 4-cc brands.
*
* @return the compatible brands
*/
public List getCompatibleBrands() {
return compatibleBrands;
}
public void setCompatibleBrands(List compatibleBrands) {
this.compatibleBrands = compatibleBrands;
}
@DoNotParseDetail
public String toString() {
StringBuilder result = new StringBuilder();
result.append("FileTypeBox[");
result.append("majorBrand=").append(getMajorBrand());
result.append(";");
result.append("minorVersion=").append(getMinorVersion());
for (String compatibleBrand : compatibleBrands) {
result.append(";");
result.append("compatibleBrand=").append(compatibleBrand);
}
result.append("]");
return result.toString();
}
}
================================================
FILE: src/com/coremedia/iso/boxes/FreeBox.java
================================================
/*
* 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;
import com.googlecode.mp4parser.AbstractBox;
import java.nio.ByteBuffer;
/**
* A free box. Just a placeholder to enable editing without rewriting the whole file.
*/
public class FreeBox extends AbstractBox {
public static final String TYPE = "free";
ByteBuffer data;
public FreeBox() {
super(TYPE);
}
public FreeBox(int size) {
super(TYPE);
this.data = ByteBuffer.allocate(size);
}
@Override
protected long getContentSize() {
return data.limit();
}
@Override
public void _parseDetails(ByteBuffer content) {
data = content;
data.position(data.position() + data.remaining());
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
data.rewind();
byteBuffer.put(data);
}
public ByteBuffer getData() {
return data;
}
public void setData(ByteBuffer data) {
this.data = data;
}
}
================================================
FILE: src/com/coremedia/iso/boxes/FreeSpaceBox.java
================================================
/*
* 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;
import com.googlecode.mp4parser.AbstractBox;
import java.nio.ByteBuffer;
/**
* The contents of a free-space box are irrelevant and may be ignored, or the object deleted, without affecting the
* presentation. Care should be excercized when deleting the object, as this may invalidate the offsets used in the
* sample table.
*/
public class FreeSpaceBox extends AbstractBox {
public static final String TYPE = "skip";
byte[] data;
protected long getContentSize() {
return data.length;
}
public FreeSpaceBox() {
super(TYPE);
}
public void setData(byte[] data) {
this.data = data;
}
public byte[] getData() {
return data;
}
@Override
public void _parseDetails(ByteBuffer content) {
data = new byte[content.remaining()];
content.get(data);
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
byteBuffer.put(data);
}
public String toString() {
return "FreeSpaceBox[size=" + data.length + ";type=" + getType() + "]";
}
}
================================================
FILE: src/com/coremedia/iso/boxes/FullBox.java
================================================
package com.coremedia.iso.boxes;
import com.coremedia.iso.boxes.Box;
/**
* The FullBox contains all getters and setters specific
* to a so-called full box according to the ISO/IEC 14496/12 specification.
*/
public interface FullBox extends Box {
int getVersion();
void setVersion(int version);
int getFlags();
void setFlags(int flags);
}
================================================
FILE: src/com/coremedia/iso/boxes/GenericMediaHeaderBoxImpl.java
================================================
package com.coremedia.iso.boxes;
import java.nio.ByteBuffer;
public class GenericMediaHeaderBoxImpl extends AbstractMediaHeaderBox {
ByteBuffer data;
@Override
protected long getContentSize() {
return 4 + data.limit();
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
this.data = content.slice();
content.position(content.remaining() + content.position());
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
byteBuffer.put((ByteBuffer) data.rewind());
}
public GenericMediaHeaderBoxImpl() {
super("gmhd");
}
public ByteBuffer getData() {
return data;
}
public void setData(ByteBuffer data) {
this.data = data;
}
}
================================================
FILE: src/com/coremedia/iso/boxes/GenreBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.coremedia.iso.Utf8;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
/**
* Containing genre information and contained in the UserDataBox.
*
* @see com.coremedia.iso.boxes.UserDataBox
*/
public class GenreBox extends AbstractFullBox {
public static final String TYPE = "gnre";
private String language;
private String genre;
public GenreBox() {
super(TYPE);
}
public String getLanguage() {
return language;
}
public String getGenre() {
return genre;
}
public void setLanguage(String language) {
this.language = language;
}
public void setGenre(String genre) {
this.genre = genre;
}
protected long getContentSize() {
return 7 + Utf8.utf8StringLengthInBytes(genre);
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
language = IsoTypeReader.readIso639(content);
genre = IsoTypeReader.readString(content);
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeIso639(byteBuffer, language);
byteBuffer.put(Utf8.convert(genre));
byteBuffer.put((byte) 0);
}
public String toString() {
return "GenreBox[language=" + getLanguage() + ";genre=" + getGenre() + "]";
}
}
================================================
FILE: src/com/coremedia/iso/boxes/HandlerBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoFile;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.coremedia.iso.Utf8;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* This box within a Media Box declares the process by which the media-data in the track is presented,
* and thus, the nature of the media in a track.
* This Box when present in a Meta Box, declares the structure or format of the 'meta' box contents.
* See ISO/IEC 14496-12 for details.
*
* @see MetaBox
* @see MediaBox
*/
public class HandlerBox extends AbstractFullBox {
public static final String TYPE = "hdlr";
public static final Map readableTypes;
static {
HashMap hm = new HashMap();
hm.put("odsm", "ObjectDescriptorStream - defined in ISO/IEC JTC1/SC29/WG11 - CODING OF MOVING PICTURES AND AUDIO");
hm.put("crsm", "ClockReferenceStream - defined in ISO/IEC JTC1/SC29/WG11 - CODING OF MOVING PICTURES AND AUDIO");
hm.put("sdsm", "SceneDescriptionStream - defined in ISO/IEC JTC1/SC29/WG11 - CODING OF MOVING PICTURES AND AUDIO");
hm.put("m7sm", "MPEG7Stream - defined in ISO/IEC JTC1/SC29/WG11 - CODING OF MOVING PICTURES AND AUDIO");
hm.put("ocsm", "ObjectContentInfoStream - defined in ISO/IEC JTC1/SC29/WG11 - CODING OF MOVING PICTURES AND AUDIO");
hm.put("ipsm", "IPMP Stream - defined in ISO/IEC JTC1/SC29/WG11 - CODING OF MOVING PICTURES AND AUDIO");
hm.put("mjsm", "MPEG-J Stream - defined in ISO/IEC JTC1/SC29/WG11 - CODING OF MOVING PICTURES AND AUDIO");
hm.put("mdir", "Apple Meta Data iTunes Reader");
hm.put("mp7b", "MPEG-7 binary XML");
hm.put("mp7t", "MPEG-7 XML");
hm.put("vide", "Video Track");
hm.put("soun", "Sound Track");
hm.put("hint", "Hint Track");
hm.put("appl", "Apple specific");
hm.put("meta", "Timed Metadata track - defined in ISO/IEC JTC1/SC29/WG11 - CODING OF MOVING PICTURES AND AUDIO");
readableTypes = Collections.unmodifiableMap(hm);
}
private String handlerType;
private String name = null;
private long a, b, c;
private boolean zeroTerm = true;
private long shouldBeZeroButAppleWritesHereSomeValue;
public HandlerBox() {
super(TYPE);
}
public String getHandlerType() {
return handlerType;
}
/**
* You are required to add a '\0' string termination by yourself.
*
* @param name the new human readable name
*/
public void setName(String name) {
this.name = name;
}
public void setHandlerType(String handlerType) {
this.handlerType = handlerType;
}
public String getName() {
return name;
}
public String getHumanReadableTrackType() {
return readableTypes.get(handlerType) != null ? readableTypes.get(handlerType) : "Unknown Handler Type";
}
protected long getContentSize() {
if (zeroTerm) {
return 25 + Utf8.utf8StringLengthInBytes(name);
} else {
return 24 + Utf8.utf8StringLengthInBytes(name);
}
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
shouldBeZeroButAppleWritesHereSomeValue = IsoTypeReader.readUInt32(content);
handlerType = IsoTypeReader.read4cc(content);
a = IsoTypeReader.readUInt32(content);
b = IsoTypeReader.readUInt32(content);
c = IsoTypeReader.readUInt32(content);
if (content.remaining() > 0) {
name = IsoTypeReader.readString(content, content.remaining());
if (name.endsWith("\0")) {
name = name.substring(0, name.length() - 1);
zeroTerm = true;
} else {
zeroTerm = false;
}
} else {
zeroTerm = false; //No string at all, not even zero term char
}
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeUInt32(byteBuffer, shouldBeZeroButAppleWritesHereSomeValue);
byteBuffer.put(IsoFile.fourCCtoBytes(handlerType));
IsoTypeWriter.writeUInt32(byteBuffer, a);
IsoTypeWriter.writeUInt32(byteBuffer, b);
IsoTypeWriter.writeUInt32(byteBuffer, c);
if (name != null) {
byteBuffer.put(Utf8.convert(name));
}
if (zeroTerm) {
byteBuffer.put((byte) 0);
}
}
public String toString() {
return "HandlerBox[handlerType=" + getHandlerType() + ";name=" + getName() + "]";
}
}
================================================
FILE: src/com/coremedia/iso/boxes/HintMediaHeaderBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import java.nio.ByteBuffer;
/**
* The hint media header contains general information, independent of the protocaol, for hint tracks. Resides
* in Media Information Box.
*
* @see com.coremedia.iso.boxes.MediaInformationBox
*/
public class HintMediaHeaderBox extends AbstractMediaHeaderBox {
private int maxPduSize;
private int avgPduSize;
private long maxBitrate;
private long avgBitrate;
public static final String TYPE = "hmhd";
public HintMediaHeaderBox() {
super(TYPE);
}
public int getMaxPduSize() {
return maxPduSize;
}
public int getAvgPduSize() {
return avgPduSize;
}
public long getMaxBitrate() {
return maxBitrate;
}
public long getAvgBitrate() {
return avgBitrate;
}
protected long getContentSize() {
return 20;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
maxPduSize = IsoTypeReader.readUInt16(content);
avgPduSize = IsoTypeReader.readUInt16(content);
maxBitrate = IsoTypeReader.readUInt32(content);
avgBitrate = IsoTypeReader.readUInt32(content);
IsoTypeReader.readUInt32(content); // reserved!
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeUInt16(byteBuffer, maxPduSize);
IsoTypeWriter.writeUInt16(byteBuffer, avgPduSize);
IsoTypeWriter.writeUInt32(byteBuffer, maxBitrate);
IsoTypeWriter.writeUInt32(byteBuffer, avgBitrate);
IsoTypeWriter.writeUInt32(byteBuffer, 0);
}
@Override
public String toString() {
return "HintMediaHeaderBox{" +
"maxPduSize=" + maxPduSize +
", avgPduSize=" + avgPduSize +
", maxBitrate=" + maxBitrate +
", avgBitrate=" + avgBitrate +
'}';
}
}
================================================
FILE: src/com/coremedia/iso/boxes/ItemDataBox.java
================================================
package com.coremedia.iso.boxes;
import com.googlecode.mp4parser.AbstractBox;
import java.nio.ByteBuffer;
/**
*
*/
public class ItemDataBox extends AbstractBox {
ByteBuffer data = ByteBuffer.allocate(0);
public static final String TYPE = "idat";
public ItemDataBox() {
super(TYPE);
}
public ByteBuffer getData() {
return data;
}
public void setData(ByteBuffer data) {
this.data = data;
}
@Override
protected long getContentSize() {
return data.limit();
}
@Override
public void _parseDetails(ByteBuffer content) {
data = content.slice();
content.position(content.position() + content.remaining());
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
byteBuffer.put(data);
}
}
================================================
FILE: src/com/coremedia/iso/boxes/ItemLocationBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeReaderVariable;
import com.coremedia.iso.IsoTypeWriter;
import com.coremedia.iso.IsoTypeWriterVariable;
import com.googlecode.mp4parser.AbstractFullBox;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.LinkedList;
import java.util.List;
/**
* aligned(8) class ItemLocationBox extends FullBox(‘iloc’, version, 0) {
* unsigned int(4) offset_size;
* unsigned int(4) length_size;
* unsigned int(4) base_offset_size;
* if (version == 1)
* unsigned int(4) index_size;
* else
* unsigned int(4) reserved;
* unsigned int(16) item_count;
* for (i=0; i 0)) {
* unsigned int(index_size*8) extent_index;
* }
* unsigned int(offset_size*8) extent_offset;
* unsigned int(length_size*8) extent_length;
* }
* }
* }
*/
public class ItemLocationBox extends AbstractFullBox {
public int offsetSize = 8;
public int lengthSize = 8;
public int baseOffsetSize = 8;
public int indexSize = 0;
public List- items = new LinkedList
- ();
public static final String TYPE = "iloc";
public ItemLocationBox() {
super(TYPE);
}
@Override
protected long getContentSize() {
long size = 8;
for (Item item : items) {
size += item.getSize();
}
return size;
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeUInt8(byteBuffer, ((offsetSize << 4) | lengthSize));
if (getVersion() == 1) {
IsoTypeWriter.writeUInt8(byteBuffer, (baseOffsetSize << 4 | indexSize));
} else {
IsoTypeWriter.writeUInt8(byteBuffer, (baseOffsetSize << 4));
}
IsoTypeWriter.writeUInt16(byteBuffer, items.size());
for (Item item : items) {
item.getContent(byteBuffer);
}
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
int tmp = IsoTypeReader.readUInt8(content);
offsetSize = tmp >>> 4;
lengthSize = tmp & 0xf;
tmp = IsoTypeReader.readUInt8(content);
baseOffsetSize = tmp >>> 4;
if (getVersion() == 1) {
indexSize = tmp & 0xf;
}
int itemCount = IsoTypeReader.readUInt16(content);
for (int i = 0; i < itemCount; i++) {
items.add(new Item(content));
}
}
public int getOffsetSize() {
return offsetSize;
}
public void setOffsetSize(int offsetSize) {
this.offsetSize = offsetSize;
}
public int getLengthSize() {
return lengthSize;
}
public void setLengthSize(int lengthSize) {
this.lengthSize = lengthSize;
}
public int getBaseOffsetSize() {
return baseOffsetSize;
}
public void setBaseOffsetSize(int baseOffsetSize) {
this.baseOffsetSize = baseOffsetSize;
}
public int getIndexSize() {
return indexSize;
}
public void setIndexSize(int indexSize) {
this.indexSize = indexSize;
}
public List
- getItems() {
return items;
}
public void setItems(List
- items) {
this.items = items;
}
public Item createItem(int itemId, int constructionMethod, int dataReferenceIndex, long baseOffset, List extents) {
return new Item(itemId, constructionMethod, dataReferenceIndex, baseOffset, extents);
}
Item createItem(ByteBuffer bb) {
return new Item(bb);
}
public class Item {
public int itemId;
public int constructionMethod;
public int dataReferenceIndex;
public long baseOffset;
public List extents = new LinkedList();
public Item(ByteBuffer in) {
itemId = IsoTypeReader.readUInt16(in);
if (getVersion() == 1) {
int tmp = IsoTypeReader.readUInt16(in);
constructionMethod = tmp & 0xf;
}
dataReferenceIndex = IsoTypeReader.readUInt16(in);
if (baseOffsetSize > 0) {
baseOffset = IsoTypeReaderVariable.read(in, baseOffsetSize);
} else {
baseOffset = 0;
}
int extentCount = IsoTypeReader.readUInt16(in);
for (int i = 0; i < extentCount; i++) {
extents.add(new Extent(in));
}
}
public Item(int itemId, int constructionMethod, int dataReferenceIndex, long baseOffset, List extents) {
this.itemId = itemId;
this.constructionMethod = constructionMethod;
this.dataReferenceIndex = dataReferenceIndex;
this.baseOffset = baseOffset;
this.extents = extents;
}
public int getSize() {
int size = 2;
if (getVersion() == 1) {
size += 2;
}
size += 2;
size += baseOffsetSize;
size += 2;
for (Extent extent : extents) {
size += extent.getSize();
}
return size;
}
public void setBaseOffset(long baseOffset) {
this.baseOffset = baseOffset;
}
public void getContent(ByteBuffer bb) {
IsoTypeWriter.writeUInt16(bb, itemId);
if (getVersion() == 1) {
IsoTypeWriter.writeUInt16(bb, constructionMethod);
}
IsoTypeWriter.writeUInt16(bb, dataReferenceIndex);
if (baseOffsetSize > 0) {
IsoTypeWriterVariable.write(baseOffset, bb, baseOffsetSize);
}
IsoTypeWriter.writeUInt16(bb, extents.size());
for (Extent extent : extents) {
extent.getContent(bb);
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Item item = (Item) o;
if (baseOffset != item.baseOffset) return false;
if (constructionMethod != item.constructionMethod) return false;
if (dataReferenceIndex != item.dataReferenceIndex) return false;
if (itemId != item.itemId) return false;
if (extents != null ? !extents.equals(item.extents) : item.extents != null) return false;
return true;
}
@Override
public int hashCode() {
int result = itemId;
result = 31 * result + constructionMethod;
result = 31 * result + dataReferenceIndex;
result = 31 * result + (int) (baseOffset ^ (baseOffset >>> 32));
result = 31 * result + (extents != null ? extents.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "Item{" +
"baseOffset=" + baseOffset +
", itemId=" + itemId +
", constructionMethod=" + constructionMethod +
", dataReferenceIndex=" + dataReferenceIndex +
", extents=" + extents +
'}';
}
}
public Extent createExtent(long extentOffset, long extentLength, long extentIndex) {
return new Extent(extentOffset, extentLength, extentIndex);
}
Extent createExtent(ByteBuffer bb) {
return new Extent(bb);
}
public class Extent {
public long extentOffset;
public long extentLength;
public long extentIndex;
public Extent(long extentOffset, long extentLength, long extentIndex) {
this.extentOffset = extentOffset;
this.extentLength = extentLength;
this.extentIndex = extentIndex;
}
public Extent(ByteBuffer in) {
if ((getVersion() == 1) && indexSize > 0) {
extentIndex = IsoTypeReaderVariable.read(in, indexSize);
}
extentOffset = IsoTypeReaderVariable.read(in, offsetSize);
extentLength = IsoTypeReaderVariable.read(in, lengthSize);
}
public void getContent(ByteBuffer os) {
if ((getVersion() == 1) && indexSize > 0) {
IsoTypeWriterVariable.write(extentIndex, os, indexSize);
}
IsoTypeWriterVariable.write(extentOffset, os, offsetSize);
IsoTypeWriterVariable.write(extentLength, os, lengthSize);
}
public int getSize() {
return (indexSize > 0 ? indexSize : 0) + offsetSize + lengthSize;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Extent extent = (Extent) o;
if (extentIndex != extent.extentIndex) return false;
if (extentLength != extent.extentLength) return false;
if (extentOffset != extent.extentOffset) return false;
return true;
}
@Override
public int hashCode() {
int result = (int) (extentOffset ^ (extentOffset >>> 32));
result = 31 * result + (int) (extentLength ^ (extentLength >>> 32));
result = 31 * result + (int) (extentIndex ^ (extentIndex >>> 32));
return result;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("Extent");
sb.append("{extentOffset=").append(extentOffset);
sb.append(", extentLength=").append(extentLength);
sb.append(", extentIndex=").append(extentIndex);
sb.append('}');
return sb.toString();
}
}
}
================================================
FILE: src/com/coremedia/iso/boxes/ItemProtectionBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.googlecode.mp4parser.FullContainerBox;
import java.nio.ByteBuffer;
/**
* The Item Protection Box provides an array of item protection information, for use by the Item Information Box.
*
* @see com.coremedia.iso.boxes.ItemProtectionBox
*/
public class ItemProtectionBox extends FullContainerBox {
public static final String TYPE = "ipro";
public ItemProtectionBox() {
super(TYPE);
}
public SchemeInformationBox getItemProtectionScheme() {
if (!getBoxes(SchemeInformationBox.class).isEmpty()) {
return getBoxes(SchemeInformationBox.class).get(0);
} else {
return null;
}
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
IsoTypeReader.readUInt16(content);
parseChildBoxes(content);
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeUInt16(byteBuffer, getBoxes().size());
writeChildBoxes(byteBuffer);
}
}
================================================
FILE: src/com/coremedia/iso/boxes/KeywordsBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.coremedia.iso.Utf8;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
/**
* List of keywords according to 3GPP 26.244.
*/
public class KeywordsBox extends AbstractFullBox {
public static final String TYPE = "kywd";
private String language;
private String[] keywords;
public KeywordsBox() {
super(TYPE);
}
public String getLanguage() {
return language;
}
public String[] getKeywords() {
return keywords;
}
public void setLanguage(String language) {
this.language = language;
}
public void setKeywords(String[] keywords) {
this.keywords = keywords;
}
protected long getContentSize() {
long contentSize = 7;
for (String keyword : keywords) {
contentSize += 1 + Utf8.utf8StringLengthInBytes(keyword) + 1;
}
return contentSize;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
language = IsoTypeReader.readIso639(content);
int keywordCount = IsoTypeReader.readUInt8(content);
keywords = new String[keywordCount];
for (int i = 0; i < keywordCount; i++) {
IsoTypeReader.readUInt8(content);
keywords[i] = IsoTypeReader.readString(content);
}
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeIso639(byteBuffer, language);
IsoTypeWriter.writeUInt8(byteBuffer, keywords.length);
for (String keyword : keywords) {
IsoTypeWriter.writeUInt8(byteBuffer, Utf8.utf8StringLengthInBytes(keyword) + 1);
byteBuffer.put(Utf8.convert(keyword));
}
}
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("KeywordsBox[language=").append(getLanguage());
for (int i = 0; i < keywords.length; i++) {
buffer.append(";keyword").append(i).append("=").append(keywords[i]);
}
buffer.append("]");
return buffer.toString();
}
}
================================================
FILE: src/com/coremedia/iso/boxes/MediaBox.java
================================================
/*
* 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;
import com.googlecode.mp4parser.AbstractContainerBox;
/**
* The media declaration container contains all the objects that declare information about the media data within a
* track.
*/
public class MediaBox extends AbstractContainerBox {
public static final String TYPE = "mdia";
public MediaBox() {
super(TYPE);
}
public MediaInformationBox getMediaInformationBox() {
for (Box box : boxes) {
if (box instanceof MediaInformationBox) {
return (MediaInformationBox) box;
}
}
return null;
}
public MediaHeaderBox getMediaHeaderBox() {
for (Box box : boxes) {
if (box instanceof MediaHeaderBox) {
return (MediaHeaderBox) box;
}
}
return null;
}
public HandlerBox getHandlerBox() {
for (Box box : boxes) {
if (box instanceof HandlerBox) {
return (HandlerBox) box;
}
}
return null;
}
}
================================================
FILE: src/com/coremedia/iso/boxes/MediaHeaderBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
/**
* This box defines overall information which is media-independent, and relevant to the entire presentation
* considered as a whole.
*/
public class MediaHeaderBox extends AbstractFullBox {
public static final String TYPE = "mdhd";
private long creationTime;
private long modificationTime;
private long timescale;
private long duration;
private String language;
public MediaHeaderBox() {
super(TYPE);
}
public long getCreationTime() {
return creationTime;
}
public long getModificationTime() {
return modificationTime;
}
public long getTimescale() {
return timescale;
}
public long getDuration() {
return duration;
}
public String getLanguage() {
return language;
}
protected long getContentSize() {
long contentSize = 4;
if (getVersion() == 1) {
contentSize += 8 + 8 + 4 + 8;
} else {
contentSize += 4 + 4 + 4 + 4;
}
contentSize += 2;
contentSize += 2;
return contentSize;
}
public void setCreationTime(long creationTime) {
this.creationTime = creationTime;
}
public void setModificationTime(long modificationTime) {
this.modificationTime = modificationTime;
}
public void setTimescale(long timescale) {
this.timescale = timescale;
}
public void setDuration(long duration) {
this.duration = duration;
}
public void setLanguage(String language) {
this.language = language;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
if (getVersion() == 1) {
creationTime = IsoTypeReader.readUInt64(content);
modificationTime = IsoTypeReader.readUInt64(content);
timescale = IsoTypeReader.readUInt32(content);
duration = IsoTypeReader.readUInt64(content);
} else {
creationTime = IsoTypeReader.readUInt32(content);
modificationTime = IsoTypeReader.readUInt32(content);
timescale = IsoTypeReader.readUInt32(content);
duration = IsoTypeReader.readUInt32(content);
}
language = IsoTypeReader.readIso639(content);
IsoTypeReader.readUInt16(content);
}
public String toString() {
StringBuilder result = new StringBuilder();
result.append("MeditHeaderBox[");
result.append("creationTime=").append(getCreationTime());
result.append(";");
result.append("modificationTime=").append(getModificationTime());
result.append(";");
result.append("timescale=").append(getTimescale());
result.append(";");
result.append("duration=").append(getDuration());
result.append(";");
result.append("language=").append(getLanguage());
result.append("]");
return result.toString();
}
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
if (getVersion() == 1) {
IsoTypeWriter.writeUInt64(byteBuffer, creationTime);
IsoTypeWriter.writeUInt64(byteBuffer, modificationTime);
IsoTypeWriter.writeUInt32(byteBuffer, timescale);
IsoTypeWriter.writeUInt64(byteBuffer, duration);
} else {
IsoTypeWriter.writeUInt32(byteBuffer, creationTime);
IsoTypeWriter.writeUInt32(byteBuffer, modificationTime);
IsoTypeWriter.writeUInt32(byteBuffer, timescale);
IsoTypeWriter.writeUInt32(byteBuffer, duration);
}
IsoTypeWriter.writeIso639(byteBuffer, language);
IsoTypeWriter.writeUInt16(byteBuffer, 0);
}
}
================================================
FILE: src/com/coremedia/iso/boxes/MediaInformationBox.java
================================================
/*
* 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;
import com.googlecode.mp4parser.AbstractContainerBox;
/**
* This box contains all the objects that declare characteristic information of the media in the track.
*/
public class MediaInformationBox extends AbstractContainerBox {
public static final String TYPE = "minf";
public MediaInformationBox() {
super(TYPE);
}
public SampleTableBox getSampleTableBox() {
for (Box box : boxes) {
if (box instanceof SampleTableBox) {
return (SampleTableBox) box;
}
}
return null;
}
public AbstractMediaHeaderBox getMediaHeaderBox() {
for (Box box : boxes) {
if (box instanceof AbstractMediaHeaderBox) {
return (AbstractMediaHeaderBox) box;
}
}
return null;
}
}
================================================
FILE: src/com/coremedia/iso/boxes/MetaBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.googlecode.mp4parser.AbstractContainerBox;
import com.googlecode.mp4parser.util.ByteBufferByteChannel;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
* A common base structure to contain general metadata. See ISO/IEC 14496-12 Ch. 8.44.1.
*/
public class MetaBox extends AbstractContainerBox {
private int version = 0;
private int flags = 0;
public static final String TYPE = "meta";
public MetaBox() {
super(TYPE);
}
@Override
public long getContentSize() {
if (isMp4Box()) {
// it's a fullbox
return 4 + super.getContentSize();
} else {
// it's an apple metabox
return super.getContentSize();
}
}
@Override
public long getNumOfBytesToFirstChild() {
if (isMp4Box()) {
// it's a fullbox
return 12;
} else {
// it's an apple metabox
return 8;
}
}
@Override
public void _parseDetails(ByteBuffer content) {
int pos = content.position();
content.get(new byte[4]);
String isHdlr = IsoTypeReader.read4cc(content);
if ("hdlr".equals(isHdlr)) {
// this is apple bullshit - it's NO FULLBOX
content.position(pos);
version = -1;
flags = -1;
} else {
content.position(pos);
version = IsoTypeReader.readUInt8(content);
flags = IsoTypeReader.readUInt24(content);
}
while (content.remaining() >= 8) {
try {
boxes.add(boxParser.parseBox(new ByteBufferByteChannel(content), this));
} catch (IOException e) {
throw new RuntimeException("Sebastian needs to fix 7518765283");
}
}
if (content.remaining() > 0) {
throw new RuntimeException("Sebastian needs to fix it 90732r26537");
}
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
if (isMp4Box()) {
IsoTypeWriter.writeUInt8(byteBuffer, version);
IsoTypeWriter.writeUInt24(byteBuffer, flags);
}
writeChildBoxes(byteBuffer);
}
public boolean isMp4Box() {
return version != -1 && flags != -1;
}
public void setMp4Box(boolean mp4) {
if (mp4) {
version = 0;
flags = 0;
} else {
version = -1;
flags = -1;
}
}
}
================================================
FILE: src/com/coremedia/iso/boxes/MovieBox.java
================================================
/*
* 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;
import com.googlecode.mp4parser.AbstractBox;
import com.googlecode.mp4parser.AbstractContainerBox;
import java.util.List;
/**
* The metadata for a presentation is stored in the single Movie Box which occurs at the top-level of a file.
* Normally this box is close to the beginning or end of the file, though this is not required.
*/
public class MovieBox extends AbstractContainerBox {
public static final String TYPE = "moov";
public MovieBox() {
super(TYPE);
}
public int getTrackCount() {
return getBoxes(TrackBox.class).size();
}
/**
* Returns the track numbers associated with this
MovieBox.
*
* @return the tracknumbers (IDs) of the tracks in their order of appearance in the file
*/
public long[] getTrackNumbers() {
List trackBoxes = this.getBoxes(TrackBox.class);
long[] trackNumbers = new long[trackBoxes.size()];
for (int trackCounter = 0; trackCounter < trackBoxes.size(); trackCounter++) {
AbstractBox trackBoxe = trackBoxes.get(trackCounter);
TrackBox trackBox = (TrackBox) trackBoxe;
trackNumbers[trackCounter] = trackBox.getTrackHeaderBox().getTrackId();
}
return trackNumbers;
}
public MovieHeaderBox getMovieHeaderBox() {
for (Box box : boxes) {
if (box instanceof MovieHeaderBox) {
return (MovieHeaderBox) box;
}
}
return null;
}
}
================================================
FILE: src/com/coremedia/iso/boxes/MovieHeaderBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
/**
*
* Box Type: 'mvhd'
* Container: {@link MovieBox} ('moov')
* Mandatory: Yes
* Quantity: Exactly one
*
* This box defines overall information which is media-independent, and relevant to the entire presentation
* considered as a whole.
*/
public class MovieHeaderBox extends AbstractFullBox {
private long creationTime;
private long modificationTime;
private long timescale;
private long duration;
private double rate = 1.0;
private float volume = 1.0f;
private long[] matrix = new long[]{0x00010000, 0, 0, 0, 0x00010000, 0, 0, 0, 0x40000000};
private long nextTrackId;
public static final String TYPE = "mvhd";
public MovieHeaderBox() {
super(TYPE);
}
public long getCreationTime() {
return creationTime;
}
public long getModificationTime() {
return modificationTime;
}
public long getTimescale() {
return timescale;
}
public long getDuration() {
return duration;
}
public double getRate() {
return rate;
}
public float getVolume() {
return volume;
}
public long[] getMatrix() {
return matrix;
}
public long getNextTrackId() {
return nextTrackId;
}
protected long getContentSize() {
long contentSize = 4;
if (getVersion() == 1) {
contentSize += 28;
} else {
contentSize += 16;
}
contentSize += 80;
return contentSize;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
if (getVersion() == 1) {
creationTime = IsoTypeReader.readUInt64(content);
modificationTime = IsoTypeReader.readUInt64(content);
timescale = IsoTypeReader.readUInt32(content);
duration = IsoTypeReader.readUInt64(content);
} else {
creationTime = IsoTypeReader.readUInt32(content);
modificationTime = IsoTypeReader.readUInt32(content);
timescale = IsoTypeReader.readUInt32(content);
duration = IsoTypeReader.readUInt32(content);
}
rate = IsoTypeReader.readFixedPoint1616(content);
volume = IsoTypeReader.readFixedPoint88(content);
IsoTypeReader.readUInt16(content);
IsoTypeReader.readUInt32(content);
IsoTypeReader.readUInt32(content);
matrix = new long[9];
for (int i = 0; i < 9; i++) {
matrix[i] = IsoTypeReader.readUInt32(content);
}
for (int i = 0; i < 6; i++) {
IsoTypeReader.readUInt32(content);
}
nextTrackId = IsoTypeReader.readUInt32(content);
}
public String toString() {
StringBuilder result = new StringBuilder();
result.append("MovieHeaderBox[");
result.append("creationTime=").append(getCreationTime());
result.append(";");
result.append("modificationTime=").append(getModificationTime());
result.append(";");
result.append("timescale=").append(getTimescale());
result.append(";");
result.append("duration=").append(getDuration());
result.append(";");
result.append("rate=").append(getRate());
result.append(";");
result.append("volume=").append(getVolume());
for (int i = 0; i < matrix.length; i++) {
result.append(";");
result.append("matrix").append(i).append("=").append(matrix[i]);
}
result.append(";");
result.append("nextTrackId=").append(getNextTrackId());
result.append("]");
return result.toString();
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
if (getVersion() == 1) {
IsoTypeWriter.writeUInt64(byteBuffer, creationTime);
IsoTypeWriter.writeUInt64(byteBuffer, modificationTime);
IsoTypeWriter.writeUInt32(byteBuffer, timescale);
IsoTypeWriter.writeUInt64(byteBuffer, duration);
} else {
IsoTypeWriter.writeUInt32(byteBuffer, creationTime);
IsoTypeWriter.writeUInt32(byteBuffer, modificationTime);
IsoTypeWriter.writeUInt32(byteBuffer, timescale);
IsoTypeWriter.writeUInt32(byteBuffer, duration);
}
IsoTypeWriter.writeFixedPont1616(byteBuffer, rate);
IsoTypeWriter.writeFixedPont88(byteBuffer, volume);
IsoTypeWriter.writeUInt16(byteBuffer, 0);
IsoTypeWriter.writeUInt32(byteBuffer, 0);
IsoTypeWriter.writeUInt32(byteBuffer, 0);
for (int i = 0; i < 9; i++) {
IsoTypeWriter.writeUInt32(byteBuffer, matrix[i]);
}
for (int i = 0; i < 6; i++) {
IsoTypeWriter.writeUInt32(byteBuffer, 0);
}
IsoTypeWriter.writeUInt32(byteBuffer, nextTrackId);
}
public void setCreationTime(long creationTime) {
this.creationTime = creationTime;
}
public void setModificationTime(long modificationTime) {
this.modificationTime = modificationTime;
}
public void setTimescale(long timescale) {
this.timescale = timescale;
}
public void setDuration(long duration) {
this.duration = duration;
}
public void setRate(double rate) {
this.rate = rate;
}
public void setVolume(float volume) {
this.volume = volume;
}
public void setMatrix(long[] matrix) {
this.matrix = matrix;
}
public void setNextTrackId(long nextTrackId) {
this.nextTrackId = nextTrackId;
}
}
================================================
FILE: src/com/coremedia/iso/boxes/NullMediaHeaderBox.java
================================================
/*
* Copyright 2011 Sebastian Annies, Hamburg, Germany
*
* 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;
import java.nio.ByteBuffer;
/**
* Streams other than visual and audio (e.g., timed metadata streams) may use a
* Null Media Header Box.
*/
public class NullMediaHeaderBox extends AbstractMediaHeaderBox {
public NullMediaHeaderBox() {
super("nmhd");
}
@Override
protected long getContentSize() {
return 4;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
}
}
================================================
FILE: src/com/coremedia/iso/boxes/ObjectDescriptorBox.java
================================================
================================================
FILE: src/com/coremedia/iso/boxes/OmaDrmAccessUnitFormatBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
/**
* Describes the format of media access units in PDCF files.
*/
public final class OmaDrmAccessUnitFormatBox extends AbstractFullBox {
public static final String TYPE = "odaf";
private boolean selectiveEncryption;
private byte allBits;
private int keyIndicatorLength;
private int initVectorLength;
protected long getContentSize() {
return 7;
}
public OmaDrmAccessUnitFormatBox() {
super("odaf");
}
public boolean isSelectiveEncryption() {
return selectiveEncryption;
}
public int getKeyIndicatorLength() {
return keyIndicatorLength;
}
public int getInitVectorLength() {
return initVectorLength;
}
public void setInitVectorLength(int initVectorLength) {
this.initVectorLength = initVectorLength;
}
public void setKeyIndicatorLength(int keyIndicatorLength) {
this.keyIndicatorLength = keyIndicatorLength;
}
public void setAllBits(byte allBits) {
this.allBits = allBits;
selectiveEncryption = (allBits & 0x80) == 0x80;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
allBits = (byte) IsoTypeReader.readUInt8(content);
selectiveEncryption = (allBits & 0x80) == 0x80;
keyIndicatorLength = IsoTypeReader.readUInt8(content);
initVectorLength = IsoTypeReader.readUInt8(content);
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeUInt8(byteBuffer, allBits);
IsoTypeWriter.writeUInt8(byteBuffer, keyIndicatorLength);
IsoTypeWriter.writeUInt8(byteBuffer, initVectorLength);
}
}
================================================
FILE: src/com/coremedia/iso/boxes/OriginalFormatBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoFile;
import com.coremedia.iso.IsoTypeReader;
import com.googlecode.mp4parser.AbstractBox;
import java.nio.ByteBuffer;
/**
* The Original Format Box contains the four-character-code of the original untransformed sample description.
* See ISO/IEC 14496-12 for details.
*
* @see ProtectionSchemeInformationBox
*/
public class OriginalFormatBox extends AbstractBox {
public static final String TYPE = "frma";
private String dataFormat = " ";
public OriginalFormatBox() {
super("frma");
}
public String getDataFormat() {
return dataFormat;
}
public void setDataFormat(String dataFormat) {
assert dataFormat.length() == 4;
this.dataFormat = dataFormat;
}
protected long getContentSize() {
return 4;
}
@Override
public void _parseDetails(ByteBuffer content) {
dataFormat = IsoTypeReader.read4cc(content);
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
byteBuffer.put(IsoFile.fourCCtoBytes(dataFormat));
}
public String toString() {
return "OriginalFormatBox[dataFormat=" + getDataFormat() + "]";
}
}
================================================
FILE: src/com/coremedia/iso/boxes/PerformerBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.coremedia.iso.Utf8;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
/**
* Used to give information about the performer. Mostly used in confunction with music files.
* See 3GPP 26.234 for details.
*/
public class PerformerBox extends AbstractFullBox {
public static final String TYPE = "perf";
private String language;
private String performer;
public PerformerBox() {
super(TYPE);
}
public String getLanguage() {
return language;
}
public String getPerformer() {
return performer;
}
public void setLanguage(String language) {
this.language = language;
}
public void setPerformer(String performer) {
this.performer = performer;
}
protected long getContentSize() {
return 6 + Utf8.utf8StringLengthInBytes(performer) + 1;
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeIso639(byteBuffer, language);
byteBuffer.put(Utf8.convert(performer));
byteBuffer.put((byte) 0);
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
language = IsoTypeReader.readIso639(content);
performer = IsoTypeReader.readString(content);
}
public String toString() {
return "PerformerBox[language=" + getLanguage() + ";performer=" + getPerformer() + "]";
}
}
================================================
FILE: src/com/coremedia/iso/boxes/ProgressiveDownloadInformationBox.java
================================================
package com.coremedia.iso.boxes;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
public class ProgressiveDownloadInformationBox extends AbstractFullBox {
List entries = Collections.emptyList();
public ProgressiveDownloadInformationBox() {
super("pdin");
}
@Override
protected long getContentSize() {
return 4 + entries.size() * 8;
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
for (Entry entry : entries) {
IsoTypeWriter.writeUInt32(byteBuffer, entry.getRate());
IsoTypeWriter.writeUInt32(byteBuffer, entry.getInitialDelay());
}
}
public List getEntries() {
return entries;
}
public void setEntries(List entries) {
this.entries = entries;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
entries = new LinkedList();
while (content.remaining() >= 8) {
Entry entry = new Entry(IsoTypeReader.readUInt32(content), IsoTypeReader.readUInt32(content));
entries.add(entry);
}
}
public static class Entry {
long rate;
long initialDelay;
public Entry(long rate, long initialDelay) {
this.rate = rate;
this.initialDelay = initialDelay;
}
public long getRate() {
return rate;
}
public void setRate(long rate) {
this.rate = rate;
}
public long getInitialDelay() {
return initialDelay;
}
public void setInitialDelay(long initialDelay) {
this.initialDelay = initialDelay;
}
@Override
public String toString() {
return "Entry{" +
"rate=" + rate +
", initialDelay=" + initialDelay +
'}';
}
}
@Override
public String toString() {
return "ProgressiveDownloadInfoBox{" +
"entries=" + entries +
'}';
}
}
================================================
FILE: src/com/coremedia/iso/boxes/ProtectionSchemeInformationBox.java
================================================
/*
* 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;
import com.googlecode.mp4parser.AbstractContainerBox;
/**
* The ProtectionSchemeInformationBox contains all the information required both
* to understand the encryption transform applied and its parameters, and also to find other
* information such as the kind and location of the key management system. It also documents the
* the original (unencrypted) format of the media. The ProtectionSchemeInformationBox
* is a container box. It is mandatory in a sample entry that uses a code idicating a
* protected stream.
*
* @see com.coremedia.iso.boxes.odf.OmaDrmKeyManagenentSystemBox
* @see com.coremedia.iso.boxes.sampleentry.AudioSampleEntry#TYPE_ENCRYPTED
* @see com.coremedia.iso.boxes.sampleentry.VisualSampleEntry#TYPE_ENCRYPTED
*/
public class ProtectionSchemeInformationBox extends AbstractContainerBox {
public static final String TYPE = "sinf";
public ProtectionSchemeInformationBox() {
super(TYPE);
}
}
================================================
FILE: src/com/coremedia/iso/boxes/RatingBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoFile;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.coremedia.iso.Utf8;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
/**
* Contained a the UserDataBox and containing information about the media's rating. E.g.
* PG13or FSK16.
*/
public class RatingBox extends AbstractFullBox {
public static final String TYPE = "rtng";
private String ratingEntity;
private String ratingCriteria;
private String language;
private String ratingInfo;
public RatingBox() {
super(TYPE);
}
public void setRatingEntity(String ratingEntity) {
this.ratingEntity = ratingEntity;
}
public void setRatingCriteria(String ratingCriteria) {
this.ratingCriteria = ratingCriteria;
}
public void setLanguage(String language) {
this.language = language;
}
public void setRatingInfo(String ratingInfo) {
this.ratingInfo = ratingInfo;
}
public String getLanguage() {
return language;
}
/**
* Gets a four-character code that indicates the rating entity grading the asset, e.g., 'BBFC'. The values of this
* field should follow common names of worldwide movie rating systems, such as those mentioned in
* [http://www.movie-ratings.net/, October 2002].
*
* @return the rating organization
*/
public String getRatingEntity() {
return ratingEntity;
}
/**
* Gets the four-character code that indicates which rating criteria are being used for the corresponding rating
* entity, e.g., 'PG13'.
*
* @return the actual rating
*/
public String getRatingCriteria() {
return ratingCriteria;
}
public String getRatingInfo() {
return ratingInfo;
}
protected long getContentSize() {
return 15 + Utf8.utf8StringLengthInBytes(ratingInfo);
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
ratingEntity = IsoTypeReader.read4cc(content);
ratingCriteria = IsoTypeReader.read4cc(content);
language = IsoTypeReader.readIso639(content);
ratingInfo = IsoTypeReader.readString(content);
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
byteBuffer.put(IsoFile.fourCCtoBytes(ratingEntity));
byteBuffer.put(IsoFile.fourCCtoBytes(ratingCriteria));
IsoTypeWriter.writeIso639(byteBuffer, language);
byteBuffer.put(Utf8.convert(ratingInfo));
byteBuffer.put((byte) 0);
}
public String toString() {
StringBuilder buffer = new StringBuilder();
buffer.append("RatingBox[language=").append(getLanguage());
buffer.append("ratingEntity=").append(getRatingEntity());
buffer.append(";ratingCriteria=").append(getRatingCriteria());
buffer.append(";language=").append(getLanguage());
buffer.append(";ratingInfo=").append(getRatingInfo());
buffer.append("]");
return buffer.toString();
}
}
================================================
FILE: src/com/coremedia/iso/boxes/RecordingYearBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
/**
*
*/
public class RecordingYearBox extends AbstractFullBox {
public static final String TYPE = "yrrc";
int recordingYear;
public RecordingYearBox() {
super(TYPE);
}
protected long getContentSize() {
return 6;
}
public int getRecordingYear() {
return recordingYear;
}
public void setRecordingYear(int recordingYear) {
this.recordingYear = recordingYear;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
recordingYear = IsoTypeReader.readUInt16(content);
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeUInt16(byteBuffer, recordingYear);
}
}
================================================
FILE: src/com/coremedia/iso/boxes/SampleAuxiliaryInformationOffsetsBox.java
================================================
/*
* Copyright 2009 castLabs GmbH, 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.coremedia.iso.boxes;
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;
/*
aligned(8) class SampleAuxiliaryInformationOffsetsBox
extends FullBox(‘saio’, version, flags)
{
if (flags & 1) {
unsigned int(32) aux_info_type;
unsigned int(32) aux_info_type_parameter;
}
unsigned int(32) entry_count;
if ( version == 0 )
{
unsigned int(32) offset[ entry_count ];
}
else
{
unsigned int(64) offset[ entry_count ];
}
}
*/
public class SampleAuxiliaryInformationOffsetsBox extends AbstractFullBox {
public static final String TYPE = "saio";
private List offsets = new LinkedList();
private long auxInfoType;
private long auxInfoTypeParameter;
public SampleAuxiliaryInformationOffsetsBox() {
super(TYPE);
}
@Override
protected long getContentSize() {
return 8 + (getVersion() == 0 ? 4 * offsets.size() : 8 * offsets.size()) + ((getFlags() & 1) == 1 ? 8 : 0);
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
if ((getFlags() & 1) == 1) {
IsoTypeWriter.writeUInt32(byteBuffer, auxInfoType);
IsoTypeWriter.writeUInt32(byteBuffer, auxInfoTypeParameter);
}
IsoTypeWriter.writeUInt32(byteBuffer, offsets.size());
for (Long offset : offsets) {
if (getVersion() == 0) {
IsoTypeWriter.writeUInt32(byteBuffer, offset);
} else {
IsoTypeWriter.writeUInt64(byteBuffer, offset);
}
}
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
if ((getFlags() & 1) == 1) {
auxInfoType = IsoTypeReader.readUInt32(content);
auxInfoTypeParameter = IsoTypeReader.readUInt32(content);
}
int entryCount = l2i(IsoTypeReader.readUInt32(content));
offsets.clear();
for (int i = 0; i < entryCount; i++) {
if (getVersion() == 0) {
offsets.add(IsoTypeReader.readUInt32(content));
} else {
offsets.add(IsoTypeReader.readUInt64(content));
}
}
}
public long getAuxInfoType() {
return auxInfoType;
}
public void setAuxInfoType(long auxInfoType) {
this.auxInfoType = auxInfoType;
}
public long getAuxInfoTypeParameter() {
return auxInfoTypeParameter;
}
public void setAuxInfoTypeParameter(long auxInfoTypeParameter) {
this.auxInfoTypeParameter = auxInfoTypeParameter;
}
public List getOffsets() {
return offsets;
}
public void setOffsets(List offsets) {
this.offsets = offsets;
}
}
================================================
FILE: src/com/coremedia/iso/boxes/SampleAuxiliaryInformationSizesBox.java
================================================
/*
* Copyright 2009 castLabs GmbH, 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.coremedia.iso.boxes;
import com.coremedia.iso.IsoFile;
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;
public class SampleAuxiliaryInformationSizesBox extends AbstractFullBox {
public static final String TYPE = "saiz";
private int defaultSampleInfoSize;
private List sampleInfoSizes = new LinkedList();
private int sampleCount;
private String auxInfoType;
private String auxInfoTypeParameter;
public SampleAuxiliaryInformationSizesBox() {
super(TYPE);
}
@Override
protected long getContentSize() {
int size = 4;
if ((getFlags() & 1) == 1) {
size += 8;
}
size += 5;
size += sampleInfoSizes.size();
return size;
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
if ((getFlags() & 1) == 1) {
byteBuffer.put(IsoFile.fourCCtoBytes(auxInfoType));
byteBuffer.put(IsoFile.fourCCtoBytes(auxInfoTypeParameter));
}
IsoTypeWriter.writeUInt8(byteBuffer, defaultSampleInfoSize);
if (defaultSampleInfoSize == 0) {
IsoTypeWriter.writeUInt32(byteBuffer, sampleInfoSizes.size());
for (short sampleInfoSize : sampleInfoSizes) {
IsoTypeWriter.writeUInt8(byteBuffer, sampleInfoSize);
}
} else {
IsoTypeWriter.writeUInt32(byteBuffer, sampleCount);
}
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
if ((getFlags() & 1) == 1) {
auxInfoType = IsoTypeReader.read4cc(content);
auxInfoTypeParameter = IsoTypeReader.read4cc(content);
}
defaultSampleInfoSize = (short) IsoTypeReader.readUInt8(content);
int sampleCount = l2i(IsoTypeReader.readUInt32(content));
sampleInfoSizes.clear();
for (int i = 0; i < sampleCount; i++) {
sampleInfoSizes.add((short) IsoTypeReader.readUInt8(content));
}
}
public String getAuxInfoType() {
return auxInfoType;
}
public void setAuxInfoType(String auxInfoType) {
this.auxInfoType = auxInfoType;
}
public String getAuxInfoTypeParameter() {
return auxInfoTypeParameter;
}
public void setAuxInfoTypeParameter(String auxInfoTypeParameter) {
this.auxInfoTypeParameter = auxInfoTypeParameter;
}
public int getDefaultSampleInfoSize() {
return defaultSampleInfoSize;
}
public void setDefaultSampleInfoSize(int defaultSampleInfoSize) {
assert defaultSampleInfoSize <= 255;
assert defaultSampleInfoSize > 0;
this.defaultSampleInfoSize = defaultSampleInfoSize;
}
public List getSampleInfoSizes() {
return sampleInfoSizes;
}
public void setSampleInfoSizes(List sampleInfoSizes) {
this.sampleInfoSizes = sampleInfoSizes;
}
public int getSampleCount() {
return sampleCount;
}
public void setSampleCount(int sampleCount) {
this.sampleCount = sampleCount;
}
}
================================================
FILE: src/com/coremedia/iso/boxes/SampleDependencyTypeBox.java
================================================
/*
* Copyright 2009 castLabs GmbH, 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.coremedia.iso.boxes;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
/**
* aligned(8) class SampleDependencyTypeBox
* extends FullBox('sdtp', version = 0, 0) {
* for (i=0; i < sample_count; i++){
* unsigned int(2) reserved = 0;
* unsigned int(2) sample_depends_on;
* unsigned int(2) sample_is_depended_on;
* unsigned int(2) sample_has_redundancy;
* }
* }
*/
public class SampleDependencyTypeBox extends AbstractFullBox {
public static final String TYPE = "sdtp";
private List entries = new ArrayList();
public static class Entry {
public Entry(int value) {
this.value = value;
}
private int value;
public int getReserved() {
return (value >> 6) & 0x03;
}
public void setReserved(int res) {
value = (res & 0x03) << 6 | value & 0x3f;
}
public int getSampleDependsOn() {
return (value >> 4) & 0x03;
}
public void setSampleDependsOn(int sdo) {
value = (sdo & 0x03) << 4 | value & 0xcf;
}
public int getSampleIsDependentOn() {
return (value >> 2) & 0x03;
}
public void setSampleIsDependentOn(int sido) {
value = (sido & 0x03) << 2 | value & 0xf3;
}
public int getSampleHasRedundancy() {
return value & 0x03;
}
public void setSampleHasRedundancy(int shr) {
value = shr & 0x03 | value & 0xfc;
}
@Override
public String toString() {
return "Entry{" +
"reserved=" + getReserved() +
", sampleDependsOn=" + getSampleDependsOn() +
", sampleIsDependentOn=" + getSampleIsDependentOn() +
", sampleHasRedundancy=" + getSampleHasRedundancy() +
'}';
}
}
public SampleDependencyTypeBox() {
super(TYPE);
}
@Override
protected long getContentSize() {
return 4 + entries.size();
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
for (Entry entry : entries) {
IsoTypeWriter.writeUInt8(byteBuffer, entry.value);
}
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
while (content.remaining() > 0) {
entries.add(new Entry(IsoTypeReader.readUInt8(content)));
}
}
public List getEntries() {
return entries;
}
public void setEntries(List entries) {
this.entries = entries;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("SampleDependencyTypeBox");
sb.append("{entries=").append(entries);
sb.append('}');
return sb.toString();
}
}
================================================
FILE: src/com/coremedia/iso/boxes/SampleDescriptionBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoTypeWriter;
import com.coremedia.iso.boxes.sampleentry.SampleEntry;
import com.googlecode.mp4parser.FullContainerBox;
import java.nio.ByteBuffer;
/**
* The sample description table gives detailed information about the coding type used, and any initialization
* information needed for that coding.
* The information stored in the sample description box after the entry-count is both track-type specific as
* documented here, and can also have variants within a track type (e.g. different codings may use different
* specific information after some common fields, even within a video track).
* For video tracks, a VisualSampleEntry is used; for audio tracks, an AudioSampleEntry. Hint tracks use an
* entry format specific to their protocol, with an appropriate name. Timed Text tracks use a TextSampleEntry
* For hint tracks, the sample description contains appropriate declarative data for the streaming protocol being
* used, and the format of the hint track. The definition of the sample description is specific to the protocol.
* Multiple descriptions may be used within a track.
* The 'protocol' and 'codingname' fields are registered identifiers that uniquely identify the streaming protocol or
* compression format decoder to be used. A given protocol or codingname may have optional or required
* extensions to the sample description (e.g. codec initialization parameters). All such extensions shall be within
* boxes; these boxes occur after the required fields. Unrecognized boxes shall be ignored.
*
* Defined in ISO/IEC 14496-12
*
* @see com.coremedia.iso.boxes.sampleentry.VisualSampleEntry
* @see com.coremedia.iso.boxes.sampleentry.TextSampleEntry
* @see com.coremedia.iso.boxes.sampleentry.AudioSampleEntry
*/
public class SampleDescriptionBox extends FullContainerBox {
public static final String TYPE = "stsd";
public SampleDescriptionBox() {
super(TYPE);
}
@Override
protected long getContentSize() {
return super.getContentSize() + 4;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
content.get(new byte[4]);
parseChildBoxes(content);
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeUInt32(byteBuffer, boxes.size());
writeChildBoxes(byteBuffer);
}
public SampleEntry getSampleEntry() {
for (Box box : boxes) {
if (box instanceof SampleEntry) {
return (SampleEntry) box;
}
}
return null;
}
}
================================================
FILE: src/com/coremedia/iso/boxes/SampleSizeBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
import static com.googlecode.mp4parser.util.CastUtils.l2i;
/**
* This box containes the sample count and a table giving the size in bytes of each sample.
* Defined in ISO/IEC 14496-12.
*/
public class SampleSizeBox extends AbstractFullBox {
private long sampleSize;
private long[] sampleSizes = new long[0];
public static final String TYPE = "stsz";
int sampleCount;
public SampleSizeBox() {
super(TYPE);
}
/**
* Returns the field sample size.
* If sampleSize > 0 every sample has the same size.
* If sampleSize == 0 the samples have different size as stated in the sampleSizes field.
*
* @return the sampleSize field
*/
public long getSampleSize() {
return sampleSize;
}
public void setSampleSize(long sampleSize) {
this.sampleSize = sampleSize;
}
public long getSampleSizeAtIndex(int index) {
if (sampleSize > 0) {
return sampleSize;
} else {
return sampleSizes[index];
}
}
public long getSampleCount() {
if (sampleSize > 0) {
return sampleCount;
} else {
return sampleSizes.length;
}
}
public long[] getSampleSizes() {
return sampleSizes;
}
public void setSampleSizes(long[] sampleSizes) {
this.sampleSizes = sampleSizes;
}
protected long getContentSize() {
return 12 + (sampleSize == 0 ? sampleSizes.length * 4 : 0);
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
sampleSize = IsoTypeReader.readUInt32(content);
sampleCount = l2i(IsoTypeReader.readUInt32(content));
if (sampleSize == 0) {
sampleSizes = new long[(int) sampleCount];
for (int i = 0; i < sampleCount; i++) {
sampleSizes[i] = IsoTypeReader.readUInt32(content);
}
}
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeUInt32(byteBuffer, sampleSize);
if (sampleSize == 0) {
IsoTypeWriter.writeUInt32(byteBuffer, sampleSizes.length);
for (long sampleSize1 : sampleSizes) {
IsoTypeWriter.writeUInt32(byteBuffer, sampleSize1);
}
} else {
IsoTypeWriter.writeUInt32(byteBuffer, sampleCount);
}
}
public String toString() {
return "SampleSizeBox[sampleSize=" + getSampleSize() + ";sampleCount=" + getSampleCount() + "]";
}
}
================================================
FILE: src/com/coremedia/iso/boxes/SampleTableBox.java
================================================
/*
* 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;
import com.googlecode.mp4parser.AbstractContainerBox;
/**
* The sample table contains all the time and data indexing of the media samples in a track. Using the tables
* here, it is possible to locate samples in time, determine their type (e.g. I-frame or not), and determine their
* size, container, and offset into that container.
* If the track that contains the Sample Table Box references no data, then the Sample Table Box does not need
* to contain any sub-boxes (this is not a very useful media track).
* If the track that the Sample Table Box is contained in does reference data, then the following sub-boxes are
* required: Sample Description, Sample Size, Sample To Chunk, and Chunk Offset. Further, the Sample
* Description Box shall contain at least one entry. A Sample Description Box is required because it contains the
* data reference index field which indicates which Data Reference Box to use to retrieve the media samples.
* Without the Sample Description, it is not possible to determine where the media samples are stored. The Sync
* Sample Box is optional. If the Sync Sample Box is not present, all samples are sync samples.
* Annex A provides a narrative description of random access using the structures defined in the Sample Table
* Box.
*/
public class SampleTableBox extends AbstractContainerBox {
public static final String TYPE = "stbl";
public SampleTableBox() {
super(TYPE);
}
public SampleDescriptionBox getSampleDescriptionBox() {
for (Box box : boxes) {
if (box instanceof SampleDescriptionBox) {
return (SampleDescriptionBox) box;
}
}
return null;
}
public SampleSizeBox getSampleSizeBox() {
for (Box box : boxes) {
if (box instanceof SampleSizeBox) {
return (SampleSizeBox) box;
}
}
return null;
}
public SampleToChunkBox getSampleToChunkBox() {
for (Box box : boxes) {
if (box instanceof SampleToChunkBox) {
return (SampleToChunkBox) box;
}
}
return null;
}
public ChunkOffsetBox getChunkOffsetBox() {
for (Box box : boxes) {
if (box instanceof ChunkOffsetBox) {
return (ChunkOffsetBox) box;
}
}
return null;
}
public void setChunkOffsetBox(ChunkOffsetBox b) {
for (int i = 0; i < boxes.size(); i++) {
Box box = boxes.get(i);
if (box instanceof ChunkOffsetBox) {
boxes.set(i, b);
}
}
}
public TimeToSampleBox getTimeToSampleBox() {
for (Box box : boxes) {
if (box instanceof TimeToSampleBox) {
return (TimeToSampleBox) box;
}
}
return null;
}
public SyncSampleBox getSyncSampleBox() {
for (Box box : boxes) {
if (box instanceof SyncSampleBox) {
return (SyncSampleBox) box;
}
}
return null;
}
public CompositionTimeToSample getCompositionTimeToSample() {
for (Box box : boxes) {
if (box instanceof CompositionTimeToSample) {
return (CompositionTimeToSample) box;
}
}
return null;
}
public SampleDependencyTypeBox getSampleDependencyTypeBox() {
for (Box box : boxes) {
if (box instanceof SampleDependencyTypeBox) {
return (SampleDependencyTypeBox) box;
}
}
return null;
}
}
================================================
FILE: src/com/coremedia/iso/boxes/SampleToChunkBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import static com.googlecode.mp4parser.util.CastUtils.l2i;
/**
* Samples within the media data are grouped into chunks. Chunks can be of different sizes, and the
* samples within a chunk can have different sizes. This table can be used to find the chunk that
* contains a sample, its position, and the associated sample description. Defined in ISO/IEC 14496-12.
*/
public class SampleToChunkBox extends AbstractFullBox {
List entries = Collections.emptyList();
public static final String TYPE = "stsc";
public SampleToChunkBox() {
super(TYPE);
}
public List getEntries() {
return entries;
}
public void setEntries(List entries) {
this.entries = entries;
}
protected long getContentSize() {
return entries.size() * 12 + 8;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
int entryCount = l2i(IsoTypeReader.readUInt32(content));
entries = new ArrayList(entryCount);
for (int i = 0; i < entryCount; i++) {
entries.add(new Entry(
IsoTypeReader.readUInt32(content),
IsoTypeReader.readUInt32(content),
IsoTypeReader.readUInt32(content)));
}
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeUInt32(byteBuffer, entries.size());
for (Entry entry : entries) {
IsoTypeWriter.writeUInt32(byteBuffer, entry.getFirstChunk());
IsoTypeWriter.writeUInt32(byteBuffer, entry.getSamplesPerChunk());
IsoTypeWriter.writeUInt32(byteBuffer, entry.getSampleDescriptionIndex());
}
}
public String toString() {
return "SampleToChunkBox[entryCount=" + entries.size() + "]";
}
/**
* Decompresses the list of entries and returns the number of samples per chunk for
* every single chunk.
*
* @param chunkCount overall number of chunks
* @return number of samples per chunk
*/
public long[] blowup(int chunkCount) {
long[] numberOfSamples = new long[chunkCount];
int j = 0;
List sampleToChunkEntries = new LinkedList(entries);
Collections.reverse(sampleToChunkEntries);
Iterator iterator = sampleToChunkEntries.iterator();
SampleToChunkBox.Entry currentEntry = iterator.next();
for (int i = numberOfSamples.length; i > 1; i--) {
numberOfSamples[i - 1] = currentEntry.getSamplesPerChunk();
if (i == currentEntry.getFirstChunk()) {
currentEntry = iterator.next();
}
}
numberOfSamples[0] = currentEntry.getSamplesPerChunk();
return numberOfSamples;
}
public static class Entry {
long firstChunk;
long samplesPerChunk;
long sampleDescriptionIndex;
public Entry(long firstChunk, long samplesPerChunk, long sampleDescriptionIndex) {
this.firstChunk = firstChunk;
this.samplesPerChunk = samplesPerChunk;
this.sampleDescriptionIndex = sampleDescriptionIndex;
}
public long getFirstChunk() {
return firstChunk;
}
public void setFirstChunk(long firstChunk) {
this.firstChunk = firstChunk;
}
public long getSamplesPerChunk() {
return samplesPerChunk;
}
public void setSamplesPerChunk(long samplesPerChunk) {
this.samplesPerChunk = samplesPerChunk;
}
public long getSampleDescriptionIndex() {
return sampleDescriptionIndex;
}
public void setSampleDescriptionIndex(long sampleDescriptionIndex) {
this.sampleDescriptionIndex = sampleDescriptionIndex;
}
@Override
public String toString() {
return "Entry{" +
"firstChunk=" + firstChunk +
", samplesPerChunk=" + samplesPerChunk +
", sampleDescriptionIndex=" + sampleDescriptionIndex +
'}';
}
}
}
================================================
FILE: src/com/coremedia/iso/boxes/SampleToGroupBox.java
================================================
package com.coremedia.iso.boxes;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
/**
* aligned(8) class SampleToGroupBox
* extends FullBox('sbgp', version = 0, 0)
* {
* unsigned int(32) grouping_type;
* unsigned int(32) entry_count;
* for (i=1; i <= entry_count; i++)
* {
* unsigned int(32) sample_count;
* unsigned int(32) group_description_index;
* }
* }
*/
public class SampleToGroupBox extends AbstractFullBox {
public static final String TYPE = "sbgp";
private long groupingType;
private long entryCount;
private long groupingTypeParameter;
private List entries = new ArrayList();
public SampleToGroupBox() {
super(TYPE);
}
@Override
protected long getContentSize() {
return 12 + entryCount * 8;
}
public long getGroupingTypeParameter() {
return groupingTypeParameter;
}
/**
* Usage of this parameter requires version == 1. The version must be set manually.
*/
public void setGroupingTypeParameter(long groupingTypeParameter) {
this.groupingTypeParameter = groupingTypeParameter;
}
public List getEntries() {
return entries;
}
public void setEntries(List entries) {
this.entries = entries;
}
public long getGroupingType() {
return groupingType;
}
public void setGroupingType(long groupingType) {
this.groupingType = groupingType;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
groupingType = IsoTypeReader.readUInt32(content);
if (getVersion() == 1) {
groupingTypeParameter = IsoTypeReader.readUInt32(content);
} else {
groupingTypeParameter = -1;
}
entryCount = IsoTypeReader.readUInt32(content);
for (int i = 0; i < entryCount; i++) {
Entry entry = new Entry();
entry.setSampleCount(IsoTypeReader.readUInt32(content));
entry.setGroupDescriptionIndex(IsoTypeReader.readUInt32(content));
entries.add(entry);
}
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeUInt32(byteBuffer, groupingType);
if (getVersion() == 1) {
IsoTypeWriter.writeUInt32(byteBuffer, groupingTypeParameter);
}
IsoTypeWriter.writeUInt32(byteBuffer, entryCount);
for (Entry entry : entries) {
IsoTypeWriter.writeUInt32(byteBuffer, entry.getSampleCount());
IsoTypeWriter.writeUInt32(byteBuffer, entry.getGroupDescriptionIndex());
}
}
public static class Entry {
private long sampleCount;
private long groupDescriptionIndex;
public long getSampleCount() {
return sampleCount;
}
public void setSampleCount(long sampleCount) {
this.sampleCount = sampleCount;
}
public long getGroupDescriptionIndex() {
return groupDescriptionIndex;
}
public void setGroupDescriptionIndex(long groupDescriptionIndex) {
this.groupDescriptionIndex = groupDescriptionIndex;
}
}
}
================================================
FILE: src/com/coremedia/iso/boxes/SchemeInformationBox.java
================================================
/*
* 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;
import com.googlecode.mp4parser.AbstractContainerBox;
/**
* The Scheme Information Box is a container box that is only interpreted by the scheme beeing used.
* Any information the encryption system needs is stored here. The content of this box is a series of
* boxexes whose type annd format are defined by the scheme declared in the {@link com.coremedia.iso.boxes.SchemeTypeBox}.
*/
public class SchemeInformationBox extends AbstractContainerBox {
public static final String TYPE = "schi";
public SchemeInformationBox() {
super(TYPE);
}
}
================================================
FILE: src/com/coremedia/iso/boxes/SchemeTypeBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoFile;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.coremedia.iso.Utf8;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
/**
* The Scheme Type Box identifies the protection scheme. Resides in a Protection Scheme Information Box or
* an SRTP Process Box.
*
* @see com.coremedia.iso.boxes.SchemeInformationBox
*/
public class SchemeTypeBox extends AbstractFullBox {
public static final String TYPE = "schm";
String schemeType = " ";
long schemeVersion;
String schemeUri = null;
public SchemeTypeBox() {
super(TYPE);
}
public String getSchemeType() {
return schemeType;
}
public long getSchemeVersion() {
return schemeVersion;
}
public String getSchemeUri() {
return schemeUri;
}
public void setSchemeType(String schemeType) {
assert schemeType != null && schemeType.length() == 4 : "SchemeType may not be null or not 4 bytes long";
this.schemeType = schemeType;
}
public void setSchemeVersion(int schemeVersion) {
this.schemeVersion = schemeVersion;
}
public void setSchemeUri(String schemeUri) {
this.schemeUri = schemeUri;
}
protected long getContentSize() {
return 12 + (((getFlags() & 1) == 1) ? Utf8.utf8StringLengthInBytes(schemeUri) + 1 : 0);
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
schemeType = IsoTypeReader.read4cc(content);
schemeVersion = IsoTypeReader.readUInt32(content);
if ((getFlags() & 1) == 1) {
schemeUri = IsoTypeReader.readString(content);
}
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
byteBuffer.put(IsoFile.fourCCtoBytes(schemeType));
IsoTypeWriter.writeUInt32(byteBuffer, schemeVersion);
if ((getFlags() & 1) == 1) {
byteBuffer.put(Utf8.convert(schemeUri));
}
}
public String toString() {
StringBuilder buffer = new StringBuilder();
buffer.append("Schema Type Box[");
buffer.append("schemeUri=").append(schemeUri).append("; ");
buffer.append("schemeType=").append(schemeType).append("; ");
buffer.append("schemeVersion=").append(schemeUri).append("; ");
buffer.append("]");
return buffer.toString();
}
}
================================================
FILE: src/com/coremedia/iso/boxes/SoundMediaHeaderBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import java.nio.ByteBuffer;
public class SoundMediaHeaderBox extends AbstractMediaHeaderBox {
public static final String TYPE = "smhd";
private float balance;
public SoundMediaHeaderBox() {
super(TYPE);
}
public float getBalance() {
return balance;
}
protected long getContentSize() {
return 8;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
balance = IsoTypeReader.readFixedPoint88(content);
IsoTypeReader.readUInt16(content);
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeFixedPont88(byteBuffer, balance);
IsoTypeWriter.writeUInt16(byteBuffer, 0);
}
public String toString() {
return "SoundMediaHeaderBox[balance=" + getBalance() + "]";
}
}
================================================
FILE: src/com/coremedia/iso/boxes/StaticChunkOffsetBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import java.nio.ByteBuffer;
import static com.googlecode.mp4parser.util.CastUtils.l2i;
/**
* The chunk offset table gives the index of each chunk into the containing file. Defined in ISO/IEC 14496-12.
*/
public class StaticChunkOffsetBox extends ChunkOffsetBox {
public static final String TYPE = "stco";
private long[] chunkOffsets = new long[0];
public StaticChunkOffsetBox() {
super(TYPE);
}
public long[] getChunkOffsets() {
return chunkOffsets;
}
protected long getContentSize() {
return 8 + chunkOffsets.length * 4;
}
public void setChunkOffsets(long[] chunkOffsets) {
this.chunkOffsets = chunkOffsets;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
int entryCount = l2i(IsoTypeReader.readUInt32(content));
chunkOffsets = new long[entryCount];
for (int i = 0; i < entryCount; i++) {
chunkOffsets[i] = IsoTypeReader.readUInt32(content);
}
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeUInt32(byteBuffer, chunkOffsets.length);
for (long chunkOffset : chunkOffsets) {
IsoTypeWriter.writeUInt32(byteBuffer, chunkOffset);
}
}
}
================================================
FILE: src/com/coremedia/iso/boxes/SubSampleInformationBox.java
================================================
package com.coremedia.iso.boxes;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import static com.googlecode.mp4parser.util.CastUtils.l2i;
/**
* aligned(8) class SubSampleInformationBox
* extends FullBox('subs', version, 0) {
* unsigned int(32) entry_count;
* int i,j;
* for (i=0; i < entry_count; i++) {
* unsigned int(32) sample_delta;
* unsigned int(16) subsample_count;
* if (subsample_count > 0) {
* for (j=0; j < subsample_count; j++) {
* if(version == 1)
* {
* unsigned int(32) subsample_size;
* }
* else
* {
* unsigned int(16) subsample_size;
* }
* unsigned int(8) subsample_priority;
* unsigned int(8) discardable;
* unsigned int(32) reserved = 0;
* }
* }
* }
* }
*/
public class SubSampleInformationBox extends AbstractFullBox {
public static final String TYPE = "subs";
private long entryCount;
private List entries = new ArrayList();
public SubSampleInformationBox() {
super(TYPE);
}
public List getEntries() {
return entries;
}
public void setEntries(List entries) {
this.entries = entries;
entryCount = entries.size();
}
@Override
protected long getContentSize() {
long entries = 8 + ((4 + 2) * entryCount);
int subsampleEntries = 0;
for (SampleEntry sampleEntry : this.entries) {
subsampleEntries += sampleEntry.getSubsampleCount() * (((getVersion() == 1) ? 4 : 2) + 1 + 1 + 4);
}
return entries + subsampleEntries;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
entryCount = IsoTypeReader.readUInt32(content);
for (int i = 0; i < entryCount; i++) {
SampleEntry sampleEntry = new SampleEntry();
sampleEntry.setSampleDelta(IsoTypeReader.readUInt32(content));
int subsampleCount = IsoTypeReader.readUInt16(content);
for (int j = 0; j < subsampleCount; j++) {
SampleEntry.SubsampleEntry subsampleEntry = new SampleEntry.SubsampleEntry();
subsampleEntry.setSubsampleSize(getVersion() == 1 ? IsoTypeReader.readUInt32(content) : IsoTypeReader.readUInt16(content));
subsampleEntry.setSubsamplePriority(IsoTypeReader.readUInt8(content));
subsampleEntry.setDiscardable(IsoTypeReader.readUInt8(content));
subsampleEntry.setReserved(IsoTypeReader.readUInt32(content));
sampleEntry.addSubsampleEntry(subsampleEntry);
}
entries.add(sampleEntry);
}
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeUInt32(byteBuffer, entries.size());
for (SampleEntry sampleEntry : entries) {
IsoTypeWriter.writeUInt32(byteBuffer, sampleEntry.getSampleDelta());
IsoTypeWriter.writeUInt16(byteBuffer, sampleEntry.getSubsampleCount());
List subsampleEntries = sampleEntry.getSubsampleEntries();
for (SampleEntry.SubsampleEntry subsampleEntry : subsampleEntries) {
if (getVersion() == 1) {
IsoTypeWriter.writeUInt32(byteBuffer, subsampleEntry.getSubsampleSize());
} else {
IsoTypeWriter.writeUInt16(byteBuffer, l2i(subsampleEntry.getSubsampleSize()));
}
IsoTypeWriter.writeUInt8(byteBuffer, subsampleEntry.getSubsamplePriority());
IsoTypeWriter.writeUInt8(byteBuffer, subsampleEntry.getDiscardable());
IsoTypeWriter.writeUInt32(byteBuffer, subsampleEntry.getReserved());
}
}
}
@Override
public String toString() {
return "SubSampleInformationBox{" +
"entryCount=" + entryCount +
", entries=" + entries +
'}';
}
public static class SampleEntry {
private long sampleDelta;
private int subsampleCount;
private List subsampleEntries = new ArrayList();
public long getSampleDelta() {
return sampleDelta;
}
public void setSampleDelta(long sampleDelta) {
this.sampleDelta = sampleDelta;
}
public int getSubsampleCount() {
return subsampleCount;
}
public void setSubsampleCount(int subsampleCount) {
this.subsampleCount = subsampleCount;
}
public List getSubsampleEntries() {
return subsampleEntries;
}
public void addSubsampleEntry(SubsampleEntry subsampleEntry) {
subsampleEntries.add(subsampleEntry);
subsampleCount++;
}
public static class SubsampleEntry {
private long subsampleSize;
private int subsamplePriority;
private int discardable;
private long reserved;
public long getSubsampleSize() {
return subsampleSize;
}
public void setSubsampleSize(long subsampleSize) {
this.subsampleSize = subsampleSize;
}
public int getSubsamplePriority() {
return subsamplePriority;
}
public void setSubsamplePriority(int subsamplePriority) {
this.subsamplePriority = subsamplePriority;
}
public int getDiscardable() {
return discardable;
}
public void setDiscardable(int discardable) {
this.discardable = discardable;
}
public long getReserved() {
return reserved;
}
public void setReserved(long reserved) {
this.reserved = reserved;
}
@Override
public String toString() {
return "SubsampleEntry{" +
"subsampleSize=" + subsampleSize +
", subsamplePriority=" + subsamplePriority +
", discardable=" + discardable +
", reserved=" + reserved +
'}';
}
}
@Override
public String toString() {
return "SampleEntry{" +
"sampleDelta=" + sampleDelta +
", subsampleCount=" + subsampleCount +
", subsampleEntries=" + subsampleEntries +
'}';
}
}
}
================================================
FILE: src/com/coremedia/iso/boxes/SubtitleMediaHeaderBox.java
================================================
package com.coremedia.iso.boxes;
import java.nio.ByteBuffer;
public class SubtitleMediaHeaderBox extends AbstractMediaHeaderBox {
public static final String TYPE = "sthd";
public SubtitleMediaHeaderBox() {
super(TYPE);
}
protected long getContentSize() {
return 4;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
}
public String toString() {
return "SubtitleMediaHeaderBox";
}
}
================================================
FILE: src/com/coremedia/iso/boxes/SyncSampleBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
import static com.googlecode.mp4parser.util.CastUtils.l2i;
/**
* This box provides a compact marking of the random access points withinthe stream. The table is arranged in
* strictly decreasinf order of sample number. Defined in ISO/IEC 14496-12.
*/
public class SyncSampleBox extends AbstractFullBox {
public static final String TYPE = "stss";
private long[] sampleNumber;
public SyncSampleBox() {
super(TYPE);
}
/**
* Gives the numbers of the samples that are random access points in the stream.
*
* @return random access sample numbers.
*/
public long[] getSampleNumber() {
return sampleNumber;
}
protected long getContentSize() {
return sampleNumber.length * 4 + 8;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
int entryCount = l2i(IsoTypeReader.readUInt32(content));
sampleNumber = new long[entryCount];
for (int i = 0; i < entryCount; i++) {
sampleNumber[i] = IsoTypeReader.readUInt32(content);
}
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeUInt32(byteBuffer, sampleNumber.length);
for (long aSampleNumber : sampleNumber) {
IsoTypeWriter.writeUInt32(byteBuffer, aSampleNumber);
}
}
public String toString() {
return "SyncSampleBox[entryCount=" + sampleNumber.length + "]";
}
public void setSampleNumber(long[] sampleNumber) {
this.sampleNumber = sampleNumber;
}
}
================================================
FILE: src/com/coremedia/iso/boxes/TimeToSampleBox.java
================================================
/*
* 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;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static com.googlecode.mp4parser.util.CastUtils.l2i;
/**
* This box contains a compact version of a table that allows indexing from decoding time to sample number.
* Other tables give sample sizes and pointers, from the sample number. Each entry in the table gives the
* number of consecutive samples with the same time delta, and the delta of those samples. By adding the
* deltas a complete time-to-sample map may be built.
* The Decoding Time to Sample Box contains decode time delta's: DT(n+1) = DT(n) + STTS(n) where STTS(n)
* is the (uncompressed) table entry for sample n.
* The sample entries are ordered by decoding time stamps; therefore the deltas are all non-negative.
* The DT axis has a zero origin; DT(i) = SUM(for j=0 to i-1 of delta(j)), and the sum of all
* deltas gives the length of the media in the track (not mapped to the overall timescale, and not considering
* any edit list).
* The Edit List Box provides the initial CT value if it is non-empty (non-zero).
*/
public class TimeToSampleBox extends AbstractFullBox {
public static final String TYPE = "stts";
List entries = Collections.emptyList();
public TimeToSampleBox() {
super(TYPE);
}
protected long getContentSize() {
return 8 + entries.size() * 8;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
int entryCount = l2i(IsoTypeReader.readUInt32(content));
entries = new ArrayList(entryCount);
for (int i = 0; i < entryCount; i++) {
entries.add(new Entry(IsoTypeReader.readUInt32(content), IsoTypeReader.readUInt32(content)));
}
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeUInt32(byteBuffer, entries.size());
for (Entry entry : entries) {
IsoTypeWriter.writeUInt32(byteBuffer, entry.getCount());
IsoTypeWriter.writeUInt32(byteBuffer, entry.getDelta());
}
}
public List getEntries() {
return entries;
}
public void setEntries(List entries) {
this.entries = entries;
}
public String toString() {
return "TimeToSampleBox[entryCount=" + entries.size() + "]";
}
public static class Entry {
long count;
long delta;
public Entry(long count, long delta) {
this.count = count;
this.delta = delta;
}
public long getCount() {
return count;
}
public long getDelta() {
return delta;
}
public void setCount(long count) {
this.count = count;
}
public void setDelta(long delta) {
this.delta = delta;
}
@Override
public String toString() {
return "Entry{" +
"count=" + count +
", delta=" + delta +
'}';
}
}
/**
* Decompresses the list of entries and returns the list of decoding times.
*
* @return decoding time per sample
*/
public static long[] blowupTimeToSamples(List