/** * Return the size required by all the extra packets on same page as setup header, usually there * are no packets immediately after the setup packet. * * @return extra data size required for additional packets on same page */ public int getExtraPacketDataSize() { int extraPacketSize = 0; for (OggPageHeader.PacketStartAndLength packet : packetList) { extraPacketSize += packet.getLength(); } return extraPacketSize; }
/** * Calculate the size of the packet data for the comment and setup headers * * @param raf * @return * @throws CannotReadException * @throws IOException */ public OggVorbisHeaderSizes readOggVorbisHeaderSizes(RandomAccessFile raf) throws CannotReadException, IOException { // //logger.fine("Started to read comment and setup header sizes:"); // Stores filepointers so return file in same state long filepointer = raf.getFilePointer(); // Extra Packets on same page as setup header List<OggPageHeader.PacketStartAndLength> extraPackets = new ArrayList<OggPageHeader.PacketStartAndLength>(); long commentHeaderStartPosition; long setupHeaderStartPosition; int commentHeaderSize = 0; int setupHeaderSize; // 1st page = codec infos OggPageHeader pageHeader = OggPageHeader.read(raf); // Skip over data to end of page header 1 raf.seek(raf.getFilePointer() + pageHeader.getPageLength()); // 2nd page = comment, may extend to additional pages or not , may also have setup header pageHeader = OggPageHeader.read(raf); commentHeaderStartPosition = raf.getFilePointer() - (OggPageHeader.OGG_PAGE_HEADER_FIXED_LENGTH + pageHeader.getSegmentTable().length); // Now at start of packets on page 2 , check this is the vorbis comment header byte[] b = new byte[VorbisHeader.FIELD_PACKET_TYPE_LENGTH + VorbisHeader.FIELD_CAPTURE_PATTERN_LENGTH]; raf.read(b); if (!isVorbisCommentHeader(b)) { throw new CannotReadException("Cannot find comment block (no vorbiscomment header)"); } raf.seek( raf.getFilePointer() - (VorbisHeader.FIELD_PACKET_TYPE_LENGTH + VorbisHeader.FIELD_CAPTURE_PATTERN_LENGTH)); // //logger.fine("Found start of comment header at:" + raf.getFilePointer()); // Calculate Comment Size (not inc header) while (true) { List<OggPageHeader.PacketStartAndLength> packetList = pageHeader.getPacketList(); commentHeaderSize += packetList.get(0).getLength(); raf.skipBytes(packetList.get(0).getLength()); // If this page contains multiple packets or if this last packet is complete then the Comment // header // end son this page and we can break if (packetList.size() > 1 || !pageHeader.isLastPacketIncomplete()) { // done comment size // //logger.fine("Found end of comment:size:" + commentHeaderSize + "finishes // at file position:" + raf.getFilePointer()); break; } pageHeader = OggPageHeader.read(raf); } // If there are no more packets on this page we need to go to next page to get the setup header OggPageHeader.PacketStartAndLength packet; if (pageHeader.getPacketList().size() == 1) { pageHeader = OggPageHeader.read(raf); List<OggPageHeader.PacketStartAndLength> packetList = pageHeader.getPacketList(); packet = pageHeader.getPacketList().get(0); // Now at start of next packet , check this is the vorbis setup header b = new byte [VorbisHeader.FIELD_PACKET_TYPE_LENGTH + VorbisHeader.FIELD_CAPTURE_PATTERN_LENGTH]; raf.read(b); if (!isVorbisSetupHeader(b)) { throw new CannotReadException(ErrorMessage.OGG_VORBIS_NO_VORBIS_HEADER_FOUND.getMsg()); } raf.seek( raf.getFilePointer() - (VorbisHeader.FIELD_PACKET_TYPE_LENGTH + VorbisHeader.FIELD_CAPTURE_PATTERN_LENGTH)); // //logger.fine("Found start of vorbis setup header at file position:" + // raf.getFilePointer()); // Set this to the start of the OggPage that setupheader was found on setupHeaderStartPosition = raf.getFilePointer() - (OggPageHeader.OGG_PAGE_HEADER_FIXED_LENGTH + pageHeader.getSegmentTable().length); // Add packet data to size to the setup header size setupHeaderSize = packet.getLength(); // //logger.fine("Adding:" + packetList.get(1).getLength() + " to setup header size"); // Skip over the packet data raf.skipBytes(packet.getLength()); // If there are other packets that follow this one, or if the last packet is complete then we // must have // got the size of the setup header. if (packetList.size() > 1 || !pageHeader.isLastPacketIncomplete()) { // logger.info("Found end of setupheader:size:" + setupHeaderSize + "finishes // at:" + raf.getFilePointer()); if (packetList.size() > 1) { extraPackets = packetList.subList(1, packetList.size()); } } // The setup header continues onto the next page else { pageHeader = OggPageHeader.read(raf); packetList = pageHeader.getPacketList(); while (true) { setupHeaderSize += packetList.get(0).getLength(); // logger.fine("Adding:" + packetList.get(0).getLength() + " to setup // header size"); raf.skipBytes(packetList.get(0).getLength()); if (packetList.size() > 1 || !pageHeader.isLastPacketIncomplete()) { // done setup size // logger.fine("Found end of setupheader:size:" + setupHeaderSize // + "finishes at:" + raf.getFilePointer()); if (packetList.size() > 1) { extraPackets = packetList.subList(1, packetList.size()); } break; } // Continues onto another page pageHeader = OggPageHeader.read(raf); } } } // else its next packet on this page else { packet = pageHeader.getPacketList().get(1); List<OggPageHeader.PacketStartAndLength> packetList = pageHeader.getPacketList(); // Now at start of next packet , check this is the vorbis setup header b = new byte [VorbisHeader.FIELD_PACKET_TYPE_LENGTH + VorbisHeader.FIELD_CAPTURE_PATTERN_LENGTH]; raf.read(b); if (!isVorbisSetupHeader(b)) { // logger.warning("Expecting but got:" + new String(b) + "at " + (raf.getFilePointer() - // b.length)); throw new CannotReadException(ErrorMessage.OGG_VORBIS_NO_VORBIS_HEADER_FOUND.getMsg()); } raf.seek( raf.getFilePointer() - (VorbisHeader.FIELD_PACKET_TYPE_LENGTH + VorbisHeader.FIELD_CAPTURE_PATTERN_LENGTH)); // logger.info("Found start of vorbis setup header at file position:" + // raf.getFilePointer()); // Set this to the start of the OggPage that setupheader was found on setupHeaderStartPosition = raf.getFilePointer() - (OggPageHeader.OGG_PAGE_HEADER_FIXED_LENGTH + pageHeader.getSegmentTable().length) - pageHeader.getPacketList().get(0).getLength(); // Add packet data to size to the setup header size setupHeaderSize = packet.getLength(); // logger.fine("Adding:" + packet.getLength() + " to setup header size"); // Skip over the packet data raf.skipBytes(packet.getLength()); // If there are other packets that follow this one, or if the last packet is complete then we // must have // got the size of the setup header. if (packetList.size() > 2 || !pageHeader.isLastPacketIncomplete()) { // logger.fine("Found end of setupheader:size:" + setupHeaderSize + "finishes // at:" + raf.getFilePointer()); if (packetList.size() > 2) { extraPackets = packetList.subList(2, packetList.size()); } } // The setup header continues onto the next page else { pageHeader = OggPageHeader.read(raf); packetList = pageHeader.getPacketList(); while (true) { setupHeaderSize += packetList.get(0).getLength(); // logger.fine("Adding:" + packetList.get(0).getLength() + " to setup // header size"); raf.skipBytes(packetList.get(0).getLength()); if (packetList.size() > 1 || !pageHeader.isLastPacketIncomplete()) { // done setup size // logger.fine("Found end of setupheader:size:" + setupHeaderSize // + "finishes at:" + raf.getFilePointer()); if (packetList.size() > 1) { extraPackets = packetList.subList(1, packetList.size()); } break; } // Continues onto another page pageHeader = OggPageHeader.read(raf); } } } // Reset filepointer to location that it was in at start of method raf.seek(filepointer); return new OggVorbisHeaderSizes( commentHeaderStartPosition, setupHeaderStartPosition, commentHeaderSize, setupHeaderSize, extraPackets); }