From 9ab6d71f8d44d414d7428fd2342fa9f8bcf45a53 Mon Sep 17 00:00:00 2001 From: Yue Chen Date: Thu, 12 Jan 2017 15:50:46 -0800 Subject: [PATCH] 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 --- av1/decoder/decodeframe.c | 104 +++++++++++++++++++++++++++++++++++++- av1/decoder/decodemv.c | 6 --- av1/encoder/bitstream.c | 58 +++++++++++++++++++++ 3 files changed, 161 insertions(+), 7 deletions(-) diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c index a7015c16b..60b678e6a 100644 --- a/av1/decoder/decodeframe.c +++ b/av1/decoder/decodeframe.c @@ -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; diff --git a/av1/decoder/decodemv.c b/av1/decoder/decodemv.c index ce2e30ed6..ff8cb005d 100644 --- a/av1/decoder/decodemv.c +++ b/av1/decoder/decodemv.c @@ -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], diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c index fc5b8a3c8..8a0b863b4 100644 --- a/av1/encoder/bitstream.c +++ b/av1/encoder/bitstream.c @@ -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 -- GitLab