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.
This commit is contained in:
Ari Koivula 2014-03-14 15:45:23 +02:00
parent 319174258b
commit 9563b50a34
3 changed files with 66 additions and 46 deletions

View file

@ -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

View file

@ -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

View file

@ -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;