From 340c7a48e6b1f199d93ce7888a961acf5f13d701 Mon Sep 17 00:00:00 2001 From: Paul Wilkins Date: Fri, 7 Jun 2013 14:59:53 +0100 Subject: [PATCH] Change to segment ref frame feature. Simplify feature to only support a single reference frame instead of a mask. Change-Id: I5dd3a98c7a224aafb35708850ab82e2f220e68fb --- vp9/common/vp9_seg_common.c | 15 --------------- vp9/common/vp9_seg_common.h | 10 ---------- vp9/decoder/vp9_decodemv.c | 17 +++-------------- vp9/encoder/vp9_bitstream.c | 14 +++----------- vp9/encoder/vp9_encodeframe.c | 30 +++++------------------------- vp9/encoder/vp9_onyx_if.c | 10 +++++----- vp9/encoder/vp9_rdopt.c | 11 +---------- 7 files changed, 17 insertions(+), 90 deletions(-) diff --git a/vp9/common/vp9_seg_common.c b/vp9/common/vp9_seg_common.c index 890dcce37..e54e6c7cb 100644 --- a/vp9/common/vp9_seg_common.c +++ b/vp9/common/vp9_seg_common.c @@ -70,21 +70,6 @@ int vp9_get_segdata(const MACROBLOCKD *xd, int segment_id, return xd->segment_feature_data[segment_id][feature_id]; } -void vp9_clear_segref(MACROBLOCKD *xd, int segment_id) { - xd->segment_feature_data[segment_id][SEG_LVL_REF_FRAME] = 0; -} - -void vp9_set_segref(MACROBLOCKD *xd, int segment_id, - MV_REFERENCE_FRAME ref_frame) { - xd->segment_feature_data[segment_id][SEG_LVL_REF_FRAME] |= 1 << ref_frame; -} - -int vp9_check_segref(const MACROBLOCKD *xd, int segment_id, - MV_REFERENCE_FRAME ref_frame) { - return (xd->segment_feature_data[segment_id][SEG_LVL_REF_FRAME] & - (1 << ref_frame)) ? 1 : 0; -} - const vp9_tree_index vp9_segment_tree[14] = { 2, 4, 6, 8, 10, 12, diff --git a/vp9/common/vp9_seg_common.h b/vp9/common/vp9_seg_common.h index c424a57f4..74ba03c3e 100644 --- a/vp9/common/vp9_seg_common.h +++ b/vp9/common/vp9_seg_common.h @@ -45,16 +45,6 @@ int vp9_get_segdata(const MACROBLOCKD *xd, int segment_id, SEG_LVL_FEATURES feature_id); -void vp9_clear_segref(MACROBLOCKD *xd, int segment_id); - -void vp9_set_segref(MACROBLOCKD *xd, - int segment_id, - MV_REFERENCE_FRAME ref_frame); - -int vp9_check_segref(const MACROBLOCKD *xd, - int segment_id, - MV_REFERENCE_FRAME ref_frame); - extern const vp9_tree_index vp9_segment_tree[14]; #endif // VP9_COMMON_VP9_SEG_COMMON_H_ diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c index cb16ccdf3..e0f128f57 100644 --- a/vp9/decoder/vp9_decodemv.c +++ b/vp9/decoder/vp9_decodemv.c @@ -241,22 +241,11 @@ static void read_ref_frame(VP9D_COMP *pbi, vp9_reader *r, int segment_id, MV_REFERENCE_FRAME ref_frame[2]) { VP9_COMMON *const cm = &pbi->common; MACROBLOCKD *const xd = &pbi->mb; - int seg_ref_count = 0; const int seg_ref_active = vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME); - const int intra = vp9_check_segref(xd, segment_id, INTRA_FRAME); - const int last = vp9_check_segref(xd, segment_id, LAST_FRAME); - const int golden = vp9_check_segref(xd, segment_id, GOLDEN_FRAME); - const int altref = vp9_check_segref(xd, segment_id, ALTREF_FRAME); - // If segment coding enabled does the segment allow for more than one - // possible reference frame - if (seg_ref_active) - seg_ref_count = intra + last + golden + altref; - - // Segment reference frame features not available or allows for - // multiple reference frame options - if (!seg_ref_active || seg_ref_count > 1) { + // Segment reference frame features not available. + if (!seg_ref_active) { int is_comp; int comp_ctx = vp9_get_pred_context(cm, xd, PRED_COMP_INTER_INTER); @@ -291,7 +280,7 @@ static void read_ref_frame(VP9D_COMP *pbi, vp9_reader *r, } } } else { - ref_frame[0] = last ? LAST_FRAME : golden ? GOLDEN_FRAME : ALTREF_FRAME; + ref_frame[0] = vp9_get_segdata(xd, segment_id, SEG_LVL_REF_FRAME); ref_frame[1] = NONE; } } diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index 28e107b55..55ed2a450 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -483,18 +483,9 @@ static void encode_ref_frame(VP9_COMP *cpi, vp9_writer *bc) { const int segment_id = mi->segment_id; int seg_ref_active = vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME); - int seg_ref_count = 0; - - if (seg_ref_active) { - seg_ref_count = vp9_check_segref(xd, segment_id, INTRA_FRAME) + - vp9_check_segref(xd, segment_id, LAST_FRAME) + - vp9_check_segref(xd, segment_id, GOLDEN_FRAME) + - vp9_check_segref(xd, segment_id, ALTREF_FRAME); - } - // If segment level coding of this signal is disabled... // or the segment allows multiple reference frame options - if (!seg_ref_active || (seg_ref_count > 1)) { + if (!seg_ref_active) { // does the feature use compound prediction or not // (if not specified at the frame/segment level) if (pc->comp_pred_mode == HYBRID_PREDICTION) { @@ -517,7 +508,8 @@ static void encode_ref_frame(VP9_COMP *cpi, vp9_writer *bc) { } } else { assert(mi->ref_frame[1] <= INTRA_FRAME); - assert(vp9_check_segref(xd, segment_id, mi->ref_frame[0])); + assert(vp9_get_segdata(xd, segment_id, SEG_LVL_REF_FRAME) == + mi->ref_frame[0]); } // if using the prediction mdoel we have nothing further to do because diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index 898030604..047bbb5e9 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -575,11 +575,7 @@ static void set_offsets(VP9_COMP *cpi, 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) && - vp9_check_segref(xd, 1, INTRA_FRAME) + - vp9_check_segref(xd, 1, LAST_FRAME) + - vp9_check_segref(xd, 1, GOLDEN_FRAME) + - vp9_check_segref(xd, 1, ALTREF_FRAME) == 1) { + vp9_segfeature_active(xd, 1, SEG_LVL_REF_FRAME)) { cpi->seg0_progress = (cpi->seg0_idx << 16) / cpi->seg0_cnt; } else { const int y = mb_row & ~3; @@ -638,20 +634,13 @@ static void update_stats(VP9_COMP *cpi, int mi_row, int mi_col) { cpi->intra_inter_count[vp9_get_pred_context(cm, xd, PRED_INTRA_INTER)] [mbmi->ref_frame[0] > INTRA_FRAME]++; - // If we have just a single reference frame coded for a segment then - // exclude from the reference frame counts used to work out - // probabilities. NOTE: At the moment we dont support custom trees - // for the reference frame coding for each segment but this is a - // possible future action. + // If the segment reference feature is enabled we have only a single + // reference frame allowed for the segment so exclude it from + // the reference frame counts used to work out probabilities. segment_id = mbmi->segment_id; seg_ref_active = vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME); - if (mbmi->ref_frame[0] > INTRA_FRAME && - (!seg_ref_active || - ((vp9_check_segref(xd, segment_id, INTRA_FRAME) + - vp9_check_segref(xd, segment_id, LAST_FRAME) + - vp9_check_segref(xd, segment_id, GOLDEN_FRAME) + - vp9_check_segref(xd, segment_id, ALTREF_FRAME)) > 1))) { + if ((mbmi->ref_frame[0] > INTRA_FRAME) && !seg_ref_active) { if (cm->comp_pred_mode == HYBRID_PREDICTION) cpi->comp_inter_count[vp9_get_pred_context(cm, xd, PRED_COMP_INTER_INTER)] @@ -1616,15 +1605,6 @@ static int check_dual_ref_flags(VP9_COMP *cpi) { int ref_flags = cpi->ref_frame_flags; if (vp9_segfeature_active(xd, 1, SEG_LVL_REF_FRAME)) { - if ((ref_flags & (VP9_LAST_FLAG | VP9_GOLD_FLAG)) == (VP9_LAST_FLAG | VP9_GOLD_FLAG) && - vp9_check_segref(xd, 1, LAST_FRAME)) - return 1; - if ((ref_flags & (VP9_GOLD_FLAG | VP9_ALT_FLAG)) == (VP9_GOLD_FLAG | VP9_ALT_FLAG) && - vp9_check_segref(xd, 1, GOLDEN_FRAME)) - return 1; - if ((ref_flags & (VP9_ALT_FLAG | VP9_LAST_FLAG)) == (VP9_ALT_FLAG | VP9_LAST_FLAG) && - vp9_check_segref(xd, 1, ALTREF_FRAME)) - return 1; return 0; } else { return (!!(ref_flags & VP9_GOLD_FLAG) + diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index 73220dcd9..5bd4e7857 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -413,7 +413,7 @@ static void configure_static_seg_features(VP9_COMP *cpi) { // Segment coding disabled for compred testing if (high_q || (cpi->static_mb_pct == 100)) { - vp9_set_segref(xd, 1, ALTREF_FRAME); + 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); } @@ -440,10 +440,10 @@ static void configure_static_seg_features(VP9_COMP *cpi) { vp9_enable_segfeature(xd, 1, SEG_LVL_REF_FRAME); // All mbs should use ALTREF_FRAME - vp9_clear_segref(xd, 0); - vp9_set_segref(xd, 0, ALTREF_FRAME); - vp9_clear_segref(xd, 1); - vp9_set_segref(xd, 1, 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); // Skip all MBs if high Q (0,0 mv and skip coeffs) if (high_q) { diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index 0fea2b931..cb081a316 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -1635,16 +1635,7 @@ static void estimate_ref_frame_costs(VP9_COMP *cpi, int segment_id, MACROBLOCKD *const xd = &cpi->mb.e_mbd; int seg_ref_active = vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME); - int seg_ref_count = 0; - if (seg_ref_active) { - seg_ref_count = vp9_check_segref(xd, segment_id, INTRA_FRAME) + - vp9_check_segref(xd, segment_id, LAST_FRAME) + - vp9_check_segref(xd, segment_id, GOLDEN_FRAME) + - vp9_check_segref(xd, segment_id, ALTREF_FRAME); - } - - if (seg_ref_active && seg_ref_count == 1) { vpx_memset(ref_costs_single, 0, MAX_REF_FRAMES * sizeof(*ref_costs_single)); vpx_memset(ref_costs_comp, 0, MAX_REF_FRAMES * sizeof(*ref_costs_comp)); *comp_mode_p = 128; @@ -2685,7 +2676,7 @@ 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_check_segref(xd, segment_id, ref_frame)) { + vp9_get_segdata(xd, 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..