summaryrefslogtreecommitdiff
path: root/vp9/decoder
diff options
context:
space:
mode:
authorScott LaVarnway <slavarnway@google.com>2016-03-29 15:03:12 -0700
committerScott LaVarnway <slavarnway@google.com>2016-04-01 04:57:39 -0700
commita2a97b869f0f4a8dec2a9d8d0c0dcdd56e5a0477 (patch)
tree12e597fb6ed94c295fb6435a4ca7c73405d63a78 /vp9/decoder
parent74ed95a33e8af1ad238e762651078eea282a16d6 (diff)
downloadlibvpx-a2a97b869f0f4a8dec2a9d8d0c0dcdd56e5a0477.tar
libvpx-a2a97b869f0f4a8dec2a9d8d0c0dcdd56e5a0477.tar.gz
libvpx-a2a97b869f0f4a8dec2a9d8d0c0dcdd56e5a0477.tar.bz2
libvpx-a2a97b869f0f4a8dec2a9d8d0c0dcdd56e5a0477.zip
VP9: Refactor vp9_decode_block_tokens()
Change-Id: I30ab27808ec903f9490f36621fb16c197bd35d16
Diffstat (limited to 'vp9/decoder')
-rw-r--r--vp9/decoder/vp9_decodeframe.c6
-rw-r--r--vp9/decoder/vp9_detokenize.c114
2 files changed, 67 insertions, 53 deletions
diff --git a/vp9/decoder/vp9_decodeframe.c b/vp9/decoder/vp9_decodeframe.c
index 32c72194d..02962c8d5 100644
--- a/vp9/decoder/vp9_decodeframe.c
+++ b/vp9/decoder/vp9_decodeframe.c
@@ -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,
diff --git a/vp9/decoder/vp9_detokenize.c b/vp9/decoder/vp9_detokenize.c
index dcc75b9d2..47dc107fe 100644
--- a/vp9/decoder/vp9_detokenize.c
+++ b/vp9/decoder/vp9_detokenize.c
@@ -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;
}
-
-