Add new files for mp4 parser

Signed-off-by: Leo Ma <begeekmyfriend@gmail.com>
camera2
Leo Ma 8 years ago
parent 4b67a0640f
commit 027335249b

@ -0,0 +1,47 @@
/*
* 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 <code>byte[]</code> -> <code>String</code> and vice versa.
*/
public final class Ascii {
public static byte[] convert(String s) {
try {
if (s != null) {
return s.getBytes("us-ascii");
} else {
return null;
}
} catch (UnsupportedEncodingException e) {
throw new Error(e);
}
}
public static String convert(byte[] b) {
try {
if (b != null) {
return new String(b, "us-ascii");
} else {
return null;
}
} catch (UnsupportedEncodingException e) {
throw new Error(e);
}
}
}

@ -0,0 +1,39 @@
/*
* 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.nio.ByteBuffer;
public final class IsoTypeReaderVariable {
public static long read(ByteBuffer bb, int bytes) {
switch (bytes) {
case 1:
return IsoTypeReader.readUInt8(bb);
case 2:
return IsoTypeReader.readUInt16(bb);
case 3:
return IsoTypeReader.readUInt24(bb);
case 4:
return IsoTypeReader.readUInt32(bb);
case 8:
return IsoTypeReader.readUInt64(bb);
default:
throw new RuntimeException("I don't know how to read " + bytes + " bytes");
}
}
}

@ -0,0 +1,45 @@
/*
* 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.IOException;
import java.nio.ByteBuffer;
public final class IsoTypeWriterVariable {
public static void write(long v, ByteBuffer bb, int bytes) {
switch (bytes) {
case 1:
IsoTypeWriter.writeUInt8(bb, (int) (v & 0xff));
break;
case 2:
IsoTypeWriter.writeUInt16(bb, (int) (v & 0xffff));
break;
case 3:
IsoTypeWriter.writeUInt24(bb, (int) (v & 0xffffff));
break;
case 4:
IsoTypeWriter.writeUInt32(bb, v);
break;
case 8:
IsoTypeWriter.writeUInt64(bb, v);
break;
default:
throw new RuntimeException("I don't know how to read " + bytes + " bytes");
}
}
}

@ -0,0 +1,112 @@
/*
* 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();
}
}

@ -0,0 +1,94 @@
/*
* 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() + "]";
}
}

@ -0,0 +1,91 @@
/*
* 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;
/**
* <code>class BitRateBox extends Box('btrt') {<br/>
* unsigned int(32) bufferSizeDB;<br/>
* // gives the size of the decoding buffer for<br/>
* // the elementary stream in bytes.<br/>
* unsigned int(32) maxBitrate;<br/>
* // gives the maximum rate in bits/second <br/>
* // over any window of one second.<br/>
* unsigned int(32) avgBitrate;<br/>
* // avgBitrate gives the average rate in <br/>
* // bits/second over the entire presentation.<br/>
* }</code>
*/
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;
}
}

@ -0,0 +1,51 @@
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);
}
}
}

@ -0,0 +1,110 @@
/*
* 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();
}
}

@ -0,0 +1,101 @@
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;
}
}

@ -0,0 +1,86 @@
/*
* 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() + "]";
}
}

@ -0,0 +1,69 @@
/*
* 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() + "]";
}
}

@ -0,0 +1,77 @@
/*
* 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;
}
}

@ -0,0 +1,34 @@
/*
* 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);
}
}

@ -0,0 +1,248 @@
/*
* 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;
/**
* <code>
* Box Type : 'elst'<br>
* Container: {@link EditBox}('edts')<br>
* Mandatory: No<br>
* Quantity : Zero or one</code><br><br>
* 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.<br>
* 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. <br>
* 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:<br>
* <p/>
* <li>Entry-count = 2</li>
* <li>Segment-duration = 10 seconds</li>
* <li>Media-Time = -1</li>
* <li>Media-Rate = 1</li>
* <li>Segment-duration = 30 seconds (could be the length of the whole track)</li>
* <li>Media-Time = 0 seconds</li>
* <li>Media-Rate = 1</li>
*/
public class EditListBox extends AbstractFullBox {
private List<Entry> entries = new LinkedList<Entry>();
public static final String TYPE = "elst";
public EditListBox() {
super(TYPE);
}
public List<Entry> getEntries() {
return entries;
}
public void setEntries(List<Entry> 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<Entry>();
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 <code>Entry</code> 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.writeFixedPoint1616(bb, mediaRate);
}
@Override
public String toString() {
return "Entry{" +
"segmentDuration=" + segmentDuration +
", mediaTime=" + mediaTime +
", mediaRate=" + mediaRate +
'}';
}
}
}

@ -0,0 +1,114 @@
/*
* 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.ChannelHelper;
import com.coremedia.iso.IsoTypeWriter;
import com.googlecode.mp4parser.AbstractBox;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.LinkedList;
import java.util.List;
import static com.googlecode.mp4parser.util.CastUtils.l2i;
/**
* A free box. Just a placeholder to enable editing without rewriting the whole file.
*/
public class FreeBox implements Box {
public static final String TYPE = "free";
ByteBuffer data;
List<Box> replacers = new LinkedList<Box>();
private ContainerBox parent;
public FreeBox() {
}
public FreeBox(int size) {
this.data = ByteBuffer.allocate(size);
}
public ByteBuffer getData() {
return data;
}
public void setData(ByteBuffer data) {
this.data = data;
}
public void getBox(WritableByteChannel os) throws IOException {
for (Box replacer : replacers) {
replacer.getBox(os);
}
ByteBuffer header = ByteBuffer.allocate(8);
IsoTypeWriter.writeUInt32(header, 8 + data.limit());
header.put(TYPE.getBytes());
header.rewind();
os.write(header);
data.rewind();
os.write(data);
}
public ContainerBox getParent() {
return parent;
}
public void setParent(ContainerBox parent) {
this.parent = parent;
}
public long getSize() {
long size = 8;
for (Box replacer : replacers) {
size += replacer.getSize();
}
size += data.limit();
return size;
}
public String getType() {
return TYPE;
}
public void parse(ReadableByteChannel readableByteChannel, ByteBuffer header, long contentSize, BoxParser boxParser) throws IOException {
if (readableByteChannel instanceof FileChannel && contentSize > 1024 * 1024) {
// It's quite expensive to map a file into the memory. Just do it when the box is larger than a MB.
data = ((FileChannel) readableByteChannel).map(FileChannel.MapMode.READ_ONLY, ((FileChannel) readableByteChannel).position(), contentSize);
((FileChannel) readableByteChannel).position(((FileChannel) readableByteChannel).position() + contentSize);
} else {
assert contentSize < Integer.MAX_VALUE;
data = ChannelHelper.readFully(readableByteChannel, contentSize);
}
}
public void addAndReplace(Box box) {
data.position(l2i(box.getSize()));
data = data.slice();
replacers.add(box);
}
}

@ -0,0 +1,63 @@
/*
* 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() + "]";
}
}

@ -0,0 +1,80 @@
/*
* 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 <code>UserDataBox</code>.
*
* @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() + "]";
}
}

@ -0,0 +1,91 @@
/*
* 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 +
'}';
}
}

@ -0,0 +1,43 @@
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);
}
}

@ -0,0 +1,360 @@
/*
* 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<item_count; i++) {
* unsigned int(16) item_ID;
* if (version == 1) {
* unsigned int(12) reserved = 0;
* unsigned int(4) construction_method;
* }
* unsigned int(16) data_reference_index;
* unsigned int(base_offset_size*8) base_offset;
* unsigned int(16) extent_count;
* for (j=0; j<extent_count; j++) {
* if ((version == 1) && (index_size > 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<Item> items = new LinkedList<Item>();
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<Item> getItems() {
return items;
}
public void setItems(List<Item> items) {
this.items = items;
}
public Item createItem(int itemId, int constructionMethod, int dataReferenceIndex, long baseOffset, List<Extent> 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<Extent> extents = new LinkedList<Extent>();
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<Extent> 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();
}
}
}

@ -0,0 +1,61 @@
/*
* 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);
}
}

@ -0,0 +1,95 @@
/*
* 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();
}
}

@ -0,0 +1,113 @@
/*
* 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;
}
}
}

@ -0,0 +1,43 @@
/*
* 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);
}
}

@ -0,0 +1,87 @@
/*
* 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);
}
}

@ -0,0 +1,69 @@
/*
* 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() + "]";
}
}

@ -0,0 +1,78 @@
/*
* 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() + "]";
}
}

@ -0,0 +1,95 @@
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<Entry> 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<Entry> getEntries() {
return entries;
}
public void setEntries(List<Entry> entries) {
this.entries = entries;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
entries = new LinkedList<Entry>();
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 +
'}';
}
}

@ -0,0 +1,42 @@
/*
* 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 <code>ProtectionSchemeInformationBox</code> 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 <code>ProtectionSchemeInformationBox</code>
* 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);
}
}

@ -0,0 +1,124 @@
/*
* 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 <code>UserDataBox</code> 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();
}
}

@ -0,0 +1,63 @@
/*
* 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);
}
}

@ -0,0 +1,127 @@
/*
* 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<Long> offsets = new LinkedList<Long>();
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<Long> getOffsets() {
return offsets;
}
public void setOffsets(List<Long> offsets) {
this.offsets = offsets;
}
}

@ -0,0 +1,145 @@
/*
* 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<Short> sampleInfoSizes = new LinkedList<Short>();
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 += defaultSampleInfoSize == 0 ? sampleInfoSizes.size() : 0;
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);
sampleCount = l2i(IsoTypeReader.readUInt32(content));
sampleInfoSizes.clear();
if (defaultSampleInfoSize == 0) {
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;
this.defaultSampleInfoSize = defaultSampleInfoSize;
}
public List<Short> getSampleInfoSizes() {
return sampleInfoSizes;
}
public void setSampleInfoSizes(List<Short> sampleInfoSizes) {
this.sampleInfoSizes = sampleInfoSizes;
}
public int getSampleCount() {
return sampleCount;
}
public void setSampleCount(int sampleCount) {
this.sampleCount = sampleCount;
}
@Override
public String toString() {
return "SampleAuxiliaryInformationSizesBox{" +
"defaultSampleInfoSize=" + defaultSampleInfoSize +
", sampleCount=" + sampleCount +
", auxInfoType='" + auxInfoType + '\'' +
", auxInfoTypeParameter='" + auxInfoTypeParameter + '\'' +
'}';
}
}

@ -0,0 +1,33 @@
/*
* 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);
}
}

@ -0,0 +1,101 @@
/*
* Copyright 2008 CoreMedia AG, Hamburg
*
* Licensed under the Apache License, Version 2.0 (the License);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.coremedia.iso.boxes;
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();
}
}

@ -0,0 +1,208 @@
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<SampleEntry> entries = new ArrayList<SampleEntry>();
public SubSampleInformationBox() {
super(TYPE);
}
public List<SampleEntry> getEntries() {
return entries;
}
public void setEntries(List<SampleEntry> 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<SampleEntry.SubsampleEntry> 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<SubsampleEntry> subsampleEntries = new ArrayList<SubsampleEntry>();
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<SubsampleEntry> 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 +
'}';
}
}
}

@ -0,0 +1,30 @@
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";
}
}

@ -0,0 +1,89 @@
/*
* 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;
/**
* <code>
* Box Type: 'titl'<br>
* Container: {@link UserDataBox} ('udta')<br>
* Mandatory: No<br>
* Quantity: Zero or one<br><br>
* </code>
* <p/>
* Title for the media.
*/
public class TitleBox extends AbstractFullBox {
public static final String TYPE = "titl";
private String language;
private String title;
public TitleBox() {
super(TYPE);
}
public String getLanguage() {
return language;
}
public String getTitle() {
return title;
}
/**
* Sets the 3-letter ISO-639 language for this title.
*
* @param language 3-letter ISO-639 code
*/
public void setLanguage(String language) {
this.language = language;
}
public void setTitle(String title) {
this.title = title;
}
protected long getContentSize() {
return 7 + Utf8.utf8StringLengthInBytes(title);
}
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeIso639(byteBuffer, language);
byteBuffer.put(Utf8.convert(title));
byteBuffer.put((byte) 0);
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
language = IsoTypeReader.readIso639(content);
title = IsoTypeReader.readString(content);
}
public String toString() {
return "TitleBox[language=" + getLanguage() + ";title=" + getTitle() + "]";
}
}

@ -0,0 +1,41 @@
/*
* 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;
/**
* <code>
* Box Type: 'tref'<br>
* Container: {@link TrackBox} ('trak')<br>
* Mandatory: No<br>
* Quantity: Zero or one<br><br>
* </code>
* This box provides a reference from the containing track to another track in the presentation. These references
* are typed. A 'hint' reference links from the containing hint track to the media data that it hints. A content
* description reference 'cdsc' links a descriptive or metadata track to the content which it describes.
* Exactly one Track Reference Box can be contained within the Track Box.
* If this box is not present, the track is not referencing any other track in any way. The reference array is sized
* to fill the reference type box.
*/
public class TrackReferenceBox extends AbstractContainerBox {
public static final String TYPE = "tref";
public TrackReferenceBox() {
super(TYPE);
}
}

@ -0,0 +1,76 @@
/*
* 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;
/**
* Contains a reference to a track. The type of the box gives the kind of reference.
*/
public class TrackReferenceTypeBox extends AbstractBox {
public static final String TYPE1 = "hint";
public static final String TYPE2 = "cdsc";
private long[] trackIds;
public TrackReferenceTypeBox(String type) {
super(type);
}
public long[] getTrackIds() {
return trackIds;
}
@Override
public void _parseDetails(ByteBuffer content) {
int count = (int) (content.remaining() / 4);
trackIds = new long[count];
for (int i = 0; i < count; i++) {
trackIds[i] = IsoTypeReader.readUInt32(content);
}
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
for (long trackId : trackIds) {
IsoTypeWriter.writeUInt32(byteBuffer, trackId);
}
}
protected long getContentSize() {
return trackIds.length * 4;
}
public String toString() {
StringBuilder buffer = new StringBuilder();
buffer.append("TrackReferenceTypeBox[type=").append(getType());
for (int i = 0; i < trackIds.length; i++) {
buffer.append(";trackId");
buffer.append(i);
buffer.append("=");
buffer.append(trackIds[i]);
}
buffer.append("]");
return buffer.toString();
}
}

@ -0,0 +1,59 @@
/*
* 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 box unknown to the ISO Parser. If there is no specific Box implementation for a Box this <code>UnknownBox</code>
* will just hold the box's data.
*/
public class UnknownBox extends AbstractBox {
ByteBuffer data;
public UnknownBox(String type) {
super(type);
}
@Override
protected long getContentSize() {
return data.limit();
}
@Override
public void _parseDetails(ByteBuffer content) {
data = content;
content.position(content.position() + content.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;
}
}

@ -0,0 +1,59 @@
/*
* 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.googlecode.mp4parser.AbstractContainerBox;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
/**
* This box contains objects that declare user information about the containing box and its data (presentation or
* track).<br>
* The User Data Box is a container box for informative user-data. This user data is formatted as a set of boxes
* with more specific box types, which declare more precisely their content
*/
public class UserDataBox extends AbstractContainerBox {
public static final String TYPE = "udta";
@Override
protected long getContentSize() {
return super.getContentSize(); //To change body of overridden methods use File | Settings | File Templates.
}
@Override
public void parse(ReadableByteChannel readableByteChannel, ByteBuffer header, long contentSize, BoxParser boxParser) throws IOException {
super.parse(readableByteChannel, header, contentSize, boxParser); //To change body of overridden methods use File | Settings | File Templates.
}
@Override
public void _parseDetails(ByteBuffer content) {
super._parseDetails(content); //To change body of overridden methods use File | Settings | File Templates.
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
super.getContent(byteBuffer); //To change body of overridden methods use File | Settings | File Templates.
}
public UserDataBox() {
super(TYPE);
}
}

@ -0,0 +1,10 @@
package com.coremedia.iso.boxes;
/**
* The <class>WriteListener</class> is used to get the offset of
* a box before writing the box. This can be used if a box written
* later needs an offset.
*/
public interface WriteListener {
public void beforeWrite(long offset);
}

@ -0,0 +1,51 @@
package com.coremedia.iso.boxes;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.Utf8;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
/**
*
*/
public class XmlBox extends AbstractFullBox {
String xml = "";
public static final String TYPE = "xml ";
public XmlBox() {
super(TYPE);
}
public String getXml() {
return xml;
}
public void setXml(String xml) {
this.xml = xml;
}
@Override
protected long getContentSize() {
return 4 + Utf8.utf8StringLengthInBytes(xml);
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
xml = IsoTypeReader.readString(content, content.remaining());
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
byteBuffer.put(Utf8.convert(xml));
}
@Override
public String toString() {
return "XmlBox{" +
"xml='" + xml + '\'' +
'}';
}
}

@ -0,0 +1,164 @@
package com.coremedia.iso.boxes.apple;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.coremedia.iso.Utf8;
import com.googlecode.mp4parser.AbstractBox;
import com.coremedia.iso.boxes.Box;
import com.coremedia.iso.boxes.ContainerBox;
import com.googlecode.mp4parser.util.ByteBufferByteChannel;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.List;
import java.util.logging.Logger;
/**
*
*/
public abstract class AbstractAppleMetaDataBox extends AbstractBox implements ContainerBox {
private static Logger LOG = Logger.getLogger(AbstractAppleMetaDataBox.class.getName());
AppleDataBox appleDataBox = new AppleDataBox();
public List<Box> getBoxes() {
return Collections.singletonList((Box) appleDataBox);
}
public void setBoxes(List<Box> boxes) {
if (boxes.size() == 1 && boxes.get(0) instanceof AppleDataBox) {
appleDataBox = (AppleDataBox) boxes.get(0);
} else {
throw new IllegalArgumentException("This box only accepts one AppleDataBox child");
}
}
public <T extends Box> List<T> getBoxes(Class<T> clazz) {
return getBoxes(clazz, false);
}
public <T extends Box> List<T> getBoxes(Class<T> clazz, boolean recursive) {
//todo recursive?
if (clazz.isAssignableFrom(appleDataBox.getClass())) {
return (List<T>) Collections.singletonList(appleDataBox);
}
return null;
}
public AbstractAppleMetaDataBox(String type) {
super(type);
}
@Override
public void _parseDetails(ByteBuffer content) {
long dataBoxSize = IsoTypeReader.readUInt32(content);
String thisShouldBeData = IsoTypeReader.read4cc(content);
assert "data".equals(thisShouldBeData);
appleDataBox = new AppleDataBox();
try {
appleDataBox.parse(new ByteBufferByteChannel(content), null, content.remaining(), null);
} catch (IOException e) {
throw new RuntimeException(e);
}
appleDataBox.setParent(this);
}
protected long getContentSize() {
return appleDataBox.getSize();
}
protected void getContent(ByteBuffer byteBuffer) {
try {
appleDataBox.getBox(new ByteBufferByteChannel(byteBuffer));
} catch (IOException e) {
throw new RuntimeException("The Channel is based on a ByteBuffer and therefore it shouldn't throw any exception");
}
}
public long getNumOfBytesToFirstChild() {
return getSize() - appleDataBox.getSize();
}
@Override
public String toString() {
return this.getClass().getSimpleName() + "{" +
"appleDataBox=" + getValue() +
'}';
}
static long toLong(byte b) {
return b < 0 ? b + 256 : b;
}
public void setValue(String value) {
if (appleDataBox.getFlags() == 1) {
appleDataBox = new AppleDataBox();
appleDataBox.setVersion(0);
appleDataBox.setFlags(1);
appleDataBox.setFourBytes(new byte[4]);
appleDataBox.setData(Utf8.convert(value));
} else if (appleDataBox.getFlags() == 21) {
byte[] content = appleDataBox.getData();
appleDataBox = new AppleDataBox();
appleDataBox.setVersion(0);
appleDataBox.setFlags(21);
appleDataBox.setFourBytes(new byte[4]);
ByteBuffer bb = ByteBuffer.allocate(content.length);
if (content.length == 1) {
IsoTypeWriter.writeUInt8(bb, (Byte.parseByte(value) & 0xFF));
} else if (content.length == 2) {
IsoTypeWriter.writeUInt16(bb, Integer.parseInt(value));
} else if (content.length == 4) {
IsoTypeWriter.writeUInt32(bb, Long.parseLong(value));
} else if (content.length == 8) {
IsoTypeWriter.writeUInt64(bb, Long.parseLong(value));
} else {
throw new Error("The content length within the appleDataBox is neither 1, 2, 4 or 8. I can't handle that!");
}
appleDataBox.setData(bb.array());
} else if (appleDataBox.getFlags() == 0) {
appleDataBox = new AppleDataBox();
appleDataBox.setVersion(0);
appleDataBox.setFlags(0);
appleDataBox.setFourBytes(new byte[4]);
appleDataBox.setData(hexStringToByteArray(value));
} else {
LOG.warning("Don't know how to handle appleDataBox with flag=" + appleDataBox.getFlags());
}
}
public String getValue() {
if (appleDataBox.getFlags() == 1) {
return Utf8.convert(appleDataBox.getData());
} else if (appleDataBox.getFlags() == 21) {
byte[] content = appleDataBox.getData();
long l = 0;
int current = 1;
int length = content.length;
for (byte b : content) {
l += toLong(b) << (8 * (length - current++));
}
return "" + l;
} else if (appleDataBox.getFlags() == 0) {
return String.format("%x", new BigInteger(appleDataBox.getData()));
} else {
return "unknown";
}
}
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i + 1), 16));
}
return data;
}
}

@ -0,0 +1,16 @@
package com.coremedia.iso.boxes.apple;
/**
* itunes MetaData comment box.
*/
public class AppleAlbumArtistBox extends AbstractAppleMetaDataBox {
public static final String TYPE = "aART";
public AppleAlbumArtistBox() {
super(TYPE);
appleDataBox = AppleDataBox.getStringAppleDataBox();
}
}

@ -0,0 +1,15 @@
package com.coremedia.iso.boxes.apple;
/**
*
*/
public final class AppleAlbumBox extends AbstractAppleMetaDataBox {
public static final String TYPE = "\u00a9alb";
public AppleAlbumBox() {
super(TYPE);
appleDataBox = AppleDataBox.getStringAppleDataBox();
}
}

@ -0,0 +1,16 @@
package com.coremedia.iso.boxes.apple;
/**
* iTunes Artist box.
*/
public final class AppleArtistBox extends AbstractAppleMetaDataBox {
public static final String TYPE = "\u00a9ART";
public AppleArtistBox() {
super(TYPE);
appleDataBox = AppleDataBox.getStringAppleDataBox();
}
}

@ -0,0 +1,16 @@
package com.coremedia.iso.boxes.apple;
/**
* itunes MetaData comment box.
*/
public final class AppleCommentBox extends AbstractAppleMetaDataBox {
public static final String TYPE = "\u00a9cmt";
public AppleCommentBox() {
super(TYPE);
appleDataBox = AppleDataBox.getStringAppleDataBox();
}
}

@ -0,0 +1,15 @@
package com.coremedia.iso.boxes.apple;
/**
* Compilation.
*/
public final class AppleCompilationBox extends AbstractAppleMetaDataBox {
public static final String TYPE = "cpil";
public AppleCompilationBox() {
super(TYPE);
appleDataBox = AppleDataBox.getUint8AppleDataBox();
}
}

@ -0,0 +1,15 @@
package com.coremedia.iso.boxes.apple;
/**
* itunes MetaData comment box.
*/
public final class AppleCopyrightBox extends AbstractAppleMetaDataBox {
public static final String TYPE = "cprt";
public AppleCopyrightBox() {
super(TYPE);
appleDataBox = AppleDataBox.getStringAppleDataBox();
}
}

@ -0,0 +1,44 @@
package com.coremedia.iso.boxes.apple;
import java.util.logging.Logger;
/**
*
*/
public final class AppleCoverBox extends AbstractAppleMetaDataBox {
private static Logger LOG = Logger.getLogger(AppleCoverBox.class.getName());
public static final String TYPE = "covr";
public AppleCoverBox() {
super(TYPE);
}
public void setPng(byte[] pngData) {
appleDataBox = new AppleDataBox();
appleDataBox.setVersion(0);
appleDataBox.setFlags(0xe);
appleDataBox.setFourBytes(new byte[4]);
appleDataBox.setData(pngData);
}
public void setJpg(byte[] jpgData) {
appleDataBox = new AppleDataBox();
appleDataBox.setVersion(0);
appleDataBox.setFlags(0xd);
appleDataBox.setFourBytes(new byte[4]);
appleDataBox.setData(jpgData);
}
@Override
public void setValue(String value) {
LOG.warning("---");
}
@Override
public String getValue() {
return "---";
}
}

@ -0,0 +1,28 @@
package com.coremedia.iso.boxes.apple;
import com.coremedia.iso.Utf8;
/**
*
*/
public final class AppleCustomGenreBox extends AbstractAppleMetaDataBox {
public static final String TYPE = "\u00a9gen";
public AppleCustomGenreBox() {
super(TYPE);
appleDataBox = AppleDataBox.getStringAppleDataBox();
}
public void setGenre(String genre) {
appleDataBox = new AppleDataBox();
appleDataBox.setVersion(0);
appleDataBox.setFlags(1);
appleDataBox.setFourBytes(new byte[4]);
appleDataBox.setData(Utf8.convert(genre));
}
public String getGenre() {
return Utf8.convert(appleDataBox.getData());
}
}

@ -0,0 +1,92 @@
package com.coremedia.iso.boxes.apple;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
/**
* Most stupid box of the world. Encapsulates actual data within
*/
public final class AppleDataBox extends AbstractFullBox {
public static final String TYPE = "data";
private byte[] fourBytes = new byte[4];
private byte[] data;
private static AppleDataBox getEmpty() {
AppleDataBox appleDataBox = new AppleDataBox();
appleDataBox.setVersion(0);
appleDataBox.setFourBytes(new byte[4]);
return appleDataBox;
}
public static AppleDataBox getStringAppleDataBox() {
AppleDataBox appleDataBox = getEmpty();
appleDataBox.setFlags(1);
appleDataBox.setData(new byte[]{0});
return appleDataBox;
}
public static AppleDataBox getUint8AppleDataBox() {
AppleDataBox appleDataBox = new AppleDataBox();
appleDataBox.setFlags(21);
appleDataBox.setData(new byte[]{0});
return appleDataBox;
}
public static AppleDataBox getUint16AppleDataBox() {
AppleDataBox appleDataBox = new AppleDataBox();
appleDataBox.setFlags(21);
appleDataBox.setData(new byte[]{0, 0});
return appleDataBox;
}
public static AppleDataBox getUint32AppleDataBox() {
AppleDataBox appleDataBox = new AppleDataBox();
appleDataBox.setFlags(21);
appleDataBox.setData(new byte[]{0, 0, 0, 0});
return appleDataBox;
}
public AppleDataBox() {
super(TYPE);
}
protected long getContentSize() {
return data.length + 8;
}
public void setData(byte[] data) {
this.data = new byte[data.length];
System.arraycopy(data, 0, this.data, 0, data.length);
}
public void setFourBytes(byte[] fourBytes) {
System.arraycopy(fourBytes, 0, this.fourBytes, 0, 4);
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
fourBytes = new byte[4];
content.get(fourBytes);
data = new byte[content.remaining()];
content.get(data);
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
byteBuffer.put(fourBytes, 0, 4);
byteBuffer.put(data);
}
public byte[] getFourBytes() {
return fourBytes;
}
public byte[] getData() {
return data;
}
}

@ -0,0 +1,53 @@
/*
* 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.apple;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
public class AppleDataRateBox extends AbstractFullBox {
public static final String TYPE = "rmdr";
private long dataRate;
public AppleDataRateBox() {
super(TYPE);
}
protected long getContentSize() {
return 8;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
dataRate = IsoTypeReader.readUInt32(content);
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeUInt32(byteBuffer, dataRate);
}
public long getDataRate() {
return dataRate;
}
}

@ -0,0 +1,71 @@
/*
* 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.apple;
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 static com.googlecode.mp4parser.util.CastUtils.l2i;
public class AppleDataReferenceBox extends AbstractFullBox {
public static final String TYPE = "rdrf";
private int dataReferenceSize;
private String dataReferenceType;
private String dataReference;
public AppleDataReferenceBox() {
super(TYPE);
}
protected long getContentSize() {
return 12 + dataReferenceSize;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
dataReferenceType = IsoTypeReader.read4cc(content);
dataReferenceSize = l2i(IsoTypeReader.readUInt32(content));
dataReference = IsoTypeReader.readString(content, dataReferenceSize);
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
byteBuffer.put(IsoFile.fourCCtoBytes(dataReferenceType));
IsoTypeWriter.writeUInt32(byteBuffer, dataReferenceSize);
byteBuffer.put(Utf8.convert(dataReference));
}
public long getDataReferenceSize() {
return dataReferenceSize;
}
public String getDataReferenceType() {
return dataReferenceType;
}
public String getDataReference() {
return dataReference;
}
}

@ -0,0 +1,15 @@
package com.coremedia.iso.boxes.apple;
/**
*
*/
public final class AppleDescriptionBox extends AbstractAppleMetaDataBox {
public static final String TYPE = "desc";
public AppleDescriptionBox() {
super(TYPE);
appleDataBox = AppleDataBox.getStringAppleDataBox();
}
}

@ -0,0 +1,15 @@
package com.coremedia.iso.boxes.apple;
/**
* itunes MetaData comment box.
*/
public final class AppleEncoderBox extends AbstractAppleMetaDataBox {
public static final String TYPE = "\u00a9too";
public AppleEncoderBox() {
super(TYPE);
appleDataBox = AppleDataBox.getStringAppleDataBox();
}
}

@ -0,0 +1,15 @@
package com.coremedia.iso.boxes.apple;
/**
* Gapless Playback.
*/
public final class AppleGaplessPlaybackBox extends AbstractAppleMetaDataBox {
public static final String TYPE = "pgap";
public AppleGaplessPlaybackBox() {
super(TYPE);
appleDataBox = AppleDataBox.getUint8AppleDataBox();
}
}

@ -0,0 +1,15 @@
package com.coremedia.iso.boxes.apple;
import com.googlecode.mp4parser.AbstractContainerBox;
/**
*
*/
public final class AppleGenericBox extends AbstractContainerBox {
public static final String TYPE = "----";
public AppleGenericBox() {
super(TYPE);
}
}

@ -0,0 +1,15 @@
package com.coremedia.iso.boxes.apple;
/**
* itunes MetaData comment box.
*/
public final class AppleGroupingBox extends AbstractAppleMetaDataBox {
public static final String TYPE = "\u00a9grp";
public AppleGroupingBox() {
super(TYPE);
appleDataBox = AppleDataBox.getStringAppleDataBox();
}
}

@ -0,0 +1,15 @@
package com.coremedia.iso.boxes.apple;
/**
*
*/
public final class AppleIdBox extends AbstractAppleMetaDataBox {
public static final String TYPE = "apID";
public AppleIdBox() {
super(TYPE);
appleDataBox = AppleDataBox.getStringAppleDataBox();
}
}

@ -0,0 +1,15 @@
package com.coremedia.iso.boxes.apple;
import com.googlecode.mp4parser.AbstractContainerBox;
/**
* undocumented iTunes MetaData Box.
*/
public class AppleItemListBox extends AbstractContainerBox {
public static final String TYPE = "ilst";
public AppleItemListBox() {
super(TYPE);
}
}

@ -0,0 +1,163 @@
package com.coremedia.iso.boxes.apple;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
/**
*
*/
public final class AppleLosslessSpecificBox extends AbstractFullBox {
public static final String TYPE = "alac";
/*
Extradata: 32bit size 32bit tag (=alac) 32bit zero?
32bit max sample per frame 8bit ?? (zero?) 8bit sample
size 8bit history mult 8bit initial history 8bit kmodifier
8bit channels? 16bit ?? 32bit max coded frame size 32bit
bitrate? 32bit samplerate
*/
private long maxSamplePerFrame; // 32bi
private int unknown1; // 8bit
private int sampleSize; // 8bit
private int historyMult; // 8bit
private int initialHistory; // 8bit
private int kModifier; // 8bit
private int channels; // 8bit
private int unknown2; // 16bit
private long maxCodedFrameSize; // 32bit
private long bitRate; // 32bit
private long sampleRate; // 32bit
public long getMaxSamplePerFrame() {
return maxSamplePerFrame;
}
public void setMaxSamplePerFrame(int maxSamplePerFrame) {
this.maxSamplePerFrame = maxSamplePerFrame;
}
public int getUnknown1() {
return unknown1;
}
public void setUnknown1(int unknown1) {
this.unknown1 = unknown1;
}
public int getSampleSize() {
return sampleSize;
}
public void setSampleSize(int sampleSize) {
this.sampleSize = sampleSize;
}
public int getHistoryMult() {
return historyMult;
}
public void setHistoryMult(int historyMult) {
this.historyMult = historyMult;
}
public int getInitialHistory() {
return initialHistory;
}
public void setInitialHistory(int initialHistory) {
this.initialHistory = initialHistory;
}
public int getKModifier() {
return kModifier;
}
public void setKModifier(int kModifier) {
this.kModifier = kModifier;
}
public int getChannels() {
return channels;
}
public void setChannels(int channels) {
this.channels = channels;
}
public int getUnknown2() {
return unknown2;
}
public void setUnknown2(int unknown2) {
this.unknown2 = unknown2;
}
public long getMaxCodedFrameSize() {
return maxCodedFrameSize;
}
public void setMaxCodedFrameSize(int maxCodedFrameSize) {
this.maxCodedFrameSize = maxCodedFrameSize;
}
public long getBitRate() {
return bitRate;
}
public void setBitRate(int bitRate) {
this.bitRate = bitRate;
}
public long getSampleRate() {
return sampleRate;
}
public void setSampleRate(int sampleRate) {
this.sampleRate = sampleRate;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
maxSamplePerFrame = IsoTypeReader.readUInt32(content);
unknown1 = IsoTypeReader.readUInt8(content);
sampleSize = IsoTypeReader.readUInt8(content);
historyMult = IsoTypeReader.readUInt8(content);
initialHistory = IsoTypeReader.readUInt8(content);
kModifier = IsoTypeReader.readUInt8(content);
channels = IsoTypeReader.readUInt8(content);
unknown2 = IsoTypeReader.readUInt16(content);
maxCodedFrameSize = IsoTypeReader.readUInt32(content);
bitRate = IsoTypeReader.readUInt32(content);
sampleRate = IsoTypeReader.readUInt32(content);
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeUInt32(byteBuffer, maxSamplePerFrame);
IsoTypeWriter.writeUInt8(byteBuffer, unknown1);
IsoTypeWriter.writeUInt8(byteBuffer, sampleSize);
IsoTypeWriter.writeUInt8(byteBuffer, historyMult);
IsoTypeWriter.writeUInt8(byteBuffer, initialHistory);
IsoTypeWriter.writeUInt8(byteBuffer, kModifier);
IsoTypeWriter.writeUInt8(byteBuffer, channels);
IsoTypeWriter.writeUInt16(byteBuffer, unknown2);
IsoTypeWriter.writeUInt32(byteBuffer, maxCodedFrameSize);
IsoTypeWriter.writeUInt32(byteBuffer, bitRate);
IsoTypeWriter.writeUInt32(byteBuffer, sampleRate);
}
public AppleLosslessSpecificBox() {
super("alac");
}
protected long getContentSize() {
return 28;
}
}

@ -0,0 +1,47 @@
package com.coremedia.iso.boxes.apple;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.Utf8;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
/**
* Apple Meaning box. Allowed as subbox of "----" box.
*
* @see com.coremedia.iso.boxes.apple.AppleGenericBox
*/
public final class AppleMeanBox extends AbstractFullBox {
public static final String TYPE = "mean";
private String meaning;
public AppleMeanBox() {
super(TYPE);
}
protected long getContentSize() {
return 4 + Utf8.utf8StringLengthInBytes(meaning);
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
meaning = IsoTypeReader.readString(content, content.remaining());
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
byteBuffer.put(Utf8.convert(meaning));
}
public String getMeaning() {
return meaning;
}
public void setMeaning(String meaning) {
this.meaning = meaning;
}
}

@ -0,0 +1,39 @@
package com.coremedia.iso.boxes.apple;
import java.util.HashMap;
import java.util.Map;
/**
* itunes MetaData comment box.
*/
public class AppleMediaTypeBox extends AbstractAppleMetaDataBox {
private static Map<String, String> mediaTypes = new HashMap<String, String>();
static {
mediaTypes.put("0", "Movie (is now 9)");
mediaTypes.put("1", "Normal (Music)");
mediaTypes.put("2", "Audiobook");
mediaTypes.put("6", "Music Video");
mediaTypes.put("9", "Movie");
mediaTypes.put("10", "TV Show");
mediaTypes.put("11", "Booklet");
mediaTypes.put("14", "Ringtone");
}
public static final String TYPE = "stik";
public AppleMediaTypeBox() {
super(TYPE);
appleDataBox = AppleDataBox.getUint8AppleDataBox();
}
public String getReadableValue() {
if (mediaTypes.containsKey(getValue())) {
return mediaTypes.get(getValue());
} else {
return "unknown media type " + getValue();
}
}
}

@ -0,0 +1,45 @@
package com.coremedia.iso.boxes.apple;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.Utf8;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
/**
* Apple Name box. Allowed as subbox of "----" box.
*
* @see AppleGenericBox
*/
public final class AppleNameBox extends AbstractFullBox {
public static final String TYPE = "name";
private String name;
public AppleNameBox() {
super(TYPE);
}
protected long getContentSize() {
return 4 + Utf8.convert(name).length;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
name = IsoTypeReader.readString(content, content.remaining());
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
byteBuffer.put(Utf8.convert(name));
}
}

@ -0,0 +1,16 @@
package com.coremedia.iso.boxes.apple;
/**
*
*/
public final class AppleNetworkBox extends AbstractAppleMetaDataBox {
public static final String TYPE = "tvnn";
public AppleNetworkBox() {
super(TYPE);
appleDataBox = AppleDataBox.getStringAppleDataBox();
}
}

@ -0,0 +1,15 @@
package com.coremedia.iso.boxes.apple;
/**
*
*/
public final class ApplePurchaseDateBox extends AbstractAppleMetaDataBox {
public static final String TYPE = "purd";
public ApplePurchaseDateBox() {
super(TYPE);
appleDataBox = AppleDataBox.getStringAppleDataBox();
}
}

@ -0,0 +1,16 @@
package com.coremedia.iso.boxes.apple;
/**
* iTunes Rating Box.
*/
public final class AppleRatingBox extends AbstractAppleMetaDataBox {
public static final String TYPE = "rtng";
public AppleRatingBox() {
super(TYPE);
appleDataBox = AppleDataBox.getUint8AppleDataBox();
}
}

@ -0,0 +1,16 @@
package com.coremedia.iso.boxes.apple;
/**
*
*/
public class AppleRecordingYearBox extends AbstractAppleMetaDataBox {
public static final String TYPE = "\u00a9day";
public AppleRecordingYearBox() {
super(TYPE);
appleDataBox = AppleDataBox.getStringAppleDataBox();
}
}

@ -0,0 +1,28 @@
/*
* 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.apple;
import com.googlecode.mp4parser.AbstractContainerBox;
public class AppleReferenceMovieBox extends AbstractContainerBox {
public static final String TYPE = "rmra";
public AppleReferenceMovieBox() {
super(TYPE);
}
}

@ -0,0 +1,27 @@
/*
* 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.apple;
import com.googlecode.mp4parser.AbstractContainerBox;
public class AppleReferenceMovieDescriptorBox extends AbstractContainerBox {
public static final String TYPE = "rmda";
public AppleReferenceMovieDescriptorBox() {
super(TYPE);
}
}

@ -0,0 +1,15 @@
package com.coremedia.iso.boxes.apple;
/**
*
*/
public final class AppleShowBox extends AbstractAppleMetaDataBox {
public static final String TYPE = "tvsh";
public AppleShowBox() {
super(TYPE);
appleDataBox = AppleDataBox.getStringAppleDataBox();
}
}

@ -0,0 +1,14 @@
package com.coremedia.iso.boxes.apple;
/**
*
*/
public final class AppleSortAlbumBox extends AbstractAppleMetaDataBox {
public static final String TYPE = "soal";
public AppleSortAlbumBox() {
super(TYPE);
appleDataBox = AppleDataBox.getStringAppleDataBox();
}
}

@ -0,0 +1,14 @@
package com.coremedia.iso.boxes.apple;
/**
*
*/
public final class AppleStandardGenreBox extends AbstractAppleMetaDataBox {
public static final String TYPE = "gnre";
public AppleStandardGenreBox() {
super(TYPE);
appleDataBox = AppleDataBox.getUint16AppleDataBox();
}
}

@ -0,0 +1,27 @@
package com.coremedia.iso.boxes.apple;
/**
* itunes MetaData comment box.
*/
public class AppleStoreAccountTypeBox extends AbstractAppleMetaDataBox {
public static final String TYPE = "akID";
public AppleStoreAccountTypeBox() {
super(TYPE);
appleDataBox = AppleDataBox.getUint8AppleDataBox();
}
public String getReadableValue() {
byte value = this.appleDataBox.getData()[0];
switch (value) {
case 0:
return "iTunes Account";
case 1:
return "AOL Account";
default:
return "unknown Account";
}
}
}

@ -0,0 +1,54 @@
package com.coremedia.iso.boxes.apple;
import java.util.HashMap;
import java.util.Map;
/**
* itunes MetaData comment box.
*/
public class AppleStoreCountryCodeBox extends AbstractAppleMetaDataBox {
private static Map<String, String> countryCodes = new HashMap<String, String>();
static {
countryCodes.put("143460", "Australia");
countryCodes.put("143445", "Austria");
countryCodes.put("143446", "Belgium");
countryCodes.put("143455", "Canada");
countryCodes.put("143458", "Denmark");
countryCodes.put("143447", "Finland");
countryCodes.put("143442", "France");
countryCodes.put("143443", "Germany");
countryCodes.put("143448", "Greece");
countryCodes.put("143449", "Ireland");
countryCodes.put("143450", "Italy");
countryCodes.put("143462", "Japan");
countryCodes.put("143451", "Luxembourg");
countryCodes.put("143452", "Netherlands");
countryCodes.put("143461", "New Zealand");
countryCodes.put("143457", "Norway");
countryCodes.put("143453", "Portugal");
countryCodes.put("143454", "Spain");
countryCodes.put("143456", "Sweden");
countryCodes.put("143459", "Switzerland");
countryCodes.put("143444", "United Kingdom");
countryCodes.put("143441", "United States");
}
public static final String TYPE = "sfID";
public AppleStoreCountryCodeBox() {
super(TYPE);
appleDataBox = AppleDataBox.getUint32AppleDataBox();
}
public String getReadableValue() {
if (countryCodes.containsKey(getValue())) {
return countryCodes.get(getValue());
} else {
return "unknown country code " + getValue();
}
}
}

@ -0,0 +1,16 @@
package com.coremedia.iso.boxes.apple;
/**
*
*/
public final class AppleSynopsisBox extends AbstractAppleMetaDataBox {
public static final String TYPE = "ldes";
public AppleSynopsisBox() {
super(TYPE);
appleDataBox = AppleDataBox.getStringAppleDataBox();
}
}

@ -0,0 +1,28 @@
package com.coremedia.iso.boxes.apple;
/**
* Beats per minute.
*/
public final class AppleTempBox extends AbstractAppleMetaDataBox {
public static final String TYPE = "tmpo";
public AppleTempBox() {
super(TYPE);
appleDataBox = AppleDataBox.getUint16AppleDataBox();
}
public int getTempo() {
return appleDataBox.getData()[1];
}
public void setTempo(int tempo) {
appleDataBox = new AppleDataBox();
appleDataBox.setVersion(0);
appleDataBox.setFlags(21);
appleDataBox.setFourBytes(new byte[4]);
appleDataBox.setData(new byte[]{0, (byte) (tempo & 0xFF)});
}
}

@ -0,0 +1,16 @@
package com.coremedia.iso.boxes.apple;
/**
*
*/
public final class AppleTrackAuthorBox extends AbstractAppleMetaDataBox {
public static final String TYPE = "\u00a9wrt";
public AppleTrackAuthorBox() {
super(TYPE);
appleDataBox = AppleDataBox.getStringAppleDataBox();
}
}

@ -0,0 +1,48 @@
package com.coremedia.iso.boxes.apple;
/**
*
*/
public final class AppleTrackNumberBox extends AbstractAppleMetaDataBox {
public static final String TYPE = "trkn";
public AppleTrackNumberBox() {
super(TYPE);
}
/**
* @param track the actual track number
* @param of number of tracks overall
*/
public void setTrackNumber(byte track, byte of) {
appleDataBox = new AppleDataBox();
appleDataBox.setVersion(0);
appleDataBox.setFlags(0);
appleDataBox.setFourBytes(new byte[4]);
appleDataBox.setData(new byte[]{0, 0, 0, track, 0, of, 0, 0});
}
public byte getTrackNumber() {
return appleDataBox.getData()[3];
}
public byte getNumberOfTracks() {
return appleDataBox.getData()[5];
}
public void setNumberOfTracks(byte numberOfTracks) {
byte[] content = appleDataBox.getData();
content[5] = numberOfTracks;
appleDataBox.setData(content);
}
public void setTrackNumber(byte trackNumber) {
byte[] content = appleDataBox.getData();
content[3] = trackNumber;
appleDataBox.setData(content);
}
}

@ -0,0 +1,15 @@
package com.coremedia.iso.boxes.apple;
/**
*
*/
public final class AppleTrackTitleBox extends AbstractAppleMetaDataBox {
public static final String TYPE = "\u00a9nam";
public AppleTrackTitleBox() {
super(TYPE);
appleDataBox = AppleDataBox.getStringAppleDataBox();
}
}

@ -0,0 +1,15 @@
package com.coremedia.iso.boxes.apple;
/**
* Tv Episode.
*/
public class AppleTvEpisodeBox extends AbstractAppleMetaDataBox {
public static final String TYPE = "tves";
public AppleTvEpisodeBox() {
super(TYPE);
appleDataBox = AppleDataBox.getUint32AppleDataBox();
}
}

@ -0,0 +1,15 @@
package com.coremedia.iso.boxes.apple;
/**
* Tv Episode.
*/
public class AppleTvEpisodeNumberBox extends AbstractAppleMetaDataBox {
public static final String TYPE = "tven";
public AppleTvEpisodeNumberBox() {
super(TYPE);
appleDataBox = AppleDataBox.getStringAppleDataBox();
}
}

@ -0,0 +1,15 @@
package com.coremedia.iso.boxes.apple;
/**
* Tv Season.
*/
public final class AppleTvSeasonBox extends AbstractAppleMetaDataBox {
public static final String TYPE = "tvsn";
public AppleTvSeasonBox() {
super(TYPE);
appleDataBox = AppleDataBox.getUint32AppleDataBox();
}
}

@ -0,0 +1,16 @@
package com.coremedia.iso.boxes.apple;
import com.googlecode.mp4parser.AbstractContainerBox;
/**
*
*/
public final class AppleWaveBox extends AbstractContainerBox {
public static final String TYPE = "wave";
public AppleWaveBox() {
super(TYPE);
}
}

@ -0,0 +1,108 @@
package com.coremedia.iso.boxes.dece;
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 TrickPlayBox
* extends FullBox(trik, version=0, flags=0)
* {
* for (i=0; I < sample_count; i++) {
* unsigned int(2) pic_type;
* unsigned int(6) dependency_level;
* }
* }
*/
public class TrickPlayBox extends AbstractFullBox {
public static final String TYPE = "trik";
private List<Entry> entries = new ArrayList<Entry>();
public TrickPlayBox() {
super(TYPE);
}
public void setEntries(List<Entry> entries) {
this.entries = entries;
}
public List<Entry> getEntries() {
return entries;
}
public static class Entry {
public Entry() {
}
public Entry(int value) {
this.value = value;
}
private int value;
public int getPicType() {
return (value >> 6) & 0x03;
}
public void setPicType(int picType) {
value = value & (0xff >> 3);
value = (picType & 0x03) << 6 | value;
}
public int getDependencyLevel() {
return value & 0x3f;
}
public void setDependencyLevel(int dependencyLevel) {
value = (dependencyLevel & 0x3f) | value;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("Entry");
sb.append("{picType=").append(getPicType());
sb.append(",dependencyLevel=").append(getDependencyLevel());
sb.append('}');
return sb.toString();
}
}
@Override
protected long getContentSize() {
return 4 + entries.size();
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
while (content.remaining() > 0) {
entries.add(new Entry(IsoTypeReader.readUInt8(content)));
}
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
for (Entry entry : entries) {
IsoTypeWriter.writeUInt8(byteBuffer, entry.value);
}
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("TrickPlayBox");
sb.append("{entries=").append(entries);
sb.append('}');
return sb.toString();
}
}

@ -0,0 +1,31 @@
/*
* 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.fragment;
import com.googlecode.mp4parser.AbstractContainerBox;
/**
* aligned(8) class MovieExtendsBox extends Box('mvex'){
* }
*/
public class MovieExtendsBox extends AbstractContainerBox {
public static final String TYPE = "mvex";
public MovieExtendsBox() {
super(TYPE);
}
}

@ -0,0 +1,71 @@
/*
* 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.fragment;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
/**
* aligned(8) class MovieExtendsHeaderBox extends FullBox('mehd', version, 0) {
* if (version==1) {
* unsigned int(64) fragment_duration;
* } else { // version==0
* unsigned int(32) fragment_duration;
* }
* }
*/
public class MovieExtendsHeaderBox extends AbstractFullBox {
public static final String TYPE = "mehd";
private long fragmentDuration;
public MovieExtendsHeaderBox() {
super(TYPE);
}
@Override
protected long getContentSize() {
return getVersion() == 1 ? 12 : 8;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
fragmentDuration = getVersion() == 1 ? IsoTypeReader.readUInt64(content) : IsoTypeReader.readUInt32(content);
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
if (getVersion() == 1) {
IsoTypeWriter.writeUInt64(byteBuffer, fragmentDuration);
} else {
IsoTypeWriter.writeUInt32(byteBuffer, fragmentDuration);
}
}
public long getFragmentDuration() {
return fragmentDuration;
}
public void setFragmentDuration(long fragmentDuration) {
this.fragmentDuration = fragmentDuration;
}
}

@ -0,0 +1,100 @@
/*
* 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.fragment;
import com.googlecode.mp4parser.AbstractContainerBox;
import com.coremedia.iso.boxes.Box;
import com.coremedia.iso.boxes.SampleDependencyTypeBox;
import com.googlecode.mp4parser.annotations.DoNotParseDetail;
import java.util.ArrayList;
import java.util.List;
/**
* aligned(8) class MovieFragmentBox extends Box(moof){
* }
*/
public class MovieFragmentBox extends AbstractContainerBox {
public static final String TYPE = "moof";
public MovieFragmentBox() {
super(TYPE);
}
public List<Long> getSyncSamples(SampleDependencyTypeBox sdtp) {
List<Long> result = new ArrayList<Long>();
final List<SampleDependencyTypeBox.Entry> sampleEntries = sdtp.getEntries();
long i = 1;
for (SampleDependencyTypeBox.Entry sampleEntry : sampleEntries) {
if (sampleEntry.getSampleDependsOn() == 2) {
result.add(i);
}
i++;
}
return result;
}
@DoNotParseDetail
public long getOffset() {
Box b = this;
long offset = 0;
while (b.getParent() != null) {
for (Box box : b.getParent().getBoxes()) {
if (b == box) {
break;
}
offset += box.getSize();
}
b = b.getParent();
}
return offset;
}
public int getTrackCount() {
return getBoxes(TrackFragmentBox.class, false).size();
}
/**
* Returns the track numbers associated with this <code>MovieBox</code>.
*
* @return the tracknumbers (IDs) of the tracks in their order of appearance in the file
*/
public long[] getTrackNumbers() {
List<TrackFragmentBox> trackBoxes = this.getBoxes(TrackFragmentBox.class, false);
long[] trackNumbers = new long[trackBoxes.size()];
for (int trackCounter = 0; trackCounter < trackBoxes.size(); trackCounter++) {
TrackFragmentBox trackBoxe = trackBoxes.get(trackCounter);
trackNumbers[trackCounter] = trackBoxe.getTrackFragmentHeaderBox().getTrackId();
}
return trackNumbers;
}
public List<TrackFragmentHeaderBox> getTrackFragmentHeaderBoxes() {
return getBoxes(TrackFragmentHeaderBox.class, true);
}
public List<TrackRunBox> getTrackRunBoxes() {
return getBoxes(TrackRunBox.class, true);
}
}

@ -0,0 +1,72 @@
/*
* 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.fragment;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
/**
* aligned(8) class MovieFragmentHeaderBox
* extends FullBox('mfhd', 0, 0){
* unsigned int(32) sequence_number;
* }
*/
public class MovieFragmentHeaderBox extends AbstractFullBox {
public static final String TYPE = "mfhd";
private long sequenceNumber;
public MovieFragmentHeaderBox() {
super(TYPE);
}
protected long getContentSize() {
return 8;
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeUInt32(byteBuffer, sequenceNumber);
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
sequenceNumber = IsoTypeReader.readUInt32(content);
}
public long getSequenceNumber() {
return sequenceNumber;
}
public void setSequenceNumber(long sequenceNumber) {
this.sequenceNumber = sequenceNumber;
}
@Override
public String toString() {
return "MovieFragmentHeaderBox{" +
"sequenceNumber=" + sequenceNumber +
'}';
}
}

@ -0,0 +1,34 @@
/*
* 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.fragment;
import com.googlecode.mp4parser.AbstractContainerBox;
/**
* aligned(8) class MovieFragmentRandomAccessBox
* extends Box('mfra')
* {
* }
*/
public class MovieFragmentRandomAccessBox extends AbstractContainerBox {
public static final String TYPE = "mfra";
public MovieFragmentRandomAccessBox() {
super(TYPE);
}
}

@ -0,0 +1,62 @@
/*
* 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.fragment;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
/**
* aligned(8) class MovieFragmentRandomAccessOffsetBox
* extends FullBox('mfro', version, 0) {
* unsigned int(32) size;
* }
*/
public class MovieFragmentRandomAccessOffsetBox extends AbstractFullBox {
public static final String TYPE = "mfro";
private long mfraSize;
public MovieFragmentRandomAccessOffsetBox() {
super(TYPE);
}
protected long getContentSize() {
return 8;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
mfraSize = IsoTypeReader.readUInt32(content);
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeUInt32(byteBuffer, mfraSize);
}
public long getMfraSize() {
return mfraSize;
}
public void setMfraSize(long mfraSize) {
this.mfraSize = mfraSize;
}
}

@ -0,0 +1,207 @@
/*
* 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.fragment;
import com.googlecode.mp4parser.boxes.mp4.objectdescriptors.BitReaderBuffer;
import com.googlecode.mp4parser.boxes.mp4.objectdescriptors.BitWriterBuffer;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
* bit(6) reserved=0;
* unsigned int(2) sample_depends_on;
* unsigned int(2) sample_is_depended_on;
* unsigned int(2) sample_has_redundancy;
* bit(3) sample_padding_value;
* bit(1) sample_is_difference_sample;
* // i.e. when 1 signals a non-key or non-sync sample
* unsigned int(16) sample_degradation_priority;
*/
public class SampleFlags {
private int reserved;
private int sampleDependsOn;
private int sampleIsDependedOn;
private int sampleHasRedundancy;
private int samplePaddingValue;
private boolean sampleIsDifferenceSample;
private int sampleDegradationPriority;
public SampleFlags() {
}
public SampleFlags(ByteBuffer bb) {
BitReaderBuffer brb = new BitReaderBuffer(bb);
reserved = brb.readBits(6);
sampleDependsOn = brb.readBits(2);
sampleIsDependedOn = brb.readBits(2);
sampleHasRedundancy = brb.readBits(2);
samplePaddingValue = brb.readBits(3);
sampleIsDifferenceSample = brb.readBits(1) == 1;
sampleDegradationPriority = brb.readBits(16);
}
public void getContent(ByteBuffer os) {
BitWriterBuffer bitWriterBuffer = new BitWriterBuffer(os);
bitWriterBuffer.writeBits(reserved, 6);
bitWriterBuffer.writeBits(sampleDependsOn, 2);
bitWriterBuffer.writeBits(sampleIsDependedOn, 2);
bitWriterBuffer.writeBits(sampleHasRedundancy, 2);
bitWriterBuffer.writeBits(samplePaddingValue, 3);
bitWriterBuffer.writeBits(this.sampleIsDifferenceSample ? 1 : 0, 1);
bitWriterBuffer.writeBits(sampleDegradationPriority, 16);
}
public int getReserved() {
return reserved;
}
public void setReserved(int reserved) {
this.reserved = reserved;
}
/**
* @see #setSampleDependsOn(int)
*/
public int getSampleDependsOn() {
return sampleDependsOn;
}
/**
* sample_depends_on takes one of the following four values:
* <pre>
* 0: the dependency of this sample is unknown;
* 1: this sample does depend on others (not an I picture);
* 2: this sample does not depend on others (I picture);
* 3: reserved
* </pre>
*
*/
public void setSampleDependsOn(int sampleDependsOn) {
this.sampleDependsOn = sampleDependsOn;
}
/**
* @see #setSampleIsDependedOn(int)
*/
public int getSampleIsDependedOn() {
return sampleIsDependedOn;
}
/**
* sample_is_depended_on takes one of the following four values:
* <pre>
* 0: the dependency of other samples on this sample is unknown;
* 1: other samples may depend on this one (not disposable);
* 2: no other sample depends on this one (disposable);
* 3: reserved
* </pre>
*
*/
public void setSampleIsDependedOn(int sampleIsDependedOn) {
this.sampleIsDependedOn = sampleIsDependedOn;
}
/**
* @see #setSampleHasRedundancy(int)
*/
public int getSampleHasRedundancy() {
return sampleHasRedundancy;
}
/**
* sample_has_redundancy takes one of the following four values:
* <pre>
* 0: it is unknown whether there is redundant coding in this sample;
* 1: there is redundant coding in this sample;
* 2: there is no redundant coding in this sample;
* 3: reserved
* </pre>
*/
public void setSampleHasRedundancy(int sampleHasRedundancy) {
this.sampleHasRedundancy = sampleHasRedundancy;
}
public int getSamplePaddingValue() {
return samplePaddingValue;
}
public void setSamplePaddingValue(int samplePaddingValue) {
this.samplePaddingValue = samplePaddingValue;
}
public boolean isSampleIsDifferenceSample() {
return sampleIsDifferenceSample;
}
public void setSampleIsDifferenceSample(boolean sampleIsDifferenceSample) {
this.sampleIsDifferenceSample = sampleIsDifferenceSample;
}
public int getSampleDegradationPriority() {
return sampleDegradationPriority;
}
public void setSampleDegradationPriority(int sampleDegradationPriority) {
this.sampleDegradationPriority = sampleDegradationPriority;
}
@Override
public String toString() {
return "SampleFlags{" +
"reserved=" + reserved +
", sampleDependsOn=" + sampleDependsOn +
", sampleHasRedundancy=" + sampleHasRedundancy +
", samplePaddingValue=" + samplePaddingValue +
", sampleIsDifferenceSample=" + sampleIsDifferenceSample +
", sampleDegradationPriority=" + sampleDegradationPriority +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
SampleFlags that = (SampleFlags) o;
if (reserved != that.reserved) return false;
if (sampleDegradationPriority != that.sampleDegradationPriority) return false;
if (sampleDependsOn != that.sampleDependsOn) return false;
if (sampleHasRedundancy != that.sampleHasRedundancy) return false;
if (sampleIsDependedOn != that.sampleIsDependedOn) return false;
if (sampleIsDifferenceSample != that.sampleIsDifferenceSample) return false;
if (samplePaddingValue != that.samplePaddingValue) return false;
return true;
}
@Override
public int hashCode() {
int result = reserved;
result = 31 * result + sampleDependsOn;
result = 31 * result + sampleIsDependedOn;
result = 31 * result + sampleHasRedundancy;
result = 31 * result + samplePaddingValue;
result = 31 * result + (sampleIsDifferenceSample ? 1 : 0);
result = 31 * result + sampleDegradationPriority;
return result;
}
}

@ -0,0 +1,143 @@
/*
* 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.fragment;
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.Collections;
import java.util.LinkedList;
import java.util.List;
/**
* This box identifies the specifications to which this file complies. <br>
* Each brand is a printable four-character code, registered with ISO, that
* identifies a precise specification.
*/
public class SegmentTypeBox extends AbstractBox {
public static final String TYPE = "styp";
private String majorBrand;
private long minorVersion;
private List<String> compatibleBrands = Collections.emptyList();
public SegmentTypeBox() {
super(TYPE);
}
public SegmentTypeBox(String majorBrand, long minorVersion, List<String> 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<String>();
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 SegmentTypeBox#getMajorBrand()
*/
public long getMinorVersion() {
return minorVersion;
}
/**
* Gets an array of 4-cc brands.
*
* @return the compatible brands
*/
public List<String> getCompatibleBrands() {
return compatibleBrands;
}
public void setCompatibleBrands(List<String> compatibleBrands) {
this.compatibleBrands = compatibleBrands;
}
@DoNotParseDetail
public String toString() {
StringBuilder result = new StringBuilder();
result.append("SegmentTypeBox[");
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();
}
}

@ -0,0 +1,115 @@
/*
* 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.fragment;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
/**
* aligned(8) class TrackExtendsBox extends FullBox('trex', 0, 0){
* unsigned int(32) track_ID;
* unsigned int(32) default_sample_description_index;
* unsigned int(32) default_sample_duration;
* unsigned int(32) default_sample_size;
* unsigned int(32) default_sample_flags
* }
*/
public class TrackExtendsBox extends AbstractFullBox {
public static final String TYPE = "trex";
private long trackId;
private long defaultSampleDescriptionIndex;
private long defaultSampleDuration;
private long defaultSampleSize;
private SampleFlags defaultSampleFlags;
public TrackExtendsBox() {
super(TYPE);
}
@Override
protected long getContentSize() {
return 5 * 4 + 4;
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeUInt32(byteBuffer, trackId);
IsoTypeWriter.writeUInt32(byteBuffer, defaultSampleDescriptionIndex);
IsoTypeWriter.writeUInt32(byteBuffer, defaultSampleDuration);
IsoTypeWriter.writeUInt32(byteBuffer, defaultSampleSize);
defaultSampleFlags.getContent(byteBuffer);
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
trackId = IsoTypeReader.readUInt32(content);
defaultSampleDescriptionIndex = IsoTypeReader.readUInt32(content);
defaultSampleDuration = IsoTypeReader.readUInt32(content);
defaultSampleSize = IsoTypeReader.readUInt32(content);
defaultSampleFlags = new SampleFlags(content);
}
public long getTrackId() {
return trackId;
}
public long getDefaultSampleDescriptionIndex() {
return defaultSampleDescriptionIndex;
}
public long getDefaultSampleDuration() {
return defaultSampleDuration;
}
public long getDefaultSampleSize() {
return defaultSampleSize;
}
public SampleFlags getDefaultSampleFlags() {
return defaultSampleFlags;
}
public String getDefaultSampleFlagsStr() {
return defaultSampleFlags.toString();
}
public void setTrackId(long trackId) {
this.trackId = trackId;
}
public void setDefaultSampleDescriptionIndex(long defaultSampleDescriptionIndex) {
this.defaultSampleDescriptionIndex = defaultSampleDescriptionIndex;
}
public void setDefaultSampleDuration(long defaultSampleDuration) {
this.defaultSampleDuration = defaultSampleDuration;
}
public void setDefaultSampleSize(long defaultSampleSize) {
this.defaultSampleSize = defaultSampleSize;
}
public void setDefaultSampleFlags(SampleFlags defaultSampleFlags) {
this.defaultSampleFlags = defaultSampleFlags;
}
}

@ -0,0 +1,76 @@
/*
* 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.fragment;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeWriter;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
public class TrackFragmentBaseMediaDecodeTimeBox extends AbstractFullBox {
public static final String TYPE = "tfdt";
private long baseMediaDecodeTime;
public TrackFragmentBaseMediaDecodeTimeBox() {
super(TYPE);
}
@Override
protected long getContentSize() {
return getVersion() == 0 ? 8 : 12;
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
if (getVersion() == 1) {
IsoTypeWriter.writeUInt64(byteBuffer, baseMediaDecodeTime);
} else {
IsoTypeWriter.writeUInt32(byteBuffer, baseMediaDecodeTime);
}
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
if (getVersion() == 1) {
baseMediaDecodeTime = IsoTypeReader.readUInt64(content);
} else {
baseMediaDecodeTime = IsoTypeReader.readUInt32(content);
}
}
public long getBaseMediaDecodeTime() {
return baseMediaDecodeTime;
}
public void setBaseMediaDecodeTime(long baseMediaDecodeTime) {
this.baseMediaDecodeTime = baseMediaDecodeTime;
}
@Override
public String toString() {
return "TrackFragmentBaseMediaDecodeTimeBox{" +
"baseMediaDecodeTime=" + baseMediaDecodeTime +
'}';
}
}

@ -0,0 +1,43 @@
/*
* 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.fragment;
import com.googlecode.mp4parser.AbstractContainerBox;
import com.coremedia.iso.boxes.Box;
/**
* aligned(8) class TrackFragmentBox extends Box('traf'){
* }
*/
public class TrackFragmentBox extends AbstractContainerBox {
public static final String TYPE = "traf";
public TrackFragmentBox() {
super(TYPE);
}
public TrackFragmentHeaderBox getTrackFragmentHeaderBox() {
for (Box box : getBoxes()) {
if (box instanceof TrackFragmentHeaderBox) {
return (TrackFragmentHeaderBox) box;
}
}
return null;
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save