001package net.bramp.ffmpeg.nut; 002 003import com.google.common.base.MoreObjects; 004import java.io.IOException; 005import org.slf4j.Logger; 006import org.slf4j.LoggerFactory; 007 008public class Packet { 009 010 static final Logger LOG = LoggerFactory.getLogger(Packet.class); 011 012 public enum Startcode { 013 MAIN(0x7A561F5F04ADL + (((long) ('N' << 8) + 'M') << 48)), 014 STREAM(0x11405BF2F9DBL + (((long) ('N' << 8) + 'S') << 48)), 015 SYNCPOINT(0xE4ADEECA4569L + (((long) ('N' << 8) + 'K') << 48)), 016 INDEX(0xDD672F23E64EL + (((long) ('N' << 8) + 'X') << 48)), 017 INFO(0xAB68B596BA78L + (((long) ('N' << 8) + 'I') << 48)); 018 019 private final long startcode; 020 021 Startcode(long startcode) { 022 this.startcode = startcode; 023 } 024 025 public long value() { 026 return startcode; 027 } 028 029 public boolean equalsCode(long startcode) { 030 return this.startcode == startcode; 031 } 032 033 /** 034 * Returns the Startcode enum for this code. 035 * 036 * @param startcode The numeric code for this Startcode. 037 * @return The Startcode 038 */ 039 public static Startcode of(long startcode) { 040 for (Startcode c : Startcode.values()) { 041 if (c.equalsCode(startcode)) { 042 return c; 043 } 044 } 045 return null; 046 } 047 048 public static boolean isPossibleStartcode(long startcode) { 049 return (startcode & 0xFFL) == 'N'; 050 } 051 052 public static String toString(long startcode) { 053 Startcode c = of(startcode); 054 if (c != null) { 055 return c.name(); 056 } 057 return String.format("%X", startcode); 058 } 059 } 060 061 public final PacketHeader header = new PacketHeader(); 062 public final PacketFooter footer = new PacketFooter(); 063 064 protected void readBody(NutDataInputStream in) throws IOException { 065 // Default implementation does nothing 066 } 067 068 public void read(NutDataInputStream in, long startcode) throws IOException { 069 header.read(in, startcode); 070 readBody(in); 071 seekToPacketFooter(in); 072 footer.read(in); 073 } 074 075 public void seekToPacketFooter(NutDataInputStream in) throws IOException { 076 long current = in.offset(); 077 if (current > header.end) { 078 throw new IOException("Can not seek backwards at:" + current + " end:" + header.end); 079 } 080 // TODO Fix this to not cast longs to ints 081 in.skipBytes((int) (header.end - current)); 082 } 083 084 @Override 085 public String toString() { 086 return MoreObjects.toStringHelper(this).add("header", header).add("footer", footer).toString(); 087 } 088}