Handle partition type coding of boundary blocks
The partition types of blocks sitting on the frame boundary are constrained by the block size and the position of each sub-block relative to the frame. Hence we use truncated probability models to handle the coding of such information. 100 frames run: yt 0.138% Change-Id: I85d9b45665c15280069c0234ea6f778af586d87d
This commit is contained in:
@@ -34,7 +34,7 @@ class BordersTest : public ::libvpx_test::EncoderTest,
|
|||||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||||
::libvpx_test::Encoder *encoder) {
|
::libvpx_test::Encoder *encoder) {
|
||||||
if ( video->frame() == 1) {
|
if ( video->frame() == 1) {
|
||||||
encoder->Control(VP8E_SET_CPUUSED, 5);
|
encoder->Control(VP8E_SET_CPUUSED, 0);
|
||||||
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
|
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
|
||||||
encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
|
encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
|
||||||
encoder->Control(VP8E_SET_ARNR_STRENGTH, 5);
|
encoder->Control(VP8E_SET_ARNR_STRENGTH, 5);
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ static void set_mb_mi(VP9_COMMON *cm, int aligned_width, int aligned_height) {
|
|||||||
|
|
||||||
cm->mi_cols = aligned_width >> LOG2_MI_SIZE;
|
cm->mi_cols = aligned_width >> LOG2_MI_SIZE;
|
||||||
cm->mi_rows = aligned_height >> LOG2_MI_SIZE;
|
cm->mi_rows = aligned_height >> LOG2_MI_SIZE;
|
||||||
cm->mode_info_stride = cm->mi_cols + 1;
|
cm->mode_info_stride = cm->mi_cols + 64 / MI_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setup_mi(VP9_COMMON *cm) {
|
static void setup_mi(VP9_COMMON *cm) {
|
||||||
@@ -131,12 +131,13 @@ int vp9_alloc_frame_buffers(VP9_COMMON *oci, int width, int height) {
|
|||||||
set_mb_mi(oci, aligned_width, aligned_height);
|
set_mb_mi(oci, aligned_width, aligned_height);
|
||||||
|
|
||||||
// Allocation
|
// Allocation
|
||||||
oci->mip = vpx_calloc(oci->mode_info_stride * (oci->mi_rows + 1),
|
oci->mip = vpx_calloc(oci->mode_info_stride * (oci->mi_rows + 64 / MI_SIZE),
|
||||||
sizeof(MODE_INFO));
|
sizeof(MODE_INFO));
|
||||||
if (!oci->mip)
|
if (!oci->mip)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
oci->prev_mip = vpx_calloc(oci->mode_info_stride * (oci->mi_rows + 1),
|
oci->prev_mip = vpx_calloc(oci->mode_info_stride *
|
||||||
|
(oci->mi_rows + 64 / MI_SIZE),
|
||||||
sizeof(MODE_INFO));
|
sizeof(MODE_INFO));
|
||||||
if (!oci->prev_mip)
|
if (!oci->prev_mip)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|||||||
@@ -301,6 +301,30 @@ static INLINE void set_partition_seg_context(VP9_COMMON *cm,
|
|||||||
xd->left_seg_context = cm->left_seg_context + (mi_row & MI_MASK);
|
xd->left_seg_context = cm->left_seg_context + (mi_row & MI_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int check_bsize_coverage(VP9_COMMON *cm, MACROBLOCKD *xd,
|
||||||
|
int mi_row, int mi_col,
|
||||||
|
BLOCK_SIZE_TYPE bsize) {
|
||||||
|
int bsl = mi_width_log2(bsize), bs = 1 << bsl;
|
||||||
|
int ms = bs / 2;
|
||||||
|
|
||||||
|
if ((mi_row + bs <= cm->mi_rows) && (mi_col + ms < cm->mi_cols))
|
||||||
|
return 0;
|
||||||
|
if ((mi_col + bs <= cm->mi_cols) && (mi_row + ms < cm->mi_rows))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// frame width/height are multiples of 8, hence 8x8 block should always
|
||||||
|
// pass the above check
|
||||||
|
assert(bsize > BLOCK_SIZE_SB8X8);
|
||||||
|
|
||||||
|
// return the node index in the prob tree for binary coding
|
||||||
|
if ((mi_col + bs <= cm->mi_cols) && (mi_row + ms >= cm->mi_rows))
|
||||||
|
return 1;
|
||||||
|
if ((mi_row + bs <= cm->mi_rows) && (mi_col + ms >= cm->mi_cols))
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
static void set_mi_row_col(VP9_COMMON *cm, MACROBLOCKD *xd,
|
static void set_mi_row_col(VP9_COMMON *cm, MACROBLOCKD *xd,
|
||||||
int mi_row, int bh,
|
int mi_row, int bh,
|
||||||
int mi_col, int bw) {
|
int mi_col, int bw) {
|
||||||
|
|||||||
@@ -469,12 +469,21 @@ static void decode_modes_sb(VP9D_COMP *pbi, int mi_row, int mi_col,
|
|||||||
|
|
||||||
if (bsize >= BLOCK_SIZE_SB8X8) {
|
if (bsize >= BLOCK_SIZE_SB8X8) {
|
||||||
int pl;
|
int pl;
|
||||||
|
int idx = check_bsize_coverage(pc, xd, mi_row, mi_col, bsize);
|
||||||
// read the partition information
|
// read the partition information
|
||||||
xd->left_seg_context = pc->left_seg_context + (mi_row & MI_MASK);
|
xd->left_seg_context = pc->left_seg_context + (mi_row & MI_MASK);
|
||||||
xd->above_seg_context = pc->above_seg_context + mi_col;
|
xd->above_seg_context = pc->above_seg_context + mi_col;
|
||||||
pl = partition_plane_context(xd, bsize);
|
pl = partition_plane_context(xd, bsize);
|
||||||
|
|
||||||
|
if (idx == 0)
|
||||||
partition = treed_read(r, vp9_partition_tree,
|
partition = treed_read(r, vp9_partition_tree,
|
||||||
pc->fc.partition_prob[pc->frame_type][pl]);
|
pc->fc.partition_prob[pc->frame_type][pl]);
|
||||||
|
else if (idx > 0 &&
|
||||||
|
!vp9_read(r, pc->fc.partition_prob[pc->frame_type][pl][idx]))
|
||||||
|
partition = (idx == 1) ? PARTITION_HORZ : PARTITION_VERT;
|
||||||
|
else
|
||||||
|
partition = PARTITION_SPLIT;
|
||||||
|
|
||||||
pc->fc.partition_counts[pl][partition]++;
|
pc->fc.partition_counts[pl][partition]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -803,13 +803,18 @@ static void write_modes_sb(VP9_COMP *cpi, MODE_INFO *m, vp9_writer *bc,
|
|||||||
|
|
||||||
if (bsize >= BLOCK_SIZE_SB8X8) {
|
if (bsize >= BLOCK_SIZE_SB8X8) {
|
||||||
int pl;
|
int pl;
|
||||||
|
int idx = check_bsize_coverage(cm, xd, mi_row, mi_col, bsize);
|
||||||
xd->left_seg_context = cm->left_seg_context + (mi_row & MI_MASK);
|
xd->left_seg_context = cm->left_seg_context + (mi_row & MI_MASK);
|
||||||
xd->above_seg_context = cm->above_seg_context + mi_col;
|
xd->above_seg_context = cm->above_seg_context + mi_col;
|
||||||
pl = partition_plane_context(xd, bsize);
|
pl = partition_plane_context(xd, bsize);
|
||||||
// encode the partition information
|
// encode the partition information
|
||||||
|
if (idx == 0)
|
||||||
write_token(bc, vp9_partition_tree,
|
write_token(bc, vp9_partition_tree,
|
||||||
cm->fc.partition_prob[cm->frame_type][pl],
|
cm->fc.partition_prob[cm->frame_type][pl],
|
||||||
vp9_partition_encodings + partition);
|
vp9_partition_encodings + partition);
|
||||||
|
else if (idx > 0)
|
||||||
|
vp9_write(bc, partition == PARTITION_SPLIT,
|
||||||
|
cm->fc.partition_prob[cm->frame_type][pl][idx]);
|
||||||
}
|
}
|
||||||
|
|
||||||
subsize = get_subsize(bsize, partition);
|
subsize = get_subsize(bsize, partition);
|
||||||
|
|||||||
@@ -1286,8 +1286,7 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PARTITION_HORZ
|
// PARTITION_HORZ
|
||||||
if ((mi_col + ms <= cm->mi_cols) && (mi_row + (ms >> 1) <= cm->mi_rows) &&
|
if ((bsize >= BLOCK_SIZE_SB8X8) && (mi_col + ms <= cm->mi_cols)) {
|
||||||
(bsize >= BLOCK_SIZE_SB8X8)) {
|
|
||||||
int r2, d2;
|
int r2, d2;
|
||||||
int mb_skip = 0;
|
int mb_skip = 0;
|
||||||
subsize = get_subsize(bsize, PARTITION_HORZ);
|
subsize = get_subsize(bsize, PARTITION_HORZ);
|
||||||
@@ -1295,7 +1294,7 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp,
|
|||||||
pick_sb_modes(cpi, mi_row, mi_col, tp, &r2, &d2, subsize,
|
pick_sb_modes(cpi, mi_row, mi_col, tp, &r2, &d2, subsize,
|
||||||
get_block_context(x, subsize));
|
get_block_context(x, subsize));
|
||||||
|
|
||||||
if (mi_row + ms <= cm->mi_rows) {
|
if (mi_row < cm->mi_rows) {
|
||||||
int r = 0, d = 0;
|
int r = 0, d = 0;
|
||||||
update_state(cpi, get_block_context(x, subsize), subsize, 0);
|
update_state(cpi, get_block_context(x, subsize), subsize, 0);
|
||||||
encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
|
encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
|
||||||
@@ -1322,15 +1321,14 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PARTITION_VERT
|
// PARTITION_VERT
|
||||||
if ((mi_row + ms <= cm->mi_rows) && (mi_col + (ms >> 1) <= cm->mi_cols) &&
|
if ((bsize >= BLOCK_SIZE_SB8X8) && (mi_row + ms <= cm->mi_rows)) {
|
||||||
(bsize >= BLOCK_SIZE_SB8X8)) {
|
|
||||||
int r2, d2;
|
int r2, d2;
|
||||||
int mb_skip = 0;
|
int mb_skip = 0;
|
||||||
subsize = get_subsize(bsize, PARTITION_VERT);
|
subsize = get_subsize(bsize, PARTITION_VERT);
|
||||||
*(get_sb_index(xd, subsize)) = 0;
|
*(get_sb_index(xd, subsize)) = 0;
|
||||||
pick_sb_modes(cpi, mi_row, mi_col, tp, &r2, &d2, subsize,
|
pick_sb_modes(cpi, mi_row, mi_col, tp, &r2, &d2, subsize,
|
||||||
get_block_context(x, subsize));
|
get_block_context(x, subsize));
|
||||||
if (mi_col + ms <= cm->mi_cols) {
|
if (mi_col < cm->mi_cols) {
|
||||||
int r = 0, d = 0;
|
int r = 0, d = 0;
|
||||||
update_state(cpi, get_block_context(x, subsize), subsize, 0);
|
update_state(cpi, get_block_context(x, subsize), subsize, 0);
|
||||||
encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
|
encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
|
||||||
@@ -1404,7 +1402,7 @@ static void encode_sb_row(VP9_COMP *cpi, int mi_row,
|
|||||||
|
|
||||||
// Code each SB in the row
|
// Code each SB in the row
|
||||||
for (mi_col = cm->cur_tile_mi_col_start;
|
for (mi_col = cm->cur_tile_mi_col_start;
|
||||||
mi_col < cm->cur_tile_mi_col_end; mi_col += 8) {
|
mi_col < cm->cur_tile_mi_col_end; mi_col += 64 / MI_SIZE) {
|
||||||
int dummy_rate, dummy_dist;
|
int dummy_rate, dummy_dist;
|
||||||
if (cpi->speed < 5) {
|
if (cpi->speed < 5) {
|
||||||
rd_pick_partition(cpi, tp, mi_row, mi_col, BLOCK_SIZE_SB64X64,
|
rd_pick_partition(cpi, tp, mi_row, mi_col, BLOCK_SIZE_SB64X64,
|
||||||
|
|||||||
@@ -815,7 +815,7 @@ static int alloc_partition_data(VP9_COMP *cpi) {
|
|||||||
vpx_free(cpi->mb.pip);
|
vpx_free(cpi->mb.pip);
|
||||||
|
|
||||||
cpi->mb.pip = vpx_calloc((cpi->common.mode_info_stride) *
|
cpi->mb.pip = vpx_calloc((cpi->common.mode_info_stride) *
|
||||||
(cpi->common.mi_rows + 1),
|
(cpi->common.mi_rows + 64 / MI_SIZE),
|
||||||
sizeof(PARTITION_INFO));
|
sizeof(PARTITION_INFO));
|
||||||
if (!cpi->mb.pip)
|
if (!cpi->mb.pip)
|
||||||
return 1;
|
return 1;
|
||||||
@@ -3385,11 +3385,11 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
|
|||||||
|
|
||||||
if (cm->show_frame) {
|
if (cm->show_frame) {
|
||||||
vpx_memcpy(cm->prev_mip, cm->mip,
|
vpx_memcpy(cm->prev_mip, cm->mip,
|
||||||
cm->mode_info_stride * (cm->mi_rows + 1) *
|
cm->mode_info_stride * (cm->mi_rows + 64 / MI_SIZE) *
|
||||||
sizeof(MODE_INFO));
|
sizeof(MODE_INFO));
|
||||||
} else {
|
} else {
|
||||||
vpx_memset(cm->prev_mip, 0,
|
vpx_memset(cm->prev_mip, 0,
|
||||||
cm->mode_info_stride * (cm->mi_rows + 1) *
|
cm->mode_info_stride * (cm->mi_rows + 64 / MI_SIZE) *
|
||||||
sizeof(MODE_INFO));
|
sizeof(MODE_INFO));
|
||||||
}
|
}
|
||||||
// restore prev_mi
|
// restore prev_mi
|
||||||
|
|||||||
Reference in New Issue
Block a user