Newer
Older
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
* 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.
#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_reconintra.h"
#include "vp9/common/vp9_reconinter.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"
#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) {
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;
break;
} else {
if (vp9_read_bit(r)) {
i++;
mk += a;
} else {
word = vp9_read_literal(r, b) + mk;
break;
}
}
}
return word;
}
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;
}
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 {
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;
static int inv_remap_prob(int v, int m) {
const int n = 256;
v = merge_index(v, n - 1, MODULUS_PARAM);
return inv_recenter_nonneg(v + 1, m);
return n - 1 - inv_recenter_nonneg(v + 1, n - 1 - m);
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) {
// DC value
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);
// AC values
pc->y_dequant[q][1] = vp9_ac_quant(q, 0);
pc->uv_dequant[q][1] = vp9_ac_quant(q, pc->uv_ac_delta_q);
static void mb_init_dequantizer(VP9_COMMON *pc, MACROBLOCKD *xd) {
const int segment_id = xd->mode_info_context->mbmi.segment_id;
xd->q_index = vp9_get_qindex(xd, segment_id, pc->base_qindex);
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);
if (tx_type != DCT_DCT) {
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...