Beispiel #1
0
void VP8CodeIntraModes(VP8Encoder* const enc) {
  VP8BitWriter* const bw = &enc->bw_;
  VP8EncIterator it;
  VP8IteratorInit(enc, &it);
  do {
    const VP8MBInfo* const mb = it.mb_;
    const uint8_t* preds = it.preds_;
    if (enc->segment_hdr_.update_map_) {
      PutSegment(bw, mb->segment_, enc->proba_.segments_);
    }
    if (enc->proba_.use_skip_proba_) {
      VP8PutBit(bw, mb->skip_, enc->proba_.skip_proba_);
    }
    if (VP8PutBit(bw, (mb->type_ != 0), 145)) {  // i16x16
      PutI16Mode(bw, preds[0]);
    } else {
      const int preds_w = enc->preds_w_;
      const uint8_t* top_pred = preds - preds_w;
      int x, y;
      for (y = 0; y < 4; ++y) {
        int left = preds[-1];
        for (x = 0; x < 4; ++x) {
          const uint8_t* const probas = kBModesProba[top_pred[x]][left];
          left = PutI4Mode(bw, preds[x], probas);
        }
        top_pred = preds;
        preds += preds_w;
      }
    }
    PutUVMode(bw, mb->uv_mode_);
  } while (VP8IteratorNext(&it));
}
Beispiel #2
0
static void PutUVMode(VP8BitWriter* const bw, int uv_mode) {
  if (VP8PutBit(bw, uv_mode != DC_PRED, 142)) {
    if (VP8PutBit(bw, uv_mode != V_PRED, 114)) {
      VP8PutBit(bw, uv_mode != H_PRED, 183);    // else: TM_PRED
    }
  }
}
Beispiel #3
0
static void PutI16Mode(VP8BitWriter* const bw, int mode) {
  if (VP8PutBit(bw, (mode == TM_PRED || mode == H_PRED), 156)) {
    VP8PutBit(bw, mode == TM_PRED, 128);    // TM or HE
  } else {
    VP8PutBit(bw, mode == V_PRED, 163);     // VE or DC
  }
}
Beispiel #4
0
static int PutI4Mode(VP8BitWriter* const bw, int mode,
                     const uint8_t* const prob) {
  if (VP8PutBit(bw, mode != B_DC_PRED, prob[0])) {
    if (VP8PutBit(bw, mode != B_TM_PRED, prob[1])) {
      if (VP8PutBit(bw, mode != B_VE_PRED, prob[2])) {
        if (!VP8PutBit(bw, mode >= B_LD_PRED, prob[3])) {
          if (VP8PutBit(bw, mode != B_HE_PRED, prob[4])) {
            VP8PutBit(bw, mode != B_RD_PRED, prob[5]);
          }
        } else {
          if (VP8PutBit(bw, mode != B_LD_PRED, prob[6])) {
            if (VP8PutBit(bw, mode != B_VL_PRED, prob[7])) {
              VP8PutBit(bw, mode != B_HD_PRED, prob[8]);
            }
          }
        }
      }
    }
  }
  return mode;
}
Beispiel #5
0
void VP8WriteProbas(VP8BitWriter* const bw, const VP8Proba* const probas) {
  int t, b, c, p;
  for (t = 0; t < NUM_TYPES; ++t) {
    for (b = 0; b < NUM_BANDS; ++b) {
      for (c = 0; c < NUM_CTX; ++c) {
        for (p = 0; p < NUM_PROBAS; ++p) {
          const uint8_t p0 = probas->coeffs_[t][b][c][p];
          const int update = (p0 != VP8CoeffsProba0[t][b][c][p]);
          if (VP8PutBit(bw, update, VP8CoeffsUpdateProba[t][b][c][p])) {
            VP8PutBits(bw, p0, 8);
          }
        }
      }
    }
  }
  if (VP8PutBitUniform(bw, probas->use_skip_proba_)) {
    VP8PutBits(bw, probas->skip_proba_, 8);
  }
}
Beispiel #6
0
static int PutCoeffs(VP8BitWriter* const bw, int ctx, const VP8Residual* res) {
  int n = res->first;
  // should be prob[VP8EncBands[n]], but it's equivalent for n=0 or 1
  const uint8_t* p = res->prob[n][ctx];
  if (!VP8PutBit(bw, res->last >= 0, p[0])) {
    return 0;
  }

  while (n < 16) {
    const int c = res->coeffs[n++];
    const int sign = c < 0;
    int v = sign ? -c : c;
    if (!VP8PutBit(bw, v != 0, p[1])) {
      p = res->prob[VP8EncBands[n]][0];
      continue;
    }
    if (!VP8PutBit(bw, v > 1, p[2])) {
      p = res->prob[VP8EncBands[n]][1];
    } else {
      if (!VP8PutBit(bw, v > 4, p[3])) {
        if (VP8PutBit(bw, v != 2, p[4]))
          VP8PutBit(bw, v == 4, p[5]);
      } else if (!VP8PutBit(bw, v > 10, p[6])) {
        if (!VP8PutBit(bw, v > 6, p[7])) {
          VP8PutBit(bw, v == 6, 159);
        } else {
          VP8PutBit(bw, v >= 9, 165);
          VP8PutBit(bw, !(v & 1), 145);
        }
      } else {
        int mask;
        const uint8_t* tab;
        if (v < 3 + (8 << 1)) {          // VP8Cat3  (3b)
          VP8PutBit(bw, 0, p[8]);
          VP8PutBit(bw, 0, p[9]);
          v -= 3 + (8 << 0);
          mask = 1 << 2;
          tab = VP8Cat3;
        } else if (v < 3 + (8 << 2)) {   // VP8Cat4  (4b)
          VP8PutBit(bw, 0, p[8]);
          VP8PutBit(bw, 1, p[9]);
          v -= 3 + (8 << 1);
          mask = 1 << 3;
          tab = VP8Cat4;
        } else if (v < 3 + (8 << 3)) {   // VP8Cat5  (5b)
          VP8PutBit(bw, 1, p[8]);
          VP8PutBit(bw, 0, p[10]);
          v -= 3 + (8 << 2);
          mask = 1 << 4;
          tab = VP8Cat5;
        } else {                         // VP8Cat6 (11b)
          VP8PutBit(bw, 1, p[8]);
          VP8PutBit(bw, 1, p[10]);
          v -= 3 + (8 << 3);
          mask = 1 << 10;
          tab = VP8Cat6;
        }
        while (mask) {
          VP8PutBit(bw, !!(v & mask), *tab++);
          mask >>= 1;
        }
      }
      p = res->prob[VP8EncBands[n]][2];
    }
    VP8PutBitUniform(bw, sign);
    if (n == 16 || !VP8PutBit(bw, n <= res->last, p[0])) {
      return 1;   // EOB
    }
  }
  return 1;
}
Beispiel #7
0
static void PutSegment(VP8BitWriter* const bw, int s, const uint8_t* p) {
  if (VP8PutBit(bw, s >= 2, p[0])) p += 1;
  VP8PutBit(bw, s & 1, p[1]);
}