Ejemplo n.º 1
0
static void tokenize_init_one(const vp9_extra_bit *const e,
                              int16_t *value_cost, int max_value) {
  int i = -max_value;

  TOKENVALUE t;
  do {

    vp9_get_token_extra(i, &t.token, &t.extra);
    // initialize the cost for extra bits for all possible coefficient value.
    {
      int cost = 0;
      const vp9_extra_bit *p = &e[t.token];

      if (p->base_val) {
        const int extra = t.extra;
        const int length = p->len;

        if (length)
          cost += treed_cost(p->tree, p->prob, extra >> 1, length);

        cost += vp9_cost_bit(vp9_prob_half, extra & 1); /* sign */
        value_cost[i] = cost;
      }
    }
  } while (++i < max_value);
}
Ejemplo n.º 2
0
static void tokenize_b(int plane, int block, BLOCK_SIZE plane_bsize,
                       TX_SIZE tx_size, void *arg) {
  struct tokenize_b_args* const args = arg;
  VP9_COMP *cpi = args->cpi;
  ThreadData *const td = args->td;
  MACROBLOCK *const x = &td->mb;
  MACROBLOCKD *const xd = &x->e_mbd;
  TOKENEXTRA **tp = args->tp;
  uint8_t token_cache[32 * 32];
  struct macroblock_plane *p = &x->plane[plane];
  struct macroblockd_plane *pd = &xd->plane[plane];
  MB_MODE_INFO *mbmi = &xd->mi[0].src_mi->mbmi;
  int pt; /* near block/prev token context index */
  int c;
  TOKENEXTRA *t = *tp;        /* store tokens starting here */
  int eob = p->eobs[block];
  const PLANE_TYPE type = pd->plane_type;
  const tran_low_t *qcoeff = BLOCK_OFFSET(p->qcoeff, block);
  const int segment_id = mbmi->segment_id;
  const int16_t *scan, *nb;
  const scan_order *so;
  const int ref = is_inter_block(mbmi);
  unsigned int (*const counts)[COEFF_CONTEXTS][ENTROPY_TOKENS] =
      td->rd_counts.coef_counts[tx_size][type][ref];
  vp9_prob (*const coef_probs)[COEFF_CONTEXTS][UNCONSTRAINED_NODES] =
      cpi->common.fc->coef_probs[tx_size][type][ref];
  unsigned int (*const eob_branch)[COEFF_CONTEXTS] =
      td->counts->eob_branch[tx_size][type][ref];
  const uint8_t *const band = get_band_translate(tx_size);
  const int seg_eob = get_tx_eob(&cpi->common.seg, segment_id, tx_size);
  int16_t token;
  EXTRABIT extra;
  int aoff, loff;
  txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &aoff, &loff);

  pt = get_entropy_context(tx_size, pd->above_context + aoff,
                           pd->left_context + loff);
  so = get_scan(xd, tx_size, type, block);
  scan = so->scan;
  nb = so->neighbors;
  c = 0;

  while (c < eob) {
    int v = 0;
    int skip_eob = 0;
    v = qcoeff[scan[c]];

    while (!v) {
      add_token_no_extra(&t, coef_probs[band[c]][pt], ZERO_TOKEN, skip_eob,
                         counts[band[c]][pt]);
      eob_branch[band[c]][pt] += !skip_eob;

      skip_eob = 1;
      token_cache[scan[c]] = 0;
      ++c;
      pt = get_coef_context(nb, token_cache, c);
      v = qcoeff[scan[c]];
    }

    vp9_get_token_extra(v, &token, &extra);

    add_token(&t, coef_probs[band[c]][pt], extra, (uint8_t)token,
              (uint8_t)skip_eob, counts[band[c]][pt]);
    eob_branch[band[c]][pt] += !skip_eob;

    token_cache[scan[c]] = vp9_pt_energy_class[token];
    ++c;
    pt = get_coef_context(nb, token_cache, c);
  }
  if (c < seg_eob) {
    add_token_no_extra(&t, coef_probs[band[c]][pt], EOB_TOKEN, 0,
                       counts[band[c]][pt]);
    ++eob_branch[band[c]][pt];
  }

  *tp = t;

  vp9_set_contexts(xd, pd, plane_bsize, tx_size, c > 0, aoff, loff);
}
Ejemplo n.º 3
0
static int optimize_b(MACROBLOCK *mb, int plane, int block,
                      TX_SIZE tx_size, int ctx) {
    MACROBLOCKD *const xd = &mb->e_mbd;
    struct macroblock_plane *const p = &mb->plane[plane];
    struct macroblockd_plane *const pd = &xd->plane[plane];
    const int ref = is_inter_block(xd->mi[0]);
    vp9_token_state tokens[1025][2];
    unsigned best_index[1025][2];
    uint8_t token_cache[1024];
    const tran_low_t *const coeff = BLOCK_OFFSET(mb->plane[plane].coeff, block);
    tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
    tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
    const int eob = p->eobs[block];
    const PLANE_TYPE type = get_plane_type(plane);
    const int default_eob = 16 << (tx_size << 1);
    const int mul = 1 + (tx_size == TX_32X32);
    const int16_t *dequant_ptr = pd->dequant;
    const uint8_t *const band_translate = get_band_translate(tx_size);
    const scan_order *const so = get_scan(xd, tx_size, type, block);
    const int16_t *const scan = so->scan;
    const int16_t *const nb = so->neighbors;
    int next = eob, sz = 0;
    int64_t rdmult = mb->rdmult * plane_rd_mult[type], rddiv = mb->rddiv;
    int64_t rd_cost0, rd_cost1;
    int rate0, rate1, error0, error1;
    int16_t t0, t1;
    EXTRABIT e0;
    int best, band, pt, i, final_eob;
#if CONFIG_VP9_HIGHBITDEPTH
    const int *cat6_high_cost = vp9_get_high_cost_table(xd->bd);
#else
    const int *cat6_high_cost = vp9_get_high_cost_table(8);
#endif

    assert((!type && !plane) || (type && plane));
    assert(eob <= default_eob);

    /* Now set up a Viterbi trellis to evaluate alternative roundings. */
    if (!ref)
        rdmult = (rdmult * 9) >> 4;

    /* Initialize the sentinel node of the trellis. */
    tokens[eob][0].rate = 0;
    tokens[eob][0].error = 0;
    tokens[eob][0].next = default_eob;
    tokens[eob][0].token = EOB_TOKEN;
    tokens[eob][0].qc = 0;
    tokens[eob][1] = tokens[eob][0];

    for (i = 0; i < eob; i++)
        token_cache[scan[i]] =
            vp9_pt_energy_class[vp9_get_token(qcoeff[scan[i]])];

    for (i = eob; i-- > 0;) {
        int base_bits, d2, dx;
        const int rc = scan[i];
        int x = qcoeff[rc];
        /* Only add a trellis state for non-zero coefficients. */
        if (x) {
            int shortcut = 0;
            error0 = tokens[next][0].error;
            error1 = tokens[next][1].error;
            /* Evaluate the first possibility for this state. */
            rate0 = tokens[next][0].rate;
            rate1 = tokens[next][1].rate;
            vp9_get_token_extra(x, &t0, &e0);
            /* Consider both possible successor states. */
            if (next < default_eob) {
                band = band_translate[i + 1];
                pt = trellis_get_coeff_context(scan, nb, i, t0, token_cache);
                rate0 += mb->token_costs[tx_size][type][ref][band][0][pt]
                         [tokens[next][0].token];
                rate1 += mb->token_costs[tx_size][type][ref][band][0][pt]
                         [tokens[next][1].token];
            }
            UPDATE_RD_COST();
            /* And pick the best. */
            best = rd_cost1 < rd_cost0;
            base_bits = vp9_get_cost(t0, e0, cat6_high_cost);
            dx = mul * (dqcoeff[rc] - coeff[rc]);
#if CONFIG_VP9_HIGHBITDEPTH
            if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
                dx >>= xd->bd - 8;
            }
#endif  // CONFIG_VP9_HIGHBITDEPTH
            d2 = dx * dx;
            tokens[i][0].rate = base_bits + (best ? rate1 : rate0);
            tokens[i][0].error = d2 + (best ? error1 : error0);
            tokens[i][0].next = next;
            tokens[i][0].token = t0;
            tokens[i][0].qc = x;
            best_index[i][0] = best;

            /* Evaluate the second possibility for this state. */
            rate0 = tokens[next][0].rate;
            rate1 = tokens[next][1].rate;

            if ((abs(x) * dequant_ptr[rc != 0] > abs(coeff[rc]) * mul) &&
                    (abs(x) * dequant_ptr[rc != 0] < abs(coeff[rc]) * mul +
                     dequant_ptr[rc != 0]))
                shortcut = 1;
            else
                shortcut = 0;

            if (shortcut) {
                sz = -(x < 0);
                x -= 2 * sz + 1;
            }

            /* Consider both possible successor states. */
            if (!x) {
                /* If we reduced this coefficient to zero, check to see if
                 *  we need to move the EOB back here.
                 */
                t0 = tokens[next][0].token == EOB_TOKEN ? EOB_TOKEN : ZERO_TOKEN;
                t1 = tokens[next][1].token == EOB_TOKEN ? EOB_TOKEN : ZERO_TOKEN;
                e0 = 0;
            } else {
                vp9_get_token_extra(x, &t0, &e0);
                t1 = t0;
            }
            if (next < default_eob) {
                band = band_translate[i + 1];
                if (t0 != EOB_TOKEN) {
                    pt = trellis_get_coeff_context(scan, nb, i, t0, token_cache);
                    rate0 += mb->token_costs[tx_size][type][ref][band][!x][pt]
                             [tokens[next][0].token];
                }
                if (t1 != EOB_TOKEN) {
                    pt = trellis_get_coeff_context(scan, nb, i, t1, token_cache);
                    rate1 += mb->token_costs[tx_size][type][ref][band][!x][pt]
                             [tokens[next][1].token];
                }
            }

            UPDATE_RD_COST();
            /* And pick the best. */
            best = rd_cost1 < rd_cost0;
            base_bits = vp9_get_cost(t0, e0, cat6_high_cost);

            if (shortcut) {
#if CONFIG_VP9_HIGHBITDEPTH
                if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
                    dx -= ((dequant_ptr[rc != 0] >> (xd->bd - 8)) + sz) ^ sz;
                } else {
                    dx -= (dequant_ptr[rc != 0] + sz) ^ sz;
                }
#else
                dx -= (dequant_ptr[rc != 0] + sz) ^ sz;
#endif  // CONFIG_VP9_HIGHBITDEPTH
                d2 = dx * dx;
            }