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_pred_common.h"
#include "vp9/common/vp9_quant_common.h"
#include "vp9/common/vp9_reconintra.h"
#include "vp9/common/vp9_reconinter.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_dsubexp.h"
#include "vp9/decoder/vp9_onyxd_int.h"
#include "vp9/decoder/vp9_read_bit_buffer.h"
static int read_be32(const uint8_t *p) {
return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
}
// 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 int decode_unsigned_max(struct vp9_read_bit_buffer *rb, int max) {
const int data = vp9_rb_read_literal(rb, get_unsigned_bits(max));
return data > max ? max : data;
}
static TX_MODE read_tx_mode(vp9_reader *r) {
TX_MODE tx_mode = vp9_read_literal(r, 2);
if (tx_mode == ALLOW_32X32)
tx_mode += vp9_read_bit(r);
return tx_mode;
static void read_tx_probs(struct tx_probs *tx_probs, vp9_reader *r) {
int i, j;
for (i = 0; i < TX_SIZE_CONTEXTS; ++i)
if (vp9_read(r, VP9_MODE_UPDATE_PROB))
vp9_diff_update_prob(r, &tx_probs->p8x8[i][j]);
for (i = 0; i < TX_SIZE_CONTEXTS; ++i)
if (vp9_read(r, VP9_MODE_UPDATE_PROB))
vp9_diff_update_prob(r, &tx_probs->p16x16[i][j]);
for (i = 0; i < TX_SIZE_CONTEXTS; ++i)
if (vp9_read(r, VP9_MODE_UPDATE_PROB))
vp9_diff_update_prob(r, &tx_probs->p32x32[i][j]);
static void init_dequantizer(VP9_COMMON *cm, MACROBLOCKD *xd) {
const int segment_id = xd->mode_info_context->mbmi.segment_id;
xd->q_index = vp9_get_qindex(xd, segment_id, cm->base_qindex);
xd->plane[0].dequant = cm->y_dequant[xd->q_index];
for (i = 1; i < MAX_MB_PLANE; i++)
xd->plane[i].dequant = cm->uv_dequant[xd->q_index];
static void decode_block(int plane, int block, BLOCK_SIZE_TYPE bsize,
int ss_txfrm_size, void *arg) {
MACROBLOCKD* const xd = arg;
struct macroblockd_plane *pd = &xd->plane[plane];
int16_t* const qcoeff = BLOCK_OFFSET(pd->qcoeff, block, 16);
const int stride = pd->dst.stride;
const int eob = pd->eobs[block];
const int raster_block = txfrm_block_to_raster_block(xd, bsize, plane,
block, ss_txfrm_size);
uint8_t* const dst = raster_block_offset_uint8(xd, bsize, plane,
raster_block,
switch (ss_txfrm_size / 2) {
case TX_4X4: {
const TX_TYPE tx_type = get_tx_type_4x4(pd->plane_type, xd, raster_block);
xd->itxm_add(qcoeff, dst, stride, eob);
vp9_iht_add_c(tx_type, qcoeff, dst, stride, eob);
vp9_iht_add_8x8_c(get_tx_type_8x8(pd->plane_type, xd), qcoeff, dst,
stride, eob);
break;
case TX_16X16:
vp9_iht_add_16x16_c(get_tx_type_16x16(pd->plane_type, xd), qcoeff, dst,
stride, eob);
break;
case TX_32X32:
vp9_idct_add_32x32(qcoeff, dst, stride, eob);
static void decode_block_intra(int plane, int block, BLOCK_SIZE_TYPE bsize,
int ss_txfrm_size, void *arg) {
MACROBLOCKD* const xd = arg;
struct macroblockd_plane *pd = &xd->plane[plane];
const int raster_block = txfrm_block_to_raster_block(xd, bsize, plane,
block, ss_txfrm_size);
uint8_t* const dst = raster_block_offset_uint8(xd, bsize, plane,
raster_block,
const TX_SIZE tx_size = (TX_SIZE)(ss_txfrm_size / 2);
const int tx_ib = raster_block >> tx_size;
const int mode = plane == 0 ? mi->mbmi.mode
: mi->mbmi.uv_mode;
if (plane == 0 && mi->mbmi.sb_type < BLOCK_SIZE_SB8X8) {
b_mode = mi->bmi[raster_block].as_mode;
if (xd->mb_to_right_edge < 0 || xd->mb_to_bottom_edge < 0)
extend_for_intra(xd, plane, block, bsize, ss_txfrm_size);
plane_b_size = b_width_log2(bsize) - pd->subsampling_x;
vp9_predict_intra_block(xd, tx_ib, plane_b_size, tx_size, b_mode,
// Early exit if there are no coefficients
decode_block(plane, block, bsize, ss_txfrm_size, arg);
static int decode_tokens(VP9D_COMP *pbi, BLOCK_SIZE_TYPE bsize, vp9_reader *r) {
MACROBLOCKD *const xd = &pbi->mb;
if (xd->mode_info_context->mbmi.mb_skip_coeff) {
vp9_reset_sb_tokens_context(xd, bsize);
if (xd->seg.enabled)
init_dequantizer(&pbi->common, xd);
// TODO(dkovalev) if (!vp9_reader_has_error(r))
return vp9_decode_tokens(pbi, r, bsize);
static void set_offsets(VP9D_COMP *pbi, BLOCK_SIZE_TYPE bsize,
VP9_COMMON *const cm = &pbi->common;
MACROBLOCKD *const xd = &pbi->mb;
const int bh = 1 << mi_height_log2(bsize);
const int bw = 1 << mi_width_log2(bsize);
const int mi_idx = mi_row * cm->mode_info_stride + mi_col;
xd->mode_info_context = cm->mi + mi_idx;
xd->mode_info_context->mbmi.sb_type = bsize;
// Special case: if prev_mi is NULL, the previous mode info context
// cannot be used.
xd->prev_mode_info_context = cm->prev_mi ? cm->prev_mi + mi_idx : NULL;
for (i = 0; i < MAX_MB_PLANE; i++) {
struct macroblockd_plane *pd = &xd->plane[i];
pd->above_context = cm->above_context[i] +
(mi_col * 2 >> pd->subsampling_x);
pd->left_context = cm->left_context[i] +
(((mi_row * 2) & 15) >> pd->subsampling_y);
Loading full blame...