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;
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]];
&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]);
}
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]);
}
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);
}
}
#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;
- }
-#endif // CONFIG_FILTERINTRA
-
#if CONFIG_PALETTE
- for (i = 0; i < 2; ++i) {
- mbmi->palette_enabled[i] = 0;
- }
+ 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
}
static INLINE int is_mv_valid(const MV *mv) {
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 &&
vpx_memcpy(t_left, xd->plane[0].left_context, sizeof(t_left));
#if CONFIG_PALETTE
mic->mbmi.palette_enabled[0] = 0;
-#endif
+#endif // CONFIG_PALETTE
// Pick modes for each sub-block (of size 4x4, 4x8, or 8x4) in an 8x8 block.
for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
int src_stride = x->plane[0].src.stride;
uint8_t *src = x->plane[0].src.buf;
uint16_t best_runs[PALETTE_MAX_RUNS];
- uint8_t best_palette[PALETTE_MAX_SIZE], best_map[4096];
+ uint8_t best_palette[PALETTE_MAX_SIZE];
uint8_t best_index[PALETTE_MAX_SIZE], best_literal[PALETTE_MAX_SIZE];
int8_t palette_color_delta[PALETTE_MAX_SIZE];
PALETTE_SCAN_ORDER best_ps = H_SCAN;
colors = count_colors(src, src_stride, rows, cols);
if (colors > 1 && colors <= 64 && cpi->common.allow_palette_mode) {
int n, r, c, i, j, temp, max_itr = 200, k;
- int indices[4096];
int l, m1, m2, d = get_bit_depth(rows * cols);
int bits, best_bits = 0, total_bits, best_total_bits;
int palette_size_cost[PALETTE_SIZES];
int palette_run_length_cost[PALETTE_RUN_LENGTHS];
- double data[4096];
double centroids[PALETTE_MAX_SIZE];
double lb = src[0], ub = src[0], val;
int64_t local_tx_cache[TX_MODES];
PALETTE_SCAN_ORDER ps;
- uint8_t map[4096];
#if CONFIG_TX_SKIP
int this_rate_tokenonly_s, s_s;
int64_t this_distortion_s;
#endif // CONFIG_TX_SKIP
- memset(data, 0, sizeof(data[0] * 4096));
- memset(indices, 0, sizeof(indices[0] * 4096));
+ vpx_memset(x->kmeans_data_buffer, 0,
+ sizeof(x->kmeans_data_buffer[0] * 4096));
+ vpx_memset(x->kmeans_indices_buffer, 0,
+ sizeof(x->kmeans_indices_buffer[0] * 4096));
mic->mbmi.palette_enabled[0] = 1;
vp9_cost_tokens(palette_size_cost,
cpi->common.fc.palette_size_prob[bsize - BLOCK_8X8],
for (r = 0; r < rows; r++) {
for (c = 0; c < cols; c++) {
val = src[r * src_stride + c];
- data[r * cols + c] = val;
+ x->kmeans_data_buffer[r * cols + c] = val;
if (val < lb)
lb = val;
else if (val > ub)
n >= 2; n--) {
for (i = 0; i < n; i++)
centroids[i] = lb + (2 * i + 1) * (ub - lb) / n / 2;
- r = k_means(data, centroids, indices, rows * cols, n, 1, max_itr);
+ r = k_means(x->kmeans_data_buffer, centroids, x->kmeans_indices_buffer,
+ rows * cols, n, 1, max_itr);
insertion_sort(centroids, n);
i = 1;
k = n;
[mic->mbmi.palette_indexed_colors[i]];
}
if (m2 > 0)
- memcpy(mic->mbmi.palette_colors + m1, mic->mbmi.palette_literal_colors,
- m2 * sizeof(mic->mbmi.palette_colors[0]));
+ vpx_memcpy(mic->mbmi.palette_colors + m1,
+ mic->mbmi.palette_literal_colors,
+ m2 * sizeof(mic->mbmi.palette_colors[0]));
for (i = 0; i < k; i++) {
centroids[i] = (double) mic->mbmi.palette_colors[i];
}
- calc_indices(data, centroids, indices, rows * cols, k, 1);
+ calc_indices(x->kmeans_data_buffer, centroids, x->kmeans_indices_buffer,
+ rows * cols, k, 1);
for (r = 0; r < rows; r++) {
for (c = 0; c < cols; c++) {
- xd->plane[0].color_index_map[r * cols + c] = indices[r * cols + c];
+ xd->plane[0].color_index_map[r * cols + c] =
+ x->kmeans_indices_buffer[r * cols + c];
}
}
}
for (ps = H_SCAN; ps < PALETTE_SCAN_ORDERS; ps++) {
- int scan_order[4096];
- switch (ps) {
- case H_SCAN:
- memcpy(map, xd->plane[0].color_index_map, rows * cols);
- break;
- case V_SCAN:
- transpose_block(xd->plane[0].color_index_map,
- map, rows, cols);
- break;
- case SPIN_SCAN:
- spin_scan_order(scan_order, rows, cols);
- for (i = 0; i < rows * cols; i++)
- map[i] = xd->plane[0].color_index_map[scan_order[i]];
- break;
- case ZZ_SCAN:
- zz_scan_order(scan_order, rows, cols);
- for (i = 0; i < rows * cols; i++)
- map[i] = xd->plane[0].color_index_map[scan_order[i]];
- break;
- default:
- break;
- }
-
- l = run_lengh_encoding(map, rows * cols, mic->mbmi.palette_runs,
- palette_max_run(bsize));
- if (!l) {
+ palette_scan(xd->plane[0].color_index_map, xd->palette_map_buffer,
+ rows, cols, ps, xd->palette_scan_buffer);
+ l = run_lengh_encoding(xd->palette_map_buffer, rows * cols,
+ mic->mbmi.palette_runs, palette_max_run(bsize));
+ if (!l)
continue;
- }
this_rate = this_rate_tokenonly +
(1 + vp9_encode_uniform_cost(MIN(k + 1, 8), m1) + PALETTE_DELTA_BIT
best_m1 = m1;
best_m2 = m2;
palette_delta_bitdepth = best_bits;
- memcpy(best_palette, mic->mbmi.palette_colors,
- k * sizeof(best_palette[0]));
- memcpy(best_runs, mic->mbmi.palette_runs, l * sizeof(best_runs[0]));
- memcpy(best_map, xd->plane[0].color_index_map,
- rows * cols * sizeof(best_map[0]));
- memcpy(best_index, mic->mbmi.palette_indexed_colors,
- best_m1 * sizeof(best_index[0]));
- memcpy(palette_color_delta, mic->mbmi.palette_color_delta,
- best_m1 * sizeof(palette_color_delta[0]));
- memcpy(best_literal, mic->mbmi.palette_literal_colors,
- best_m2 * sizeof(best_literal[0]));
+ vpx_memcpy(best_palette, mic->mbmi.palette_colors,
+ k * sizeof(best_palette[0]));
+ vpx_memcpy(best_runs, mic->mbmi.palette_runs,
+ l * sizeof(best_runs[0]));
+ vpx_memcpy(best_index, mic->mbmi.palette_indexed_colors,
+ best_m1 * sizeof(best_index[0]));
+ vpx_memcpy(palette_color_delta, mic->mbmi.palette_color_delta,
+ best_m1 * sizeof(palette_color_delta[0]));
+ vpx_memcpy(best_literal, mic->mbmi.palette_literal_colors,
+ best_m2 * sizeof(best_literal[0]));
#if CONFIG_TX_SKIP
tx_skipped = mic->mbmi.tx_skip[0];
#endif // CONFIG_TX_SKIP
mic->mbmi.palette_indexed_size = best_m1;
mic->mbmi.palette_literal_size = best_m2;
mic->mbmi.palette_delta_bitdepth = palette_delta_bitdepth;
- memcpy(mic->mbmi.palette_colors, best_palette,
- best_n * sizeof(best_palette[0]));
- memcpy(mic->mbmi.palette_runs, best_runs, best_l * sizeof(best_runs[0]));
- memcpy(xd->plane[0].color_index_map, best_map,
- 4 * num_4x4_blocks_high_lookup[bsize] *
- 4 * num_4x4_blocks_wide_lookup[bsize] * sizeof(best_map[0]));
- memcpy(mic->mbmi.palette_indexed_colors, best_index,
- best_m1 * sizeof(best_index[0]));
- memcpy(mic->mbmi.palette_color_delta, palette_color_delta,
- best_m1 * sizeof(palette_color_delta[0]));
- memcpy(mic->mbmi.palette_literal_colors, best_literal,
- best_m2 * sizeof(best_literal[0]));
+ vpx_memcpy(mic->mbmi.palette_colors, best_palette,
+ best_n * sizeof(best_palette[0]));
+ vpx_memcpy(mic->mbmi.palette_runs, best_runs,
+ best_l * sizeof(best_runs[0]));
+ vpx_memcpy(mic->mbmi.palette_indexed_colors, best_index,
+ best_m1 * sizeof(best_index[0]));
+ vpx_memcpy(mic->mbmi.palette_color_delta, palette_color_delta,
+ best_m1 * sizeof(palette_color_delta[0]));
+ vpx_memcpy(mic->mbmi.palette_literal_colors, best_literal,
+ best_m2 * sizeof(best_literal[0]));
+ run_lengh_decoding(mic->mbmi.palette_runs, mic->mbmi.palette_run_length[0],
+ xd->palette_map_buffer);
+ palette_iscan(xd->plane[0].color_index_map, xd->palette_map_buffer,
+ rows, cols, mic->mbmi.palette_scan_order[0],
+ xd->palette_scan_buffer);
#if CONFIG_FILTERINTRA
mic->mbmi.filterbit = 0;
#endif // CONFIG_FILTERINTRA
(xd->plane[1].subsampling_y);
int src_stride = x->plane[1].src.stride;
uint16_t best_runs[PALETTE_MAX_RUNS];
- uint8_t best_palette[2 * PALETTE_MAX_SIZE], best_map[4096];
+ uint8_t best_palette[2 * PALETTE_MAX_SIZE];
uint8_t *src_u = x->plane[1].src.buf;
uint8_t *src_v = x->plane[2].src.buf;
PALETTE_SCAN_ORDER best_ps;
[get_uv_tx_size(&(x->e_mbd.mi[0].mbmi), &xd->plane[1])][mode], fbit);
#endif // CONFIG_FILTERINTRA
#if CONFIG_PALETTE
- if (frame_is_intra_only(&cpi->common) &&
- xd->mi[0].src_mi->mbmi.sb_type >= BLOCK_8X8 &&
+ if (xd->mi[0].src_mi->mbmi.sb_type >= BLOCK_8X8 &&
xd->plane[1].subsampling_x && xd->plane[1].subsampling_y &&
cpi->common.allow_palette_mode)
this_rate += vp9_cost_bit(128, 0);
#endif
#if CONFIG_PALETTE
- if (frame_is_intra_only(&cpi->common) &&
- xd->mi[0].src_mi->mbmi.sb_type >= BLOCK_8X8 &&
+ if (xd->mi[0].src_mi->mbmi.sb_type >= BLOCK_8X8 &&
xd->plane[1].subsampling_x && xd->plane[1].subsampling_y &&
cpi->common.allow_palette_mode) {
int colors_u = count_colors(src_u, src_stride, rows, cols);
if (colors > 1 && colors <= 64) {
int n, r, c, i, j, max_itr = 200;
- int indices[4096];
int l, d = get_bit_depth(rows * cols);
int palette_run_length_cost[PALETTE_RUN_LENGTHS];
int palette_size_cost[PALETTE_SIZES];
- double data[2048];
double centroids[2 * PALETTE_MAX_SIZE];
double lb_u = src_u[0], ub_u = src_u[0];
double lb_v = src_v[0], ub_v = src_v[0], val;
PALETTE_SCAN_ORDER ps;
- uint8_t map[4096];
BLOCK_SIZE uv_bsize = get_plane_block_size(bsize, &xd->plane[1]);
#if CONFIG_TX_SKIP
int this_rate_tokenonly_s, s_s;
#if CONFIG_FILTERINTRA
mbmi->uv_filterbit = 0;
#endif // CONFIG_FILTERINTRA
-#if CONFIG_TX_SKIP
- mbmi->tx_skip[1] = 0;
-#endif // CONFIG_TX_SKIP
mbmi->palette_enabled[1] = 1;
mbmi->uv_mode = DC_PRED;
for (r = 0; r < rows; r++) {
for (c = 0; c < cols; c++) {
- data[(r * cols + c) * 2 ] = src_u[r * src_stride + c];
- data[(r * cols + c) * 2 + 1] = src_v[r * src_stride + c];
+ x->kmeans_data_buffer[(r * cols + c) * 2 ] =
+ src_u[r * src_stride + c];
+ x->kmeans_data_buffer[(r * cols + c) * 2 + 1] =
+ src_v[r * src_stride + c];
val = src_u[r * src_stride + c];
if (val < lb_u)
lb_u = val;
centroids[i * 2 + 1] =
lb_v + (2 * i + 1) * (ub_v - lb_v) / n / 2;;
}
- r = k_means(data, centroids, indices, rows * cols, n, 2, max_itr);
+ r = k_means(x->kmeans_data_buffer, centroids, x->kmeans_indices_buffer,
+ rows * cols, n, 2, max_itr);
mbmi->palette_size[1] = n;
for (i = 1; i < 3; i++) {
for (r = 0; r < rows; r++)
for (c = 0; c < cols; c++) {
xd->plane[1].color_index_map[r * cols + c] =
- indices[r * cols + c];
+ x->kmeans_indices_buffer[r * cols + c];
}
#if CONFIG_TX_SKIP
}
for (ps = H_SCAN; ps < PALETTE_SCAN_ORDERS; ps++) {
- int scan_order[4096];
-
- switch (ps) {
- case H_SCAN:
- memcpy(map, xd->plane[1].color_index_map, rows * cols);
- break;
- case V_SCAN:
- transpose_block(xd->plane[1].color_index_map,
- map, rows, cols);
- break;
- case SPIN_SCAN:
- spin_scan_order(scan_order, rows, cols);
- for (i = 0; i < rows * cols; i++)
- map[i] = xd->plane[1].color_index_map[scan_order[i]];
- break;
- case ZZ_SCAN:
- zz_scan_order(scan_order, rows, cols);
- for (i = 0; i < rows * cols; i++)
- map[i] = xd->plane[1].color_index_map[scan_order[i]];
- break;
- default:
- break;
- }
-
- l = run_lengh_encoding(map, rows * cols,
+ palette_scan(xd->plane[1].color_index_map, xd->palette_map_buffer,
+ rows, cols, ps, xd->palette_scan_buffer);
+ l = run_lengh_encoding(xd->palette_map_buffer, rows * cols,
mbmi->palette_runs + PALETTE_MAX_RUNS,
palette_max_run(uv_bsize));
- if (!l) {
+ if (!l)
continue;
- }
this_rate = this_rate_tokenonly +
(1 + get_bit_depth(palette_max_run(uv_bsize)) + 2 + 2 * 8 * n +
best_l = l;
palette_selected = 1;
best_ps = ps;
- memcpy(best_palette, mbmi->palette_colors + PALETTE_MAX_SIZE,
- 2 * PALETTE_MAX_SIZE * sizeof(best_palette[0]));
- memcpy(best_runs, mbmi->palette_runs + PALETTE_MAX_RUNS,
- l * sizeof(best_runs[0]));
- memcpy(best_map, xd->plane[1].color_index_map,
- rows * cols * sizeof(best_map[0]));
+ vpx_memcpy(best_palette, mbmi->palette_colors + PALETTE_MAX_SIZE,
+ 2 * PALETTE_MAX_SIZE * sizeof(best_palette[0]));
+ vpx_memcpy(best_runs, mbmi->palette_runs + PALETTE_MAX_RUNS,
+ PALETTE_MAX_RUNS * sizeof(best_runs[0]));
#if CONFIG_TX_SKIP
tx_skipped = mbmi->tx_skip[1];
#endif // CONFIG_TX_SKIP
mbmi->palette_size[1] = best_n;
mbmi->palette_run_length[1] = best_l;
mbmi->palette_scan_order[1] = best_ps;
- memcpy(mbmi->palette_colors + PALETTE_MAX_SIZE, best_palette,
- 2 * PALETTE_MAX_SIZE * sizeof(best_palette[0]));
- memcpy(mbmi->palette_runs + PALETTE_MAX_RUNS, best_runs,
- best_l * sizeof(best_runs[0]));
- memcpy(xd->plane[1].color_index_map, best_map,
- rows * cols * sizeof(best_map[0]));
+ vpx_memcpy(mbmi->palette_colors + PALETTE_MAX_SIZE, best_palette,
+ 2 * PALETTE_MAX_SIZE * sizeof(best_palette[0]));
+ vpx_memcpy(mbmi->palette_runs + PALETTE_MAX_RUNS, best_runs,
+ best_l * sizeof(best_runs[0]));
+ 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);
}
#endif // CONFIG_PALETTE
return best_rd;
int colors = count_colors(src_y, src_stride_y, rows, cols);
if (colors >= 2 && colors <= 64 && cm->allow_palette_mode) {
- uint8_t color_index_map_copy[4096], map[4096];
uint16_t best_runs[PALETTE_MAX_RUNS];
- uint8_t best_palette[PALETTE_MAX_SIZE * 3], best_map[4096];
+ uint8_t best_palette[PALETTE_MAX_SIZE * 3];
uint8_t best_index[PALETTE_MAX_SIZE], best_literal[PALETTE_MAX_SIZE];
int8_t palette_color_delta[PALETTE_MAX_SIZE];
int64_t local_tx_cache[TX_MODES], sse;
int r, c, i, j;
int d = get_bit_depth(rows * cols), max_itr = 200;
int palette_run_length_cost[PALETTE_RUN_LENGTHS];
- int palette_size_cost[PALETTE_SIZES], indices[4096];
+ int palette_size_cost[PALETTE_SIZES];
int best_m1 = 0, best_m2 = 0, palette_delta_bitdepth = 0;
- double data[3 * 4096], centroids[3 * PALETTE_MAX_SIZE];
+ double centroids[3 * PALETTE_MAX_SIZE];
double lb = src_y[0], ub = src_y[0];
MB_MODE_INFO *mbmi = &xd->mi[0].src_mi->mbmi;
MB_MODE_INFO mbmi_copy;
palette_best_rd.dist = INT64_MAX;
palette_best_rd.rdcost = INT64_MAX;
mbmi_copy = *mbmi;
- memcpy(color_index_map_copy, xd->plane[0].color_index_map,
- rows * cols * sizeof(color_index_map_copy[0]));
- memset(data, 0, sizeof(data[0]) * 3 * 4096);
- memset(map, 0, sizeof(map[0]) * 4096);
- memset(centroids, 0, sizeof(centroids[0]) * 3 * PALETTE_MAX_SIZE);
+ vpx_memset(x->kmeans_data_buffer, 0,
+ sizeof(x->kmeans_data_buffer[0]) * 3 * 4096);
+ vpx_memset(xd->palette_map_buffer, 0,
+ sizeof(xd->palette_map_buffer[0]) * 4096);
+ vpx_memset(centroids, 0, sizeof(centroids[0]) * 3 * PALETTE_MAX_SIZE);
vp9_cost_tokens(palette_size_cost,
cpi->common.fc.palette_size_prob[bsize - BLOCK_8X8],
vp9_palette_size_tree);
#endif // CONFIG_FILTERINTRA
for (r = 0; r < rows; r++) {
for (c = 0; c < cols; c++) {
- data[(r * cols + c) * 3] = src_y[r * src_stride_y + c];
- data[(r * cols + c) * 3 + 1] = src_u[r * src_stride_uv + c];
- data[(r * cols + c) * 3 + 2] = src_v[r * src_stride_uv + c];
+ x->kmeans_data_buffer[(r * cols + c) * 3] =
+ src_y[r * src_stride_y + c];
+ x->kmeans_data_buffer[(r * cols + c) * 3 + 1] =
+ src_u[r * src_stride_uv + c];
+ x->kmeans_data_buffer[(r * cols + c) * 3 + 2] =
+ src_v[r * src_stride_uv + c];
}
}
centroids[i * 3 + 1] = 128;
centroids[i * 3 + 2] = 128;
}
- r = k_means(data, centroids, indices, rows * cols, n, 3, max_itr);
+ r = k_means(x->kmeans_data_buffer, centroids, x->kmeans_indices_buffer,
+ rows * cols, n, 3, max_itr);
for (i = 0; i < 3; i++) {
for (j = 0; j < n; j++)
mbmi->palette_colors[i * PALETTE_MAX_SIZE + j] =
for (r = 0; r < rows; r++)
for (c = 0; c < cols; c++)
xd->plane[0].color_index_map[r * cols + c] =
- indices[r * cols + c];
+ x->kmeans_data_buffer[r * cols + c];
m1 = 0;
m2 = n;
best_bits = 0;
- memcpy(mbmi->palette_literal_colors, mbmi->palette_colors,
- m2 * sizeof(mbmi->palette_literal_colors[0]));
+ vpx_memcpy(mbmi->palette_literal_colors, mbmi->palette_colors,
+ m2 * sizeof(mbmi->palette_literal_colors[0]));
#if CONFIG_TX_SKIP
mbmi->tx_skip[0] = 0;
continue;
for (ps = H_SCAN; ps < PALETTE_SCAN_ORDERS; ps++) {
- int scan_order[4096];
- switch (ps) {
- case H_SCAN:
- memcpy(map, xd->plane[0].color_index_map, rows * cols);
- break;
- case V_SCAN:
- transpose_block(xd->plane[0].color_index_map,
- map, rows, cols);
- break;
- case SPIN_SCAN:
- spin_scan_order(scan_order, rows, cols);
- for (i = 0; i < rows * cols; i++)
- map[i] = xd->plane[0].color_index_map[scan_order[i]];
- break;
- case ZZ_SCAN:
- zz_scan_order(scan_order, rows, cols);
- for (i = 0; i < rows * cols; i++)
- map[i] = xd->plane[0].color_index_map[scan_order[i]];
- break;
- default:
- break;
- }
- l = run_lengh_encoding(map, rows * cols, mbmi->palette_runs,
- palette_max_run(bsize));
- if (!l) {
+ palette_scan(xd->plane[0].color_index_map, xd->palette_map_buffer,
+ rows, cols, ps, xd->palette_scan_buffer);
+ l = run_lengh_encoding(xd->palette_map_buffer, rows * cols,
+ mbmi->palette_runs, palette_max_run(bsize));
+ if (!l)
continue;
- }
rate_y = rate_y_tokenonly +
(1 + PALETTE_DELTA_BIT + get_bit_depth(palette_max_run(bsize)) +
tx_skipped_uv = mbmi->tx_skip[1];
#endif // CONFIG_TX_SKIP
- memcpy(best_palette, mbmi->palette_colors,
- PALETTE_MAX_SIZE * 3 * sizeof(best_palette[0]));
- memcpy(best_runs, mbmi->palette_runs, l * sizeof(best_runs[0]));
- memcpy(best_map, xd->plane[0].color_index_map,
- rows * cols * sizeof(best_map[0]));
- memcpy(best_index, mbmi->palette_indexed_colors,
- best_m1 * sizeof(best_index[0]));
- memcpy(palette_color_delta, mbmi->palette_color_delta,
- best_m1 * sizeof(palette_color_delta[0]));
- memcpy(best_literal, mbmi->palette_literal_colors,
- best_m2 * sizeof(best_literal[0]));
+ vpx_memcpy(best_palette, mbmi->palette_colors,
+ PALETTE_MAX_SIZE * 3 * sizeof(best_palette[0]));
+ vpx_memcpy(best_runs, mbmi->palette_runs, l * sizeof(best_runs[0]));
+ vpx_memcpy(best_index, mbmi->palette_indexed_colors,
+ best_m1 * sizeof(best_index[0]));
+ vpx_memcpy(palette_color_delta, mbmi->palette_color_delta,
+ best_m1 * sizeof(palette_color_delta[0]));
+ vpx_memcpy(best_literal, mbmi->palette_literal_colors,
+ best_m2 * sizeof(best_literal[0]));
}
}
}
mbmi->palette_indexed_size = best_m1;
mbmi->palette_literal_size = best_m2;
mbmi->palette_delta_bitdepth = palette_delta_bitdepth;
- memcpy(mbmi->palette_colors, best_palette,
- PALETTE_MAX_SIZE * 3 * sizeof(best_palette[0]));
- memcpy(mbmi->palette_runs, best_runs, best_l * sizeof(best_runs[0]));
- memcpy(xd->plane[0].color_index_map, best_map,
- rows * cols * sizeof(best_map[0]));
- memcpy(mbmi->palette_indexed_colors, best_index,
- best_m1 * sizeof(best_index[0]));
- memcpy(mbmi->palette_color_delta, palette_color_delta,
- best_m1 * sizeof(palette_color_delta[0]));
- memcpy(mbmi->palette_literal_colors, best_literal,
- best_m2 * sizeof(best_literal[0]));
+ vpx_memcpy(mbmi->palette_colors, best_palette,
+ PALETTE_MAX_SIZE * 3 * sizeof(best_palette[0]));
+ vpx_memcpy(mbmi->palette_runs, best_runs,
+ best_l * sizeof(best_runs[0]));
+ vpx_memcpy(mbmi->palette_indexed_colors, best_index,
+ best_m1 * sizeof(best_index[0]));
+ vpx_memcpy(mbmi->palette_color_delta, palette_color_delta,
+ best_m1 * sizeof(palette_color_delta[0]));
+ vpx_memcpy(mbmi->palette_literal_colors, best_literal,
+ best_m2 * sizeof(best_literal[0]));
#if CONFIG_FILTERINTRA
mbmi->filterbit = 0;
mbmi->uv_filterbit = 0;
#endif // CONFIG_TX_SKIP
} else {
*mbmi = mbmi_copy;
- memcpy(xd->plane[0].color_index_map, color_index_map_copy,
- rows * cols * sizeof(color_index_map_copy[0]));
+ if (mbmi->palette_enabled[0]) {
+ 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);
+ }
}
ctx->mic = *xd->mi[0].src_mi;
}
PREDICTION_MODE mode_uv[TX_SIZES];
#if CONFIG_FILTERINTRA
int fbit_uv[TX_SIZES];
-#endif
+#endif // CONFIG_FILTERINTRA
#if CONFIG_INTERINTRA
int single_newmv_rate[MAX_REF_FRAMES] = { 0 };
#endif // CONFIG_INTERINTRA
MB_MODE_INFO *inter_ref_list[18];
int copy_mode_context = vp9_get_copy_mode_context(xd);
#endif // CONFIG_COPY_MODE
+#if CONFIG_PALETTE
+ int best_n = 0, best_l = 0, colors;
+ int rows = 4 * num_4x4_blocks_high_lookup[bsize];
+ int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
+ int src_stride = x->plane[0].src.stride;
+ int palette_enabled_uv[TX_SIZES], palette_run_length_uv[TX_SIZES];
+ int palette_size_uv[TX_SIZES];
+ uint8_t *src = x->plane[0].src.buf;
+ uint8_t best_palette[PALETTE_MAX_SIZE];
+ uint8_t palette_colors_uv[TX_SIZES][2 * PALETTE_MAX_SIZE];
+ uint16_t best_runs[PALETTE_MAX_RUNS];
+ uint16_t palette_runs_uv[TX_SIZES][PALETTE_MAX_RUNS];
+ PALETTE_SCAN_ORDER best_ps = H_SCAN, ps_uv[TX_SIZES];
+#endif // CONFIG_PALETTE
vp9_zero(best_mbmode);
x->skip_encode = sf->skip_encode_frame && x->q_index < QIDX_SKIP_THRESH;
rd_cost->rate = INT_MAX;
#if CONFIG_SUPERTX
*returnrate_nocoef = INT_MAX;
-#endif
+#endif // CONFIG_SUPERTX
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
x->pred_mv_sad[ref_frame] = INT_MAX;
#if CONFIG_COMPOUND_MODES
frame_mv[NEW_NEWMV][ref_frame].as_int = INVALID_MV;
frame_mv[ZERO_ZEROMV][ref_frame].as_int = 0;
-#endif
+#endif // CONFIG_COMPOUND_MODES
}
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARMV);
if (frame_mv[NEAR_NEARESTMV][ALTREF_FRAME].as_int != 0)
mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARESTMV);
-#endif
+#endif // CONFIG_COMPOUND_MODES
}
}
midx = end_pos;
}
-#if CONFIG_PALETTE
- for (i = 0; i < 2; ++i) {
- mbmi->palette_enabled[i] = 0;
- }
-#endif // CONFIG_PALETTE
-
for (midx = 0; midx < MAX_MODES; ++midx) {
int mode_index = mode_map[midx];
int mode_excluded = 0;
int compmode_cost = 0;
#if CONFIG_INTERINTRA
int compmode_interintra_cost = 0;
-#endif
+#endif // CONFIG_INTERINTRA
#if CONFIG_WEDGE_PARTITION
int compmode_wedge_cost = 0;
-#endif
+#endif // CONFIG_WEDGE_PARTITION
int rate2 = 0, rate_y = 0, rate_uv = 0;
int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
int skippable = 0;
frame_mv[NEW_NEWMV][second_ref_frame].as_int =
frame_mv[NEWMV][second_ref_frame].as_int;
}
-#endif
+#endif // CONFIG_COMPOUND_MODES
// Look at the reference frame of the best mode so far and set the
// skip mask to look at a subset of the remaining modes.
if (midx == mode_skip_start && best_mode_index >= 0) {
this_mode != NEW_NEARMV)
#else
if (skip_ref_frame && this_mode != NEARESTMV && this_mode != NEWMV)
-#endif
+#endif // CONFIG_COMPOUND_MODES
if (rf > INTRA_FRAME)
if (ref_frame != rf)
continue;
this_mode == ZERO_ZEROMV)
#else
if (this_mode == NEARMV || this_mode == ZEROMV)
-#endif
+#endif // CONFIG_COMPOUND_MODES
continue;
}
if (ref_frame > INTRA_FRAME && second_ref_frame == INTRA_FRAME &&
!is_interintra_allowed(bsize))
continue;
-#endif
+#endif // CONFIG_INTERINTRA
mbmi->mode = this_mode;
mbmi->uv_mode = DC_PRED;
#if CONFIG_COPY_MODE
mbmi->copy_mode = NOREF;
#endif // CONFIG_COPY_MODE
+#if CONFIG_PALETTE
+ mbmi->palette_enabled[0] = 0;
+ mbmi->palette_enabled[1] = 0;
+#endif // CONFIG_PALETTE
// Evaluate all sub-pel filters irrespective of whether we can use
// them for this frame.
mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP
#if CONFIG_INTERINTRA
mbmi->interintra_mode = (PREDICTION_MODE)(DC_PRED - 1);
mbmi->interintra_uv_mode = (PREDICTION_MODE)(DC_PRED - 1);
-#endif
+#endif // CONFIG_INTERINTRA
#if CONFIG_WEDGE_PARTITION
mbmi->use_wedge_interinter = 0;
-#endif
+#endif // CONFIG_WEDGE_PARTITION
if (ref_frame == INTRA_FRAME) {
TX_SIZE uv_tx;
int rate_y_s, skippable_s;
int64_t distortion_y_s;
int64_t tx_cache_s[TX_MODES];
-#endif
+#endif // CONFIG_TX_SKIP
#if CONFIG_FILTERINTRA
mbmi->filterbit = 0;
-#endif
+#endif // CONFIG_FILTERINTRA
#if CONFIG_EXT_TX
mbmi->ext_txfrm = NORM;
-#endif
+#endif // CONFIG_EXT_TX
vpx_memset(x->skip_txfm, 0, sizeof(x->skip_txfm));
super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
NULL, bsize, tx_cache, best_rd);
vpx_memcpy(tx_cache, tx_cache_tmp, TX_MODES * sizeof(int64_t));
}
}
-#endif
+#endif // CONFIG_FILTERINTRA
#if CONFIG_TX_SKIP
if (try_tx_skip) {
mbmi->tx_skip[0] = 1;
rate_y += vp9_cost_bit(cpi->common.fc.y_tx_skip_prob[0],
mbmi->tx_skip[0]);
}
-#endif
+#endif // CONFIG_TX_SKIP
if (rate_y == INT_MAX)
continue;
&dist_uv[uv_tx], &skip_uv[uv_tx],
#if CONFIG_FILTERINTRA
&fbit_uv[uv_tx],
-#endif
+#endif // CONFIG_FILTERINTRA
&mode_uv[uv_tx]);
#if CONFIG_TX_SKIP
tx_skipped_uv[uv_tx] = mbmi->tx_skip[1];
-#endif
-
+#endif // CONFIG_TX_SKIP
+#if CONFIG_PALETTE
+ palette_enabled_uv[uv_tx] = mbmi->palette_enabled[1];
+ if (palette_enabled_uv[uv_tx]) {
+ palette_size_uv[uv_tx] = mbmi->palette_size[1];
+ palette_run_length_uv[uv_tx] = mbmi->palette_run_length[1];
+ ps_uv[uv_tx] = mbmi->palette_scan_order[1];
+ vpx_memcpy(&palette_colors_uv[uv_tx][0],
+ mbmi->palette_colors + PALETTE_MAX_SIZE,
+ 2 * PALETTE_MAX_SIZE *
+ sizeof(palette_colors_uv[uv_tx][0]));
+ vpx_memcpy(&palette_runs_uv[uv_tx][0],
+ mbmi->palette_runs + PALETTE_MAX_RUNS,
+ PALETTE_MAX_RUNS * sizeof(palette_runs_uv[uv_tx][0]));
+ }
+#endif // CONFIG_PALETTE
}
-
rate_uv = rate_uv_tokenonly[uv_tx];
distortion_uv = dist_uv[uv_tx];
skippable = skippable && skip_uv[uv_tx];
mbmi->uv_mode = mode_uv[uv_tx];
#if CONFIG_FILTERINTRA
mbmi->uv_filterbit = fbit_uv[uv_tx];
-#endif
+#endif // CONFIG_FILTERINTRA
#if CONFIG_TX_SKIP
mbmi->tx_skip[1] = tx_skipped_uv[uv_tx];
-#endif
+#endif // CONFIG_TX_SKIP
+#if CONFIG_PALETTE
+ mbmi->palette_enabled[1] = palette_enabled_uv[uv_tx];
+ if (mbmi->palette_enabled[1]) {
+ mbmi->palette_size[1] = palette_size_uv[uv_tx];
+ mbmi->palette_run_length[1] = palette_run_length_uv[uv_tx];
+ mbmi->palette_scan_order[1] = ps_uv[uv_tx];
+ vpx_memcpy(mbmi->palette_colors + PALETTE_MAX_SIZE,
+ &palette_colors_uv[uv_tx][0],
+ 2 * PALETTE_MAX_SIZE * sizeof(palette_colors_uv[uv_tx][0]));
+ vpx_memcpy(mbmi->palette_runs + PALETTE_MAX_RUNS,
+ &palette_runs_uv[uv_tx][0],
+ PALETTE_MAX_RUNS * sizeof(palette_runs_uv[uv_tx][0]));
+ }
+#endif // CONFIG_PALETTE
rate2 = rate_y + cpi->mbmode_cost[mbmi->mode] + rate_uv_intra[uv_tx];
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mbmi->mode) && is_filter_enabled(mbmi->tx_size))
rate2 += vp9_cost_bit(
cm->fc.filterintra_prob[mbmi->tx_size][mbmi->mode], mbmi->filterbit);
-#endif
+#endif // CONFIG_FILTERINTRA
+#if CONFIG_PALETTE
+ if (cpi->common.allow_palette_mode && bsize >= BLOCK_8X8)
+ rate2 += vp9_cost_bit(128, 0);
+#endif // CONFIG_PALETTE
if (this_mode != DC_PRED && this_mode != TM_PRED)
rate2 += intra_cost_penalty;
distortion2 = distortion_y + distortion_uv;
#if CONFIG_TX_SKIP
mbmi->tx_skip[0] = 0;
mbmi->tx_skip[1] = 0;
-#endif
+#endif // CONFIG_TX_SKIP
x->skip = 0;
set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
for (i = 0; i < MAX_MB_PLANE; i++) {
rd_cost->rdcost = this_rd;
#if CONFIG_SUPERTX
*returnrate_nocoef = rate_copy_mode;
-#endif
+#endif // CONFIG_SUPERTX
best_rd = this_rd;
best_mbmode = *mbmi;
best_skip2 = this_skip2;
vp9_zero(best_filter_diff);
vp9_zero(best_tx_diff);
}
-#endif
+#endif // CONFIG_COPY_MODE
+#if CONFIG_PALETTE
+ if (bsize >= BLOCK_8X8 && cpi->common.allow_palette_mode &&
+ !is_inter_block(mbmi)) {
+ MB_MODE_INFO mbmi_copy = *mbmi;
+ colors = count_colors(src, src_stride, rows, cols);
+ x->skip = 0;
+ if (colors > 1 && colors <= 64) {
+ int n, r, c, i, j, max_itr = 200, k;
+ int l, d = get_bit_depth(rows * cols);
+ int palette_size_cost[PALETTE_SIZES];
+ int palette_run_length_cost[PALETTE_RUN_LENGTHS];
+ double centroids[PALETTE_MAX_SIZE];
+ double lb = src[0], ub = src[0], val;
+ PALETTE_SCAN_ORDER ps;
+
+ int64_t this_rd = INT64_MAX, this_rd_y, best_rd_y;
+ int rate2, rate_y , rate_uv, best_token_rate_y = INT_MAX;
+ int total_rate_y, current_best_total_rate_y, best_total_rate_y = INT_MAX;
+ int64_t distortion2, distortion_y, distortion_uv;
+ int64_t best_distortion_y = INT64_MAX;
+ int skippable, skip_y = 0;
+ int64_t tx_cache[TX_MODES];
+ TX_SIZE uv_tx;
+#if CONFIG_TX_SKIP
+ int rate_y_s, skippable_s;
+ int64_t distortion_y_s;
+ int64_t tx_cache_s[TX_MODES];
+ int tx_skipped_y = 0;
+#endif // CONFIG_TX_SKIP
+
+ vpx_memset(x->kmeans_data_buffer, 0,
+ sizeof(x->kmeans_data_buffer[0] * 4096));
+ vpx_memset(x->kmeans_indices_buffer, 0,
+ sizeof(x->kmeans_indices_buffer[0] * 4096));
+ mbmi->palette_enabled[0] = 1;
+ vp9_cost_tokens(palette_size_cost,
+ cpi->common.fc.palette_size_prob[bsize - BLOCK_8X8],
+ vp9_palette_size_tree);
+ vp9_cost_tokens(palette_run_length_cost,
+ cpi->common.fc.palette_run_length_prob[bsize - BLOCK_8X8],
+ vp9_palette_run_length_tree);
+ mbmi->ref_frame[0] = INTRA_FRAME;
+ mbmi->mode = DC_PRED;
+ for (r = 0; r < rows; r++) {
+ for (c = 0; c < cols; c++) {
+ val = src[r * src_stride + c];
+ x->kmeans_data_buffer[r * cols + c] = val;
+ if (val < lb)
+ lb = val;
+ else if (val > ub)
+ ub = val;
+ }
+ }
+
+#if CONFIG_FILTERINTRA
+ mbmi->filterbit = 0;
+#endif // CONFIG_FILTERINTRA
+#if CONFIG_COPY_MODE
+ mbmi->copy_mode = NOREF;
+#endif // CONFIG_COPY_MODE
+ best_rd_y = INT64_MAX;
+ for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors;
+ n >= 2; n--) {
+ for (i = 0; i < n; i++)
+ centroids[i] = lb + (2 * i + 1) * (ub - lb) / n / 2;
+ r = k_means(x->kmeans_data_buffer, centroids, x->kmeans_indices_buffer,
+ rows * cols, n, 1, max_itr);
+ insertion_sort(centroids, n);
+ i = 1;
+ k = n;
+ while (i < k) {
+ if (centroids[i] == centroids[i - 1]) {
+ j = i;
+ while (j < k - 1) {
+ centroids[j] = centroids[j + 1];
+ j++;
+ }
+ k--;
+ } else {
+ i++;
+ }
+ }
+
+ mbmi->palette_size[0] = k;
+ for (i = 0; i < k; i++) {
+ mbmi->palette_colors[i] = clip_pixel(round(centroids[i]));
+ centroids[i] = (double) mbmi->palette_colors[i];
+ }
+ calc_indices(x->kmeans_data_buffer, centroids, x->kmeans_indices_buffer,
+ rows * cols, k, 1);
+ for (r = 0; r < rows; r++) {
+ for (c = 0; c < cols; c++) {
+ xd->plane[0].color_index_map[r * cols + c] =
+ x->kmeans_indices_buffer[r * cols + c];
+ }
+ }
+ vpx_memset(x->skip_txfm, 0, sizeof(x->skip_txfm));
+#if CONFIG_TX_SKIP
+ mbmi->tx_skip[0] = 0;
+#endif // CONFIG_TX_SKIP
+ super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
+ NULL, bsize, tx_cache, best_rd);
+#if CONFIG_TX_SKIP
+ if (try_tx_skip) {
+ mbmi->tx_skip[0] = 1;
+ super_block_yrd(cpi, x, &rate_y_s, &distortion_y_s, &skippable_s,
+ NULL, bsize, tx_cache_s, best_rd);
+
+ if (rate_y != INT_MAX)
+ rate_y += vp9_cost_bit(cpi->common.fc.y_tx_skip_prob[0], 0);
+ if (rate_y_s != INT_MAX)
+ rate_y_s += vp9_cost_bit(cpi->common.fc.y_tx_skip_prob[0], 1);
+
+ if (rate_y_s != INT_MAX &&
+ (rate_y == INT_MAX ||
+ RDCOST(x->rdmult, x->rddiv, rate_y, distortion_y) >
+ RDCOST(x->rdmult, x->rddiv, rate_y_s, distortion_y_s)))
+ mbmi->tx_skip[0] = 1;
+ else
+ mbmi->tx_skip[0] = 0;
+
+ super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
+ NULL, bsize, tx_cache, best_rd);
+ }
+#endif // CONFIG_TX_SKIP
+ if (rate_y == INT_MAX) {
+ continue;
+ }
+
+ current_best_total_rate_y = INT_MAX;
+ for (ps = H_SCAN; ps < PALETTE_SCAN_ORDERS; ps++) {
+ palette_scan(xd->plane[0].color_index_map, xd->palette_map_buffer,
+ rows, cols, ps, xd->palette_scan_buffer);
+ l = run_lengh_encoding(xd->palette_map_buffer, rows * cols,
+ mbmi->palette_runs, palette_max_run(bsize));
+ if (!l)
+ continue;
+
+ total_rate_y = rate_y +
+ (1 + get_bit_depth(palette_max_run(bsize)) + 2 +
+ 8 * k + get_bit_depth(k) * (l >> 1)) * vp9_cost_bit(128, 0) +
+ palette_size_cost[k - 2];
+ for (i = 0; i < l; i += 2) {
+ int bits = get_bit_depth(mbmi->palette_runs[i + 1]);
+ total_rate_y += palette_run_length_cost[bits > 6 ? 6 : bits - 1];
+ total_rate_y += (bits > 6 ? d : bits) * vp9_cost_bit(128, 0);
+ }
+#if CONFIG_TX_SKIP
+ total_rate_y += vp9_cost_bit(cpi->common.fc.y_tx_skip_prob[0],
+ mbmi->tx_skip[0]);
+#endif // CONFIG_TX_SKIP
+ if (total_rate_y < current_best_total_rate_y) {
+ mbmi->palette_scan_order[0] = ps;
+ current_best_total_rate_y = total_rate_y;
+ }
+ }
+
+ palette_scan(xd->plane[0].color_index_map, xd->palette_map_buffer,
+ rows, cols, mbmi->palette_scan_order[0],
+ xd->palette_scan_buffer);
+ l = run_lengh_encoding(xd->palette_map_buffer, rows * cols,
+ mbmi->palette_runs, palette_max_run(bsize));
+ if (!l)
+ continue;
+
+ this_rd_y = RDCOST(x->rdmult, x->rddiv,
+ current_best_total_rate_y, distortion_y);
+ if (this_rd_y < best_rd_y) {
+ best_rd_y = this_rd_y;
+ skip_y = skippable;
+ best_distortion_y = distortion_y;
+ best_total_rate_y = current_best_total_rate_y;
+ best_token_rate_y = rate_y;
+ best_n = k;
+ best_l = l;
+ best_ps = mbmi->palette_scan_order[0];
+ vpx_memcpy(best_palette, mbmi->palette_colors,
+ k * sizeof(best_palette[0]));
+ vpx_memcpy(best_runs, mbmi->palette_runs, l * sizeof(best_runs[0]));
+#if CONFIG_TX_SKIP
+ tx_skipped_y = mbmi->tx_skip[0];
+#endif // CONFIG_TX_SKIP
+ }
+ }
+
+ if (best_rd_y < best_rd) {
+ rate_y = best_token_rate_y;
+ uv_tx = get_uv_tx_size_impl(mbmi->tx_size, bsize,
+ xd->plane[1].subsampling_x,
+ xd->plane[1].subsampling_y);
+ if (rate_uv_intra[uv_tx] == INT_MAX) {
+ choose_intra_uv_mode(cpi, ctx, bsize, uv_tx,
+ &rate_uv_intra[uv_tx], &rate_uv_tokenonly[uv_tx],
+ &dist_uv[uv_tx], &skip_uv[uv_tx],
+#if CONFIG_FILTERINTRA
+ &fbit_uv[uv_tx],
+#endif // CONFIG_FILTERINTRA
+ &mode_uv[uv_tx]);
+ palette_enabled_uv[uv_tx] = mbmi->palette_enabled[1];
+ if (palette_enabled_uv[uv_tx]) {
+ palette_size_uv[uv_tx] = mbmi->palette_size[1];
+ palette_run_length_uv[uv_tx] = mbmi->palette_run_length[1];
+ ps_uv[uv_tx] = mbmi->palette_scan_order[1];
+ vpx_memcpy(&palette_colors_uv[uv_tx][0],
+ mbmi->palette_colors + PALETTE_MAX_SIZE,
+ 2 * PALETTE_MAX_SIZE *
+ sizeof(palette_colors_uv[uv_tx][0]));
+ vpx_memcpy(&palette_runs_uv[uv_tx][0],
+ mbmi->palette_runs + PALETTE_MAX_RUNS,
+ PALETTE_MAX_RUNS * sizeof(palette_runs_uv[uv_tx][0]));
+ }
+#if CONFIG_TX_SKIP
+ tx_skipped_uv[uv_tx] = mbmi->tx_skip[1];
+#endif // CONFIG_TX_SKIP
+ }
+
+ rate_uv = rate_uv_tokenonly[uv_tx];
+ distortion_uv = dist_uv[uv_tx];
+ skippable = skip_y && skip_uv[uv_tx];
+ mbmi->uv_mode = mode_uv[uv_tx];
+
+ mbmi->palette_enabled[1] = palette_enabled_uv[uv_tx];
+ if (mbmi->palette_enabled[1]) {
+ mbmi->palette_size[1] = palette_size_uv[uv_tx];
+ mbmi->palette_run_length[1] = palette_run_length_uv[uv_tx];
+ mbmi->palette_scan_order[1] = ps_uv[uv_tx];
+ vpx_memcpy(mbmi->palette_colors + PALETTE_MAX_SIZE,
+ &palette_colors_uv[uv_tx][0],
+ 2 * PALETTE_MAX_SIZE *
+ sizeof(palette_colors_uv[uv_tx][0]));
+ vpx_memcpy(mbmi->palette_runs + PALETTE_MAX_RUNS,
+ &palette_runs_uv[uv_tx][0],
+ PALETTE_MAX_RUNS * sizeof(palette_runs_uv[uv_tx][0]));
+ }
+#if CONFIG_FILTERINTRA
+ mbmi->uv_filterbit = fbit_uv[uv_tx];
+#endif // CONFIG_FILTERINTRA
+#if CONFIG_TX_SKIP
+ mbmi->tx_skip[1] = tx_skipped_uv[uv_tx];
+#endif // CONFIG_TX_SKIP
+
+ rate2 = best_total_rate_y + rate_uv_intra[uv_tx];
+ distortion2 = best_distortion_y + distortion_uv;
+ x->skip = skippable;
+ if (skippable) {
+ // Back out the coefficient coding costs
+ rate2 -= (rate_y + rate_uv);
+ rate_y = 0;
+ rate_uv = 0;
+ // Cost the skip mb case
+ rate2 += vp9_cost_bit(vp9_get_skip_prob(cm, xd), 1);
+ } else {
+ // Add in the cost of the no skip flag.
+ rate2 += vp9_cost_bit(vp9_get_skip_prob(cm, xd), 0);
+ }
+
+ // Calculate the final RD estimate for this mode.
+ this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
+ }
+
+ if (this_rd < best_rd) {
+ ctx->skip = x->skip;
+ ctx->skippable = skippable;
+ ctx->best_mode_index = 3;
+ mbmi->skip = skippable;
+ mbmi->mode = DC_PRED;
+ mbmi->ref_frame[0] = INTRA_FRAME;
+ mbmi->ref_frame[1] = NONE;
+ mbmi->palette_enabled[0] = 1;
+ mbmi->palette_size[0] = best_n;
+ mbmi->palette_run_length[0] = best_l;
+ mbmi->palette_scan_order[0] = best_ps;
+ vpx_memcpy(mbmi->palette_colors, best_palette,
+ best_n * sizeof(best_palette[0]));
+ vpx_memcpy(mbmi->palette_runs, best_runs,
+ best_l * sizeof(best_runs[0]));
+#if CONFIG_FILTERINTRA1
+ mbmi->filterbit = 0;
+#endif // CONFIG_FILTERINTRA
+#if CONFIG_TX_SKIP
+ mbmi->tx_skip[0] = tx_skipped_y;
+#endif // CONFIG_TX_SKIP
+ } else {
+ *mbmi = mbmi_copy;
+ }
+ ctx->mic = *xd->mi[0].src_mi;
+ }
+ }
+
+ if (mbmi->palette_enabled[0]) {
+ int rows = 4 * num_4x4_blocks_high_lookup[bsize];
+ int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
+
+ 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);
+ }
+
+ if (mbmi->palette_enabled[1]) {
+ 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;
+
+ 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);
+ }
+#endif // CONFIG_PALETTE
}
void vp9_rd_pick_inter_mode_sb_seg_skip(VP9_COMP *cpi, MACROBLOCK *x,