diff options
-rw-r--r-- | test/idct_test.cc | 135 | ||||
-rw-r--r-- | test/ivf_video_source.h | 3 | ||||
-rw-r--r-- | test/subtract_test.cc | 2 | ||||
-rw-r--r-- | test/util.h | 2 | ||||
-rw-r--r-- | vp9/common/vp9_blockd.h | 46 | ||||
-rw-r--r-- | vp9/common/vp9_entropy.c | 4 | ||||
-rw-r--r-- | vp9/common/vp9_entropymode.c | 62 | ||||
-rw-r--r-- | vp9/common/vp9_entropymode.h | 6 | ||||
-rw-r--r-- | vp9/common/vp9_entropymv.c | 4 | ||||
-rw-r--r-- | vp9/common/vp9_loopfilter.c | 21 | ||||
-rw-r--r-- | vp9/common/vp9_loopfilter.h | 2 | ||||
-rw-r--r-- | vp9/common/vp9_onyx.h | 28 | ||||
-rw-r--r-- | vp9/common/vp9_onyxc_int.h | 20 | ||||
-rw-r--r-- | vp9/common/vp9_postproc.c | 6 | ||||
-rw-r--r-- | vp9/common/vp9_postproc.h | 4 | ||||
-rw-r--r-- | vp9/decoder/vp9_decodemv.c | 2 | ||||
-rw-r--r-- | vp9/decoder/vp9_decodframe.c | 85 | ||||
-rw-r--r-- | vp9/decoder/vp9_onyxd_if.c | 8 | ||||
-rw-r--r-- | vp9/encoder/vp9_bitstream.c | 47 | ||||
-rw-r--r-- | vp9/encoder/vp9_encodeframe.c | 62 | ||||
-rw-r--r-- | vp9/encoder/vp9_onyx_if.c | 162 | ||||
-rw-r--r-- | vp9/encoder/vp9_onyx_int.h | 57 | ||||
-rw-r--r-- | vp9/encoder/vp9_picklpf.c | 12 | ||||
-rw-r--r-- | vp9/encoder/vp9_ratectrl.c | 50 | ||||
-rw-r--r-- | vp9/encoder/vp9_rdopt.c | 311 |
25 files changed, 572 insertions, 569 deletions
diff --git a/test/idct_test.cc b/test/idct_test.cc index 659cce05f..aa786cb5d 100644 --- a/test/idct_test.cc +++ b/test/idct_test.cc @@ -8,7 +8,6 @@ * be found in the AUTHORS file in the root of the source tree. */ - extern "C" { #include "./vpx_config.h" #include "./vp8_rtcd.h" @@ -22,100 +21,94 @@ typedef void (*idct_fn_t)(short *input, unsigned char *pred_ptr, int dst_stride); namespace { class IDCTTest : public ::testing::TestWithParam<idct_fn_t> { - protected: - virtual void SetUp() { - int i; - - UUT = GetParam(); - memset(input, 0, sizeof(input)); - /* Set up guard blocks */ - for (i = 0; i < 256; i++) - output[i] = ((i & 0xF) < 4 && (i < 64)) ? 0 : -1; - } - - virtual void TearDown() { - libvpx_test::ClearSystemState(); - } - - idct_fn_t UUT; - short input[16]; - unsigned char output[256]; - unsigned char predict[256]; + protected: + virtual void SetUp() { + int i; + + UUT = GetParam(); + memset(input, 0, sizeof(input)); + /* Set up guard blocks */ + for (i = 0; i < 256; i++) output[i] = ((i & 0xF) < 4 && (i < 64)) ? 0 : -1; + } + + virtual void TearDown() { libvpx_test::ClearSystemState(); } + + idct_fn_t UUT; + short input[16]; + unsigned char output[256]; + unsigned char predict[256]; }; TEST_P(IDCTTest, TestGuardBlocks) { - int i; + int i; - for (i = 0; i < 256; i++) - if ((i & 0xF) < 4 && i < 64) - EXPECT_EQ(0, output[i]) << i; - else - EXPECT_EQ(255, output[i]); + for (i = 0; i < 256; i++) + if ((i & 0xF) < 4 && i < 64) + EXPECT_EQ(0, output[i]) << i; + else + EXPECT_EQ(255, output[i]); } TEST_P(IDCTTest, TestAllZeros) { - int i; + int i; - REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16)); + REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16)); - for (i = 0; i < 256; i++) - if ((i & 0xF) < 4 && i < 64) - EXPECT_EQ(0, output[i]) << "i==" << i; - else - EXPECT_EQ(255, output[i]) << "i==" << i; + for (i = 0; i < 256; i++) + if ((i & 0xF) < 4 && i < 64) + EXPECT_EQ(0, output[i]) << "i==" << i; + else + EXPECT_EQ(255, output[i]) << "i==" << i; } TEST_P(IDCTTest, TestAllOnes) { - int i; + int i; - input[0] = 4; - REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16)); + input[0] = 4; + REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16)); - for (i = 0; i < 256; i++) - if ((i & 0xF) < 4 && i < 64) - EXPECT_EQ(1, output[i]) << "i==" << i; - else - EXPECT_EQ(255, output[i]) << "i==" << i; + for (i = 0; i < 256; i++) + if ((i & 0xF) < 4 && i < 64) + EXPECT_EQ(1, output[i]) << "i==" << i; + else + EXPECT_EQ(255, output[i]) << "i==" << i; } TEST_P(IDCTTest, TestAddOne) { - int i; + int i; - for (i = 0; i < 256; i++) - predict[i] = i; - input[0] = 4; - REGISTER_STATE_CHECK(UUT(input, predict, 16, output, 16)); + for (i = 0; i < 256; i++) predict[i] = i; + input[0] = 4; + REGISTER_STATE_CHECK(UUT(input, predict, 16, output, 16)); - for (i = 0; i < 256; i++) - if ((i & 0xF) < 4 && i < 64) - EXPECT_EQ(i+1, output[i]) << "i==" << i; - else - EXPECT_EQ(255, output[i]) << "i==" << i; + for (i = 0; i < 256; i++) + if ((i & 0xF) < 4 && i < 64) + EXPECT_EQ(i + 1, output[i]) << "i==" << i; + else + EXPECT_EQ(255, output[i]) << "i==" << i; } TEST_P(IDCTTest, TestWithData) { - int i; - - for (i = 0; i < 16; i++) - input[i] = i; - - REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16)); - - for (i = 0; i < 256; i++) - if ((i & 0xF) > 3 || i > 63) - EXPECT_EQ(255, output[i]) << "i==" << i; - else if (i == 0) - EXPECT_EQ(11, output[i]) << "i==" << i; - else if (i == 34) - EXPECT_EQ(1, output[i]) << "i==" << i; - else if (i == 2 || i == 17 || i == 32) - EXPECT_EQ(3, output[i]) << "i==" << i; - else - EXPECT_EQ(0, output[i]) << "i==" << i; + int i; + + for (i = 0; i < 16; i++) input[i] = i; + + REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16)); + + for (i = 0; i < 256; i++) + if ((i & 0xF) > 3 || i > 63) + EXPECT_EQ(255, output[i]) << "i==" << i; + else if (i == 0) + EXPECT_EQ(11, output[i]) << "i==" << i; + else if (i == 34) + EXPECT_EQ(1, output[i]) << "i==" << i; + else if (i == 2 || i == 17 || i == 32) + EXPECT_EQ(3, output[i]) << "i==" << i; + else + EXPECT_EQ(0, output[i]) << "i==" << i; } -INSTANTIATE_TEST_CASE_P(C, IDCTTest, - ::testing::Values(vp8_short_idct4x4llm_c)); +INSTANTIATE_TEST_CASE_P(C, IDCTTest, ::testing::Values(vp8_short_idct4x4llm_c)); #if HAVE_MMX INSTANTIATE_TEST_CASE_P(MMX, IDCTTest, ::testing::Values(vp8_short_idct4x4llm_mmx)); diff --git a/test/ivf_video_source.h b/test/ivf_video_source.h index 88bc597ae..926f801d4 100644 --- a/test/ivf_video_source.h +++ b/test/ivf_video_source.h @@ -47,7 +47,8 @@ class IVFVideoSource : public CompressedVideoSource { virtual void Init() { // Allocate a buffer for read in the compressed video frame. compressed_frame_buf_ = new uint8_t[libvpx_test::kCodeBufferSize]; - ASSERT_TRUE(compressed_frame_buf_) << "Allocate frame buffer failed"; + ASSERT_TRUE(compressed_frame_buf_ != NULL) + << "Allocate frame buffer failed"; } virtual void Begin() { diff --git a/test/subtract_test.cc b/test/subtract_test.cc index 81bfb662c..574bfbf47 100644 --- a/test/subtract_test.cc +++ b/test/subtract_test.cc @@ -61,7 +61,7 @@ TEST_P(SubtractBlockTest, SimpleSubtract) { int16_t *src_diff = be.src_diff; for (int r = 0; r < kBlockHeight; ++r) { for (int c = 0; c < kBlockWidth; ++c) { - src_diff[c] = 0xa5a5; + src_diff[c] = static_cast<int16_t>(0xa5a5); } src_diff += kDiffPredStride; } diff --git a/test/util.h b/test/util.h index 533a1db5c..4d7f3d41e 100644 --- a/test/util.h +++ b/test/util.h @@ -37,7 +37,7 @@ static double compute_psnr(const vpx_image_t *img1, img2->planes[VPX_PLANE_Y][i * img2->stride[VPX_PLANE_Y] + j]; sqrerr += d * d; } - double mse = sqrerr / (width_y * height_y); + double mse = static_cast<double>(sqrerr) / (width_y * height_y); double psnr = 100.0; if (mse > 0.0) { psnr = 10 * log10(255.0 * 255.0 / mse); diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h index 35a6b1ec1..dc20f2ad2 100644 --- a/vp9/common/vp9_blockd.h +++ b/vp9/common/vp9_blockd.h @@ -31,9 +31,6 @@ #define MBSKIP_CONTEXTS 3 -#define MAX_REF_LF_DELTAS 4 -#define MAX_MODE_LF_DELTAS 2 - /* Segment Feature Masks */ #define MAX_MV_REF_CANDIDATES 2 @@ -99,6 +96,10 @@ static INLINE int is_inter_mode(MB_PREDICTION_MODE mode) { #define VP9_INTER_MODES (1 + NEWMV - NEARESTMV) +static INLINE int inter_mode_offset(MB_PREDICTION_MODE mode) { + return (mode - NEARESTMV); +} + /* For keyframes, intra block modes are predicted by the (already decoded) modes for the Y blocks to the left and above us; for interframes, there is a single probability table. */ @@ -215,6 +216,27 @@ struct macroblockd_plane { #define BLOCK_OFFSET(x, i, n) ((x) + (i) * (n)) +#define MAX_REF_LF_DELTAS 4 +#define MAX_MODE_LF_DELTAS 2 + +struct loopfilter { + int filter_level; + + int sharpness_level; + int last_sharpness_level; + + uint8_t mode_ref_delta_enabled; + uint8_t mode_ref_delta_update; + + // 0 = Intra, Last, GF, ARF + signed char ref_deltas[MAX_REF_LF_DELTAS]; + signed char last_ref_deltas[MAX_REF_LF_DELTAS]; + + // 0 = ZERO_MV, MV + signed char mode_deltas[MAX_MODE_LF_DELTAS]; + signed char last_mode_deltas[MAX_MODE_LF_DELTAS]; +}; + typedef struct macroblockd { struct macroblockd_plane plane[MAX_MB_PLANE]; @@ -224,33 +246,17 @@ typedef struct macroblockd { MODE_INFO *mode_info_context; int mode_info_stride; - FRAME_TYPE frame_type; - int up_available; int left_available; int right_available; struct segmentation seg; + struct loopfilter lf; // partition contexts PARTITION_CONTEXT *above_seg_context; PARTITION_CONTEXT *left_seg_context; - /* mode_based Loop filter adjustment */ - unsigned char mode_ref_lf_delta_enabled; - unsigned char mode_ref_lf_delta_update; - - /* Delta values have the range +/- MAX_LOOP_FILTER */ - /* 0 = Intra, Last, GF, ARF */ - signed char last_ref_lf_deltas[MAX_REF_LF_DELTAS]; - /* 0 = Intra, Last, GF, ARF */ - signed char ref_lf_deltas[MAX_REF_LF_DELTAS]; - - /* 0 = ZERO_MV, MV */ - signed char last_mode_lf_deltas[MAX_MODE_LF_DELTAS]; - /* 0 = ZERO_MV, MV */ - signed char mode_lf_deltas[MAX_MODE_LF_DELTAS]; - /* Distance of MB away from frame edges */ int mb_to_left_edge; int mb_to_right_edge; diff --git a/vp9/common/vp9_entropy.c b/vp9/common/vp9_entropy.c index 5e8af6c91..06929180e 100644 --- a/vp9/common/vp9_entropy.c +++ b/vp9/common/vp9_entropy.c @@ -625,8 +625,10 @@ void vp9_coef_tree_initialize() { static void adapt_coef_probs(VP9_COMMON *cm, TX_SIZE txfm_size, int count_sat, int update_factor) { + FRAME_CONTEXT *pre_fc = &cm->frame_contexts[cm->frame_context_idx]; + vp9_coeff_probs_model *dst_coef_probs = cm->fc.coef_probs[txfm_size]; - vp9_coeff_probs_model *pre_coef_probs = cm->fc.pre_coef_probs[txfm_size]; + vp9_coeff_probs_model *pre_coef_probs = pre_fc->coef_probs[txfm_size]; vp9_coeff_count_model *coef_counts = cm->fc.coef_counts[txfm_size]; unsigned int (*eob_branch_count)[REF_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS] = cm->fc.eob_branch_counts[txfm_size]; diff --git a/vp9/common/vp9_entropymode.c b/vp9/common/vp9_entropymode.c index f66f2f317..4cfde35b0 100644 --- a/vp9/common/vp9_entropymode.c +++ b/vp9/common/vp9_entropymode.c @@ -238,7 +238,7 @@ const vp9_tree_index vp9_intra_mode_tree[VP9_INTRA_MODES * 2 - 2] = { -D153_PRED, -D27_PRED /* 8 = D153_NODE */ }; -const vp9_tree_index vp9_sb_mv_ref_tree[6] = { +const vp9_tree_index vp9_inter_mode_tree[6] = { -ZEROMV, 2, -NEARESTMV, 4, -NEARMV, -NEWMV @@ -251,8 +251,7 @@ const vp9_tree_index vp9_partition_tree[6] = { }; struct vp9_token vp9_intra_mode_encodings[VP9_INTRA_MODES]; - -struct vp9_token vp9_sb_mv_ref_encoding_array[VP9_INTER_MODES]; +struct vp9_token vp9_inter_mode_encodings[VP9_INTER_MODES]; struct vp9_token vp9_partition_encodings[PARTITION_TYPES]; @@ -356,8 +355,8 @@ void vp9_entropy_mode_init() { vp9_tokens_from_tree(vp9_switchable_interp_encodings, vp9_switchable_interp_tree); vp9_tokens_from_tree(vp9_partition_encodings, vp9_partition_tree); - vp9_tokens_from_tree_offset(vp9_sb_mv_ref_encoding_array, - vp9_sb_mv_ref_tree, NEARESTMV); + vp9_tokens_from_tree_offset(vp9_inter_mode_encodings, + vp9_inter_mode_tree, NEARESTMV); } void vp9_init_mode_contexts(VP9_COMMON *pc) { @@ -392,6 +391,8 @@ void vp9_accum_mv_refs(VP9_COMMON *pc, #define MVREF_MAX_UPDATE_FACTOR 128 void vp9_adapt_mode_context(VP9_COMMON *pc) { int i, j; + FRAME_CONTEXT *pre_fc = &pc->frame_contexts[pc->frame_context_idx]; + unsigned int (*inter_mode_counts)[VP9_INTER_MODES - 1][2] = pc->fc.inter_mode_counts; vp9_prob (*mode_context)[VP9_INTER_MODES - 1] = pc->fc.inter_mode_probs; @@ -403,7 +404,7 @@ void vp9_adapt_mode_context(VP9_COMMON *pc) { count = count > MVREF_COUNT_SAT ? MVREF_COUNT_SAT : count; factor = (MVREF_MAX_UPDATE_FACTOR * count / MVREF_COUNT_SAT); mode_context[j][i] = weighted_prob( - pc->fc.pre_inter_mode_probs[j][i], + pre_fc->inter_mode_probs[j][i], get_binary_prob(inter_mode_counts[j][i][0], inter_mode_counts[j][i][1]), factor); @@ -450,6 +451,8 @@ static void update_mode_probs(int n_modes, void vp9_adapt_mode_probs(VP9_COMMON *cm) { int i, j; FRAME_CONTEXT *fc = &cm->fc; + FRAME_CONTEXT *pre_fc = &cm->frame_contexts[cm->frame_context_idx]; + #ifdef MODE_COUNT_TESTING int t; @@ -485,39 +488,40 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) { #endif for (i = 0; i < INTRA_INTER_CONTEXTS; i++) - fc->intra_inter_prob[i] = update_mode_ct2(fc->pre_intra_inter_prob[i], + fc->intra_inter_prob[i] = update_mode_ct2(pre_fc->intra_inter_prob[i], fc->intra_inter_count[i]); for (i = 0; i < COMP_INTER_CONTEXTS; i++) - fc->comp_inter_prob[i] = update_mode_ct2(fc->pre_comp_inter_prob[i], + fc->comp_inter_prob[i] = update_mode_ct2(pre_fc->comp_inter_prob[i], fc->comp_inter_count[i]); for (i = 0; i < REF_CONTEXTS; i++) - fc->comp_ref_prob[i] = update_mode_ct2(fc->pre_comp_ref_prob[i], + fc->comp_ref_prob[i] = update_mode_ct2(pre_fc->comp_ref_prob[i], fc->comp_ref_count[i]); for (i = 0; i < REF_CONTEXTS; i++) for (j = 0; j < 2; j++) - fc->single_ref_prob[i][j] = update_mode_ct2(fc->pre_single_ref_prob[i][j], + fc->single_ref_prob[i][j] = update_mode_ct2(pre_fc->single_ref_prob[i][j], fc->single_ref_count[i][j]); for (i = 0; i < BLOCK_SIZE_GROUPS; i++) update_mode_probs(VP9_INTRA_MODES, vp9_intra_mode_tree, - fc->y_mode_counts[i], fc->pre_y_mode_prob[i], + fc->y_mode_counts[i], pre_fc->y_mode_prob[i], fc->y_mode_prob[i], 0); for (i = 0; i < VP9_INTRA_MODES; ++i) update_mode_probs(VP9_INTRA_MODES, vp9_intra_mode_tree, - fc->uv_mode_counts[i], fc->pre_uv_mode_prob[i], + fc->uv_mode_counts[i], pre_fc->uv_mode_prob[i], fc->uv_mode_prob[i], 0); for (i = 0; i < NUM_PARTITION_CONTEXTS; i++) update_mode_probs(PARTITION_TYPES, vp9_partition_tree, - fc->partition_counts[i], fc->pre_partition_prob[i], + fc->partition_counts[i], + pre_fc->partition_prob[INTER_FRAME][i], fc->partition_prob[INTER_FRAME][i], 0); if (cm->mcomp_filter_type == SWITCHABLE) { for (i = 0; i <= VP9_SWITCHABLE_FILTERS; i++) update_mode_probs(VP9_SWITCHABLE_FILTERS, vp9_switchable_interp_tree, fc->switchable_interp_count[i], - fc->pre_switchable_interp_prob[i], + pre_fc->switchable_interp_prob[i], fc->switchable_interp_prob[i], 0); } @@ -530,39 +534,39 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) { for (i = 0; i < TX_SIZE_CONTEXTS; ++i) { tx_counts_to_branch_counts_8x8(fc->tx_counts.p8x8[i], branch_ct_8x8p); for (j = 0; j < TX_SIZE_MAX_SB - 3; ++j) - fc->tx_probs.p8x8[i][j] = update_tx_ct(fc->pre_tx_probs.p8x8[i][j], + fc->tx_probs.p8x8[i][j] = update_tx_ct(pre_fc->tx_probs.p8x8[i][j], branch_ct_8x8p[j]); tx_counts_to_branch_counts_16x16(fc->tx_counts.p16x16[i], branch_ct_16x16p); for (j = 0; j < TX_SIZE_MAX_SB - 2; ++j) - fc->tx_probs.p16x16[i][j] = update_tx_ct(fc->tx_probs.p16x16[i][j], + fc->tx_probs.p16x16[i][j] = update_tx_ct(pre_fc->tx_probs.p16x16[i][j], branch_ct_16x16p[j]); tx_counts_to_branch_counts_32x32(fc->tx_counts.p32x32[i], branch_ct_32x32p); for (j = 0; j < TX_SIZE_MAX_SB - 1; ++j) - fc->tx_probs.p32x32[i][j] = update_tx_ct(fc->pre_tx_probs.p32x32[i][j], + fc->tx_probs.p32x32[i][j] = update_tx_ct(pre_fc->tx_probs.p32x32[i][j], branch_ct_32x32p[j]); } } for (i = 0; i < MBSKIP_CONTEXTS; ++i) - fc->mbskip_probs[i] = update_mode_ct2(fc->pre_mbskip_probs[i], + fc->mbskip_probs[i] = update_mode_ct2(pre_fc->mbskip_probs[i], fc->mbskip_count[i]); } static void set_default_lf_deltas(MACROBLOCKD *xd) { - xd->mode_ref_lf_delta_enabled = 1; - xd->mode_ref_lf_delta_update = 1; + xd->lf.mode_ref_delta_enabled = 1; + xd->lf.mode_ref_delta_update = 1; - xd->ref_lf_deltas[INTRA_FRAME] = 1; - xd->ref_lf_deltas[LAST_FRAME] = 0; - xd->ref_lf_deltas[GOLDEN_FRAME] = -1; - xd->ref_lf_deltas[ALTREF_FRAME] = -1; + xd->lf.ref_deltas[INTRA_FRAME] = 1; + xd->lf.ref_deltas[LAST_FRAME] = 0; + xd->lf.ref_deltas[GOLDEN_FRAME] = -1; + xd->lf.ref_deltas[ALTREF_FRAME] = -1; - xd->mode_lf_deltas[0] = 0; - xd->mode_lf_deltas[1] = 0; + xd->lf.mode_deltas[0] = 0; + xd->lf.mode_deltas[1] = 0; } void vp9_setup_past_independence(VP9_COMMON *cm, MACROBLOCKD *xd) { @@ -575,8 +579,8 @@ void vp9_setup_past_independence(VP9_COMMON *cm, MACROBLOCKD *xd) { vpx_memset(cm->last_frame_seg_map, 0, (cm->mi_rows * cm->mi_cols)); // Reset the mode ref deltas for loop filter - vp9_zero(xd->last_ref_lf_deltas); - vp9_zero(xd->last_mode_lf_deltas); + vp9_zero(xd->lf.last_ref_deltas); + vp9_zero(xd->lf.last_mode_deltas); set_default_lf_deltas(xd); vp9_default_coef_probs(cm); @@ -585,7 +589,7 @@ void vp9_setup_past_independence(VP9_COMMON *cm, MACROBLOCKD *xd) { vp9_init_mv_probs(cm); // To force update of the sharpness - cm->last_sharpness_level = -1; + xd->lf.last_sharpness_level = -1; vp9_init_mode_contexts(cm); diff --git a/vp9/common/vp9_entropymode.h b/vp9/common/vp9_entropymode.h index fa6722c8d..613657be7 100644 --- a/vp9/common/vp9_entropymode.h +++ b/vp9/common/vp9_entropymode.h @@ -26,7 +26,7 @@ struct VP9Common; struct tx_probs { vp9_prob p32x32[TX_SIZE_CONTEXTS][TX_SIZE_MAX_SB - 1]; vp9_prob p16x16[TX_SIZE_CONTEXTS][TX_SIZE_MAX_SB - 2]; - vp9_prob p8x8[TX_SIZE_CONTEXTS][TX_SIZE_MAX_SB - 2]; + vp9_prob p8x8[TX_SIZE_CONTEXTS][TX_SIZE_MAX_SB - 3]; }; struct tx_counts { @@ -40,10 +40,10 @@ extern const vp9_prob vp9_kf_y_mode_prob[VP9_INTRA_MODES][VP9_INTRA_MODES] [VP9_INTRA_MODES - 1]; extern const vp9_tree_index vp9_intra_mode_tree[]; -extern const vp9_tree_index vp9_sb_mv_ref_tree[]; +extern const vp9_tree_index vp9_inter_mode_tree[]; extern struct vp9_token vp9_intra_mode_encodings[VP9_INTRA_MODES]; -extern struct vp9_token vp9_sb_mv_ref_encoding_array[VP9_INTER_MODES]; +extern struct vp9_token vp9_inter_mode_encodings[VP9_INTER_MODES]; // probability models for partition information extern const vp9_tree_index vp9_partition_tree[]; diff --git a/vp9/common/vp9_entropymv.c b/vp9/common/vp9_entropymv.c index c4bdb6b7e..a03862bb1 100644 --- a/vp9/common/vp9_entropymv.c +++ b/vp9/common/vp9_entropymv.c @@ -222,8 +222,10 @@ static unsigned int adapt_probs(unsigned int i, void vp9_adapt_mv_probs(VP9_COMMON *cm, int usehp) { int i, j; + FRAME_CONTEXT *pre_fc = &cm->frame_contexts[cm->frame_context_idx]; + nmv_context *ctx = &cm->fc.nmvc; - nmv_context *pre_ctx = &cm->fc.pre_nmvc; + nmv_context *pre_ctx = &pre_fc->nmvc; nmv_context_counts *cts = &cm->fc.NMVcount; vp9_counts_process(cts, usehp); diff --git a/vp9/common/vp9_loopfilter.c b/vp9/common/vp9_loopfilter.c index eea2eea6c..f0c0e3987 100644 --- a/vp9/common/vp9_loopfilter.c +++ b/vp9/common/vp9_loopfilter.c @@ -55,13 +55,13 @@ static void update_sharpness(loop_filter_info_n *const lfi, int sharpness_lvl) { } } -void vp9_loop_filter_init(VP9_COMMON *cm) { +void vp9_loop_filter_init(VP9_COMMON *cm, struct loopfilter *lf) { loop_filter_info_n *lfi = &cm->lf_info; int i; // init limits for given sharpness - update_sharpness(lfi, cm->sharpness_level); - cm->last_sharpness_level = cm->sharpness_level; + update_sharpness(lfi, lf->sharpness_level); + lf->last_sharpness_level = lf->sharpness_level; // init LUT for lvl and hev thr picking lf_init_lut(lfi); @@ -79,11 +79,12 @@ static void loop_filter_frame_init(VP9_COMMON *const cm, MACROBLOCKD *const xd, // 2 when filter_lvl is between 32 and 63 const int n_shift = default_filt_lvl >> 5; loop_filter_info_n *const lfi = &cm->lf_info; + struct loopfilter *lf = &xd->lf; // update limits if sharpness has changed - if (cm->last_sharpness_level != cm->sharpness_level) { - update_sharpness(lfi, cm->sharpness_level); - cm->last_sharpness_level = cm->sharpness_level; + if (lf->last_sharpness_level != lf->sharpness_level) { + update_sharpness(lfi, lf->sharpness_level); + lf->last_sharpness_level = lf->sharpness_level; } for (seg = 0; seg < MAX_MB_SEGMENTS; seg++) { @@ -97,20 +98,20 @@ static void loop_filter_frame_init(VP9_COMMON *const cm, MACROBLOCKD *const xd, : clamp(default_filt_lvl + data, 0, MAX_LOOP_FILTER); } - if (!xd->mode_ref_lf_delta_enabled) { + if (!lf->mode_ref_delta_enabled) { // we could get rid of this if we assume that deltas are set to // zero when not in use; encoder always uses deltas vpx_memset(lfi->lvl[seg][0], lvl_seg, 4 * 4); continue; } - intra_lvl = lvl_seg + (xd->ref_lf_deltas[INTRA_FRAME] << n_shift); + intra_lvl = lvl_seg + (lf->ref_deltas[INTRA_FRAME] << n_shift); lfi->lvl[seg][INTRA_FRAME][0] = clamp(intra_lvl, 0, MAX_LOOP_FILTER); for (ref = LAST_FRAME; ref < MAX_REF_FRAMES; ++ref) for (mode = 0; mode < MAX_MODE_LF_DELTAS; ++mode) { - const int inter_lvl = lvl_seg + (xd->ref_lf_deltas[ref] << n_shift) - + (xd->mode_lf_deltas[mode] << n_shift); + const int inter_lvl = lvl_seg + (lf->ref_deltas[ref] << n_shift) + + (lf->mode_deltas[mode] << n_shift); lfi->lvl[seg][ref][mode] = clamp(inter_lvl, 0, MAX_LOOP_FILTER); } } diff --git a/vp9/common/vp9_loopfilter.h b/vp9/common/vp9_loopfilter.h index 9620a5269..cbe52c22c 100644 --- a/vp9/common/vp9_loopfilter.h +++ b/vp9/common/vp9_loopfilter.h @@ -46,7 +46,7 @@ struct loop_filter_info { struct VP9Common; struct macroblockd; -void vp9_loop_filter_init(struct VP9Common *cm); +void vp9_loop_filter_init(struct VP9Common *cm, struct loopfilter *lf); void vp9_loop_filter_frame(struct VP9Common *cm, struct macroblockd *mbd, diff --git a/vp9/common/vp9_onyx.h b/vp9/common/vp9_onyx.h index d266c1567..fe8122b46 100644 --- a/vp9/common/vp9_onyx.h +++ b/vp9/common/vp9_onyx.h @@ -64,34 +64,6 @@ extern "C" FRAMEFLAGS_ALTREF = 4, } FRAMETYPE_FLAGS; - -#include <assert.h> - static INLINE void Scale2Ratio(int mode, int *hr, int *hs) { - switch (mode) { - case NORMAL: - *hr = 1; - *hs = 1; - break; - case FOURFIVE: - *hr = 4; - *hs = 5; - break; - case THREEFIVE: - *hr = 3; - *hs = 5; - break; - case ONETWO: - *hr = 1; - *hs = 2; - break; - default: - *hr = 1; - *hs = 1; - assert(0); - break; - } - } - typedef struct { int version; // 4 versions of bitstream defined: // 0 - best quality/slowest decode, diff --git a/vp9/common/vp9_onyxc_int.h b/vp9/common/vp9_onyxc_int.h index b237f1f9d..7239bf0a2 100644 --- a/vp9/common/vp9_onyxc_int.h +++ b/vp9/common/vp9_onyxc_int.h @@ -43,16 +43,13 @@ typedef struct frame_contexts { vp9_prob uv_mode_prob[VP9_INTRA_MODES][VP9_INTRA_MODES - 1]; vp9_prob partition_prob[NUM_FRAME_TYPES][NUM_PARTITION_CONTEXTS] [PARTITION_TYPES - 1]; - vp9_prob pre_y_mode_prob[BLOCK_SIZE_GROUPS][VP9_INTRA_MODES - 1]; - vp9_prob pre_uv_mode_prob[VP9_INTRA_MODES][VP9_INTRA_MODES - 1]; - vp9_prob pre_partition_prob[NUM_PARTITION_CONTEXTS][PARTITION_TYPES - 1]; + unsigned int y_mode_counts[BLOCK_SIZE_GROUPS][VP9_INTRA_MODES]; unsigned int uv_mode_counts[VP9_INTRA_MODES][VP9_INTRA_MODES]; unsigned int partition_counts[NUM_PARTITION_CONTEXTS][PARTITION_TYPES]; // coeff vp9_coeff_probs_model coef_probs[TX_SIZE_MAX_SB][BLOCK_TYPES]; - vp9_coeff_probs_model pre_coef_probs[TX_SIZE_MAX_SB][BLOCK_TYPES]; vp9_coeff_count_model coef_counts[TX_SIZE_MAX_SB][BLOCK_TYPES]; unsigned int eob_branch_counts[TX_SIZE_MAX_SB][BLOCK_TYPES][REF_TYPES] [COEF_BANDS][PREV_COEF_CONTEXTS]; @@ -60,13 +57,10 @@ typedef struct frame_contexts { // switchable_interp vp9_prob switchable_interp_prob[VP9_SWITCHABLE_FILTERS + 1] [VP9_SWITCHABLE_FILTERS - 1]; - vp9_prob pre_switchable_interp_prob[VP9_SWITCHABLE_FILTERS + 1] - [VP9_SWITCHABLE_FILTERS - 1]; unsigned int switchable_interp_count[VP9_SWITCHABLE_FILTERS + 1] [VP9_SWITCHABLE_FILTERS]; // inter_mode vp9_prob inter_mode_probs[INTER_MODE_CONTEXTS][VP9_INTER_MODES - 1]; - vp9_prob pre_inter_mode_probs[INTER_MODE_CONTEXTS][VP9_INTER_MODES - 1]; unsigned int inter_mode_counts[INTER_MODE_CONTEXTS][VP9_INTER_MODES - 1][2]; // intra_inter, comp_inter, single_ref, comp_ref @@ -74,10 +68,7 @@ typedef struct frame_contexts { vp9_prob comp_inter_prob[COMP_INTER_CONTEXTS]; vp9_prob single_ref_prob[REF_CONTEXTS][2]; vp9_prob comp_ref_prob[REF_CONTEXTS]; - vp9_prob pre_intra_inter_prob[INTRA_INTER_CONTEXTS]; - vp9_prob pre_comp_inter_prob[COMP_INTER_CONTEXTS]; - vp9_prob pre_single_ref_prob[REF_CONTEXTS][2]; - vp9_prob pre_comp_ref_prob[REF_CONTEXTS]; + unsigned int intra_inter_count[INTRA_INTER_CONTEXTS][2]; unsigned int comp_inter_count[COMP_INTER_CONTEXTS][2]; unsigned int single_ref_count[REF_CONTEXTS][2][2]; @@ -85,17 +76,14 @@ typedef struct frame_contexts { // tx_probs struct tx_probs tx_probs; - struct tx_probs pre_tx_probs; struct tx_counts tx_counts; // mbskip vp9_prob mbskip_probs[MBSKIP_CONTEXTS]; - vp9_prob pre_mbskip_probs[MBSKIP_CONTEXTS]; unsigned int mbskip_count[MBSKIP_CONTEXTS][2]; // mv nmv_context nmvc; - nmv_context pre_nmvc; nmv_context_counts NMVcount; } FRAME_CONTEXT; @@ -202,10 +190,6 @@ typedef struct VP9Common { loop_filter_info_n lf_info; - int filter_level; - int last_sharpness_level; - int sharpness_level; - int refresh_frame_context; /* Two state 0 = NO, 1 = YES */ int ref_frame_sign_bias[MAX_REF_FRAMES]; /* Two state 0, 1 */ diff --git a/vp9/common/vp9_postproc.c b/vp9/common/vp9_postproc.c index 840d922fd..1157fbbed 100644 --- a/vp9/common/vp9_postproc.c +++ b/vp9/common/vp9_postproc.c @@ -630,9 +630,11 @@ static void constrain_line(int x0, int *x1, int y0, int *y1, } } -int vp9_post_proc_frame(VP9_COMMON *oci, YV12_BUFFER_CONFIG *dest, +int vp9_post_proc_frame(struct VP9Common *oci, + struct loopfilter *lf, + YV12_BUFFER_CONFIG *dest, vp9_ppflags_t *ppflags) { - int q = oci->filter_level * 10 / 6; + int q = lf->filter_level * 10 / 6; int flags = ppflags->post_proc_flag; int deblock_level = ppflags->deblocking_level; int noise_level = ppflags->noise_level; diff --git a/vp9/common/vp9_postproc.h b/vp9/common/vp9_postproc.h index 2c0d333b6..a814e39cc 100644 --- a/vp9/common/vp9_postproc.h +++ b/vp9/common/vp9_postproc.h @@ -26,8 +26,8 @@ struct postproc_state { #include "vp9/common/vp9_onyxc_int.h" #include "vp9/common/vp9_ppflags.h" -int vp9_post_proc_frame(struct VP9Common *oci, YV12_BUFFER_CONFIG *dest, - vp9_ppflags_t *flags); +int vp9_post_proc_frame(struct VP9Common *oci, struct loopfilter *lf, + YV12_BUFFER_CONFIG *dest, vp9_ppflags_t *flags); void vp9_denoise(const YV12_BUFFER_CONFIG *src, YV12_BUFFER_CONFIG *dst, int q); diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c index aaef9d66a..6660f5b8e 100644 --- a/vp9/decoder/vp9_decodemv.c +++ b/vp9/decoder/vp9_decodemv.c @@ -31,7 +31,7 @@ static MB_PREDICTION_MODE read_intra_mode(vp9_reader *r, const vp9_prob *p) { } 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); + return (MB_PREDICTION_MODE)treed_read(r, vp9_inter_mode_tree, p); } static int read_segment_id(vp9_reader *r, const struct segmentation *seg) { diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c index 40308c8e0..3d11a2297 100644 --- a/vp9/decoder/vp9_decodframe.c +++ b/vp9/decoder/vp9_decodframe.c @@ -438,30 +438,29 @@ static void setup_segmentation(struct segmentation *seg, } } -static void setup_loopfilter(VP9D_COMP *pbi, struct vp9_read_bit_buffer *rb) { - VP9_COMMON *const cm = &pbi->common; - MACROBLOCKD *const xd = &pbi->mb; +static void setup_loopfilter(struct loopfilter *lf, + struct vp9_read_bit_buffer *rb) { - cm->filter_level = vp9_rb_read_literal(rb, 6); - cm->sharpness_level = vp9_rb_read_literal(rb, 3); + lf->filter_level = vp9_rb_read_literal(rb, 6); + lf->sharpness_level = vp9_rb_read_literal(rb, 3); // Read in loop filter deltas applied at the MB level based on mode or ref // frame. - xd->mode_ref_lf_delta_update = 0; + lf->mode_ref_delta_update = 0; - xd->mode_ref_lf_delta_enabled = vp9_rb_read_bit(rb); - if (xd->mode_ref_lf_delta_enabled) { - xd->mode_ref_lf_delta_update = vp9_rb_read_bit(rb); - if (xd->mode_ref_lf_delta_update) { + lf->mode_ref_delta_enabled = vp9_rb_read_bit(rb); + if (lf->mode_ref_delta_enabled) { + lf->mode_ref_delta_update = vp9_rb_read_bit(rb); + if (lf->mode_ref_delta_update) { int i; for (i = 0; i < MAX_REF_LF_DELTAS; i++) if (vp9_rb_read_bit(rb)) - xd->ref_lf_deltas[i] = vp9_rb_read_signed_literal(rb, 6); + lf->ref_deltas[i] = vp9_rb_read_signed_literal(rb, 6); for (i = 0; i < MAX_MODE_LF_DELTAS; i++) if (vp9_rb_read_bit(rb)) - xd->mode_lf_deltas[i] = vp9_rb_read_signed_literal(rb, 6); + lf->mode_deltas[i] = vp9_rb_read_signed_literal(rb, 6); } } } @@ -583,21 +582,7 @@ static void setup_frame_size_with_refs(VP9D_COMP *pbi, apply_frame_size(pbi, width, height); } -static void update_frame_context(FRAME_CONTEXT *fc) { - vp9_copy(fc->pre_coef_probs, fc->coef_probs); - vp9_copy(fc->pre_y_mode_prob, fc->y_mode_prob); - vp9_copy(fc->pre_uv_mode_prob, fc->uv_mode_prob); - vp9_copy(fc->pre_partition_prob, fc->partition_prob[1]); - vp9_copy(fc->pre_intra_inter_prob, fc->intra_inter_prob); - vp9_copy(fc->pre_comp_inter_prob, fc->comp_inter_prob); - vp9_copy(fc->pre_single_ref_prob, fc->single_ref_prob); - vp9_copy(fc->pre_comp_ref_prob, fc->comp_ref_prob); - fc->pre_nmvc = fc->nmvc; - vp9_copy(fc->pre_switchable_interp_prob, fc->switchable_interp_prob); - vp9_copy(fc->pre_inter_mode_probs, fc->inter_mode_probs); - fc->pre_tx_probs = fc->tx_probs; - vp9_copy(fc->pre_mbskip_probs, fc->mbskip_probs); - +static void zero_counts(FRAME_CONTEXT *fc) { vp9_zero(fc->coef_counts); vp9_zero(fc->eob_branch_counts); vp9_zero(fc->y_mode_counts); @@ -645,12 +630,11 @@ static void setup_tile_info(VP9_COMMON *cm, struct vp9_read_bit_buffer *rb) { cm->log2_tile_rows += vp9_rb_read_bit(rb); } -static void decode_tiles(VP9D_COMP *pbi, - const uint8_t *data, size_t first_partition_size, - vp9_reader *residual_bc) { +static const uint8_t *decode_tiles(VP9D_COMP *pbi, const uint8_t *data) { + vp9_reader residual_bc; + VP9_COMMON *const pc = &pbi->common; - const uint8_t *data_ptr = data + first_partition_size; const uint8_t *const data_end = pbi->source + pbi->source_sz; const int aligned_mi_cols = mi_cols_aligned_to_sb(pc->mi_cols); const int tile_cols = 1 << pc->log2_tile_cols; @@ -670,7 +654,7 @@ static void decode_tiles(VP9D_COMP *pbi, vp9_reader bc_bak = {0}; // pre-initialize the offsets, we're going to read in inverse order - data_ptr2[0][0] = data_ptr; + data_ptr2[0][0] = data; for (tile_row = 0; tile_row < tile_rows; tile_row++) { if (tile_row) { const int size = read_be32(data_ptr2[tile_row - 1][tile_cols - 1]); @@ -692,13 +676,13 @@ static void decode_tiles(VP9D_COMP *pbi, vp9_get_tile_col_offsets(pc, tile_col); setup_token_decoder(pbi, data_ptr2[tile_row][tile_col], data_end - data_ptr2[tile_row][tile_col], - residual_bc); - decode_tile(pbi, residual_bc); + &residual_bc); + decode_tile(pbi, &residual_bc); if (tile_row == tile_rows - 1 && tile_col == tile_cols - 1) - bc_bak = *residual_bc; + bc_bak = residual_bc; } } - *residual_bc = bc_bak; + residual_bc = bc_bak; } else { int has_more; @@ -711,22 +695,24 @@ static void decode_tiles(VP9D_COMP *pbi, has_more = tile_col < tile_cols - 1 || tile_row < tile_rows - 1; if (has_more) { - if (!read_is_valid(data_ptr, 4, data_end)) + if (!read_is_valid(data, 4, data_end)) vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, "Truncated packet or corrupt tile length"); - size = read_be32(data_ptr); - data_ptr += 4; + size = read_be32(data); + data += 4; } else { - size = data_end - data_ptr; + size = data_end - data; } - setup_token_decoder(pbi, data_ptr, size, residual_bc); - decode_tile(pbi, residual_bc); - data_ptr += size; + setup_token_decoder(pbi, data, size, &residual_bc); + decode_tile(pbi, &residual_bc); + data += size; } } } + + return vp9_reader_find_end(&residual_bc); } static void check_sync_code(VP9_COMMON *cm, struct vp9_read_bit_buffer *rb) { @@ -796,7 +782,7 @@ static size_t read_uncompressed_header(VP9D_COMP *pbi, int frame_to_show = cm->ref_frame_map[vp9_rb_read_literal(rb, 3)]; ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->new_fb_idx, frame_to_show); pbi->refresh_frame_flags = 0; - cm->filter_level = 0; + xd->lf.filter_level = 0; return 0; } @@ -880,9 +866,9 @@ static size_t read_uncompressed_header(VP9D_COMP *pbi, if (cm->frame_type == KEY_FRAME || cm->error_resilient_mode || cm->intra_only) vp9_setup_past_independence(cm, xd); - setup_loopfilter(pbi, rb); + setup_loopfilter(&xd->lf, rb); setup_quantization(pbi, rb); - setup_segmentation(&pbi->mb.seg, rb); + setup_segmentation(&xd->seg, rb); setup_tile_info(cm, rb); @@ -923,7 +909,6 @@ void vp9_init_dequantizer(VP9_COMMON *cm) { int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) { int i; - vp9_reader residual_bc; VP9_COMMON *const pc = &pbi->common; MACROBLOCKD *const xd = &pbi->mb; @@ -954,7 +939,6 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) { xd->mode_info_context = pc->mi; xd->prev_mode_info_context = pc->prev_mi; - xd->frame_type = pc->frame_type; xd->mode_info_stride = pc->mode_info_stride; init_dequantizer(pc, &pbi->mb); @@ -964,7 +948,7 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) { pc->fc = pc->frame_contexts[pc->frame_context_idx]; - update_frame_context(&pc->fc); + zero_counts(&pc->fc); // Initialize xd pointers. Any reference should do for xd->pre, so use 0. setup_pre_planes(xd, 0, &pc->yv12_fb[pc->active_ref_idx[0]], 0, 0, NULL); @@ -985,7 +969,7 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) { set_prev_mi(pc); - decode_tiles(pbi, data, first_partition_size, &residual_bc); + *p_data_end = decode_tiles(pbi, data + first_partition_size); pc->last_width = pc->width; pc->last_height = pc->height; @@ -1013,6 +997,5 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) { if (pc->refresh_frame_context) pc->frame_contexts[pc->frame_context_idx] = pc->fc; - *p_data_end = vp9_reader_find_end(&residual_bc); return 0; } diff --git a/vp9/decoder/vp9_onyxd_if.c b/vp9/decoder/vp9_onyxd_if.c index d1f081ed4..095485c22 100644 --- a/vp9/decoder/vp9_onyxd_if.c +++ b/vp9/decoder/vp9_onyxd_if.c @@ -136,7 +136,7 @@ VP9D_PTR vp9_create_decompressor(VP9D_CONFIG *oxcf) { // vp9_init_dequantizer() for every frame. vp9_init_dequantizer(&pbi->common); - vp9_loop_filter_init(&pbi->common); + vp9_loop_filter_init(&pbi->common, &pbi->mb.lf); pbi->common.error.setjmp = 0; pbi->decoded_key_frame = 0; @@ -346,9 +346,9 @@ int vp9_receive_compressed_data(VP9D_PTR ptr, cm->current_video_frame + 1000); #endif - if (cm->filter_level) { + if (pbi->mb.lf.filter_level) { /* Apply the loop filter if appropriate. */ - vp9_loop_filter_frame(cm, &pbi->mb, cm->filter_level, 0); + vp9_loop_filter_frame(cm, &pbi->mb, pbi->mb.lf.filter_level, 0); } #if WRITE_RECON_BUFFER == 2 @@ -413,7 +413,7 @@ int vp9_get_raw_frame(VP9D_PTR ptr, YV12_BUFFER_CONFIG *sd, *time_end_stamp = 0; #if CONFIG_POSTPROC - ret = vp9_post_proc_frame(&pbi->common, sd, flags); + ret = vp9_post_proc_frame(&pbi->common, &pbi->mb.lf, sd, flags); #else if (pbi->common.frame_to_show) { diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index 4e9fe440c..07cb2b83e 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -350,8 +350,8 @@ static void pack_mb_tokens(vp9_writer* const bc, static void write_sb_mv_ref(vp9_writer *w, MB_PREDICTION_MODE mode, const vp9_prob *p) { assert(is_inter_mode(mode)); - write_token(w, vp9_sb_mv_ref_tree, p, - &vp9_sb_mv_ref_encoding_array[mode - NEARESTMV]); + write_token(w, vp9_inter_mode_tree, p, + &vp9_inter_mode_encodings[mode - NEARESTMV]); } @@ -925,29 +925,29 @@ static void update_coef_probs(VP9_COMP* const cpi, vp9_writer* const bc) { update_coef_probs_common(bc, cpi, TX_32X32); } -static void encode_loopfilter(VP9_COMMON *pc, MACROBLOCKD *xd, +static void encode_loopfilter(struct loopfilter *lf, struct vp9_write_bit_buffer *wb) { int i; // Encode the loop filter level and type - vp9_wb_write_literal(wb, pc->filter_level, 6); - vp9_wb_write_literal(wb, pc->sharpness_level, 3); + vp9_wb_write_literal(wb, lf->filter_level, 6); + vp9_wb_write_literal(wb, lf->sharpness_level, 3); // Write out loop filter deltas applied at the MB level based on mode or // ref frame (if they are enabled). - vp9_wb_write_bit(wb, xd->mode_ref_lf_delta_enabled); + vp9_wb_write_bit(wb, lf->mode_ref_delta_enabled); - if (xd->mode_ref_lf_delta_enabled) { + if (lf->mode_ref_delta_enabled) { // Do the deltas need to be updated - vp9_wb_write_bit(wb, xd->mode_ref_lf_delta_update); - if (xd->mode_ref_lf_delta_update) { + vp9_wb_write_bit(wb, lf->mode_ref_delta_update); + if (lf->mode_ref_delta_update) { // Send update for (i = 0; i < MAX_REF_LF_DELTAS; i++) { - const int delta = xd->ref_lf_deltas[i]; + const int delta = lf->ref_deltas[i]; // Frame level data - if (delta != xd->last_ref_lf_deltas[i]) { - xd->last_ref_lf_deltas[i] = delta; + if (delta != lf->last_ref_deltas[i]) { + lf->last_ref_deltas[i] = delta; vp9_wb_write_bit(wb, 1); assert(delta != 0); @@ -960,9 +960,9 @@ static void encode_loopfilter(VP9_COMMON *pc, MACROBLOCKD *xd, // Send update for (i = 0; i < MAX_MODE_LF_DELTAS; i++) { - const int delta = xd->mode_lf_deltas[i]; - if (delta != xd->last_mode_lf_deltas[i]) { - xd->last_mode_lf_deltas[i] = delta; + const int delta = lf->mode_deltas[i]; + if (delta != lf->last_mode_deltas[i]) { + lf->last_mode_deltas[i] = delta; vp9_wb_write_bit(wb, 1); assert(delta != 0); @@ -1372,7 +1372,7 @@ static void write_uncompressed_header(VP9_COMP *cpi, vp9_wb_write_literal(wb, cm->frame_context_idx, NUM_FRAME_CONTEXTS_LOG2); - encode_loopfilter(cm, xd, wb); + encode_loopfilter(&xd->lf, wb); encode_quantization(cm, wb); encode_segmentation(cpi, wb); @@ -1471,7 +1471,6 @@ static size_t write_compressed_header(VP9_COMP *cpi, uint8_t *data) { } void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) { - FRAME_CONTEXT *const fc = &cpi->common.fc; uint8_t *data = dest; size_t first_part_size; struct vp9_write_bit_buffer wb = {data, 0}; @@ -1494,20 +1493,6 @@ void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) { vp9_clear_system_state(); // __asm emms; - vp9_copy(fc->pre_coef_probs, fc->coef_probs); - vp9_copy(fc->pre_y_mode_prob, fc->y_mode_prob); - vp9_copy(fc->pre_uv_mode_prob, fc->uv_mode_prob); - vp9_copy(fc->pre_partition_prob, fc->partition_prob[INTER_FRAME]); - fc->pre_nmvc = fc->nmvc; - vp9_copy(fc->pre_switchable_interp_prob, fc->switchable_interp_prob); - vp9_copy(fc->pre_inter_mode_probs, fc->inter_mode_probs); - vp9_copy(fc->pre_intra_inter_prob, fc->intra_inter_prob); - vp9_copy(fc->pre_comp_inter_prob, fc->comp_inter_prob); - vp9_copy(fc->pre_comp_ref_prob, fc->comp_ref_prob); - vp9_copy(fc->pre_single_ref_prob, fc->single_ref_prob); - fc->pre_tx_probs = fc->tx_probs; - vp9_copy(fc->pre_mbskip_probs, fc->mbskip_probs); - first_part_size = write_compressed_header(cpi, data); data += first_part_size; vp9_wb_write_literal(&saved_wb, first_part_size, 16); diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index 503c6a829..2e7cb291d 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -1248,15 +1248,13 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO *m, TOKENEXTRA **tp, case PARTITION_NONE: pick_sb_modes(cpi, mi_row, mi_col, &last_part_rate, &last_part_dist, bsize, get_block_context(x, bsize), INT64_MAX); - set_partition_seg_context(cm, xd, mi_row, mi_col); - pl = partition_plane_context(xd, bsize); - last_part_rate += x->partition_cost[pl][PARTITION_NONE]; break; case PARTITION_HORZ: *(get_sb_index(xd, subsize)) = 0; pick_sb_modes(cpi, mi_row, mi_col, &last_part_rate, &last_part_dist, subsize, get_block_context(x, subsize), INT64_MAX); - if (bsize >= BLOCK_SIZE_SB8X8 && mi_row + (mh >> 1) < cm->mi_rows) { + if (last_part_rate != INT_MAX && + bsize >= BLOCK_SIZE_SB8X8 && mi_row + (mh >> 1) < cm->mi_rows) { int rt = 0; int64_t dt = 0; update_state(cpi, get_block_context(x, subsize), subsize, 0); @@ -1264,18 +1262,22 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO *m, TOKENEXTRA **tp, *(get_sb_index(xd, subsize)) = 1; pick_sb_modes(cpi, mi_row + (ms >> 1), mi_col, &rt, &dt, subsize, get_block_context(x, subsize), INT64_MAX); + if (rt == INT_MAX || dt == INT_MAX) { + last_part_rate = INT_MAX; + last_part_dist = INT_MAX; + break; + } + last_part_rate += rt; last_part_dist += dt; } - set_partition_seg_context(cm, xd, mi_row, mi_col); - pl = partition_plane_context(xd, bsize); - last_part_rate += x->partition_cost[pl][PARTITION_HORZ]; break; case PARTITION_VERT: *(get_sb_index(xd, subsize)) = 0; pick_sb_modes(cpi, mi_row, mi_col, &last_part_rate, &last_part_dist, subsize, get_block_context(x, subsize), INT64_MAX); - if (bsize >= BLOCK_SIZE_SB8X8 && mi_col + (ms >> 1) < cm->mi_cols) { + if (last_part_rate != INT_MAX && + bsize >= BLOCK_SIZE_SB8X8 && mi_col + (ms >> 1) < cm->mi_cols) { int rt = 0; int64_t dt = 0; update_state(cpi, get_block_context(x, subsize), subsize, 0); @@ -1283,12 +1285,14 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO *m, TOKENEXTRA **tp, *(get_sb_index(xd, subsize)) = 1; pick_sb_modes(cpi, mi_row, mi_col + (ms >> 1), &rt, &dt, subsize, get_block_context(x, subsize), INT64_MAX); + if (rt == INT_MAX || dt == INT_MAX) { + last_part_rate = INT_MAX; + last_part_dist = INT_MAX; + break; + } last_part_rate += rt; last_part_dist += dt; } - set_partition_seg_context(cm, xd, mi_row, mi_col); - pl = partition_plane_context(xd, bsize); - last_part_rate += x->partition_cost[pl][PARTITION_VERT]; break; case PARTITION_SPLIT: // Split partition. @@ -1308,16 +1312,23 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO *m, TOKENEXTRA **tp, rd_use_partition(cpi, m + jj * bss * mis + ii * bss, tp, mi_row + y_idx, mi_col + x_idx, subsize, &rt, &dt, i != 3); + if (rt == INT_MAX || dt == INT_MAX) { + last_part_rate = INT_MAX; + last_part_dist = INT_MAX; + break; + } last_part_rate += rt; last_part_dist += dt; } - set_partition_seg_context(cm, xd, mi_row, mi_col); - pl = partition_plane_context(xd, bsize); - last_part_rate += x->partition_cost[pl][PARTITION_SPLIT]; break; default: assert(0); } + set_partition_seg_context(cm, xd, mi_row, mi_col); + pl = partition_plane_context(xd, bsize); + if (last_part_rate < INT_MAX) + last_part_rate += x->partition_cost[pl][partition]; + if (cpi->sf.adjust_partitioning_from_last_frame && partition != PARTITION_SPLIT && bsize > BLOCK_SIZE_SB8X8 && (mi_row + ms < cm->mi_rows || mi_row + (ms >> 1) == cm->mi_rows) @@ -1352,7 +1363,13 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO *m, TOKENEXTRA **tp, restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); - if (rt < INT_MAX && dt < INT_MAX && i != 3) + if (rt == INT_MAX || dt == INT_MAX) { + split_rate = INT_MAX; + split_dist = INT_MAX; + break; + } + + if (i != 3) encode_sb(cpi, tp, mi_row + y_idx, mi_col + x_idx, 0, split_subsize); @@ -1364,10 +1381,12 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO *m, TOKENEXTRA **tp, } set_partition_seg_context(cm, xd, mi_row, mi_col); pl = partition_plane_context(xd, bsize); - split_rate += x->partition_cost[pl][PARTITION_SPLIT]; + if (split_rate < INT_MAX) { + split_rate += x->partition_cost[pl][PARTITION_SPLIT]; - chosen_rate = split_rate; - chosen_dist = split_dist; + chosen_rate = split_rate; + chosen_dist = split_dist; + } } // If last_part is better set the partitioning to that... @@ -1392,10 +1411,12 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO *m, TOKENEXTRA **tp, // We must have chosen a partitioning and encoding or we'll fail later on. // No other opportunities for success. - assert(chosen_rate < INT_MAX && chosen_dist < INT_MAX); + if ( bsize == BLOCK_SIZE_SB64X64) + assert(chosen_rate < INT_MAX && chosen_dist < INT_MAX); if (do_recon) encode_sb(cpi, tp, mi_row, mi_col, bsize == BLOCK_SIZE_SB64X64, bsize); + *rate = chosen_rate; *dist = chosen_dist; } @@ -1907,7 +1928,6 @@ static void init_encode_frame_mb_context(VP9_COMP *cpi) { cpi->seg0_idx = 0; xd->mode_info_stride = cm->mode_info_stride; - xd->frame_type = cm->frame_type; // reset intra mode contexts if (cm->frame_type == KEY_FRAME) @@ -1953,7 +1973,7 @@ static void switch_lossless_mode(VP9_COMP *cpi, int lossless) { cpi->mb.e_mbd.inv_txm4x4_1_add = vp9_short_iwalsh4x4_1_add; cpi->mb.e_mbd.inv_txm4x4_add = vp9_short_iwalsh4x4_add; cpi->mb.optimize = 0; - cpi->common.filter_level = 0; + cpi->mb.e_mbd.lf.filter_level = 0; cpi->zbin_mode_boost_enabled = 0; cpi->common.tx_mode = ONLY_4X4; } else { diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index 2afcd27b1..88d9688ca 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -131,6 +131,32 @@ static int gf_low_motion_minq[QINDEX_RANGE]; static int gf_high_motion_minq[QINDEX_RANGE]; static int inter_minq[QINDEX_RANGE]; +static INLINE void Scale2Ratio(int mode, int *hr, int *hs) { + switch (mode) { + case NORMAL: + *hr = 1; + *hs = 1; + break; + case FOURFIVE: + *hr = 4; + *hs = 5; + break; + case THREEFIVE: + *hr = 3; + *hs = 5; + break; + case ONETWO: + *hr = 1; + *hs = 2; + break; + default: + *hr = 1; + *hs = 1; + assert(0); + break; + } +} + // Functions to compute the active minq lookup table entries based on a // formulaic approach to facilitate easier adjustment of the Q tables. // The formulae were derived from computing a 3rd order polynomial best @@ -217,6 +243,7 @@ void vp9_initialize_enc() { static void setup_features(VP9_COMP *cpi) { MACROBLOCKD *xd = &cpi->mb.e_mbd; + struct loopfilter *lf = &xd->lf; // Set up default state for MB feature flags xd->seg.enabled = 0; @@ -227,12 +254,12 @@ static void setup_features(VP9_COMP *cpi) { vp9_clearall_segfeatures(&xd->seg); - xd->mode_ref_lf_delta_enabled = 0; - xd->mode_ref_lf_delta_update = 0; - vpx_memset(xd->ref_lf_deltas, 0, sizeof(xd->ref_lf_deltas)); - vpx_memset(xd->mode_lf_deltas, 0, sizeof(xd->mode_lf_deltas)); - vpx_memset(xd->last_ref_lf_deltas, 0, sizeof(xd->ref_lf_deltas)); - vpx_memset(xd->last_mode_lf_deltas, 0, sizeof(xd->mode_lf_deltas)); + lf->mode_ref_delta_enabled = 0; + lf->mode_ref_delta_update = 0; + vp9_zero(lf->ref_deltas); + vp9_zero(lf->mode_deltas); + vp9_zero(lf->last_ref_deltas); + vp9_zero(lf->last_mode_deltas); set_default_lf_deltas(cpi); } @@ -518,20 +545,22 @@ static void update_reference_segmentation_map(VP9_COMP *cpi) { } static void set_default_lf_deltas(VP9_COMP *cpi) { - cpi->mb.e_mbd.mode_ref_lf_delta_enabled = 1; - cpi->mb.e_mbd.mode_ref_lf_delta_update = 1; + struct loopfilter *lf = &cpi->mb.e_mbd.lf; + + lf->mode_ref_delta_enabled = 1; + lf->mode_ref_delta_update = 1; - vpx_memset(cpi->mb.e_mbd.ref_lf_deltas, 0, sizeof(cpi->mb.e_mbd.ref_lf_deltas)); - vpx_memset(cpi->mb.e_mbd.mode_lf_deltas, 0, sizeof(cpi->mb.e_mbd.mode_lf_deltas)); + vp9_zero(lf->ref_deltas); + vp9_zero(lf->mode_deltas); // Test of ref frame deltas - cpi->mb.e_mbd.ref_lf_deltas[INTRA_FRAME] = 2; - cpi->mb.e_mbd.ref_lf_deltas[LAST_FRAME] = 0; - cpi->mb.e_mbd.ref_lf_deltas[GOLDEN_FRAME] = -2; - cpi->mb.e_mbd.ref_lf_deltas[ALTREF_FRAME] = -2; + lf->ref_deltas[INTRA_FRAME] = 2; + lf->ref_deltas[LAST_FRAME] = 0; + lf->ref_deltas[GOLDEN_FRAME] = -2; + lf->ref_deltas[ALTREF_FRAME] = -2; - cpi->mb.e_mbd.mode_lf_deltas[0] = 0; // Zero - cpi->mb.e_mbd.mode_lf_deltas[1] = 0; // New mv + lf->mode_deltas[0] = 0; // Zero + lf->mode_deltas[1] = 0; // New mv } static void set_rd_speed_thresholds(VP9_COMP *cpi, int mode, int speed) { @@ -543,60 +572,57 @@ static void set_rd_speed_thresholds(VP9_COMP *cpi, int mode, int speed) { for (i = 0; i < MAX_MODES; ++i) sf->thresh_mult[i] = mode == 0 ? -500 : 0; - sf->thresh_mult[THR_ZEROMV] = 0; - sf->thresh_mult[THR_ZEROG] = 0; - sf->thresh_mult[THR_ZEROA] = 0; - sf->thresh_mult[THR_NEARESTMV] = 0; sf->thresh_mult[THR_NEARESTG] = 0; sf->thresh_mult[THR_NEARESTA] = 0; + sf->thresh_mult[THR_NEWMV] += speed_multiplier * 1000; + sf->thresh_mult[THR_COMP_NEARESTLA] += speed_multiplier * 1000; sf->thresh_mult[THR_NEARMV] += speed_multiplier * 1000; - sf->thresh_mult[THR_NEARG] += speed_multiplier * 1000; - sf->thresh_mult[THR_NEARA] += speed_multiplier * 1000; + sf->thresh_mult[THR_COMP_NEARESTGA] += speed_multiplier * 1000; - sf->thresh_mult[THR_DC ] = 0; - sf->thresh_mult[THR_TM] += speed_multiplier * 1000; - sf->thresh_mult[THR_V_PRED ] += speed_multiplier * 1000; - sf->thresh_mult[THR_H_PRED ] += speed_multiplier * 1000; - sf->thresh_mult[THR_D45_PRED ] += speed_multiplier * 1500; - sf->thresh_mult[THR_D135_PRED] += speed_multiplier * 1500; - sf->thresh_mult[THR_D117_PRED] += speed_multiplier * 1500; - sf->thresh_mult[THR_D153_PRED] += speed_multiplier * 1500; - sf->thresh_mult[THR_D27_PRED ] += speed_multiplier * 1500; - sf->thresh_mult[THR_D63_PRED ] += speed_multiplier * 1500; - - sf->thresh_mult[THR_B_PRED ] += speed_multiplier * 2500; - - sf->thresh_mult[THR_NEWMV ] += speed_multiplier * 1000; - sf->thresh_mult[THR_NEWG ] += speed_multiplier * 1000; - sf->thresh_mult[THR_NEWA ] += speed_multiplier * 1000; + sf->thresh_mult[THR_DC] += speed_multiplier * 1000; - sf->thresh_mult[THR_SPLITMV ] += speed_multiplier * 2500; - sf->thresh_mult[THR_SPLITG ] += speed_multiplier * 2500; - sf->thresh_mult[THR_SPLITA ] += speed_multiplier * 2500; - - sf->thresh_mult[THR_COMP_ZEROLA] += speed_multiplier * 1500; - sf->thresh_mult[THR_COMP_ZEROGA] += speed_multiplier * 1500; + sf->thresh_mult[THR_NEWG] += speed_multiplier * 1000; + sf->thresh_mult[THR_NEWA] += speed_multiplier * 1000; + sf->thresh_mult[THR_NEARA] += speed_multiplier * 1000; - sf->thresh_mult[THR_COMP_NEARESTLA] += speed_multiplier * 1500; - sf->thresh_mult[THR_COMP_NEARESTGA] += speed_multiplier * 1500; + sf->thresh_mult[THR_TM] += speed_multiplier * 1000; sf->thresh_mult[THR_COMP_NEARLA] += speed_multiplier * 1500; + sf->thresh_mult[THR_COMP_NEWLA] += speed_multiplier * 2000; + sf->thresh_mult[THR_NEARG] += speed_multiplier * 1000; sf->thresh_mult[THR_COMP_NEARGA] += speed_multiplier * 1500; - - sf->thresh_mult[THR_COMP_NEWLA ] += speed_multiplier * 2000; - sf->thresh_mult[THR_COMP_NEWGA ] += speed_multiplier * 2000; - - sf->thresh_mult[THR_COMP_SPLITLA ] += speed_multiplier * 4500; - sf->thresh_mult[THR_COMP_SPLITGA ] += speed_multiplier * 4500; + sf->thresh_mult[THR_COMP_NEWGA] += speed_multiplier * 2000; + + sf->thresh_mult[THR_SPLITMV] += speed_multiplier * 2500; + sf->thresh_mult[THR_SPLITG] += speed_multiplier * 2500; + sf->thresh_mult[THR_SPLITA] += speed_multiplier * 2500; + sf->thresh_mult[THR_COMP_SPLITLA] += speed_multiplier * 4500; + sf->thresh_mult[THR_COMP_SPLITGA] += speed_multiplier * 4500; + + sf->thresh_mult[THR_ZEROMV] += speed_multiplier * 2000; + sf->thresh_mult[THR_ZEROG] += speed_multiplier * 2000; + sf->thresh_mult[THR_ZEROA] += speed_multiplier * 2000; + sf->thresh_mult[THR_COMP_ZEROLA] += speed_multiplier * 2500; + sf->thresh_mult[THR_COMP_ZEROGA] += speed_multiplier * 2500; + + sf->thresh_mult[THR_B_PRED] += speed_multiplier * 2500; + sf->thresh_mult[THR_H_PRED] += speed_multiplier * 2000; + sf->thresh_mult[THR_V_PRED] += speed_multiplier * 2000; + sf->thresh_mult[THR_D45_PRED ] += speed_multiplier * 2500; + sf->thresh_mult[THR_D135_PRED] += speed_multiplier * 2500; + sf->thresh_mult[THR_D117_PRED] += speed_multiplier * 2500; + sf->thresh_mult[THR_D153_PRED] += speed_multiplier * 2500; + sf->thresh_mult[THR_D27_PRED] += speed_multiplier * 2500; + sf->thresh_mult[THR_D63_PRED] += speed_multiplier * 2500; if (cpi->sf.skip_lots_of_modes) { for (i = 0; i < MAX_MODES; ++i) sf->thresh_mult[i] = INT_MAX; - sf->thresh_mult[THR_DC] = 0; - sf->thresh_mult[THR_TM] = 0; + sf->thresh_mult[THR_DC] = 2000; + sf->thresh_mult[THR_TM] = 2000; sf->thresh_mult[THR_NEWMV] = 4000; sf->thresh_mult[THR_NEWG] = 4000; sf->thresh_mult[THR_NEWA] = 4000; @@ -1259,7 +1285,7 @@ void vp9_change_config(VP9_PTR ptr, VP9_CONFIG *oxcf) { // VP8 sharpness level mapping 0-7 (vs 0-10 in general VPx dialogs) cpi->oxcf.Sharpness = MIN(7, cpi->oxcf.Sharpness); - cm->sharpness_level = cpi->oxcf.Sharpness; + cpi->mb.e_mbd.lf.sharpness_level = cpi->oxcf.Sharpness; if (cpi->initial_width) { // Increasing the size of the frame beyond the first seen frame, or some @@ -1662,7 +1688,7 @@ VP9_PTR vp9_create_compressor(VP9_CONFIG *oxcf) { */ vp9_init_quantizer(cpi); - vp9_loop_filter_init(cm); + vp9_loop_filter_init(cm, &cpi->mb.e_mbd.lf); cpi->common.error.setjmp = 0; @@ -2382,8 +2408,9 @@ static void update_reference_frames(VP9_COMP * const cpi) { } static void loopfilter_frame(VP9_COMP *cpi, VP9_COMMON *cm) { - if (cpi->mb.e_mbd.lossless) { - cm->filter_level = 0; + MACROBLOCKD *xd = &cpi->mb.e_mbd; + if (xd->lossless) { + xd->lf.filter_level = 0; } else { struct vpx_usec_timer timer; @@ -2397,14 +2424,13 @@ static void loopfilter_frame(VP9_COMP *cpi, VP9_COMMON *cm) { cpi->time_pick_lpf += vpx_usec_timer_elapsed(&timer); } - if (cm->filter_level > 0) { - vp9_set_alt_lf_level(cpi, cm->filter_level); - vp9_loop_filter_frame(cm, &cpi->mb.e_mbd, cm->filter_level, 0); + if (xd->lf.filter_level > 0) { + vp9_set_alt_lf_level(cpi, xd->lf.filter_level); + vp9_loop_filter_frame(cm, xd, xd->lf.filter_level, 0); } vp9_extend_frame_inner_borders(cm->frame_to_show, - cm->subsampling_x, cm->subsampling_y); - + cm->subsampling_x, cm->subsampling_y); } static void scale_references(VP9_COMP *cpi) { @@ -2559,7 +2585,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, } // Set default state for segment based loop filter update flags - xd->mode_ref_lf_delta_update = 0; + xd->lf.mode_ref_delta_update = 0; // Set various flags etc to special state if it is a key frame @@ -3412,7 +3438,7 @@ 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->seg.update_map = 0; xd->seg.update_data = 0; - xd->mode_ref_lf_delta_update = 0; + xd->lf.mode_ref_delta_update = 0; // keep track of the last coded dimensions cm->last_width = cm->width; @@ -3521,7 +3547,7 @@ static int frame_is_reference(const VP9_COMP *cpi) { cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame || cm->refresh_frame_context || - mb->mode_ref_lf_delta_update || + mb->lf.mode_ref_delta_update || mb->seg.update_map || mb->seg.update_data; } @@ -3852,7 +3878,7 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags, double weight = 0; #if CONFIG_POSTPROC vp9_deblock(cm->frame_to_show, &cm->post_proc_buffer, - cm->filter_level * 10 / 6); + cpi->mb.e_mbd.lf.filter_level * 10 / 6); #endif vp9_clear_system_state(); @@ -3927,7 +3953,7 @@ int vp9_get_preview_raw_frame(VP9_PTR comp, YV12_BUFFER_CONFIG *dest, else { int ret; #if CONFIG_POSTPROC - ret = vp9_post_proc_frame(&cpi->common, dest, flags); + ret = vp9_post_proc_frame(&cpi->common, &cpi->mb.e_mbd.lf, dest, flags); #else if (cpi->common.frame_to_show) { diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h index cb8748027..00d8684ed 100644 --- a/vp9/encoder/vp9_onyx_int.h +++ b/vp9/encoder/vp9_onyx_int.h @@ -145,53 +145,48 @@ typedef struct { // const MODE_DEFINITION vp9_mode_order[MAX_MODES] used in the rd code. typedef enum { THR_NEARESTMV, + THR_NEARESTA, + THR_NEARESTG, + THR_NEWMV, + THR_COMP_NEARESTLA, THR_NEARMV, + THR_COMP_NEARESTGA, - THR_ZEROMV, THR_DC, - THR_ZEROG, - THR_NEARESTG, - - THR_ZEROA, - THR_NEARESTA, - - THR_NEARG, + THR_NEWG, + THR_NEWA, THR_NEARA, - THR_V_PRED, - THR_H_PRED, - THR_D45_PRED, - THR_D135_PRED, - THR_D117_PRED, - THR_D153_PRED, - THR_D27_PRED, - THR_D63_PRED, THR_TM, - THR_NEWMV, - THR_NEWG, - THR_NEWA, + THR_COMP_NEARLA, + THR_COMP_NEWLA, + THR_NEARG, + THR_COMP_NEARGA, + THR_COMP_NEWGA, THR_SPLITMV, THR_SPLITG, THR_SPLITA, + THR_COMP_SPLITLA, + THR_COMP_SPLITGA, - THR_B_PRED, - + THR_ZEROMV, + THR_ZEROG, + THR_ZEROA, THR_COMP_ZEROLA, - THR_COMP_NEARESTLA, - THR_COMP_NEARLA, - THR_COMP_ZEROGA, - THR_COMP_NEARESTGA, - THR_COMP_NEARGA, - THR_COMP_NEWLA, - THR_COMP_NEWGA, - - THR_COMP_SPLITLA, - THR_COMP_SPLITGA, + THR_B_PRED, + THR_H_PRED, + THR_V_PRED, + THR_D135_PRED, + THR_D27_PRED, + THR_D153_PRED, + THR_D63_PRED, + THR_D117_PRED, + THR_D45_PRED, } THR_MODES; typedef enum { diff --git a/vp9/encoder/vp9_picklpf.c b/vp9/encoder/vp9_picklpf.c index 1d05839f5..2b8f2cd29 100644 --- a/vp9/encoder/vp9_picklpf.c +++ b/vp9/encoder/vp9_picklpf.c @@ -127,6 +127,7 @@ void vp9_set_alt_lf_level(VP9_COMP *cpi, int filt_val) { void vp9_pick_filter_level(YV12_BUFFER_CONFIG *sd, VP9_COMP *cpi) { VP9_COMMON *cm = &cpi->common; + struct loopfilter *lf = &cpi->mb.e_mbd.lf; int best_err = 0; int filt_err = 0; @@ -135,7 +136,8 @@ void vp9_pick_filter_level(YV12_BUFFER_CONFIG *sd, VP9_COMP *cpi) { int filter_step; int filt_high = 0; - int filt_mid = cm->filter_level; // Start search at previous frame filter level + // Start search at previous frame filter level + int filt_mid = lf->filter_level; int filt_low = 0; int filt_best; int filt_direction = 0; @@ -146,12 +148,12 @@ void vp9_pick_filter_level(YV12_BUFFER_CONFIG *sd, VP9_COMP *cpi) { vp8_yv12_copy_y(cm->frame_to_show, &cpi->last_frame_uf); if (cm->frame_type == KEY_FRAME) - cm->sharpness_level = 0; + lf->sharpness_level = 0; else - cm->sharpness_level = cpi->oxcf.Sharpness; + lf->sharpness_level = cpi->oxcf.Sharpness; // Start the search at the previous frame filter level unless it is now out of range. - filt_mid = cm->filter_level; + filt_mid = lf->filter_level; if (filt_mid < min_filter_level) filt_mid = min_filter_level; @@ -232,5 +234,5 @@ void vp9_pick_filter_level(YV12_BUFFER_CONFIG *sd, VP9_COMP *cpi) { } } - cm->filter_level = filt_best; + lf->filter_level = filt_best; } diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index da5a805b2..d3a9529a9 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -32,46 +32,8 @@ // Bits Per MB at different Q (Multiplied by 512) #define BPER_MB_NORMBITS 9 -// % adjustment to target kf size based on seperation from previous frame -static const int kf_boost_seperation_adjustment[16] = { - 30, 40, 50, 55, 60, 65, 70, 75, - 80, 85, 90, 95, 100, 100, 100, 100, -}; - -static const int gf_adjust_table[101] = { - 100, - 115, 130, 145, 160, 175, 190, 200, 210, 220, 230, - 240, 260, 270, 280, 290, 300, 310, 320, 330, 340, - 350, 360, 370, 380, 390, 400, 400, 400, 400, 400, - 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, - 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, - 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, - 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, - 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, - 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, - 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, -}; - -static const int gf_intra_usage_adjustment[20] = { - 125, 120, 115, 110, 105, 100, 95, 85, 80, 75, - 70, 65, 60, 55, 50, 50, 50, 50, 50, 50, -}; - -static const int gf_interval_table[101] = { - 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, -}; - -static const unsigned int prior_key_frame_weight[KEY_FRAME_CONTEXT] = { 1, 2, 3, 4, 5 }; +static const unsigned int prior_key_frame_weight[KEY_FRAME_CONTEXT] = + { 1, 2, 3, 4, 5 }; // These functions use formulaic calculations to make playing with the // quantizer tables easier. If necessary they can be replaced by lookup @@ -137,8 +99,8 @@ void vp9_save_coding_context(VP9_COMP *cpi) { vpx_memcpy(cpi->coding_context.last_frame_seg_map_copy, cm->last_frame_seg_map, (cm->mi_rows * cm->mi_cols)); - vp9_copy(cc->last_ref_lf_deltas, xd->last_ref_lf_deltas); - vp9_copy(cc->last_mode_lf_deltas, xd->last_mode_lf_deltas); + vp9_copy(cc->last_ref_lf_deltas, xd->lf.last_ref_deltas); + vp9_copy(cc->last_mode_lf_deltas, xd->lf.last_mode_deltas); vp9_copy(cc->coef_probs, cm->fc.coef_probs); vp9_copy(cc->switchable_interp_prob, cm->fc.switchable_interp_prob); @@ -176,8 +138,8 @@ void vp9_restore_coding_context(VP9_COMP *cpi) { cpi->coding_context.last_frame_seg_map_copy, (cm->mi_rows * cm->mi_cols)); - vp9_copy(xd->last_ref_lf_deltas, cc->last_ref_lf_deltas); - vp9_copy(xd->last_mode_lf_deltas, cc->last_mode_lf_deltas); + vp9_copy(xd->lf.last_ref_deltas, cc->last_ref_lf_deltas); + vp9_copy(xd->lf.last_mode_deltas, cc->last_mode_lf_deltas); vp9_copy(cm->fc.coef_probs, cc->coef_probs); vp9_copy(cm->fc.switchable_interp_prob, cc->switchable_interp_prob); diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index 69e45e800..775e10745 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -54,55 +54,48 @@ DECLARE_ALIGNED(16, extern const uint8_t, const MODE_DEFINITION vp9_mode_order[MAX_MODES] = { {NEARESTMV, LAST_FRAME, NONE}, + {NEARESTMV, ALTREF_FRAME, NONE}, + {NEARESTMV, GOLDEN_FRAME, NONE}, + {NEWMV, LAST_FRAME, NONE}, + {NEARESTMV, LAST_FRAME, ALTREF_FRAME}, {NEARMV, LAST_FRAME, NONE}, + {NEARESTMV, GOLDEN_FRAME, ALTREF_FRAME}, - {ZEROMV, LAST_FRAME, NONE}, {DC_PRED, INTRA_FRAME, NONE}, - {ZEROMV, GOLDEN_FRAME, NONE}, - {NEARESTMV, GOLDEN_FRAME, NONE}, - - {ZEROMV, ALTREF_FRAME, NONE}, - {NEARESTMV, ALTREF_FRAME, NONE}, - - {NEARMV, GOLDEN_FRAME, NONE}, + {NEWMV, GOLDEN_FRAME, NONE}, + {NEWMV, ALTREF_FRAME, NONE}, {NEARMV, ALTREF_FRAME, NONE}, - {V_PRED, INTRA_FRAME, NONE}, - {H_PRED, INTRA_FRAME, NONE}, - {D45_PRED, INTRA_FRAME, NONE}, - {D135_PRED, INTRA_FRAME, NONE}, - {D117_PRED, INTRA_FRAME, NONE}, - {D153_PRED, INTRA_FRAME, NONE}, - {D27_PRED, INTRA_FRAME, NONE}, - {D63_PRED, INTRA_FRAME, NONE}, - {TM_PRED, INTRA_FRAME, NONE}, - {NEWMV, LAST_FRAME, NONE}, - {NEWMV, GOLDEN_FRAME, NONE}, - {NEWMV, ALTREF_FRAME, NONE}, + {NEARMV, LAST_FRAME, ALTREF_FRAME}, + {NEWMV, LAST_FRAME, ALTREF_FRAME}, + {NEARMV, GOLDEN_FRAME, NONE}, + {NEARMV, GOLDEN_FRAME, ALTREF_FRAME}, + {NEWMV, GOLDEN_FRAME, ALTREF_FRAME}, {SPLITMV, LAST_FRAME, NONE}, {SPLITMV, GOLDEN_FRAME, NONE}, {SPLITMV, ALTREF_FRAME, NONE}, + {SPLITMV, LAST_FRAME, ALTREF_FRAME}, + {SPLITMV, GOLDEN_FRAME, ALTREF_FRAME}, - {I4X4_PRED, INTRA_FRAME, NONE}, - - /* compound prediction modes */ + {ZEROMV, LAST_FRAME, NONE}, + {ZEROMV, GOLDEN_FRAME, NONE}, + {ZEROMV, ALTREF_FRAME, NONE}, {ZEROMV, LAST_FRAME, ALTREF_FRAME}, - {NEARESTMV, LAST_FRAME, ALTREF_FRAME}, - {NEARMV, LAST_FRAME, ALTREF_FRAME}, - {ZEROMV, GOLDEN_FRAME, ALTREF_FRAME}, - {NEARESTMV, GOLDEN_FRAME, ALTREF_FRAME}, - {NEARMV, GOLDEN_FRAME, ALTREF_FRAME}, - {NEWMV, LAST_FRAME, ALTREF_FRAME}, - {NEWMV, GOLDEN_FRAME, ALTREF_FRAME}, - - {SPLITMV, LAST_FRAME, ALTREF_FRAME}, - {SPLITMV, GOLDEN_FRAME, ALTREF_FRAME}, + {I4X4_PRED, INTRA_FRAME, NONE}, + {H_PRED, INTRA_FRAME, NONE}, + {V_PRED, INTRA_FRAME, NONE}, + {D135_PRED, INTRA_FRAME, NONE}, + {D27_PRED, INTRA_FRAME, NONE}, + {D153_PRED, INTRA_FRAME, NONE}, + {D63_PRED, INTRA_FRAME, NONE}, + {D117_PRED, INTRA_FRAME, NONE}, + {D45_PRED, INTRA_FRAME, NONE}, }; // The baseline rd thresholds for breaking out of the rd loop for @@ -282,9 +275,9 @@ void vp9_initialize_rd_consts(VP9_COMP *cpi, int qindex) { for (m = NEARESTMV; m < MB_MODE_COUNT; m++) cpi->mb.inter_mode_cost[i][m - NEARESTMV] = - cost_token(vp9_sb_mv_ref_tree, + cost_token(vp9_inter_mode_tree, cpi->common.fc.inter_mode_probs[i], - vp9_sb_mv_ref_encoding_array - NEARESTMV + m); + vp9_inter_mode_encodings - NEARESTMV + m); } } } @@ -1346,7 +1339,7 @@ static int64_t rd_pick_intra4x4mby_modes(VP9_COMP *cpi, MACROBLOCK *mb, int64_t UNINITIALIZED_IS_SAFE(d); i = idy * 2 + idx; - if (xd->frame_type == KEY_FRAME) { + if (cpi->common.frame_type == KEY_FRAME) { const MB_PREDICTION_MODE A = above_block_mode(mic, i, mis); const MB_PREDICTION_MODE L = (xd->left_available || idx) ? left_block_mode(mic, i) : DC_PRED; @@ -1488,13 +1481,12 @@ static int64_t rd_pick_intra_sbuv_mode(VP9_COMP *cpi, MACROBLOCK *x, int64_t *distortion, int *skippable, BLOCK_SIZE_TYPE bsize) { MB_PREDICTION_MODE mode; - MB_PREDICTION_MODE last_mode; MB_PREDICTION_MODE UNINITIALIZED_IS_SAFE(mode_selected); int64_t best_rd = INT64_MAX, this_rd; int this_rate_tokenonly, this_rate, s; int64_t this_distortion; - last_mode = bsize <= BLOCK_SIZE_SB8X8 ? + MB_PREDICTION_MODE last_mode = bsize <= BLOCK_SIZE_SB8X8 ? TM_PRED : cpi->sf.last_chroma_intra_mode; for (mode = DC_PRED; mode <= last_mode; mode++) { @@ -1502,7 +1494,7 @@ static int64_t rd_pick_intra_sbuv_mode(VP9_COMP *cpi, MACROBLOCK *x, super_block_uvrd(&cpi->common, x, &this_rate_tokenonly, &this_distortion, &s, NULL, bsize); this_rate = this_rate_tokenonly + - x->intra_uv_mode_cost[x->e_mbd.frame_type][mode]; + x->intra_uv_mode_cost[cpi->common.frame_type][mode]; this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion); if (this_rd < best_rd) { @@ -1530,7 +1522,7 @@ static int64_t rd_sbuv_dcpred(VP9_COMP *cpi, MACROBLOCK *x, super_block_uvrd(&cpi->common, x, rate_tokenonly, distortion, skippable, NULL, bsize); *rate = *rate_tokenonly + - x->intra_uv_mode_cost[x->e_mbd.frame_type][DC_PRED]; + x->intra_uv_mode_cost[cpi->common.frame_type][DC_PRED]; this_rd = RDCOST(x->rdmult, x->rddiv, *rate, *distortion); x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED; @@ -1656,15 +1648,10 @@ static int labels2mode(MACROBLOCK *x, int i, mic->bmi[i].as_mv[1].as_int = this_second_mv->as_int; x->partition_info->bmi[i].mode = m; - for (idy = 0; idy < bh; ++idy) { - for (idx = 0; idx < bw; ++idx) { + for (idy = 0; idy < bh; ++idy) + for (idx = 0; idx < bw; ++idx) vpx_memcpy(&mic->bmi[i + idy * 2 + idx], &mic->bmi[i], sizeof(mic->bmi[i])); - vpx_memcpy(&x->partition_info->bmi[i + idy * 2 + idx], - &x->partition_info->bmi[i], - sizeof(x->partition_info->bmi[i])); - } - } cost += thismvcost; return cost; @@ -1761,6 +1748,18 @@ static int64_t encode_inter_mb_segment(VP9_COMP *cpi, } typedef struct { + int eobs; + int brate; + int byrate; + int64_t bdist; + int64_t bsse; + int64_t brdcost; + int_mv mvs[2]; + ENTROPY_CONTEXT ta[2]; + ENTROPY_CONTEXT tl[2]; +} SEG_RDSTAT; + +typedef struct { int_mv *ref_mv, *second_ref_mv; int_mv mvp; @@ -1770,8 +1769,7 @@ typedef struct { int64_t sse; int segment_yrate; MB_PREDICTION_MODE modes[4]; - int_mv mvs[4], second_mvs[4]; - int eobs[4]; + SEG_RDSTAT rdstat[4][VP9_INTER_MODES]; int mvthresh; } BEST_SEG_INFO; @@ -1812,11 +1810,11 @@ static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src, } static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x, - BEST_SEG_INFO *bsi, + BEST_SEG_INFO *bsi_buf, int filter_idx, int_mv seg_mvs[4][MAX_REF_FRAMES], int mi_row, int mi_col) { - int i, j, br = 0, rate = 0, sbr = 0, idx, idy; - int64_t bd = 0, sbd = 0, subblock_sse = 0, block_sse = 0; + int i, j, br = 0, idx, idy; + int64_t bd = 0, block_sse = 0; MB_PREDICTION_MODE this_mode; MODE_INFO *mi = x->e_mbd.mode_info_context; MB_MODE_INFO *const mbmi = &mi->mbmi; @@ -1824,13 +1822,14 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x, int64_t this_segment_rd = 0; int label_mv_thresh; int segmentyrate = 0; - int best_eobs[4] = { 0 }; BLOCK_SIZE_TYPE bsize = mbmi->sb_type; int bwl = b_width_log2(bsize), bw = 1 << bwl; int bhl = b_height_log2(bsize), bh = 1 << bhl; vp9_variance_fn_ptr_t *v_fn_ptr; - ENTROPY_CONTEXT t_above[4], t_left[4]; - ENTROPY_CONTEXT t_above_b[4], t_left_b[4]; + ENTROPY_CONTEXT t_above[2], t_left[2]; + BEST_SEG_INFO *bsi = bsi_buf + filter_idx; + int mode_idx; + int subpelmv = 1, have_ref = 0; vpx_memcpy(t_above, x->e_mbd.plane[0].above_context, sizeof(t_above)); vpx_memcpy(t_left, x->e_mbd.plane[0].left_context, sizeof(t_left)); @@ -1850,9 +1849,8 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x, // loop for 4x4/4x8/8x4 block coding. to be replaced with new rd loop int_mv mode_mv[MB_MODE_COUNT], second_mode_mv[MB_MODE_COUNT]; int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES]; - int64_t best_label_rd = INT64_MAX; MB_PREDICTION_MODE mode_selected = ZEROMV; - int bestlabelyrate = 0; + int64_t best_rd = INT64_MAX; i = idy * 2 + idx; frame_mv[ZEROMV][mbmi->ref_frame[0]].as_int = 0; @@ -1869,13 +1867,12 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x, // search for the best motion vector on this segment for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) { - int64_t this_rd; - int64_t distortion, sse; - int labelyrate; - ENTROPY_CONTEXT t_above_s[4], t_left_s[4]; const struct buf_2d orig_src = x->plane[0].src; struct buf_2d orig_pre[2]; + mode_idx = inter_mode_offset(this_mode); + bsi->rdstat[i][mode_idx].brdcost = INT64_MAX; + // if we're near/nearest and mv == 0,0, compare to zeromv if ((this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) && @@ -1914,9 +1911,10 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x, } vpx_memcpy(orig_pre, x->e_mbd.plane[0].pre, sizeof(orig_pre)); - - vpx_memcpy(t_above_s, t_above, sizeof(t_above_s)); - vpx_memcpy(t_left_s, t_left, sizeof(t_left_s)); + vpx_memcpy(bsi->rdstat[i][mode_idx].ta, t_above, + sizeof(bsi->rdstat[i][mode_idx].ta)); + vpx_memcpy(bsi->rdstat[i][mode_idx].tl, t_left, + sizeof(bsi->rdstat[i][mode_idx].tl)); // motion search for newmv (single predictor case only) if (mbmi->ref_frame[1] <= 0 && this_mode == NEWMV && @@ -1929,7 +1927,7 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x, /* Is the best so far sufficiently good that we cant justify doing * and new motion search. */ - if (best_label_rd < label_mv_thresh) + if (best_rd < label_mv_thresh) break; if (cpi->compressor_speed) { @@ -2016,10 +2014,29 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x, mi_buf_restore(x, orig_src, orig_pre); } - rate = labels2mode(x, i, this_mode, &mode_mv[this_mode], - &second_mode_mv[this_mode], frame_mv, seg_mvs[i], - bsi->ref_mv, bsi->second_ref_mv, x->nmvjointcost, - x->mvcost, cpi); + bsi->rdstat[i][mode_idx].brate = + labels2mode(x, i, this_mode, &mode_mv[this_mode], + &second_mode_mv[this_mode], frame_mv, seg_mvs[i], + bsi->ref_mv, bsi->second_ref_mv, x->nmvjointcost, + x->mvcost, cpi); + + bsi->rdstat[i][mode_idx].mvs[0].as_int = mode_mv[this_mode].as_int; + if (bw > 1) + bsi->rdstat[i + 1][mode_idx].mvs[0].as_int = + mode_mv[this_mode].as_int; + if (bh > 1) + bsi->rdstat[i + 2][mode_idx].mvs[0].as_int = + mode_mv[this_mode].as_int; + if (mbmi->ref_frame[1] > 0) { + bsi->rdstat[i][mode_idx].mvs[1].as_int = + second_mode_mv[this_mode].as_int; + if (bw > 1) + bsi->rdstat[i + 1][mode_idx].mvs[1].as_int = + second_mode_mv[this_mode].as_int; + if (bh > 1) + bsi->rdstat[i + 2][mode_idx].mvs[1].as_int = + second_mode_mv[this_mode].as_int; + } // Trap vectors that reach beyond the UMV borders if (mv_check_bounds(x, &mode_mv[this_mode])) @@ -2028,48 +2045,91 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x, mv_check_bounds(x, &second_mode_mv[this_mode])) continue; - this_rd = encode_inter_mb_segment(cpi, x, - bsi->segment_rd - this_segment_rd, - i, &labelyrate, &distortion, &sse, - t_above_s, t_left_s); - if (this_rd < INT64_MAX) { - this_rd += RDCOST(x->rdmult, x->rddiv, rate, 0); - rate += labelyrate; + if (filter_idx > 0) { + BEST_SEG_INFO *ref_bsi = bsi_buf; + subpelmv = (mode_mv[this_mode].as_mv.row & 0x0f) || + (mode_mv[this_mode].as_mv.col & 0x0f); + have_ref = mode_mv[this_mode].as_int == + ref_bsi->rdstat[i][mode_idx].mvs[0].as_int; + if (mbmi->ref_frame[1] > 0) { + subpelmv |= (second_mode_mv[this_mode].as_mv.row & 0x0f) || + (second_mode_mv[this_mode].as_mv.col & 0x0f); + have_ref &= second_mode_mv[this_mode].as_int == + ref_bsi->rdstat[i][mode_idx].mvs[1].as_int; + } + + if (filter_idx > 1 && !subpelmv && !have_ref) { + ref_bsi = bsi_buf + 1; + have_ref = mode_mv[this_mode].as_int == + ref_bsi->rdstat[i][mode_idx].mvs[0].as_int; + if (mbmi->ref_frame[1] > 0) { + have_ref &= second_mode_mv[this_mode].as_int == + ref_bsi->rdstat[i][mode_idx].mvs[1].as_int; + } + } + + if (!subpelmv && have_ref && + ref_bsi->rdstat[i][mode_idx].brdcost < INT64_MAX) { + vpx_memcpy(&bsi->rdstat[i][mode_idx], &ref_bsi->rdstat[i][mode_idx], + sizeof(SEG_RDSTAT)); + if (bsi->rdstat[i][mode_idx].brdcost < best_rd) { + mode_selected = this_mode; + best_rd = bsi->rdstat[i][mode_idx].brdcost; + } + continue; + } } - if (this_rd < best_label_rd) { - sbr = rate; - sbd = distortion; - subblock_sse = sse; - bestlabelyrate = labelyrate; + bsi->rdstat[i][mode_idx].brdcost = + encode_inter_mb_segment(cpi, x, + bsi->segment_rd - this_segment_rd, i, + &bsi->rdstat[i][mode_idx].byrate, + &bsi->rdstat[i][mode_idx].bdist, + &bsi->rdstat[i][mode_idx].bsse, + bsi->rdstat[i][mode_idx].ta, + bsi->rdstat[i][mode_idx].tl); + if (bsi->rdstat[i][mode_idx].brdcost < INT64_MAX) { + bsi->rdstat[i][mode_idx].brdcost += RDCOST(x->rdmult, x->rddiv, + bsi->rdstat[i][mode_idx].brate, 0); + bsi->rdstat[i][mode_idx].brate += bsi->rdstat[i][mode_idx].byrate; + bsi->rdstat[i][mode_idx].eobs = x->e_mbd.plane[0].eobs[i]; + } + + if (bsi->rdstat[i][mode_idx].brdcost < best_rd) { mode_selected = this_mode; - best_label_rd = this_rd; - best_eobs[i] = x->e_mbd.plane[0].eobs[i]; - vpx_memcpy(t_above_b, t_above_s, sizeof(t_above_s)); - vpx_memcpy(t_left_b, t_left_s, sizeof(t_left_s)); + best_rd = bsi->rdstat[i][mode_idx].brdcost; } } /*for each 4x4 mode*/ - if (best_label_rd == INT64_MAX) { + if (best_rd == INT64_MAX) { + int iy, midx; + for (iy = i + 1; iy < 4; ++iy) + for (midx = 0; midx < VP9_INTER_MODES; ++midx) + bsi->rdstat[iy][midx].brdcost = INT64_MAX; bsi->segment_rd = INT64_MAX; return; } - vpx_memcpy(t_above, t_above_b, sizeof(t_above)); - vpx_memcpy(t_left, t_left_b, sizeof(t_left)); + mode_idx = inter_mode_offset(mode_selected); + vpx_memcpy(t_above, bsi->rdstat[i][mode_idx].ta, sizeof(t_above)); + vpx_memcpy(t_left, bsi->rdstat[i][mode_idx].tl, sizeof(t_left)); labels2mode(x, i, mode_selected, &mode_mv[mode_selected], &second_mode_mv[mode_selected], frame_mv, seg_mvs[i], bsi->ref_mv, bsi->second_ref_mv, x->nmvjointcost, x->mvcost, cpi); - br += sbr; - bd += sbd; - block_sse += subblock_sse; - segmentyrate += bestlabelyrate; - this_segment_rd += best_label_rd; + br += bsi->rdstat[i][mode_idx].brate; + bd += bsi->rdstat[i][mode_idx].bdist; + block_sse += bsi->rdstat[i][mode_idx].bsse; + segmentyrate += bsi->rdstat[i][mode_idx].byrate; + this_segment_rd += bsi->rdstat[i][mode_idx].brdcost; if (this_segment_rd > bsi->segment_rd) { + int iy, midx; + for (iy = i + 1; iy < 4; ++iy) + for (midx = 0; midx < VP9_INTER_MODES; ++midx) + bsi->rdstat[iy][midx].brdcost = INT64_MAX; bsi->segment_rd = INT64_MAX; return; } @@ -2091,14 +2151,9 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x, bsi->segment_rd = this_segment_rd; bsi->sse = block_sse; - // store everything needed to come back to this!! - for (i = 0; i < 4; i++) { - bsi->mvs[i].as_mv = mi->bmi[i].as_mv[0].as_mv; - if (mbmi->ref_frame[1] > 0) - bsi->second_mvs[i].as_mv = mi->bmi[i].as_mv[1].as_mv; + // update the coding decisions + for (i = 0; i < 4; ++i) bsi->modes[i] = x->partition_info->bmi[i].mode; - bsi->eobs[i] = best_eobs[i]; - } } static int64_t rd_pick_best_mbsegmentation(VP9_COMP *cpi, MACROBLOCK *x, @@ -2111,47 +2166,52 @@ static int64_t rd_pick_best_mbsegmentation(VP9_COMP *cpi, MACROBLOCK *x, int *skippable, int64_t *psse, int mvthresh, int_mv seg_mvs[4][MAX_REF_FRAMES], + BEST_SEG_INFO *bsi_buf, + int filter_idx, int mi_row, int mi_col) { int i; - BEST_SEG_INFO bsi; - MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi; + BEST_SEG_INFO *bsi = bsi_buf + filter_idx; + MACROBLOCKD *xd = &x->e_mbd; + MODE_INFO *mi = xd->mode_info_context; + MB_MODE_INFO *mbmi = &mi->mbmi; + int mode_idx; - vpx_memset(&bsi, 0, sizeof(bsi)); + vpx_memset(bsi, 0, sizeof(*bsi)); - bsi.segment_rd = best_rd; - bsi.ref_mv = best_ref_mv; - bsi.second_ref_mv = second_best_ref_mv; - bsi.mvp.as_int = best_ref_mv->as_int; - bsi.mvthresh = mvthresh; + bsi->segment_rd = best_rd; + bsi->ref_mv = best_ref_mv; + bsi->second_ref_mv = second_best_ref_mv; + bsi->mvp.as_int = best_ref_mv->as_int; + bsi->mvthresh = mvthresh; for (i = 0; i < 4; i++) - bsi.modes[i] = ZEROMV; + bsi->modes[i] = ZEROMV; - rd_check_segment_txsize(cpi, x, &bsi, seg_mvs, mi_row, mi_col); + rd_check_segment_txsize(cpi, x, bsi_buf, filter_idx, seg_mvs, mi_row, mi_col); if (bsi.segment_rd > best_rd) return INT64_MAX; /* set it to the best */ for (i = 0; i < 4; i++) { - x->e_mbd.mode_info_context->bmi[i].as_mv[0].as_int = bsi.mvs[i].as_int; + mode_idx = inter_mode_offset(bsi->modes[i]); + mi->bmi[i].as_mv[0].as_int = bsi->rdstat[i][mode_idx].mvs[0].as_int; if (mbmi->ref_frame[1] > 0) - x->e_mbd.mode_info_context->bmi[i].as_mv[1].as_int = - bsi.second_mvs[i].as_int; - x->e_mbd.plane[0].eobs[i] = bsi.eobs[i]; - x->partition_info->bmi[i].mode = bsi.modes[i]; + mi->bmi[i].as_mv[1].as_int = bsi->rdstat[i][mode_idx].mvs[1].as_int; + xd->plane[0].eobs[i] = bsi->rdstat[i][mode_idx].eobs; + x->partition_info->bmi[i].mode = bsi->modes[i]; } /* * used to set mbmi->mv.as_int */ - *returntotrate = bsi.r; - *returndistortion = bsi.d; - *returnyrate = bsi.segment_yrate; + *returntotrate = bsi->r; + *returndistortion = bsi->d; + *returnyrate = bsi->segment_yrate; *skippable = vp9_sby_is_skippable(&x->e_mbd, BLOCK_SIZE_SB8X8); - *psse = bsi.sse; - mbmi->mode = bsi.modes[3]; + *psse = bsi->sse; + mbmi->mode = bsi->modes[3]; - return bsi.segment_rd; + return bsi->segment_rd; } static void mv_pred(VP9_COMP *cpi, MACROBLOCK *x, @@ -2706,7 +2766,6 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, frame_mv[refs[1]].as_int == INVALID_MV) return INT64_MAX; *rate2 += rate_mv; - } else { int_mv tmp_mv; single_motion_search(cpi, x, bsize, mi_row, mi_col, @@ -3486,6 +3545,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, union b_mode_info tmp_best_bmodes[16]; MB_MODE_INFO tmp_best_mbmode; PARTITION_INFO tmp_best_partition; + BEST_SEG_INFO bsi[VP9_SWITCHABLE_FILTERS]; int pred_exists = 0; int uv_skippable; if (is_comp_pred) { @@ -3523,10 +3583,11 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, &rate, &rate_y, &distortion, &skippable, &total_sse, (int)this_rd_thresh, seg_mvs, + bsi, switchable_filter_index, mi_row, mi_col); - if (tmp_rd == INT64_MAX) { + + if (tmp_rd == INT64_MAX) continue; - } cpi->rd_filter_cache[switchable_filter_index] = tmp_rd; rs = get_switchable_rate(cm, x); rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0); @@ -3567,6 +3628,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, } } } // switchable_filter_index loop + if (tmp_best_rdu == INT64_MAX) continue; @@ -3583,6 +3645,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, &rate, &rate_y, &distortion, &skippable, &total_sse, (int)this_rd_thresh, seg_mvs, + bsi, 0, mi_row, mi_col); if (tmp_rd == INT64_MAX) continue; |