import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.image.*;
import java.applet.*;
/**
* This class represents a buffered input stream which can read
* variable length codes from MPEG-1 video streams.
*/
class BitInputStream {
/**
* MPEG video layers start codes
*/
public final static int SYNC_START_CODE = 0x000001;
public final static int PIC_START_CODE = 0x00000100;
public final static int SLICE_MIN_CODE = 0x00000101;
public final static int SLICE_MAX_CODE = 0x000001af;
public final static int USER_START_CODE = 0x000001b2;
public final static int SEQ_START_CODE = 0x000001b3;
public final static int EXT_START_CODE = 0x000001b5;
public final static int SEQ_END_CODE = 0x000001b7;
public final static int GOP_START_CODE = 0x000001b8;
/**
* The underlying input stream
*/
private InputStream stream;
/**
* The bit buffer variables
*/
private int bitbuffer, bitcount;
/**
* The 32 bit buffer variables
*/
private int buffer[], count, position;
/**
* Initializes the bit input stream object
*/
public BitInputStream(InputStream inputStream) {
stream = inputStream;
buffer = new int[1024];
bitbuffer = bitcount = 0;
count = position = 0;
}
/**
* Reads the next MPEG-1 layer start code
*/
public int getCode() throws IOException {
alignBits(8);
while (showBits(24) != SYNC_START_CODE)
flushBits(8);
return getBits(32);
}
/**
* Shows the next MPEG-1 layer start code
*/
public int showCode() throws IOException {
alignBits(8);
while (showBits(24) != SYNC_START_CODE)
flushBits(8);
return showBits(32);
}
/**
* Reads the next variable length code
*/
public int getBits(int nbits) throws IOException {
int bits;
if (nbits <= bitcount) {
bits = bitbuffer >>> (32 - nbits);
bitbuffer <<= nbits;
bitcount -= nbits;
}
else {
bits = bitbuffer >>> (32 - nbits);
nbits -= bitcount;
bitbuffer = get32Bits();
bits |= bitbuffer >>> (32 - nbits);
bitbuffer <<= nbits;
bitcount = 32 - nbits;
}
if (nbits >= 32)
bitbuffer = 0;
return bits;
}
/**
* Shows the next variable length code
*/
public int showBits(int nbits) throws IOException {
int bits = bitbuffer >>> (32 - nbits);
if (nbits > bitcount) {
bits |= show32Bits() >>> (32 + bitcount - nbits);
}
return bits;
}
/**
* Flushes the current variable length code
*/
public void flushBits(int nbits) throws IOException {
if (nbits <= bitcount) {
bitbuffer <<= nbits;
bitcount -= nbits;
}
else {
nbits -= bitcount;
bitbuffer = get32Bits() << nbits;
bitcount = 32 - nbits;
}
}
/**
* Aligns the input stream pointer to a given boundary
*/
public void alignBits(int nbits) throws IOException {
flushBits(bitcount % nbits);
}
/**
* Reads the next 32-bit code from the buffered stream
*/
private int get32Bits() throws IOException {
if (position >= count) {
position = 0;
for (count = 0; count < buffer.length; count++)
buffer[count] = read32Bits();
}
return buffer[position++];
}
/**
* Shows the next 32-bit code from the buffered stream
*/
private int show32Bits() throws IOException {
if (position >= count) {
position = 0;
for (count = 0; count < buffer.length; count++)
buffer[count] = read32Bits();
}
return buffer[position];
}
/**
* Reads 32-bit big endian codes from the stream
*/
private int read32Bits() throws IOException {
if (stream.available() <= 0)
return SEQ_END_CODE;
int a0 = stream.read() & 0xff;
int a1 = stream.read() & 0xff;
int a2 = stream.read() & 0xff;
int a3 = stream.read() & 0xff;
return (a0 << 24) + (a1 << 16) + (a2 << 8) + (a3 << 0);
}
}
/**
* Huffman VLC entropy decoder for MPEG-1 video streams. The tables
* are from ISO/IEC 13818-2 DIS, Annex B, variable length code tables.
*/
class VLCInputStream extends BitInputStream {
/**
* Table B-1, variable length codes for macroblock address increments
*/
private final static byte MBAtable[][] = {
// 00000011xxx
{ 33,11 }, { 32,11 }, { 31,11 }, { 30,11 },
{ 29,11 }, { 28,11 }, { 27,11 }, { 26,11 },
// 0000010xxxx
{ 25,11 }, { 24,11 }, { 23,11 }, { 22,11 },
{ 21,10 }, { 21,10 }, { 20,10 }, { 20,10 },
{ 19,10 }, { 19,10 }, { 18,10 }, { 18,10 },
{ 17,10 }, { 17,10 }, { 16,10 }, { 16,10 },
// 0000xxxx...
{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 33,11 },
{ 25,11 }, { 19,10 }, { 15, 8 }, { 14, 8 },
{ 13, 8 }, { 12, 8 }, { 11, 8 }, { 10, 8 },
{ 9, 7 }, { 9, 7 }, { 8, 7 }, { 8, 7 },
// 00xxx......
{ 0, 0 }, { 13, 8 }, { 7, 5 }, { 6, 5 },
{ 5, 4 }, { 5, 4 }, { 4, 4 }, { 4, 4 },
// xxx........
{ 0, 0 }, { 5, 4 }, { 3, 3 }, { 2, 3 },
{ 1, 1 }, { 1, 1 }, { 1, 1 }, { 1, 1 }
};
/**
* Table B-2, variable length codes for I-picture macroblock types
*/
private final static byte IMBtable[][] = {
// xx
{ 0, 0 }, { 17,2 }, { 1,1 }, { 1,1 }
};
/**
* Table B-3, variable length codes for P-picture macroblock types
*/
private final static byte PMBtable[][] = {
// 000xxx
{ 0,0 }, { 17,6 }, { 18,5 }, { 18,5 },
{ 26,5 }, { 26,5 }, { 1,5 }, { 1,5 },
// xxx...
{ 0,0 }, { 8,3 }, { 2,2 }, { 2,2 },
{ 10,1 }, { 10,1 }, { 10,1 }, { 10,1 }
};
/**
* Table B-4, variable length codes for B-picture macroblock types
*/
private final static byte BMBtable[][] = {
// 00xxxx
{ 0,0 }, { 17,6 }, { 22,6 }, { 26,6 },
{ 30,5 }, { 30,5 }, { 1,5 }, { 1,5 },
{ 8,4 }, { 8,4 }, { 8,4 }, { 8,4 },
{ 10,4 }, { 10,4 }, { 10,4 }, { 10,4 },
// xxx...
{ 0,0 }, { 8,4 }, { 4,3 }, { 6,3 },
{ 12,2 }, { 12,2 }, { 14,2 }, { 14,2 },
};
/**
* Table B-9, variable length codes for coded block patterns
*/
private final static byte CBPtable[][] = {
// 000000xxx
{ 0,0 }, { 0,9 }, { 39,9 }, { 27,9 },
{ 59,9 }, { 55,9 }, { 47,9 }, { 31,9 },
// 000xxxxx.
{ 0,0 }, { 39,9 }, { 59,9 }, { 47,9 },
{ 58,8 }, { 54,8 }, { 46,8 }, { 30,8 },
{ 57,8 }, { 53,8 }, { 45,8 }, { 29,8 },
{ 38,8 }, { 26,8 }, { 37,8 }, { 25,8 },
{ 43,8 }, { 23,8 }, { 51,8 }, { 15,8 },
{ 42,8 }, { 22,8 }, { 50,8 }, { 14,8 },
{ 41,8 }, { 21,8 }, { 49,8 }, { 13,8 },
{ 35,8 }, { 19,8 }, { 11,8 }, { 7,8 },
// 001xxxx..
{ 34,7 }, { 18,7 }, { 10,7 }, { 6,7 },
{ 33,7 }, { 17,7 }, { 9,7 }, { 5,7 },
{ 63,6 }, { 63,6 }, { 3,6 }, { 3,6 },
{ 36,6 }, { 36,6 }, { 24,6 }, { 24,6 },
// xxxxx....
{ 0,0 }, { 57,8 }, { 43,8 }, { 41,8 },
{ 34,7 }, { 33,7 }, { 63,6 }, { 36,6 },
{ 62,5 }, { 2,5 }, { 61,5 }, { 1,5 },
{ 56,5 }, { 52,5 }, { 44,5 }, { 28,5 },
{ 40,5 }, { 20,5 }, { 48,5 }, { 12,5 },
{ 32,4 }, { 32,4 }, { 16,4 }, { 16,4 },
{ 8,4 }, { 8,4 }, { 4,4 }, { 4,4 },
{ 60,3 }, { 60,3 }, { 60,3 }, { 60,3 }
};
/**
* Table B-10, variable length codes for motion vector codes
*/
private final static byte MVtable[][] = {
// 00000011xx
{ 16,10 }, { 15,10 }, { 14,10 }, { 13,10 },
// 0000010xxx
{ 12,10 }, { 11,10 }, { 10, 9 }, { 10, 9 },
{ 9, 9 }, { 9, 9 }, { 8, 9 }, { 8, 9 },
// 000xxxx...
{ 0, 0 }, { 0, 0 }, { 12,10 }, { 7, 7 },
{ 6, 7 }, { 5, 7 }, { 4, 6 }, { 4, 6 },
{ 3, 4 }, { 3, 4 }, { 3, 4 }, { 3, 4 },
{ 3, 4 }, { 3, 4 }, { 3, 4 }, { 3, 4 },
// xxx.......
{ 0, 0 }, { 2, 3 }, { 1, 2 }, { 1, 2 },
{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }
};
/**
* Table B-12, variable length codes for DC luminance sizes
*/
private final static byte DClumtable[][] = {
// xxx......
{ 1,2 }, { 1,2 }, { 2,2 }, { 2,2 },
{ 0,3 }, { 3,3 }, { 4,3 }, { 5,4 },
// 111xxx...
{ 5,4 },