diff options
Diffstat (limited to 'isoparser/src/main/java/com/coremedia/iso/.svn/text-base/AbstractBoxParser.java.svn-base')
-rw-r--r-- | isoparser/src/main/java/com/coremedia/iso/.svn/text-base/AbstractBoxParser.java.svn-base | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/isoparser/src/main/java/com/coremedia/iso/.svn/text-base/AbstractBoxParser.java.svn-base b/isoparser/src/main/java/com/coremedia/iso/.svn/text-base/AbstractBoxParser.java.svn-base new file mode 100644 index 0000000..6d92acd --- /dev/null +++ b/isoparser/src/main/java/com/coremedia/iso/.svn/text-base/AbstractBoxParser.java.svn-base @@ -0,0 +1,130 @@ +/* + * 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 com.coremedia.iso.boxes.Box; +import com.coremedia.iso.boxes.ContainerBox; +import com.coremedia.iso.boxes.UserBox; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.channels.ReadableByteChannel; +import java.util.logging.Logger; + +import static com.googlecode.mp4parser.util.CastUtils.l2i; + +/** + * This BoxParser handles the basic stuff like reading size and extracting box type. + */ +public abstract class AbstractBoxParser implements BoxParser { + + private static Logger LOG = Logger.getLogger(AbstractBoxParser.class.getName()); + + public abstract Box createBox(String type, byte[] userType, String parent); + + /** + * Parses the next size and type, creates a box instance and parses the box's content. + * + * @param byteChannel the FileChannel pointing to the ISO file + * @param parent the current box's parent (null if no parent) + * @return the box just parsed + * @throws java.io.IOException if reading from <code>in</code> fails + */ + public Box parseBox(ReadableByteChannel byteChannel, ContainerBox parent) throws IOException { + + + ByteBuffer header = ChannelHelper.readFully(byteChannel, 8); + + long size = IsoTypeReader.readUInt32(header); + // do plausibility check + if (size < 8 && size > 1) { + LOG.severe("Plausibility check failed: size < 8 (size = " + size + "). Stop parsing!"); + return null; + } + + + String type = IsoTypeReader.read4cc(header); + byte[] usertype = null; + long contentSize; + + if (size == 1) { + ByteBuffer bb = ByteBuffer.allocate(8); + byteChannel.read(bb); + bb.rewind(); + size = IsoTypeReader.readUInt64(bb); + contentSize = size - 16; + } else if (size == 0) { + if (byteChannel instanceof FileChannel) { + size = ((FileChannel) byteChannel).size() - ((FileChannel) byteChannel).position() - 8; + } else { + throw new RuntimeException("Only FileChannel inputs may use size == 0 (box reaches to the end of file)"); + } + contentSize = size - 8; + } else { + contentSize = size - 8; + } + if (UserBox.TYPE.equals(type)) { + ByteBuffer bb = ByteBuffer.allocate(16); + byteChannel.read(bb); + bb.rewind(); + usertype = bb.array(); + contentSize -= 16; + } + Box box = createBox(type, usertype, parent.getType()); + box.setParent(parent); + LOG.finest("Parsing " + box.getType()); + // System.out.println("parsing " + Arrays.toString(box.getType()) + " " + box.getClass().getName() + " size=" + size); + + + if (l2i(size - contentSize) == 8) { + // default - no large box - no uuid + // do nothing header's already correct + header.rewind(); + } else if (l2i(size - contentSize) == 16) { + header = ByteBuffer.allocate(16); + IsoTypeWriter.writeUInt32(header, 1); + header.put(IsoFile.fourCCtoBytes(type)); + IsoTypeWriter.writeUInt64(header, size); + } else if (l2i(size - contentSize) == 24) { + header = ByteBuffer.allocate(24); + IsoTypeWriter.writeUInt32(header, size); + header.put(IsoFile.fourCCtoBytes(type)); + header.put(usertype); + } else if (l2i(size - contentSize) == 32) { + header = ByteBuffer.allocate(32); + IsoTypeWriter.writeUInt32(header, size); + header.put(IsoFile.fourCCtoBytes(type)); + IsoTypeWriter.writeUInt64(header, size); + header.put(usertype); + } else { + throw new RuntimeException("I didn't expect that"); + } + + + box.parse(byteChannel, header, contentSize, this); + // System.out.println("box = " + box); + + + assert size == box.getSize() : + "Reconstructed Size is not x to the number of parsed bytes! (" + + box.getType() + ")" + + " Actual Box size: " + size + " Calculated size: " + box.getSize(); + return box; + } + + +} |