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_idct.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"
#include "vp9/decoder/vp9_thread.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)
vp9_diff_update_prob(r, MODE_UPDATE_PROB, &tx_probs->p8x8[i][j]);
for (i = 0; i < TX_SIZE_CONTEXTS; ++i)
vp9_diff_update_prob(r, MODE_UPDATE_PROB, &tx_probs->p16x16[i][j]);
for (i = 0; i < TX_SIZE_CONTEXTS; ++i)
vp9_diff_update_prob(r, MODE_UPDATE_PROB, &tx_probs->p32x32[i][j]);
static void setup_plane_dequants(VP9_COMMON *cm, MACROBLOCKD *xd, int q_index) {
xd->plane[0].dequant = cm->y_dequant[q_index];
for (i = 1; i < MAX_MB_PLANE; i++)
xd->plane[i].dequant = cm->uv_dequant[q_index];
static void decode_block(int plane, int block, BLOCK_SIZE plane_bsize,
MACROBLOCKD* const xd = arg;
struct macroblockd_plane *const pd = &xd->plane[plane];
int16_t* const qcoeff = BLOCK_OFFSET(pd->qcoeff, block);
const int stride = pd->dst.stride;
const int eob = pd->eobs[block];
if (eob > 0) {
TX_TYPE tx_type;
const int raster_block = txfrm_block_to_raster_block(plane_bsize, tx_size,
block);
uint8_t* const dst = raster_block_offset_uint8(plane_bsize, raster_block,
pd->dst.buf, stride);
switch (tx_size) {
case TX_4X4:
tx_type = get_tx_type_4x4(pd->plane_type, xd, raster_block);
if (tx_type == DCT_DCT)
xd->itxm_add(qcoeff, dst, stride, eob);
else
vp9_iht_add(tx_type, qcoeff, dst, stride, eob);
break;
case TX_8X8:
tx_type = get_tx_type_8x8(pd->plane_type, xd);
vp9_iht_add_8x8(tx_type, qcoeff, dst, stride, eob);
break;
case TX_16X16:
tx_type = get_tx_type_16x16(pd->plane_type, xd);
vp9_iht_add_16x16(tx_type, qcoeff, dst, stride, eob);
break;
case TX_32X32:
tx_type = DCT_DCT;
vp9_idct32x32_add(qcoeff, dst, stride, eob);
break;
default:
assert(!"Invalid transform size");
}
if (eob == 1) {
*((int32_t *)qcoeff) = 0;
} else {
if (tx_type == DCT_DCT && tx_size <= TX_16X16 && eob <= 10)
vpx_memset(qcoeff, 0, 4 * (4 << tx_size) * sizeof(qcoeff[0]));
vpx_memset(qcoeff, 0, (16 << (tx_size << 1)) * sizeof(qcoeff[0]));
static void decode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
struct macroblockd_plane *const pd = &xd->plane[plane];
MODE_INFO *const mi = xd->this_mi;
const int raster_block = txfrm_block_to_raster_block(plane_bsize, tx_size,
block);
uint8_t* const dst = raster_block_offset_uint8(plane_bsize, raster_block,
const MB_PREDICTION_MODE mode = (plane == 0)
? ((mi->mbmi.sb_type < BLOCK_8X8) ? mi->bmi[raster_block].as_mode
: mi->mbmi.mode)
: mi->mbmi.uv_mode;
if (xd->mb_to_right_edge < 0 || xd->mb_to_bottom_edge < 0)
extend_for_intra(xd, plane_bsize, plane, block, tx_size);
vp9_predict_intra_block(xd, raster_block >> tx_size,
b_width_log2(plane_bsize), tx_size, mode,
dst, pd->dst.stride, dst, pd->dst.stride);
if (!mi->mbmi.skip_coeff)
decode_block(plane, block, plane_bsize, tx_size, arg);
static int decode_tokens(VP9D_COMP *pbi, BLOCK_SIZE bsize, vp9_reader *r) {
VP9_COMMON *const cm = &pbi->common;
MB_MODE_INFO *const mbmi = &xd->this_mi->mbmi;
if (mbmi->skip_coeff) {
reset_skip_context(xd, bsize);
if (cm->seg.enabled)
setup_plane_dequants(cm, xd, vp9_get_qindex(&cm->seg, mbmi->segment_id,
cm->base_qindex));
// TODO(dkovalev) if (!vp9_reader_has_error(r))
return vp9_decode_tokens(pbi, r, bsize);
static void set_offsets(VP9D_COMP *pbi, BLOCK_SIZE bsize,
VP9_COMMON *const cm = &pbi->common;
MACROBLOCKD *const xd = &pbi->mb;
const int bh = num_8x8_blocks_high_lookup[bsize];
const int bw = num_8x8_blocks_wide_lookup[bsize];
const int offset = mi_row * cm->mode_info_stride + mi_col;
xd->mode_info_stride = cm->mode_info_stride;
xd->mi_8x8 = cm->mi_grid_visible + offset;
xd->prev_mi_8x8 = cm->prev_mi_grid_visible + offset;
// we are using the mode info context stream here
xd->this_mi =
xd->mi_8x8[0] = xd->mic_stream_ptr;
xd->this_mi->mbmi.sb_type = bsize;
xd->mic_stream_ptr++;
// Special case: if prev_mi is NULL, the previous mode info context
// cannot be used.
xd->last_mi = cm->prev_mi ? xd->prev_mi_8x8[0] : NULL;
set_skip_context(cm, xd, mi_row, mi_col);
set_partition_seg_context(cm, xd, mi_row, mi_col);
Loading full blame...