void predictInter16x16(
      MBlock mBlock,
      Picture8Bit mb,
      Picture8Bit[][] references,
      int mbX,
      int mbY,
      boolean leftAvailable,
      boolean topAvailable,
      boolean tlAvailable,
      boolean trAvailable,
      int[][][] x,
      int xx,
      int list,
      PartPred curPred) {

    int mvX = 0, mvY = 0, r = -1;
    if (curPred.usesList(list)) {
      int mvpX =
          calcMVPredictionMedian(
              s.mvLeft[list][0],
              s.mvTop[list][mbX << 2],
              s.mvTop[list][(mbX << 2) + 4],
              s.mvTopLeft[list],
              leftAvailable,
              topAvailable,
              trAvailable,
              tlAvailable,
              mBlock.pb16x16.refIdx[list],
              0);
      int mvpY =
          calcMVPredictionMedian(
              s.mvLeft[list][0],
              s.mvTop[list][mbX << 2],
              s.mvTop[list][(mbX << 2) + 4],
              s.mvTopLeft[list],
              leftAvailable,
              topAvailable,
              trAvailable,
              tlAvailable,
              mBlock.pb16x16.refIdx[list],
              1);

      mvX = mBlock.pb16x16.mvdX[list] + mvpX;
      mvY = mBlock.pb16x16.mvdY[list] + mvpY;

      debugPrint(
          "MVP: (%d, %d), MVD: (%d, %d), MV: (%d,%d,%d)",
          mvpX,
          mvpY,
          mBlock.pb16x16.mvdX[list],
          mBlock.pb16x16.mvdY[list],
          mvX,
          mvY,
          mBlock.pb16x16.refIdx[list]);
      r = mBlock.pb16x16.refIdx[list];

      BlockInterpolator.getBlockLuma(
          references[list][r], mb, 0, (mbX << 6) + mvX, (mbY << 6) + mvY, 16, 16);
    }

    copyVect(s.mvTopLeft[list], s.mvTop[list][xx + 3]);
    saveVect(s.mvTop[list], xx, xx + 4, mvX, mvY, r);
    saveVect(s.mvLeft[list], 0, 4, mvX, mvY, r);

    int[] v = {mvX, mvY, r};
    x[list] = new int[][] {v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v};
  }
  private void predictInter16x8(
      MBlock mBlock,
      Picture8Bit mb,
      Picture8Bit[][] references,
      int mbX,
      int mbY,
      boolean leftAvailable,
      boolean topAvailable,
      boolean tlAvailable,
      boolean trAvailable,
      int xx,
      int[][][] x,
      PartPred p0,
      PartPred p1,
      int list) {

    int mvX1 = 0, mvY1 = 0, mvX2 = 0, mvY2 = 0, r1 = -1, r2 = -1;
    if (p0.usesList(list)) {

      int mvpX1 =
          calcMVPrediction16x8Top(
              s.mvLeft[list][0],
              s.mvTop[list][mbX << 2],
              s.mvTop[list][(mbX << 2) + 4],
              s.mvTopLeft[list],
              leftAvailable,
              topAvailable,
              trAvailable,
              tlAvailable,
              mBlock.pb168x168.refIdx1[list],
              0);
      int mvpY1 =
          calcMVPrediction16x8Top(
              s.mvLeft[list][0],
              s.mvTop[list][mbX << 2],
              s.mvTop[list][(mbX << 2) + 4],
              s.mvTopLeft[list],
              leftAvailable,
              topAvailable,
              trAvailable,
              tlAvailable,
              mBlock.pb168x168.refIdx1[list],
              1);

      mvX1 = mBlock.pb168x168.mvdX1[list] + mvpX1;
      mvY1 = mBlock.pb168x168.mvdY1[list] + mvpY1;

      debugPrint(
          "MVP: (%d, %d), MVD: (%d, %d), MV: (%d,%d,%d)",
          mvpX1,
          mvpY1,
          mBlock.pb168x168.mvdX1[list],
          mBlock.pb168x168.mvdY1[list],
          mvX1,
          mvY1,
          mBlock.pb168x168.refIdx1[list]);

      BlockInterpolator.getBlockLuma(
          references[list][mBlock.pb168x168.refIdx1[list]],
          mb,
          0,
          (mbX << 6) + mvX1,
          (mbY << 6) + mvY1,
          16,
          8);
      r1 = mBlock.pb168x168.refIdx1[list];
    }
    int[] v1 = {mvX1, mvY1, r1};

    if (p1.usesList(list)) {
      int mvpX2 =
          calcMVPrediction16x8Bottom(
              s.mvLeft[list][2],
              v1,
              null,
              s.mvLeft[list][1],
              leftAvailable,
              true,
              false,
              leftAvailable,
              mBlock.pb168x168.refIdx2[list],
              0);
      int mvpY2 =
          calcMVPrediction16x8Bottom(
              s.mvLeft[list][2],
              v1,
              null,
              s.mvLeft[list][1],
              leftAvailable,
              true,
              false,
              leftAvailable,
              mBlock.pb168x168.refIdx2[list],
              1);

      mvX2 = mBlock.pb168x168.mvdX2[list] + mvpX2;
      mvY2 = mBlock.pb168x168.mvdY2[list] + mvpY2;

      debugPrint(
          "MVP: (%d, %d), MVD: (%d, %d), MV: (%d,%d,%d)",
          mvpX2,
          mvpY2,
          mBlock.pb168x168.mvdX2[list],
          mBlock.pb168x168.mvdY2[list],
          mvX2,
          mvY2,
          mBlock.pb168x168.refIdx2[list]);

      BlockInterpolator.getBlockLuma(
          references[list][mBlock.pb168x168.refIdx2[list]],
          mb,
          128,
          (mbX << 6) + mvX2,
          (mbY << 6) + 32 + mvY2,
          16,
          8);
      r2 = mBlock.pb168x168.refIdx2[list];
    }
    int[] v2 = {mvX2, mvY2, r2};

    copyVect(s.mvTopLeft[list], s.mvTop[list][xx + 3]);
    saveVect(s.mvLeft[list], 0, 2, mvX1, mvY1, r1);
    saveVect(s.mvLeft[list], 2, 4, mvX2, mvY2, r2);
    saveVect(s.mvTop[list], xx, xx + 4, mvX2, mvY2, r2);

    x[list] = new int[][] {v1, v1, v1, v1, v1, v1, v1, v1, v2, v2, v2, v2, v2, v2, v2, v2};
  }