From c56b4d574740f20ff91ba7e8fb85fe88cfada7bc Mon Sep 17 00:00:00 2001 From: Marko Viitanen Date: Wed, 18 Mar 2015 10:03:06 +0200 Subject: [PATCH] Added combined merge candidates on B-slices and struct inter_merge_cand_t --- src/inter.c | 87 +++++++++++++++++++++++++++++++++++++++------------- src/inter.h | 9 +++++- src/search.c | 38 ++++++++++++----------- 3 files changed, 93 insertions(+), 41 deletions(-) diff --git a/src/inter.c b/src/inter.c index ea21b390..3b435da6 100644 --- a/src/inter.c +++ b/src/inter.c @@ -514,7 +514,7 @@ void inter_get_mv_cand(const encoder_state_t * const state, int32_t x, int32_t y * \param depth current block depth * \param mv_pred[MRG_MAX_NUM_CANDS][2] MRG_MAX_NUM_CANDS motion vector prediction */ -uint8_t inter_get_merge_cand(int32_t x, int32_t y, int8_t depth, int16_t mv_cand[MRG_MAX_NUM_CANDS][3], lcu_t *lcu) +uint8_t inter_get_merge_cand(int32_t x, int32_t y, int8_t depth, inter_merge_cand_t mv_cand[MRG_MAX_NUM_CANDS], lcu_t *lcu, bool inter_b) { uint8_t candidates = 0; int8_t duplicate = 0; @@ -530,19 +530,21 @@ uint8_t inter_get_merge_cand(int32_t x, int32_t y, int8_t depth, int16_t mv_cand (CU1)->inter.mv[1] == (CU2)->inter.mv[1] && \ (CU1)->inter.mv_ref == (CU2)->inter.mv_ref) duplicate = 1; } - if (a1 && a1->type == CU_INTER) { - mv_cand[candidates][0] = a1->inter.mv[0]; - mv_cand[candidates][1] = a1->inter.mv[1]; - mv_cand[candidates][2] = a1->inter.mv_ref; - candidates++; + if (a1 && a1->type == CU_INTER) { + mv_cand[candidates].mv[a1->inter.mv_dir - 1][0] = a1->inter.mv[0]; + mv_cand[candidates].mv[a1->inter.mv_dir - 1][1] = a1->inter.mv[1]; + mv_cand[candidates].ref = a1->inter.mv_ref; + mv_cand[candidates].dir = a1->inter.mv_dir; + candidates++; } if (b1 && b1->type == CU_INTER) { if(candidates) CHECK_DUPLICATE(b1, a1); if(!duplicate) { - mv_cand[candidates][0] = b1->inter.mv[0]; - mv_cand[candidates][1] = b1->inter.mv[1]; - mv_cand[candidates][2] = b1->inter.mv_ref; + mv_cand[candidates].mv[b1->inter.mv_dir - 1][0] = b1->inter.mv[0]; + mv_cand[candidates].mv[b1->inter.mv_dir - 1][1] = b1->inter.mv[1]; + mv_cand[candidates].ref = b1->inter.mv_ref; + mv_cand[candidates].dir = b1->inter.mv_dir; candidates++; } } @@ -550,9 +552,10 @@ uint8_t inter_get_merge_cand(int32_t x, int32_t y, int8_t depth, int16_t mv_cand if (b0 && b0->type == CU_INTER) { if(candidates) CHECK_DUPLICATE(b0,b1); if(!duplicate) { - mv_cand[candidates][0] = b0->inter.mv[0]; - mv_cand[candidates][1] = b0->inter.mv[1]; - mv_cand[candidates][2] = b0->inter.mv_ref; + mv_cand[candidates].mv[b0->inter.mv_dir - 1][0] = b0->inter.mv[0]; + mv_cand[candidates].mv[b0->inter.mv_dir - 1][1] = b0->inter.mv[1]; + mv_cand[candidates].ref = b0->inter.mv_ref; + mv_cand[candidates].dir = b0->inter.mv_dir; candidates++; } } @@ -560,9 +563,10 @@ uint8_t inter_get_merge_cand(int32_t x, int32_t y, int8_t depth, int16_t mv_cand if (a0 && a0->type == CU_INTER) { if(candidates) CHECK_DUPLICATE(a0,a1); if(!duplicate) { - mv_cand[candidates][0] = a0->inter.mv[0]; - mv_cand[candidates][1] = a0->inter.mv[1]; - mv_cand[candidates][2] = a0->inter.mv_ref; + mv_cand[candidates].mv[a0->inter.mv_dir - 1][0] = a0->inter.mv[0]; + mv_cand[candidates].mv[a0->inter.mv_dir - 1][1] = a0->inter.mv[1]; + mv_cand[candidates].ref = a0->inter.mv_ref; + mv_cand[candidates].dir = a0->inter.mv_dir; candidates++; } } @@ -573,9 +577,10 @@ uint8_t inter_get_merge_cand(int32_t x, int32_t y, int8_t depth, int16_t mv_cand if(!duplicate) { CHECK_DUPLICATE(b2,b1); if(!duplicate) { - mv_cand[candidates][0] = b2->inter.mv[0]; - mv_cand[candidates][1] = b2->inter.mv[1]; - mv_cand[candidates][2] = b2->inter.mv_ref; + mv_cand[candidates].mv[b2->inter.mv_dir - 1][0] = b2->inter.mv[0]; + mv_cand[candidates].mv[b2->inter.mv_dir - 1][1] = b2->inter.mv[1]; + mv_cand[candidates].ref = b2->inter.mv_ref; + mv_cand[candidates].dir = b2->inter.mv_dir; candidates++; } } @@ -589,11 +594,49 @@ uint8_t inter_get_merge_cand(int32_t x, int32_t y, int8_t depth, int16_t mv_cand } #endif + if (candidates == MRG_MAX_NUM_CANDS) return MRG_MAX_NUM_CANDS; + + if (inter_b) { + #define NUM_PRIORITY_LIST 12; + static const uint8_t priorityList0[] = { 0, 1, 0, 2, 1, 2, 0, 3, 1, 3, 2, 3 }; + static const uint8_t priorityList1[] = { 1, 0, 2, 0, 2, 1, 3, 0, 3, 1, 3, 2 }; + uint8_t cutoff = candidates; + for (int32_t idx = 0; idxx >> 2, mv_in_out->y >> 2 }; @@ -267,8 +267,8 @@ static unsigned hexagon_search(const encoder_state_t * const state, unsigned dep // Select starting point from among merge candidates. These should include // both mv_cand vectors and (0, 0). for (i = 0; i < num_cand; ++i) { - mv.x = merge_cand[i][0] >> 2; - mv.y = merge_cand[i][1] >> 2; + mv.x = merge_cand[i].mv[merge_cand[i].dir - 1][0] >> 2; + mv.y = merge_cand[i].mv[merge_cand[i].dir - 1][1] >> 2; PERFORMANCE_MEASURE_START(_DEBUG_PERF_SEARCH_PIXELS); @@ -291,8 +291,8 @@ static unsigned hexagon_search(const encoder_state_t * const state, unsigned dep } } if (best_index < num_cand) { - mv.x = merge_cand[best_index][0] >> 2; - mv.y = merge_cand[best_index][1] >> 2; + mv.x = merge_cand[best_index].mv[merge_cand[best_index].dir - 1][0] >> 2; + mv.y = merge_cand[best_index].mv[merge_cand[best_index].dir - 1][1] >> 2; } else { mv.x = mv_in_out->x >> 2; mv.y = mv_in_out->y >> 2; @@ -483,7 +483,7 @@ static unsigned search_frac(const encoder_state_t * const state, unsigned depth, const image_t *pic, const image_t *ref, const vector2d_t *orig, vector2d_t *mv_in_out, - int16_t mv_cand[2][2], int16_t merge_cand[MRG_MAX_NUM_CANDS][3], + int16_t mv_cand[2][2], inter_merge_cand_t merge_cand[MRG_MAX_NUM_CANDS], int16_t num_cand, int32_t ref_idx, uint32_t *bitcost_out) { @@ -626,9 +626,9 @@ static int search_cu_inter(const encoder_state_t * const state, int x, int y, in int16_t mv_cand[2][2]; // Search for merge mode candidate - int16_t merge_cand[MRG_MAX_NUM_CANDS][3]; + inter_merge_cand_t merge_cand[MRG_MAX_NUM_CANDS]; // Get list of candidates - int16_t num_cand = inter_get_merge_cand(x, y, depth, merge_cand, lcu); + int16_t num_cand = inter_get_merge_cand(x, y, depth, merge_cand, lcu, (state->global->pictype == SLICE_B)); // Select better candidate cur_cu->inter.mv_cand = 0; // Default to candidate 0 @@ -670,9 +670,10 @@ static int search_cu_inter(const encoder_state_t * const state, int x, int y, in merged = 0; // Check every candidate to find a match for(merge_idx = 0; merge_idx < num_cand; merge_idx++) { - if (merge_cand[merge_idx][0] == mv.x && - merge_cand[merge_idx][1] == mv.y && - (uint32_t)merge_cand[merge_idx][2] == ref_idx) { + if (merge_cand[merge_idx].mv[merge_cand[merge_idx].dir - 1][0] == mv.x && + merge_cand[merge_idx].mv[merge_cand[merge_idx].dir - 1][1] == mv.y && + merge_cand[merge_idx].dir != 3 && + (uint32_t)merge_cand[merge_idx].ref == ref_idx) { merged = 1; break; } @@ -705,13 +706,15 @@ static int search_cu_inter(const encoder_state_t * const state, int x, int y, in if (state->global->ref->images[j]->poc < state->global->poc) { if (ref_idx == j) { cur_cu->inter.mv_dir = 1; - cur_cu->inter.mv_ref_coded = ref_list[0]; + cur_cu->inter.mv_ref_coded = ref_list[0]; + break; } ref_list[0]++; } else { if (ref_idx == j) { cur_cu->inter.mv_dir = 2; cur_cu->inter.mv_ref_coded = ref_list[1]; + break; } ref_list[1]++; } @@ -719,13 +722,12 @@ static int search_cu_inter(const encoder_state_t * const state, int x, int y, in cur_cu->merged = merged; cur_cu->merge_idx = merge_idx; cur_cu->inter.mv_ref = ref_idx; - //cur_cu->inter.mv_dir = 1; cur_cu->inter.mv[0] = (int16_t)mv.x; cur_cu->inter.mv[1] = (int16_t)mv.y; cur_cu->inter.mvd[0] = (int16_t)mvd.x; cur_cu->inter.mvd[1] = (int16_t)mvd.y; cur_cu->inter.cost = temp_cost; - cur_cu->inter.bitcost = temp_bitcost + ref_idx; + cur_cu->inter.bitcost = temp_bitcost + cur_cu->inter.mv_dir - 1 + cur_cu->inter.mv_ref_coded; cur_cu->inter.mv_cand = cu_mv_cand; } }