Commit 90a91cc6 authored by Jingning Han's avatar Jingning Han

Recursive partition syntax coding

Enable recursive partition information coding from SB64X64 down to
MB16X16. The bit-stream syntax is now supporting rectangular block
sizes. It starts from SB64X64 and recursively describes the partition
type of the current block. If the partition type is PARTITION_NONE,
the block is coded as a single unit; if it is PARTITION_HORZ or
PARTITION_VERT, the block is segmented into two independently coded
rectangular units, with no further partition needed; otherwise, the
block is segmented into 4 square blocks. i.e., PARTITION_SPLIT case,
each can be potentially further partitioned.

Forward adaptive probability modeling is used for the partition
information coding, conditioned on the current block size.

Change-Id: I499365fb547839d555498e3bcc0387d8a3587d87
parent 0e65e08e
......@@ -240,6 +240,11 @@ static INLINE int b_height_log2(BLOCK_SIZE_TYPE sb_type) {
return mb_height_log2(sb_type) + 2;
}
static INLINE int partition_plane(BLOCK_SIZE_TYPE sb_type) {
assert(mb_width_log2(sb_type) == mb_height_log2(sb_type));
return (mb_width_log2(sb_type) - 1);
}
typedef enum {
BLOCK_4X4_LG2 = 0,
BLOCK_8X8_LG2 = 2,
......
......@@ -151,6 +151,17 @@ const int vp9_mbsplit_count [VP9_NUMMBSPLITS] = { 2, 2, 4, 16};
const vp9_prob vp9_mbsplit_probs [VP9_NUMMBSPLITS - 1] = { 110, 111, 150};
#if CONFIG_SBSEGMENT
const vp9_prob vp9_partition_probs[PARTITION_PLANES][PARTITION_TYPES - 1] = {
{110, 111, 150},
{110, 111, 150},
};
#else
const vp9_prob vp9_partition_probs[PARTITION_PLANES][PARTITION_TYPES - 1] = {
{200}, {200},
};
#endif
/* Array indices are identical to previously-existing INTRAMODECONTEXTNODES. */
const vp9_tree_index vp9_kf_bmode_tree[VP9_KF_BINTRAMODES * 2 - 2] = {
......@@ -283,6 +294,18 @@ const vp9_tree_index vp9_sub_mv_ref_tree[6] = {
-ZERO4X4, -NEW4X4
};
#if CONFIG_SBSEGMENT
const vp9_tree_index vp9_partition_tree[6] = {
-PARTITION_NONE, 2,
-PARTITION_HORZ, 4,
-PARTITION_VERT, -PARTITION_SPLIT
};
#else
const vp9_tree_index vp9_partition_tree[2] = {
-PARTITION_NONE, -PARTITION_SPLIT
};
#endif
struct vp9_token vp9_bmode_encodings[VP9_NKF_BINTRAMODES];
struct vp9_token vp9_kf_bmode_encodings[VP9_KF_BINTRAMODES];
struct vp9_token vp9_ymode_encodings[VP9_YMODES];
......@@ -297,6 +320,8 @@ struct vp9_token vp9_mv_ref_encoding_array[VP9_MVREFS];
struct vp9_token vp9_sb_mv_ref_encoding_array[VP9_MVREFS];
struct vp9_token vp9_sub_mv_ref_encoding_array[VP9_SUBMVREFS];
struct vp9_token vp9_partition_encodings[PARTITION_TYPES];
void vp9_init_mbmode_probs(VP9_COMMON *x) {
unsigned int bct [VP9_YMODES] [2]; /* num Ymodes > num UV modes */
......@@ -332,6 +357,10 @@ void vp9_init_mbmode_probs(VP9_COMMON *x) {
vpx_memcpy(x->fc.mbsplit_prob, vp9_mbsplit_probs, sizeof(vp9_mbsplit_probs));
vpx_memcpy(x->fc.switchable_interp_prob, vp9_switchable_interp_prob,
sizeof(vp9_switchable_interp_prob));
vpx_memcpy(x->fc.partition_prob, vp9_partition_probs,
sizeof(vp9_partition_probs));
#if CONFIG_COMP_INTERINTRA_PRED
x->fc.interintra_prob = VP9_DEF_INTERINTRA_PROB;
#endif
......@@ -433,6 +462,7 @@ void vp9_entropy_mode_init() {
vp9_tokens_from_tree(vp9_mbsplit_encodings, vp9_mbsplit_tree);
vp9_tokens_from_tree(vp9_switchable_interp_encodings,
vp9_switchable_interp_tree);
vp9_tokens_from_tree(vp9_partition_encodings, vp9_partition_tree);
vp9_tokens_from_tree_offset(vp9_mv_ref_encoding_array,
vp9_mv_ref_tree, NEARESTMV);
......@@ -631,6 +661,10 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) {
interintra_prob, factor);
}
#endif
for (i = 0; i < PARTITION_PLANES; i++)
update_mode_probs(PARTITION_TYPES, vp9_partition_tree,
cm->fc.partition_counts[i], cm->fc.pre_partition_prob[i],
cm->fc.partition_prob[i], 0);
}
static void set_default_lf_deltas(MACROBLOCKD *xd) {
......
......@@ -70,6 +70,10 @@ extern struct vp9_token vp9_mv_ref_encoding_array[VP9_MVREFS];
extern struct vp9_token vp9_sb_mv_ref_encoding_array[VP9_MVREFS];
extern struct vp9_token vp9_sub_mv_ref_encoding_array[VP9_SUBMVREFS];
// probability models for partition information
extern const vp9_tree_index vp9_partition_tree[];
extern struct vp9_token vp9_partition_encodings[PARTITION_TYPES];
void vp9_entropy_mode_init(void);
struct VP9Common;
......
......@@ -27,4 +27,16 @@ typedef enum BLOCK_SIZE_TYPE {
BLOCK_SIZE_SB64X64,
} BLOCK_SIZE_TYPE;
typedef enum PARTITION_TYPE {
PARTITION_NONE,
#if CONFIG_SBSEGMENT
PARTITION_HORZ,
PARTITION_VERT,
#endif
PARTITION_SPLIT,
PARTITION_TYPES
} PARTITION_TYPE;
#define PARTITION_PLANES 2 // number of probability models
#endif // VP9_COMMON_VP9_ENUMS_H_
......@@ -68,6 +68,7 @@ typedef struct frame_contexts {
vp9_prob i8x8_mode_prob[VP9_I8X8_MODES - 1];
vp9_prob sub_mv_ref_prob[SUBMVREF_COUNT][VP9_SUBMVREFS - 1];
vp9_prob mbsplit_prob[VP9_NUMMBSPLITS - 1];
vp9_prob partition_prob[PARTITION_PLANES][PARTITION_TYPES - 1];
vp9_coeff_probs coef_probs_4x4[BLOCK_TYPES];
vp9_coeff_probs coef_probs_8x8[BLOCK_TYPES];
......@@ -95,6 +96,7 @@ typedef struct frame_contexts {
vp9_prob pre_i8x8_mode_prob[VP9_I8X8_MODES - 1];
vp9_prob pre_sub_mv_ref_prob[SUBMVREF_COUNT][VP9_SUBMVREFS - 1];
vp9_prob pre_mbsplit_prob[VP9_NUMMBSPLITS - 1];
vp9_prob pre_partition_prob[PARTITION_PLANES][PARTITION_TYPES - 1];
unsigned int bmode_counts[VP9_NKF_BINTRAMODES];
unsigned int ymode_counts[VP9_YMODES]; /* interframe intra mode probs */
unsigned int sb_ymode_counts[VP9_I32X32_MODES];
......@@ -102,6 +104,7 @@ typedef struct frame_contexts {
unsigned int i8x8_mode_counts[VP9_I8X8_MODES]; /* interframe intra probs */
unsigned int sub_mv_ref_counts[SUBMVREF_COUNT][VP9_SUBMVREFS];
unsigned int mbsplit_counts[VP9_NUMMBSPLITS];
unsigned int partition_counts[PARTITION_PLANES][PARTITION_TYPES];
vp9_coeff_probs pre_coef_probs_4x4[BLOCK_TYPES];
vp9_coeff_probs pre_coef_probs_8x8[BLOCK_TYPES];
......@@ -279,8 +282,6 @@ typedef struct VP9Common {
vp9_prob prob_intra_coded;
vp9_prob prob_last_coded;
vp9_prob prob_gf_coded;
vp9_prob prob_sb32_coded;
vp9_prob prob_sb64_coded;
// Context probabilities when using predictive coding of segment id
vp9_prob segment_pred_probs[PREDICTION_PROBS];
......
......@@ -483,7 +483,9 @@ static void mb_mode_mv_init(VP9D_COMP *pbi, vp9_reader *r) {
if (!cm->kf_ymode_probs_update)
cm->kf_ymode_probs_index = vp9_read_literal(r, 3);
} else {
int i;
nmv_context *const nmvc = &pbi->common.fc.nmvc;
MACROBLOCKD *const xd = &pbi->mb;
int i, j;
if (cm->mcomp_filter_type == SWITCHABLE)
read_switchable_interp_probs(pbi, r);
......@@ -517,7 +519,14 @@ static void mb_mode_mv_init(VP9D_COMP *pbi, vp9_reader *r) {
for (i = 0; i < VP9_I32X32_MODES - 1; ++i)
cm->fc.sb_ymode_prob[i] = vp9_read_prob(r);
read_nmvprobs(r, &cm->fc.nmvc, pbi->mb.allow_high_precision_mv);
for (j = 0; j < PARTITION_PLANES; j++) {
if (vp9_read_bit(r)) {
for (i = 0; i < PARTITION_TYPES - 1; i++)
cm->fc.partition_prob[j][i] = vp9_read_prob(r);
}
}
read_nmvprobs(r, nmvc, xd->allow_high_precision_mv);
}
}
......
......@@ -815,10 +815,83 @@ static void set_refs(VP9D_COMP *pbi, int mb_row, int mb_col) {
}
}
/* Decode a row of Superblocks (2x2 region of MBs) */
static void decode_sb_row(VP9D_COMP *pbi, int mb_row, vp9_reader* r) {
static void decode_modes_b(VP9D_COMP *pbi, int mb_row, int mb_col,
vp9_reader *r, BLOCK_SIZE_TYPE bsize) {
MACROBLOCKD *const xd = &pbi->mb;
set_offsets(pbi, bsize, mb_row, mb_col);
vp9_decode_mb_mode_mv(pbi, xd, mb_row, mb_col, r);
set_refs(pbi, mb_row, mb_col);
// TODO(jingning): merge decode_sb_ and decode_mb_
if (bsize > BLOCK_SIZE_MB16X16)
decode_sb(pbi, xd, mb_row, mb_col, r, bsize);
else
decode_mb(pbi, xd, mb_row, mb_col, r);
xd->corrupted |= bool_error(r);
}
static void decode_modes_sb(VP9D_COMP *pbi, int mb_row, int mb_col,
vp9_reader* r, BLOCK_SIZE_TYPE bsize) {
VP9_COMMON *const pc = &pbi->common;
MACROBLOCKD *const xd = &pbi->mb;
int bsl = mb_width_log2(bsize), bs = (1 << bsl) / 2;
int n;
PARTITION_TYPE partition = PARTITION_NONE;
BLOCK_SIZE_TYPE subsize;
if (mb_row >= pc->mb_rows || mb_col >= pc->mb_cols)
return;
if (bsize > BLOCK_SIZE_MB16X16) {
// read the partition information
partition = treed_read(r, vp9_partition_tree,
pc->fc.partition_prob[bsl - 1]);
pc->fc.partition_counts[bsl - 1][partition]++;
}
switch (partition) {
case PARTITION_NONE:
subsize = bsize;
decode_modes_b(pbi, mb_row, mb_col, r, subsize);
break;
#if CONFIG_SBSEGMENT
case PARTITION_HORZ:
subsize = (bsize == BLOCK_SIZE_SB64X64) ? BLOCK_SIZE_SB64X32 :
BLOCK_SIZE_SB32X16;
decode_modes_b(pbi, mb_row, mb_col, r, subsize);
if ((mb_row + bs) < pc->mb_rows)
decode_modes_b(pbi, mb_row + bs, mb_col, r, subsize);
break;
case PARTITION_VERT:
subsize = (bsize == BLOCK_SIZE_SB64X64) ? BLOCK_SIZE_SB32X64 :
BLOCK_SIZE_SB16X32;
decode_modes_b(pbi, mb_row, mb_col, r, subsize);
if ((mb_col + bs) < pc->mb_cols)
decode_modes_b(pbi, mb_row, mb_col + bs, r, subsize);
break;
#endif
case PARTITION_SPLIT:
subsize = (bsize == BLOCK_SIZE_SB64X64) ? BLOCK_SIZE_SB32X32 :
BLOCK_SIZE_MB16X16;
for (n = 0; n < 4; n++) {
int j = n >> 1, i = n & 0x01;
if (subsize == BLOCK_SIZE_SB32X32)
xd->sb_index = n;
else
xd->mb_index = n;
decode_modes_sb(pbi, mb_row + j * bs, mb_col + i * bs, r, subsize);
}
break;
default:
assert(0);
}
}
/* Decode a row of Superblocks (4x4 region of MBs) */
static void decode_sb_row(VP9D_COMP *pbi, int mb_row, vp9_reader* r) {
VP9_COMMON *const pc = &pbi->common;
int mb_col;
// For a SB there are 2 left contexts, each pertaining to a MB row within
......@@ -826,60 +899,10 @@ static void decode_sb_row(VP9D_COMP *pbi, int mb_row, vp9_reader* r) {
for (mb_col = pc->cur_tile_mb_col_start;
mb_col < pc->cur_tile_mb_col_end; mb_col += 4) {
if (vp9_read(r, pc->prob_sb64_coded)) {
// SB64 decoding
set_offsets(pbi, BLOCK_SIZE_SB64X64, mb_row, mb_col);
vp9_decode_mb_mode_mv(pbi, xd, mb_row, mb_col, r);
set_refs(pbi, mb_row, mb_col);
decode_sb(pbi, xd, mb_row, mb_col, r, BLOCK_SIZE_SB64X64);
xd->corrupted |= bool_error(r);
} else {
// not SB64
int j;
for (j = 0; j < 4; j++) {
const int x_idx_sb = mb_col + 2 * (j % 2);
const int y_idx_sb = mb_row + 2 * (j / 2);
if (y_idx_sb >= pc->mb_rows || x_idx_sb >= pc->mb_cols)
continue; // MB lies outside frame, skip on to next
xd->sb_index = j;
if (vp9_read(r, pc->prob_sb32_coded)) {
// SB32 decoding
set_offsets(pbi, BLOCK_SIZE_SB32X32, y_idx_sb, x_idx_sb);
vp9_decode_mb_mode_mv(pbi, xd, y_idx_sb, x_idx_sb, r);
set_refs(pbi, y_idx_sb, x_idx_sb);
decode_sb(pbi, xd, y_idx_sb, x_idx_sb, r, BLOCK_SIZE_SB32X32);
xd->corrupted |= bool_error(r);
} else {
// not SB32
// Process the 4 MBs within the SB in the order:
// top-left, top-right, bottom-left, bottom-right
int i;
for (i = 0; i < 4; i++) {
const int x_idx_mb = x_idx_sb + (i % 2);
const int y_idx_mb = y_idx_sb + (i / 2);
if (y_idx_mb >= pc->mb_rows || x_idx_mb >= pc->mb_cols)
continue; // MB lies outside frame, skip on to next
xd->mb_index = i;
// MB decoding
set_offsets(pbi, BLOCK_SIZE_MB16X16, y_idx_mb, x_idx_mb);
vp9_decode_mb_mode_mv(pbi, xd, y_idx_mb, x_idx_mb, r);
set_refs(pbi, y_idx_mb, x_idx_mb);
decode_mb(pbi, xd, y_idx_mb, x_idx_mb, r);
xd->corrupted |= bool_error(r);
}
}
}
}
decode_modes_sb(pbi, mb_row, mb_col, r, BLOCK_SIZE_SB64X64);
}
}
static void setup_token_decoder(VP9D_COMP *pbi,
const uint8_t *data,
vp9_reader *r) {
......@@ -1290,6 +1313,7 @@ static void update_frame_context(VP9D_COMP *pbi, vp9_reader *r) {
vp9_copy(fc->pre_i8x8_mode_prob, fc->i8x8_mode_prob);
vp9_copy(fc->pre_sub_mv_ref_prob, fc->sub_mv_ref_prob);
vp9_copy(fc->pre_mbsplit_prob, fc->mbsplit_prob);
vp9_copy(fc->pre_partition_prob, fc->partition_prob);
fc->pre_nmvc = fc->nmvc;
vp9_zero(fc->coef_counts_4x4);
......@@ -1306,6 +1330,7 @@ static void update_frame_context(VP9D_COMP *pbi, vp9_reader *r) {
vp9_zero(fc->mbsplit_counts);
vp9_zero(fc->NMVcount);
vp9_zero(fc->mv_ref_ct);
vp9_zero(fc->partition_counts);
#if CONFIG_COMP_INTERINTRA_PRED
fc->pre_interintra_prob = fc->interintra_prob;
......@@ -1497,8 +1522,6 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) {
setup_pred_probs(pc, &header_bc);
pc->prob_sb64_coded = vp9_read_prob(&header_bc);
pc->prob_sb32_coded = vp9_read_prob(&header_bc);
xd->lossless = vp9_read_bit(&header_bc);
pc->txfm_mode = xd->lossless ? ONLY_4X4 : read_txfm_mode(&header_bc);
if (pc->txfm_mode == TX_MODE_SELECT) {
......
......@@ -1673,64 +1673,104 @@ static void write_modes_b(VP9_COMP *cpi, MODE_INFO *m, vp9_writer *bc,
pack_mb_tokens(bc, tok, tok_end);
}
static void write_modes_sb(VP9_COMP *cpi, MODE_INFO *m, vp9_writer *bc,
TOKENEXTRA **tok, TOKENEXTRA *tok_end,
int mb_row, int mb_col,
BLOCK_SIZE_TYPE bsize) {
VP9_COMMON *const cm = &cpi->common;
const int mis = cm->mode_info_stride;
int bwl, bhl;
#if CONFIG_SBSEGMENT
int bw, bh;
#endif
int bsl = mb_width_log2(bsize), bs = (1 << bsl) / 2;
int n;
PARTITION_TYPE partition;
BLOCK_SIZE_TYPE subsize;
if (mb_row >= cm->mb_rows || mb_col >= cm->mb_cols)
return;
bwl = mb_width_log2(m->mbmi.sb_type);
bhl = mb_height_log2(m->mbmi.sb_type);
#if CONFIG_SBSEGMENT
bw = 1 << bwl;
bh = 1 << bhl;
#endif
// parse the partition type
if ((bwl == bsl) && (bhl == bsl))
partition = PARTITION_NONE;
#if CONFIG_SBSEGMENT
else if ((bwl == bsl) && (bhl < bsl))
partition = PARTITION_HORZ;
else if ((bwl < bsl) && (bhl == bsl))
partition = PARTITION_VERT;
#endif
else if ((bwl < bsl) && (bhl < bsl))
partition = PARTITION_SPLIT;
else
assert(0);
if (bsize > BLOCK_SIZE_MB16X16)
// encode the partition information
write_token(bc, vp9_partition_tree, cm->fc.partition_prob[bsl - 1],
vp9_partition_encodings + partition);
switch (partition) {
case PARTITION_NONE:
write_modes_b(cpi, m, bc, tok, tok_end, mb_row, mb_col);
break;
#if CONFIG_SBSEGMENT
case PARTITION_HORZ:
write_modes_b(cpi, m, bc, tok, tok_end, mb_row, mb_col);
if ((mb_row + bh) < cm->mb_rows)
write_modes_b(cpi, m + bh * mis, bc, tok, tok_end, mb_row + bh, mb_col);
break;
case PARTITION_VERT:
write_modes_b(cpi, m, bc, tok, tok_end, mb_row, mb_col);
if ((mb_col + bw) < cm->mb_cols)
write_modes_b(cpi, m + bw, bc, tok, tok_end, mb_row, mb_col + bw);
break;
#endif
case PARTITION_SPLIT:
// TODO(jingning): support recursive partitioning down to 16x16 as for
// now. need to merge in 16x8, 8x16, 8x8, and smaller partitions.
if (bsize == BLOCK_SIZE_SB64X64)
subsize = BLOCK_SIZE_SB32X32;
else if (bsize == BLOCK_SIZE_SB32X32)
subsize = BLOCK_SIZE_MB16X16;
else
assert(0);
for (n = 0; n < 4; n++) {
int j = n >> 1, i = n & 0x01;
write_modes_sb(cpi, m + j * bs * mis + i * bs, bc, tok, tok_end,
mb_row + j * bs, mb_col + i * bs, subsize);
}
break;
default:
assert(0);
}
}
static void write_modes(VP9_COMP *cpi, vp9_writer* const bc,
TOKENEXTRA **tok, TOKENEXTRA *tok_end) {
VP9_COMMON *const c = &cpi->common;
const int mis = c->mode_info_stride;
MODE_INFO *m, *m_ptr = c->mi;
int i, mb_row, mb_col;
int mb_row, mb_col;
m_ptr += c->cur_tile_mb_col_start + c->cur_tile_mb_row_start * mis;
for (mb_row = c->cur_tile_mb_row_start;
mb_row < c->cur_tile_mb_row_end; mb_row += 4, m_ptr += 4 * mis) {
m = m_ptr;
for (mb_col = c->cur_tile_mb_col_start;
mb_col < c->cur_tile_mb_col_end; mb_col += 4, m += 4) {
vp9_write(bc, m->mbmi.sb_type == BLOCK_SIZE_SB64X64, c->prob_sb64_coded);
if (m->mbmi.sb_type == BLOCK_SIZE_SB64X64) {
write_modes_b(cpi, m, bc, tok, tok_end, mb_row, mb_col);
} else {
int j;
for (j = 0; j < 4; j++) {
const int x_idx_sb = (j & 1) << 1, y_idx_sb = j & 2;
MODE_INFO *sb_m = m + y_idx_sb * mis + x_idx_sb;
if (mb_col + x_idx_sb >= c->mb_cols ||
mb_row + y_idx_sb >= c->mb_rows)
continue;
vp9_write(bc, sb_m->mbmi.sb_type == BLOCK_SIZE_SB32X32,
c->prob_sb32_coded);
if (sb_m->mbmi.sb_type) {
assert(sb_m->mbmi.sb_type == BLOCK_SIZE_SB32X32);
write_modes_b(cpi, sb_m, bc, tok, tok_end,
mb_row + y_idx_sb, mb_col + x_idx_sb);
} else {
// Process the 4 MBs in the order:
// top-left, top-right, bottom-left, bottom-right
for (i = 0; i < 4; i++) {
const int x_idx = x_idx_sb + (i & 1), y_idx = y_idx_sb + (i >> 1);
MODE_INFO *mb_m = m + x_idx + y_idx * mis;
if (mb_row + y_idx >= c->mb_rows ||
mb_col + x_idx >= c->mb_cols) {
// MB lies outside frame, move on
continue;
}
assert(mb_m->mbmi.sb_type == BLOCK_SIZE_MB16X16);
write_modes_b(cpi, mb_m, bc, tok, tok_end,
mb_row + y_idx, mb_col + x_idx);
}
}
}
}
}
mb_col < c->cur_tile_mb_col_end; mb_col += 4, m += 4)
write_modes_sb(cpi, m, bc, tok, tok_end, mb_row, mb_col,
BLOCK_SIZE_SB64X64);
}
}
/* This function is used for debugging probability trees. */
static void print_prob_tree(vp9_coeff_probs *coef_probs, int block_types) {
/* print coef probability tree */
......@@ -2468,11 +2508,6 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
}
}
pc->prob_sb64_coded = get_binary_prob(cpi->sb64_count[0], cpi->sb64_count[1]);
vp9_write_prob(&header_bc, pc->prob_sb64_coded);
pc->prob_sb32_coded = get_binary_prob(cpi->sb32_count[0], cpi->sb32_count[1]);
vp9_write_prob(&header_bc, pc->prob_sb32_coded);
vp9_write_bit(&header_bc, cpi->mb.e_mbd.lossless);
if (cpi->mb.e_mbd.lossless) {
pc->txfm_mode = ONLY_4X4;
......@@ -2791,13 +2826,14 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
vp9_copy(cpi->common.fc.pre_sub_mv_ref_prob, cpi->common.fc.sub_mv_ref_prob);
vp9_copy(cpi->common.fc.pre_mbsplit_prob, cpi->common.fc.mbsplit_prob);
vp9_copy(cpi->common.fc.pre_i8x8_mode_prob, cpi->common.fc.i8x8_mode_prob);
vp9_copy(cpi->common.fc.pre_partition_prob, cpi->common.fc.partition_prob);
cpi->common.fc.pre_nmvc = cpi->common.fc.nmvc;
#if CONFIG_COMP_INTERINTRA_PRED
cpi->common.fc.pre_interintra_prob = cpi->common.fc.interintra_prob;
#endif
vp9_zero(cpi->sub_mv_ref_count);
vp9_zero(cpi->mbsplit_count);
vp9_zero(cpi->common.fc.mv_ref_ct)
vp9_zero(cpi->common.fc.mv_ref_ct);
update_coef_probs(cpi, &header_bc);
#if CONFIG_CODE_NONZEROCOUNT
......@@ -2863,6 +2899,14 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
}
update_mbintra_mode_probs(cpi, &header_bc);
for (i = 0; i < PARTITION_PLANES; i++) {
vp9_prob Pnew[PARTITION_TYPES - 1];
unsigned int bct[PARTITION_TYPES - 1][2];
update_mode(&header_bc, PARTITION_TYPES, vp9_partition_encodings,
vp9_partition_tree, Pnew, pc->fc.partition_prob[i], bct,
(unsigned int *)cpi->partition_count[i]);
}
vp9_write_nmv_probs(cpi, xd->allow_high_precision_mv, &header_bc);
}
......
......@@ -857,17 +857,18 @@ static void encode_sb(VP9_COMP *cpi,
VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->mb;
MACROBLOCKD *const xd = &x->e_mbd;
BLOCK_SIZE_TYPE bsize = BLOCK_SIZE_SB32X32;
cpi->sb32_count[is_sb]++;
if (is_sb) {
set_offsets(cpi, mb_row, mb_col, BLOCK_SIZE_SB32X32);
set_offsets(cpi, mb_row, mb_col, bsize);
update_state(cpi, &x->sb32_context[xd->sb_index],
BLOCK_SIZE_SB32X32, output_enabled);
bsize, output_enabled);
encode_superblock(cpi, tp,
output_enabled, mb_row, mb_col, BLOCK_SIZE_SB32X32);
output_enabled, mb_row, mb_col, bsize);
if (output_enabled) {
update_stats(cpi, mb_row, mb_col);
cpi->partition_count[partition_plane(bsize)][PARTITION_NONE]++;
}
if (output_enabled) {
......@@ -876,6 +877,8 @@ static void encode_sb(VP9_COMP *cpi,
}
} else {
int i;
if (output_enabled)
cpi->partition_count[partition_plane(bsize)][PARTITION_SPLIT]++;
for (i = 0; i < 4; i++) {
const int x_idx = i & 1, y_idx = i >> 1;
......@@ -924,20 +927,21 @@ static void encode_sb64(VP9_COMP *cpi,
VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->mb;
MACROBLOCKD *const xd = &x->e_mbd;
BLOCK_SIZE_TYPE bsize = BLOCK_SIZE_SB64X64;
cpi->sb64_count[is_sb[0] == 2]++;
if (is_sb[0] == 2) {
set_offsets(cpi, mb_row, mb_col, BLOCK_SIZE_SB64X64);
update_state(cpi, &x->sb64_context, BLOCK_SIZE_SB64X64, 1);
set_offsets(cpi, mb_row, mb_col, bsize);
update_state(cpi, &x->sb64_context, bsize, 1);
encode_superblock(cpi, tp,
1, mb_row, mb_col, BLOCK_SIZE_SB64X64);
1, mb_row, mb_col, bsize);
update_stats(cpi, mb_row, mb_col);
(*tp)->Token = EOSB_TOKEN;
(*tp)++;
cpi->partition_count[partition_plane(bsize)][PARTITION_NONE]++;
} else {
int i;
cpi->partition_count[partition_plane(bsize)][PARTITION_SPLIT]++;
for (i = 0; i < 4; i++) {
const int x_idx = i & 1, y_idx = i >> 1;
......@@ -1024,7 +1028,9 @@ static void encode_sb_row(VP9_COMP *cpi,
vpx_memcpy(cm->left_context + y_idx, l2, sizeof(l2));
vpx_memcpy(cm->above_context + mb_col + x_idx, a2, sizeof(a2));
mb_rate += vp9_cost_bit(cm->prob_sb32_coded, 0);
// TODO(jingning): pre-calculate the overhead costs
mb_rate += vp9_cost_bit(cm->fc.partition_prob
[partition_plane(BLOCK_SIZE_SB32X32)][0], 0);
if (cpi->sf.splitmode_breakout) {
sb32_skip = splitmodes_used;
......@@ -1037,7 +1043,8 @@ static void encode_sb_row(VP9_COMP *cpi,
pick_sb_modes(cpi, mb_row + y_idx, mb_col + x_idx,
tp, &sb_rate, &sb_dist, BLOCK_SIZE_SB32X32,
&x->sb32_context[xd->sb_index]);
sb_rate += vp9_cost_bit(cm->prob_sb32_coded, 1);
sb_rate += vp9_cost_bit(cm->fc.partition_prob
[partition_plane(BLOCK_SIZE_SB32X32)][0], 1);
}
/* Decide whether to encode as a SB or 4xMBs */
......@@ -1069,13 +1076,15 @@ static void encode_sb_row(VP9_COMP *cpi,
memcpy(cm->above_context + mb_col, &a, sizeof(a));
memcpy(cm->left_context, &l, sizeof(l));
sb32_rate += vp9_cost_bit(cm->prob_sb64_coded, 0);
sb32_rate += vp9_cost_bit(cm->fc.partition_prob
[partition_plane(BLOCK_SIZE_SB64X64)][0], 0);