From 26082d532887f6ed4abaabd663e608f2770b3b5f Mon Sep 17 00:00:00 2001 From: Marko Viitanen Date: Fri, 20 Mar 2015 10:33:05 +0200 Subject: [PATCH] Zero merge candidate fix for B-frames --- src/inter.c | 25 +++++++++++++++++++++++-- src/search.c | 2 ++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/inter.c b/src/inter.c index def56c0c..df1f820d 100644 --- a/src/inter.c +++ b/src/inter.c @@ -604,6 +604,7 @@ uint8_t inter_get_merge_cand(const encoder_state_t * const state, int32_t x, int for (int32_t idx = 0; idx= candidates || j >= candidates) break; // Find one L0 and L1 candidate according to the priority list if ((mv_cand[i].dir & 0x1) && (mv_cand[j].dir & 0x2)) { @@ -626,11 +627,31 @@ uint8_t inter_get_merge_cand(const encoder_state_t * const state, int32_t x, int } } + if (candidates == MRG_MAX_NUM_CANDS) return MRG_MAX_NUM_CANDS; + + int num_ref = state->global->ref->used_size; + + if (state->global->slicetype == SLICE_B) { + int j; + int ref_negative = 0; + int ref_positive = 0; + for (j = 0; j < state->global->ref->used_size; j++) { + if (state->global->ref->images[j]->poc < state->global->poc) { + ref_negative++; + } else { + ref_positive++; + } + if (!ref_negative) ref_negative = 1; + if (!ref_positive) ref_positive = 1; + } + num_ref = MIN(ref_negative, ref_positive); + } + // Add (0,0) prediction - if (candidates != MRG_MAX_NUM_CANDS) { + while (candidates != MRG_MAX_NUM_CANDS) { mv_cand[candidates].mv[0][0] = 0; mv_cand[candidates].mv[0][1] = 0; - mv_cand[candidates].ref = zero_idx; + mv_cand[candidates].ref = (zero_idx>=num_ref-1)?0:zero_idx; mv_cand[candidates].dir = 1; if (state->global->slicetype == SLICE_B) { mv_cand[candidates].mv[1][0] = 0; diff --git a/src/search.c b/src/search.c index d179a828..93b6f13d 100644 --- a/src/search.c +++ b/src/search.c @@ -701,6 +701,8 @@ static int search_cu_inter(const encoder_state_t * const state, int x, int y, in mvd.y = mv.y - mv_cand[cu_mv_cand][1]; if(temp_cost < cur_cu->inter.cost) { + + // Map reference index to L0/L1 pictures cur_cu->inter.mv_dir = state->global->refmap[ref_idx].list; cur_cu->inter.mv_ref_coded = state->global->refmap[ref_idx].idx;