From 94675717773c347f9d4a7329365ff3ee1645950e Mon Sep 17 00:00:00 2001 From: Dmitry Kovalev Date: Tue, 25 Jun 2013 11:52:44 -0700 Subject: [PATCH] Moving subexp encoding functions in separate vp9_dsubexp.c file. Change-Id: Idbb2ea80f764fa830fe2ddcfc54ef7fe232f05a8 --- vp9/common/vp9_common.h | 12 ++++ vp9/decoder/vp9_decodemv.c | 53 ++++++-------- vp9/decoder/vp9_decodframe.c | 162 ++++++++++--------------------------------- vp9/decoder/vp9_decodframe.h | 1 - vp9/decoder/vp9_dsubexp.c | 85 +++++++++++++++++++++++ vp9/decoder/vp9_dsubexp.h | 19 +++++ vp9/encoder/vp9_bitstream.c | 10 --- vp9/vp9dx.mk | 2 + 8 files changed, 174 insertions(+), 170 deletions(-) create mode 100644 vp9/decoder/vp9_dsubexp.c create mode 100644 vp9/decoder/vp9_dsubexp.h diff --git a/vp9/common/vp9_common.h b/vp9/common/vp9_common.h index 0d7babf..9a14ab1 100644 --- a/vp9/common/vp9_common.h +++ b/vp9/common/vp9_common.h @@ -60,6 +60,18 @@ static INLINE int multiple8(int value) { return (value + 7) & ~7; } +static int get_unsigned_bits(unsigned int num_values) { + int cat = 0; + if (num_values <= 1) + return 0; + num_values--; + while (num_values > 0) { + cat++; + num_values >>= 1; + } + return cat; +} + #define SYNC_CODE_0 0x49 #define SYNC_CODE_1 0x83 #define SYNC_CODE_2 0x42 diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c index ac97e5c..9bb7724 100644 --- a/vp9/decoder/vp9_decodemv.c +++ b/vp9/decoder/vp9_decodemv.c @@ -21,8 +21,10 @@ #include "vp9/decoder/vp9_decodemv.h" #include "vp9/decoder/vp9_decodframe.h" #include "vp9/decoder/vp9_onyxd_int.h" +#include "vp9/decoder/vp9_dsubexp.h" #include "vp9/decoder/vp9_treereader.h" + #if CONFIG_DEBUG #include #endif @@ -313,8 +315,7 @@ static void read_switchable_interp_probs(FRAME_CONTEXT *fc, vp9_reader *r) { for (j = 0; j < VP9_SWITCHABLE_FILTERS + 1; ++j) for (i = 0; i < VP9_SWITCHABLE_FILTERS - 1; ++i) if (vp9_read(r, VP9_MODE_UPDATE_PROB)) - fc->switchable_interp_prob[j][i] = vp9_read_prob_diff_update(r, - fc->switchable_interp_prob[j][i]); + vp9_diff_update_prob(r, &fc->switchable_interp_prob[j][i]); } static void read_inter_mode_probs(FRAME_CONTEXT *fc, vp9_reader *r) { @@ -322,8 +323,7 @@ static void read_inter_mode_probs(FRAME_CONTEXT *fc, vp9_reader *r) { for (i = 0; i < INTER_MODE_CONTEXTS; ++i) for (j = 0; j < VP9_INTER_MODES - 1; ++j) if (vp9_read(r, VP9_MODE_UPDATE_PROB)) - fc->inter_mode_probs[i][j] = vp9_read_prob_diff_update(r, - fc->inter_mode_probs[i][j]); + vp9_diff_update_prob(r, &fc->inter_mode_probs[i][j]); } static INLINE COMPPREDMODE_TYPE read_comp_pred_mode(vp9_reader *r) { @@ -348,16 +348,14 @@ static void mb_mode_mv_init(VP9D_COMP *pbi, vp9_reader *r) { for (i = 0; i < INTRA_INTER_CONTEXTS; i++) if (vp9_read(r, VP9_MODE_UPDATE_PROB)) - cm->fc.intra_inter_prob[i] = - vp9_read_prob_diff_update(r, cm->fc.intra_inter_prob[i]); + vp9_diff_update_prob(r, &cm->fc.intra_inter_prob[i]); if (cm->allow_comp_inter_inter) { cm->comp_pred_mode = read_comp_pred_mode(r); if (cm->comp_pred_mode == HYBRID_PREDICTION) for (i = 0; i < COMP_INTER_CONTEXTS; i++) if (vp9_read(r, VP9_MODE_UPDATE_PROB)) - cm->fc.comp_inter_prob[i] = - vp9_read_prob_diff_update(r, cm->fc.comp_inter_prob[i]); + vp9_diff_update_prob(r, &cm->fc.comp_inter_prob[i]); } else { cm->comp_pred_mode = SINGLE_PREDICTION_ONLY; } @@ -365,37 +363,27 @@ static void mb_mode_mv_init(VP9D_COMP *pbi, vp9_reader *r) { if (cm->comp_pred_mode != COMP_PREDICTION_ONLY) for (i = 0; i < REF_CONTEXTS; i++) { if (vp9_read(r, VP9_MODE_UPDATE_PROB)) - cm->fc.single_ref_prob[i][0] = - vp9_read_prob_diff_update(r, cm->fc.single_ref_prob[i][0]); + vp9_diff_update_prob(r, &cm->fc.single_ref_prob[i][0]); + if (vp9_read(r, VP9_MODE_UPDATE_PROB)) - cm->fc.single_ref_prob[i][1] = - vp9_read_prob_diff_update(r, cm->fc.single_ref_prob[i][1]); + vp9_diff_update_prob(r, &cm->fc.single_ref_prob[i][1]); } if (cm->comp_pred_mode != SINGLE_PREDICTION_ONLY) for (i = 0; i < REF_CONTEXTS; i++) if (vp9_read(r, VP9_MODE_UPDATE_PROB)) - cm->fc.comp_ref_prob[i] = - vp9_read_prob_diff_update(r, cm->fc.comp_ref_prob[i]); + vp9_diff_update_prob(r, &cm->fc.comp_ref_prob[i]); // VP9_INTRA_MODES - for (j = 0; j < BLOCK_SIZE_GROUPS; j++) { - for (i = 0; i < VP9_INTRA_MODES - 1; ++i) { - if (vp9_read(r, VP9_MODE_UPDATE_PROB)) { - cm->fc.y_mode_prob[j][i] = - vp9_read_prob_diff_update(r, cm->fc.y_mode_prob[j][i]); - } - } - } - for (j = 0; j < NUM_PARTITION_CONTEXTS; ++j) { - for (i = 0; i < PARTITION_TYPES - 1; ++i) { - if (vp9_read(r, VP9_MODE_UPDATE_PROB)) { - cm->fc.partition_prob[INTER_FRAME][j][i] = - vp9_read_prob_diff_update(r, - cm->fc.partition_prob[INTER_FRAME][j][i]); - } - } - } + for (j = 0; j < BLOCK_SIZE_GROUPS; j++) + for (i = 0; i < VP9_INTRA_MODES - 1; ++i) + if (vp9_read(r, VP9_MODE_UPDATE_PROB)) + vp9_diff_update_prob(r, &cm->fc.y_mode_prob[j][i]); + + for (j = 0; j < NUM_PARTITION_CONTEXTS; ++j) + for (i = 0; i < PARTITION_TYPES - 1; ++i) + if (vp9_read(r, VP9_MODE_UPDATE_PROB)) + vp9_diff_update_prob(r, &cm->fc.partition_prob[INTER_FRAME][j][i]); read_nmvprobs(r, nmvc, xd->allow_high_precision_mv); } @@ -788,8 +776,7 @@ void vp9_decode_mode_mvs_init(VP9D_COMP* const pbi, vp9_reader *r) { // vpx_memset(cm->fc.mbskip_probs, 0, sizeof(cm->fc.mbskip_probs)); for (k = 0; k < MBSKIP_CONTEXTS; ++k) if (vp9_read(r, VP9_MODE_UPDATE_PROB)) - cm->fc.mbskip_probs[k] = - vp9_read_prob_diff_update(r, cm->fc.mbskip_probs[k]); + vp9_diff_update_prob(r, &cm->fc.mbskip_probs[k]); mb_mode_mv_init(pbi, r); } diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c index a87cfd3..73903ea 100644 --- a/vp9/decoder/vp9_decodframe.c +++ b/vp9/decoder/vp9_decodframe.c @@ -30,6 +30,7 @@ #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" @@ -49,6 +50,11 @@ static int read_is_valid(const uint8_t *start, size_t len, 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 void setup_txfm_mode(VP9_COMMON *pc, int lossless, vp9_reader *r) { if (lossless) { pc->txfm_mode = ONLY_4X4; @@ -56,133 +62,25 @@ static void setup_txfm_mode(VP9_COMMON *pc, int lossless, vp9_reader *r) { pc->txfm_mode = vp9_read_literal(r, 2); if (pc->txfm_mode == ALLOW_32X32) pc->txfm_mode += vp9_read_bit(r); + if (pc->txfm_mode == TX_MODE_SELECT) { int i, j; - for (i = 0; i < TX_SIZE_CONTEXTS; ++i) { - for (j = 0; j < TX_SIZE_MAX_SB - 3; ++j) { - if (vp9_read(r, VP9_MODE_UPDATE_PROB)) - pc->fc.tx_probs_8x8p[i][j] = - vp9_read_prob_diff_update(r, pc->fc.tx_probs_8x8p[i][j]); - } - } - for (i = 0; i < TX_SIZE_CONTEXTS; ++i) { - for (j = 0; j < TX_SIZE_MAX_SB - 2; ++j) { - if (vp9_read(r, VP9_MODE_UPDATE_PROB)) - pc->fc.tx_probs_16x16p[i][j] = - vp9_read_prob_diff_update(r, pc->fc.tx_probs_16x16p[i][j]); - } - } - for (i = 0; i < TX_SIZE_CONTEXTS; ++i) { - for (j = 0; j < TX_SIZE_MAX_SB - 1; ++j) { + for (i = 0; i < TX_SIZE_CONTEXTS; ++i) + for (j = 0; j < TX_SIZE_MAX_SB - 3; ++j) if (vp9_read(r, VP9_MODE_UPDATE_PROB)) - pc->fc.tx_probs_32x32p[i][j] = - vp9_read_prob_diff_update(r, pc->fc.tx_probs_32x32p[i][j]); - } - } - } - } -} - -static int get_unsigned_bits(unsigned int num_values) { - int cat = 0; - if (num_values <= 1) - return 0; - num_values--; - while (num_values > 0) { - cat++; - num_values >>= 1; - } - return cat; -} - -static int inv_recenter_nonneg(int v, int m) { - if (v > 2 * m) - return v; - - return v % 2 ? m - (v + 1) / 2 : m + v / 2; -} - -static int decode_uniform(vp9_reader *r, int n) { - int v; - const int l = get_unsigned_bits(n); - const int m = (1 << l) - n; - if (!l) - return 0; + vp9_diff_update_prob(r, &pc->fc.tx_probs_8x8p[i][j]); - v = vp9_read_literal(r, l - 1); - return v < m ? v : (v << 1) - m + vp9_read_bit(r); -} + for (i = 0; i < TX_SIZE_CONTEXTS; ++i) + for (j = 0; j < TX_SIZE_MAX_SB - 2; ++j) + if (vp9_read(r, VP9_MODE_UPDATE_PROB)) + vp9_diff_update_prob(r, &pc->fc.tx_probs_16x16p[i][j]); -static int decode_term_subexp(vp9_reader *r, int k, int num_syms) { - int i = 0, mk = 0, word; - while (1) { - const int b = i ? k + i - 1 : k; - const int a = 1 << b; - if (num_syms <= mk + 3 * a) { - word = decode_uniform(r, num_syms - mk) + mk; - break; - } else { - if (vp9_read_bit(r)) { - i++; - mk += a; - } else { - word = vp9_read_literal(r, b) + mk; - break; - } + for (i = 0; i < TX_SIZE_CONTEXTS; ++i) + for (j = 0; j < TX_SIZE_MAX_SB - 1; ++j) + if (vp9_read(r, VP9_MODE_UPDATE_PROB)) + vp9_diff_update_prob(r, &pc->fc.tx_probs_32x32p[i][j]); } } - return word; -} - -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 int merge_index(int v, int n, int modulus) { - int max1 = (n - 1 - modulus / 2) / modulus + 1; - if (v < max1) { - v = v * modulus + modulus / 2; - } else { - int w; - v -= max1; - w = v; - v += (v + modulus - modulus / 2) / modulus; - while (v % modulus == modulus / 2 || - w != v - (v + modulus - modulus / 2) / modulus) v++; - } - return v; -} - -static int inv_remap_prob(int v, int m) { - const int n = 255; - - v = merge_index(v, n - 1, MODULUS_PARAM); - m--; - if ((m << 1) <= n) { - return 1 + inv_recenter_nonneg(v + 1, m); - } else { - return n - inv_recenter_nonneg(v + 1, n - 1 - m); - } -} - -vp9_prob vp9_read_prob_diff_update(vp9_reader *r, int oldp) { - int delp = decode_term_subexp(r, SUBEXP_PARAM, 255); - return (vp9_prob)inv_remap_prob(delp, oldp); -} - -void vp9_init_dequantizer(VP9_COMMON *pc) { - int q; - - for (q = 0; q < QINDEX_RANGE; q++) { - // DC value - pc->y_dequant[q][0] = vp9_dc_quant(q, pc->y_dc_delta_q); - pc->uv_dequant[q][0] = vp9_dc_quant(q, pc->uv_dc_delta_q); - - // AC values - pc->y_dequant[q][1] = vp9_ac_quant(q, 0); - pc->uv_dequant[q][1] = vp9_ac_quant(q, pc->uv_ac_delta_q); - } } static void mb_init_dequantizer(VP9_COMMON *pc, MACROBLOCKD *xd) { @@ -540,7 +438,7 @@ static void read_coef_probs_common(FRAME_CONTEXT *fc, TX_SIZE tx_size, vp9_prob *const p = coef_probs[i][j][k][l] + m; if (vp9_read(r, VP9_COEF_UPDATE_PROB)) - *p = vp9_read_prob_diff_update(r, *p); + vp9_diff_update_prob(r, p); } } } @@ -678,11 +576,9 @@ static void setup_quantization(VP9D_COMP *pbi, struct vp9_read_bit_buffer *rb) { cm->y_dc_delta_q == 0 && cm->uv_dc_delta_q == 0 && cm->uv_ac_delta_q == 0; - if (xd->lossless) { - xd->itxm_add = vp9_idct_add_lossless_c; - } else { - xd->itxm_add = vp9_idct_add; - } + + xd->itxm_add = xd->lossless ? vp9_idct_add_lossless_c + : vp9_idct_add; } static INTERPOLATIONFILTERTYPE read_interp_filter_type( @@ -1088,6 +984,20 @@ static size_t read_uncompressed_header(VP9D_COMP *pbi, return vp9_rb_read_literal(rb, 16); } +void vp9_init_dequantizer(VP9_COMMON *pc) { + int q; + + for (q = 0; q < QINDEX_RANGE; q++) { + // DC value + pc->y_dequant[q][0] = vp9_dc_quant(q, pc->y_dc_delta_q); + pc->uv_dequant[q][0] = vp9_dc_quant(q, pc->uv_dc_delta_q); + + // AC values + pc->y_dequant[q][1] = vp9_ac_quant(q, 0); + pc->uv_dequant[q][1] = vp9_ac_quant(q, pc->uv_ac_delta_q); + } +} + int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) { int i; vp9_reader header_bc, residual_bc; diff --git a/vp9/decoder/vp9_decodframe.h b/vp9/decoder/vp9_decodframe.h index 66e951d..00b6d67 100644 --- a/vp9/decoder/vp9_decodframe.h +++ b/vp9/decoder/vp9_decodframe.h @@ -17,6 +17,5 @@ struct VP9Decompressor; void vp9_init_dequantizer(struct VP9Common *pc); int vp9_decode_frame(struct VP9Decompressor *cpi, const uint8_t **p_data_end); -vp9_prob vp9_read_prob_diff_update(vp9_reader *r, int oldp); #endif // VP9_DECODER_VP9_DECODFRAME_H_ diff --git a/vp9/decoder/vp9_dsubexp.c b/vp9/decoder/vp9_dsubexp.c new file mode 100644 index 0000000..0f204df --- /dev/null +++ b/vp9/decoder/vp9_dsubexp.c @@ -0,0 +1,85 @@ +/* + 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/common/vp9_entropy.h" + +#include "vp9/decoder/vp9_dsubexp.h" + +static int inv_recenter_nonneg(int v, int m) { + if (v > 2 * m) + return v; + + return v % 2 ? m - (v + 1) / 2 : m + v / 2; +} + +static int decode_uniform(vp9_reader *r, int n) { + int v; + const int l = get_unsigned_bits(n); + const int m = (1 << l) - n; + if (!l) + return 0; + + v = vp9_read_literal(r, l - 1); + return v < m ? v : (v << 1) - m + vp9_read_bit(r); +} + + +static int merge_index(int v, int n, int modulus) { + int max1 = (n - 1 - modulus / 2) / modulus + 1; + if (v < max1) { + v = v * modulus + modulus / 2; + } else { + int w; + v -= max1; + w = v; + v += (v + modulus - modulus / 2) / modulus; + while (v % modulus == modulus / 2 || + w != v - (v + modulus - modulus / 2) / modulus) v++; + } + return v; +} + +static int inv_remap_prob(int v, int m) { + const int n = 255; + + v = merge_index(v, n - 1, MODULUS_PARAM); + m--; + if ((m << 1) <= n) { + return 1 + inv_recenter_nonneg(v + 1, m); + } else { + return n - inv_recenter_nonneg(v + 1, n - 1 - m); + } +} + +static int decode_term_subexp(vp9_reader *r, int k, int num_syms) { + int i = 0, mk = 0, word; + while (1) { + const int b = i ? k + i - 1 : k; + const int a = 1 << b; + if (num_syms <= mk + 3 * a) { + word = decode_uniform(r, num_syms - mk) + mk; + break; + } else { + if (vp9_read_bit(r)) { + i++; + mk += a; + } else { + word = vp9_read_literal(r, b) + mk; + break; + } + } + } + return word; +} + +void vp9_diff_update_prob(vp9_reader *r, vp9_prob* p) { + int delp = decode_term_subexp(r, SUBEXP_PARAM, 255); + *p = (vp9_prob)inv_remap_prob(delp, *p); +} diff --git a/vp9/decoder/vp9_dsubexp.h b/vp9/decoder/vp9_dsubexp.h new file mode 100644 index 0000000..aeb9399 --- /dev/null +++ b/vp9/decoder/vp9_dsubexp.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2013 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. + */ + + +#ifndef VP9_DECODER_VP9_DSUBEXP_H_ +#define VP9_DECODER_VP9_DSUBEXP_H_ + +#include "vp9/decoder/vp9_dboolhuff.h" + +void vp9_diff_update_prob(vp9_reader *r, vp9_prob* p); + +#endif // VP9_DECODER_VP9_DSUBEXP_H_ diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index 09ab2db..5236a3b 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -175,16 +175,6 @@ int recenter_nonneg(int v, int m) { return ((m - v) << 1) - 1; } -static int get_unsigned_bits(unsigned num_values) { - int cat = 0; - if ((num_values--) <= 1) return 0; - while (num_values > 0) { - cat++; - num_values >>= 1; - } - return cat; -} - void vp9_encode_unsigned_max(struct vp9_write_bit_buffer *wb, int data, int max) { vp9_wb_write_literal(wb, data, get_unsigned_bits(max)); diff --git a/vp9/vp9dx.mk b/vp9/vp9dx.mk index 7ae3219..7ede9c2 100644 --- a/vp9/vp9dx.mk +++ b/vp9/vp9dx.mk @@ -33,6 +33,8 @@ VP9_DX_SRCS-yes += decoder/vp9_treereader.h VP9_DX_SRCS-yes += decoder/vp9_onyxd_if.c VP9_DX_SRCS-yes += decoder/vp9_idct_blk.c VP9_DX_SRCS-yes += decoder/vp9_idct_blk.h +VP9_DX_SRCS-yes += decoder/vp9_dsubexp.c +VP9_DX_SRCS-yes += decoder/vp9_dsubexp.h VP9_DX_SRCS-yes := $(filter-out $(VP9_DX_SRCS_REMOVE-yes),$(VP9_DX_SRCS-yes)) -- 2.7.4