Commit a2a97b86 authored by Scott LaVarnway's avatar Scott LaVarnway

VP9: Refactor vp9_decode_block_tokens()

Change-Id: I30ab27808ec903f9490f36621fb16c197bd35d16
parent 74ed95a3
......@@ -158,6 +158,9 @@ typedef struct macroblockd {
MODE_INFO *left_mi;
MODE_INFO *above_mi;
unsigned int max_blocks_wide;
unsigned int max_blocks_high;
const vpx_prob (*partition_probs)[PARTITION_TYPES - 1];
/* Distance of MB away from frame edges */
......
......@@ -883,6 +883,9 @@ static void decode_block(VP9Decoder *const pbi, MACROBLOCKD *const xd,
const int max_blocks_high = num_4x4_h + (xd->mb_to_bottom_edge >= 0 ?
0 : xd->mb_to_bottom_edge >> (5 + pd->subsampling_y));
xd->max_blocks_wide = xd->mb_to_right_edge >= 0 ? 0 : max_blocks_wide;
xd->max_blocks_high = xd->mb_to_bottom_edge >= 0 ? 0 : max_blocks_high;
for (row = 0; row < max_blocks_high; row += step)
for (col = 0; col < max_blocks_wide; col += step)
predict_and_reconstruct_intra_block(xd, r, mi, plane,
......@@ -911,6 +914,9 @@ static void decode_block(VP9Decoder *const pbi, MACROBLOCKD *const xd,
const int max_blocks_high = num_4x4_h + (xd->mb_to_bottom_edge >= 0 ?
0 : xd->mb_to_bottom_edge >> (5 + pd->subsampling_y));
xd->max_blocks_wide = xd->mb_to_right_edge >= 0 ? 0 : max_blocks_wide;
xd->max_blocks_high = xd->mb_to_bottom_edge >= 0 ? 0 : max_blocks_high;
for (row = 0; row < max_blocks_high; row += step)
for (col = 0; col < max_blocks_wide; col += step)
eobtotal += reconstruct_inter_block(xd, r, mi, plane, row, col,
......
......@@ -152,65 +152,73 @@ static int decode_coefs(const MACROBLOCKD *xd,
return c;
}
// TODO(slavarnway): Decode version of vp9_set_context. Modify vp9_set_context
// after testing is complete, then delete this version.
static
void dec_set_contexts(const MACROBLOCKD *xd, struct macroblockd_plane *pd,
TX_SIZE tx_size, int has_eob,
int aoff, int loff) {
ENTROPY_CONTEXT *const a = pd->above_context + aoff;
ENTROPY_CONTEXT *const l = pd->left_context + loff;
const int tx_size_in_blocks = 1 << tx_size;
// above
if (has_eob && xd->mb_to_right_edge < 0) {
int i;
const int blocks_wide = pd->n4_w +
(xd->mb_to_right_edge >> (5 + pd->subsampling_x));
int above_contexts = tx_size_in_blocks;
if (above_contexts + aoff > blocks_wide)
above_contexts = blocks_wide - aoff;
for (i = 0; i < above_contexts; ++i)
a[i] = has_eob;
for (i = above_contexts; i < tx_size_in_blocks; ++i)
a[i] = 0;
} else {
memset(a, has_eob, sizeof(ENTROPY_CONTEXT) * tx_size_in_blocks);
static void get_ctx_shift(MACROBLOCKD *xd, int *ctx_shift_a, int *ctx_shift_l,
int x, int y, unsigned int tx_size_in_blocks) {
if (xd->max_blocks_wide) {
if (tx_size_in_blocks + x > xd->max_blocks_wide)
*ctx_shift_a = (tx_size_in_blocks - (xd->max_blocks_wide - x)) * 8;
}
// left
if (has_eob && xd->mb_to_bottom_edge < 0) {
int i;
const int blocks_high = pd->n4_h +
(xd->mb_to_bottom_edge >> (5 + pd->subsampling_y));
int left_contexts = tx_size_in_blocks;
if (left_contexts + loff > blocks_high)
left_contexts = blocks_high - loff;
for (i = 0; i < left_contexts; ++i)
l[i] = has_eob;
for (i = left_contexts; i < tx_size_in_blocks; ++i)
l[i] = 0;
} else {
memset(l, has_eob, sizeof(ENTROPY_CONTEXT) * tx_size_in_blocks);
if (xd->max_blocks_high) {
if (tx_size_in_blocks + y > xd->max_blocks_high)
*ctx_shift_l = (tx_size_in_blocks - (xd->max_blocks_high - y)) * 8;
}
}
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 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];
const int ctx = get_entropy_context(tx_size, pd->above_context + x,
pd->left_context + y);
const int eob = decode_coefs(xd, get_plane_type(plane),
pd->dqcoeff, tx_size,
dequant, ctx, sc->scan, sc->neighbors, r);
dec_set_contexts(xd, pd, tx_size, eob > 0, x, y);
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;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment