From 9563b50a34326ee31431ed1c128f36c63130c41b Mon Sep 17 00:00:00 2001 From: Ari Koivula Date: Fri, 14 Mar 2014 15:45:23 +0200 Subject: [PATCH] Refactor coefficient group scan mapping lists. The relation between coefficients positions and coefficient group positions was a big confusing due to the use of 16x16 diagonal coefficient mappings also as coefficient group mappings. - Moved all coefficient group mappings to their own const arrays and added a new array the select the correct coefficient group mapping. This removes special cases for 8x8 and 32x32 transform sizes. - Removed all coefficient group mapping initialization from init_sig_last_scan. - Removed 128x128 and 64x64 from regular coefficient group array as those transform sizes don't exist anymore in HEVC. --- src/encoder.c | 46 +++++++++++++++++------------------------- src/encoder.h | 56 ++++++++++++++++++++++++++++++++++++++++++--------- src/rdo.c | 10 +-------- 3 files changed, 66 insertions(+), 46 deletions(-) diff --git a/src/encoder.c b/src/encoder.c index fe16f596..d078ac2b 100644 --- a/src/encoder.c +++ b/src/encoder.c @@ -44,13 +44,17 @@ double g_lambda_cost[55]; double g_cur_lambda_cost; -uint32_t* g_sig_last_scan[3][7]; +uint32_t* g_sig_last_scan[3][5]; int8_t g_convert_to_bit[LCU_WIDTH + 1]; /* Local functions. */ static void add_checksum(encoder_control* encoder); static void encode_VUI(encoder_control* encoder); +/** + * Initialize g_sig_last_scan with scan positions for a transform block of + * size width x height. + */ static void init_sig_last_scan(uint32_t *buff_d, uint32_t *buff_h, uint32_t *buff_v, int32_t width, int32_t height) @@ -63,12 +67,10 @@ static void init_sig_last_scan(uint32_t *buff_d, uint32_t *buff_h, uint32_t blk; uint32_t cnt = 0; - if (width < 16) { - uint32_t *buff_tmp = buff_d; + assert(width == height && width <= 32); - if (width == 8) { - buff_tmp = (uint32_t *)g_sig_last_scan_32x32; - } + if (width <= 4) { + uint32_t *buff_tmp = buff_d; for (scan_line = 0; next_scan_pos < num_scan_pos; scan_line++) { int primary_dim = scan_line; @@ -88,19 +90,15 @@ static void init_sig_last_scan(uint32_t *buff_d, uint32_t *buff_h, } } - if (width > 4) { + if (width > 4 && width <= 32) { uint32_t num_blk_side = width >> 2; - uint32_t num_blks = num_blk_side * num_blk_side; - uint32_t log2_blk = g_convert_to_bit[num_blk_side] + 1; + uint32_t num_blks = num_blk_side * num_blk_side; + uint32_t log2_width = g_to_bits[width]; for (blk = 0; blk < num_blks; blk++) { - uint32_t init_blk_pos = g_sig_last_scan[SCAN_DIAG][log2_blk][blk]; + uint32_t init_blk_pos = g_sig_last_scan_cg[log2_width][SCAN_DIAG][blk]; next_scan_pos = 0; - if (width == 32) { - init_blk_pos = g_sig_last_scan_32x32[blk]; - } - { uint32_t offset_y = init_blk_pos / num_blk_side; uint32_t offset_x = init_blk_pos - offset_y * num_blk_side; @@ -194,7 +192,7 @@ void init_tables(void) g_convert_to_bit[i] = (int8_t)c; c = 2; - for (i = 0; i < 7; i++) { + for (i = 0; i < 5; i++) { g_sig_last_scan[0][i] = (uint32_t*)malloc(c*c*sizeof(uint32_t)); g_sig_last_scan[1][i] = (uint32_t*)malloc(c*c*sizeof(uint32_t)); g_sig_last_scan[2][i] = (uint32_t*)malloc(c*c*sizeof(uint32_t)); @@ -238,7 +236,7 @@ void init_lambda(encoder_control *encoder) void free_tables(void) { int i; - for (i = 0; i < 7; i++) { + for (i = 0; i < 5; i++) { free(g_sig_last_scan[0][i]); free(g_sig_last_scan[1][i]); free(g_sig_last_scan[2][i]); @@ -790,7 +788,7 @@ static void encode_scaling_list(encoder_control* encoder) } else { int32_t delta; int32_t coef_num = MIN(MAX_MATRIX_COEF_NUM, g_scaling_list_size[size_id]); - uint32_t *scan = (size_id == 0) ? g_sig_last_scan[SCAN_DIAG][1] : g_sig_last_scan_32x32; + const uint32_t *scan_cg = (size_id == 0) ? g_sig_last_scan_16x16 : g_sig_last_scan_32x32; int32_t next_coef = 8; int32_t *coef_list = g_scaling_list_coeff[size_id][list_id]; @@ -800,8 +798,8 @@ static void encode_scaling_list(encoder_control* encoder) } for (i = 0; i < coef_num; i++) { - delta = coef_list[scan[i]] - next_coef; - next_coef = coef_list[scan[i]]; + delta = coef_list[scan_cg[i]] - next_coef; + next_coef = coef_list[scan_cg[i]]; if (delta > 127) delta -= 256; if (delta < -128) @@ -2319,7 +2317,7 @@ void encode_coeff_nxn(encoder_control *encoder, coefficient *coeff, uint8_t widt const uint32_t log2_block_size = g_convert_to_bit[width] + 2; const uint32_t *scan = g_sig_last_scan[scan_mode][log2_block_size - 1]; - const uint32_t *scan_cg = NULL; + const uint32_t *scan_cg = g_sig_last_scan_cg[log2_block_size - 2][scan_mode]; // Init base contexts according to block type cabac_ctx *base_coeff_group_ctx = &g_cu_sig_coeff_group_model[type]; @@ -2334,14 +2332,6 @@ void encode_coeff_nxn(encoder_control *encoder, coefficient *coeff, uint8_t widt } } - scan_cg = g_sig_last_scan[scan_mode][log2_block_size > 3 ? log2_block_size - 3 : 0]; - - if (log2_block_size == 3) { - scan_cg = g_sig_last_scan_8x8[scan_mode]; - } else if (log2_block_size == 5) { - scan_cg = g_sig_last_scan_32x32; - } - scan_pos_last = -1; // Significance mapping diff --git a/src/encoder.h b/src/encoder.h index 76008da1..b4f6dd22 100644 --- a/src/encoder.h +++ b/src/encoder.h @@ -128,7 +128,6 @@ void encode_block_residual(encoder_control *encoder, extern double g_lambda_cost[55]; extern double g_cur_lambda_cost; -extern uint32_t* g_sig_last_scan[3][7]; extern int8_t g_convert_to_bit[LCU_WIDTH + 1]; static int8_t g_bitdepth = 8; static int8_t g_bit_increment = 0; @@ -146,21 +145,60 @@ static const uint8_t g_group_idx[32] = { static const uint8_t g_min_in_group[10] = { 0, 1, 2, 3, 4, 6, 8, 12, 16, 24 }; -static uint32_t g_sig_last_scan_32x32[64] = { - 0, 8, 1, 16, 9, 2, 24, 17, 10, 3, - 32, 25, 18, 11, 4, 40, 33, 26, 19, 12, - 5, 48, 41, 34, 27, 20, 13, 6, 56, 49, - 42, 35, 28, 21, 14, 7, 57, 50, 43, 36, - 29, 22, 15, 58, 51, 44, 37, 30, 23, 59, - 52, 45, 38, 31, 60, 53, 46, 39, 61, 54, - 47, 62, 55, 63 }; +/** + * List of mappings for coefficients within a transform block. + * First index: scan pattern 0 = diagonal, 1 = horizontal, 2 = vertical + * Second index: (log2 - 1) size of transform block. 2x2 .. 32x32 + */ +extern uint32_t* g_sig_last_scan[3][5]; +/*** + * List of indices for 4x4 coefficient groups within 8x8 transform block. + * First index: 0 = diagonal, 1 = vertical, 2 horizontal scan pattern. + * Second index: (log2 - 2) size of transform block. 4x4 .. 32x32 + */ static const uint32_t g_sig_last_scan_8x8[3][4] = { {0, 2, 1, 3}, {0, 1, 2, 3}, {0, 2, 1, 3} }; +/*** + * List of indices for 4x4 coefficient groups within 16x16 transform block. + */ +static const uint32_t g_sig_last_scan_16x16[16] = { + 0, 4, 1, 8, + 5, 2, 12, 9, + 6, 3, 13, 10, + 7, 14, 11, 15 +}; + +/*** + * List of indices for 4x4 coefficient groups within 32x32 transform block. + */ +static const uint32_t g_sig_last_scan_32x32[64] = { + 0, 8, 1, 16, 9, 2, 24, 17, + 10, 3, 32, 25, 18, 11, 4, 40, + 33, 26, 19, 12, 5, 48, 41, 34, + 27, 20, 13, 6, 56, 49, 42, 35, + 28, 21, 14, 7, 57, 50, 43, 36, + 29, 22, 15, 58, 51, 44, 37, 30, + 23, 59, 52, 45, 38, 31, 60, 53, + 46, 39, 61, 54, 47, 62, 55, 63 +}; + +/** + * List of pointers to coefficient group mappings. + * First index: (log2 - 2) of transform block size + * Second index: scan pattern 0 = diagonal, 1 = horizontal, 2 = vertical + */ +static const uint32_t *g_sig_last_scan_cg[4][3] = { + { g_sig_last_scan_8x8[0], g_sig_last_scan_8x8[1], g_sig_last_scan_8x8[2] }, // 4x4, only first element is used + { g_sig_last_scan_8x8[0], g_sig_last_scan_8x8[1], g_sig_last_scan_8x8[2] }, + { g_sig_last_scan_16x16, 0, 0 }, + { g_sig_last_scan_32x32, 0, 0 } +}; + //4 8 16 32 64 128 //0 1 2 3 4 5 diff --git a/src/rdo.c b/src/rdo.c index 321d86a5..81fc2449 100644 --- a/src/rdo.c +++ b/src/rdo.c @@ -308,7 +308,7 @@ void rdoq(encoder_control *encoder, coefficient *coef, coefficient *dest_coeff, int32_t delta_u [ 32 * 32 ]; - const uint32_t *scan_cg = NULL; + const uint32_t *scan_cg = g_sig_last_scan_cg[log2_block_size - 2][scan_mode]; const int32_t shift = 4>>1; const uint32_t cg_size = 16; const uint32_t num_blk_side = width >> shift; @@ -358,14 +358,6 @@ void rdoq(encoder_control *encoder, coefficient *coef, coefficient *dest_coeff, memset( cost_coeffgroup_sig, 0, sizeof(double) * 64 ); memset( sig_coeffgroup_flag, 0, sizeof(uint32_t) * 64 ); - scan_cg = g_sig_last_scan[scan_mode][log2_block_size > 3 ? log2_block_size - 3 : 0]; - - if (log2_block_size == 3) { - scan_cg = g_sig_last_scan_8x8[scan_mode]; - } else if (log2_block_size == 5) { - scan_cg = g_sig_last_scan_32x32; - } - for (cg_scanpos = cg_num-1; cg_scanpos >= 0; cg_scanpos--) { uint32_t cg_blkpos = scan_cg[ cg_scanpos ]; uint32_t cg_pos_y = cg_blkpos / num_blk_side;