User Tools

Site Tools


tech:multimedia:asf_parser
package JTest;
 
import java.io.*;
import java.util.Vector;
 
public class MyTest {
 
	public static void main(String[] args) throws IOException {
		File file = new File(args[0]);
    	FileInputStream in = new FileInputStream(file);    	
    	ASFTopObject asf = new ASFTopObject(file.length(), 0);
 
    	if (asf.parse(in)) {
    		asf.dump();
    	} else {
    		System.out.println("Error[PARSE]");
    	}
    }
}
 
class ASFParser {
	public static final byte GUID_Header[] = {0x30, 0x26, (byte) 0xB2, 0x75, (byte) 0x8E, 0x66, (byte) 0xCF, 0x11,
		                                     (byte) 0xA6, (byte) 0xD9, 0x00, (byte) 0xAA, 0x00, 0x62, (byte) 0xCE, 0x6C};
    public static final byte GUID_Data[] = {0x36, 0x26, (byte) 0xb2, 0x75, (byte) 0x8E, 0x66, (byte) 0xCF, 0x11, 
    	                                     (byte) 0xa6, (byte) 0xd9, 0x00, (byte) 0xaa, 0x00, 0x62, (byte) 0xce, 0x6c};
    public static final byte GUID_Index[] = {(byte) 0xD3, 0x29, (byte) 0xE2, (byte) 0xD6, (byte) 0xDA, (byte) 0x35, (byte) 0xD1, 0x11, 
    	                                     (byte) 0x90, 0x34, 0x00, (byte) 0xA0, (byte) 0xC9, 0x03, 0x49, (byte) 0xBE};
    public static final byte GUID_Simple_Index[] = {(byte) 0x90, 0x08, 0x00, 0x33, (byte) 0xB1, (byte) 0xE5, (byte) 0xCF, 0x11, 
    	                                            (byte) 0x89, (byte) 0xF4, 0x00, (byte) 0xA0, (byte) 0xC9, 0x03, 0x49, (byte) 0xCB};
	public static final byte GUID_File_Properties[] = {(byte) 0xA1, (byte) 0xDC, (byte) 0xAB, (byte) 0x8C, 0x47, (byte) 0xA9, (byte) 0xCF, 0x11, 
		                                               (byte) 0x8E, (byte) 0xE4, 0x00, (byte) 0xC0, 0x0C, 0x20, 0x53, 0x65};
	public static final byte GUID_Stream_Properties[] = {(byte) 0x91, 0x07, (byte) 0xDC, (byte) 0xB7, (byte) 0xB7, (byte) 0xA9, (byte) 0xCF, 0x11, 
		                                                 (byte) 0x8E, (byte) 0xE6, 0x00, (byte) 0xC0, 0x0C, 0x20, 0x53, 0x65};
	public static final byte GUID_Codec_List[] = {0x40, 0x52, (byte) 0xD1, (byte) 0x86, 0x1D, 0x31, (byte) 0xD0, 0x11, 
		                                          (byte) 0xA3, (byte) 0xA4, 0x00, (byte) 0xA0, (byte) 0xC9, 0x03, 0x48, (byte) 0xF6};
	public static final byte GUID_Header_Ext[] = {(byte) 0xb5, 0x03, (byte) 0xbf, 0x5f, 0x2E, (byte) 0xA9, (byte) 0xCF, 0x11, 
		                                          (byte) 0x8e, (byte) 0xe3, 0x00, (byte) 0xc0, 0x0c, 0x20, 0x53, 0x65};
	public static final byte GUID_Content_Description[] = {0x33, 0x26, (byte) 0xb2, 0x75, (byte) 0x8E, 0x66, (byte) 0xCF, 0x11, 
		                                                  (byte) 0xa6, (byte) 0xd9, 0x00, (byte) 0xaa, 0x00, 0x62, (byte) 0xce, 0x6c};
	public static final byte GUID_Content_Description_Ext[] = {0x40, (byte) 0xA4,(byte)  0xD0, (byte) 0xD2, 0x07, (byte) 0xE3, (byte) 0xD2, 0x11, 
		                                                      (byte) 0x97, (byte) 0xF0, 0x00, (byte) 0xA0, (byte) 0xC9, 0x5E, (byte) 0xA8, 0x50};
	public static final byte GUID_Audio_Stream[] = {0x40, (byte) 0x9E, 0x69, (byte) 0xF8, 0x4D, 0x5B, (byte) 0xCF, 0x11, 
		                                           (byte) 0xA8, (byte) 0xFD, 0x00, (byte) 0x80, 0x5F, 0x5C, 0x44, 0x2B};
	public static final byte GUID_Video_Stream[] = {(byte) 0xC0, (byte) 0xEF, 0x19, (byte) 0xBC, 0x4D, 0x5B, (byte) 0xCF, 0x11, 
		                                            (byte) 0xA8, (byte) 0xFD, 0x00, (byte) 0x80, 0x5F, 0x5C, 0x44, 0x2B};
 
    public static boolean compareGUID(byte[] guid1, byte[] guid2) {
		for (int i = 0; i < 16; i++) {
			if (guid1[i] != guid2[i]) {
				return false;
			}
		}
		return true;
	}
	public static boolean readGUID(FileInputStream in, byte[] guid) throws IOException {
		if (guid == null || in.read(guid) != guid.length) {
			return false;
		} 
		return true;
	}
 
	public static long readLong(FileInputStream in) throws IOException {
		long val = 0;
		byte data[] = new byte[8];
 
		in.read(data);
		for (int i = 7; i >=0; i--) {
			val = (val << 8) | (((long)data[i])&0xFF);
		}
		return val;
	}
 
	public static int readInt(FileInputStream in) throws IOException {
		int val = 0;
		byte data[] = new byte[4];
 
		in.read(data);
		for (int i = 3; i>=0; i--) {
			val = (val << 8) | (((int)data[i])&0xFF);
		}
 
		return val;
	}
 
	public static short readShort(FileInputStream in) throws IOException {
		byte data[] = new byte[2];
 
		in.read(data);
		return (short) (((((short)data[1])&0xFF)<<8)|(((short)data[0])&0xFF));
	}
 
	public static int readVar(FileInputStream in, int length) throws IOException {
	    byte data[] = new byte[length];
	    int val = 0;
 
	    in.read(data);
	    for (int i = length-1; i>=0; i--) {
	    	val = (val << 8) | (((int)data[i])&0xFF);
	    }				
		return val;
	}
}
 
abstract class ASFObject {
	protected String name;
	protected long length;
	protected int level;
	protected int varMap[] = {0, 1, 2, 4};
 
	ASFObject (String n, long l1, int l2) {
		name = n;
		length = l1;
		level = l2;
	}
 
	public abstract boolean parse(FileInputStream in) throws IOException;
 
	public void dump() {
		for (int i = 0; i < level; i++) System.out.print("\t");
		System.out.println(name+" Object Found with Size "+length);
	}
 
	public void add(ASFObject obj) {
 
	}
 
	public ASFObject getChild(int index) {
		return null;
	}
 
	public long getLength() {
		return length;
	}
 
	public String getName() {
		return name;
	}
 
	public int getLevel() {
		return level;
	}
}
 
class ASFSuperObject extends ASFObject {
	protected Vector<ASFObject> children;
	protected long offset;
 
	ASFSuperObject(String n, long l1, int l2, long off) {
		super(n, l1, l2);
		children = new Vector<ASFObject>();
		offset = off;
	}
 
	@Override
	public boolean parse(FileInputStream in) throws IOException {
		long size = offset+24;
		do {
			byte[] guid = new byte[16];
			ASFObject child;
 
			ASFParser.readGUID(in, guid);
			if (ASFParser.compareGUID(guid, ASFParser.GUID_Header)) {
				child = new ASFHeaderObject(ASFParser.readLong(in), this.getLevel()+1);
			} else if (ASFParser.compareGUID(guid, ASFParser.GUID_Data)) {
				int pktLen = 0;
				for (int i = 0; i < children.size(); i++) {
					ASFObject obj = getChild(i);
					if (obj.getName().equals("Header")) {
						ASFHeaderObject header = (ASFHeaderObject) obj;
						for (int j = 0; j < header.children.size(); j++) {
							ASFObject o = header.getChild(j);
							if (o.getName().equals("File Properties")) {
								pktLen = ((ASFFilePropertiesObject) o).maxPktLen;
							}
						}
					} 
				}
				child = new ASFDataObject(ASFParser.readLong(in), this.getLevel()+1, pktLen);
			} else if (ASFParser.compareGUID(guid, ASFParser.GUID_Index)) {
				child = new ASFIndexObject(ASFParser.readLong(in), this.getLevel()+1);
			} else if (ASFParser.compareGUID(guid, ASFParser.GUID_Simple_Index)) {
				child = new ASFSimpleIndexObject(ASFParser.readLong(in), this.getLevel()+1);
			} else if (ASFParser.compareGUID(guid, ASFParser.GUID_File_Properties)) {
				child = new ASFFilePropertiesObject(ASFParser.readLong(in), this.getLevel()+1);
			} else if (ASFParser.compareGUID(guid, ASFParser.GUID_Stream_Properties)) {
				child = new ASFStreamPropertiesObject(ASFParser.readLong(in), this.getLevel()+1);
			} else if (ASFParser.compareGUID(guid, ASFParser.GUID_Codec_List)) {
				child = new ASFCodecListObject(ASFParser.readLong(in), this.getLevel()+1);
			} else if (ASFParser.compareGUID(guid, ASFParser.GUID_Header_Ext)) {
				child = new ASFHeaderExtObject(ASFParser.readLong(in), this.getLevel()+1);
			} else if (ASFParser.compareGUID(guid, ASFParser.GUID_Content_Description)) {
				child = new ASFContentDescriptionObject(ASFParser.readLong(in), this.getLevel()+1);
			} else if (ASFParser.compareGUID(guid, ASFParser.GUID_Content_Description_Ext)) {
				child = new ASFContentDescriptionExtObject(ASFParser.readLong(in), this.getLevel()+1);
			} else {
				child = new ASFUnknownObject(ASFParser.readLong(in), this.getLevel()+1);
			}
			if (child.parse(in)) {
				add(child);
				size += child.getLength();
			} else {
				return false;
			}
		} while (size < length);
		return true;
	}
	@Override
	public void add(ASFObject obj) {
		children.add(obj);
	}
 
	@Override
	public ASFObject getChild(int index) {
		return children.get(index);
	}
 
	@Override
	public void dump() {
		super.dump();
		for (int i = 0; i < children.size(); i++) {
			getChild(i).dump();
		}
	}
}
 
class ASFHeaderObject extends ASFSuperObject {
	protected int nHeaders;
 
	ASFHeaderObject(long l1, int l2) {
		super("Header", l1, l2, 6);
		nHeaders = 0;
	}
 
	@Override
	public boolean parse(FileInputStream in) throws IOException {
		nHeaders = ASFParser.readInt(in);
		in.skip(2);
		if (!super.parse(in)) {
			return false;
		}
		return true;
	}
 
	public void dump() {
		super.dump();
 
		for (int i = 0; i < level; i++) System.out.print("\t");
		System.out.println("{ "+nHeaders+" headers contained. }");		
	}
}
 
class ASFTopObject extends ASFSuperObject {
	ASFTopObject(long l1, int l2) {
		super("ASF", l1, l2, 0);
	}
}
 
class ASFDataObject extends ASFObject {
	protected static final int MAX_PACKETS_DUMP = 50;
	protected static final int MAX_PAYLOADS_DUMP = 5;
	protected long nPackets;
	protected int pktLen;
	public Vector<ASFPacket> packets;
 
	class ASFPacket {
		public int nPayloads;
		public byte flag1;
		public byte flag2;
		public int errLen;
		public int pktLen;
		public int timestamp;
		public int padding;
		public Vector<Payload> payloads;
	}
 
	class Payload {
	    public int stream;
	    public int frame;
	    public int offset;
	    public int replicateLen;
	    public int length;
	    public int timestamp;
	    public int frameLen;
	    public int subpayloads;
	}
 
	ASFDataObject(long l1, int l2, int l3) {
		super("Data", l1, l2);
		nPackets = 0;
		pktLen = l3;
	}
 
	@Override
	public boolean parse(FileInputStream in) throws IOException {
		long skipped = length-24;
 
		/* skip guid */
		in.skip(16);
		skipped -= 16;
		/* number of packets */
		nPackets = ASFParser.readLong(in);
		skipped -= 8;
		if (nPackets > MAX_PACKETS_DUMP)  {
			packets = new Vector<ASFPacket>(MAX_PACKETS_DUMP);
		} else {
			packets = new Vector<ASFPacket>((int)nPackets);
		}
		ASFParser.readShort(in);
		skipped -=2;
 
		/* parser packets, no more than 10 */
		for (int i = 0; i < packets.capacity(); i++) {
			int bytes = 0;
			ASFPacket packet = new ASFPacket();
			byte b = (byte) in.read();
			bytes++;
			if (b < 0) {
				packet.errLen = (int) (b&0xF);
				in.skip(packet.errLen);
				bytes += packet.errLen;
				packet.flag1 = (byte) in.read();
				bytes++;
			} else {
				packet.flag1 = b;
			}
			packet.flag2 = (byte) in.read();
			bytes++;
 
			/* packet header */
			packet.pktLen = ASFParser.readVar(in, varMap[(packet.flag1>>5)&0x3]); /* Packet Length */
			bytes += varMap[(packet.flag1>>5)&0x3];
			ASFParser.readVar(in, varMap[(packet.flag1>>1)&0x3]); /* Sequence (not used) */
			bytes += varMap[(packet.flag1>>1)&0x3];
			packet.padding = ASFParser.readVar(in, varMap[(packet.flag1>>3)&0x3]); /* Padding Length */
			bytes += varMap[(packet.flag1>>3)&0x3];
			packet.timestamp = ASFParser.readInt(in); /* Send Time */
			bytes += 4;
			in.skip(2); /* Duration */
			bytes += 2;
 
			/* payload */
			if (packet.flag1%2 == 0) {
				int pktSize;
				if (packet.pktLen == 0) {
					if (pktLen != 0) {
						pktSize = pktLen;
					}
					else {
						System.out.println("ERROR parsing ASF Data Object");
						return false;
					}
				} else {
					pktSize = packet.pktLen;
				}
 
				packet.nPayloads = 1;		
				packet.payloads = new Vector<Payload>(packet.nPayloads);
 
				Payload payload = new Payload();
				payload.stream = in.read()&0x7F;
				bytes++;
				payload.frame = ASFParser.readVar(in, varMap[(packet.flag2>>4)&3]);
				bytes += varMap[(packet.flag2>>4)&3];
				payload.offset = ASFParser.readVar(in, varMap[(packet.flag2>>2)&3]);
				bytes += varMap[(packet.flag2>>2)&3];
				payload.replicateLen = ASFParser.readVar(in, varMap[packet.flag2&3]);
				bytes += varMap[packet.flag2&3];	
	    		if (payload.replicateLen == 1) {
					int sublen;
					int left;
 
					in.read(); /* timestamp delta */
					bytes++;
					left = pktSize - bytes + packet.errLen + 1;					
					while (left > 0) {
						sublen = in.read();
						bytes++;
						in.skip(sublen);
						bytes += sublen; 
						left -= sublen;
						payload.subpayloads++;
					} 					
				} else {
					in.skip(payload.replicateLen);
					bytes += payload.replicateLen;
 
					int left = pktSize - bytes - packet.padding;
					in.skip(left); /* skip payload */
					bytes += left;									
				}
				packet.payloads.add(payload);
			} else {
				byte flag = (byte)in.read();
				bytes++;
				packet.nPayloads = flag & 0x3F;
				packet.payloads = new Vector<Payload>(packet.nPayloads);
 
				for (int j = 0; j < packet.nPayloads; j++) {
					Payload payload = new Payload();
					payload.stream = in.read()&0x7F;
					bytes++;
					payload.frame = ASFParser.readVar(in, varMap[(packet.flag2>>4)&3]);
					bytes += varMap[(packet.flag2>>4)&3];
					payload.offset = ASFParser.readVar(in, varMap[(packet.flag2>>2)&3]);
					bytes += varMap[(packet.flag2>>2)&3];
					payload.replicateLen = ASFParser.readVar(in, varMap[packet.flag2&3]);
					bytes += varMap[packet.flag2&3];
					if (payload.replicateLen >= 8) {
						payload.frameLen = ASFParser.readInt(in);
						payload.timestamp = ASFParser.readInt(in);
						in.skip(payload.replicateLen-8);
					} else {
						in.skip(payload.replicateLen);
					}					
					bytes += payload.replicateLen;
 
                    payload.length = ASFParser.readVar(in, varMap[(flag >> 6)&3]);
                    bytes += varMap[(flag >> 6)&3];
                    in.skip(payload.length);
                    bytes += payload.length;
 
                    packet.payloads.add(payload);
				}
			}
 
			/* padding */
			in.skip(packet.padding);
			bytes += packet.padding;
 
			skipped -= bytes;
			packets.add(packet);
		}
 
		in.skip(skipped);
		return true;
	}	
 
	public void dump() {
		super.dump();
 
		for (int j = 0; j < packets.size(); j++) {
			ASFPacket packet = packets.get(j);
			for (int i = 0; i < level; i++) System.out.print("\t");
			System.out.print("{ ");
			if (packet.errLen != 0)
				System.out.print("[ERR DATA + "+ packet.errLen + "B]"); 
		    System.out.print("[PACKET DATA + " + packet.pktLen + "B Timestamp=" + packet.timestamp + " ");
		    System.out.print("Payloads: ");
		    for (int k = 0; k < MAX_PAYLOADS_DUMP-1; k++) {
		    	if (k >= packet.payloads.size()) break;
 
		    	Payload payload = packet.payloads.get(k);
		    	System.out.print("{" +
		    			           "S:" + payload.stream + "," +
		    			           "F:" + payload.frame + "," +
		    			           "L:" + payload.length + "/" + payload.frameLen + "," +
		    			           "O:" + payload.offset + "," +
		    			           "T:" + payload.timestamp + "," +
		    			           "Subs:" + payload.subpayloads +
		    			           "}"); 
		    }
		    if (packet.payloads.size() > MAX_PAYLOADS_DUMP) {
		    	System.out.print(" ......");
		    	Payload payload = packet.payloads.get(packet.payloads.size()-1);
		    	System.out.print("{" +
 			           "S:" + payload.stream + "," +
 			           "F:" + payload.frame + "," +
 			           "L:" + payload.length + "/" + payload.frameLen + "," +
 			           "O:" + payload.offset + "," +
 			           "T:" + payload.timestamp + "," +
 			           "Subs:" + payload.subpayloads +
 			           "}");
		    }
			System.out.print("]");
			if (packet.padding != 0)
				System.out.print("[PADDING + " + packet.padding + "B]");
			System.out.println(" }");
		}
		if (nPackets > MAX_PACKETS_DUMP) {
			for (int i = 0; i < level; i++) System.out.print("\t");
			System.out.println("{ ...... }");
		}
 
		for (int i = 0; i < level; i++) System.out.print("\t");
		System.out.println("{ "+nPackets+" packets contained. }");			
	}
}
 
class ASFFilePropertiesObject extends ASFObject {
	public long size;
	public long duration;
	public long sendDuration;
	public long preRoll;
	public int maxPktLen;
	public int minPktLen;
	public int bitrate;
	public int flag;
 
	ASFFilePropertiesObject(long l1, int l2) {
		super("File Properties", l1, l2);
	}
 
	@Override
	public boolean parse(FileInputStream in) throws IOException {
		long skipped = length - 24;
 
		in.skip(16);
		skipped -= 16;
		size = ASFParser.readLong(in);
		skipped -= 8;
		in.skip(16);
		skipped -= 16;
		duration = ASFParser.readLong(in);
		skipped -= 8;
		sendDuration = ASFParser.readLong(in);
		skipped -= 8;
		preRoll = ASFParser.readLong(in);
		skipped -= 8;
		flag = ASFParser.readInt(in);
		skipped -= 4;
		minPktLen = ASFParser.readInt(in);
		skipped -= 4;
		maxPktLen = ASFParser.readInt(in);
		skipped -= 4;
		bitrate = ASFParser.readInt(in);
		skipped -= 4;
 
		in.skip(skipped);
		return true;
	}	
 
	@Override
	public void dump () {
		super.dump();
		for (int i = 0; i < level; i++) System.out.print("\t");
		System.out.println("{ " +
				            "Size: " + size + ", " +
				            "Duration: " + duration/10 + "ms, " +
				            "Sending: " + sendDuration/10 + "ms, " +
				            "PreRolling: " + preRoll + "ms, " +
				            "Packet Size: " + minPktLen + "/" + maxPktLen + ", " +
				            "Bitrate: " + bitrate + "bps" +
				            " }");
	}
}
 
class ASFStreamPropertiesObject extends ASFObject {
	protected String type;
	protected long offset;
	protected int number;
	protected WaveEx wave;
	protected BitmapInfo bmp;
 
	class BitmapInfo {
		int width;
		int height;
		byte[] codec;
	};
 
	class WaveEx {
		short codecId;
		short channels;
		int sampleRate;
		int bitrate;
		short blockAlign;
		short bits;
	};
 
	ASFStreamPropertiesObject(long l1, int l2) {
		super("Stream Properties", l1, l2);
	}
 
	@Override
	public boolean parse(FileInputStream in) throws IOException {
		long skipped = length - 24;
 
		byte[] guid = new byte[16];
		ASFParser.readGUID(in, guid);
		skipped -= 16;
		if (ASFParser.compareGUID(ASFParser.GUID_Video_Stream, guid)) {
			type = "Video";
			bmp = new BitmapInfo();
		} else if (ASFParser.compareGUID(ASFParser.GUID_Audio_Stream, guid)) {
			type = "Audio";
			wave = new WaveEx();
		} else {
			type = "Unknown";
		}
		in.skip(16);
		skipped -= 16;
		offset = ASFParser.readLong(in);
		skipped -= 8;
 
		int dataLen = ASFParser.readInt(in);
		skipped -= 4;
		in.skip(4);
		skipped -= 4;
		number = (ASFParser.readShort(in))&0x7;
		skipped -= 2;
		in.skip(4);
		skipped -= 4;
 
		/* for type specific data */
		if (type.equals("Audio")) {
			wave.codecId = ASFParser.readShort(in); 
			skipped -= 2;
			wave.channels = ASFParser.readShort(in);
			skipped -= 2;
			wave.sampleRate = ASFParser.readInt(in);
			skipped -= 4;
			wave.bitrate = ASFParser.readInt(in)*8;
			skipped -= 4;
			wave.blockAlign = ASFParser.readShort(in);
			skipped -= 2;
			wave.bits = ASFParser.readShort(in);
			skipped -= 2;
		} else if (type.equals("Video")) {
			bmp.width = ASFParser.readInt(in);
			bmp.height = ASFParser.readInt(in);
			skipped -= 8;
			in.skip(19);
			skipped -= 19;
			bmp.codec = new byte[4];
			in.read(bmp.codec);
			skipped -= 4;
		}
 
		in.skip(skipped);
 
		return true;
	}	
 
	@Override
	public void dump() {
		super.dump();
		for (int i = 0; i < level; i++) System.out.print("\t");
		System.out.print("{ " +
				            "Type: " + type + ", " +
				            "Time Offset: " + offset/10 + "ms, " +
				            "Number: " + number + ", " );
		if (bmp != null) {
		    System.out.print("{" +
		    		         bmp.width + "x" + bmp.height +", " +
		    		         new String(bmp.codec) +
		    		          "}");
		} else if (wave != null) {
			System.out.print("{" +
					         "codecID:0x" + Integer.toHexString(wave.codecId) + ", "  +
					         "channels:" + wave.channels + ", " +
					         "sampe rate:" + wave.sampleRate + ", " +
					         "bitrate:" + wave.bitrate + ", " +
					         "block align:" + wave.blockAlign +", " +
					         "Bitwidth:" + wave.bits + ", " +
	                         "}");
		}
        System.out.println(" }");
	}		
}
 
class ASFIndexObject extends ASFObject {
	protected int interval;
	protected Vector<Block> blocks;
	protected Vector<Specifier> specifiers;
 
	class Specifier {
		protected short stream;
		protected short type;
		public Specifier(short num, short t) {
			stream = num;
			type = t;
		}
 
		public short getStream() {
			return stream;
		}
 
		public short getType() {
			return type;
		}
	}
 
	class Block {
		protected int[][] entries;
		protected long[] offsets; 
 
		public Block(int e1, int e2) {
			entries = new int[e1][e2];
		}
 
		public void setOffsets(long[] offs) {
			offsets = offs;
		}
 
		public long[] getOffsets() {
			return offsets;
		}
 
		public int[][] getEntries() {
			return entries;
		}
	}
 
	ASFIndexObject(long l1, int l2) {
		super("Index", l1, l2);
 
		interval = 0;
	}
 
	@Override
	public boolean parse(FileInputStream in) throws IOException {
		long skipped = length - 24;
		interval = ASFParser.readInt(in);
		specifiers = new Vector<Specifier>(ASFParser.readShort(in)); 
		blocks = new Vector<Block>(ASFParser.readInt(in));
		skipped -= 10;
 
		for (int i = 0; i < specifiers.capacity(); i++) {
			specifiers.add(new Specifier(ASFParser.readShort(in), ASFParser.readShort(in)));
			skipped -= 4;
		}
 
		for (int i = 0; i < blocks.capacity(); i++) {
			blocks.add(new Block(ASFParser.readInt(in), specifiers.size()));
			skipped -= 4;
 
            long[] offs = new long[specifiers.size()];
            for (int j = 0; j < offs.length; j++) {
            	offs[j] = ASFParser.readLong(in);
            	skipped -= 8;
            }
            blocks.get(i).setOffsets(offs);
 
            int[][] entries = blocks.get(i).getEntries();
            for (int j = 0; j < entries.length; j++) {
            	for (int k = 0; k < specifiers.size(); k++) {
            		entries[j][k] = ASFParser.readInt(in);
            		skipped -= 4;
            	}
            }
		}
		in.skip(skipped);
		return true;
	}
 
	public void dump() {
		super.dump();
 
		for (int i = 0; i < level; i++) System.out.print("\t");
		System.out.print("{ DeltaT="+interval+"ms, ");
		System.out.print("Streams: {");
		for (int i = 0; i < specifiers.size(); i++) {
			System.out.print(specifiers.get(i).getStream());
			if (i != specifiers.size()-1) {
				System.out.print(", ");
			}
		}
		System.out.print("}, ");
		System.out.print("Types: {");
		for (int i = 0; i < specifiers.size(); i++) {
			System.out.print(specifiers.get(i).getType());
			if (i != specifiers.size()-1) {
				System.out.print(", ");
			}
		}
		System.out.print("} ");
		System.out.println("}");
		for (int i = 0; i < level; i++) System.out.print("\t");
		for (int i = 0; i < blocks.size(); i++) {
			System.out.print("{ ");
			System.out.print("Off={");
			for (int j = 0; j < blocks.get(i).getOffsets().length; j++) {
				System.out.print(blocks.get(i).getOffsets()[j]);
				if (j != blocks.get(i).getOffsets().length-1) {
					System.out.print(", ");
				}
			}
			System.out.print("}, ");
			System.out.print("indexing as ");
			for (int j = 0; j < blocks.get(i).getEntries().length && j < 8; j++) {
				System.out.print("{ ");
				for (int k = 0; k < specifiers.size(); k++) {
					System.out.print(blocks.get(i).getEntries()[j][k]);
					if (k != specifiers.size()-1) {
						System.out.print(", ");
					}
				}
				System.out.print("} ");
			}
			if (blocks.get(i).getEntries().length > 8) System.out.print("......");
			System.out.println(" }");
		}
	}
 }
 
class ASFSimpleIndexObject extends ASFObject {
	ASFSimpleIndexObject(long l1, int l2) {
		super("Simple Index", l1, l2);
	}
 
	@Override
	public boolean parse(FileInputStream in) throws IOException {
		in.skip(length-24);
		return true;
	}	
 }
 
class ASFCodecListObject extends ASFObject {
	ASFCodecListObject(long l1, int l2) {
		super("Codec List", l1, l2);
	}
 
	@Override
	public boolean parse(FileInputStream in) throws IOException {
		in.skip(length-24);
		return true;
	}	
}
 
class ASFHeaderExtObject extends ASFObject {
	ASFHeaderExtObject(long l1, int l2) {
		super("Header Extension", l1, l2);
	}
 
	@Override
	public boolean parse(FileInputStream in) throws IOException {
		in.skip(length-24);
		return true;
	}	
}
 
class ASFContentDescriptionObject extends ASFObject {
	ASFContentDescriptionObject(long l1, int l2) {
		super("Content Description", l1, l2);
	}
 
	@Override
	public boolean parse(FileInputStream in) throws IOException {
		in.skip(length-24);
		return true;
	}	
}
 
class ASFContentDescriptionExtObject extends ASFObject {
	ASFContentDescriptionExtObject(long l1, int l2) {
		super("Extended Content Description", l1, l2);
	}
 
	@Override
	public boolean parse(FileInputStream in) throws IOException {
		in.skip(length-24);
		return true;
	}	
}
 
class ASFUnknownObject extends ASFObject {
	ASFUnknownObject(long l1, int l2) {
		super("Unknown", l1, l2);
	}
 
	@Override
	public boolean parse(FileInputStream in) throws IOException {
		in.skip(length-24);
		return true;
	}
}
tech/multimedia/asf_parser.txt · Last modified: 2014/11/10 08:22 (external edit)