summaryrefslogtreecommitdiff
path: root/vp9/encoder/vp9_encodeframe.c
diff options
context:
space:
mode:
Diffstat (limited to 'vp9/encoder/vp9_encodeframe.c')
-rw-r--r--vp9/encoder/vp9_encodeframe.c597
1 files changed, 279 insertions, 318 deletions
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index 8e524f4ba..d40c604a4 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -562,6 +562,15 @@ void vp9_setup_src_planes(MACROBLOCK *x,
x->e_mbd.plane[2].subsampling_y);
}
+static INLINE void set_partition_seg_context(VP9_COMP *cpi,
+ int mi_row, int mi_col) {
+ VP9_COMMON *const cm = &cpi->common;
+ MACROBLOCKD *const xd = &cpi->mb.e_mbd;
+
+ xd->above_seg_context = cm->above_seg_context + (mi_col >> CONFIG_SB8X8);
+ xd->left_seg_context = cm->left_seg_context + ((mi_row >> CONFIG_SB8X8) & 3);
+}
+
static void set_offsets(VP9_COMP *cpi,
int mi_row, int mi_col, BLOCK_SIZE_TYPE bsize) {
MACROBLOCK *const x = &cpi->mb;
@@ -574,14 +583,18 @@ static void set_offsets(VP9_COMP *cpi,
const int mb_row = mi_row >> CONFIG_SB8X8;
const int mb_col = mi_col >> CONFIG_SB8X8;
const int idx_map = mb_row * cm->mb_cols + mb_col;
+ int i;
// entropy context structures
- xd->above_context = cm->above_context + mb_col;
- xd->left_context = cm->left_context + (mb_row & 3);
+ for (i = 0; i < MAX_MB_PLANE; i++) {
+ xd->plane[i].above_context = cm->above_context[i] +
+ (mi_col * 4 >> (CONFIG_SB8X8 + xd->plane[i].subsampling_x));
+ xd->plane[i].left_context = cm->left_context[i] +
+ (((mi_row * 4 >> CONFIG_SB8X8) & 15) >> xd->plane[i].subsampling_y);
+ }
// partition contexts
- xd->above_seg_context = cm->above_seg_context + mb_col;
- xd->left_seg_context = cm->left_seg_context + (mb_row & 3);
+ set_partition_seg_context(cpi, mi_row, mi_col);
// Activity map pointer
x->mb_activity_ptr = &cpi->mb_activity_map[idx_map];
@@ -773,203 +786,134 @@ static void update_stats(VP9_COMP *cpi, int mi_row, int mi_col) {
}
}
-static void encode_sb(VP9_COMP *cpi,
- int mi_row,
- int mi_col,
- int output_enabled,
- TOKENEXTRA **tp, BLOCK_SIZE_TYPE is_sb) {
- VP9_COMMON *const cm = &cpi->common;
- MACROBLOCK *const x = &cpi->mb;
- MACROBLOCKD *const xd = &x->e_mbd;
- BLOCK_SIZE_TYPE bsize = BLOCK_SIZE_SB32X32;
- int pl;
-
- xd->left_seg_context =
- cm->left_seg_context + ((mi_row >> CONFIG_SB8X8) & 0x03);
- xd->above_seg_context =
- cm->above_seg_context + (mi_col >> CONFIG_SB8X8);
- pl = partition_plane_context(xd, bsize);
-
- if (is_sb == BLOCK_SIZE_SB32X32) {
- set_offsets(cpi, mi_row, mi_col, bsize);
- update_state(cpi, &x->sb32_context[xd->sb_index],
- bsize, output_enabled);
-
- encode_superblock(cpi, tp,
- output_enabled, mi_row, mi_col, bsize);
- if (output_enabled) {
- update_stats(cpi, mi_row, mi_col);
- cpi->partition_count[pl][PARTITION_NONE]++;
-
- (*tp)->token = EOSB_TOKEN;
- (*tp)++;
- }
- } else if (is_sb == BLOCK_SIZE_SB16X32) {
- int i;
-
- if (output_enabled)
- cpi->partition_count[pl][PARTITION_VERT]++;
- for (i = 0; i < 2 && mi_col + (i << CONFIG_SB8X8) != cm->mi_cols; i++) {
- set_offsets(cpi, mi_row, mi_col + (i << CONFIG_SB8X8),
- BLOCK_SIZE_SB16X32);
- update_state(cpi, &x->sb16x32_context[xd->sb_index][i],
- BLOCK_SIZE_SB16X32, output_enabled);
- encode_superblock(cpi, tp,
- output_enabled, mi_row, mi_col + (i << CONFIG_SB8X8),
- BLOCK_SIZE_SB16X32);
- if (output_enabled) {
- update_stats(cpi, mi_row, mi_col + i);
-
- (*tp)->token = EOSB_TOKEN;
- (*tp)++;
- }
- }
- } else if (is_sb == BLOCK_SIZE_SB32X16) {
- int i;
-
- if (output_enabled)
- cpi->partition_count[pl][PARTITION_HORZ]++;
- for (i = 0; i < 2 && mi_row + (i << CONFIG_SB8X8) != cm->mi_rows; i++) {
- set_offsets(cpi, mi_row + (i << CONFIG_SB8X8), mi_col,
- BLOCK_SIZE_SB32X16);
- update_state(cpi, &x->sb32x16_context[xd->sb_index][i],
- BLOCK_SIZE_SB32X16, output_enabled);
- encode_superblock(cpi, tp,
- output_enabled, mi_row + (i << CONFIG_SB8X8), mi_col,
- BLOCK_SIZE_SB32X16);
- if (output_enabled) {
- update_stats(cpi, mi_row + (i << CONFIG_SB8X8), mi_col);
-
- (*tp)->token = EOSB_TOKEN;
- (*tp)++;
- }
- }
+static void set_block_index(MACROBLOCKD *xd, int idx,
+ BLOCK_SIZE_TYPE bsize) {
+ if (bsize >= BLOCK_SIZE_SB32X32) {
+ xd->sb_index = idx;
} else {
- int i;
- if (output_enabled)
- cpi->partition_count[pl][PARTITION_SPLIT]++;
+#if CONFIG_SB8X8
+ assert(bsize >= BLOCK_SIZE_MB16X16);
+#endif
+ xd->mb_index = idx;
+ }
+}
- for (i = 0; i < 4; i++) {
- const int x_idx = (i & 1) << CONFIG_SB8X8;
- const int y_idx = (i >> 1) << CONFIG_SB8X8;
+static PICK_MODE_CONTEXT *get_block_context(MACROBLOCK *x,
+ BLOCK_SIZE_TYPE bsize) {
+ MACROBLOCKD *const xd = &x->e_mbd;
- if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols)) {
- // MB lies outside frame, move on
- continue;
- }
+ switch (bsize) {
+ case BLOCK_SIZE_SB64X64:
+ return &x->sb64_context;
+ case BLOCK_SIZE_SB64X32:
+ return &x->sb64x32_context[xd->sb_index];
+ case BLOCK_SIZE_SB32X64:
+ return &x->sb32x64_context[xd->sb_index];
+ case BLOCK_SIZE_SB32X32:
+ return &x->sb32_context[xd->sb_index];
+ case BLOCK_SIZE_SB32X16:
+ return &x->sb32x16_context[xd->sb_index][xd->mb_index];
+ case BLOCK_SIZE_SB16X32:
+ return &x->sb16x32_context[xd->sb_index][xd->mb_index];
+ case BLOCK_SIZE_MB16X16:
+ return &x->mb_context[xd->sb_index][xd->mb_index];
+ default:
+ assert(0);
+ return NULL;
+ }
+}
- set_offsets(cpi, mi_row + y_idx, mi_col + x_idx, BLOCK_SIZE_MB16X16);
- xd->mb_index = i;
- update_state(cpi, &x->mb_context[xd->sb_index][i],
- BLOCK_SIZE_MB16X16, output_enabled);
+static void encode_b(VP9_COMP *cpi, TOKENEXTRA **tp,
+ int mi_row, int mi_col, int output_enabled,
+ BLOCK_SIZE_TYPE bsize, int sub_index) {
+ VP9_COMMON *const cm = &cpi->common;
+ MACROBLOCK *const x = &cpi->mb;
+ MACROBLOCKD *const xd = &x->e_mbd;
- if (cpi->oxcf.tuning == VP8_TUNE_SSIM)
- vp9_activity_masking(cpi, x);
+ if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
+ return;
- encode_macroblock(cpi, tp,
- output_enabled, mi_row + y_idx, mi_col + x_idx);
- if (output_enabled) {
- update_stats(cpi, mi_row + y_idx, mi_col + x_idx);
+ if (sub_index != -1)
+ set_block_index(xd, sub_index, bsize);
+ set_offsets(cpi, mi_row, mi_col, bsize);
+ update_state(cpi, get_block_context(x, bsize), bsize, output_enabled);
+ if (bsize == BLOCK_SIZE_MB16X16) {
+ if (cpi->oxcf.tuning == VP8_TUNE_SSIM)
+ vp9_activity_masking(cpi, x);
- (*tp)->token = EOSB_TOKEN;
- (*tp)++;
- }
- }
+ encode_macroblock(cpi, tp, output_enabled, mi_row, mi_col);
+ } else {
+ encode_superblock(cpi, tp, output_enabled, mi_row, mi_col, bsize);
}
- xd->above_seg_context = cm->above_seg_context + (mi_col >> CONFIG_SB8X8);
- xd->left_seg_context = cm->left_seg_context + ((mi_row >> CONFIG_SB8X8) & 3);
- update_partition_context(xd, is_sb, BLOCK_SIZE_SB32X32);
+ if (output_enabled) {
+ update_stats(cpi, mi_row, mi_col);
- // debug output
-#if DBG_PRNT_SEGMAP
- {
- FILE *statsfile;
- statsfile = fopen("segmap2.stt", "a");
- fprintf(statsfile, "\n");
- fclose(statsfile);
+ (*tp)->token = EOSB_TOKEN;
+ (*tp)++;
}
-#endif
}
-static void encode_sb64(VP9_COMP *cpi,
- int mi_row,
- int mi_col,
- TOKENEXTRA **tp, BLOCK_SIZE_TYPE is_sb[4]) {
+static void encode_sb(VP9_COMP *cpi, TOKENEXTRA **tp,
+ int mi_row, int mi_col, int output_enabled,
+ BLOCK_SIZE_TYPE level,
+ BLOCK_SIZE_TYPE c1, BLOCK_SIZE_TYPE c2[4]) {
VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->mb;
MACROBLOCKD *const xd = &x->e_mbd;
- BLOCK_SIZE_TYPE bsize = BLOCK_SIZE_SB64X64;
+ const int bsl = mi_width_log2(level), bs = 1 << (bsl - 1);
+ const int bwl = mi_width_log2(c1), bhl = mi_height_log2(c1);
int pl;
- xd->left_seg_context = cm->left_seg_context + ((mi_row >> CONFIG_SB8X8) & 3);
- xd->above_seg_context = cm->above_seg_context + (mi_col >> CONFIG_SB8X8);
- pl = partition_plane_context(xd, bsize);
+ if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
+ return;
- if (is_sb[0] == BLOCK_SIZE_SB64X64) {
- set_offsets(cpi, mi_row, mi_col, bsize);
- update_state(cpi, &x->sb64_context, bsize, 1);
- encode_superblock(cpi, tp,
- 1, mi_row, mi_col, bsize);
- update_stats(cpi, mi_row, mi_col);
+ set_partition_seg_context(cpi, mi_row, mi_col);
+ pl = partition_plane_context(xd, level);
- (*tp)->token = EOSB_TOKEN;
- (*tp)++;
- cpi->partition_count[pl][PARTITION_NONE]++;
- } else if (is_sb[0] == BLOCK_SIZE_SB32X64) {
+ if (bsl == bwl && bsl == bhl) {
+ if (output_enabled && level > BLOCK_SIZE_MB16X16)
+ cpi->partition_count[pl][PARTITION_NONE]++;
+ encode_b(cpi, tp, mi_row, mi_col, output_enabled, c1, -1);
+ } else if (bsl == bhl && bsl > bwl) {
+ if (output_enabled)
+ cpi->partition_count[pl][PARTITION_VERT]++;
+ encode_b(cpi, tp, mi_row, mi_col, output_enabled, c1, 0);
+ encode_b(cpi, tp, mi_row, mi_col + bs, output_enabled, c1, 1);
+ } else if (bsl == bwl && bsl > bhl) {
+ if (output_enabled)
+ cpi->partition_count[pl][PARTITION_HORZ]++;
+ encode_b(cpi, tp, mi_row, mi_col, output_enabled, c1, 0);
+ encode_b(cpi, tp, mi_row + bs, mi_col, output_enabled, c1, 1);
+ } else {
+ BLOCK_SIZE_TYPE subsize;
int i;
- cpi->partition_count[pl][PARTITION_VERT]++;
- for (i = 0; i < 2 && mi_col + (i * 2 << CONFIG_SB8X8) != cm->mi_cols; i++) {
- set_offsets(cpi, mi_row, mi_col + (i * 2 << CONFIG_SB8X8),
- BLOCK_SIZE_SB32X64);
- update_state(cpi, &x->sb32x64_context[i], BLOCK_SIZE_SB32X64, 1);
- encode_superblock(cpi, tp,
- 1, mi_row, mi_col + (i * 2 << CONFIG_SB8X8),
- BLOCK_SIZE_SB32X64);
- update_stats(cpi, mi_row, mi_col + (i * 2 << CONFIG_SB8X8));
-
- (*tp)->token = EOSB_TOKEN;
- (*tp)++;
+ assert(bwl < bsl && bhl < bsl);
+ if (level == BLOCK_SIZE_SB64X64) {
+ subsize = BLOCK_SIZE_SB32X32;
+ } else {
+ assert(level == BLOCK_SIZE_SB32X32);
+ subsize = BLOCK_SIZE_MB16X16;
}
- } else if (is_sb[0] == BLOCK_SIZE_SB64X32) {
- int i;
- cpi->partition_count[pl][PARTITION_HORZ]++;
- for (i = 0; i < 2 && mi_row + (i * 2 << CONFIG_SB8X8) != cm->mi_rows; i++) {
- set_offsets(cpi, mi_row + (i * 2 << CONFIG_SB8X8), mi_col,
- BLOCK_SIZE_SB64X32);
- update_state(cpi, &x->sb64x32_context[i], BLOCK_SIZE_SB64X32, 1);
- encode_superblock(cpi, tp,
- 1, mi_row + (i * 2 << CONFIG_SB8X8), mi_col,
- BLOCK_SIZE_SB64X32);
- update_stats(cpi, mi_row + (i * 2 << CONFIG_SB8X8), mi_col);
-
- (*tp)->token = EOSB_TOKEN;
- (*tp)++;
- }
- } else {
- int i;
- cpi->partition_count[pl][PARTITION_SPLIT]++;
+ if (output_enabled)
+ cpi->partition_count[pl][PARTITION_SPLIT]++;
+
for (i = 0; i < 4; i++) {
- const int x_idx = (i & 1) << (1 + CONFIG_SB8X8);
- const int y_idx = (i & 2) << CONFIG_SB8X8;
+ const int x_idx = i & 1, y_idx = i >> 1;
- if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols) {
- // MB lies outside frame, move on
- continue;
- }
- xd->sb_index = i;
- encode_sb(cpi, mi_row + y_idx, mi_col + x_idx, 1, tp,
- is_sb[i]);
+ set_block_index(xd, i, subsize);
+ encode_sb(cpi, tp, mi_row + y_idx * bs, mi_col + x_idx * bs,
+ output_enabled, subsize,
+ subsize == BLOCK_SIZE_MB16X16 ? c1 : c2[i], c2);
}
}
- if (is_sb[0] > BLOCK_SIZE_SB32X32) {
- xd->above_seg_context = cm->above_seg_context + (mi_col >> CONFIG_SB8X8);
- xd->left_seg_context =
- cm->left_seg_context + ((mi_row >> CONFIG_SB8X8) & 3);
- update_partition_context(xd, is_sb[0], BLOCK_SIZE_SB64X64);
+ if (level > BLOCK_SIZE_MB16X16 &&
+ (level == BLOCK_SIZE_SB32X32 || bsl == bwl || bsl == bhl)) {
+ set_partition_seg_context(cpi, mi_row, mi_col);
+ update_partition_context(xd, c1, level);
}
}
@@ -983,22 +927,27 @@ static void encode_sb_row(VP9_COMP *cpi,
int mi_col, pl;
// Initialize the left context for the new SB row
- vpx_memset(cm->left_context, 0, sizeof(cm->left_context));
+ vpx_memset(&cm->left_context, 0, sizeof(cm->left_context));
vpx_memset(cm->left_seg_context, 0, sizeof(cm->left_seg_context));
// Code each SB in the row
for (mi_col = cm->cur_tile_mi_col_start;
mi_col < cm->cur_tile_mi_col_end; mi_col += (4 << CONFIG_SB8X8)) {
- int i;
+ int i, p;
BLOCK_SIZE_TYPE sb_partitioning[4];
int sb64_rate = 0, sb64_dist = 0;
int sb64_skip = 0;
- ENTROPY_CONTEXT_PLANES l[4], a[4];
+ ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE];
PARTITION_CONTEXT seg_l[4], seg_a[4];
TOKENEXTRA *tp_orig = *tp;
- memcpy(&a, cm->above_context + (mi_col >> CONFIG_SB8X8), sizeof(a));
- memcpy(&l, cm->left_context, sizeof(l));
+ for (p = 0; p < MAX_MB_PLANE; p++) {
+ memcpy(a + 16 * p, cm->above_context[p] +
+ (mi_col * 4 >> (CONFIG_SB8X8 + xd->plane[p].subsampling_x)),
+ sizeof(ENTROPY_CONTEXT) * 16 >> xd->plane[p].subsampling_x);
+ memcpy(l + 16 * p, cm->left_context[p],
+ sizeof(ENTROPY_CONTEXT) * 16 >> xd->plane[p].subsampling_y);
+ }
memcpy(&seg_a, cm->above_seg_context + (mi_col >> CONFIG_SB8X8),
sizeof(seg_a));
memcpy(&seg_l, cm->left_seg_context, sizeof(seg_l));
@@ -1009,7 +958,7 @@ static void encode_sb_row(VP9_COMP *cpi,
int splitmodes_used = 0;
int sb32_skip = 0;
int j;
- ENTROPY_CONTEXT_PLANES l2[2], a2[2];
+ ENTROPY_CONTEXT l2[8 * MAX_MB_PLANE], a2[8 * MAX_MB_PLANE];
if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols)
continue;
@@ -1017,9 +966,18 @@ static void encode_sb_row(VP9_COMP *cpi,
xd->sb_index = i;
/* Function should not modify L & A contexts; save and restore on exit */
- vpx_memcpy(l2, cm->left_context + (y_idx >> CONFIG_SB8X8), sizeof(l2));
- vpx_memcpy(a2, cm->above_context + ((mi_col + x_idx) >> CONFIG_SB8X8),
- sizeof(a2));
+ for (p = 0; p < MAX_MB_PLANE; p++) {
+ vpx_memcpy(l2 + 8 * p,
+ cm->left_context[p] +
+ (y_idx * 4 >> (CONFIG_SB8X8 +
+ xd->plane[p].subsampling_y)),
+ sizeof(ENTROPY_CONTEXT) * 8 >> xd->plane[p].subsampling_y);
+ vpx_memcpy(a2 + 8 * p,
+ cm->above_context[p] +
+ ((mi_col + x_idx) * 4 >> (CONFIG_SB8X8 +
+ xd->plane[p].subsampling_x)),
+ sizeof(ENTROPY_CONTEXT) * 8 >> xd->plane[p].subsampling_x);
+ }
/* Encode MBs in raster order within the SB */
sb_partitioning[i] = BLOCK_SIZE_MB16X16;
@@ -1052,13 +1010,20 @@ static void encode_sb_row(VP9_COMP *cpi,
}
/* Restore L & A coding context to those in place on entry */
- vpx_memcpy(cm->left_context + (y_idx >> CONFIG_SB8X8), l2, sizeof(l2));
- vpx_memcpy(cm->above_context + ((mi_col + x_idx) >> CONFIG_SB8X8), a2,
- sizeof(a2));
+ for (p = 0; p < MAX_MB_PLANE; p++) {
+ vpx_memcpy(cm->left_context[p] +
+ (y_idx * 4 >> (CONFIG_SB8X8 +
+ xd->plane[p].subsampling_y)),
+ l2 + 8 * p,
+ sizeof(ENTROPY_CONTEXT) * 8 >> xd->plane[p].subsampling_y);
+ vpx_memcpy(cm->above_context[p] +
+ ((mi_col + x_idx) * 4 >> (CONFIG_SB8X8 +
+ xd->plane[p].subsampling_x)),
+ a2 + 8 * p,
+ sizeof(ENTROPY_CONTEXT) * 8 >> xd->plane[p].subsampling_x);
+ }
- xd->left_seg_context = cm->left_seg_context + (y_idx >> CONFIG_SB8X8);
- xd->above_seg_context =
- cm->above_seg_context + ((mi_col + x_idx) >> CONFIG_SB8X8);
+ set_partition_seg_context(cpi, mi_row + y_idx, mi_col + x_idx);
pl = partition_plane_context(xd, BLOCK_SIZE_SB32X32);
sb32_rate += x->partition_cost[pl][PARTITION_SPLIT];
@@ -1091,9 +1056,7 @@ static void encode_sb_row(VP9_COMP *cpi,
d += d2;
}
- xd->left_seg_context = cm->left_seg_context + (y_idx >> CONFIG_SB8X8);
- xd->above_seg_context =
- cm->above_seg_context + ((mi_col + x_idx) >> CONFIG_SB8X8);
+ set_partition_seg_context(cpi, mi_row + y_idx, mi_col + x_idx);
pl = partition_plane_context(xd, BLOCK_SIZE_SB32X32);
r += x->partition_cost[pl][PARTITION_HORZ];
@@ -1105,9 +1068,18 @@ static void encode_sb_row(VP9_COMP *cpi,
sb_partitioning[i] = BLOCK_SIZE_SB32X16;
}
- vpx_memcpy(cm->left_context + (y_idx >> CONFIG_SB8X8), l2, sizeof(l2));
- vpx_memcpy(cm->above_context + ((mi_col + x_idx) >> CONFIG_SB8X8), a2,
- sizeof(a2));
+ for (p = 0; p < MAX_MB_PLANE; p++) {
+ vpx_memcpy(cm->left_context[p] +
+ (y_idx * 4 >> (CONFIG_SB8X8 +
+ xd->plane[p].subsampling_y)),
+ l2 + 8 * p,
+ sizeof(ENTROPY_CONTEXT) * 8 >> xd->plane[p].subsampling_y);
+ vpx_memcpy(cm->above_context[p] +
+ ((mi_col + x_idx) * 4 >> (CONFIG_SB8X8 +
+ xd->plane[p].subsampling_x)),
+ a2 + 8 * p,
+ sizeof(ENTROPY_CONTEXT) * 8 >> xd->plane[p].subsampling_x);
+ }
}
// check 16x32
@@ -1135,10 +1107,7 @@ static void encode_sb_row(VP9_COMP *cpi,
d += d2;
}
- xd->left_seg_context =
- cm->left_seg_context + (y_idx >> CONFIG_SB8X8);
- xd->above_seg_context =
- cm->above_seg_context + ((mi_col + x_idx) >> CONFIG_SB8X8);
+ set_partition_seg_context(cpi, mi_row + y_idx, mi_col + x_idx);
pl = partition_plane_context(xd, BLOCK_SIZE_SB32X32);
r += x->partition_cost[pl][PARTITION_VERT];
@@ -1150,9 +1119,18 @@ static void encode_sb_row(VP9_COMP *cpi,
sb_partitioning[i] = BLOCK_SIZE_SB16X32;
}
- vpx_memcpy(cm->left_context + (y_idx >> CONFIG_SB8X8), l2, sizeof(l2));
- vpx_memcpy(cm->above_context + ((mi_col + x_idx) >> CONFIG_SB8X8), a2,
- sizeof(a2));
+ for (p = 0; p < MAX_MB_PLANE; p++) {
+ vpx_memcpy(cm->left_context[p] +
+ (y_idx * 4 >> (CONFIG_SB8X8 +
+ xd->plane[p].subsampling_y)),
+ l2 + 8 * p,
+ sizeof(ENTROPY_CONTEXT) * 8 >> xd->plane[p].subsampling_y);
+ vpx_memcpy(cm->above_context[p] +
+ ((mi_col + x_idx) * 4 >> (CONFIG_SB8X8 +
+ xd->plane[p].subsampling_x)),
+ a2 + 8 * p,
+ sizeof(ENTROPY_CONTEXT) * 8 >> xd->plane[p].subsampling_x);
+ }
}
if (!sb32_skip &&
@@ -1165,9 +1143,7 @@ static void encode_sb_row(VP9_COMP *cpi,
tp, &r, &d, BLOCK_SIZE_SB32X32,
&x->sb32_context[xd->sb_index]);
- xd->left_seg_context = cm->left_seg_context + (y_idx >> CONFIG_SB8X8);
- xd->above_seg_context =
- cm->above_seg_context + ((mi_col + x_idx) >> CONFIG_SB8X8);
+ set_partition_seg_context(cpi, mi_row + y_idx, mi_col + x_idx);
pl = partition_plane_context(xd, BLOCK_SIZE_SB32X32);
r += x->partition_cost[pl][PARTITION_NONE];
@@ -1193,18 +1169,23 @@ static void encode_sb_row(VP9_COMP *cpi,
// pixels of the lower level; also, inverting SB/MB order (big->small
// instead of small->big) means we can use as threshold for small, which
// may enable breakouts if RD is not good enough (i.e. faster)
- encode_sb(cpi, mi_row + y_idx, mi_col + x_idx, 0, tp,
- sb_partitioning[i]);
+ encode_sb(cpi, tp, mi_row + y_idx, mi_col + x_idx, 0,
+ BLOCK_SIZE_SB32X32, sb_partitioning[i], sb_partitioning);
}
- memcpy(cm->above_context + (mi_col >> CONFIG_SB8X8), &a, sizeof(a));
- memcpy(cm->left_context, &l, sizeof(l));
+ for (p = 0; p < MAX_MB_PLANE; p++) {
+ memcpy(cm->above_context[p] +
+ (mi_col * 4 >> (CONFIG_SB8X8 + xd->plane[p].subsampling_x)),
+ a + 16 * p,
+ sizeof(ENTROPY_CONTEXT) * 16 >> xd->plane[p].subsampling_x);
+ memcpy(cm->left_context[p], l + 16 * p,
+ sizeof(ENTROPY_CONTEXT) * 16 >> xd->plane[p].subsampling_y);
+ }
memcpy(cm->above_seg_context + (mi_col >> CONFIG_SB8X8), &seg_a,
sizeof(seg_a));
memcpy(cm->left_seg_context, &seg_l, sizeof(seg_l));
- xd->left_seg_context = cm->left_seg_context;
- xd->above_seg_context = cm->above_seg_context + (mi_col >> CONFIG_SB8X8);
+ set_partition_seg_context(cpi, mi_row, mi_col);
pl = partition_plane_context(xd, BLOCK_SIZE_SB64X64);
sb64_rate += x->partition_cost[pl][PARTITION_SPLIT];
@@ -1231,8 +1212,7 @@ static void encode_sb_row(VP9_COMP *cpi,
d += d2;
}
- xd->left_seg_context = cm->left_seg_context;
- xd->above_seg_context = cm->above_seg_context + (mi_col >> CONFIG_SB8X8);
+ set_partition_seg_context(cpi, mi_row, mi_col);
pl = partition_plane_context(xd, BLOCK_SIZE_SB64X64);
r += x->partition_cost[pl][PARTITION_HORZ];
@@ -1244,8 +1224,14 @@ static void encode_sb_row(VP9_COMP *cpi,
sb_partitioning[0] = BLOCK_SIZE_SB64X32;
}
- vpx_memcpy(cm->left_context, l, sizeof(l));
- vpx_memcpy(cm->above_context + (mi_col >> CONFIG_SB8X8), a, sizeof(a));
+ for (p = 0; p < MAX_MB_PLANE; p++) {
+ memcpy(cm->above_context[p] +
+ (mi_col * 4 >> (CONFIG_SB8X8 + xd->plane[p].subsampling_x)),
+ a + 16 * p,
+ sizeof(ENTROPY_CONTEXT) * 16 >> xd->plane[p].subsampling_x);
+ memcpy(cm->left_context[p], l + 16 * p,
+ sizeof(ENTROPY_CONTEXT) * 16 >> xd->plane[p].subsampling_y);
+ }
}
// check 32x64
@@ -1271,8 +1257,7 @@ static void encode_sb_row(VP9_COMP *cpi,
d += d2;
}
- xd->left_seg_context = cm->left_seg_context;
- xd->above_seg_context = cm->above_seg_context + (mi_col >> CONFIG_SB8X8);
+ set_partition_seg_context(cpi, mi_row, mi_col);
pl = partition_plane_context(xd, BLOCK_SIZE_SB64X64);
r += x->partition_cost[pl][PARTITION_VERT];
@@ -1284,8 +1269,14 @@ static void encode_sb_row(VP9_COMP *cpi,
sb_partitioning[0] = BLOCK_SIZE_SB32X64;
}
- vpx_memcpy(cm->left_context, l, sizeof(l));
- vpx_memcpy(cm->above_context + (mi_col >> CONFIG_SB8X8), a, sizeof(a));
+ for (p = 0; p < MAX_MB_PLANE; p++) {
+ memcpy(cm->above_context[p] +
+ (mi_col * 4 >> (CONFIG_SB8X8 + xd->plane[p].subsampling_x)),
+ a + 16 * p,
+ sizeof(ENTROPY_CONTEXT) * 16 >> xd->plane[p].subsampling_x);
+ memcpy(cm->left_context[p], l + 16 * p,
+ sizeof(ENTROPY_CONTEXT) * 16 >> xd->plane[p].subsampling_y);
+ }
}
if (!sb64_skip &&
@@ -1296,8 +1287,7 @@ static void encode_sb_row(VP9_COMP *cpi,
pick_sb_modes(cpi, mi_row, mi_col, tp, &r, &d,
BLOCK_SIZE_SB64X64, &x->sb64_context);
- xd->left_seg_context = cm->left_seg_context;
- xd->above_seg_context = cm->above_seg_context + (mi_col >> CONFIG_SB8X8);
+ set_partition_seg_context(cpi, mi_row, mi_col);
pl = partition_plane_context(xd, BLOCK_SIZE_SB64X64);
r += x->partition_cost[pl][PARTITION_NONE];
@@ -1310,7 +1300,8 @@ static void encode_sb_row(VP9_COMP *cpi,
}
assert(tp_orig == *tp);
- encode_sb64(cpi, mi_row, mi_col, tp, sb_partitioning);
+ encode_sb(cpi, tp, mi_row, mi_col, 1,
+ BLOCK_SIZE_SB64X64, sb_partitioning[0], sb_partitioning);
assert(tp_orig < *tp);
}
}
@@ -1368,8 +1359,10 @@ static void init_encode_frame_mb_context(VP9_COMP *cpi) {
vp9_zero(cpi->interintra_select_count);
#endif
- vpx_memset(cm->above_context, 0,
- sizeof(ENTROPY_CONTEXT_PLANES) * mb_cols_aligned_to_sb(cm));
+ // Note: this memset assumes above_context[0], [1] and [2]
+ // are allocated as part of the same buffer.
+ vpx_memset(cm->above_context[0], 0, sizeof(ENTROPY_CONTEXT) * 4 *
+ MAX_MB_PLANE * mb_cols_aligned_to_sb(cm));
vpx_memset(cm->above_seg_context, 0, sizeof(PARTITION_CONTEXT) *
mb_cols_aligned_to_sb(cm));
}
@@ -1564,19 +1557,22 @@ static void set_txfm_flag(MODE_INFO *mi, int mis, int ymbs, int xmbs,
}
}
-static void reset_skip_txfm_size_sb(VP9_COMP *cpi, MODE_INFO *mi,
- int mis, TX_SIZE txfm_max,
- int mi_rows_left, int mi_cols_left,
- BLOCK_SIZE_TYPE bsize) {
+static void reset_skip_txfm_size_b(VP9_COMP *cpi, MODE_INFO *mi,
+ int mis, TX_SIZE txfm_max,
+ int bw, int bh, int mi_row, int mi_col,
+ BLOCK_SIZE_TYPE bsize) {
+ VP9_COMMON *const cm = &cpi->common;
MB_MODE_INFO *const mbmi = &mi->mbmi;
+ if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
+ return;
+
if (mbmi->txfm_size > txfm_max) {
MACROBLOCK *const x = &cpi->mb;
MACROBLOCKD *const xd = &x->e_mbd;
const int segment_id = mbmi->segment_id;
- const int bh = 1 << mi_height_log2(bsize), bw = 1 << mi_width_log2(bsize);
- const int ymbs = MIN(bh, mi_rows_left);
- const int xmbs = MIN(bw, mi_cols_left);
+ const int ymbs = MIN(bh, cm->mi_rows - mi_row);
+ const int xmbs = MIN(bw, cm->mi_cols - mi_col);
xd->mode_info_context = mi;
assert(vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP) ||
@@ -1585,6 +1581,56 @@ static void reset_skip_txfm_size_sb(VP9_COMP *cpi, MODE_INFO *mi,
}
}
+static void reset_skip_txfm_size_sb(VP9_COMP *cpi, MODE_INFO *mi,
+ TX_SIZE txfm_max,
+ int mi_row, int mi_col,
+ BLOCK_SIZE_TYPE bsize) {
+ VP9_COMMON *const cm = &cpi->common;
+ const int mis = cm->mode_info_stride;
+ int bwl, bhl;
+ const int bsl = mi_width_log2(bsize), bs = 1 << (bsl - 1);
+
+ if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
+ return;
+
+ bwl = mi_width_log2(mi->mbmi.sb_type);
+ bhl = mi_height_log2(mi->mbmi.sb_type);
+
+ if (bwl == bsl && bhl == bsl) {
+ reset_skip_txfm_size_b(cpi, mi, mis, txfm_max, 1 << bsl, 1 << bsl,
+ mi_row, mi_col, bsize);
+ } else if (bwl == bsl && bhl < bsl) {
+ reset_skip_txfm_size_b(cpi, mi, mis, txfm_max, 1 << bsl, bs,
+ mi_row, mi_col, bsize);
+ reset_skip_txfm_size_b(cpi, mi + bs * mis, mis, txfm_max, 1 << bsl, bs,
+ mi_row + bs, mi_col, bsize);
+ } else if (bwl < bsl && bhl == bsl) {
+ reset_skip_txfm_size_b(cpi, mi, mis, txfm_max, bs, 1 << bsl,
+ mi_row, mi_col, bsize);
+ reset_skip_txfm_size_b(cpi, mi + bs, mis, txfm_max, bs, 1 << bsl,
+ mi_row, mi_col + bs, bsize);
+ } else {
+ BLOCK_SIZE_TYPE subsize;
+ int n;
+
+ assert(bwl < bsl && bhl < bsl);
+ if (bsize == BLOCK_SIZE_SB64X64) {
+ subsize = BLOCK_SIZE_SB32X32;
+ } else {
+ assert(bsize == BLOCK_SIZE_SB32X32);
+ subsize = BLOCK_SIZE_MB16X16;
+ }
+
+ for (n = 0; n < 4; n++) {
+ const int y_idx = n >> 1, x_idx = n & 0x01;
+
+ reset_skip_txfm_size_sb(cpi, mi + y_idx * bs * mis + x_idx * bs,
+ txfm_max, mi_row + y_idx * bs,
+ mi_col + x_idx * bs, subsize);
+ }
+ }
+}
+
static void reset_skip_txfm_size(VP9_COMP *cpi, TX_SIZE txfm_max) {
VP9_COMMON *const cm = &cpi->common;
int mi_row, mi_col;
@@ -1596,92 +1642,8 @@ static void reset_skip_txfm_size(VP9_COMP *cpi, TX_SIZE txfm_max) {
mi = mi_ptr;
for (mi_col = 0; mi_col < cm->mi_cols;
mi_col += (4 << CONFIG_SB8X8), mi += (4 << CONFIG_SB8X8)) {
- if (mi->mbmi.sb_type == BLOCK_SIZE_SB64X64) {
- reset_skip_txfm_size_sb(cpi, mi, mis, txfm_max,
- cm->mi_rows - mi_row, cm->mi_cols - mi_col,
- BLOCK_SIZE_SB64X64);
- } else if (mi->mbmi.sb_type == BLOCK_SIZE_SB64X32) {
- reset_skip_txfm_size_sb(cpi, mi, mis, txfm_max,
- cm->mi_rows - mi_row, cm->mi_cols - mi_col,
- BLOCK_SIZE_SB64X32);
- if (mi_row + (2 << CONFIG_SB8X8) != cm->mi_rows)
- reset_skip_txfm_size_sb(cpi, mi + (2 << CONFIG_SB8X8) * mis, mis,
- txfm_max,
- cm->mi_rows - mi_row - (2 << CONFIG_SB8X8),
- cm->mi_cols - mi_col,
- BLOCK_SIZE_SB64X32);
- } else if (mi->mbmi.sb_type == BLOCK_SIZE_SB32X64) {
- reset_skip_txfm_size_sb(cpi, mi, mis, txfm_max,
- cm->mi_rows - mi_row, cm->mi_cols - mi_col,
- BLOCK_SIZE_SB32X64);
- if (mi_col + (2 << CONFIG_SB8X8) != cm->mi_cols)
- reset_skip_txfm_size_sb(cpi, mi + (2 << CONFIG_SB8X8), mis, txfm_max,
- cm->mi_rows - mi_row,
- cm->mi_cols - mi_col - (2 << CONFIG_SB8X8),
- BLOCK_SIZE_SB32X64);
- } else {
- int i;
-
- for (i = 0; i < 4; i++) {
- const int x_idx_sb = (i & 1) << (1 + CONFIG_SB8X8);
- const int y_idx_sb = (i & 2) << CONFIG_SB8X8;
- MODE_INFO *sb_mi = mi + y_idx_sb * mis + x_idx_sb;
-
- if (mi_row + y_idx_sb >= cm->mi_rows ||
- mi_col + x_idx_sb >= cm->mi_cols)
- continue;
-
- if (sb_mi->mbmi.sb_type == BLOCK_SIZE_SB32X32) {
- reset_skip_txfm_size_sb(cpi, sb_mi, mis, txfm_max,
- cm->mi_rows - mi_row - y_idx_sb,
- cm->mi_cols - mi_col - x_idx_sb,
- BLOCK_SIZE_SB32X32);
- } else if (sb_mi->mbmi.sb_type == BLOCK_SIZE_SB32X16) {
- reset_skip_txfm_size_sb(cpi, sb_mi, mis, txfm_max,
- cm->mi_rows - mi_row - y_idx_sb,
- cm->mi_cols - mi_col - x_idx_sb,
- BLOCK_SIZE_SB32X16);
- if (mi_row + y_idx_sb + (1 << CONFIG_SB8X8) != cm->mi_rows)
- reset_skip_txfm_size_sb(cpi, sb_mi + (mis << CONFIG_SB8X8), mis,
- txfm_max,
- cm->mi_rows - mi_row - y_idx_sb -
- (1 << CONFIG_SB8X8),
- cm->mi_cols - mi_col - x_idx_sb,
- BLOCK_SIZE_SB32X16);
- } else if (sb_mi->mbmi.sb_type == BLOCK_SIZE_SB16X32) {
- reset_skip_txfm_size_sb(cpi, sb_mi, mis, txfm_max,
- cm->mi_rows - mi_row - y_idx_sb,
- cm->mi_cols - mi_col - x_idx_sb,
- BLOCK_SIZE_SB16X32);
- if (mi_col + x_idx_sb + (1 << CONFIG_SB8X8) != cm->mi_cols)
- reset_skip_txfm_size_sb(cpi, sb_mi + (1 << CONFIG_SB8X8), mis,
- txfm_max,
- cm->mi_rows - mi_row - y_idx_sb,
- cm->mi_cols - mi_col - x_idx_sb -
- (1 << CONFIG_SB8X8),
- BLOCK_SIZE_SB16X32);
- } else {
- int m;
-
- for (m = 0; m < 4; m++) {
- const int x_idx = x_idx_sb + ((m & 1) << CONFIG_SB8X8);
- const int y_idx = y_idx_sb + ((m >> 1) << CONFIG_SB8X8);
- MODE_INFO *mb_mi;
-
- if (mi_col + x_idx >= cm->mi_cols ||
- mi_row + y_idx >= cm->mi_rows)
- continue;
-
- mb_mi = mi + y_idx * mis + x_idx;
- assert(mb_mi->mbmi.sb_type == BLOCK_SIZE_MB16X16);
- reset_skip_txfm_size_sb(cpi, mb_mi, mis, txfm_max,
- cm->mi_rows - mi_row - y_idx,
- cm->mi_cols - mi_col - x_idx,
- BLOCK_SIZE_MB16X16);
- }
- }
- }
- }
+ reset_skip_txfm_size_sb(cpi, mi, txfm_max,
+ mi_row, mi_col, BLOCK_SIZE_SB64X64);
}
}
}
@@ -1984,7 +1946,7 @@ static void encode_macroblock(VP9_COMP *cpi, TOKENEXTRA **t,
#endif
if (mbmi->mode == I4X4_PRED) {
vp9_encode_intra16x16mbuv(cm, x);
- vp9_encode_intra4x4mby(x);
+ vp9_encode_intra4x4mby(x, BLOCK_SIZE_MB16X16);
} else if (mbmi->mode == I8X8_PRED) {
vp9_encode_intra8x8mby(x);
vp9_encode_intra8x8mbuv(x);
@@ -2101,8 +2063,7 @@ static void encode_macroblock(VP9_COMP *cpi, TOKENEXTRA **t,
}
#endif
- vp9_tokenize_mb(cpi, xd, t, !output_enabled);
-
+ vp9_tokenize_sb(cpi, xd, t, !output_enabled, BLOCK_SIZE_MB16X16);
} else {
// FIXME(rbultje): not tile-aware (mi - 1)
int mb_skip_context =