Mp4StcoBoxpublic class Mp4StcoBox extends AbstractMp4Box StcoBox ( media (stream) header), holds offsets into the Audio data |
Fields Summary |
---|
public static final int | VERSION_FLAG_POS | public static final int | OTHER_FLAG_POS | public static final int | NO_OF_OFFSETS_POS | public static final int | VERSION_FLAG_LENGTH | public static final int | OTHER_FLAG_LENGTH | public static final int | NO_OF_OFFSETS_LENGTH | public static final int | OFFSET_LENGTH | private int | noOfOffSets | private int | firstOffSet |
Constructors Summary |
---|
public Mp4StcoBox(Mp4BoxHeader header, ByteBuffer buffer)Construct box from data and show contents
this.header = header;
//Make a slice of databuffer then we can work with relative or absolute methods safetly
dataBuffer = buffer.slice();
//Skip the flags
dataBuffer.position(dataBuffer.position() + VERSION_FLAG_LENGTH + OTHER_FLAG_LENGTH);
//No of offsets
this.noOfOffSets = Utils.getIntBE(dataBuffer, dataBuffer.position(), (dataBuffer.position() + NO_OF_OFFSETS_LENGTH - 1));
dataBuffer.position(dataBuffer.position() + NO_OF_OFFSETS_LENGTH);
//First Offset, useful for sanity checks
firstOffSet = Utils.getIntBE(dataBuffer, dataBuffer.position(), (dataBuffer.position() + OFFSET_LENGTH - 1));
| public Mp4StcoBox(Mp4BoxHeader header, ByteBuffer originalDataBuffer, int adjustment)Construct box from data and adjust offets accordingly
this.header = header;
//Make a slice of databuffer then we can work with relative or absolute methods safetly
this.dataBuffer = originalDataBuffer.slice();
//Skip the flags
dataBuffer.position(dataBuffer.position() + VERSION_FLAG_LENGTH + OTHER_FLAG_LENGTH);
//No of offsets
this.noOfOffSets = Utils.getIntBE(dataBuffer, dataBuffer.position(), (dataBuffer.position() + NO_OF_OFFSETS_LENGTH - 1));
dataBuffer.position(dataBuffer.position() + NO_OF_OFFSETS_LENGTH);
for (int i = 0; i < noOfOffSets; i++)
{
int offset = Utils.getIntBE(dataBuffer, dataBuffer.position(), (dataBuffer.position() + NO_OF_OFFSETS_LENGTH - 1));
//Calculate new offset and update buffer
offset = offset + adjustment;
dataBuffer.put(Utils.getSizeBEInt32(offset));
}
|
Methods Summary |
---|
public void | adjustOffsets(int adjustment)
//Skip the flags
dataBuffer.rewind();
dataBuffer.position(dataBuffer.position() + VERSION_FLAG_LENGTH + OTHER_FLAG_LENGTH + NO_OF_OFFSETS_LENGTH);
for (int i = 0; i < noOfOffSets; i++)
{
int offset = Utils.getIntBE(dataBuffer, dataBuffer.position(), (dataBuffer.position() + NO_OF_OFFSETS_LENGTH - 1));
//Calculate new offset and update buffer
offset = offset + adjustment;
dataBuffer.put(Utils.getSizeBEInt32(offset));
}
| public static void | debugShowStcoInfo(java.io.RandomAccessFile raf)
Mp4BoxHeader moovHeader = Mp4BoxHeader.seekWithinLevel(raf, Mp4AtomIdentifier.MOOV.getFieldName());
if (moovHeader == null)
{
throw new CannotReadException("This file does not appear to be an audio file");
}
ByteBuffer moovBuffer = ByteBuffer.allocate(moovHeader.getLength() - Mp4BoxHeader.HEADER_LENGTH);
raf.getChannel().read(moovBuffer);
moovBuffer.rewind();
//Level 2-Searching for "mvhd" somewhere within "moov", we make a slice after finding header
//so all getFields() methods will be relative to mvdh positions
Mp4BoxHeader boxHeader = Mp4BoxHeader.seekWithinLevel(moovBuffer, Mp4AtomIdentifier.MVHD.getFieldName());
if (boxHeader == null)
{
throw new CannotReadException("This file does not appear to be an audio file");
}
ByteBuffer mvhdBuffer = moovBuffer.slice();
Mp4MvhdBox mvhd = new Mp4MvhdBox(boxHeader, mvhdBuffer);
mvhdBuffer.position(mvhdBuffer.position() + boxHeader.getDataLength());
//Level 2-Searching for "trak" within "moov"
boxHeader = Mp4BoxHeader.seekWithinLevel(mvhdBuffer, Mp4AtomIdentifier.TRAK.getFieldName());
int endOfFirstTrackInBuffer = mvhdBuffer.position() + boxHeader.getDataLength();
if (boxHeader == null)
{
throw new CannotReadException("This file does not appear to be an audio file");
}
//Level 3-Searching for "mdia" within "trak"
boxHeader = Mp4BoxHeader.seekWithinLevel(mvhdBuffer, Mp4AtomIdentifier.MDIA.getFieldName());
if (boxHeader == null)
{
throw new CannotReadException("This file does not appear to be an audio file");
}
//Level 4-Searching for "mdhd" within "mdia"
boxHeader = Mp4BoxHeader.seekWithinLevel(mvhdBuffer, Mp4AtomIdentifier.MDHD.getFieldName());
if (boxHeader == null)
{
throw new CannotReadException("This file does not appear to be an audio file");
}
//Level 4-Searching for "minf" within "mdia"
mvhdBuffer.position(mvhdBuffer.position() + boxHeader.getDataLength());
boxHeader = Mp4BoxHeader.seekWithinLevel(mvhdBuffer, Mp4AtomIdentifier.MINF.getFieldName());
if (boxHeader == null)
{
throw new CannotReadException("This file does not appear to be an audio file");
}
//Level 5-Searching for "smhd" within "minf"
//Only an audio track would have a smhd frame
boxHeader = Mp4BoxHeader.seekWithinLevel(mvhdBuffer, Mp4AtomIdentifier.SMHD.getFieldName());
if (boxHeader == null)
{
throw new CannotReadException("This file does not appear to be an audio file");
}
mvhdBuffer.position(mvhdBuffer.position() + boxHeader.getDataLength());
//Level 5-Searching for "stbl within "minf"
boxHeader = Mp4BoxHeader.seekWithinLevel(mvhdBuffer, Mp4AtomIdentifier.STBL.getFieldName());
if (boxHeader == null)
{
throw new CannotReadException("This file does not appear to be an audio file");
}
//Level 6-Searching for "stco within "stbl"
boxHeader = Mp4BoxHeader.seekWithinLevel(mvhdBuffer, Mp4AtomIdentifier.STCO.getFieldName());
if (boxHeader == null)
{
throw new CannotReadException("This file does not appear to be an audio file");
}
Mp4StcoBox stco = new Mp4StcoBox(boxHeader, mvhdBuffer);
stco.printAlloffsets();
| public int | getFirstOffSet()The value of the first offset
return firstOffSet;
| public int | getNoOfOffSets()The number of offsets
return noOfOffSets;
| public void | printAlloffsets()Show All offsets, useful for debugging
System.out.println("Print Offsets:start");
dataBuffer.rewind();
dataBuffer.position(VERSION_FLAG_LENGTH + OTHER_FLAG_LENGTH + NO_OF_OFFSETS_LENGTH);
for (int i = 0; i < noOfOffSets - 1; i++)
{
int offset = Utils.getIntBE(dataBuffer, dataBuffer.position(), (dataBuffer.position() + OFFSET_LENGTH - 1));
System.out.println("offset into audio data is:" + offset);
dataBuffer.position(dataBuffer.position() + OFFSET_LENGTH);
}
int offset = Utils.getIntBE(dataBuffer, dataBuffer.position(), (dataBuffer.position() + OFFSET_LENGTH - 1));
System.out.println("offset into audio data is:" + offset);
System.out.println("Print Offsets:end");
| public void | printTotalOffset()
int offset = 0;
dataBuffer.rewind();
dataBuffer.position(VERSION_FLAG_LENGTH + OTHER_FLAG_LENGTH + NO_OF_OFFSETS_LENGTH);
for (int i = 0; i < noOfOffSets - 1; i++)
{
offset += Utils.getIntBE(dataBuffer, dataBuffer.position(), (dataBuffer.position() + OFFSET_LENGTH - 1));
dataBuffer.position(dataBuffer.position() + OFFSET_LENGTH);
}
offset += Utils.getIntBE(dataBuffer, dataBuffer.position(), (dataBuffer.position() + OFFSET_LENGTH - 1));
System.out.println("Print Offset Total:" + offset);
|
|