vp9_decodframe.c 37 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
/*
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
John Koleszar's avatar
John Koleszar committed
 */

#include <assert.h>
John Koleszar's avatar
John Koleszar committed

#include "./vp9_rtcd.h"
#include "vpx_mem/vpx_mem.h"
#include "vpx_scale/vpx_scale.h"

#include "vp9/common/vp9_extend.h"
#include "vp9/common/vp9_modecont.h"
#include "vp9/common/vp9_common.h"
#include "vp9/common/vp9_reconintra.h"
#include "vp9/common/vp9_reconinter.h"
#include "vp9/common/vp9_entropy.h"
#include "vp9/common/vp9_invtrans.h"
#include "vp9/common/vp9_alloccommon.h"
#include "vp9/common/vp9_entropymode.h"
#include "vp9/common/vp9_quant_common.h"
#include "vp9/common/vp9_seg_common.h"
#include "vp9/common/vp9_tile_common.h"

#include "vp9/decoder/vp9_dboolhuff.h"
#include "vp9/decoder/vp9_decodframe.h"
#include "vp9/decoder/vp9_detokenize.h"
#include "vp9/decoder/vp9_decodemv.h"
#include "vp9/decoder/vp9_onyxd_int.h"
#include "vp9/decoder/vp9_read_bit_buffer.h"
// #define DEC_DEBUG
#ifdef DEC_DEBUG
int dec_debug = 0;
#endif

static int read_le16(const uint8_t *p) {
  return (p[1] << 8) | p[0];
}

static int read_le32(const uint8_t *p) {
  return (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
}

// len == 0 is not allowed
static int read_is_valid(const uint8_t *start, size_t len,
                         const uint8_t *end) {
  return start + len > start && start + len <= end;
}

static void setup_txfm_mode(VP9_COMMON *pc, int lossless, vp9_reader *r) {
  if (lossless) {
    pc->txfm_mode = ONLY_4X4;
  } else {
    pc->txfm_mode = vp9_read_literal(r, 2);
    if (pc->txfm_mode == ALLOW_32X32)
      pc->txfm_mode += vp9_read_bit(r);

    if (pc->txfm_mode == TX_MODE_SELECT) {
      pc->prob_tx[0] = vp9_read_prob(r);
      pc->prob_tx[1] = vp9_read_prob(r);
      pc->prob_tx[2] = vp9_read_prob(r);
    }
  }
static int get_unsigned_bits(unsigned int num_values) {
  int cat = 0;
  if (num_values <= 1)
    return 0;
  num_values--;
  while (num_values > 0) {
    cat++;
    num_values >>= 1;
  }
  return cat;
}

static int inv_recenter_nonneg(int v, int m) {
  if (v > 2 * m)

  return v % 2 ? m - (v + 1) / 2 : m + v / 2;
static int decode_uniform(vp9_reader *r, int n) {
  int v;
  const int l = get_unsigned_bits(n);
  const int m = (1 << l) - n;
  if (!l)
    return 0;

  v = vp9_read_literal(r, l - 1);
  return v < m ?  v : (v << 1) - m + vp9_read_bit(r);
static int decode_term_subexp(vp9_reader *r, int k, int num_syms) {
  int i = 0, mk = 0, word;
  while (1) {
    const int b = i ? k + i - 1 : k;
    const int a = 1 << b;
    if (num_syms <= mk + 3 * a) {
      word = decode_uniform(r, num_syms - mk) + mk;
        word = vp9_read_literal(r, b) + mk;
static int decode_unsigned_max(vp9_reader *r, int max) {
  int data = 0, bit = 0, lmax = max;

  while (lmax) {
    data |= vp9_read_bit(r) << bit++;
    lmax >>= 1;
  }
  return data > max ? max : data;
}

John Koleszar's avatar
John Koleszar committed
static int merge_index(int v, int n, int modulus) {
  int max1 = (n - 1 - modulus / 2) / modulus + 1;
  if (v < max1) {
    v = v * modulus + modulus / 2;
  } else {
John Koleszar's avatar
John Koleszar committed
    int w;
    v -= max1;
    w = v;
    v += (v + modulus - modulus / 2) / modulus;
    while (v % modulus == modulus / 2 ||
           w != v - (v + modulus - modulus / 2) / modulus) v++;
  }
  return v;
John Koleszar's avatar
John Koleszar committed
static int inv_remap_prob(int v, int m) {
  const int n = 256;
  v = merge_index(v, n - 1, MODULUS_PARAM);
John Koleszar's avatar
John Koleszar committed
  if ((m << 1) <= n) {
    return inv_recenter_nonneg(v + 1, m);
John Koleszar's avatar
John Koleszar committed
  } else {
    return n - 1 - inv_recenter_nonneg(v + 1, n - 1 - m);
John Koleszar's avatar
John Koleszar committed
  }
static vp9_prob read_prob_diff_update(vp9_reader *r, int oldp) {
  int delp = decode_term_subexp(r, SUBEXP_PARAM, 255);
  return (vp9_prob)inv_remap_prob(delp, oldp);
void vp9_init_dequantizer(VP9_COMMON *pc) {
John Koleszar's avatar
John Koleszar committed

Dmitry Kovalev's avatar
Dmitry Kovalev committed
  for (q = 0; q < QINDEX_RANGE; q++) {
    pc->y_dequant[q][0] = vp9_dc_quant(q, pc->y_dc_delta_q);
    pc->uv_dequant[q][0] = vp9_dc_quant(q, pc->uv_dc_delta_q);
John Koleszar's avatar
John Koleszar committed

    pc->y_dequant[q][1] = vp9_ac_quant(q, 0);
    pc->uv_dequant[q][1] = vp9_ac_quant(q, pc->uv_ac_delta_q);
John Koleszar's avatar
John Koleszar committed
  }
static void mb_init_dequantizer(VP9_COMMON *pc, MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
  int i;
  const int segment_id = xd->mode_info_context->mbmi.segment_id;
  xd->q_index = vp9_get_qindex(xd, segment_id, pc->base_qindex);
John Koleszar's avatar
John Koleszar committed

  xd->plane[0].dequant = pc->y_dequant[xd->q_index];
  for (i = 1; i < MAX_MB_PLANE; i++)
    xd->plane[i].dequant = pc->uv_dequant[xd->q_index];
static INLINE void dequant_add_y(MACROBLOCKD *xd, TX_TYPE tx_type, int idx,
                                 BLOCK_SIZE_TYPE bsize) {
  struct macroblockd_plane *const y = &xd->plane[0];
  uint8_t* const dst = raster_block_offset_uint8(xd, bsize, 0, idx,
                                                 xd->plane[0].dst.buf,
                                                 xd->plane[0].dst.stride);
    vp9_iht_add_c(tx_type, BLOCK_OFFSET(y->qcoeff, idx, 16),
                  dst, xd->plane[0].dst.stride, y->eobs[idx]);
    xd->itxm_add(BLOCK_OFFSET(y->qcoeff, idx, 16),
                 dst, xd->plane[0].dst.stride, y->eobs[idx]);
Loading full blame...