📄 mpegplayer.java
字号:
return forward; } /** * Returns the backward motion vector */ public MotionVector getBackwardVector() { return backward; } /** * Resets the DCT coefficient predictors */ public void resetDataPredictors() { for (int i = 0; i < 3; i++) predictor[i] = 1024; } /** * Resets the motion vector predictors */ public void resetMotionVectors() { forward.setVector(0, 0); backward.setVector(0, 0); } /** * Parses the next encoded MPEG-1 macroblock (according to ISO 11172-2) * decoding and dequantizing the DCT coefficient component blocks. */ public void getMacroblock(VLCInputStream stream) throws IOException { /* read macro block bit flags */ switch (getType()) { case I_TYPE: setFlags(stream.getIMBCode()); break; case P_TYPE: setFlags(stream.getPMBCode()); if (!isForwardPredicted()) resetMotionVectors(); if (!isIntraCoded()) resetDataPredictors(); break; case B_TYPE: setFlags(stream.getBMBCode()); if (isIntraCoded()) resetMotionVectors(); else resetDataPredictors(); break; } /* read quantization scale */ if (isQuantScaled()) { setScale(stream.getBits(5)); } /* read forward motion vector */ if (isForwardPredicted()) { getForwardVector().getMotionVector(stream); } /* read backward motion vector */ if (isBackwardPredicted()) { getBackwardVector().getMotionVector(stream); } /* read block pattern code */ int pattern = 0; if (isPatternCoded()) { pattern = stream.getCBPCode(); } /* clear DCT coefficients blocks */ for (int i = 0; i < 6; i++) { for (int j = 0; j < 64; j++) { block[i][j] = 0; } } /* read DCT coefficient blocks */ if (isIntraCoded()) { /* read intra coded DCT coefficients */ for (int i = 0; i < 6; i++) { block[i][0] = predictor[i < 4 ? 0 : i - 3]; getIntraBlock(stream, block[i], i); predictor[i < 4 ? 0 : i - 3] = block[i][0]; IDCT.transform(block[i]); } } else { /* read inter coded DCT coefficients */ for (int i = 0; i < 6; i++) { if ((pattern & (1 << (5 - i))) != 0) { getInterBlock(stream, block[i]); IDCT.transform(block[i]); } } } } /** * Parses an intra coded MPEG-1 block (according to ISO 11172-2) decoding * and dequantizing the DC and AC coefficients stored in zig zag order. */ private void getIntraBlock(VLCInputStream stream, int block[], int component) throws IOException { /* decode DC coefficients */ if (component < 4) block[0] += stream.getIntraDCLumValue() << 3; else block[0] += stream.getIntraDCChromValue() << 3; /* decode AC coefficients */ for (int i = 1; i <= block.length; i++) { int data[] = stream.getACValue(); if (data[0] == stream.EOB) break; int position = zigzag[i = (i + data[0]) & 63]; block[position] = (data[1] * scale * intraMatrix[i]) >> 3; } } /** * Parses a inter coded MPEG-1 block (according to ISO 11172-2) decoding * and dequantizing the DC and AC coefficients stored in zig zag order. */ private void getInterBlock(VLCInputStream stream, int block[]) throws IOException { /* decode DC and AC coefficients */ for (int i = 0; i <= block.length; i++) { int data[] = (i == 0 ? stream.getInterDCValue() : stream.getACValue()); if (data[0] == stream.EOB) break; data[1] += ((data[1] >> 31) << 1) + 1; int position = zigzag[i = (i + data[0]) & 63]; block[position] = (data[1] * scale * interMatrix[i]) >> 3; } }}/** * Picture decoder for MPEG-1 video streams according to ISO 11172-2. */class Picture { /** * Picture current and predictors frame buffers */ private int frameBuffer[]; private int forwardBuffer[]; private int backwardBuffer[]; /** * Macroblock decoder and dequantizer */ private Macroblock macroblock; /** * Dimension of the picture in pixels */ private int width, height; /** * Dimension of the picture in macro blocks */ private int mbColumns, mbRows; /** * Picture temporal reference number */ private int number; /** * Picture synchronization delay (1/90000s ticks) */ private int delay; /** * Constructs a MPEG-1 video stream picture */ public Picture() { /* constructs the macroblock */ macroblock = new Macroblock(); /* initialize temporal fields */ number = 0; delay = 0; /* initialize dimension and frame buffers */ width = height = 0; mbColumns = mbRows = 0; frameBuffer = null; forwardBuffer = null; backwardBuffer = null; } /** * Changes the picture dimensions */ public void setSize(int width, int height) { /* set up picture dimension */ this.width = width; this.height = height; /* compute dimension in macro blocks */ mbColumns = (width + 15) >> 4; mbRows = (height + 15) >> 4; /* allocate frame buffers */ frameBuffer = new int[256 * mbRows * mbColumns]; forwardBuffer = new int[256 * mbRows * mbColumns]; backwardBuffer = new int[256 * mbRows * mbColumns]; } /** * Returns the picture temporal reference */ public int getNumber() { return number; } /** * Changes the picture temporal reference */ public void setNumber(int number) { this.number = number; } /** * Returns the picture temporal delay */ public int getDelay() { return delay; } /** * Changes the picture temporal delay */ public void setDelay(int delay) { this.delay = delay; } /** * Returns the macro block object */ public Macroblock getMacroblock() { return macroblock; } /** * Returns the dimension of the picture in pixels */ public int getWidth() { return width; } public int getHeight() { return height; } public int getStride() { return mbColumns << 4; } /** * Returns the last picture of the MPEG-1 video stream */ public int[] getLastFrame() { return backwardBuffer; } /** * Parses the next picture from the MPEG-1 video stream */ public int[] getFrame(VLCInputStream stream) throws IOException { /* read picture temporal reference */ setNumber(stream.getBits(10)); /* read picture encoding type */ macroblock.setType(stream.getBits(3)); /* read VBV delay of this picture */ setDelay(stream.getBits(16)); /* read forward motion information */ if (macroblock.getType() != Macroblock.I_TYPE) { macroblock.getForwardVector().getMotionInfo(stream); } /* read backward motion information */ if (macroblock.getType() == Macroblock.B_TYPE) { macroblock.getBackwardVector().getMotionInfo(stream); } /* skip extra bit information */ while (stream.getBits(1) != 0) stream.flushBits(8); /* skip extensions and user data chunks */ while (stream.showCode() == BitInputStream.EXT_START_CODE || stream.showCode() == BitInputStream.USER_START_CODE) { stream.getCode(); } /* update forward frame buffer */ if (macroblock.getType() != Macroblock.B_TYPE) { int buffer[] = forwardBuffer; forwardBuffer = backwardBuffer; backwardBuffer = buffer; } /* parse picture slices */ while (stream.showCode() >= BitInputStream.SLICE_MIN_CODE && stream.showCode() <= BitInputStream.SLICE_MAX_CODE) { getSlice(stream, stream.getCode()); } /* update backward frame buffer */ if (macroblock.getType() != Macroblock.B_TYPE) { int buffer[] = backwardBuffer; backwardBuffer = frameBuffer; frameBuffer = buffer; return forwardBuffer; } return frameBuffer; } /** * Parses the next picture slice from the MPEG-1 video stream */ private void getSlice(VLCInputStream stream, int code) throws IOException { /* compute macro block address */ int address = (code - BitInputStream.SLICE_MIN_CODE) * mbColumns - 1; /* read slice quantization scale */ macroblock.setScale(stream.getBits(5)); /* skip extra bit information */ while (stream.getBits(1) != 0) { stream.flushBits(8); } /* reset DCT predictors and motion vectors */ macroblock.setFlags(Macroblock.EMPTY); macroblock.resetDataPredictors(); macroblock.resetMotionVectors(); /* parse slice macro blocks */ while (stream.showBits(23) != 0) { /* get macro block address increment */ int lastAddress = address + stream.getMBACode(); /* handle skipped macro blocks */ if (macroblock.isEmpty()) { /* handle the first macro block address in the slice */ address = lastAddress; } else { while (++address < lastAddress) { /* assume inter coded macro block with zero coefficients */ macroblock.resetDataPredictors(); /* use previous motion vectors or zero in P-picture macro blocks */ if (macroblock.getType() == Macroblock.P_TYPE) macroblock.resetMotionVectors(); /* process skipped macro block */ if (macroblock.isBidirPredicted()) { motionPrediction(address, forwardBuffer, backwardBuffer, macroblock.getForwardVector(), macroblock.getBackwardVector()); } else if (macroblock.isBackwardPredicted()) { motionPrediction(address, backwardBuffer, macroblock.getBackwardVector()); } else { motionPrediction(address, forwardBuffer, macroblock.getForwardVector()); } } } /* decode macro block */ macroblock.getMacroblock(stream); /* process macro block */ if (macroblock.isIntraCoded()) { motionPrediction(address, macroblock.getData()); } else { if (macroblock.isBidirPredicted()) { motionPrediction(address, forwardBuffer, backwardBuffer, macroblock.getForwardVector(), macroblock.getBackwardVector()); } else if (macroblock.isBackwardPredicted()) { motionPrediction(address, backwardBuffer, macroblock.getBackwardVector()); } else { motionPrediction(address, forwardBuffer, macroblock.getForwardVector()); } motionCompensation(address, macroblock.getData()); } } } private void motionPrediction(int address, int sourceBuffer[], MotionVector vector) { int width = mbColumns << 4; int offset = ((address % mbColumns) + width * (address / mbColumns)) << 4; int deltaA = (vector.horizontal >> 1) + width * (vector.vertical >> 1); int deltaB = (vector.horizontal & 1) + width * (vector.vertical & 1); if (deltaB == 0) { for (int i = 0; i < 16; i++) { System.arraycopy(sourceBuffer, offset + deltaA, frameBuffer, offset, 16); offset += width; } } else { deltaB += deltaA; for (int i = 0; i < 16; i++) { for (int j = 0; j < 16; j++) { int d0 = sourceBuffer[offset + deltaA]; int d1 = sourceBuffer[offset + deltaB]; int d2 = (d0 & 0xfefefe) + (d1 & 0xfefefe); int d3 = (d0 & d1) & 0x010101; frameBuffer[offset++] = (d2 >> 1) + d3; } offset += width - 16; } } } private void motionPrediction(int address, int sourceBufferA[], int sourceBufferB[], MotionVector vectorA, MotionVector vectorB) { int width = mbColumns << 4; int offset = ((address % mbColumns) + width * (address / mbColumns)) << 4; int deltaA = (vectorA.horizontal >> 1) + width * (vectorA.vertical >> 1); int deltaB = (vectorB.horizontal >> 1) + width * (vectorB.vertical >> 1); int deltaC = (vectorA.horizontal & 1) + width * (vectorA.vertical & 1); int deltaD = (vectorB.horizontal & 1) + width * (vectorB.vertical & 1); if (deltaC == 0 && deltaD == 0) { for (int i = 0; i < 16; i++) { for (int j = 0; j < 16; j++) { int d0 = sourceBufferA[offset + deltaA]; int d1 = sourceBufferB[offset + deltaB]; int d2 = (d0 & 0xfefefe) + (d1 & 0xfefefe); int d3 = (d0 & d1) & 0x010101; frameBuffer[offset++] = (d2 >> 1) + d3; } offset += width - 16; } } else { deltaC += deltaA; deltaD += deltaB; for (int i = 0; i < 16; i++) { for (int j = 0; j < 16; j++) { int d0 = sourceBufferA[offset + deltaA]; int d1 = sourceBufferB[offset + deltaB]; int d2 = sourceBufferA[offset + deltaC]; int d3 = sourceBufferB[offset + deltaD]; int d4 = ((d0 & 0xfcfcfc) + (d1 & 0xfcfcfc) + (d2 & 0xfcfcfc) + (d3 & 0xfcfcfc)); int d5 = (d0 + d1 + d2 + d3 - d4) & 0x040404; frameBuffer[offset++] = (d4 + d5) >> 2; } offset += width - 16; } } } private void motionPrediction(int address, int block[][]) { int width, offset, index; /* compute macroblock address */ width = mbColumns << 4; address = ((address % mbColumns) + width * (address / mbColumns)) << 4; /* reconstruct luminance blocks */ offset = address; index = 0; for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { frameBuffer[offset] = clip[512 + block[0][index]]; frameBuffer[offset+8] = clip[512 + block[1][index]]; offset++; index++; } offset += width - 8; } offset = address + (width << 3); index = 0; for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { frameBuffer[offset] = clip[512 + block[2][index]]; frameBuffer[offset+8] = clip[512 + block[3][index]]; offset++; index++; } offset += width - 8; } /* reconstruct chrominance blocks */ offset = address; index = 0; for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { int Cb = clip[512 + block[4][index]]; int Cr = clip[512 + block[5][index]]; int CbCr = (Cb << 8) + (Cr << 16); frameBuffer[offset++] += CbCr; frameBuffer[offset++] += CbCr; offset += width - 2; frameBuffer[offset++] += CbCr; frameBuffer[offset++] += CbCr; offset -= width; index++; } offset += width + width - 16; } } private void motionCompensation(int address, int block[][]) { int width, offset, index; /* compute macroblock address */ width = mbColumns << 4; address = ((address % mbColumns) + width * (address / mbColumns)) << 4; /* reconstruct luminance blocks */ offset = index = 0; for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { data[offset] = block[0][index]; data[offset+8] = block[1][index]; data[offset+128] = block[2][index]; data[offset+8+128] = block[3][index]; offset++; index++; } offset += 8; } /* reconstruct chrominance blocks */ offset = index = 0; for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { int Y, YCbCr; int Cb = 512 + block[4][index]; int Cr = 512 + block[5][index];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -