Add palette coding mode for inter frames

on screen_content
--enable-palette                                    +6.74%

on derflr
with all other experiments                          +6.02%
(--enable-supertx --enable-copy-mode
 --enable-ext-tx --enable-filterintra
 --enable-tx64x64 --enable-tx-skip
 --enable-interintra --enable-wedge-partition
 --enable-compound-modes --enable-new-quant
 --enable-palette)

Change-Id: Ib85049b4c3fcf52bf95efbc9d6aecf53d53ca1a3
This commit is contained in:
hui su 2015-02-25 10:00:40 -08:00
parent 73dcd41b72
commit 070d635657
10 changed files with 934 additions and 364 deletions

View File

@ -113,7 +113,7 @@ typedef enum {
typedef enum {
H_SCAN,
V_SCAN,
SPIN_SCAN,
SPIRAL_SCAN,
ZZ_SCAN,
PALETTE_SCAN_ORDERS
} PALETTE_SCAN_ORDER;
@ -365,6 +365,8 @@ typedef struct macroblockd {
DECLARE_ALIGNED(16, tran_low_t, dqcoeff[MAX_MB_PLANE][64 * 64]);
#if CONFIG_PALETTE
DECLARE_ALIGNED(16, uint8_t, color_index_map[2][64 * 64]);
DECLARE_ALIGNED(16, int, palette_scan_buffer[64 * 64]);
DECLARE_ALIGNED(16, uint8_t, palette_map_buffer[64 * 64]);
#endif
ENTROPY_CONTEXT *above_context[MAX_MB_PLANE];

View File

@ -41,7 +41,7 @@ void insertion_sort(double *data, int n) {
int count_colors(const uint8_t *src, int stride, int rows, int cols) {
int n = 0, r, c, i, val_count[256];
uint8_t val;
memset(val_count, 0, sizeof(val_count));
vpx_memset(val_count, 0, sizeof(val_count));
for (r = 0; r < rows; r++) {
for (c = 0; c < cols; c++) {
@ -85,7 +85,7 @@ int run_lengh_decoding(uint16_t *runs, int l, uint8_t *seq) {
int i, j = 0;
for (i = 0; i < l; i += 2) {
memset(seq + j, runs[i], runs[i + 1]);
vpx_memset(seq + j, runs[i], runs[i + 1]);
j += runs[i + 1];
}
@ -94,14 +94,10 @@ int run_lengh_decoding(uint16_t *runs, int l, uint8_t *seq) {
void transpose_block(uint8_t *seq_in, uint8_t *seq_out, int rows, int cols) {
int r, c;
uint8_t seq_dup[4096];
memcpy(seq_dup, seq_in, rows * cols);
for (r = 0; r < cols; r++) {
for (c = 0; c < rows; c++) {
seq_out[r * rows + c] = seq_dup[c * cols + r];
}
}
for (r = 0; r < cols; r++)
for (c = 0; c < rows; c++)
seq_out[r * rows + c] = seq_in[c * cols + r];
}
void palette_color_insertion(uint8_t *old_colors, int *m, int *count,
@ -230,8 +226,8 @@ void calc_centroids(double *data, double *centroids, int *indices,
int i, j, index;
int count[256];
unsigned int seed = time(NULL);
memset(count, 0, sizeof(count[0]) * k);
memset(centroids, 0, sizeof(centroids[0]) * k * dim);
vpx_memset(count, 0, sizeof(count[0]) * k);
vpx_memset(centroids, 0, sizeof(centroids[0]) * k * dim);
for (i = 0; i < n; i++) {
index = indices[i];
@ -243,8 +239,8 @@ void calc_centroids(double *data, double *centroids, int *indices,
for (i = 0; i < k; i++) {
if (!count[i])
memcpy(centroids + i * dim, data + (rand_r(&seed) % n) * dim,
sizeof(centroids[0]) * dim);
vpx_memcpy(centroids + i * dim, data + (rand_r(&seed) % n) * dim,
sizeof(centroids[0]) * dim);
else
for (j = 0; j < dim; j++)
centroids[i * dim + j] /= count[i];
@ -267,32 +263,35 @@ double calc_total_dist(double *data, double *centroids, int *indices,
int k_means(double *data, double *centroids, int *indices,
int n, int k, int dim, int max_itr) {
int i = 0;
int pre_indices[4096];
int *pre_indices;
double pre_total_dist, cur_total_dist;
double pre_centroids[256];
pre_indices = vpx_memalign(16, n * sizeof(indices[0]));
calc_indices(data, centroids, indices, n, k, dim);
pre_total_dist = calc_total_dist(data, centroids, indices, n, k, dim);
memcpy(pre_centroids, centroids, sizeof(pre_centroids[0]) * k * dim);
memcpy(pre_indices, indices, sizeof(pre_indices[0]) * n);
vpx_memcpy(pre_centroids, centroids, sizeof(pre_centroids[0]) * k * dim);
vpx_memcpy(pre_indices, indices, sizeof(pre_indices[0]) * n);
while (i < max_itr) {
calc_centroids(data, centroids, indices, n, k, dim);
calc_indices(data, centroids, indices, n, k, dim);
cur_total_dist = calc_total_dist(data, centroids, indices, n, k, dim);
if (cur_total_dist > pre_total_dist && 0) {
memcpy(centroids, pre_centroids, sizeof(pre_centroids[0]) * k * dim);
memcpy(indices, pre_indices, sizeof(pre_indices[0]) * n);
vpx_memcpy(centroids, pre_centroids, sizeof(pre_centroids[0]) * k * dim);
vpx_memcpy(indices, pre_indices, sizeof(pre_indices[0]) * n);
break;
}
if (!memcmp(centroids, pre_centroids, sizeof(pre_centroids[0]) * k * dim))
break;
memcpy(pre_centroids, centroids, sizeof(pre_centroids[0]) * k * dim);
memcpy(pre_indices, indices, sizeof(pre_indices[0]) * n);
vpx_memcpy(pre_centroids, centroids, sizeof(pre_centroids[0]) * k * dim);
vpx_memcpy(pre_indices, indices, sizeof(pre_indices[0]) * n);
pre_total_dist = cur_total_dist;
i++;
}
vpx_free(pre_indices);
return i;
}
@ -305,7 +304,7 @@ int is_in_boundary(int rows, int cols, int r, int c) {
void zz_scan_order(int *order, int rows, int cols) {
int r, c, dir, idx;
memset(order, 0, sizeof(order[0]) * rows * cols);
vpx_memset(order, 0, sizeof(order[0]) * rows * cols);
r = 0;
c = 0;
dir = 1;
@ -339,7 +338,7 @@ void zz_scan_order(int *order, int rows, int cols) {
order[idx] = (rows - 1) * cols + cols - 1;
}
void spin_order(int *order, int cols, int r_start, int c_start,
void spiral_order(int *order, int cols, int r_start, int c_start,
int h, int w, int idx) {
int r, c;
@ -367,10 +366,62 @@ void spin_order(int *order, int cols, int r_start, int c_start,
for (c = 0; c < w; c++)
order[idx++] = r_start * cols + w - c + c_start;
spin_order(order, cols, r_start + 1, c_start + 1, h - 2, w - 2, idx);
spiral_order(order, cols, r_start + 1, c_start + 1, h - 2, w - 2, idx);
}
void spin_scan_order(int *order, int rows, int cols) {
spin_order(order, cols, 0, 0, rows - 1, cols - 1, 0);
void spiral_scan_order(int *order, int rows, int cols) {
spiral_order(order, cols, 0, 0, rows - 1, cols - 1, 0);
}
void palette_scan(uint8_t *color_index_map, uint8_t *sequence,
int rows, int cols, PALETTE_SCAN_ORDER ps, int *scan_order) {
int i;
switch (ps) {
case H_SCAN:
vpx_memcpy(sequence, color_index_map, rows * cols);
break;
case V_SCAN:
transpose_block(color_index_map, sequence, rows, cols);
break;
case SPIRAL_SCAN:
spiral_scan_order(scan_order, rows, cols);
for (i = 0; i < rows * cols; i++)
sequence[i] = color_index_map[scan_order[i]];
break;
case ZZ_SCAN:
zz_scan_order(scan_order, rows, cols);
for (i = 0; i < rows * cols; i++)
sequence[i] = color_index_map[scan_order[i]];
break;
default:
break;
}
}
void palette_iscan(uint8_t *color_index_map, uint8_t *sequence,
int rows, int cols, PALETTE_SCAN_ORDER ps, int *scan_order) {
int i;
switch (ps) {
case H_SCAN:
vpx_memcpy(color_index_map, sequence, rows * cols);
break;
case V_SCAN:
transpose_block(sequence, color_index_map, cols, rows);
break;
case SPIRAL_SCAN:
spiral_scan_order(scan_order, rows, cols);
for (i = 0; i < rows * cols; i++)
color_index_map[scan_order[i]] = sequence[i];
break;
case ZZ_SCAN:
zz_scan_order(scan_order, rows, cols);
for (i = 0; i < rows * cols; i++)
color_index_map[scan_order[i]] = sequence[i];
break;
default:
break;
}
}
#endif

View File

@ -29,7 +29,11 @@ int k_means(double *data, double *centroids, int *indices,
void calc_indices(double *data, double *centroids, int *indices,
int n, int k, int dim);
void zz_scan_order(int *order, int rows, int cols);
void spin_scan_order(int *order, int rows, int cols);
void spiral_scan_order(int *order, int rows, int cols);
void palette_scan(uint8_t *color_index_map, uint8_t *sequence,
int rows, int cols, PALETTE_SCAN_ORDER ps, int *scan_order);
void palette_iscan(uint8_t *color_index_map, uint8_t *sequence,
int rows, int cols, PALETTE_SCAN_ORDER ps, int *scan_order);
#endif
#endif // VP9_COMMON_VP9_PALETTE_H_

View File

@ -271,11 +271,11 @@ static void vp9_intra_dpcm_add_nocoeff(uint8_t *dst, int stride,
switch (mode) {
case H_PRED:
for (r = 0; r < bs; r++)
memset(dst + r * stride + 1, dst[r * stride], bs - 1);
vpx_memset(dst + r * stride + 1, dst[r * stride], bs - 1);
break;
case V_PRED:
for (r = 1; r < bs; r++)
memcpy(dst + r * stride, dst, bs * sizeof(*dst));
vpx_memcpy(dst + r * stride, dst, bs * sizeof(*dst));
break;
case TM_PRED:
for (r = 1; r < bs; r++)

View File

@ -235,8 +235,6 @@ static void read_intra_frame_mode_info(VP9_COMMON *const cm,
int i, m1, m2, d, val;
int rows = 4 * num_4x4_blocks_high_lookup[bsize];
int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
int scan_order[4096];
uint8_t map[4096];
PALETTE_RUN_LENGTH bits;
mbmi->mode = DC_PRED;
@ -279,8 +277,8 @@ static void read_intra_frame_mode_info(VP9_COMMON *const cm,
s * vp9_read_literal(r, mbmi->palette_delta_bitdepth);
}
} else {
memset(mbmi->palette_color_delta, 0,
m1 * sizeof(mbmi->palette_color_delta[0]));
vpx_memset(mbmi->palette_color_delta, 0,
m1 * sizeof(mbmi->palette_color_delta[0]));
}
for (i = 0; i < m1; i++) {
val = cm->current_palette_colors[mbmi->palette_indexed_colors[i]];
@ -314,27 +312,11 @@ static void read_intra_frame_mode_info(VP9_COMMON *const cm,
&cm ->current_palette_size,
cm->current_palette_count, mbmi);
run_lengh_decoding(mbmi->palette_runs, mbmi->palette_run_length[0], map);
switch (mbmi->palette_scan_order[0]) {
case H_SCAN:
memcpy(xd->plane[0].color_index_map, map, rows * cols);
break;
case V_SCAN:
transpose_block(map, xd->plane[0].color_index_map, cols, rows);
break;
case SPIN_SCAN:
spin_scan_order(scan_order, rows, cols);
for (i = 0; i < rows * cols; i++)
xd->plane[0].color_index_map[scan_order[i]] = map[i];
break;
case ZZ_SCAN:
zz_scan_order(scan_order, rows, cols);
for (i = 0; i < rows * cols; i++)
xd->plane[0].color_index_map[scan_order[i]] = map[i];
break;
default:
break;
}
run_lengh_decoding(mbmi->palette_runs, mbmi->palette_run_length[0],
xd->palette_map_buffer);
palette_iscan(xd->plane[0].color_index_map, xd->palette_map_buffer,
rows, cols, mbmi->palette_scan_order[0],
xd->palette_scan_buffer);
mbmi->tx_size = MIN(max_txsize_lookup[bsize],
tx_mode_to_biggest_tx_size[cm->tx_mode]);
}
@ -345,8 +327,6 @@ static void read_intra_frame_mode_info(VP9_COMMON *const cm,
xd->plane[1].subsampling_y;
int cols = 4 * num_4x4_blocks_wide_lookup[bsize] >>
xd->plane[1].subsampling_x;
int scan_order[4096];
uint8_t map[4096];
PALETTE_RUN_LENGTH bits;
BLOCK_SIZE uv_bsize = get_plane_block_size(bsize, &xd->plane[1]);
@ -387,27 +367,9 @@ static void read_intra_frame_mode_info(VP9_COMMON *const cm,
}
run_lengh_decoding(mbmi->palette_runs + PALETTE_MAX_RUNS,
mbmi->palette_run_length[1], map);
switch (mbmi->palette_scan_order[1]) {
case H_SCAN:
memcpy(xd->plane[1].color_index_map, map, rows * cols);
break;
case V_SCAN:
transpose_block(map, xd->plane[1].color_index_map, cols, rows);
break;
case SPIN_SCAN:
spin_scan_order(scan_order, rows, cols);
for (i = 0; i < rows * cols; i++)
xd->plane[1].color_index_map[scan_order[i]] = map[i];
break;
case ZZ_SCAN:
zz_scan_order(scan_order, rows, cols);
for (i = 0; i < rows * cols; i++)
xd->plane[1].color_index_map[scan_order[i]] = map[i];
break;
default:
break;
}
mbmi->palette_run_length[1], xd->palette_map_buffer);
palette_iscan(xd->plane[1].color_index_map, xd->palette_map_buffer, rows,
cols, mbmi->palette_scan_order[1], xd->palette_scan_buffer);
}
}
@ -757,36 +719,67 @@ static void read_intra_block_mode_info(VP9_COMMON *const cm, MODE_INFO *mi,
#endif
break;
default:
#if CONFIG_PALETTE
if (!mbmi->palette_enabled[0]) {
mbmi->mode = read_intra_mode_y(cm, r, size_group_lookup[bsize]);
} else {
mbmi->mode = DC_PRED;
if (!cm->frame_parallel_decoding_mode)
++cm->counts.y_mode[size_group_lookup[bsize]][DC_PRED];
}
#else
mbmi->mode = read_intra_mode_y(cm, r, size_group_lookup[bsize]);
#endif // CONFIG_PALETTE
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mbmi->mode) && is_filter_enabled(mbmi->tx_size)) {
if (is_filter_allowed(mbmi->mode) && is_filter_enabled(mbmi->tx_size)
#if CONFIG_PALETTE
&& !mbmi->palette_enabled[0]
#endif // CONFIG_PALETTE
) {
mbmi->filterbit = vp9_read(r,
cm->fc.filterintra_prob[mbmi->tx_size][mbmi->mode]);
cm->counts.filterintra[mbmi->tx_size][mbmi->mode][mbmi->filterbit]++;
} else {
mbmi->filterbit = 0;
#if CONFIG_PALETTE
if (mbmi->palette_enabled[0])
cm->counts.filterintra[mbmi->tx_size][mbmi->mode][mbmi->filterbit]++;
#endif // CONFIG_PALETTE
}
#endif
#endif // CONFIG_FILTERINTRA
}
#if CONFIG_PALETTE
if (!mbmi->palette_enabled[1]) {
mbmi->uv_mode = read_intra_mode_uv(cm, r, mbmi->mode);
} else {
mbmi->uv_mode = DC_PRED;
if (!cm->frame_parallel_decoding_mode)
++cm->counts.uv_mode[mbmi->mode][DC_PRED];
}
#else
mbmi->uv_mode = read_intra_mode_uv(cm, r, mbmi->mode);
#endif // CONFIG_PALETTE
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mbmi->uv_mode) &&
is_filter_enabled(get_uv_tx_size(mbmi, &xd->plane[1]))) {
is_filter_enabled(get_uv_tx_size(mbmi, &xd->plane[1]))
#if CONFIG_PALETTE
&& !mbmi->palette_enabled[1]
#endif // CONFIG_PALETTE
) {
mbmi->uv_filterbit = vp9_read(r,
cm->fc.filterintra_prob[get_uv_tx_size(mbmi, &xd->plane[1])][mbmi->uv_mode]);
cm->counts.filterintra[get_uv_tx_size(mbmi, &xd->plane[1])]
[mbmi->uv_mode][mbmi->uv_filterbit]++;
} else {
mbmi->uv_filterbit = 0;
#if CONFIG_PALETTE
if (mbmi->palette_enabled[1])
cm->counts.filterintra[get_uv_tx_size(mbmi, &xd->plane[1])]
[mbmi->uv_mode][mbmi->uv_filterbit]++;
#endif // CONFIG_PALETTE
}
#endif // CONFIG_FILTERINTRA
#if CONFIG_PALETTE
for (i = 0; i < 2; ++i) {
mbmi->palette_enabled[i] = 0;
}
#endif // CONFIG_PALETTE
}
static INLINE int is_mv_valid(const MV *mv) {
@ -1254,8 +1247,124 @@ static void read_inter_frame_mode_info(VP9_COMMON *const cm,
if (mbmi->copy_mode == NOREF)
#endif
inter_block = read_is_inter_block(cm, xd, mbmi->segment_id, r);
#if CONFIG_PALETTE
mbmi->palette_enabled[0] = 0;
mbmi->palette_enabled[1] = 0;
if (!inter_block && mbmi->sb_type >= BLOCK_8X8 && cm->allow_palette_mode) {
mbmi->palette_enabled[0] = vp9_read_bit(r);
mbmi->palette_enabled[1] = vp9_read_bit(r);
}
if (mbmi->palette_enabled[0]) {
BLOCK_SIZE bsize = mbmi->sb_type;
int i, d;
int rows = 4 * num_4x4_blocks_high_lookup[bsize];
int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
PALETTE_RUN_LENGTH bits;
mbmi->mode = DC_PRED;
mbmi->palette_size[0] =
vp9_read_tree(r, vp9_palette_size_tree,
cm->fc.palette_size_prob[bsize - BLOCK_8X8]);
mbmi->palette_size[0] += 2;
mbmi->palette_run_length[0] =
vp9_read_literal(r, get_bit_depth(palette_max_run(bsize)));
mbmi->palette_run_length[0] = (mbmi->palette_run_length[0]) << 1;
mbmi->palette_scan_order[0] = vp9_read_literal(r, 2);
for (i = 0; i < mbmi->palette_size[0]; i++) {
mbmi->palette_colors[i] = vp9_read_literal(r, 8);
}
d = get_bit_depth(rows * cols);
for (i = 0; i < mbmi->palette_run_length[0]; i += 2) {
mbmi->palette_runs[i] =
vp9_read_literal(r, get_bit_depth(mbmi->palette_size[0]));
bits = vp9_read_tree(r, vp9_palette_run_length_tree,
cm->fc.palette_run_length_prob[bsize - BLOCK_8X8]);
if (bits == MAX_BITS)
mbmi->palette_runs[i + 1] = vp9_read_literal(r, d);
else
mbmi->palette_runs[i + 1] = vp9_read_literal(r, bits - ONE_BITS + 1);
mbmi->palette_runs[i + 1] += 1;
}
run_lengh_decoding(mbmi->palette_runs, mbmi->palette_run_length[0],
xd->palette_map_buffer);
palette_iscan(xd->plane[0].color_index_map, xd->palette_map_buffer, rows,
cols, mbmi->palette_scan_order[0], xd->palette_scan_buffer);
mbmi->tx_size = MIN(max_txsize_lookup[bsize],
tx_mode_to_biggest_tx_size[cm->tx_mode]);
if (!cm->frame_parallel_decoding_mode)
++get_tx_counts(max_txsize_lookup[bsize], vp9_get_tx_size_context(xd),
&cm->counts.tx)[mbmi->tx_size];
}
if (mbmi->palette_enabled[1]) {
int i, d;
BLOCK_SIZE bsize = mbmi->sb_type;
int rows = 4 * num_4x4_blocks_high_lookup[bsize] >>
xd->plane[1].subsampling_y;
int cols = 4 * num_4x4_blocks_wide_lookup[bsize] >>
xd->plane[1].subsampling_y;
PALETTE_RUN_LENGTH bits;
BLOCK_SIZE uv_bsize = get_plane_block_size(bsize, &xd->plane[1]);
mbmi->uv_mode = DC_PRED;
if (xd->plane[1].subsampling_x && xd->plane[1].subsampling_y) {
mbmi->palette_size[1] =
vp9_read_tree(r, vp9_palette_size_tree,
cm->fc.palette_uv_size_prob[uv_bsize - BLOCK_4X4]);
mbmi->palette_size[1] += 2;
mbmi->palette_run_length[1] =
vp9_read_literal(r, get_bit_depth(palette_max_run(uv_bsize)));
mbmi->palette_run_length[1] = (mbmi->palette_run_length[1]) << 1;
mbmi->palette_scan_order[1] = vp9_read_literal(r, 2);
} else {
mbmi->palette_size[1] = mbmi->palette_size[0];
}
for (i = 0; i < mbmi->palette_size[1]; i++)
mbmi->palette_colors[PALETTE_MAX_SIZE + i] = vp9_read_literal(r, 8);
for (i = 0; i < mbmi->palette_size[1]; i++)
mbmi->palette_colors[2 * PALETTE_MAX_SIZE + i] = vp9_read_literal(r, 8);
if (xd->plane[1].subsampling_x && xd->plane[1].subsampling_y) {
d = get_bit_depth(rows * cols);
for (i = 0; i < mbmi->palette_run_length[1]; i += 2) {
mbmi->palette_runs[PALETTE_MAX_RUNS + i] =
vp9_read_literal(r, get_bit_depth(mbmi->palette_size[1]));
bits = vp9_read_tree(r, vp9_palette_run_length_tree,
cm->fc.palette_uv_run_length_prob[uv_bsize -
BLOCK_4X4]);
if (bits == MAX_BITS)
mbmi->palette_runs[PALETTE_MAX_RUNS + i + 1] =
vp9_read_literal(r, d);
else
mbmi->palette_runs[PALETTE_MAX_RUNS + i + 1] =
vp9_read_literal(r, bits - ONE_BITS + 1);
mbmi->palette_runs[ PALETTE_MAX_RUNS + i + 1] += 1;
}
run_lengh_decoding(mbmi->palette_runs + PALETTE_MAX_RUNS,
mbmi->palette_run_length[1], xd->palette_map_buffer);
palette_iscan(xd->plane[1].color_index_map, xd->palette_map_buffer,
rows, cols, mbmi->palette_scan_order[1],
xd->palette_scan_buffer);
}
}
if (!mbmi->palette_enabled[0]) {
mbmi->tx_size = read_tx_size(cm, xd, cm->tx_mode, mbmi->sb_type,
!mbmi->skip || !inter_block, r);
}
#else
mbmi->tx_size = read_tx_size(cm, xd, cm->tx_mode, mbmi->sb_type,
!mbmi->skip || !inter_block, r);
!mbmi->skip || !inter_block, r);
#endif
#if CONFIG_EXT_TX
if (inter_block &&
mbmi->tx_size <= TX_16X16 &&

View File

@ -266,8 +266,8 @@ int vp9_receive_compressed_data(VP9Decoder *pbi,
#if CONFIG_PALETTE
if (frame_is_intra_only(cm)) {
cm->current_palette_size = 0;
memset(cm->current_palette_count, 0,
PALETTE_BUF_SIZE * sizeof(cm->current_palette_count[0]));
vpx_memset(cm->current_palette_count, 0,
PALETTE_BUF_SIZE * sizeof(cm->current_palette_count[0]));
}
#endif

View File

@ -462,10 +462,92 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
}
#endif
#if CONFIG_PALETTE
if (!is_inter && bsize >= BLOCK_8X8 && cm->allow_palette_mode) {
int l, n, i, d, bits;
vp9_write_bit(w, mbmi->palette_enabled[0]);
vp9_write_bit(w, mbmi->palette_enabled[1]);
if (mbmi->palette_enabled[0]) {
int rows = 4 * num_4x4_blocks_high_lookup[bsize];
int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
n = mbmi->palette_size[0];
l = mbmi->palette_run_length[0];
vp9_write_token(w, vp9_palette_size_tree,
cm->fc.palette_size_prob[bsize - BLOCK_8X8],
&palette_size_encodings[n - 2]);
vp9_write_literal(w, (l >> 1),
get_bit_depth(palette_max_run(bsize)));
vp9_write_literal(w, mbmi->palette_scan_order[0], 2);
for (i = 0; i < n; i++)
vp9_write_literal(w, mbmi->palette_colors[i], 8);
d = get_bit_depth(rows * cols);
for (i = 0; i < l; i += 2) {
vp9_write_literal(w, mbmi->palette_runs[i],
get_bit_depth(n));
bits = get_bit_depth(mbmi->palette_runs[i + 1]);
vp9_write_token(w, vp9_palette_run_length_tree,
cm->fc.palette_run_length_prob[bsize - BLOCK_8X8],
&palette_run_length_encodings[bits > 6 ?
6 : bits - 1]);
vp9_write_literal(w, mbmi->palette_runs[i + 1] - 1,
bits > 6 ? d : bits);
}
}
if (mbmi->palette_enabled[1]) {
const uint16_t *runs = mbmi->palette_runs + PALETTE_MAX_RUNS;
int rows = 4 * num_4x4_blocks_high_lookup[bsize] >>
xd->plane[1].subsampling_y;
int cols = 4 * num_4x4_blocks_wide_lookup[bsize] >>
xd->plane[1].subsampling_x;
BLOCK_SIZE uv_bsize = get_plane_block_size(bsize, &xd->plane[1]);
n = mbmi->palette_size[1];
l = mbmi->palette_run_length[1];
if (xd->plane[1].subsampling_x && xd->plane[1].subsampling_y) {
vp9_write_token(w, vp9_palette_size_tree,
cm->fc.palette_uv_size_prob[uv_bsize - BLOCK_4X4],
&palette_size_encodings[n - 2]);
vp9_write_literal(w, (l >> 1),
get_bit_depth(palette_max_run(uv_bsize)));
vp9_write_literal(w, mbmi->palette_scan_order[1], 2);
}
for (i = 0; i < n; i++)
vp9_write_literal(w, mbmi->palette_colors[PALETTE_MAX_SIZE + i], 8);
for (i = 0; i < n; i++)
vp9_write_literal(w, mbmi->palette_colors[2 * PALETTE_MAX_SIZE + i], 8);
if (xd->plane[1].subsampling_x && xd->plane[1].subsampling_y) {
d = get_bit_depth(rows * cols);
for (i = 0; i < l; i += 2) {
vp9_write_literal(w, runs[i],
get_bit_depth(mbmi->palette_size[1]));
bits = get_bit_depth(runs[i + 1]);
vp9_write_token(w, vp9_palette_run_length_tree,
cm->fc.palette_uv_run_length_prob[uv_bsize -
BLOCK_4X4],
&palette_run_length_encodings[bits > 6 ?
6 : bits - 1]);
vp9_write_literal(w, runs[i + 1] - 1,
bits > 6 ? d : bits);
}
}
}
}
#endif
if (bsize >= BLOCK_8X8 && cm->tx_mode == TX_MODE_SELECT &&
#if CONFIG_SUPERTX
!supertx_enabled &&
#endif
#endif // CONFIG_SUPERTX
#if CONFIG_PALETTE
!mbmi->palette_enabled[0] &&
#endif // CONFIG_PALETTE
!(is_inter &&
(skip || vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP)))) {
write_selected_tx_size(cm, xd, mbmi->tx_size, bsize, w);
@ -527,13 +609,22 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
if (!is_inter) {
if (bsize >= BLOCK_8X8) {
#if CONFIG_PALETTE
if (!mbmi->palette_enabled[0])
write_intra_mode(w, mode, cm->fc.y_mode_prob[size_group_lookup[bsize]]);
#else
write_intra_mode(w, mode, cm->fc.y_mode_prob[size_group_lookup[bsize]]);
#endif // CONFIG_PALETTE
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mode) && is_filter_enabled(mbmi->tx_size)) {
if (is_filter_allowed(mode) && is_filter_enabled(mbmi->tx_size)
#if CONFIG_PALETTE
&& !mbmi->palette_enabled[0]
#endif // CONFIG_PALETTE
) {
vp9_write(w, mbmi->filterbit,
cm->fc.filterintra_prob[mbmi->tx_size][mode]);
}
#endif
#endif // CONFIG_FILTERINTRA
} else {
int idx, idy;
const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
@ -547,29 +638,38 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
vp9_write(w, mi->b_filter_info[idy * 2 + idx],
cm->fc.filterintra_prob[0][b_mode]);
}
#endif
#endif // CONFIG_FILTERINTRA
}
}
}
#if CONFIG_PALETTE
if (!mbmi->palette_enabled[1])
write_intra_mode(w, mbmi->uv_mode, cm->fc.uv_mode_prob[mode]);
#else
write_intra_mode(w, mbmi->uv_mode, cm->fc.uv_mode_prob[mode]);
#endif // CONFIG_PALETTE
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mbmi->uv_mode) &&
is_filter_enabled(get_uv_tx_size(mbmi, &xd->plane[1]))) {
is_filter_enabled(get_uv_tx_size(mbmi, &xd->plane[1]))
#if CONFIG_PALETTE
&& !mbmi->palette_enabled[1]
#endif // CONFIG_PALETTE
) {
vp9_write(w, mbmi->uv_filterbit,
cm->fc.filterintra_prob[get_uv_tx_size(mbmi, &xd->plane[1])][mbmi->uv_mode]);
}
#endif
#endif // CONFIG_FILTERINTRA
#if CONFIG_COPY_MODE
} else if (mbmi->copy_mode == NOREF) {
#else
} else {
#endif
#endif // CONFIG_COPY_MODE
const int mode_ctx = mbmi->mode_context[mbmi->ref_frame[0]];
const vp9_prob *const inter_probs = cm->fc.inter_mode_probs[mode_ctx];
#if CONFIG_COMPOUND_MODES
const vp9_prob *const inter_compound_probs =
cm->fc.inter_compound_mode_probs[mode_ctx];
#endif
#endif // CONFIG_COMPOUND_MODES
write_ref_frames(cm, xd, w);
// If segment skip is not enabled code the mode.
@ -602,7 +702,7 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
is_inter_mode(mode) &&
#if CONFIG_SUPERTX
!supertx_enabled &&
#endif
#endif // CONFIG_SUPERTX
mbmi->ref_frame[1] <= INTRA_FRAME) {
vp9_write(w, mbmi->ref_frame[1] == INTRA_FRAME,
cm->fc.interintra_prob[bsize]);
@ -645,7 +745,7 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
if (b_mode == NEWMV || b_mode == NEW_NEWMV) {
#else
if (b_mode == NEWMV) {
#endif
#endif // CONFIG_COMPOUND_MODES
for (ref = 0; ref < 1 + is_compound; ++ref) {
vp9_encode_mv(cpi, w, &mi->bmi[j].as_mv[ref].as_mv,
#if CONFIG_NEWMVREF_SUB8X8
@ -682,7 +782,7 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
if (mode == NEWMV || mode == NEW_NEWMV) {
#else
if (mode == NEWMV) {
#endif
#endif // CONFIG_COMPOUND_MODES
for (ref = 0; ref < 1 + is_compound; ++ref)
vp9_encode_mv(cpi, w, &mbmi->mv[ref].as_mv,
&mbmi->ref_mvs[mbmi->ref_frame[ref]][0].as_mv, nmvc,
@ -698,7 +798,7 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
&mbmi->ref_mvs[mbmi->ref_frame[0]][0].as_mv, nmvc,
allow_hp);
}
#endif
#endif // CONFIG_COMPOUND_MODES
}
#if CONFIG_WEDGE_PARTITION
if (cm->reference_mode != SINGLE_REFERENCE &&

View File

@ -124,7 +124,11 @@ struct macroblock {
#if CONFIG_VP9_HIGHBITDEPTH
void (*highbd_itxm_add)(const tran_low_t *input, uint8_t *dest, int stride,
int eob, int bd);
#endif
#endif // CONFIG_VP9_HIGHBITDEPTH
#if CONFIG_PALETTE
DECLARE_ALIGNED(16, double, kmeans_data_buffer[MAX_MB_PLANE * 64 * 64]);
DECLARE_ALIGNED(16, int, kmeans_indices_buffer[64 * 64]);
#endif // CONFIG_PALETTE
};
#ifdef __cplusplus

View File

@ -369,10 +369,10 @@ static void set_offsets_extend(VP9_COMP *cpi, const TileInfo *const tile,
#if CONFIG_PALETTE
void copy_palette_info(PICK_MODE_CONTEXT *c, PICK_MODE_CONTEXT *p) {
c->palette_buf_size = p->palette_buf_size;
memcpy(c->palette_colors_buf, p->palette_colors_buf,
c->palette_buf_size * sizeof(c->palette_colors_buf[0]));
memcpy(c->palette_count_buf, p->palette_count_buf,
c->palette_buf_size * sizeof(c->palette_count_buf[0]));
vpx_memcpy(c->palette_colors_buf, p->palette_colors_buf,
c->palette_buf_size * sizeof(c->palette_colors_buf[0]));
vpx_memcpy(c->palette_count_buf, p->palette_count_buf,
c->palette_buf_size * sizeof(c->palette_count_buf[0]));
}
#endif
@ -1363,19 +1363,23 @@ static void rd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile,
uint8_t palette[PALETTE_BUF_SIZE];
int count[PALETTE_BUF_SIZE];
memcpy(palette, cpi->common.current_palette_colors, n * sizeof(palette[0]));
memcpy(count, cpi->common.current_palette_count, n * sizeof(count[0]));
vpx_memcpy(palette, cpi->common.current_palette_colors,
n * sizeof(palette[0]));
vpx_memcpy(count, cpi->common.current_palette_count,
n * sizeof(count[0]));
cpi->common.current_palette_size = ctx->palette_buf_size;
memcpy(cpi->common.current_palette_colors, ctx->palette_colors_buf,
ctx->palette_buf_size * sizeof(ctx->palette_colors_buf[0]));
memcpy(cpi->common.current_palette_count, ctx->palette_count_buf,
ctx->palette_buf_size * sizeof(ctx->palette_count_buf[0]));
vpx_memcpy(cpi->common.current_palette_colors, ctx->palette_colors_buf,
ctx->palette_buf_size * sizeof(ctx->palette_colors_buf[0]));
vpx_memcpy(cpi->common.current_palette_count, ctx->palette_count_buf,
ctx->palette_buf_size * sizeof(ctx->palette_count_buf[0]));
#endif
vp9_rd_pick_intra_mode_sb(cpi, x, rd_cost, bsize, ctx, best_rd);
#if CONFIG_PALETTE
cpi->common.current_palette_size = n;
memcpy(cpi->common.current_palette_colors, palette, n * sizeof(palette[0]));
memcpy(cpi->common.current_palette_count, count, n * sizeof(count[0]));
vpx_memcpy(cpi->common.current_palette_colors,
palette, n * sizeof(palette[0]));
vpx_memcpy(cpi->common.current_palette_count,
count, n * sizeof(count[0]));
#endif
#if CONFIG_SUPERTX
*totalrate_nocoef = 0;
@ -2831,18 +2835,18 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
if (bsize == BLOCK_64X64) {
c = &pc_tree->current;
c->palette_buf_size = cm->current_palette_size;
memcpy(c->palette_colors_buf, cm->current_palette_colors,
c->palette_buf_size * sizeof(cm->current_palette_colors[0]));
memcpy(c->palette_count_buf, cm->current_palette_count,
c->palette_buf_size * sizeof(cm->current_palette_count[0]));
vpx_memcpy(c->palette_colors_buf, cm->current_palette_colors,
c->palette_buf_size * sizeof(cm->current_palette_colors[0]));
vpx_memcpy(c->palette_count_buf, cm->current_palette_count,
c->palette_buf_size * sizeof(cm->current_palette_count[0]));
}
c = &pc_tree->current;
previous_size = c->palette_buf_size;
memcpy(previous_colors, c->palette_colors_buf,
previous_size * sizeof(previous_colors[0]));
memcpy(previous_count, c->palette_count_buf,
previous_size * sizeof(previous_count[0]));
vpx_memcpy(previous_colors, c->palette_colors_buf,
previous_size * sizeof(previous_colors[0]));
vpx_memcpy(previous_count, c->palette_count_buf,
previous_size * sizeof(previous_count[0]));
c = &pc_tree->none;
p = &pc_tree->current;
@ -3141,10 +3145,10 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
c = &pc_tree->split[i]->current;
if (last < 0) {
c->palette_buf_size = previous_size;
memcpy(c->palette_colors_buf, previous_colors,
previous_size * sizeof(previous_colors[0]));
memcpy(c->palette_count_buf, previous_count,
previous_size * sizeof(previous_count[0]));
vpx_memcpy(c->palette_colors_buf, previous_colors,
previous_size * sizeof(previous_colors[0]));
vpx_memcpy(c->palette_count_buf, previous_count,
previous_size * sizeof(previous_count[0]));
} else {
p = &pc_tree->split[last]->current;
copy_palette_info(c, p);
@ -3250,10 +3254,10 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
} else {
c = &pc_tree->current;
c->palette_buf_size = previous_size;
memcpy(c->palette_colors_buf, previous_colors,
previous_size * sizeof(previous_colors[0]));
memcpy(c->palette_count_buf, previous_count,
previous_size * sizeof(previous_count[0]));
vpx_memcpy(c->palette_colors_buf, previous_colors,
previous_size * sizeof(previous_colors[0]));
vpx_memcpy(c->palette_count_buf, previous_count,
previous_size * sizeof(previous_count[0]));
}
#endif
}
@ -3282,10 +3286,10 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
#if CONFIG_PALETTE
c = &pc_tree->horizontal[0];
c->palette_buf_size = previous_size;
memcpy(c->palette_colors_buf, previous_colors,
previous_size * sizeof(previous_colors[0]));
memcpy(c->palette_count_buf, previous_count,
previous_size * sizeof(previous_count[0]));
vpx_memcpy(c->palette_colors_buf, previous_colors,
previous_size * sizeof(previous_colors[0]));
vpx_memcpy(c->palette_count_buf, previous_count,
previous_size * sizeof(previous_count[0]));
last = 0;
#endif
@ -3410,10 +3414,10 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
} else {
c = &pc_tree->current;
c->palette_buf_size = previous_size;
memcpy(c->palette_colors_buf, previous_colors,
previous_size * sizeof(previous_colors[0]));
memcpy(c->palette_count_buf, previous_count,
previous_size * sizeof(previous_count[0]));
vpx_memcpy(c->palette_colors_buf, previous_colors,
previous_size * sizeof(previous_colors[0]));
vpx_memcpy(c->palette_count_buf, previous_count,
previous_size * sizeof(previous_count[0]));
}
#endif
}
@ -3437,10 +3441,10 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
#if CONFIG_PALETTE
c = &pc_tree->vertical[0];
c->palette_buf_size = previous_size;
memcpy(c->palette_colors_buf, previous_colors,
previous_size * sizeof(previous_colors[0]));
memcpy(c->palette_count_buf, previous_count,
previous_size * sizeof(previous_count[0]));
vpx_memcpy(c->palette_colors_buf, previous_colors,
previous_size * sizeof(previous_colors[0]));
vpx_memcpy(c->palette_count_buf, previous_count,
previous_size * sizeof(previous_count[0]));
last = 0;
#endif
@ -3562,10 +3566,10 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
} else {
c = &pc_tree->current;
c->palette_buf_size = previous_size;
memcpy(c->palette_colors_buf, previous_colors,
previous_size * sizeof(previous_colors[0]));
memcpy(c->palette_count_buf, previous_count,
previous_size * sizeof(previous_count[0]));
vpx_memcpy(c->palette_colors_buf, previous_colors,
previous_size * sizeof(previous_colors[0]));
vpx_memcpy(c->palette_count_buf, previous_count,
previous_size * sizeof(previous_count[0]));
}
#endif
}
@ -4633,8 +4637,8 @@ static void encode_frame_internal(VP9_COMP *cpi) {
#if CONFIG_PALETTE
if (frame_is_intra_only(cm)) {
cm->current_palette_size = 0;
memset(cm->current_palette_count, 0,
PALETTE_BUF_SIZE * sizeof(cm->current_palette_count[0]));
vpx_memset(cm->current_palette_count, 0,
PALETTE_BUF_SIZE * sizeof(cm->current_palette_count[0]));
cm->palette_counter = 0;
cm->block_counter = 0;
}

File diff suppressed because it is too large Load Diff