Skip to content
Snippets Groups Projects
Commit 02733524 authored by Leo Ma's avatar Leo Ma
Browse files

Add new files for mp4 parser


Signed-off-by: default avatarLeo Ma <begeekmyfriend@gmail.com>
parent 4b67a064
No related branches found
No related tags found
No related merge requests found
Showing
with 1955 additions and 0 deletions
/*
* 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);
}
}
}
\ No newline at end of file
/*
* 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");
}
}
}
/*
* 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");
}
}
}
/*
* 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();
}
}
/*
* 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() + "]";
}
}
/*
* 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;
}
}
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);
}
}
}
/*
* 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();
}
}
package com.coremedia.iso.boxes;
import com.googlecode.mp4parser.AbstractFullBox;
import java.nio.ByteBuffer;
/**
* The optional composition shift least greatest atom summarizes the calculated
* minimum and maximum offsets between decode and composition time, as well as
* the start and end times, for all samples. This allows a reader to determine
* the minimum required time for decode to obtain proper presentation order without
* needing to scan the sample table for the range of offsets. The type of the
* composition shift least greatest atom is cslg.
*/
public class CompositionShiftLeastGreatestAtom extends AbstractFullBox {
public CompositionShiftLeastGreatestAtom() {
super("cslg");
}
// A 32-bit unsigned integer that specifies the calculated value.
int compositionOffsetToDisplayOffsetShift;
// A 32-bit signed integer that specifies the calculated value.
int leastDisplayOffset;
// A 32-bit signed integer that specifies the calculated value.
int greatestDisplayOffset;
//A 32-bit signed integer that specifies the calculated value.
int displayStartTime;
//A 32-bit signed integer that specifies the calculated value.
int displayEndTime;
@Override
protected long getContentSize() {
return 24;
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
compositionOffsetToDisplayOffsetShift = content.getInt();
leastDisplayOffset = content.getInt();
greatestDisplayOffset = content.getInt();
displayStartTime = content.getInt();
displayEndTime = content.getInt();
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
byteBuffer.putInt(compositionOffsetToDisplayOffsetShift);
byteBuffer.putInt(leastDisplayOffset);
byteBuffer.putInt(greatestDisplayOffset);
byteBuffer.putInt(displayStartTime);
byteBuffer.putInt(displayEndTime);
}
public int getCompositionOffsetToDisplayOffsetShift() {
return compositionOffsetToDisplayOffsetShift;
}
public void setCompositionOffsetToDisplayOffsetShift(int compositionOffsetToDisplayOffsetShift) {
this.compositionOffsetToDisplayOffsetShift = compositionOffsetToDisplayOffsetShift;
}
public int getLeastDisplayOffset() {
return leastDisplayOffset;
}
public void setLeastDisplayOffset(int leastDisplayOffset) {
this.leastDisplayOffset = leastDisplayOffset;
}
public int getGreatestDisplayOffset() {
return greatestDisplayOffset;
}
public void setGreatestDisplayOffset(int greatestDisplayOffset) {
this.greatestDisplayOffset = greatestDisplayOffset;
}
public int getDisplayStartTime() {
return displayStartTime;
}
public void setDisplayStartTime(int displayStartTime) {
this.displayStartTime = displayStartTime;
}
public int getDisplayEndTime() {
return displayEndTime;
}
public void setDisplayEndTime(int displayEndTime) {
this.displayEndTime = displayEndTime;
}
}
/*
* 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() + "]";
}
}
/*
* 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() + "]";
}
}
/*
* 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;
}
}
/*
* 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);
}
}
/*
* 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 +
'}';
}
}
}
/*
* 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);
}
}
\ No newline at end of file
/*
* 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() + "]";
}
}
/*
* 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() + "]";
}
}
/*
* 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 +
'}';
}
}
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);
}
}
/*
* Copyright 2008 CoreMedia AG, Hamburg
*
* Licensed under the Apache License, Version 2.0 (the License);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.coremedia.iso.boxes;
import com.coremedia.iso.IsoTypeReader;
import com.coremedia.iso.IsoTypeReaderVariable;
import com.coremedia.iso.IsoTypeWriter;
import com.coremedia.iso.IsoTypeWriterVariable;
import com.googlecode.mp4parser.AbstractFullBox;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.LinkedList;
import java.util.List;
/**
* aligned(8) class ItemLocationBox extends FullBox(iloc, version, 0) {
* unsigned int(4) offset_size;
* unsigned int(4) length_size;
* unsigned int(4) base_offset_size;
* if (version == 1)
* unsigned int(4) index_size;
* else
* unsigned int(4) reserved;
* unsigned int(16) item_count;
* for (i=0; i<item_count; i++) {
* unsigned int(16) item_ID;
* if (version == 1) {
* unsigned int(12) reserved = 0;
* unsigned int(4) construction_method;
* }
* unsigned int(16) data_reference_index;
* unsigned int(base_offset_size*8) base_offset;
* unsigned int(16) extent_count;
* for (j=0; j<extent_count; j++) {
* if ((version == 1) && (index_size > 0)) {
* unsigned int(index_size*8) extent_index;
* }
* unsigned int(offset_size*8) extent_offset;
* unsigned int(length_size*8) extent_length;
* }
* }
* }
*/
public class ItemLocationBox extends AbstractFullBox {
public int offsetSize = 8;
public int lengthSize = 8;
public int baseOffsetSize = 8;
public int indexSize = 0;
public List<Item> items = new LinkedList<Item>();
public static final String TYPE = "iloc";
public ItemLocationBox() {
super(TYPE);
}
@Override
protected long getContentSize() {
long size = 8;
for (Item item : items) {
size += item.getSize();
}
return size;
}
@Override
protected void getContent(ByteBuffer byteBuffer) {
writeVersionAndFlags(byteBuffer);
IsoTypeWriter.writeUInt8(byteBuffer, ((offsetSize << 4) | lengthSize));
if (getVersion() == 1) {
IsoTypeWriter.writeUInt8(byteBuffer, (baseOffsetSize << 4 | indexSize));
} else {
IsoTypeWriter.writeUInt8(byteBuffer, (baseOffsetSize << 4));
}
IsoTypeWriter.writeUInt16(byteBuffer, items.size());
for (Item item : items) {
item.getContent(byteBuffer);
}
}
@Override
public void _parseDetails(ByteBuffer content) {
parseVersionAndFlags(content);
int tmp = IsoTypeReader.readUInt8(content);
offsetSize = tmp >>> 4;
lengthSize = tmp & 0xf;
tmp = IsoTypeReader.readUInt8(content);
baseOffsetSize = tmp >>> 4;
if (getVersion() == 1) {
indexSize = tmp & 0xf;
}
int itemCount = IsoTypeReader.readUInt16(content);
for (int i = 0; i < itemCount; i++) {
items.add(new Item(content));
}
}
public int getOffsetSize() {
return offsetSize;
}
public void setOffsetSize(int offsetSize) {
this.offsetSize = offsetSize;
}
public int getLengthSize() {
return lengthSize;
}
public void setLengthSize(int lengthSize) {
this.lengthSize = lengthSize;
}
public int getBaseOffsetSize() {
return baseOffsetSize;
}
public void setBaseOffsetSize(int baseOffsetSize) {
this.baseOffsetSize = baseOffsetSize;
}
public int getIndexSize() {
return indexSize;
}
public void setIndexSize(int indexSize) {
this.indexSize = indexSize;
}
public List<Item> getItems() {
return items;
}
public void setItems(List<Item> items) {
this.items = items;
}
public Item createItem(int itemId, int constructionMethod, int dataReferenceIndex, long baseOffset, List<Extent> extents) {
return new Item(itemId, constructionMethod, dataReferenceIndex, baseOffset, extents);
}
Item createItem(ByteBuffer bb) {
return new Item(bb);
}
public class Item {
public int itemId;
public int constructionMethod;
public int dataReferenceIndex;
public long baseOffset;
public List<Extent> extents = new LinkedList<Extent>();
public Item(ByteBuffer in) {
itemId = IsoTypeReader.readUInt16(in);
if (getVersion() == 1) {
int tmp = IsoTypeReader.readUInt16(in);
constructionMethod = tmp & 0xf;
}
dataReferenceIndex = IsoTypeReader.readUInt16(in);
if (baseOffsetSize > 0) {
baseOffset = IsoTypeReaderVariable.read(in, baseOffsetSize);
} else {
baseOffset = 0;
}
int extentCount = IsoTypeReader.readUInt16(in);
for (int i = 0; i < extentCount; i++) {
extents.add(new Extent(in));
}
}
public Item(int itemId, int constructionMethod, int dataReferenceIndex, long baseOffset, List<Extent> extents) {
this.itemId = itemId;
this.constructionMethod = constructionMethod;
this.dataReferenceIndex = dataReferenceIndex;
this.baseOffset = baseOffset;
this.extents = extents;
}
public int getSize() {
int size = 2;
if (getVersion() == 1) {
size += 2;
}
size += 2;
size += baseOffsetSize;
size += 2;
for (Extent extent : extents) {
size += extent.getSize();
}
return size;
}
public void setBaseOffset(long baseOffset) {
this.baseOffset = baseOffset;
}
public void getContent(ByteBuffer bb) {
IsoTypeWriter.writeUInt16(bb, itemId);
if (getVersion() == 1) {
IsoTypeWriter.writeUInt16(bb, constructionMethod);
}
IsoTypeWriter.writeUInt16(bb, dataReferenceIndex);
if (baseOffsetSize > 0) {
IsoTypeWriterVariable.write(baseOffset, bb, baseOffsetSize);
}
IsoTypeWriter.writeUInt16(bb, extents.size());
for (Extent extent : extents) {
extent.getContent(bb);
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Item item = (Item) o;
if (baseOffset != item.baseOffset) return false;
if (constructionMethod != item.constructionMethod) return false;
if (dataReferenceIndex != item.dataReferenceIndex) return false;
if (itemId != item.itemId) return false;
if (extents != null ? !extents.equals(item.extents) : item.extents != null) return false;
return true;
}
@Override
public int hashCode() {
int result = itemId;
result = 31 * result + constructionMethod;
result = 31 * result + dataReferenceIndex;
result = 31 * result + (int) (baseOffset ^ (baseOffset >>> 32));
result = 31 * result + (extents != null ? extents.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "Item{" +
"baseOffset=" + baseOffset +
", itemId=" + itemId +
", constructionMethod=" + constructionMethod +
", dataReferenceIndex=" + dataReferenceIndex +
", extents=" + extents +
'}';
}
}
public Extent createExtent(long extentOffset, long extentLength, long extentIndex) {
return new Extent(extentOffset, extentLength, extentIndex);
}
Extent createExtent(ByteBuffer bb) {
return new Extent(bb);
}
public class Extent {
public long extentOffset;
public long extentLength;
public long extentIndex;
public Extent(long extentOffset, long extentLength, long extentIndex) {
this.extentOffset = extentOffset;
this.extentLength = extentLength;
this.extentIndex = extentIndex;
}
public Extent(ByteBuffer in) {
if ((getVersion() == 1) && indexSize > 0) {
extentIndex = IsoTypeReaderVariable.read(in, indexSize);
}
extentOffset = IsoTypeReaderVariable.read(in, offsetSize);
extentLength = IsoTypeReaderVariable.read(in, lengthSize);
}
public void getContent(ByteBuffer os) {
if ((getVersion() == 1) && indexSize > 0) {
IsoTypeWriterVariable.write(extentIndex, os, indexSize);
}
IsoTypeWriterVariable.write(extentOffset, os, offsetSize);
IsoTypeWriterVariable.write(extentLength, os, lengthSize);
}
public int getSize() {
return (indexSize > 0 ? indexSize : 0) + offsetSize + lengthSize;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Extent extent = (Extent) o;
if (extentIndex != extent.extentIndex) return false;
if (extentLength != extent.extentLength) return false;
if (extentOffset != extent.extentOffset) return false;
return true;
}
@Override
public int hashCode() {
int result = (int) (extentOffset ^ (extentOffset >>> 32));
result = 31 * result + (int) (extentLength ^ (extentLength >>> 32));
result = 31 * result + (int) (extentIndex ^ (extentIndex >>> 32));
return result;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("Extent");
sb.append("{extentOffset=").append(extentOffset);
sb.append(", extentLength=").append(extentLength);
sb.append(", extentIndex=").append(extentIndex);
sb.append('}');
return sb.toString();
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment