diff options
author | John Koleszar <jkoleszar@google.com> | 2010-06-30 11:23:04 -0400 |
---|---|---|
committer | John Koleszar <jkoleszar@google.com> | 2010-07-07 13:29:19 -0400 |
commit | 940599ff2c0716a76ff2a3f42d145475612c6374 (patch) | |
tree | d4d44007bee3f87b981e23fe4734efa0ad8cc144 | |
parent | 86262018ad8abf7e4a359fc334720545aadae8ea (diff) | |
download | libvpx-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.h | 38 | ||||
-rw-r--r-- | vp8/dixie/dixie.c | 83 | ||||
-rw-r--r-- | vp8/dixie/dixie.h | 22 | ||||
-rw-r--r-- | vp8/dixie/tokens.c | 41 |
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++; |