public QTFastStartRAF(FileAccessor accessor, boolean enable) throws IOException { input = accessor; if (enable) { String name = accessor.getName(); boolean log; String fail = null; synchronized (tested) { log = !tested.contains(name); if (log) { tested.add(name); } } try { Atom ah = null; Atom ftypAtom = null; boolean gotFtyp = false; boolean gotMdat = false; boolean justCopy = false; while (input.getFilePointer() < input.length()) { ah = new Atom(input); // System.out.println( "got " + ah.type +", size=" + ah.size ); if (!isValidTopLevelAtom(ah)) { throw new IOException("Non top level QT atom found (" + ah.type + "). File invalid?"); } if (gotFtyp && !gotMdat && ah.type.equalsIgnoreCase(ATOM_MOOV)) { justCopy = true; break; } // store ftyp atom to buffer if (ah.type.equalsIgnoreCase(ATOM_FTYP)) { ftypAtom = ah; ftypAtom.fillBuffer(input); gotFtyp = true; } else if (ah.type.equalsIgnoreCase(ATOM_MDAT)) { gotMdat = true; input.skipBytes((int) ah.size); } else { input.skipBytes((int) ah.size); } } if (justCopy) { transparent = true; return; } if (ftypAtom == null) { throw new IOException("No FTYP atom found"); } if (ah == null || !ah.type.equalsIgnoreCase(ATOM_MOOV)) { throw new IOException("Last QT atom was not the MOOV atom."); } input.seek(ah.offset); Atom moovAtom = ah; moovAtom.fillBuffer(input); if (isCompressedMoovAtom(moovAtom)) { throw new IOException("Compressed MOOV qt atoms are not supported"); } patchMoovAtom(moovAtom); body_start = ftypAtom.offset + ftypAtom.size; body_end = moovAtom.offset; header = new byte[ftypAtom.buffer.length + moovAtom.buffer.length]; System.arraycopy(ftypAtom.buffer, 0, header, 0, ftypAtom.buffer.length); System.arraycopy( moovAtom.buffer, 0, header, ftypAtom.buffer.length, moovAtom.buffer.length); if (accessor.length() != header.length + (body_end - body_start)) { throw (new IOException("Inconsistent: file size has changed")); } } catch (Throwable e) { // e.printStackTrace(); fail = Debug.getNestedExceptionMessage(e); transparent = true; } finally { input.seek(0); if (log) { String message; if (fail == null) { message = transparent ? "Not required" : "Required"; } else { message = "Failed - " + fail; } Debug.outNoStack("MOOV relocation for " + accessor.getName() + ": " + message); } } } else { transparent = true; } }
public long length() throws IOException { return (input.length()); }