From dfbc61f3ab8c20e3ac7ed94209ab62dfe080b53e Mon Sep 17 00:00:00 2001 From: Paul Wilkins Date: Tue, 13 Sep 2011 11:26:39 +0100 Subject: [PATCH] Segment Features: Some basic plumbing added for a range of segment level features. MB_LVL_* changed to SEG_LVL_* to better reflect meaning. Change-Id: Iac96da36990aa0e40afc0d86e990df337fd0c50b --- vp8/common/blockd.h | 27 +++++++++++------- vp8/common/entropy.c | 6 +++- vp8/common/entropy.h | 2 +- vp8/common/loopfilter.c | 8 +++--- vp8/decoder/decodframe.c | 6 ++-- vp8/encoder/bitstream.c | 4 +-- vp8/encoder/encodeframe.c | 2 +- vp8/encoder/onyx_if.c | 58 +++++++++++++++++++-------------------- vp8/encoder/onyx_int.h | 14 ++++++---- vp8/encoder/picklpf.c | 8 +++--- vp8/encoder/quantize.c | 12 ++++---- 11 files changed, 81 insertions(+), 66 deletions(-) diff --git a/vp8/common/blockd.h b/vp8/common/blockd.h index f66e73c59..873c67467 100644 --- a/vp8/common/blockd.h +++ b/vp8/common/blockd.h @@ -94,18 +94,23 @@ typedef enum MB_MODE_COUNT } MB_PREDICTION_MODE; -/* Macroblock level features */ +// Segment level features. typedef enum { - MB_LVL_ALT_Q = 0, /* Use alternate Quantizer .... */ - MB_LVL_ALT_LF = 1, /* Use alternate loop filter value... */ - MB_LVL_MAX = 2 /* Number of MB level features supported */ + SEG_LVL_ALT_Q = 0, // Use alternate Quantizer .... + SEG_LVL_ALT_LF = 1, // Use alternate loop filter value... +#if CONFIG_SEGFEATURES + SEG_LVL_REF_FRAME = 2, // Optional Segment reference frame + SEG_LVL_MODE = 3, // Optional Segment mode + SEG_LVL_EOB = 4, // EOB end stop marker. + SEG_LVL_TRANSFORM = 6, // Block transform size. + + SEG_LVL_MAX = 6 // Number of MB level features supported +#else + SEG_LVL_MAX = 2 // Number of MB level features supported +#endif -} MB_LVL_FEATURES; - -/* Segment Feature Masks */ -#define SEGMENT_ALTQ 0x01 -#define SEGMENT_ALT_LF 0x02 +} SEG_LVL_FEATURES; #define VP8_YMODES (B_PRED + 1) #define VP8_UV_MODES (TM_PRED + 1) @@ -246,7 +251,9 @@ typedef struct MacroBlockD #else vp8_prob mb_segment_tree_probs[MB_FEATURE_TREE_PROBS]; #endif - signed char segment_feature_data[MB_LVL_MAX][MAX_MB_SEGMENTS]; // Segment parameters + + // Segment features + signed char segment_feature_data[SEG_LVL_MAX][MAX_MB_SEGMENTS]; /* mode_based Loop filter adjustment */ unsigned char mode_ref_lf_delta_enabled; diff --git a/vp8/common/entropy.c b/vp8/common/entropy.c index 34b54b9a7..5fb64df36 100644 --- a/vp8/common/entropy.c +++ b/vp8/common/entropy.c @@ -92,7 +92,11 @@ DECLARE_ALIGNED(16, short, vp8_default_zig_zag_mask[16]); DECLARE_ALIGNED(64, short, vp8_default_zig_zag_mask_8x8[64]);//int64_t #endif -const int vp8_mb_feature_data_bits[MB_LVL_MAX] = {7, 6}; +#if CONFIG_SEGFEATURES +const int vp8_mb_feature_data_bits[SEG_LVL_MAX] = {7, 6, 2, 3, 4, 2}; +#else +const int vp8_mb_feature_data_bits[SEG_LVL_MAX] = {7, 6}; +#endif /* Array indices are identical to previously-existing CONTEXT_NODE indices */ diff --git a/vp8/common/entropy.h b/vp8/common/entropy.h index d3e841c3e..4d15449c9 100644 --- a/vp8/common/entropy.h +++ b/vp8/common/entropy.h @@ -106,7 +106,7 @@ extern short vp8_default_zig_zag_mask[16]; extern DECLARE_ALIGNED(64, const int, vp8_default_zig_zag1d_8x8[64]); extern short vp8_default_zig_zag_mask_8x8[64];//int64_t #endif -extern const int vp8_mb_feature_data_bits[MB_LVL_MAX]; +extern const int vp8_mb_feature_data_bits[SEG_LVL_MAX]; void vp8_coef_tree_initialize(void); #endif diff --git a/vp8/common/loopfilter.c b/vp8/common/loopfilter.c index fe0644bdd..b74521622 100644 --- a/vp8/common/loopfilter.c +++ b/vp8/common/loopfilter.c @@ -221,11 +221,11 @@ void vp8_loop_filter_frame_init(VP8_COMMON *cm, /* Abs value */ if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA) { - lvl_seg = mbd->segment_feature_data[MB_LVL_ALT_LF][seg]; + lvl_seg = mbd->segment_feature_data[SEG_LVL_ALT_LF][seg]; } else /* Delta Value */ { - lvl_seg += mbd->segment_feature_data[MB_LVL_ALT_LF][seg]; + lvl_seg += mbd->segment_feature_data[SEG_LVL_ALT_LF][seg]; lvl_seg = (lvl_seg > 0) ? ((lvl_seg > 63) ? 63: lvl_seg) : 0; } } @@ -541,13 +541,13 @@ void vp8_loop_filter_partial_frame { /* Abs value */ if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA) { - lvl_seg[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i]; + lvl_seg[i] = mbd->segment_feature_data[SEG_LVL_ALT_LF][i]; } /* Delta Value */ else { lvl_seg[i] = default_filt_lvl - + mbd->segment_feature_data[MB_LVL_ALT_LF][i]; + + mbd->segment_feature_data[SEG_LVL_ALT_LF][i]; lvl_seg[i] = (lvl_seg[i] > 0) ? ((lvl_seg[i] > 63) ? 63: lvl_seg[i]) : 0; } diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c index a1aa1ec8a..02ac80aab 100644 --- a/vp8/decoder/decodframe.c +++ b/vp8/decoder/decodframe.c @@ -80,12 +80,12 @@ void mb_init_dequantizer(VP8D_COMP *pbi, MACROBLOCKD *xd) { /* Abs Value */ if (xd->mb_segement_abs_delta == SEGMENT_ABSDATA) - QIndex = xd->segment_feature_data[MB_LVL_ALT_Q][mbmi->segment_id]; + QIndex = xd->segment_feature_data[SEG_LVL_ALT_Q][mbmi->segment_id]; /* Delta Value */ else { - QIndex = pc->base_qindex + xd->segment_feature_data[MB_LVL_ALT_Q][mbmi->segment_id]; + QIndex = pc->base_qindex + xd->segment_feature_data[SEG_LVL_ALT_Q][mbmi->segment_id]; QIndex = (QIndex >= 0) ? ((QIndex <= MAXQ) ? QIndex : MAXQ) : 0; /* Clamp to valid range */ } } @@ -939,7 +939,7 @@ int vp8_decode_frame(VP8D_COMP *pbi) vpx_memset(xd->segment_feature_data, 0, sizeof(xd->segment_feature_data)); /* For each segmentation feature (Quant and loop filter level) */ - for (i = 0; i < MB_LVL_MAX; i++) + for (i = 0; i < SEG_LVL_MAX; i++) { for (j = 0; j < MAX_MB_SEGMENTS; j++) { diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c index e65a7f9d4..7c4ec9a88 100644 --- a/vp8/encoder/bitstream.c +++ b/vp8/encoder/bitstream.c @@ -1846,8 +1846,8 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size) vp8_write_bit(bc, (xd->mb_segement_abs_delta) ? 1 : 0); - // For each segmentation feature (Quant and loop filter level) - for (i = 0; i < MB_LVL_MAX; i++) + // For each segmentation codable feature + for (i = 0; i < SEG_LVL_MAX; i++) { // For each of the segments for (j = 0; j < MAX_MB_SEGMENTS; j++) diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c index e3c214580..a37727510 100644 --- a/vp8/encoder/encodeframe.c +++ b/vp8/encoder/encodeframe.c @@ -995,7 +995,7 @@ void vp8_encode_frame(VP8_COMP *cpi) vp8cx_frame_init_quantizer(cpi); - vp8_initialize_rd_consts(cpi, cm->base_qindex + cm->y1dc_delta_q); + vp8_initialize_rd_consts(cpi, cm->base_qindex + cm->y1dc_delta_q); vp8cx_initialize_me_consts(cpi, cm->base_qindex); if(cpi->oxcf.tuning == VP8_TUNE_SSIM) diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index e2fd622f3..866f542b8 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -428,8 +428,8 @@ static void set_segmentation_map(VP8_PTR ptr, unsigned char *segmentation_map) // The values given for each segment can be either deltas (from the default value chosen for the frame) or absolute values. // -// Valid range for abs values is (0-127 for MB_LVL_ALT_Q) , (0-63 for SEGMENT_ALT_LF) -// Valid range for delta values are (+/-127 for MB_LVL_ALT_Q) , (+/-63 for SEGMENT_ALT_LF) +// Valid range for abs values is (0-127 for SEG_LVL_ALT_Q) , (0-63 for SEGMENT_ALT_LF) +// Valid range for delta values are (+/-127 for SEG_LVL_ALT_Q) , (+/-63 for SEGMENT_ALT_LF) // // abs_delta = SEGMENT_DELTADATA (deltas) abs_delta = SEGMENT_ABSDATA (use the absolute values given). // @@ -447,7 +447,7 @@ static void segmentation_test_function(VP8_PTR ptr) { VP8_COMP *cpi = (VP8_COMP *)(ptr); unsigned char *seg_map; - signed char feature_data[MB_LVL_MAX][MAX_MB_SEGMENTS]; + signed char feature_data[SEG_LVL_MAX][MAX_MB_SEGMENTS]; CHECK_MEM_ERROR(seg_map, vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1)); // Create a temporary map for segmentation data. @@ -478,15 +478,15 @@ static void segmentation_test_function(VP8_PTR ptr) enable_segmentation(ptr); // Set up the quant segment data - feature_data[MB_LVL_ALT_Q][0] = 0; - feature_data[MB_LVL_ALT_Q][1] = 4; - feature_data[MB_LVL_ALT_Q][2] = 0; - feature_data[MB_LVL_ALT_Q][3] = 0; + feature_data[SEG_LVL_ALT_Q][0] = 0; + feature_data[SEG_LVL_ALT_Q][1] = 4; + feature_data[SEG_LVL_ALT_Q][2] = 0; + feature_data[SEG_LVL_ALT_Q][3] = 0; // Set up the loop segment data - feature_data[MB_LVL_ALT_LF][0] = 0; - feature_data[MB_LVL_ALT_LF][1] = 0; - feature_data[MB_LVL_ALT_LF][2] = 0; - feature_data[MB_LVL_ALT_LF][3] = 0; + feature_data[SEG_LVL_ALT_LF][0] = 0; + feature_data[SEG_LVL_ALT_LF][1] = 0; + feature_data[SEG_LVL_ALT_LF][2] = 0; + feature_data[SEG_LVL_ALT_LF][3] = 0; // Initialise the feature data structure // SEGMENT_DELTADATA 0, SEGMENT_ABSDATA 1 @@ -503,7 +503,7 @@ static void segmentation_test_function(VP8_PTR ptr) static void cyclic_background_refresh(VP8_COMP *cpi, int Q, int lf_adjustment) { unsigned char *seg_map; - signed char feature_data[MB_LVL_MAX][MAX_MB_SEGMENTS]; + signed char feature_data[SEG_LVL_MAX][MAX_MB_SEGMENTS]; int i; int block_count = cpi->cyclic_refresh_mode_max_mbs_perframe; int mbs_in_frame = cpi->common.mb_rows * cpi->common.mb_cols; @@ -570,16 +570,16 @@ static void cyclic_background_refresh(VP8_COMP *cpi, int Q, int lf_adjustment) enable_segmentation((VP8_PTR)cpi); // Set up the quant segment data - feature_data[MB_LVL_ALT_Q][0] = 0; - feature_data[MB_LVL_ALT_Q][1] = (cpi->cyclic_refresh_q - Q); - feature_data[MB_LVL_ALT_Q][2] = 0; - feature_data[MB_LVL_ALT_Q][3] = 0; + feature_data[SEG_LVL_ALT_Q][0] = 0; + feature_data[SEG_LVL_ALT_Q][1] = (cpi->cyclic_refresh_q - Q); + feature_data[SEG_LVL_ALT_Q][2] = 0; + feature_data[SEG_LVL_ALT_Q][3] = 0; // Set up the loop segment data - feature_data[MB_LVL_ALT_LF][0] = 0; - feature_data[MB_LVL_ALT_LF][1] = lf_adjustment; - feature_data[MB_LVL_ALT_LF][2] = 0; - feature_data[MB_LVL_ALT_LF][3] = 0; + feature_data[SEG_LVL_ALT_LF][0] = 0; + feature_data[SEG_LVL_ALT_LF][1] = lf_adjustment; + feature_data[SEG_LVL_ALT_LF][2] = 0; + feature_data[SEG_LVL_ALT_LF][3] = 0; // Initialise the feature data structure // SEGMENT_DELTADATA 0, SEGMENT_ABSDATA 1 @@ -5202,7 +5202,7 @@ int vp8_get_preview_raw_frame(VP8_PTR comp, YV12_BUFFER_CONFIG *dest, vp8_ppflag int vp8_set_roimap(VP8_PTR comp, unsigned char *map, unsigned int rows, unsigned int cols, int delta_q[4], int delta_lf[4], unsigned int threshold[4]) { VP8_COMP *cpi = (VP8_COMP *) comp; - signed char feature_data[MB_LVL_MAX][MAX_MB_SEGMENTS]; + signed char feature_data[SEG_LVL_MAX][MAX_MB_SEGMENTS]; if (cpi->common.mb_rows != rows || cpi->common.mb_cols != cols) return -1; @@ -5220,16 +5220,16 @@ int vp8_set_roimap(VP8_PTR comp, unsigned char *map, unsigned int rows, unsigned enable_segmentation((VP8_PTR)cpi); // Set up the quant segment data - feature_data[MB_LVL_ALT_Q][0] = delta_q[0]; - feature_data[MB_LVL_ALT_Q][1] = delta_q[1]; - feature_data[MB_LVL_ALT_Q][2] = delta_q[2]; - feature_data[MB_LVL_ALT_Q][3] = delta_q[3]; + feature_data[SEG_LVL_ALT_Q][0] = delta_q[0]; + feature_data[SEG_LVL_ALT_Q][1] = delta_q[1]; + feature_data[SEG_LVL_ALT_Q][2] = delta_q[2]; + feature_data[SEG_LVL_ALT_Q][3] = delta_q[3]; // Set up the loop segment data s - feature_data[MB_LVL_ALT_LF][0] = delta_lf[0]; - feature_data[MB_LVL_ALT_LF][1] = delta_lf[1]; - feature_data[MB_LVL_ALT_LF][2] = delta_lf[2]; - feature_data[MB_LVL_ALT_LF][3] = delta_lf[3]; + feature_data[SEG_LVL_ALT_LF][0] = delta_lf[0]; + feature_data[SEG_LVL_ALT_LF][1] = delta_lf[1]; + feature_data[SEG_LVL_ALT_LF][2] = delta_lf[2]; + feature_data[SEG_LVL_ALT_LF][3] = delta_lf[3]; cpi->segment_encode_breakout[0] = threshold[0]; cpi->segment_encode_breakout[1] = threshold[1]; diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h index 8519b8f81..403508bb0 100644 --- a/vp8/encoder/onyx_int.h +++ b/vp8/encoder/onyx_int.h @@ -470,14 +470,18 @@ typedef struct VP8_COMP int gf_update_recommended; int skip_true_count; int skip_false_count; -#if CONFIG_T8X8 - int t4x4_count; - int t8x8_count; +#if CONFIG_T8X8 + int t4x4_count; + int t8x8_count; #endif unsigned char *segmentation_map; - signed char segment_feature_data[MB_LVL_MAX][MAX_MB_SEGMENTS]; // Segment data (can be deltas or absolute values) - int segment_encode_breakout[MAX_MB_SEGMENTS]; // segment threashold for encode breakout + + // Segment data (can be deltas or absolute values) + signed char segment_feature_data[SEG_LVL_MAX][MAX_MB_SEGMENTS]; + + // segment threashold for encode breakout + int segment_encode_breakout[MAX_MB_SEGMENTS]; unsigned char *active_map; unsigned int active_map_enabled; diff --git a/vp8/encoder/picklpf.c b/vp8/encoder/picklpf.c index beefe8d8e..3a6117f6f 100644 --- a/vp8/encoder/picklpf.c +++ b/vp8/encoder/picklpf.c @@ -259,10 +259,10 @@ void vp8cx_set_alt_lf_level(VP8_COMP *cpi, int filt_val) MACROBLOCKD *mbd = &cpi->mb.e_mbd; (void) filt_val; - mbd->segment_feature_data[MB_LVL_ALT_LF][0] = cpi->segment_feature_data[MB_LVL_ALT_LF][0]; - mbd->segment_feature_data[MB_LVL_ALT_LF][1] = cpi->segment_feature_data[MB_LVL_ALT_LF][1]; - mbd->segment_feature_data[MB_LVL_ALT_LF][2] = cpi->segment_feature_data[MB_LVL_ALT_LF][2]; - mbd->segment_feature_data[MB_LVL_ALT_LF][3] = cpi->segment_feature_data[MB_LVL_ALT_LF][3]; + mbd->segment_feature_data[SEG_LVL_ALT_LF][0] = cpi->segment_feature_data[SEG_LVL_ALT_LF][0]; + mbd->segment_feature_data[SEG_LVL_ALT_LF][1] = cpi->segment_feature_data[SEG_LVL_ALT_LF][1]; + mbd->segment_feature_data[SEG_LVL_ALT_LF][2] = cpi->segment_feature_data[SEG_LVL_ALT_LF][2]; + mbd->segment_feature_data[SEG_LVL_ALT_LF][3] = cpi->segment_feature_data[SEG_LVL_ALT_LF][3]; } void vp8cx_pick_filter_level(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi) diff --git a/vp8/encoder/quantize.c b/vp8/encoder/quantize.c index 328eabbf9..200d1ae0a 100644 --- a/vp8/encoder/quantize.c +++ b/vp8/encoder/quantize.c @@ -1174,11 +1174,11 @@ void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x) // Abs Value if (xd->mb_segement_abs_delta == SEGMENT_ABSDATA) - QIndex = xd->segment_feature_data[MB_LVL_ALT_Q][xd->mode_info_context->mbmi.segment_id]; + QIndex = xd->segment_feature_data[SEG_LVL_ALT_Q][xd->mode_info_context->mbmi.segment_id]; // Delta Value else { - QIndex = cpi->common.base_qindex + xd->segment_feature_data[MB_LVL_ALT_Q][xd->mode_info_context->mbmi.segment_id]; + QIndex = cpi->common.base_qindex + xd->segment_feature_data[SEG_LVL_ALT_Q][xd->mode_info_context->mbmi.segment_id]; QIndex = (QIndex >= 0) ? ((QIndex <= MAXQ) ? QIndex : MAXQ) : 0; // Clamp to valid range } } @@ -1316,10 +1316,10 @@ void vp8_set_quantizer(struct VP8_COMP *cpi, int Q) // Set Segment specific quatizers - mbd->segment_feature_data[MB_LVL_ALT_Q][0] = cpi->segment_feature_data[MB_LVL_ALT_Q][0]; - mbd->segment_feature_data[MB_LVL_ALT_Q][1] = cpi->segment_feature_data[MB_LVL_ALT_Q][1]; - mbd->segment_feature_data[MB_LVL_ALT_Q][2] = cpi->segment_feature_data[MB_LVL_ALT_Q][2]; - mbd->segment_feature_data[MB_LVL_ALT_Q][3] = cpi->segment_feature_data[MB_LVL_ALT_Q][3]; + mbd->segment_feature_data[SEG_LVL_ALT_Q][0] = cpi->segment_feature_data[SEG_LVL_ALT_Q][0]; + mbd->segment_feature_data[SEG_LVL_ALT_Q][1] = cpi->segment_feature_data[SEG_LVL_ALT_Q][1]; + mbd->segment_feature_data[SEG_LVL_ALT_Q][2] = cpi->segment_feature_data[SEG_LVL_ALT_Q][2]; + mbd->segment_feature_data[SEG_LVL_ALT_Q][3] = cpi->segment_feature_data[SEG_LVL_ALT_Q][3]; /* quantizer has to be reinitialized for any delta_q changes */ if(update) -- 2.40.0