From c4ad3273c7af292df189a095a64b9139cbed5285 Mon Sep 17 00:00:00 2001 From: Dmitry Kovalev Date: Wed, 10 Jul 2013 12:29:43 -0700 Subject: [PATCH] Moving segmentation related vars into separate struct. Adding segmentation struct to vp9_seg_common.h. Struct members are from macroblockd and VP9Common structs. Moving segmentation related constants and enums to vp9_seg_common.h. Change-Id: I23fabc33f11a359249f5f80d161daf569d02ec03 --- vp9/common/vp9_blockd.h | 48 ++++------------- vp9/common/vp9_entropymode.c | 4 +- vp9/common/vp9_loopfilter.c | 6 +-- vp9/common/vp9_loopfilter.h | 2 + vp9/common/vp9_onyxc_int.h | 4 -- vp9/common/vp9_pred_common.h | 2 +- vp9/common/vp9_quant_common.c | 6 +-- vp9/common/vp9_seg_common.c | 35 +++++++------ vp9/common/vp9_seg_common.h | 51 +++++++++++++++---- vp9/decoder/vp9_decodemv.c | 40 ++++++++------- vp9/decoder/vp9_decodframe.c | 48 +++++++++-------- vp9/decoder/vp9_detokenize.c | 6 +-- vp9/encoder/vp9_bitstream.c | 69 ++++++++++++------------- vp9/encoder/vp9_encodeframe.c | 36 +++++++------ vp9/encoder/vp9_onyx_if.c | 113 ++++++++++++++++++++--------------------- vp9/encoder/vp9_quantize.c | 2 +- vp9/encoder/vp9_ratectrl.c | 4 +- vp9/encoder/vp9_rdopt.c | 31 +++++------ vp9/encoder/vp9_segmentation.c | 32 ++++++------ vp9/encoder/vp9_tokenize.c | 10 ++-- 20 files changed, 271 insertions(+), 278 deletions(-) diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h index 385dcc1..e67250b 100644 --- a/vp9/common/vp9_blockd.h +++ b/vp9/common/vp9_blockd.h @@ -13,18 +13,19 @@ #define VP9_COMMON_VP9_BLOCKD_H_ #include "./vpx_config.h" + +#include "vpx_ports/mem.h" #include "vpx_scale/yv12config.h" + +#include "vp9/common/vp9_common.h" +#include "vp9/common/vp9_common_data.h" #include "vp9/common/vp9_convolve.h" +#include "vp9/common/vp9_enums.h" #include "vp9/common/vp9_mv.h" +#include "vp9/common/vp9_seg_common.h" #include "vp9/common/vp9_treecoder.h" -#include "vpx_ports/mem.h" -#include "vp9/common/vp9_common.h" -#include "vp9/common/vp9_enums.h" -#include "vp9/common/vp9_common_data.h" #define BLOCK_SIZE_GROUPS 4 -#define MAX_MB_SEGMENTS 8 -#define MB_SEG_TREE_PROBS (MAX_MB_SEGMENTS-1) #define PREDICTION_PROBS 3 @@ -34,8 +35,6 @@ #define MAX_MODE_LF_DELTAS 2 /* Segment Feature Masks */ -#define SEGMENT_DELTADATA 0 -#define SEGMENT_ABSDATA 1 #define MAX_MV_REF_CANDIDATES 2 #define INTRA_INTER_CONTEXTS 4 @@ -94,15 +93,6 @@ static INLINE int is_inter_mode(MB_PREDICTION_MODE mode) { // Segment level features. typedef enum { - SEG_LVL_ALT_Q = 0, // Use alternate Quantizer .... - SEG_LVL_ALT_LF = 1, // Use alternate loop filter value... - SEG_LVL_REF_FRAME = 2, // Optional Segment reference frame - SEG_LVL_SKIP = 3, // Optional Segment (0,0) + skip mode - SEG_LVL_MAX = 4 // Number of MB level features supported -} SEG_LVL_FEATURES; - -// Segment level features. -typedef enum { TX_4X4 = 0, // 4x4 dct transform TX_8X8 = 1, // 8x8 dct transform TX_16X16 = 2, // 16x16 dct transform @@ -253,32 +243,12 @@ typedef struct macroblockd { int left_available; int right_available; + struct segmentation seg; + // partition contexts PARTITION_CONTEXT *above_seg_context; PARTITION_CONTEXT *left_seg_context; - /* 0 (disable) 1 (enable) segmentation */ - unsigned char segmentation_enabled; - - /* 0 (do not update) 1 (update) the macroblock segmentation map. */ - unsigned char update_mb_segmentation_map; - - /* 0 (do not update) 1 (update) the macroblock segmentation feature data. */ - unsigned char update_mb_segmentation_data; - - /* 0 (do not update) 1 (update) the macroblock segmentation feature data. */ - unsigned char mb_segment_abs_delta; - - /* Per frame flags that define which MB level features (such as quantizer or loop filter level) */ - /* are enabled and when enabled the proabilities used to decode the per MB flags in MB_MODE_INFO */ - - // Probability Tree used to code Segment number - vp9_prob mb_segment_tree_probs[MB_SEG_TREE_PROBS]; - - // Segment features - int16_t segment_feature_data[MAX_MB_SEGMENTS][SEG_LVL_MAX]; - unsigned int segment_feature_mask[MAX_MB_SEGMENTS]; - /* mode_based Loop filter adjustment */ unsigned char mode_ref_lf_delta_enabled; unsigned char mode_ref_lf_delta_update; diff --git a/vp9/common/vp9_entropymode.c b/vp9/common/vp9_entropymode.c index 1cdf138..0b5f2ea 100644 --- a/vp9/common/vp9_entropymode.c +++ b/vp9/common/vp9_entropymode.c @@ -460,8 +460,8 @@ void vp9_setup_past_independence(VP9_COMMON *cm, MACROBLOCKD *xd) { // Reset the segment feature data to the default stats: // Features disabled, 0, with delta coding (Default state). int i; - vp9_clearall_segfeatures(xd); - xd->mb_segment_abs_delta = SEGMENT_DELTADATA; + vp9_clearall_segfeatures(&xd->seg); + xd->seg.abs_delta = SEGMENT_DELTADATA; if (cm->last_frame_seg_map) vpx_memset(cm->last_frame_seg_map, 0, (cm->mi_rows * cm->mi_cols)); diff --git a/vp9/common/vp9_loopfilter.c b/vp9/common/vp9_loopfilter.c index 6dc622a..37209a7 100644 --- a/vp9/common/vp9_loopfilter.c +++ b/vp9/common/vp9_loopfilter.c @@ -92,9 +92,9 @@ void vp9_loop_filter_frame_init(VP9_COMMON *cm, MACROBLOCKD *xd, int lvl_seg = default_filt_lvl, ref, mode, intra_lvl; // Set the baseline filter values for each segment - if (vp9_segfeature_active(xd, seg, SEG_LVL_ALT_LF)) { - const int data = vp9_get_segdata(xd, seg, SEG_LVL_ALT_LF); - lvl_seg = xd->mb_segment_abs_delta == SEGMENT_ABSDATA + if (vp9_segfeature_active(&xd->seg, seg, SEG_LVL_ALT_LF)) { + const int data = vp9_get_segdata(&xd->seg, seg, SEG_LVL_ALT_LF); + lvl_seg = xd->seg.abs_delta == SEGMENT_ABSDATA ? data : clamp(default_filt_lvl + data, 0, MAX_LOOP_FILTER); } diff --git a/vp9/common/vp9_loopfilter.h b/vp9/common/vp9_loopfilter.h index 2582979..52d3b2d 100644 --- a/vp9/common/vp9_loopfilter.h +++ b/vp9/common/vp9_loopfilter.h @@ -13,7 +13,9 @@ #include "vpx_ports/mem.h" #include "vpx_config.h" + #include "vp9/common/vp9_blockd.h" +#include "vp9/common/vp9_seg_common.h" #define MAX_LOOP_FILTER 63 #define MAX_SHARPNESS 7 diff --git a/vp9/common/vp9_onyxc_int.h b/vp9/common/vp9_onyxc_int.h index 7094e71..b7025ca 100644 --- a/vp9/common/vp9_onyxc_int.h +++ b/vp9/common/vp9_onyxc_int.h @@ -247,10 +247,6 @@ typedef struct VP9Common { [VP9_INTRA_MODES - 1]; vp9_prob kf_uv_mode_prob[VP9_INTRA_MODES] [VP9_INTRA_MODES - 1]; - // Context probabilities when using predictive coding of segment id - vp9_prob segment_pred_probs[PREDICTION_PROBS]; - unsigned char temporal_update; - // Context probabilities for reference frame prediction int allow_comp_inter_inter; MV_REFERENCE_FRAME comp_fixed_ref; diff --git a/vp9/common/vp9_pred_common.h b/vp9/common/vp9_pred_common.h index 3ec1ff7..21a7d80 100644 --- a/vp9/common/vp9_pred_common.h +++ b/vp9/common/vp9_pred_common.h @@ -32,7 +32,7 @@ static INLINE unsigned char vp9_get_pred_context_seg_id(const VP9_COMMON *cm, static INLINE vp9_prob vp9_get_pred_prob_seg_id(const VP9_COMMON *cm, const MACROBLOCKD *xd) { const int pred_context = vp9_get_pred_context_seg_id(cm, xd); - return cm->segment_pred_probs[pred_context]; + return xd->seg.pred_probs[pred_context]; } static INLINE unsigned char vp9_get_pred_flag_seg_id( const MACROBLOCKD * const xd) { diff --git a/vp9/common/vp9_quant_common.c b/vp9/common/vp9_quant_common.c index 295c8e7..2b81c2e 100644 --- a/vp9/common/vp9_quant_common.c +++ b/vp9/common/vp9_quant_common.c @@ -57,9 +57,9 @@ int16_t vp9_ac_quant(int qindex, int delta) { int vp9_get_qindex(MACROBLOCKD *xd, int segment_id, int base_qindex) { - if (vp9_segfeature_active(xd, segment_id, SEG_LVL_ALT_Q)) { - const int data = vp9_get_segdata(xd, segment_id, SEG_LVL_ALT_Q); - return xd->mb_segment_abs_delta == SEGMENT_ABSDATA ? + if (vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_ALT_Q)) { + const int data = vp9_get_segdata(&xd->seg, segment_id, SEG_LVL_ALT_Q); + return xd->seg.abs_delta == SEGMENT_ABSDATA ? data : // Abs value clamp(base_qindex + data, 0, MAXQ); // Delta value } else { diff --git a/vp9/common/vp9_seg_common.c b/vp9/common/vp9_seg_common.c index 9bf2072..9b13b5b 100644 --- a/vp9/common/vp9_seg_common.c +++ b/vp9/common/vp9_seg_common.c @@ -9,8 +9,11 @@ */ #include + #include "vp9/common/vp9_blockd.h" +#include "vp9/common/vp9_loopfilter.h" #include "vp9/common/vp9_seg_common.h" +#include "vp9/common/vp9_quant_common.h" static const int seg_feature_data_signed[SEG_LVL_MAX] = { 1, 1, 0, 0 }; @@ -22,25 +25,25 @@ static const int seg_feature_data_max[SEG_LVL_MAX] = { // the coding mechanism is still subject to change so these provide a // convenient single point of change. -int vp9_segfeature_active(const MACROBLOCKD *xd, int segment_id, +int vp9_segfeature_active(const struct segmentation *seg, int segment_id, SEG_LVL_FEATURES feature_id) { - return xd->segmentation_enabled && - (xd->segment_feature_mask[segment_id] & (1 << feature_id)); + return seg->enabled && + (seg->feature_mask[segment_id] & (1 << feature_id)); } -void vp9_clearall_segfeatures(MACROBLOCKD *xd) { - vpx_memset(xd->segment_feature_data, 0, sizeof(xd->segment_feature_data)); - vpx_memset(xd->segment_feature_mask, 0, sizeof(xd->segment_feature_mask)); +void vp9_clearall_segfeatures(struct segmentation *seg) { + vpx_memset(seg->feature_data, 0, sizeof(seg->feature_data)); + vpx_memset(seg->feature_mask, 0, sizeof(seg->feature_mask)); } -void vp9_enable_segfeature(MACROBLOCKD *xd, int segment_id, +void vp9_enable_segfeature(struct segmentation *seg, int segment_id, SEG_LVL_FEATURES feature_id) { - xd->segment_feature_mask[segment_id] |= 1 << feature_id; + seg->feature_mask[segment_id] |= 1 << feature_id; } -void vp9_disable_segfeature(MACROBLOCKD *xd, int segment_id, +void vp9_disable_segfeature(struct segmentation *seg, int segment_id, SEG_LVL_FEATURES feature_id) { - xd->segment_feature_mask[segment_id] &= ~(1 << feature_id); + seg->feature_mask[segment_id] &= ~(1 << feature_id); } int vp9_seg_feature_data_max(SEG_LVL_FEATURES feature_id) { @@ -51,12 +54,12 @@ int vp9_is_segfeature_signed(SEG_LVL_FEATURES feature_id) { return seg_feature_data_signed[feature_id]; } -void vp9_clear_segdata(MACROBLOCKD *xd, int segment_id, +void vp9_clear_segdata(struct segmentation *seg, int segment_id, SEG_LVL_FEATURES feature_id) { - xd->segment_feature_data[segment_id][feature_id] = 0; + seg->feature_data[segment_id][feature_id] = 0; } -void vp9_set_segdata(MACROBLOCKD *xd, int segment_id, +void vp9_set_segdata(struct segmentation *seg, int segment_id, SEG_LVL_FEATURES feature_id, int seg_data) { assert(seg_data <= seg_feature_data_max[feature_id]); if (seg_data < 0) { @@ -64,12 +67,12 @@ void vp9_set_segdata(MACROBLOCKD *xd, int segment_id, assert(-seg_data <= seg_feature_data_max[feature_id]); } - xd->segment_feature_data[segment_id][feature_id] = seg_data; + seg->feature_data[segment_id][feature_id] = seg_data; } -int vp9_get_segdata(const MACROBLOCKD *xd, int segment_id, +int vp9_get_segdata(const struct segmentation *seg, int segment_id, SEG_LVL_FEATURES feature_id) { - return xd->segment_feature_data[segment_id][feature_id]; + return seg->feature_data[segment_id][feature_id]; } diff --git a/vp9/common/vp9_seg_common.h b/vp9/common/vp9_seg_common.h index 74ba03c..f072a51 100644 --- a/vp9/common/vp9_seg_common.h +++ b/vp9/common/vp9_seg_common.h @@ -8,23 +8,54 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "vp9/common/vp9_onyxc_int.h" -#include "vp9/common/vp9_blockd.h" - #ifndef VP9_COMMON_VP9_SEG_COMMON_H_ #define VP9_COMMON_VP9_SEG_COMMON_H_ -int vp9_segfeature_active(const MACROBLOCKD *xd, +#include "vp9/common/vp9_treecoder.h" + +#define SEGMENT_DELTADATA 0 +#define SEGMENT_ABSDATA 1 + +#define MAX_MB_SEGMENTS 8 +#define MB_SEG_TREE_PROBS (MAX_MB_SEGMENTS-1) + +#define PREDICTION_PROBS 3 + +// Segment level features. +typedef enum { + SEG_LVL_ALT_Q = 0, // Use alternate Quantizer .... + SEG_LVL_ALT_LF = 1, // Use alternate loop filter value... + SEG_LVL_REF_FRAME = 2, // Optional Segment reference frame + SEG_LVL_SKIP = 3, // Optional Segment (0,0) + skip mode + SEG_LVL_MAX = 4 // Number of MB level features supported +} SEG_LVL_FEATURES; + + +struct segmentation { + uint8_t enabled; + uint8_t update_map; + uint8_t update_data; + uint8_t abs_delta; + uint8_t temporal_update; + + vp9_prob tree_probs[MB_SEG_TREE_PROBS]; + vp9_prob pred_probs[PREDICTION_PROBS]; + + int16_t feature_data[MAX_MB_SEGMENTS][SEG_LVL_MAX]; + unsigned int feature_mask[MAX_MB_SEGMENTS]; +}; + +int vp9_segfeature_active(const struct segmentation *seg, int segment_id, SEG_LVL_FEATURES feature_id); -void vp9_clearall_segfeatures(MACROBLOCKD *xd); +void vp9_clearall_segfeatures(struct segmentation *seg); -void vp9_enable_segfeature(MACROBLOCKD *xd, +void vp9_enable_segfeature(struct segmentation *seg, int segment_id, SEG_LVL_FEATURES feature_id); -void vp9_disable_segfeature(MACROBLOCKD *xd, +void vp9_disable_segfeature(struct segmentation *seg, int segment_id, SEG_LVL_FEATURES feature_id); @@ -32,16 +63,16 @@ int vp9_seg_feature_data_max(SEG_LVL_FEATURES feature_id); int vp9_is_segfeature_signed(SEG_LVL_FEATURES feature_id); -void vp9_clear_segdata(MACROBLOCKD *xd, +void vp9_clear_segdata(struct segmentation *seg, int segment_id, SEG_LVL_FEATURES feature_id); -void vp9_set_segdata(MACROBLOCKD *xd, +void vp9_set_segdata(struct segmentation *seg, int segment_id, SEG_LVL_FEATURES feature_id, int seg_data); -int vp9_get_segdata(const MACROBLOCKD *xd, +int vp9_get_segdata(const struct segmentation *seg, int segment_id, SEG_LVL_FEATURES feature_id); diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c index 369505c..3fc62c3 100644 --- a/vp9/decoder/vp9_decodemv.c +++ b/vp9/decoder/vp9_decodemv.c @@ -44,8 +44,8 @@ static MB_PREDICTION_MODE read_inter_mode(vp9_reader *r, const vp9_prob *p) { return (MB_PREDICTION_MODE)treed_read(r, vp9_sb_mv_ref_tree, p); } -static int read_segment_id(vp9_reader *r, MACROBLOCKD *xd) { - return treed_read(r, vp9_segment_tree, xd->mb_segment_tree_probs); +static int read_segment_id(vp9_reader *r, const struct segmentation *seg) { + return treed_read(r, vp9_segment_tree, seg->tree_probs); } static TX_SIZE read_selected_txfm_size(VP9_COMMON *cm, MACROBLOCKD *xd, @@ -105,13 +105,13 @@ static void set_segment_id(VP9_COMMON *cm, BLOCK_SIZE_TYPE bsize, static int read_intra_segment_id(VP9D_COMP *pbi, int mi_row, int mi_col, vp9_reader *r) { - VP9_COMMON *const cm = &pbi->common; MACROBLOCKD *const xd = &pbi->mb; + struct segmentation *const seg = &xd->seg; const BLOCK_SIZE_TYPE bsize = xd->mode_info_context->mbmi.sb_type; - if (xd->segmentation_enabled && xd->update_mb_segmentation_map) { - const int segment_id = read_segment_id(r, xd); - set_segment_id(cm, bsize, mi_row, mi_col, segment_id); + if (seg->enabled && seg->update_map) { + const int segment_id = read_segment_id(r, seg); + set_segment_id(&pbi->common, bsize, mi_row, mi_col, segment_id); return segment_id; } else { return 0; @@ -121,7 +121,7 @@ static int read_intra_segment_id(VP9D_COMP *pbi, int mi_row, int mi_col, static uint8_t read_skip_coeff(VP9D_COMP *pbi, int segment_id, vp9_reader *r) { VP9_COMMON *const cm = &pbi->common; MACROBLOCKD *const xd = &pbi->mb; - int skip_coeff = vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP); + int skip_coeff = vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_SKIP); if (!skip_coeff) { const uint8_t ctx = vp9_get_pred_context_mbskip(cm, xd); skip_coeff = vp9_read(r, vp9_get_pred_prob_mbskip(cm, xd)); @@ -290,8 +290,8 @@ static void read_ref_frame(VP9D_COMP *pbi, vp9_reader *r, MACROBLOCKD *const xd = &pbi->mb; FRAME_CONTEXT *const fc = &cm->fc; - if (vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME)) { - ref_frame[0] = vp9_get_segdata(xd, segment_id, SEG_LVL_REF_FRAME); + if (vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_REF_FRAME)) { + ref_frame[0] = vp9_get_segdata(&xd->seg, segment_id, SEG_LVL_REF_FRAME); ref_frame[1] = NONE; } else { const int comp_ctx = vp9_get_pred_context_comp_inter_inter(cm, xd); @@ -366,26 +366,28 @@ static int read_inter_segment_id(VP9D_COMP *pbi, int mi_row, int mi_col, vp9_reader *r) { VP9_COMMON *const cm = &pbi->common; MACROBLOCKD *const xd = &pbi->mb; + struct segmentation *const seg = &xd->seg; const BLOCK_SIZE_TYPE bsize = xd->mode_info_context->mbmi.sb_type; int pred_segment_id; int segment_id; - if (!xd->segmentation_enabled) + if (!seg->enabled) return 0; // Default for disabled segmentation pred_segment_id = vp9_get_segment_id(cm, cm->last_frame_seg_map, - bsize, mi_row, mi_col); - if (!xd->update_mb_segmentation_map) + bsize, mi_row, mi_col); + if (!seg->update_map) return pred_segment_id; - if (cm->temporal_update) { + + if (seg->temporal_update) { const vp9_prob pred_prob = vp9_get_pred_prob_seg_id(cm, xd); const int pred_flag = vp9_read(r, pred_prob); vp9_set_pred_flag_seg_id(xd, bsize, pred_flag); segment_id = pred_flag ? pred_segment_id - : read_segment_id(r, xd); + : read_segment_id(r, seg); } else { - segment_id = read_segment_id(r, xd); + segment_id = read_segment_id(r, seg); } set_segment_id(cm, bsize, mi_row, mi_col, segment_id); return segment_id; @@ -455,14 +457,14 @@ static MV_REFERENCE_FRAME read_reference_frame(VP9D_COMP *pbi, int segment_id, MACROBLOCKD *const xd = &pbi->mb; MV_REFERENCE_FRAME ref; - if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME)) { + if (!vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_REF_FRAME)) { const int ctx = vp9_get_pred_context_intra_inter(cm, xd); ref = (MV_REFERENCE_FRAME) vp9_read(r, vp9_get_pred_prob_intra_inter(cm, xd)); cm->fc.intra_inter_count[ctx][ref != INTRA_FRAME]++; } else { - ref = (MV_REFERENCE_FRAME) - vp9_get_segdata(xd, segment_id, SEG_LVL_REF_FRAME) != INTRA_FRAME; + ref = (MV_REFERENCE_FRAME) vp9_get_segdata(&xd->seg, segment_id, + SEG_LVL_REF_FRAME) != INTRA_FRAME; } return ref; } @@ -515,7 +517,7 @@ static void read_inter_mode_info(VP9D_COMP *pbi, MODE_INFO *mi, mv_ref_p = cm->fc.inter_mode_probs[mbmi->mb_mode_context[ref0]]; - if (vp9_segfeature_active(xd, mbmi->segment_id, SEG_LVL_SKIP)) { + if (vp9_segfeature_active(&xd->seg, mbmi->segment_id, SEG_LVL_SKIP)) { mbmi->mode = ZEROMV; } else if (bsize >= BLOCK_SIZE_SB8X8) { mbmi->mode = read_inter_mode(r, mv_ref_p); diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c index 37bdad2..48be069 100644 --- a/vp9/decoder/vp9_decodframe.c +++ b/vp9/decoder/vp9_decodframe.c @@ -174,7 +174,7 @@ static int decode_tokens(VP9D_COMP *pbi, BLOCK_SIZE_TYPE bsize, vp9_reader *r) { vp9_reset_sb_tokens_context(xd, bsize); return -1; } else { - if (xd->segmentation_enabled) + if (xd->seg.enabled) mb_init_dequantizer(&pbi->common, xd); // TODO(dkovalev) if (!vp9_reader_has_error(r)) @@ -395,55 +395,53 @@ static void read_coef_probs(FRAME_CONTEXT *fc, TXFM_MODE txfm_mode, read_coef_probs_common(fc, TX_32X32, r); } -static void setup_segmentation(VP9D_COMP *pbi, struct vp9_read_bit_buffer *rb) { +static void setup_segmentation(struct segmentation *seg, + struct vp9_read_bit_buffer *rb) { int i, j; - VP9_COMMON *const cm = &pbi->common; - MACROBLOCKD *const xd = &pbi->mb; - - xd->update_mb_segmentation_map = 0; - xd->update_mb_segmentation_data = 0; + seg->update_map = 0; + seg->update_data = 0; - xd->segmentation_enabled = vp9_rb_read_bit(rb); - if (!xd->segmentation_enabled) + seg->enabled = vp9_rb_read_bit(rb); + if (!seg->enabled) return; // Segmentation map update - xd->update_mb_segmentation_map = vp9_rb_read_bit(rb); - if (xd->update_mb_segmentation_map) { + seg->update_map = vp9_rb_read_bit(rb); + if (seg->update_map) { for (i = 0; i < MB_SEG_TREE_PROBS; i++) - xd->mb_segment_tree_probs[i] = vp9_rb_read_bit(rb) ? - vp9_rb_read_literal(rb, 8) : MAX_PROB; + seg->tree_probs[i] = vp9_rb_read_bit(rb) ? vp9_rb_read_literal(rb, 8) + : MAX_PROB; - cm->temporal_update = vp9_rb_read_bit(rb); - if (cm->temporal_update) { + seg->temporal_update = vp9_rb_read_bit(rb); + if (seg->temporal_update) { for (i = 0; i < PREDICTION_PROBS; i++) - cm->segment_pred_probs[i] = vp9_rb_read_bit(rb) ? - vp9_rb_read_literal(rb, 8) : MAX_PROB; + seg->pred_probs[i] = vp9_rb_read_bit(rb) ? vp9_rb_read_literal(rb, 8) + : MAX_PROB; } else { for (i = 0; i < PREDICTION_PROBS; i++) - cm->segment_pred_probs[i] = MAX_PROB; + seg->pred_probs[i] = MAX_PROB; } } // Segmentation data update - xd->update_mb_segmentation_data = vp9_rb_read_bit(rb); - if (xd->update_mb_segmentation_data) { - xd->mb_segment_abs_delta = vp9_rb_read_bit(rb); + seg->update_data = vp9_rb_read_bit(rb); + if (seg->update_data) { + seg->abs_delta = vp9_rb_read_bit(rb); - vp9_clearall_segfeatures(xd); + vp9_clearall_segfeatures(seg); for (i = 0; i < MAX_MB_SEGMENTS; i++) { for (j = 0; j < SEG_LVL_MAX; j++) { int data = 0; const int feature_enabled = vp9_rb_read_bit(rb); if (feature_enabled) { - vp9_enable_segfeature(xd, i, j); + vp9_enable_segfeature(seg, i, j); data = decode_unsigned_max(rb, vp9_seg_feature_data_max(j)); if (vp9_is_segfeature_signed(j)) data = vp9_rb_read_bit(rb) ? -data : data; } - vp9_set_segdata(xd, i, j, data); + vp9_set_segdata(seg, i, j, data); } } } @@ -902,7 +900,7 @@ static size_t read_uncompressed_header(VP9D_COMP *pbi, setup_loopfilter(pbi, rb); setup_quantization(pbi, rb); - setup_segmentation(pbi, rb); + setup_segmentation(&pbi->mb.seg, rb); setup_tile_info(cm, rb); diff --git a/vp9/decoder/vp9_detokenize.c b/vp9/decoder/vp9_detokenize.c index 76889c4..3a4fae0 100644 --- a/vp9/decoder/vp9_detokenize.c +++ b/vp9/decoder/vp9_detokenize.c @@ -278,8 +278,8 @@ SKIP_START: return c; } -static int get_eob(MACROBLOCKD* const xd, int segment_id, int eob_max) { - return vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP) ? 0 : eob_max; +static int get_eob(struct segmentation *seg, int segment_id, int eob_max) { + return vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP) ? 0 : eob_max; } struct decode_block_args { @@ -300,7 +300,7 @@ static void decode_block(int plane, int block, struct macroblockd_plane* pd = &xd->plane[plane]; const int segment_id = xd->mode_info_context->mbmi.segment_id; const TX_SIZE ss_tx_size = ss_txfrm_size / 2; - const int seg_eob = get_eob(xd, segment_id, 16 << ss_txfrm_size); + const int seg_eob = get_eob(&xd->seg, segment_id, 16 << ss_txfrm_size); const int off = block >> ss_txfrm_size; const int mod = bw - ss_tx_size - pd->subsampling_x; const int aoff = (off & ((1 << mod) - 1)) << ss_tx_size; diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index 0b5cb89..099b0b3 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -216,7 +216,7 @@ static void write_selected_txfm_size(const VP9_COMP *cpi, TX_SIZE tx_size, static int write_skip_coeff(const VP9_COMP *cpi, int segment_id, MODE_INFO *m, vp9_writer *w) { const MACROBLOCKD *const xd = &cpi->mb.e_mbd; - if (vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)) { + if (vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_SKIP)) { return 1; } else { const int skip_coeff = m->mbmi.mb_skip_coeff; @@ -356,10 +356,10 @@ static void write_sb_mv_ref(vp9_writer *w, MB_PREDICTION_MODE m, } -static void write_segment_id(vp9_writer *w, const MACROBLOCKD *xd, +static void write_segment_id(vp9_writer *w, const struct segmentation *seg, int segment_id) { - if (xd->segmentation_enabled && xd->update_mb_segmentation_map) - treed_write(w, vp9_segment_tree, xd->mb_segment_tree_probs, segment_id, 3); + if (seg->enabled && seg->update_map) + treed_write(w, vp9_segment_tree, seg->tree_probs, segment_id, 3); } // This function encodes the reference frame @@ -369,7 +369,7 @@ static void encode_ref_frame(VP9_COMP *cpi, vp9_writer *bc) { MACROBLOCKD *const xd = &x->e_mbd; MB_MODE_INFO *mi = &xd->mode_info_context->mbmi; const int segment_id = mi->segment_id; - int seg_ref_active = vp9_segfeature_active(xd, segment_id, + int seg_ref_active = vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_REF_FRAME); // If segment level coding of this signal is disabled... // or the segment allows multiple reference frame options @@ -396,7 +396,7 @@ static void encode_ref_frame(VP9_COMP *cpi, vp9_writer *bc) { } } else { assert(mi->ref_frame[1] <= INTRA_FRAME); - assert(vp9_get_segdata(xd, segment_id, SEG_LVL_REF_FRAME) == + assert(vp9_get_segdata(&xd->seg, segment_id, SEG_LVL_REF_FRAME) == mi->ref_frame[0]); } @@ -410,6 +410,7 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m, const nmv_context *nmvc = &pc->fc.nmvc; MACROBLOCK *const x = &cpi->mb; MACROBLOCKD *const xd = &x->e_mbd; + struct segmentation *seg = &xd->seg; MB_MODE_INFO *const mi = &m->mbmi; const MV_REFERENCE_FRAME rf = mi->ref_frame[0]; const MB_PREDICTION_MODE mode = mi->mode; @@ -423,33 +424,27 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m, active_section = 9; #endif - if (cpi->mb.e_mbd.update_mb_segmentation_map) { - // Is temporal coding of the segment map enabled - if (pc->temporal_update) { + if (seg->update_map) { + if (seg->temporal_update) { unsigned char prediction_flag = vp9_get_pred_flag_seg_id(xd); vp9_prob pred_prob = vp9_get_pred_prob_seg_id(pc, xd); - - // Code the segment id prediction flag for this mb vp9_write(bc, prediction_flag, pred_prob); - - // If the mb segment id wasn't predicted code explicitly if (!prediction_flag) - write_segment_id(bc, xd, mi->segment_id); + write_segment_id(bc, seg, mi->segment_id); } else { - // Normal unpredicted coding - write_segment_id(bc, xd, mi->segment_id); + write_segment_id(bc, seg, mi->segment_id); } } skip_coeff = write_skip_coeff(cpi, segment_id, m, bc); - if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME)) + if (!vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) vp9_write(bc, rf != INTRA_FRAME, vp9_get_pred_prob_intra_inter(pc, xd)); if (mi->sb_type >= BLOCK_SIZE_SB8X8 && pc->txfm_mode == TX_MODE_SELECT && !(rf != INTRA_FRAME && - (skip_coeff || vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)))) { + (skip_coeff || vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP)))) { write_selected_txfm_size(cpi, mi->txfm_size, mi->sb_type, bc); } @@ -484,7 +479,7 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m, #endif // If segment skip is not enabled code the mode. - if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)) { + if (!vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP)) { if (mi->sb_type >= BLOCK_SIZE_SB8X8) { write_sb_mv_ref(bc, mode, mv_ref_p); vp9_accum_mv_refs(&cpi->common, mode, mi->mb_mode_context[rf]); @@ -554,8 +549,8 @@ static void write_mb_modes_kf(const VP9_COMP *cpi, const int mis = c->mode_info_stride; const int segment_id = m->mbmi.segment_id; - if (xd->update_mb_segmentation_map) - write_segment_id(bc, xd, m->mbmi.segment_id); + if (xd->seg.update_map) + write_segment_id(bc, &xd->seg, m->mbmi.segment_id); write_skip_coeff(cpi, segment_id, m, bc); @@ -1002,23 +997,23 @@ static void encode_quantization(VP9_COMMON *cm, static void encode_segmentation(VP9_COMP *cpi, - struct vp9_write_bit_buffer *wb) { + struct vp9_write_bit_buffer *wb) { int i, j; - VP9_COMMON *const cm = &cpi->common; - MACROBLOCKD *const xd = &cpi->mb.e_mbd; - vp9_wb_write_bit(wb, xd->segmentation_enabled); - if (!xd->segmentation_enabled) + struct segmentation *seg = &cpi->mb.e_mbd.seg; + + vp9_wb_write_bit(wb, seg->enabled); + if (!seg->enabled) return; // Segmentation map - vp9_wb_write_bit(wb, xd->update_mb_segmentation_map); - if (xd->update_mb_segmentation_map) { + vp9_wb_write_bit(wb, seg->update_map); + if (seg->update_map) { // Select the coding strategy (temporal or spatial) vp9_choose_segmap_coding_method(cpi); // Write out probabilities used to decode unpredicted macro-block segments for (i = 0; i < MB_SEG_TREE_PROBS; i++) { - const int prob = xd->mb_segment_tree_probs[i]; + const int prob = seg->tree_probs[i]; const int update = prob != MAX_PROB; vp9_wb_write_bit(wb, update); if (update) @@ -1026,10 +1021,10 @@ static void encode_segmentation(VP9_COMP *cpi, } // Write out the chosen coding method. - vp9_wb_write_bit(wb, cm->temporal_update); - if (cm->temporal_update) { + vp9_wb_write_bit(wb, seg->temporal_update); + if (seg->temporal_update) { for (i = 0; i < PREDICTION_PROBS; i++) { - const int prob = cm->segment_pred_probs[i]; + const int prob = seg->pred_probs[i]; const int update = prob != MAX_PROB; vp9_wb_write_bit(wb, update); if (update) @@ -1039,16 +1034,16 @@ static void encode_segmentation(VP9_COMP *cpi, } // Segmentation data - vp9_wb_write_bit(wb, xd->update_mb_segmentation_data); - if (xd->update_mb_segmentation_data) { - vp9_wb_write_bit(wb, xd->mb_segment_abs_delta); + vp9_wb_write_bit(wb, seg->update_data); + if (seg->update_data) { + vp9_wb_write_bit(wb, seg->abs_delta); for (i = 0; i < MAX_MB_SEGMENTS; i++) { for (j = 0; j < SEG_LVL_MAX; j++) { - const int active = vp9_segfeature_active(xd, i, j); + const int active = vp9_segfeature_active(seg, i, j); vp9_wb_write_bit(wb, active); if (active) { - const int data = vp9_get_segdata(xd, i, j); + const int data = vp9_get_segdata(seg, i, j); const int data_max = vp9_seg_feature_data_max(j); if (vp9_is_segfeature_signed(j)) { diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index 2c31edc..a3e116b 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -360,7 +360,7 @@ static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx, if (!output_enabled) return; - if (!vp9_segfeature_active(xd, mbmi->segment_id, SEG_LVL_SKIP)) { + if (!vp9_segfeature_active(&xd->seg, mbmi->segment_id, SEG_LVL_SKIP)) { for (i = 0; i < NB_TXFM_MODES; i++) { cpi->rd_tx_select_diff[i] += ctx->txfm_rd_diff[i]; } @@ -512,16 +512,16 @@ static void set_offsets(VP9_COMP *cpi, int mi_row, int mi_col, x->rdmult = cpi->RDMULT; /* segment ID */ - if (xd->segmentation_enabled) { - uint8_t *map = xd->update_mb_segmentation_map ? cpi->segmentation_map - : cm->last_frame_seg_map; + if (xd->seg.enabled) { + uint8_t *map = xd->seg.update_map ? cpi->segmentation_map + : cm->last_frame_seg_map; mbmi->segment_id = vp9_get_segment_id(cm, map, bsize, mi_row, mi_col); vp9_mb_init_quantizer(cpi, x); - if (xd->segmentation_enabled && cpi->seg0_cnt > 0 - && !vp9_segfeature_active(xd, 0, SEG_LVL_REF_FRAME) - && vp9_segfeature_active(xd, 1, SEG_LVL_REF_FRAME)) { + if (xd->seg.enabled && cpi->seg0_cnt > 0 + && !vp9_segfeature_active(&xd->seg, 0, SEG_LVL_REF_FRAME) + && vp9_segfeature_active(&xd->seg, 1, SEG_LVL_REF_FRAME)) { cpi->seg0_progress = (cpi->seg0_idx << 16) / cpi->seg0_cnt; } else { const int y = mb_row & ~3; @@ -575,10 +575,8 @@ static void update_stats(VP9_COMP *cpi, int mi_row, int mi_col) { MB_MODE_INFO * const mbmi = &mi->mbmi; if (cm->frame_type != KEY_FRAME) { - int segment_id, seg_ref_active; - - segment_id = mbmi->segment_id; - seg_ref_active = vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME); + const int seg_ref_active = vp9_segfeature_active(&xd->seg, mbmi->segment_id, + SEG_LVL_REF_FRAME); if (!seg_ref_active) cpi->intra_inter_count[vp9_get_pred_context_intra_inter(cm, xd)][mbmi @@ -1885,7 +1883,7 @@ static int check_dual_ref_flags(VP9_COMP *cpi) { MACROBLOCKD *xd = &cpi->mb.e_mbd; int ref_flags = cpi->ref_frame_flags; - if (vp9_segfeature_active(xd, 1, SEG_LVL_REF_FRAME)) { + if (vp9_segfeature_active(&xd->seg, 1, SEG_LVL_REF_FRAME)) { return 0; } else { return (!!(ref_flags & VP9_GOLD_FLAG) + !!(ref_flags & VP9_LAST_FLAG) @@ -1932,9 +1930,8 @@ static void reset_skip_txfm_size_b(VP9_COMP *cpi, MODE_INFO *mi, int mis, const int xmbs = MIN(bw, cm->mi_cols - mi_col); xd->mode_info_context = mi; - assert( - vp9_segfeature_active(xd, mbmi->segment_id, SEG_LVL_SKIP) || - get_skip_flag(mi, mis, ymbs, xmbs)); + assert(vp9_segfeature_active(&xd->seg, mbmi->segment_id, SEG_LVL_SKIP) || + get_skip_flag(mi, mis, ymbs, xmbs)); set_txfm_flag(mi, mis, ymbs, xmbs, txfm_max); } } @@ -2370,10 +2367,11 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled, vp9_set_pred_flag_mbskip(xd, bsize, mi->mbmi.mb_skip_coeff); if (output_enabled) { - if (cm->txfm_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_SIZE_SB8X8 - && !(mbmi->ref_frame[0] != INTRA_FRAME - && (mbmi->mb_skip_coeff - || vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)))) { + if (cm->txfm_mode == TX_MODE_SELECT && + mbmi->sb_type >= BLOCK_SIZE_SB8X8 && + !(mbmi->ref_frame[0] != INTRA_FRAME && + (mbmi->mb_skip_coeff || + vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_SKIP)))) { const int context = vp9_get_pred_context_tx_size(cm, xd); if (bsize >= BLOCK_SIZE_SB32X32) { cm->fc.tx_count_32x32p[context][mbmi->txfm_size]++; diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index 67d0c4c..486686a 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -219,13 +219,13 @@ static void setup_features(VP9_COMP *cpi) { MACROBLOCKD *xd = &cpi->mb.e_mbd; // Set up default state for MB feature flags - xd->segmentation_enabled = 0; + xd->seg.enabled = 0; - xd->update_mb_segmentation_map = 0; - xd->update_mb_segmentation_data = 0; - vpx_memset(xd->mb_segment_tree_probs, 255, sizeof(xd->mb_segment_tree_probs)); + xd->seg.update_map = 0; + xd->seg.update_data = 0; + vpx_memset(xd->seg.tree_probs, 255, sizeof(xd->seg.tree_probs)); - vp9_clearall_segfeatures(xd); + vp9_clearall_segfeatures(&xd->seg); xd->mode_ref_lf_delta_enabled = 0; xd->mode_ref_lf_delta_update = 0; @@ -305,26 +305,26 @@ static void configure_static_seg_features(VP9_COMP *cpi) { if (cm->frame_type == KEY_FRAME) { // Clear down the global segmentation map vpx_memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols); - xd->update_mb_segmentation_map = 0; - xd->update_mb_segmentation_data = 0; + xd->seg.update_map = 0; + xd->seg.update_data = 0; cpi->static_mb_pct = 0; // Disable segmentation vp9_disable_segmentation((VP9_PTR)cpi); // Clear down the segment features. - vp9_clearall_segfeatures(xd); + vp9_clearall_segfeatures(&xd->seg); } else if (cpi->refresh_alt_ref_frame) { // If this is an alt ref frame // Clear down the global segmentation map vpx_memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols); - xd->update_mb_segmentation_map = 0; - xd->update_mb_segmentation_data = 0; + xd->seg.update_map = 0; + xd->seg.update_data = 0; cpi->static_mb_pct = 0; // Disable segmentation and individual segment features by default vp9_disable_segmentation((VP9_PTR)cpi); - vp9_clearall_segfeatures(xd); + vp9_clearall_segfeatures(&xd->seg); // Scan frames from current to arf frame. // This function re-enables segmentation if appropriate. @@ -332,45 +332,45 @@ static void configure_static_seg_features(VP9_COMP *cpi) { // If segmentation was enabled set those features needed for the // arf itself. - if (xd->segmentation_enabled) { - xd->update_mb_segmentation_map = 1; - xd->update_mb_segmentation_data = 1; + if (xd->seg.enabled) { + xd->seg.update_map = 1; + xd->seg.update_data = 1; qi_delta = compute_qdelta(cpi, cpi->avg_q, (cpi->avg_q * 0.875)); - vp9_set_segdata(xd, 1, SEG_LVL_ALT_Q, (qi_delta - 2)); - vp9_set_segdata(xd, 1, SEG_LVL_ALT_LF, -2); + vp9_set_segdata(&xd->seg, 1, SEG_LVL_ALT_Q, (qi_delta - 2)); + vp9_set_segdata(&xd->seg, 1, SEG_LVL_ALT_LF, -2); - vp9_enable_segfeature(xd, 1, SEG_LVL_ALT_Q); - vp9_enable_segfeature(xd, 1, SEG_LVL_ALT_LF); + vp9_enable_segfeature(&xd->seg, 1, SEG_LVL_ALT_Q); + vp9_enable_segfeature(&xd->seg, 1, SEG_LVL_ALT_LF); // Where relevant assume segment data is delta data - xd->mb_segment_abs_delta = SEGMENT_DELTADATA; + xd->seg.abs_delta = SEGMENT_DELTADATA; } - } else if (xd->segmentation_enabled) { + } else if (xd->seg.enabled) { // All other frames if segmentation has been enabled // First normal frame in a valid gf or alt ref group if (cpi->common.frames_since_golden == 0) { // Set up segment features for normal frames in an arf group if (cpi->source_alt_ref_active) { - xd->update_mb_segmentation_map = 0; - xd->update_mb_segmentation_data = 1; - xd->mb_segment_abs_delta = SEGMENT_DELTADATA; + xd->seg.update_map = 0; + xd->seg.update_data = 1; + xd->seg.abs_delta = SEGMENT_DELTADATA; qi_delta = compute_qdelta(cpi, cpi->avg_q, (cpi->avg_q * 1.125)); - vp9_set_segdata(xd, 1, SEG_LVL_ALT_Q, (qi_delta + 2)); - vp9_enable_segfeature(xd, 1, SEG_LVL_ALT_Q); + vp9_set_segdata(&xd->seg, 1, SEG_LVL_ALT_Q, (qi_delta + 2)); + vp9_enable_segfeature(&xd->seg, 1, SEG_LVL_ALT_Q); - vp9_set_segdata(xd, 1, SEG_LVL_ALT_LF, -2); - vp9_enable_segfeature(xd, 1, SEG_LVL_ALT_LF); + vp9_set_segdata(&xd->seg, 1, SEG_LVL_ALT_LF, -2); + vp9_enable_segfeature(&xd->seg, 1, SEG_LVL_ALT_LF); // Segment coding disabled for compred testing if (high_q || (cpi->static_mb_pct == 100)) { - vp9_set_segdata(xd, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME); - vp9_enable_segfeature(xd, 1, SEG_LVL_REF_FRAME); - vp9_enable_segfeature(xd, 1, SEG_LVL_SKIP); + vp9_set_segdata(&xd->seg, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME); + vp9_enable_segfeature(&xd->seg, 1, SEG_LVL_REF_FRAME); + vp9_enable_segfeature(&xd->seg, 1, SEG_LVL_SKIP); } } else { // Disable segmentation and clear down features if alt ref @@ -380,10 +380,10 @@ static void configure_static_seg_features(VP9_COMP *cpi) { vpx_memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols); - xd->update_mb_segmentation_map = 0; - xd->update_mb_segmentation_data = 0; + xd->seg.update_map = 0; + xd->seg.update_data = 0; - vp9_clearall_segfeatures(xd); + vp9_clearall_segfeatures(&xd->seg); } } else if (cpi->is_src_frame_alt_ref) { // Special case where we are coding over the top of a previous @@ -391,28 +391,28 @@ static void configure_static_seg_features(VP9_COMP *cpi) { // Segment coding disabled for compred testing // Enable ref frame features for segment 0 as well - vp9_enable_segfeature(xd, 0, SEG_LVL_REF_FRAME); - vp9_enable_segfeature(xd, 1, SEG_LVL_REF_FRAME); + vp9_enable_segfeature(&xd->seg, 0, SEG_LVL_REF_FRAME); + vp9_enable_segfeature(&xd->seg, 1, SEG_LVL_REF_FRAME); // All mbs should use ALTREF_FRAME - vp9_clear_segdata(xd, 0, SEG_LVL_REF_FRAME); - vp9_set_segdata(xd, 0, SEG_LVL_REF_FRAME, ALTREF_FRAME); - vp9_clear_segdata(xd, 1, SEG_LVL_REF_FRAME); - vp9_set_segdata(xd, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME); + vp9_clear_segdata(&xd->seg, 0, SEG_LVL_REF_FRAME); + vp9_set_segdata(&xd->seg, 0, SEG_LVL_REF_FRAME, ALTREF_FRAME); + vp9_clear_segdata(&xd->seg, 1, SEG_LVL_REF_FRAME); + vp9_set_segdata(&xd->seg, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME); // Skip all MBs if high Q (0,0 mv and skip coeffs) if (high_q) { - vp9_enable_segfeature(xd, 0, SEG_LVL_SKIP); - vp9_enable_segfeature(xd, 1, SEG_LVL_SKIP); + vp9_enable_segfeature(&xd->seg, 0, SEG_LVL_SKIP); + vp9_enable_segfeature(&xd->seg, 1, SEG_LVL_SKIP); } // Enable data udpate - xd->update_mb_segmentation_data = 1; + xd->seg.update_data = 1; } else { // All other frames. // No updates.. leave things as they are. - xd->update_mb_segmentation_map = 0; - xd->update_mb_segmentation_data = 0; + xd->seg.update_map = 0; + xd->seg.update_data = 0; } } } @@ -2567,9 +2567,9 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, setup_features(cpi); // If segmentation is enabled force a map update for key frames - if (xd->segmentation_enabled) { - xd->update_mb_segmentation_map = 1; - xd->update_mb_segmentation_data = 1; + if (xd->seg.enabled) { + xd->seg.update_map = 1; + xd->seg.update_data = 1; } // The alternate reference frame cannot be active for a key frame @@ -3100,9 +3100,8 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, cpi->dummy_packing = 0; vp9_pack_bitstream(cpi, dest, size); - if (xd->update_mb_segmentation_map) { + if (xd->seg.update_map) update_reference_segmentation_map(cpi); - } release_scaled_references(cpi); update_reference_frames(cpi); @@ -3408,8 +3407,8 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, } // Clear the one shot update flags for segmentation map and mode/ref loop filter deltas. - xd->update_mb_segmentation_map = 0; - xd->update_mb_segmentation_data = 0; + xd->seg.update_map = 0; + xd->seg.update_data = 0; xd->mode_ref_lf_delta_update = 0; // keep track of the last coded dimensions @@ -3521,8 +3520,8 @@ static int frame_is_reference(const VP9_COMP *cpi) { cpi->refresh_alt_ref_frame || cm->refresh_frame_context || mb->mode_ref_lf_delta_update || - mb->update_mb_segmentation_map || - mb->update_mb_segmentation_data; + mb->seg.update_map || + mb->seg.update_data; } #if CONFIG_MULTIPLE_ARF @@ -3978,14 +3977,14 @@ int vp9_set_roimap(VP9_PTR comp, unsigned char *map, unsigned int rows, // Enable the loop and quant changes in the feature mask for (i = 0; i < MAX_MB_SEGMENTS; i++) { if (delta_q[i]) - vp9_enable_segfeature(xd, i, SEG_LVL_ALT_Q); + vp9_enable_segfeature(&xd->seg, i, SEG_LVL_ALT_Q); else - vp9_disable_segfeature(xd, i, SEG_LVL_ALT_Q); + vp9_disable_segfeature(&xd->seg, i, SEG_LVL_ALT_Q); if (delta_lf[i]) - vp9_enable_segfeature(xd, i, SEG_LVL_ALT_LF); + vp9_enable_segfeature(&xd->seg, i, SEG_LVL_ALT_LF); else - vp9_disable_segfeature(xd, i, SEG_LVL_ALT_LF); + vp9_disable_segfeature(&xd->seg, i, SEG_LVL_ALT_LF); } // Initialise the feature data structure diff --git a/vp9/encoder/vp9_quantize.c b/vp9/encoder/vp9_quantize.c index 862923f..2d3d6bf 100644 --- a/vp9/encoder/vp9_quantize.c +++ b/vp9/encoder/vp9_quantize.c @@ -365,7 +365,7 @@ void vp9_mb_init_quantizer(VP9_COMP *cpi, MACROBLOCK *x) { x->e_mbd.plane[3].dequant = cpi->common.a_dequant[qindex]; #endif - x->skip_block = vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP); + x->skip_block = vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_SKIP); /* save this macroblock QIndex for vp9_update_zbin_extra() */ x->e_mbd.q_index = qindex; diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index 93f8bb5..7339328 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -127,7 +127,7 @@ void vp9_save_coding_context(VP9_COMP *cpi) { vp9_copy(cc->uv_mode_prob, cm->fc.uv_mode_prob); vp9_copy(cc->partition_prob, cm->fc.partition_prob); - vp9_copy(cc->segment_pred_probs, cm->segment_pred_probs); + vp9_copy(cc->segment_pred_probs, xd->seg.pred_probs); vp9_copy(cc->intra_inter_prob, cm->fc.intra_inter_prob); vp9_copy(cc->comp_inter_prob, cm->fc.comp_inter_prob); @@ -167,7 +167,7 @@ void vp9_restore_coding_context(VP9_COMP *cpi) { vp9_copy(cm->fc.uv_mode_prob, cc->uv_mode_prob); vp9_copy(cm->fc.partition_prob, cc->partition_prob); - vp9_copy(cm->segment_pred_probs, cc->segment_pred_probs); + vp9_copy(xd->seg.pred_probs, cc->segment_pred_probs); vp9_copy(cm->fc.intra_inter_prob, cc->intra_inter_prob); vp9_copy(cm->fc.comp_inter_prob, cc->comp_inter_prob); diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index f424679..6bac9f5 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -644,7 +644,7 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb, pt = combine_entropy_contexts(above_ec, left_ec); nb = vp9_get_coef_neighbors_handle(scan); - if (vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)) + if (vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_SKIP)) seg_eob = 0; /* sanity check to ensure that we do not have spurious non-zero q values */ @@ -1564,7 +1564,7 @@ static int cost_mv_ref(VP9_COMP *cpi, int segment_id = xd->mode_info_context->mbmi.segment_id; // Dont account for mode here if segment skip is enabled. - if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)) { + if (!vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_SKIP)) { assert(NEARESTMV <= m && m <= NEWMV); return x->inter_mode_cost[mode_context][m - NEARESTMV]; } else @@ -2172,7 +2172,7 @@ static void estimate_ref_frame_costs(VP9_COMP *cpi, int segment_id, vp9_prob *comp_mode_p) { VP9_COMMON *const cm = &cpi->common; MACROBLOCKD *const xd = &cpi->mb.e_mbd; - int seg_ref_active = vp9_segfeature_active(xd, segment_id, + int seg_ref_active = vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_REF_FRAME); if (seg_ref_active) { vpx_memset(ref_costs_single, 0, MAX_REF_FRAMES * sizeof(*ref_costs_single)); @@ -3189,7 +3189,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, // Do not allow compound prediction if the segment level reference // frame feature is in use as in this case there can only be one reference. if ((vp9_mode_order[mode_index].second_ref_frame > INTRA_FRAME) && - vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME)) + vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_REF_FRAME)) continue; x->skip = 0; @@ -3271,9 +3271,9 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, set_scale_factors(xd, mbmi->ref_frame[0], mbmi->ref_frame[1], scale_factor); - mode_excluded = - mode_excluded ? - mode_excluded : cm->comp_pred_mode == SINGLE_PREDICTION_ONLY; + mode_excluded = mode_excluded + ? mode_excluded + : cm->comp_pred_mode == SINGLE_PREDICTION_ONLY; } else { // mbmi->ref_frame[1] = vp9_mode_order[mode_index].ref_frame[1]; if (ref_frame != INTRA_FRAME) { @@ -3293,18 +3293,20 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, // If the segment reference frame feature is enabled.... // then do nothing if the current ref frame is not allowed.. - if (vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME) && - vp9_get_segdata(xd, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) { + if (vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_REF_FRAME) && + vp9_get_segdata(&xd->seg, segment_id, SEG_LVL_REF_FRAME) != + (int)ref_frame) { continue; // If the segment skip feature is enabled.... // then do nothing if the current mode is not allowed.. - } else if (vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP) && + } else if (vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_SKIP) && (this_mode != ZEROMV && ref_frame != INTRA_FRAME)) { continue; // Disable this drop out case if the ref frame // segment level feature is enabled for this segment. This is to // prevent the possibility that we end up unable to pick any mode. - } else if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME)) { + } else if (!vp9_segfeature_active(&xd->seg, segment_id, + SEG_LVL_REF_FRAME)) { // Only consider ZEROMV/ALTREF_FRAME for alt ref frame, // unless ARNR filtering is enabled in which case we want // an unfiltered alternative @@ -3579,10 +3581,9 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, // because there are no non zero coefficients and make any // necessary adjustment for rate. Ignore if skip is coded at // segment level as the cost wont have been added in. - int mb_skip_allowed; - // Is Mb level skip allowed (i.e. not coded at segment level). - mb_skip_allowed = !vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP); + const int mb_skip_allowed = !vp9_segfeature_active(&xd->seg, segment_id, + SEG_LVL_SKIP); if (skippable && bsize >= BLOCK_SIZE_SB8X8) { // Back out the coefficient coding costs @@ -3881,7 +3882,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, // This code forces Altref,0,0 and skip for the frame that overlays a // an alrtef unless Altref is filtered. However, this is unsafe if // segment level coding of ref frame is enabled for this segment. - if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME) && + if (!vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_REF_FRAME) && cpi->is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0) && (best_mbmode.mode != ZEROMV || best_mbmode.ref_frame[0] != ALTREF_FRAME) diff --git a/vp9/encoder/vp9_segmentation.c b/vp9/encoder/vp9_segmentation.c index fb2b23d..6a22df8 100644 --- a/vp9/encoder/vp9_segmentation.c +++ b/vp9/encoder/vp9_segmentation.c @@ -18,14 +18,14 @@ void vp9_enable_segmentation(VP9_PTR ptr) { VP9_COMP *cpi = (VP9_COMP *)ptr; - cpi->mb.e_mbd.segmentation_enabled = 1; - cpi->mb.e_mbd.update_mb_segmentation_map = 1; - cpi->mb.e_mbd.update_mb_segmentation_data = 1; + cpi->mb.e_mbd.seg.enabled = 1; + cpi->mb.e_mbd.seg.update_map = 1; + cpi->mb.e_mbd.seg.update_data = 1; } void vp9_disable_segmentation(VP9_PTR ptr) { VP9_COMP *cpi = (VP9_COMP *)ptr; - cpi->mb.e_mbd.segmentation_enabled = 0; + cpi->mb.e_mbd.seg.enabled = 0; } void vp9_set_segmentation_map(VP9_PTR ptr, @@ -37,8 +37,8 @@ void vp9_set_segmentation_map(VP9_PTR ptr, (cpi->common.mi_rows * cpi->common.mi_cols)); // Signal that the map should be updated. - cpi->mb.e_mbd.update_mb_segmentation_map = 1; - cpi->mb.e_mbd.update_mb_segmentation_data = 1; + cpi->mb.e_mbd.seg.update_map = 1; + cpi->mb.e_mbd.seg.update_data = 1; } void vp9_set_segment_data(VP9_PTR ptr, @@ -46,10 +46,10 @@ void vp9_set_segment_data(VP9_PTR ptr, unsigned char abs_delta) { VP9_COMP *cpi = (VP9_COMP *)(ptr); - cpi->mb.e_mbd.mb_segment_abs_delta = abs_delta; + cpi->mb.e_mbd.seg.abs_delta = abs_delta; - vpx_memcpy(cpi->mb.e_mbd.segment_feature_data, feature_data, - sizeof(cpi->mb.e_mbd.segment_feature_data)); + vpx_memcpy(cpi->mb.e_mbd.seg.feature_data, feature_data, + sizeof(cpi->mb.e_mbd.seg.feature_data)); // TBD ?? Set the feature mask // vpx_memcpy(cpi->mb.e_mbd.segment_feature_mask, 0, @@ -232,8 +232,8 @@ void vp9_choose_segmap_coding_method(VP9_COMP *cpi) { // Set default state for the segment tree probabilities and the // temporal coding probabilities - vpx_memset(xd->mb_segment_tree_probs, 255, sizeof(xd->mb_segment_tree_probs)); - vpx_memset(cm->segment_pred_probs, 255, sizeof(cm->segment_pred_probs)); + vpx_memset(xd->seg.tree_probs, 255, sizeof(xd->seg.tree_probs)); + vpx_memset(xd->seg.pred_probs, 255, sizeof(xd->seg.pred_probs)); vpx_memset(no_pred_segcounts, 0, sizeof(no_pred_segcounts)); vpx_memset(t_unpred_seg_counts, 0, sizeof(t_unpred_seg_counts)); @@ -283,11 +283,11 @@ void vp9_choose_segmap_coding_method(VP9_COMP *cpi) { // Now choose which coding method to use. if (t_pred_cost < no_pred_cost) { - cm->temporal_update = 1; - vpx_memcpy(xd->mb_segment_tree_probs, t_pred_tree, sizeof(t_pred_tree)); - vpx_memcpy(cm->segment_pred_probs, t_nopred_prob, sizeof(t_nopred_prob)); + xd->seg.temporal_update = 1; + vpx_memcpy(xd->seg.tree_probs, t_pred_tree, sizeof(t_pred_tree)); + vpx_memcpy(xd->seg.pred_probs, t_nopred_prob, sizeof(t_nopred_prob)); } else { - cm->temporal_update = 0; - vpx_memcpy(xd->mb_segment_tree_probs, no_pred_tree, sizeof(no_pred_tree)); + xd->seg.temporal_update = 0; + vpx_memcpy(xd->seg.tree_probs, no_pred_tree, sizeof(no_pred_tree)); } } diff --git a/vp9/encoder/vp9_tokenize.c b/vp9/encoder/vp9_tokenize.c index c16bdff..d526990 100644 --- a/vp9/encoder/vp9_tokenize.c +++ b/vp9/encoder/vp9_tokenize.c @@ -180,7 +180,7 @@ static void tokenize_b(int plane, int block, BLOCK_SIZE_TYPE bsize, pt = combine_entropy_contexts(above_ec, left_ec); nb = vp9_get_coef_neighbors_handle(scan); - if (vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)) + if (vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_SKIP)) seg_eob = 0; c = 0; @@ -274,12 +274,10 @@ void vp9_tokenize_sb(VP9_COMP *cpi, MB_MODE_INFO * const mbmi = &xd->mode_info_context->mbmi; TOKENEXTRA *t_backup = *t; const int mb_skip_context = vp9_get_pred_context_mbskip(cm, xd); - const int segment_id = mbmi->segment_id; - const int skip_inc = !vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP); + const int skip_inc = !vp9_segfeature_active(&xd->seg, mbmi->segment_id, + SEG_LVL_SKIP); const TX_SIZE txfm_size = mbmi->txfm_size; - struct tokenize_b_args arg = { - cpi, xd, t, txfm_size, dry_run - }; + struct tokenize_b_args arg = { cpi, xd, t, txfm_size, dry_run }; mbmi->mb_skip_coeff = vp9_sb_is_skippable(xd, bsize); -- 2.7.4