package org.jcodec.codecs.h264.decode; import org.jcodec.codecs.h264.io.model.MBType; import org.jcodec.common.model.ColorSpace; import java.util.Arrays; /** * This class is part of JCodec ( www.jcodec.org ) This software is distributed * under FreeBSD License * * A codec macroblock * * @author The JCodec project * */ public class MBlock { public int chromaPredictionMode; public int mbQPDelta; public int[] dc; public int[][][] ac; public boolean transform8x8Used; public int[] lumaModes; public int[] dc1; public int[] dc2; public int _cbp; public int mbType; public MBType curMbType; public PB16x16 pb16x16; public PB168x168 pb168x168; public PB8x8 pb8x8; public IPCM ipcm; public int mbIdx; public boolean fieldDecoding; public MBType prevMbType; public int luma16x16Mode; public boolean skipped; // Number of coefficients in AC blocks, stored in 8x8 encoding order: 0 1 4 5 2 3 6 7 8 9 12 13 10 11 14 15 public int[] nCoeff; public MBlock(ColorSpace chromaFormat) { this.pb8x8 = new PB8x8(); this.pb16x16 = new PB16x16(); this.pb168x168 = new PB168x168(); dc = new int[16]; ac = new int[][][] { new int[16][64], new int[4][16], new int[4][16] }; lumaModes = new int[16]; nCoeff = new int[16]; dc1 = new int[(16 >> chromaFormat.compWidth[1]) >> chromaFormat.compHeight[1]]; dc2 = new int[(16 >> chromaFormat.compWidth[2]) >> chromaFormat.compHeight[2]]; ipcm = new IPCM(chromaFormat); } public int cbpLuma() { return _cbp & 0xf; } public int cbpChroma() { return _cbp >> 4; } public void cbp(int cbpLuma, int cbpChroma) { _cbp = (cbpLuma & 0xf) | (cbpChroma << 4); } static class PB16x16 { public int[] refIdx; public int[] mvdX; public int[] mvdY; public PB16x16() { this.refIdx = new int[2]; this.mvdX = new int[2]; this.mvdY = new int[2]; } public void clean() { refIdx[0] = refIdx[1] = 0; mvdX[0] = mvdX[1] = 0; mvdY[0] = mvdY[1] = 0; } } static class PB168x168 { public int[] refIdx1; public int[] refIdx2; public int[] mvdX1; public int[] mvdY1; public int[] mvdX2; public int[] mvdY2; public PB168x168() { this.refIdx1 = new int[2]; this.refIdx2 = new int[2]; this.mvdX1 = new int[2]; this.mvdY1 = new int[2]; this.mvdX2 = new int[2]; this.mvdY2 = new int[2]; } public void clean() { refIdx1[0] = refIdx1[1] = 0; refIdx2[0] = refIdx2[1] = 0; mvdX1[0] = mvdX1[1] = 0; mvdY1[0] = mvdY1[1] = 0; mvdX2[0] = mvdX2[1] = 0; mvdY2[0] = mvdY2[1] = 0; } } static class PB8x8 { public int[][] refIdx; public int[] subMbTypes; public int[][] mvdX1; public int[][] mvdY1; public int[][] mvdX2; public int[][] mvdY2; public int[][] mvdX3; public int[][] mvdY3; public int[][] mvdX4; public int[][] mvdY4; public PB8x8() { this.refIdx = new int[2][4]; this.subMbTypes = new int[4]; this.mvdX1 = new int[2][4]; this.mvdY1 = new int[2][4]; this.mvdX2 = new int[2][4]; this.mvdY2 = new int[2][4]; this.mvdX3 = new int[2][4]; this.mvdY3 = new int[2][4]; this.mvdX4 = new int[2][4]; this.mvdY4 = new int[2][4]; } public void clean() { mvdX1[0][0] = mvdX1[0][1] = mvdX1[0][2] = mvdX1[0][3] = 0; mvdX2[0][0] = mvdX2[0][1] = mvdX2[0][2] = mvdX2[0][3] = 0; mvdX3[0][0] = mvdX3[0][1] = mvdX3[0][2] = mvdX3[0][3] = 0; mvdX4[0][0] = mvdX4[0][1] = mvdX4[0][2] = mvdX4[0][3] = 0; mvdY1[0][0] = mvdY1[0][1] = mvdY1[0][2] = mvdY1[0][3] = 0; mvdY2[0][0] = mvdY2[0][1] = mvdY2[0][2] = mvdY2[0][3] = 0; mvdY3[0][0] = mvdY3[0][1] = mvdY3[0][2] = mvdY3[0][3] = 0; mvdY4[0][0] = mvdY4[0][1] = mvdY4[0][2] = mvdY4[0][3] = 0; mvdX1[1][0] = mvdX1[1][1] = mvdX1[1][2] = mvdX1[1][3] = 0; mvdX2[1][0] = mvdX2[1][1] = mvdX2[1][2] = mvdX2[1][3] = 0; mvdX3[1][0] = mvdX3[1][1] = mvdX3[1][2] = mvdX3[1][3] = 0; mvdX4[1][0] = mvdX4[1][1] = mvdX4[1][2] = mvdX4[1][3] = 0; mvdY1[1][0] = mvdY1[1][1] = mvdY1[1][2] = mvdY1[1][3] = 0; mvdY2[1][0] = mvdY2[1][1] = mvdY2[1][2] = mvdY2[1][3] = 0; mvdY3[1][0] = mvdY3[1][1] = mvdY3[1][2] = mvdY3[1][3] = 0; mvdY4[1][0] = mvdY4[1][1] = mvdY4[1][2] = mvdY4[1][3] = 0; subMbTypes[0] = subMbTypes[1] = subMbTypes[2] = subMbTypes[3] = 0; refIdx[0][0] = refIdx[0][1] = refIdx[0][2] = refIdx[0][3] = 0; refIdx[1][0] = refIdx[1][1] = refIdx[1][2] = refIdx[1][3] = 0; } } static class IPCM { public int[] samplesLuma; public int[] samplesChroma; public IPCM(ColorSpace chromaFormat) { this.samplesLuma = new int[256]; int MbWidthC = 16 >> chromaFormat.compWidth[1]; int MbHeightC = 16 >> chromaFormat.compHeight[1]; samplesChroma = new int[2 * MbWidthC * MbHeightC]; } public void clean() { Arrays.fill(samplesLuma, 0); Arrays.fill(samplesChroma, 0); } } public void clear() { chromaPredictionMode = 0; mbQPDelta = 0; Arrays.fill(dc, 0); for (int i = 0; i < ac.length; i++) for (int j = 0; j < ac[i].length; j++) for (int k = 0; k < ac[i][j].length; k++) ac[i][j][k] = 0; transform8x8Used = false; Arrays.fill(lumaModes, 0); Arrays.fill(dc1, 0); Arrays.fill(dc2, 0); Arrays.fill(nCoeff, 0); _cbp = 0; mbType = 0; pb16x16.clean(); pb168x168.clean(); pb8x8.clean(); if (curMbType == MBType.I_PCM) ipcm.clean(); mbIdx = 0; fieldDecoding = false; prevMbType = null; luma16x16Mode = 0; skipped = false; curMbType = null; } }