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
This commit is contained in:
@@ -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);
|
||||
|
||||
if (!sb64_skip && !(mb_col + 3 >= cm->mb_cols ||
|
||||
mb_row + 3 >= cm->mb_rows)) {
|
||||
pick_sb_modes(cpi, mb_row, mb_col, tp, &sb64_rate, &sb64_dist,
|
||||
BLOCK_SIZE_SB64X64, &x->sb64_context);
|
||||
sb64_rate += vp9_cost_bit(cm->prob_sb64_coded, 1);
|
||||
sb64_rate += vp9_cost_bit(cm->fc.partition_prob
|
||||
[partition_plane(BLOCK_SIZE_SB64X64)][0], 1);
|
||||
}
|
||||
|
||||
/* Decide whether to encode as a SB or 4xMBs */
|
||||
@@ -1139,8 +1148,8 @@ static void init_encode_frame_mb_context(VP9_COMP *cpi) {
|
||||
vp9_zero(cpi->mbsplit_count)
|
||||
vp9_zero(cpi->common.fc.mv_ref_ct)
|
||||
vp9_zero(cpi->sb_ymode_count)
|
||||
vp9_zero(cpi->sb32_count);
|
||||
vp9_zero(cpi->sb64_count);
|
||||
vp9_zero(cpi->partition_count);
|
||||
|
||||
#if CONFIG_COMP_INTERINTRA_PRED
|
||||
vp9_zero(cpi->interintra_count);
|
||||
vp9_zero(cpi->interintra_select_count);
|
||||
|
||||
@@ -1380,8 +1380,6 @@ VP9_PTR vp9_create_compressor(VP9_CONFIG *oxcf) {
|
||||
cm->prob_last_coded = 128;
|
||||
cm->prob_gf_coded = 128;
|
||||
cm->prob_intra_coded = 63;
|
||||
cm->prob_sb32_coded = 200;
|
||||
cm->prob_sb64_coded = 200;
|
||||
for (i = 0; i < COMP_PRED_CONTEXTS; i++)
|
||||
cm->prob_comppred[i] = 128;
|
||||
for (i = 0; i < TX_SIZE_MAX_SB - 1; i++)
|
||||
@@ -3351,6 +3349,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
|
||||
vp9_copy(cpi->common.fc.i8x8_mode_counts, cpi->i8x8_mode_count);
|
||||
vp9_copy(cpi->common.fc.sub_mv_ref_counts, cpi->sub_mv_ref_count);
|
||||
vp9_copy(cpi->common.fc.mbsplit_counts, cpi->mbsplit_count);
|
||||
vp9_copy(cpi->common.fc.partition_counts, cpi->partition_count);
|
||||
#if CONFIG_COMP_INTERINTRA_PRED
|
||||
vp9_copy(cpi->common.fc.interintra_counts, cpi->interintra_count);
|
||||
#endif
|
||||
|
||||
@@ -103,6 +103,7 @@ typedef struct {
|
||||
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_prob switchable_interp_prob[VP9_SWITCHABLE_FILTERS + 1]
|
||||
[VP9_SWITCHABLE_FILTERS - 1];
|
||||
@@ -455,8 +456,6 @@ typedef struct VP9_COMP {
|
||||
|
||||
int cq_target_quality;
|
||||
|
||||
int sb32_count[2];
|
||||
int sb64_count[2];
|
||||
int sb_ymode_count [VP9_I32X32_MODES];
|
||||
int ymode_count[VP9_YMODES]; /* intra MB type cts this frame */
|
||||
int bmode_count[VP9_NKF_BINTRAMODES];
|
||||
@@ -464,6 +463,7 @@ typedef struct VP9_COMP {
|
||||
int sub_mv_ref_count[SUBMVREF_COUNT][VP9_SUBMVREFS];
|
||||
int mbsplit_count[VP9_NUMMBSPLITS];
|
||||
int y_uv_mode_count[VP9_YMODES][VP9_UV_MODES];
|
||||
unsigned int partition_count[PARTITION_PLANES][PARTITION_TYPES];
|
||||
#if CONFIG_COMP_INTERINTRA_PRED
|
||||
unsigned int interintra_count[2];
|
||||
unsigned int interintra_select_count[2];
|
||||
|
||||
@@ -141,6 +141,7 @@ void vp9_save_coding_context(VP9_COMP *cpi) {
|
||||
vp9_copy(cc->i8x8_mode_prob, cm->fc.i8x8_mode_prob);
|
||||
vp9_copy(cc->sub_mv_ref_prob, cm->fc.sub_mv_ref_prob);
|
||||
vp9_copy(cc->mbsplit_prob, cm->fc.mbsplit_prob);
|
||||
vp9_copy(cc->partition_prob, cm->fc.partition_prob);
|
||||
|
||||
// Stats
|
||||
#ifdef MODE_STATS
|
||||
@@ -202,6 +203,7 @@ void vp9_restore_coding_context(VP9_COMP *cpi) {
|
||||
vp9_copy(cm->fc.uv_mode_prob, cc->uv_mode_prob);
|
||||
vp9_copy(cm->fc.sub_mv_ref_prob, cc->sub_mv_ref_prob);
|
||||
vp9_copy(cm->fc.mbsplit_prob, cc->mbsplit_prob);
|
||||
vp9_copy(cm->fc.partition_prob, cc->partition_prob);
|
||||
|
||||
// Stats
|
||||
#ifdef MODE_STATS
|
||||
|
||||
Reference in New Issue
Block a user