From e1f0274b51822bba44fd6bcab8c31ba5be542848 Mon Sep 17 00:00:00 2001 From: Marko Viitanen Date: Wed, 23 Oct 2013 15:14:26 +0300 Subject: [PATCH] Merge mode working on blocks > 8x8 --- src/encoder.c | 51 ++++++++++++++++++++++++++++++++++++--------------- src/inter.c | 4 ++-- src/picture.c | 23 +++++++++++++++++++++++ src/picture.h | 4 +++- 4 files changed, 64 insertions(+), 18 deletions(-) diff --git a/src/encoder.c b/src/encoder.c index e310e3d8..7999d808 100644 --- a/src/encoder.c +++ b/src/encoder.c @@ -860,12 +860,12 @@ void encode_coding_tree(encoder_control *encoder, uint16_t x_ctb, for(unary_idx = 0; unary_idx < num_cand; unary_idx++) { if(merge_cand[unary_idx][0] == cur_cu->inter.mv[0] && merge_cand[unary_idx][1] == cur_cu->inter.mv[1]) { - //cur_cu->skipped = 1; + //picture_set_block_skipped(encoder->in.cur_pic, x_ctb, y_ctb, depth, 1); break; } } } - // Get left and top skipped flags and if they are present and true, increase model number + // Get left and top skipped flags and if they are present and true, increase context number if (x_ctb > 0 && (&encoder->in.cur_pic->cu_array[MAX_DEPTH][x_ctb - 1 + y_ctb * (encoder->in.width_in_lcu << MAX_DEPTH)])->skipped) { ctx_skip++; } @@ -917,16 +917,20 @@ void encode_coding_tree(encoder_control *encoder, uint16_t x_ctb, if (cur_cu->type == CU_INTER) { // FOR each part // Mergeflag - int16_t unary_idx = 0; + int16_t num_cand = 0; + /* int16_t merge_cand[MRG_MAX_NUM_CANDS][2]; - int16_t num_cand = inter_get_merge_cand(encoder, x_ctb, y_ctb, depth, merge_cand); - for(unary_idx = 0; unary_idx < num_cand; unary_idx++) { - if(merge_cand[unary_idx][0] == cur_cu->inter.mv[0] && - merge_cand[unary_idx][1] == cur_cu->inter.mv[1]) { - //cur_cu->merged = 1; - break; + int16_t num_cand = inter_get_merge_cand(encoder, x_ctb, y_ctb, depth, merge_cand); + if(cur_cu->coeff_top_y[depth] | cur_cu->coeff_top_u[depth] | cur_cu->coeff_top_v[depth]) { + for(unary_idx = 0; unary_idx < num_cand; unary_idx++) { + if(merge_cand[unary_idx][0] == cur_cu->inter.mv[0] && + merge_cand[unary_idx][1] == cur_cu->inter.mv[1]) { + cur_cu->merged = 1; + break; + } } - } + } + */ cabac.ctx = &g_cu_merge_flag_ext_model; CABAC_BIN(&cabac, cur_cu->merged, "MergeFlag"); num_cand = MRG_MAX_NUM_CANDS; @@ -934,12 +938,12 @@ void encode_coding_tree(encoder_control *encoder, uint16_t x_ctb, if (num_cand > 1) { int32_t ui; for (ui = 0; ui < num_cand - 1; ui++) { - int32_t symbol = (ui != unary_idx); + int32_t symbol = (ui != cur_cu->merge_idx); if (ui == 0) { - cabac.ctx = &g_cu_merge_idx_ext_model; - CABAC_BIN(&cabac, symbol, "MergeIndex"); + cabac.ctx = &g_cu_merge_idx_ext_model; + CABAC_BIN(&cabac, symbol, "MergeIndex"); } else { - CABAC_BIN_EP(&cabac,symbol,"MergeIndex"); + CABAC_BIN_EP(&cabac,symbol,"MergeIndex"); } if (symbol == 0) break; } @@ -2087,6 +2091,18 @@ void encode_block_residual(encoder_control *encoder, } else { int16_t mv_cand[2][2]; + + int16_t merge_cand[MRG_MAX_NUM_CANDS][2]; + int16_t num_cand = inter_get_merge_cand(encoder, x_ctb, y_ctb, depth, merge_cand); + for(cur_cu->merge_idx = 0; cur_cu->merge_idx < num_cand; cur_cu->merge_idx++) { + if(merge_cand[cur_cu->merge_idx][0] == cur_cu->inter.mv[0] && + merge_cand[cur_cu->merge_idx][1] == cur_cu->inter.mv[1]) { + cur_cu->merged = 1; + break; + } + } + + // Get MV candidates inter_get_mv_cand(encoder, x_ctb, y_ctb, depth, mv_cand); @@ -2111,11 +2127,16 @@ void encode_block_residual(encoder_control *encoder, // Inter reconstruction inter_recon(encoder->ref->pics[0], x_ctb * CU_MIN_SIZE_PIXELS, y_ctb * CU_MIN_SIZE_PIXELS, LCU_WIDTH >> depth, cur_cu->inter.mv, - encoder->in.cur_pic); + encoder->in.cur_pic); } // Mark this block as "coded" (can be used for predictions..) picture_set_block_coded(encoder->in.cur_pic, x_ctb, y_ctb, depth, 1); encode_transform_tree(encoder,x_ctb, y_ctb, depth); + if(cur_cu->merged &&!cur_cu->coeff_top_y[depth] && !cur_cu->coeff_top_u[depth] && !cur_cu->coeff_top_v[depth]) { + cur_cu->merged = 0; + //cur_cu->skipped = 1; + } + } diff --git a/src/inter.c b/src/inter.c index 2e76b210..3f9846ed 100644 --- a/src/inter.c +++ b/src/inter.c @@ -412,9 +412,9 @@ uint8_t inter_get_merge_cand(encoder_control *encoder, int32_t x_cu, int32_t y_c } #endif - // Fill with (0,0) + // Fill with (0,0) + //i = candidates; /* - i = candidates; while (candidates < MRG_MAX_NUM_CANDS) { mv_cand[candidates][0] = 0; mv_cand[candidates][1] = 0; diff --git a/src/picture.c b/src/picture.c index 3983d392..1cebe141 100644 --- a/src/picture.c +++ b/src/picture.c @@ -20,6 +20,29 @@ #define PSNRMAX (255.0 * 255.0) +/** + * \brief Set block skipped + * \param pic picture to use + * \param x_scu x SCU position (smallest CU) + * \param y_scu y SCU position (smallest CU) + * \param depth current CU depth + * \param skipped skipped flag + */ +void picture_set_block_skipped(picture *pic, uint32_t x_scu, uint32_t y_scu, + uint8_t depth, int8_t skipped) +{ + uint32_t x, y; + int width_in_scu = pic->width_in_lcu << MAX_DEPTH; + int block_scu_width = (LCU_WIDTH >> depth) / (LCU_WIDTH >> MAX_DEPTH); + + for (y = y_scu; y < y_scu + block_scu_width; ++y) { + int cu_row = y * width_in_scu; + for (x = x_scu; x < x_scu + block_scu_width; ++x) { + pic->cu_array[MAX_DEPTH][cu_row + x].skipped = skipped; + } + } +} + /** * \brief Set block residual status * \param pic picture to use diff --git a/src/picture.h b/src/picture.h index 87065ab6..662dbcaf 100644 --- a/src/picture.h +++ b/src/picture.h @@ -62,6 +62,7 @@ typedef struct int8_t coded; //!< \brief flag to indicate this block is coded and reconstructed int8_t skipped; //!< \brief flag to indicate this block is skipped int8_t merged; //!< \brief flag to indicate this block is merged + int8_t merge_idx; //!< \brief merge index int8_t coeff_y; //!< \brief is there coded coeffs Y int8_t coeff_u; //!< \brief is there coded coeffs U int8_t coeff_v; //!< \brief is there coded coeffs V @@ -127,7 +128,8 @@ void picture_set_block_residual(picture *pic, uint32_t x_scu, uint32_t y_scu, uint8_t depth, int8_t residual); void picture_set_block_split(picture *pic, uint32_t x_scu, uint32_t y_scu, uint8_t depth, int8_t split); - +void picture_set_block_skipped(picture *pic, uint32_t x_scu, uint32_t y_scu, + uint8_t depth, int8_t skipped); picture_list * picture_list_init(int size); int picture_list_resize(picture_list *list, int size); int picture_list_destroy(picture_list *list);