예제 #1
0
  static void MBfilter(
      int hev_threshold, /* detect high edge variance */
      int interior_limit, /* possibly disable filter */
      int edge_limit,
      Segment seg) {
    int p3 = u2s(seg.P3), p2 = u2s(seg.P2), p1 = u2s(seg.P1), p0 = u2s(seg.P0);
    int q0 = u2s(seg.Q0), q1 = u2s(seg.Q1), q2 = u2s(seg.Q2), q3 = u2s(seg.Q3);
    if (filter_yes(interior_limit, edge_limit, q3, q2, q1, q0, p0, p1, p2, p3)) {
      if (!hev(hev_threshold, p1, p0, q0, q1)) {
        // Same as the initial calculation in "common_adjust",
        // w is something like twice the edge difference
        int w = c(c(p1 - q1) + 3 * (q0 - p0));

        // 9/64 is approximately 9/63 = 1/7 and 1<<7 = 128 = 2*64.
        // So this a, used to adjust the pixels adjacent to the edge,
        // is something like 3/7 the edge difference.
        int a = (27 * w + 63) >> 7;

        seg.Q0 = s2u(q0 - a);
        seg.P0 = s2u(p0 + a);
        // Next two are adjusted by 2/7 the edge difference
        a = (18 * w + 63) >> 7;
        // System.out.println("a: "+a);
        seg.Q1 = s2u(q1 - a);
        seg.P1 = s2u(p1 + a);
        // Last two are adjusted by 1/7 the edge difference
        a = (9 * w + 63) >> 7;
        seg.Q2 = s2u(q2 - a);
        seg.P2 = s2u(p2 + a);
      } else
        // if hev, do simple filter
        common_adjust(true, seg); // using outer taps
    }
  }
예제 #2
0
 private static Segment getSegH(SubBlock rsb, SubBlock lsb, int a) {
   Segment seg = new Segment();
   int[][] rdest = rsb.getDest();
   int[][] ldest = lsb.getDest();
   seg.P0 = ldest[3][a];
   seg.P1 = ldest[2][a];
   seg.P2 = ldest[1][a];
   seg.P3 = ldest[0][a];
   seg.Q0 = rdest[0][a];
   seg.Q1 = rdest[1][a];
   seg.Q2 = rdest[2][a];
   seg.Q3 = rdest[3][a];
   return seg;
 }
예제 #3
0
  private static Segment getSegV(SubBlock bsb, SubBlock tsb, int a) {
    Segment seg = new Segment();
    int[][] bdest = bsb.getDest();
    int[][] tdest = tsb.getDest();

    seg.P0 = tdest[a][3];
    seg.P1 = tdest[a][2];
    seg.P2 = tdest[a][1];
    seg.P3 = tdest[a][0];
    seg.Q0 = bdest[a][0];
    seg.Q1 = bdest[a][1];
    seg.Q2 = bdest[a][2];
    seg.Q3 = bdest[a][3];
    return seg;
  }
예제 #4
0
  private static int common_adjust(boolean use_outer_taps, /*
															 * filter is 2 or 4
															 * taps wide
															 */ Segment seg) {
    int p1 = u2s(seg.P1); /* retrieve and convert all 4 pixels */
    int p0 = u2s(seg.P0);
    int q0 = u2s(seg.Q0);
    int q1 = u2s(seg.Q1);

    /*
     * Disregarding clamping, when "use_outer_taps" is false, "a" is
     * 3*(q0-p0). Since we are about to divide "a" by 8, in this case we end
     * up multiplying the edge difference by 5/8. When "use_outer_taps" is
     * true (as for the simple filter), "a" is p1 - 3*p0 + 3*q0 - q1, which
     * can be thought of as a refinement of 2*(q0 - p0) and the adjustment
     * is something like (q0 - p0)/4.
     */
    int a = c((use_outer_taps ? c(p1 - q1) : 0) + 3 * (q0 - p0));
    /*
     * b is used to balance the rounding of a/8 in the case where the
     * "fractional" part "f" of a/8 is exactly 1/2.
     */
    int b = (c(a + 3)) >> 3;
    /*
     * Divide a by 8, rounding up when f >= 1/2. Although not strictly part
     * of the "C" language, the right-shift is assumed to propagate the sign
     * bit.
     */
    a = c(a + 4) >> 3;
    /* Subtract "a" from q0, "bringing it closer" to p0. */
    seg.Q0 = s2u(q0 - a);
    /*
     * Add "a" (with adjustment "b") to p0, "bringing it closer" to q0. The
     * clamp of "a+b", while present in the reference decoder, is
     * superfluous; we have -16 <= a <= 15 at this point.
     */
    seg.P0 = s2u(p0 + b);

    return a;
  }