Commit 9ab6d71f authored by Yue Chen's avatar Yue Chen

Separate mbmi coding and coeff coding+recon at sb level in NCOBMC

In order to use mvs from a future block in obmc, we first send mbmi
info for the entire superblock, and then call another recursion to
handle the coeffs and recon.

Note: this change is currently not compatible with SUPERTX, later I
will move detoken and recon for supertx to a proper place

Change-Id: I19ab77fa137f53a370e68ea777f70d0306e3e303
parent de0c70a2
......@@ -1617,7 +1617,18 @@ static void decode_token_and_recon_block(AV1Decoder *const pbi,
tx_size);
}
} else {
// Prediction
int ref;
for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
RefBuffer *ref_buf = &cm->frame_refs[frame - LAST_FRAME];
xd->block_refs[ref] = ref_buf;
if ((!av1_is_valid_scale(&ref_buf->sf)))
aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM,
"Reference frame has invalid dimensions");
av1_setup_pre_planes(xd, ref, ref_buf->buf, mi_row, mi_col, &ref_buf->sf);
}
#if CONFIG_WARPED_MOTION
if (mbmi->motion_mode == WARPED_CAUSAL) {
int i;
......@@ -1700,6 +1711,87 @@ static void decode_token_and_recon_block(AV1Decoder *const pbi,
xd->corrupted |= aom_reader_has_error(r);
}
#if CONFIG_NCOBMC && CONFIG_MOTION_VAR
static void detoken_and_recon_sb(AV1Decoder *const pbi, MACROBLOCKD *const xd,
int mi_row, int mi_col, aom_reader *r,
BLOCK_SIZE bsize) {
AV1_COMMON *const cm = &pbi->common;
const int hbs = mi_size_wide[bsize] >> 1;
#if CONFIG_CB4X4
const int unify_bsize = 1;
#else
const int unify_bsize = 0;
#endif
#if CONFIG_EXT_PARTITION_TYPES
BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
#endif
PARTITION_TYPE partition;
BLOCK_SIZE subsize;
const int has_rows = (mi_row + hbs) < cm->mi_rows;
const int has_cols = (mi_col + hbs) < cm->mi_cols;
if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
partition = get_partition(cm, mi_row, mi_col, bsize);
subsize = subsize_lookup[partition][bsize];
if (!hbs && !unify_bsize) {
xd->bmode_blocks_wl = 1 >> !!(partition & PARTITION_VERT);
xd->bmode_blocks_hl = 1 >> !!(partition & PARTITION_HORZ);
decode_token_and_recon_block(pbi, xd, mi_row, mi_col, r, subsize);
} else {
switch (partition) {
case PARTITION_NONE:
decode_token_and_recon_block(pbi, xd, mi_row, mi_col, r, bsize);
break;
case PARTITION_HORZ:
decode_token_and_recon_block(pbi, xd, mi_row, mi_col, r, subsize);
if (has_rows)
decode_token_and_recon_block(pbi, xd, mi_row + hbs, mi_col, r,
subsize);
break;
case PARTITION_VERT:
decode_token_and_recon_block(pbi, xd, mi_row, mi_col, r, subsize);
if (has_cols)
decode_token_and_recon_block(pbi, xd, mi_row, mi_col + hbs, r,
subsize);
break;
case PARTITION_SPLIT:
detoken_and_recon_sb(pbi, xd, mi_row, mi_col, r, subsize);
detoken_and_recon_sb(pbi, xd, mi_row, mi_col + hbs, r, subsize);
detoken_and_recon_sb(pbi, xd, mi_row + hbs, mi_col, r, subsize);
detoken_and_recon_sb(pbi, xd, mi_row + hbs, mi_col + hbs, r, subsize);
break;
#if CONFIG_EXT_PARTITION_TYPES
case PARTITION_HORZ_A:
decode_token_and_recon_block(pbi, xd, mi_row, mi_col, r, bsize2);
decode_token_and_recon_block(pbi, xd, mi_row, mi_col + hbs, r, bsize2);
decode_token_and_recon_block(pbi, xd, mi_row + hbs, mi_col, r, subsize);
break;
case PARTITION_HORZ_B:
decode_token_and_recon_block(pbi, xd, mi_row, mi_col, r, subsize);
decode_token_and_recon_block(pbi, xd, mi_row + hbs, mi_col, r, bsize2);
decode_token_and_recon_block(pbi, xd, mi_row + hbs, mi_col + hbs, r,
bsize2);
break;
case PARTITION_VERT_A:
decode_token_and_recon_block(pbi, xd, mi_row, mi_col, r, bsize2);
decode_token_and_recon_block(pbi, xd, mi_row + hbs, mi_col, r, bsize2);
decode_token_and_recon_block(pbi, xd, mi_row, mi_col + hbs, r, subsize);
break;
case PARTITION_VERT_B:
decode_token_and_recon_block(pbi, xd, mi_row, mi_col, r, subsize);
decode_token_and_recon_block(pbi, xd, mi_row, mi_col + hbs, r, bsize2);
decode_token_and_recon_block(pbi, xd, mi_row + hbs, mi_col + hbs, r,
bsize2);
break;
#endif
default: assert(0 && "Invalid partition type");
}
}
}
#endif
static void decode_block(AV1Decoder *const pbi, MACROBLOCKD *const xd,
#if CONFIG_SUPERTX
int supertx_enabled,
......@@ -1718,10 +1810,12 @@ static void decode_block(AV1Decoder *const pbi, MACROBLOCKD *const xd,
partition,
#endif
bsize);
#if !(CONFIG_MOTION_VAR && CONFIG_NCOBMC)
#if CONFIG_SUPERTX
if (!supertx_enabled)
#endif // CONFIG_SUPERTX
decode_token_and_recon_block(pbi, xd, mi_row, mi_col, r, bsize);
#endif
}
static PARTITION_TYPE read_partition(AV1_COMMON *cm, MACROBLOCKD *xd,
......@@ -3334,6 +3428,10 @@ static const uint8_t *decode_tiles(AV1Decoder *pbi, const uint8_t *data,
#endif // CONFIG_SUPERTX
mi_row, mi_col, &td->bit_reader, cm->sb_size,
b_width_log2_lookup[cm->sb_size]);
#if CONFIG_NCOBMC && CONFIG_MOTION_VAR
detoken_and_recon_sb(pbi, &td->xd, mi_row, mi_col, &td->bit_reader,
cm->sb_size);
#endif
}
pbi->mb.corrupted |= td->xd.corrupted;
if (pbi->mb.corrupted)
......@@ -3474,6 +3572,10 @@ static int tile_worker_hook(TileWorkerData *const tile_data,
#endif
mi_row, mi_col, &tile_data->bit_reader, cm->sb_size,
b_width_log2_lookup[cm->sb_size]);
#if CONFIG_NCOBMC && CONFIG_MOTION_VAR
detoken_and_recon_sb(pbi, &tile_data->xd, mi_row, mi_col,
&tile_data->bit_reader, cm->sb_size);
#endif
}
}
return !tile_data->xd.corrupted;
......
......@@ -1483,13 +1483,7 @@ static void read_inter_block_mode_info(AV1Decoder *const pbi,
for (ref = 0; ref < 1 + is_compound; ++ref) {
MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
RefBuffer *ref_buf = &cm->frame_refs[frame - LAST_FRAME];
xd->block_refs[ref] = ref_buf;
if ((!av1_is_valid_scale(&ref_buf->sf)))
aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM,
"Reference frame has invalid dimensions");
av1_setup_pre_planes(xd, ref, ref_buf->buf, mi_row, mi_col, &ref_buf->sf);
av1_find_mv_refs(cm, xd, mi, frame,
#if CONFIG_REF_MV
&xd->ref_mv_count[frame], xd->ref_mv_stack[frame],
......
......@@ -2177,6 +2177,56 @@ static void write_tokens_b(AV1_COMP *cpi, const TileInfo *const tile,
#endif
}
#if CONFIG_MOTION_VAR && CONFIG_NCOBMC
static void write_tokens_sb(AV1_COMP *cpi, const TileInfo *const tile,
aom_writer *w, const TOKENEXTRA **tok,
const TOKENEXTRA *const tok_end, int mi_row,
int mi_col, BLOCK_SIZE bsize) {
const AV1_COMMON *const cm = &cpi->common;
const int bsl = b_width_log2_lookup[bsize];
const int bs = (1 << bsl) / 4;
PARTITION_TYPE partition;
BLOCK_SIZE subsize;
const MODE_INFO *m = NULL;
if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
m = cm->mi_grid_visible[mi_row * cm->mi_stride + mi_col];
partition = partition_lookup[bsl][m->mbmi.sb_type];
subsize = get_subsize(bsize, partition);
if (subsize < BLOCK_8X8) {
write_tokens_b(cpi, tile, w, tok, tok_end, mi_row, mi_col);
} else {
switch (partition) {
case PARTITION_NONE:
write_tokens_b(cpi, tile, w, tok, tok_end, mi_row, mi_col);
break;
case PARTITION_HORZ:
write_tokens_b(cpi, tile, w, tok, tok_end, mi_row, mi_col);
if (mi_row + bs < cm->mi_rows)
write_tokens_b(cpi, tile, w, tok, tok_end, mi_row + bs, mi_col);
break;
case PARTITION_VERT:
write_tokens_b(cpi, tile, w, tok, tok_end, mi_row, mi_col);
if (mi_col + bs < cm->mi_cols)
write_tokens_b(cpi, tile, w, tok, tok_end, mi_row, mi_col + bs);
break;
case PARTITION_SPLIT:
write_tokens_sb(cpi, tile, w, tok, tok_end, mi_row, mi_col, subsize);
write_tokens_sb(cpi, tile, w, tok, tok_end, mi_row, mi_col + bs,
subsize);
write_tokens_sb(cpi, tile, w, tok, tok_end, mi_row + bs, mi_col,
subsize);
write_tokens_sb(cpi, tile, w, tok, tok_end, mi_row + bs, mi_col + bs,
subsize);
break;
default: assert(0);
}
}
}
#endif
static void write_modes_b(AV1_COMP *cpi, const TileInfo *const tile,
aom_writer *w, const TOKENEXTRA **tok,
const TOKENEXTRA *const tok_end,
......@@ -2189,10 +2239,15 @@ static void write_modes_b(AV1_COMP *cpi, const TileInfo *const tile,
supertx_enabled,
#endif
mi_row, mi_col);
#if CONFIG_MOTION_VAR && CONFIG_NCOBMC
(void)tok;
(void)tok_end;
#else
#if !CONFIG_PVQ && CONFIG_SUPERTX
if (!supertx_enabled)
#endif
write_tokens_b(cpi, tile, w, tok, tok_end, mi_row, mi_col);
#endif
}
static void write_partition(const AV1_COMMON *const cm,
......@@ -2556,6 +2611,9 @@ static void write_modes(AV1_COMP *const cpi, const TileInfo *const tile,
for (mi_col = mi_col_start; mi_col < mi_col_end; mi_col += cm->mib_size) {
write_modes_sb_wrapper(cpi, tile, w, tok, tok_end, 0, mi_row, mi_col,
cm->sb_size);
#if CONFIG_MOTION_VAR && CONFIG_NCOBMC
write_tokens_sb(cpi, tile, w, tok, tok_end, mi_row, mi_col, cm->sb_size);
#endif
}
}
#if CONFIG_PVQ
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment