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,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,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,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,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…
Reference in New Issue