Exemple #1
0
int vp9_decode_block_tokens(MACROBLOCKD *xd, int plane, const scan_order *sc,
                            int x, int y, TX_SIZE tx_size, vpx_reader *r,
                            int seg_id) {
  struct macroblockd_plane *const pd = &xd->plane[plane];
  const int16_t *const dequant = pd->seg_dequant[seg_id];
  int eob;
  ENTROPY_CONTEXT *a = pd->above_context + x;
  ENTROPY_CONTEXT *l = pd->left_context + y;
  int ctx;
  int ctx_shift_a = 0;
  int ctx_shift_l = 0;

  switch (tx_size) {
    case TX_4X4:
      ctx = a[0] != 0;
      ctx += l[0] != 0;
      eob = decode_coefs(xd, get_plane_type(plane), pd->dqcoeff, tx_size,
                         dequant, ctx, sc->scan, sc->neighbors, r);
      a[0] = l[0] = (eob > 0);
      break;
    case TX_8X8:
      get_ctx_shift(xd, &ctx_shift_a, &ctx_shift_l, x, y, 1 << TX_8X8);
      ctx = !!*(const uint16_t *)a;
      ctx += !!*(const uint16_t *)l;
      eob = decode_coefs(xd, get_plane_type(plane), pd->dqcoeff, tx_size,
                         dequant, ctx, sc->scan, sc->neighbors, r);
      *(uint16_t *)a = ((eob > 0) * 0x0101) >> ctx_shift_a;
      *(uint16_t *)l = ((eob > 0) * 0x0101) >> ctx_shift_l;
      break;
    case TX_16X16:
      get_ctx_shift(xd, &ctx_shift_a, &ctx_shift_l, x, y, 1 << TX_16X16);
      ctx = !!*(const uint32_t *)a;
      ctx += !!*(const uint32_t *)l;
      eob = decode_coefs(xd, get_plane_type(plane), pd->dqcoeff, tx_size,
                         dequant, ctx, sc->scan, sc->neighbors, r);
      *(uint32_t *)a = ((eob > 0) * 0x01010101) >> ctx_shift_a;
      *(uint32_t *)l = ((eob > 0) * 0x01010101) >> ctx_shift_l;
      break;
    case TX_32X32:
      get_ctx_shift(xd, &ctx_shift_a, &ctx_shift_l, x, y, 1 << TX_32X32);
      // NOTE: casting to uint64_t here is safe because the default memory
      // alignment is at least 8 bytes and the TX_32X32 is aligned on 8 byte
      // boundaries.
      ctx = !!*(const uint64_t *)a;
      ctx += !!*(const uint64_t *)l;
      eob = decode_coefs(xd, get_plane_type(plane), pd->dqcoeff, tx_size,
                         dequant, ctx, sc->scan, sc->neighbors, r);
      *(uint64_t *)a = ((eob > 0) * 0x0101010101010101ULL) >> ctx_shift_a;
      *(uint64_t *)l = ((eob > 0) * 0x0101010101010101ULL) >> ctx_shift_l;
      break;
    default:
      assert(0 && "Invalid transform size.");
      eob = 0;
      break;
  }

  return eob;
}
Exemple #2
0
int vp9_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];
  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 shift = (tx_size == TX_32X32);
  const int16_t *const 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;
  const int dq_step[2] = { dequant_ptr[0] >> shift, dequant_ptr[1] >> shift };
Exemple #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;
            }
Exemple #4
0
static void tokenize_b(int plane, int block, int row, int col,
                       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];
  MODE_INFO *mi = xd->mi[0];
  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 = get_plane_type(plane);
  const tran_low_t *qcoeff = BLOCK_OFFSET(p->qcoeff, block);
  const int16_t *scan, *nb;
  const scan_order *so;
  const int ref = is_inter_block(mi);
  unsigned int (*const counts)[COEFF_CONTEXTS][ENTROPY_TOKENS] =
      td->rd_counts.coef_counts[tx_size][type][ref];
  vpx_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 tx_eob = 16 << (tx_size << 1);
  int16_t token;
  EXTRABIT extra;
  pt = get_entropy_context(tx_size, pd->above_context + col,
                           pd->left_context + row);
  so = get_scan(xd, tx_size, type, block);
  scan = so->scan;
  nb = so->neighbors;
  c = 0;

  while (c < eob) {
    int v = 0;
    v = qcoeff[scan[c]];
    ++eob_branch[band[c]][pt];

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

      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], token, extra, counts[band[c]][pt]);

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

  *tp = t;

  vp9_set_contexts(xd, pd, plane_bsize, tx_size, c > 0, col, row);
}