summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Koleszar <jkoleszar@google.com>2010-06-30 11:23:04 -0400
committerJohn Koleszar <jkoleszar@google.com>2010-07-07 13:29:19 -0400
commit940599ff2c0716a76ff2a3f42d145475612c6374 (patch)
treed4d44007bee3f87b981e23fe4734efa0ad8cc144
parent86262018ad8abf7e4a359fc334720545aadae8ea (diff)
downloadlibvpx-940599ff2c0716a76ff2a3f42d145475612c6374.tar.gz
dixie: combine dequant with token decode
Scales as O(number-of-tokens) rather than O(16). Change-Id: Ic67b81289eeef7fedacd0b5973b7c06e5a507f29
-rw-r--r--vp8/dixie/dequant_data.h38
-rw-r--r--vp8/dixie/dixie.c83
-rw-r--r--vp8/dixie/dixie.h22
-rw-r--r--vp8/dixie/tokens.c41
4 files changed, 169 insertions, 15 deletions
diff --git a/vp8/dixie/dequant_data.h b/vp8/dixie/dequant_data.h
new file mode 100644
index 000000000..a03583e93
--- /dev/null
+++ b/vp8/dixie/dequant_data.h
@@ -0,0 +1,38 @@
+static const int dc_q_lookup[128] =
+{
+ 4, 5, 6, 7, 8, 9, 10, 10,
+ 11, 12, 13, 14, 15, 16, 17, 17,
+ 18, 19, 20, 20, 21, 21, 22, 22,
+ 23, 23, 24, 25, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36,
+ 37, 37, 38, 39, 40, 41, 42, 43,
+ 44, 45, 46, 46, 47, 48, 49, 50,
+ 51, 52, 53, 54, 55, 56, 57, 58,
+ 59, 60, 61, 62, 63, 64, 65, 66,
+ 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 76, 77, 78, 79, 80, 81,
+ 82, 83, 84, 85, 86, 87, 88, 89,
+ 91, 93, 95, 96, 98, 100, 101, 102,
+ 104, 106, 108, 110, 112, 114, 116, 118,
+ 122, 124, 126, 128, 130, 132, 134, 136,
+ 138, 140, 143, 145, 148, 151, 154, 157
+};
+static const int ac_q_lookup[128] =
+{
+ 4, 5, 6, 7, 8, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 40, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, 57, 58, 60,
+ 62, 64, 66, 68, 70, 72, 74, 76,
+ 78, 80, 82, 84, 86, 88, 90, 92,
+ 94, 96, 98, 100, 102, 104, 106, 108,
+ 110, 112, 114, 116, 119, 122, 125, 128,
+ 131, 134, 137, 140, 143, 146, 149, 152,
+ 155, 158, 161, 164, 167, 170, 173, 177,
+ 181, 185, 189, 193, 197, 201, 205, 209,
+ 213, 217, 221, 225, 229, 234, 239, 245,
+ 249, 254, 259, 264, 269, 274, 279, 284
+};
diff --git a/vp8/dixie/dixie.c b/vp8/dixie/dixie.c
index 33a032861..1ea642ea2 100644
--- a/vp8/dixie/dixie.c
+++ b/vp8/dixie/dixie.c
@@ -11,6 +11,7 @@
#include "bit_ops.h"
#include "dixie.h"
#include "vp8_prob_data.h"
+#include "dequant_data.h"
#include "modemv.h"
#include "tokens.h"
#include <string.h>
@@ -107,6 +108,7 @@ decode_quantizer_header(struct vp8_decoder_ctx *ctx,
update |= (hdr->y2_ac_delta_q = bool_maybe_get_int(bool, 4));
update |= (hdr->y1_dc_delta_q = bool_maybe_get_int(bool, 4));
update |= (hdr->y1_dc_delta_q = bool_maybe_get_int(bool, 4));
+ hdr->delta_update = update;
}
@@ -225,6 +227,77 @@ decode_segmentation_header(struct vp8_decoder_ctx *ctx,
static void
+dequant_global_init(struct dequant_factors dqf[MAX_MB_SEGMENTS])
+{
+ int i;
+
+ for (i = 0; i < MAX_MB_SEGMENTS; i++)
+ dqf[i].quant_idx = -1;
+}
+
+
+static int
+clamp_q(int q)
+{
+ if (q < 0) return 0;
+ else if (q > 127) return 127;
+
+ return q;
+}
+
+
+static int
+dc_q(int q)
+{
+ return dc_q_lookup[clamp_q(q)];
+}
+
+
+static int
+ac_q(int q)
+{
+ return ac_q_lookup[clamp_q(q)];
+}
+
+
+static void
+dequant_init(struct dequant_factors dqf[MAX_MB_SEGMENTS],
+ const struct vp8_segment_hdr *seg,
+ const struct vp8_quant_hdr *quant_hdr)
+{
+ int i, q;
+
+ for (i = 0; i < (seg->enabled ? MAX_MB_SEGMENTS : 1); i++)
+ {
+ q = quant_hdr->q_index;
+
+ if (seg->enabled)
+ q = (!seg->abs) ? q + seg->quant_idx[i] : seg->quant_idx[i];
+
+ if (dqf->quant_idx != q || quant_hdr->delta_update)
+ {
+ dqf->factor[TOKEN_BLOCK_Y1][0] = dc_q(q + quant_hdr->y1_dc_delta_q);
+ dqf->factor[TOKEN_BLOCK_Y1][1] = ac_q(q);
+ dqf->factor[TOKEN_BLOCK_UV][0] = dc_q(q + quant_hdr->uv_dc_delta_q);
+ dqf->factor[TOKEN_BLOCK_UV][1] = ac_q(q + quant_hdr->uv_ac_delta_q);
+ dqf->factor[TOKEN_BLOCK_Y2][0] = dc_q(q + quant_hdr->y2_dc_delta_q)
+ * 2;
+ dqf->factor[TOKEN_BLOCK_Y2][1] = ac_q(q + quant_hdr->y2_ac_delta_q)
+ * 155 / 100;
+
+ if (dqf->factor[TOKEN_BLOCK_Y2][1] < 8)
+ dqf->factor[TOKEN_BLOCK_Y2][1] = 8;
+
+ if (dqf->factor[TOKEN_BLOCK_UV][0] > 132)
+ dqf->factor[TOKEN_BLOCK_UV][0] = 132;
+
+ dqf->quant_idx = q;
+ }
+ }
+}
+
+
+static void
decode_frame(struct vp8_decoder_ctx *ctx,
const unsigned char *data,
unsigned int sz)
@@ -301,6 +374,7 @@ decode_frame(struct vp8_decoder_ctx *ctx,
vp8_dixie_modemv_init(ctx);
vp8_dixie_tokens_init(ctx);
+ dequant_init(ctx->dequant_factors, &ctx->segment_hdr, &ctx->quant_hdr);
for (row = 0, partition = 0; row < ctx->mb_rows; row++)
{
@@ -311,6 +385,8 @@ decode_frame(struct vp8_decoder_ctx *ctx,
partition = 0;
}
+ ctx->frame_cnt++;
+
if (!ctx->reference_hdr.refresh_entropy)
{
ctx->entropy_hdr = ctx->saved_entropy;
@@ -319,6 +395,13 @@ decode_frame(struct vp8_decoder_ctx *ctx,
}
+void
+vp8_dixie_decode_init(struct vp8_decoder_ctx *ctx)
+{
+ dequant_global_init(ctx->dequant_factors);
+}
+
+
#define CHECK_FOR_UPDATE(lval,rval,update_flag) do {\
unsigned int old = lval; \
update_flag |= (old != (lval = rval)); \
diff --git a/vp8/dixie/dixie.h b/vp8/dixie/dixie.h
index 9c48a03c1..951e7816f 100644
--- a/vp8/dixie/dixie.h
+++ b/vp8/dixie/dixie.h
@@ -83,6 +83,7 @@ struct vp8_token_hdr
struct vp8_quant_hdr
{
unsigned int q_index;
+ int delta_update;
int y1_dc_delta_q;
int y2_dc_delta_q;
int y2_ac_delta_q;
@@ -184,6 +185,7 @@ struct mb_base_info
unsigned char ref_frame : 2;
unsigned char skip_coeff : 1;
union mv mv;
+ unsigned int eob_mask;
};
@@ -208,9 +210,24 @@ struct token_decoder
short *coeffs;
};
+enum token_block_type
+{
+ TOKEN_BLOCK_Y1,
+ TOKEN_BLOCK_UV,
+ TOKEN_BLOCK_Y2,
+ TOKEN_BLOCK_TYPES,
+};
+
+struct dequant_factors
+{
+ int quant_idx;
+ short factor[TOKEN_BLOCK_TYPES][2]; /* [ Y1, UV, Y2 ] [ DC, AC ] */
+};
+
struct vp8_decoder_ctx
{
struct vpx_internal_error_info error;
+ unsigned int frame_cnt;
struct vp8_frame_hdr frame_hdr;
struct vp8_segment_hdr segment_hdr;
@@ -231,9 +248,14 @@ struct vp8_decoder_ctx
token_entropy_ctx_t *above_token_entropy_ctx;
struct token_decoder tokens[MAX_PARTITIONS];
+ struct dequant_factors dequant_factors[MAX_MB_SEGMENTS];
};
+void
+vp8_dixie_decode_init(struct vp8_decoder_ctx *ctx);
+
+
vpx_codec_err_t
vp8_parse_frame_header(const unsigned char *data,
unsigned int sz,
diff --git a/vp8/dixie/tokens.c b/vp8/dixie/tokens.c
index aa9310c95..c55195152 100644
--- a/vp8/dixie/tokens.c
+++ b/vp8/dixie/tokens.c
@@ -114,6 +114,7 @@ static const unsigned int zigzag[16] =
value = value-bigsplit; \
v = -value_to_sign; \
} \
+ v *= dqf[!!c]; \
range +=range; \
value +=value; \
count--;
@@ -188,17 +189,18 @@ decode_mb_tokens(struct bool_decoder *bool,
token_entropy_ctx_t left,
token_entropy_ctx_t above,
short *tokens,
- int *eobs,
enum prediction_mode mode,
- coeff_probs_table_t probs)
+ coeff_probs_table_t probs,
+ short factor[TOKEN_BLOCK_TYPES][2])
{
int i, stop, type;
int c, t, v;
int val, bits_count;
- int eob_total;
+ int eob_mask;
short *b_tokens; /* tokens for this block */
unsigned char *type_probs; /* probabilities for this block type */
unsigned char *prob;
+ short *dqf;
/* Unpack bool decoder to local variables */
const unsigned char *bufend = bool->user_buffer_end;
@@ -210,13 +212,15 @@ decode_mb_tokens(struct bool_decoder *bool,
vp8_bool_value_t bigsplit;
unsigned int shift;
+ eob_mask = 0;
+
if (mode != B_PRED && mode != SPLITMV)
{
i = 24;
stop = 24;
type = 1;
b_tokens = tokens + 24 * 16;
- eob_total = -16;
+ dqf = factor[TOKEN_BLOCK_Y2];
}
else
{
@@ -224,7 +228,7 @@ decode_mb_tokens(struct bool_decoder *bool,
stop = 16;
type = 3;
b_tokens = tokens;
- eob_total = 0;
+ dqf = factor[TOKEN_BLOCK_Y1];
}
/* Save a pointer to the coefficient probs for the current type. Need
@@ -324,7 +328,7 @@ ONE_CONTEXT_NODE_0_:
b_tokens[zigzag[15]] = v;
BLOCK_FINISHED:
- eob_total += eobs[i] = c;
+ eob_mask |= (c > 1) << i;
t = (c != !type); // any nonzero data?
left[left_context_index[i]] = above[above_context_index[i]] = t;
@@ -342,6 +346,7 @@ BLOCK_FINISHED:
stop = 16;
type_probs = probs[type][0][0];
b_tokens = tokens;
+ dqf = factor[TOKEN_BLOCK_Y1];
goto BLOCK_LOOP;
}
@@ -350,6 +355,7 @@ BLOCK_FINISHED:
type = 2;
type_probs = probs[type][0][0];
stop = 24;
+ dqf = factor[TOKEN_BLOCK_UV];
goto BLOCK_LOOP;
}
@@ -358,7 +364,7 @@ BLOCK_FINISHED:
bool->value = value;
bool->count = count;
bool->range = range;
- return eob_total;
+ return eob_mask;
}
@@ -418,19 +424,24 @@ vp8_dixie_tokens_process_row(struct vp8_decoder_ctx *ctx,
for (col = start_col; col < start_col + num_cols; col++)
{
- int eob_cnt, eobs[25];
+ memset(coeffs, 0, 25 * 16 * sizeof(short));
if (mbi->base.skip_coeff)
+ {
reset_mb_context(left, above, mbi->base.y_mode);
+ mbi->base.eob_mask = 0;
+ }
else
{
- memset(coeffs, 0, 25 * 16 * sizeof(short));
- eob_cnt = decode_mb_tokens(&tokens->bool,
- *left, *above,
- coeffs,
- eobs,
- mbi->base.y_mode,
- ctx->entropy_hdr.coeff_probs);
+ struct dequant_factors *dqf;
+
+ dqf = ctx->dequant_factors + mbi->base.segment_id;
+ mbi->base.eob_mask = decode_mb_tokens(&tokens->bool,
+ *left, *above,
+ coeffs,
+ mbi->base.y_mode,
+ ctx->entropy_hdr.coeff_probs,
+ dqf->factor);
}
above++;