📄 mpegplayer.java
字号:
} return getACValue(); } /** * Returns AC luminance or chrominance coefficients */ public int[] getACValue() throws IOException { int code = showBits(16); if (code >= 10240) code = (code >> 11) + 112; else if (code >= 8192) code = (code >> 8) + 72; else if (code >= 1024) code = (code >> 9) + 88; else if (code >= 512) code = (code >> 6) + 72; else if (code >= 256) code = (code >> 4) + 48; else if (code >= 128) code = (code >> 3) + 32; else if (code >= 64) code = (code >> 2) + 16; else if (code >= 32) code >>= 1; else if (code >= 16) code -= 16; else throw new IOException("Invalid DCT coefficient code"); flushBits(DCTtable[code][1]); data[0] = DCTtable[code][0] & 0xFF; data[1] = DCTtable[code][0] >>> 8; if (data[0] == ESC) { data[0] = getBits(6); data[1] = getBits(8); if (data[1] == 0x00) data[1] = getBits(8); else if (data[1] == 0x80) data[1] = getBits(8) - 256; else if (data[1] >= 0x80) data[1] -= 256; } else if (data[0] != EOB) { if (getBits(1) != 0) data[1] = -data[1]; } return data; }}/** * Fast inverse two-dimensional discrete cosine transform algorithm * by Chen-Wang using 32 bit integer arithmetic (8 bit coefficients). */class IDCT { /** * The basic DCT block is 8x8 samples */ private final static int DCTSIZE = 8; /** * Integer arithmetic precision constants */ private final static int PASS_BITS = 3; private final static int CONST_BITS = 11; /** * Precomputed DCT cosine kernel functions: * Ci = (2^CONST_BITS)*sqrt(2.0)*cos(i * PI / 16.0) */ private final static int C1 = 2841; private final static int C2 = 2676; private final static int C3 = 2408; private final static int C5 = 1609; private final static int C6 = 1108; private final static int C7 = 565; public static void transform(int block[]) { /* pass 1: process rows */ for (int i = 0, offset = 0; i < DCTSIZE; i++, offset += DCTSIZE) { /* get coefficients */ int d0 = block[offset + 0]; int d4 = block[offset + 1]; int d3 = block[offset + 2]; int d7 = block[offset + 3]; int d1 = block[offset + 4]; int d6 = block[offset + 5]; int d2 = block[offset + 6]; int d5 = block[offset + 7]; int d8; /* AC terms all zero? */ if ((d1 | d2 | d3 | d4 | d5 | d6 | d7) == 0) { d0 <<= PASS_BITS; block[offset + 0] = d0; block[offset + 1] = d0; block[offset + 2] = d0; block[offset + 3] = d0; block[offset + 4] = d0; block[offset + 5] = d0; block[offset + 6] = d0; block[offset + 7] = d0; continue; } /* first stage */ d8 = (d4 + d5) * C7; d4 = d8 + d4 * (C1 - C7); d5 = d8 - d5 * (C1 + C7); d8 = (d6 + d7) * C3; d6 = d8 - d6 * (C3 - C5); d7 = d8 - d7 * (C3 + C5); /* second stage */ d8 = ((d0 + d1) << CONST_BITS) + (1 << (CONST_BITS - PASS_BITS - 1)); d0 = ((d0 - d1) << CONST_BITS) + (1 << (CONST_BITS - PASS_BITS - 1)); d1 = (d2 + d3) * C6; d2 = d1 - d2 * (C2 + C6); d3 = d1 + d3 * (C2 - C6); d1 = d4 + d6; d4 = d4 - d6; d6 = d5 + d7; d5 = d5 - d7; /* third stage */ d7 = d8 + d3; d8 = d8 - d3; d3 = d0 + d2; d0 = d0 - d2; d2 = ((d4 + d5) * 181) >> 8; d4 = ((d4 - d5) * 181) >> 8; /* output stage */ block[offset + 0] = (d7 + d1) >> (CONST_BITS - PASS_BITS); block[offset + 7] = (d7 - d1) >> (CONST_BITS - PASS_BITS); block[offset + 1] = (d3 + d2) >> (CONST_BITS - PASS_BITS); block[offset + 6] = (d3 - d2) >> (CONST_BITS - PASS_BITS); block[offset + 2] = (d0 + d4) >> (CONST_BITS - PASS_BITS); block[offset + 5] = (d0 - d4) >> (CONST_BITS - PASS_BITS); block[offset + 3] = (d8 + d6) >> (CONST_BITS - PASS_BITS); block[offset + 4] = (d8 - d6) >> (CONST_BITS - PASS_BITS); } /* pass 2: process columns */ for (int i = 0, offset = 0; i < DCTSIZE; i++, offset++) { /* get coefficients */ int d0 = block[offset + DCTSIZE*0]; int d4 = block[offset + DCTSIZE*1]; int d3 = block[offset + DCTSIZE*2]; int d7 = block[offset + DCTSIZE*3]; int d1 = block[offset + DCTSIZE*4]; int d6 = block[offset + DCTSIZE*5]; int d2 = block[offset + DCTSIZE*6]; int d5 = block[offset + DCTSIZE*7]; int d8; /* AC terms all zero? */ if ((d1 | d2 | d3 | d4 | d5 | d6 | d7) == 0) { d0 >>= PASS_BITS + 3; block[offset + DCTSIZE*0] = d0; block[offset + DCTSIZE*1] = d0; block[offset + DCTSIZE*2] = d0; block[offset + DCTSIZE*3] = d0; block[offset + DCTSIZE*4] = d0; block[offset + DCTSIZE*5] = d0; block[offset + DCTSIZE*6] = d0; block[offset + DCTSIZE*7] = d0; continue; } /* first stage */ d8 = (d4 + d5) * C7; d4 = (d8 + d4 * (C1 - C7)) >> 3; d5 = (d8 - d5 * (C1 + C7)) >> 3; d8 = (d6 + d7) * C3; d6 = (d8 - d6 * (C3 - C5)) >> 3; d7 = (d8 - d7 * (C3 + C5)) >> 3; /* second stage */ d8 = ((d0 + d1) << (CONST_BITS - 3)) + (1 << (CONST_BITS + PASS_BITS-1)); d0 = ((d0 - d1) << (CONST_BITS - 3)) + (1 << (CONST_BITS + PASS_BITS-1)); d1 = (d2 + d3) * C6; d2 = (d1 - d2 * (C2 + C6)) >> 3; d3 = (d1 + d3 * (C2 - C6)) >> 3; d1 = d4 + d6; d4 = d4 - d6; d6 = d5 + d7; d5 = d5 - d7; /* third stage */ d7 = d8 + d3; d8 = d8 - d3; d3 = d0 + d2; d0 = d0 - d2; d2 = ((d4 + d5) * 181) >> 8; d4 = ((d4 - d5) * 181) >> 8; /* output stage */ block[offset + DCTSIZE*0] = (d7 + d1) >> (CONST_BITS + PASS_BITS); block[offset + DCTSIZE*7] = (d7 - d1) >> (CONST_BITS + PASS_BITS); block[offset + DCTSIZE*1] = (d3 + d2) >> (CONST_BITS + PASS_BITS); block[offset + DCTSIZE*6] = (d3 - d2) >> (CONST_BITS + PASS_BITS); block[offset + DCTSIZE*2] = (d0 + d4) >> (CONST_BITS + PASS_BITS); block[offset + DCTSIZE*5] = (d0 - d4) >> (CONST_BITS + PASS_BITS); block[offset + DCTSIZE*3] = (d8 + d6) >> (CONST_BITS + PASS_BITS); block[offset + DCTSIZE*4] = (d8 - d6) >> (CONST_BITS + PASS_BITS); } }}/** * Motion vector information used for MPEG-1 motion prediction. */class MotionVector { /** * Motion vector displacements (6 bits) */ public int horizontal; public int vertical; /** * Motion vector displacement residual size */ private int residualSize; /** * Motion displacement in half or full pixels? */ private boolean pixelSteps; /** * Initializes the motion vector object */ public MotionVector() { horizontal = vertical = 0; residualSize = 0; pixelSteps = false; } /** * Changes the current motion vector predictors */ public void setVector(int horizontal, int vertical) { this.horizontal = horizontal; this.vertical = vertical; } /** * Reads the picture motion vector information */ public void getMotionInfo(BitInputStream stream) throws IOException { pixelSteps = (stream.getBits(1) != 0); residualSize = (stream.getBits(3) - 1); } /** * Reads the macro block motion vectors */ public void getMotionVector(VLCInputStream stream) throws IOException { horizontal = getMotionDisplacement(stream, horizontal); vertical = getMotionDisplacement(stream, vertical); } /** * Reads and reconstructs the motion vector displacements */ private int getMotionDisplacement(VLCInputStream stream, int vector) throws IOException { int code = stream.getMVCode(); int residual = (code != 0 && residualSize != 0 ? stream.getBits(residualSize) : 0); int limit = 16 << residualSize; if (pixelSteps) vector >>= 1; if (code > 0) { if ((vector += ((code - 1) << residualSize) + residual + 1) >= limit) vector -= limit << 1; } else if (code < 0) { if ((vector -= ((-code - 1) << residualSize) + residual + 1) < -limit) vector += limit << 1; } if (pixelSteps) vector <<= 1; return vector; }}/** * Macroblock decoder and dequantizer for MPEG-1 video streams. */class Macroblock { /** * Macroblock type encoding */ public final static int I_TYPE = 1; public final static int P_TYPE = 2; public final static int B_TYPE = 3; public final static int D_TYPE = 4; /** * Macroblock type bit fields */ public final static int INTRA = 0x01; public final static int PATTERN = 0x02; public final static int BACKWARD = 0x04; public final static int FORWARD = 0x08; public final static int QUANT = 0x10; public final static int EMPTY = 0x80; /** * Default quantization matrix for intra coded macro blocks */ private final static int defaultIntraMatrix[] = { 8, 16, 16, 19, 16, 19, 22, 22, 22, 22, 22, 22, 26, 24, 26, 27, 27, 27, 26, 26, 26, 26, 27, 27, 27, 29, 29, 29, 34, 34, 34, 29, 29, 29, 27, 27, 29, 29, 32, 32, 34, 34, 37, 38, 37, 35, 35, 34, 35, 38, 38, 40, 40, 40, 48, 48, 46, 46, 56, 56, 58, 69, 69, 83 }; /** * Mapping for zig-zag scan ordering */ private final static int zigzag[] = { 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 }; /** * Quantization scale for macro blocks */ private int scale; /** * Quantization matrix for intra coded blocks */ private int intraMatrix[]; /** * Quantization matrix for inter coded blocks */ private int interMatrix[]; /** * Color components sample blocks (8 bits) */ private int block[][]; /** * Predictors for DC coefficients (10 bits) */ private int predictor[]; /** * Macroblock type encoding */ private int type; /** * Macroblock type flags */ private int flags; /** * Motion prediction vectors */ private MotionVector forward; private MotionVector backward; /** * Initializes the MPEG-1 macroblock decoder object */ public Macroblock() { /* create quantization matrices */ intraMatrix = new int[64]; interMatrix = new int[64]; /* create motion prediction vectors */ forward = new MotionVector(); backward = new MotionVector(); /* create DCT blocks and predictors */ block = new int[6][64]; predictor = new int[3]; /* set up default macro block types */ type = I_TYPE; flags = EMPTY; /* set up default quantization scale */ scale = 0; /* set up default quantization matrices */ for (int i = 0; i < 64; i++) { intraMatrix[i] = defaultIntraMatrix[i]; interMatrix[i] = 16; } /* set up default DC coefficient predictors */ for (int i = 0; i < 3; i++) predictor[i] = 1024; } /** * Returns the quantization scale */ public int getScale() { return scale; } /** * Changes the quantization scale */ public void setScale(int scale) { this.scale = scale; } /** * Returns the quantization matrix for intra coded blocks */ public int[] getIntraMatrix() { return intraMatrix; } /** * Changes the quantization matrix for intra coded blocks */ public void setIntraMatrix(int matrix[]) { for (int i = 0; i < 64; i++) intraMatrix[i] = matrix[i]; } /** * Returns the quantization matrix for inter coded blocks */ public int[] getInterMatrix() { return interMatrix; } /** * Changes the quantization matrix for inter coded blocks */ public void setInterMatrix(int matrix[]) { for (int i = 0; i < 64; i++) interMatrix[i] = matrix[i]; } /** * Returns the macroblock type encoding */ public int getType() { return type; } /** * Changes the macroblock type encoding */ public void setType(int type) { this.type = type; } /** * Returns the component block of samples */ public int[][] getData() { return block; } /** * Changes the component block of samples */ public void setData(int component, int data[]) { for (int i = 0; i < 64; i++) block[component][i] = data[i]; } /** * Returns the macro block type flags */ public int getFlags() { return flags; } /** * Changes the macro block type flags */ public void setFlags(int flags) { this.flags = flags; } /** * Returns true if the block is empty */ public boolean isEmpty() { return (flags & EMPTY) != 0; } /** * Returns true if the block is intra coded */ public boolean isIntraCoded() { return (flags & INTRA) != 0; } /** * Returns true if the block is pattern coded */ public boolean isPatternCoded() { return ((flags & PATTERN) != 0); } /** * Returns true if the block is forward predicted */ public boolean isBackwardPredicted() { return (flags & BACKWARD) != 0; } /** * Returns true if the block is backward predicted */ public boolean isForwardPredicted() { return (flags & FORWARD) != 0; } /** * Returns true if the block is forward and backward predicted */ public boolean isBidirPredicted() { return ((flags & FORWARD) != 0) && ((flags & BACKWARD) != 0); } /** * Returns true if the block has a quantization scale */ public boolean isQuantScaled() { return ((flags & QUANT) != 0); } /** * Returns the forward motion vector */ public MotionVector getForwardVector() {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -