📄 mpegplayer.java
字号:
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 }, { 5,4 }, { 5,4 }, { 5,4 }, { 6,5 }, { 6,5 }, { 7,6 }, { 8,7 }, // 111111xxx { 8,7 }, { 8,7 }, { 8,7 }, { 8,7 }, { 9,8 }, { 9,8 }, { 10,9 }, { 11,9 } }; /** * Table B-13, variable length codes for DC chrominance sizes */ private final static byte DCchrtable[][] = { // xxxx...... { 0,2 }, { 0,2 }, { 0,2 }, { 0,2 }, { 1,2 }, { 1,2 }, { 1,2 }, { 1,2 }, { 2,2 }, { 2,2 }, { 2,2 }, { 2,2 }, { 3,3 }, { 3,3 }, { 4,4 }, { 5,5 }, // 1111xxx... { 5,5 }, { 5,5 }, { 5,5 }, { 5,5 }, { 6,6 }, { 6,6 }, { 7,7 }, { 8,8 }, // 1111111xxx { 8,8 }, { 8,8 }, { 8,8 }, { 8,8 }, { 9,9 }, { 9,9 }, { 10,10 }, { 11,10 } }; public final static short EOB = 64; public final static short ESC = 65; /** * Table B-14, variable length codes for DCT coefficients */ private final static short DCTtable[][] = { // 000000000001xxxx { 4609,16 }, { 4353,16 }, { 4097,16 }, { 3841,16 }, { 774,16 }, { 528,16 }, { 527,16 }, { 526,16 }, { 525,16 }, { 524,16 }, { 523,16 }, { 287,16 }, { 286,16 }, { 285,16 }, { 284,16 }, { 283,16 }, // 00000000001xxxx. {10240,15 }, { 9984,15 }, { 9728,15 }, { 9472,15 }, { 9216,15 }, { 8960,15 }, { 8704,15 }, { 8448,15 }, { 8192,15 }, { 3585,15 }, { 3329,15 }, { 3073,15 }, { 2817,15 }, { 2561,15 }, { 2305,15 }, { 2049,15 }, // 0000000001xxxx.. { 7936,14 }, { 7680,14 }, { 7424,14 }, { 7168,14 }, { 6912,14 }, { 6656,14 }, { 6400,14 }, { 6144,14 }, { 5888,14 }, { 5632,14 }, { 5376,14 }, { 5120,14 }, { 4864,14 }, { 4608,14 }, { 4352,14 }, { 4096,14 }, // 000000001xxxx... { 522,13 }, { 521,13 }, { 773,13 }, { 1027,13 }, { 1282,13 }, { 1793,13 }, { 1537,13 }, { 3840,13 }, { 3584,13 }, { 3328,13 }, { 3072,13 }, { 282,13 }, { 281,13 }, { 280,13 }, { 279,13 }, { 278,13 }, // 00000001xxxx.... { 2816,12 }, { 520,12 }, { 772,12 }, { 2560,12 }, { 1026,12 }, { 519,12 }, { 277,12 }, { 276,12 }, { 2304,12 }, { 275,12 }, { 274,12 }, { 1281,12 }, { 771,12 }, { 2048,12 }, { 518,12 }, { 273,12 }, // 0000001xxx...... { 272,10 }, { 517,10 }, { 1792,10 }, { 770,10 }, { 1025,10 }, { 271,10 }, { 270,10 }, { 516,10 }, // 000xxxx......... { 0, 0 }, { 272,10 }, { ESC, 6 }, { ESC, 6 }, { 514, 7 }, { 265, 7 }, { 1024, 7 }, { 264, 7 }, { 263, 6 }, { 263, 6 }, { 262, 6 }, { 262, 6 }, { 513, 6 }, { 513, 6 }, { 261, 6 }, { 261, 6 }, // 00100xxx........ { 269, 8 }, { 1536, 8 }, { 268, 8 }, { 267, 8 }, { 515, 8 }, { 769, 8 }, { 1280, 8 }, { 266, 8 }, // xxxxx........... { 0, 0 }, { 514, 7 }, { 263, 6 }, { 513, 6 }, { 269, 8 }, { 768, 5 }, { 260, 5 }, { 259, 5 }, { 512, 4 }, { 512, 4 }, { 258, 4 }, { 258, 4 }, { 257, 3 }, { 257, 3 }, { 257, 3 }, { 257, 3 }, { EOB, 2 }, { EOB, 2 }, { EOB, 2 }, { EOB, 2 }, { EOB, 2 }, { EOB, 2 }, { EOB, 2 }, { EOB, 2 }, { 256, 2 }, { 256, 2 }, { 256, 2 }, { 256, 2 }, { 256, 2 }, { 256, 2 }, { 256, 2 }, { 256, 2 } }; /** * Storage for RLE run and level of DCT block coefficients */ private int data[]; /** * Initializes the Huffman entropy decoder for MPEG-1 streams */ public VLCInputStream(InputStream inputStream) { super(inputStream); data = new int[2]; } /** * Returns macroblock address increment codes */ public int getMBACode() throws IOException { int code, value = 0; /* skip macroblock escape */ while ((code = showBits(11)) == 15) { flushBits(11); } /* decode macroblock skip codes */ while ((code = showBits(11)) == 8) { flushBits(11); value += 33; } /* decode macroblock increment */ if (code >= 512) code = (code >> 8) + 48; else if (code >= 128) code = (code >> 6) + 40; else if (code >= 48) code = (code >> 3) + 24; else if (code >= 24) code -= 24; else throw new IOException("Invalid macro block address increment"); flushBits(MBAtable[code][1]); return value + MBAtable[code][0]; } /** * Returns I-picture macroblock type flags */ public int getIMBCode() throws IOException { int code = showBits(2); if (code <= 0) throw new IOException("Invalid I-picture macro block code"); flushBits(IMBtable[code][1]); return IMBtable[code][0]; } /** * Returns P-picture macroblock type flags */ public int getPMBCode() throws IOException { int code = showBits(6); if (code >= 8) code = (code >> 3) + 8; else if (code <= 0) throw new IOException("Invalid P-picture macro block code"); flushBits(PMBtable[code][1]); return PMBtable[code][0]; } /** * Returns B-picture macroblock type flags */ public int getBMBCode() throws IOException { int code = showBits(6); if (code >= 16) code = (code >> 3) + 16; else if (code <= 0) throw new IOException("Invalid B-picture macro block code"); flushBits(BMBtable[code][1]); return BMBtable[code][0]; } /** * Returns coded block pattern flags */ public int getCBPCode() throws IOException { int code = showBits(9); if (code >= 128) code = (code >> 4) + 56; else if (code >= 64) code = (code >> 2) + 24; else if (code >= 8) code = (code >> 1) + 8; else if (code <= 0) throw new IOException("Invalid block pattern code"); flushBits(CBPtable[code][1]); return CBPtable[code][0]; } /** * Returns motion vector codes */ public int getMVCode() throws IOException { int code = showBits(10); if (code >= 128) code = (code >> 7) + 28; else if (code >= 24) code = (code >> 3) + 12; else if (code >= 12) code -= 12; else throw new IOException("Invalid motion vector code"); flushBits(MVtable[code][1]); code = MVtable[code][0]; return (getBits(1) == 0 ? code : -code); } /** * Returns intra coded DC luminance coefficients */ public int getIntraDCLumValue() throws IOException { int code = showBits(9); if (code >= 504) code -= 488; else if (code >= 448) code = (code >> 3) - 48; else code >>= 6; flushBits(DClumtable[code][1]); int nbits = DClumtable[code][0]; if (nbits != 0) { code = getBits(nbits); if ((code & (1 << (nbits - 1))) == 0) code -= (1 << nbits) - 1; return code; } return 0; } /** * Returns intra coded DC chrominance coefficients */ public int getIntraDCChromValue() throws IOException { int code = showBits(10); if (code >= 1016) code -= 992; else if (code >= 960) code = (code >> 3) - 104; else code >>= 6; flushBits(DCchrtable[code][1]); int nbits = DCchrtable[code][0]; if (nbits != 0) { code = getBits(nbits); if ((code & (1 << (nbits - 1))) == 0) code -= (1 << nbits) - 1; return code; } return 0; } /** * Returns inter coded DC luminance or chrominance coefficients */ public int[] getInterDCValue() throws IOException { /* handle special variable length code */ if (showBits(1) != 0) { data[0] = 0; data[1] = getBits(2) == 2 ? 1 : -1; return data;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -