Commit 01d4d8f2 authored by Wei-Ting Lin's avatar Wei-Ting Lin Committed by Wei-ting Lin

ncobmc-adapt-weight: applying at the encoder as new motion mode

Change-Id: I1cd1197b48a3315fe4f44578b80634be73de17a3
parent 8396d2c5
......@@ -1651,7 +1651,6 @@ static void decode_mbmi_block(AV1Decoder *const pbi, MACROBLOCKD *const xd,
#endif
av1_read_mode_info(pbi, xd, mi_row, mi_col, r, x_mis, y_mis);
#endif // CONFIG_SUPERTX
if (bsize >= BLOCK_8X8 && (cm->subsampling_x || cm->subsampling_y)) {
const BLOCK_SIZE uv_subsize =
ss_size_lookup[bsize][cm->subsampling_x][cm->subsampling_y];
......@@ -1668,6 +1667,101 @@ static void decode_mbmi_block(AV1Decoder *const pbi, MACROBLOCKD *const xd,
aom_merge_corrupted_flag(&xd->corrupted, reader_corrupted_flag);
}
#if CONFIG_NCOBMC_ADAPT_WEIGHT
static void set_mode_info_offsets(AV1_COMMON *const cm, MACROBLOCKD *const xd,
int mi_row, int mi_col) {
const int offset = mi_row * cm->mi_stride + mi_col;
xd->mi = cm->mi_grid_visible + offset;
xd->mi[0] = &cm->mi[offset];
}
static void get_ncobmc_recon(AV1_COMMON *const cm, MACROBLOCKD *xd, int mi_row,
int mi_col, int bsize, int mode) {
#if CONFIG_HIGHBITDEPTH
DECLARE_ALIGNED(16, uint8_t, tmp_buf_0[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
DECLARE_ALIGNED(16, uint8_t, tmp_buf_1[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
DECLARE_ALIGNED(16, uint8_t, tmp_buf_2[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
DECLARE_ALIGNED(16, uint8_t, tmp_buf_3[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
#else
DECLARE_ALIGNED(16, uint8_t, tmp_buf_0[MAX_MB_PLANE * MAX_SB_SQUARE]);
DECLARE_ALIGNED(16, uint8_t, tmp_buf_1[MAX_MB_PLANE * MAX_SB_SQUARE]);
DECLARE_ALIGNED(16, uint8_t, tmp_buf_2[MAX_MB_PLANE * MAX_SB_SQUARE]);
DECLARE_ALIGNED(16, uint8_t, tmp_buf_3[MAX_MB_PLANE * MAX_SB_SQUARE]);
#endif
uint8_t *pred_buf[4][MAX_MB_PLANE];
int pred_stride[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
// target block in pxl
int pxl_row = mi_row << MI_SIZE_LOG2;
int pxl_col = mi_col << MI_SIZE_LOG2;
int plane;
#if CONFIG_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
int len = sizeof(uint16_t);
ASSIGN_ALIGNED_PTRS_HBD(pred_buf[0], tmp_buf_0, MAX_SB_SQUARE, len);
ASSIGN_ALIGNED_PTRS_HBD(pred_buf[1], tmp_buf_0, MAX_SB_SQUARE, len);
ASSIGN_ALIGNED_PTRS_HBD(pred_buf[2], tmp_buf_0, MAX_SB_SQUARE, len);
ASSIGN_ALIGNED_PTRS_HBD(pred_buf[3], tmp_buf_0, MAX_SB_SQUARE, len);
} else {
#endif // CONFIG_HIGHBITDEPTH
ASSIGN_ALIGNED_PTRS(pred_buf[0], tmp_buf_0, MAX_SB_SQUARE);
ASSIGN_ALIGNED_PTRS(pred_buf[1], tmp_buf_1, MAX_SB_SQUARE);
ASSIGN_ALIGNED_PTRS(pred_buf[2], tmp_buf_2, MAX_SB_SQUARE);
ASSIGN_ALIGNED_PTRS(pred_buf[3], tmp_buf_3, MAX_SB_SQUARE);
#if CONFIG_HIGHBITDEPTH
}
#endif
av1_get_ext_blk_preds(cm, xd, bsize, mi_row, mi_col, pred_buf, pred_stride);
av1_get_ori_blk_pred(cm, xd, bsize, mi_row, mi_col, pred_buf[3], pred_stride);
for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
build_ncobmc_intrpl_pred(cm, xd, plane, pxl_row, pxl_col, bsize, pred_buf,
pred_stride, mode);
}
}
static void av1_get_ncobmc_recon(AV1_COMMON *const cm, MACROBLOCKD *const xd,
int bsize, const int mi_row, const int mi_col,
const NCOBMC_MODE modes) {
const int mi_width = mi_size_wide[bsize];
const int mi_height = mi_size_high[bsize];
assert(bsize >= BLOCK_8X8);
reset_xd_boundary(xd, mi_row, mi_height, mi_col, mi_width, cm->mi_rows,
cm->mi_cols);
get_ncobmc_recon(cm, xd, mi_row, mi_col, bsize, modes);
}
static void recon_ncobmc_intrpl_pred(AV1_COMMON *const cm,
MACROBLOCKD *const xd, int mi_row,
int mi_col, BLOCK_SIZE bsize) {
MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
const int mi_width = mi_size_wide[bsize];
const int mi_height = mi_size_high[bsize];
const int hbs = AOMMAX(mi_size_wide[bsize] / 2, mi_size_high[bsize] / 2);
const BLOCK_SIZE sqr_blk = bsize_2_sqr_bsize[bsize];
if (mi_width > mi_height) {
// horizontal partition
av1_get_ncobmc_recon(cm, xd, sqr_blk, mi_row, mi_col, mbmi->ncobmc_mode[0]);
xd->mi += hbs;
av1_get_ncobmc_recon(cm, xd, sqr_blk, mi_row, mi_col + hbs,
mbmi->ncobmc_mode[1]);
} else if (mi_height > mi_width) {
// vertical partition
av1_get_ncobmc_recon(cm, xd, sqr_blk, mi_row, mi_col, mbmi->ncobmc_mode[0]);
xd->mi += hbs * xd->mi_stride;
av1_get_ncobmc_recon(cm, xd, sqr_blk, mi_row + hbs, mi_col,
mbmi->ncobmc_mode[1]);
} else {
av1_get_ncobmc_recon(cm, xd, sqr_blk, mi_row, mi_col, mbmi->ncobmc_mode[0]);
}
set_mode_info_offsets(cm, xd, mi_row, mi_col);
// restore dst buffer and mode info
av1_setup_dst_planes(xd->plane, bsize, get_frame_new_buffer(cm), mi_row,
mi_col);
}
#endif // CONFIG_NCOBMC_ADAPT_WEIGHT
static void decode_token_and_recon_block(AV1Decoder *const pbi,
MACROBLOCKD *const xd, int mi_row,
int mi_col, aom_reader *r,
......@@ -1933,7 +2027,15 @@ static void decode_token_and_recon_block(AV1Decoder *const pbi,
#endif
}
#endif // CONFIG_MOTION_VAR
#if CONFIG_NCOBMC_ADAPT_WEIGHT
if (mbmi->motion_mode == NCOBMC_ADAPT_WEIGHT) {
int plane;
recon_ncobmc_intrpl_pred(cm, xd, mi_row, mi_col, bsize);
for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
get_pred_from_intrpl_buf(xd, mi_row, mi_col, bsize, plane);
}
}
#endif
// Reconstruction
if (!mbmi->skip) {
int eobtotal = 0;
......@@ -3728,6 +3830,10 @@ static const uint8_t *decode_tiles(AV1Decoder *pbi, const uint8_t *data,
for (mi_col = tile_info.mi_col_start; mi_col < tile_info.mi_col_end;
mi_col += cm->mib_size) {
#if CONFIG_NCOBMC_ADAPT_WEIGHT
alloc_ncobmc_pred_buffer(&td->xd);
set_sb_mi_boundaries(cm, &td->xd, mi_row, mi_col);
#endif
decode_partition(pbi, &td->xd,
#if CONFIG_SUPERTX
0,
......@@ -3736,6 +3842,9 @@ static const uint8_t *decode_tiles(AV1Decoder *pbi, const uint8_t *data,
#if (CONFIG_NCOBMC || CONFIG_NCOBMC_ADAPT_WEIGHT) && CONFIG_MOTION_VAR
detoken_and_recon_sb(pbi, &td->xd, mi_row, mi_col, &td->bit_reader,
cm->sb_size);
#endif
#if CONFIG_NCOBMC_ADAPT_WEIGHT
free_ncobmc_pred_buffer(&td->xd);
#endif
}
aom_merge_corrupted_flag(&pbi->mb.corrupted, td->xd.corrupted);
......
......@@ -33,7 +33,9 @@
#include "av1/decoder/decodeframe.h"
#include "av1/decoder/decoder.h"
#if CONFIG_NCOBMC_ADAPT_WEIGHT
#include "av1/common/ncobmc_kernels.h"
#endif // CONFIG_NCOBMC_ADAPT_WEIGHT
#if !CONFIG_PVQ
#include "av1/decoder/detokenize.h"
#endif
......@@ -133,6 +135,10 @@ AV1Decoder *av1_decoder_create(BufferPool *const pool) {
av1_loop_filter_init(cm);
#if CONFIG_NCOBMC_ADAPT_WEIGHT
get_default_ncobmc_kernels(cm);
#endif // CONFIG_NCOBMC_ADAPT_WEIGHT
#if CONFIG_AOM_QM
aom_qm_init(cm);
#endif
......
......@@ -1286,7 +1286,60 @@ static void set_mode_info_sb(const AV1_COMP *const cpi, ThreadData *td,
default: assert(0 && "Invalid partition type."); break;
}
}
#endif
#if CONFIG_NCOBMC_ADAPT_WEIGHT
static void av1_get_ncobmc_mode_rd(const AV1_COMP *const cpi,
MACROBLOCK *const x, MACROBLOCKD *const xd,
int bsize, const int mi_row,
const int mi_col, NCOBMC_MODE *mode) {
const AV1_COMMON *const cm = &cpi->common;
const int mi_width = mi_size_wide[bsize];
const int mi_height = mi_size_high[bsize];
assert(bsize >= BLOCK_8X8);
reset_xd_boundary(xd, mi_row, mi_height, mi_col, mi_width, cm->mi_rows,
cm->mi_cols);
// set up source buffers before calling the mode searching function
av1_setup_src_planes(x, cpi->source, mi_row, mi_col);
*mode = get_ncobmc_mode(cpi, x, xd, mi_row, mi_col, bsize);
}
static void get_ncobmc_intrpl_pred(const AV1_COMP *const cpi, ThreadData *td,
int mi_row, int mi_col, BLOCK_SIZE bsize) {
MACROBLOCK *const x = &td->mb;
MACROBLOCKD *const xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
const int mi_width = mi_size_wide[bsize];
const int mi_height = mi_size_high[bsize];
const int hbs = AOMMAX(mi_size_wide[bsize] / 2, mi_size_high[bsize] / 2);
const BLOCK_SIZE sqr_blk = bsize_2_sqr_bsize[bsize];
if (mi_width > mi_height) {
// horizontal partition
av1_get_ncobmc_mode_rd(cpi, x, xd, sqr_blk, mi_row, mi_col,
&mbmi->ncobmc_mode[0]);
xd->mi += hbs;
av1_get_ncobmc_mode_rd(cpi, x, xd, sqr_blk, mi_row, mi_col + hbs,
&mbmi->ncobmc_mode[1]);
} else if (mi_height > mi_width) {
// vertical partition
av1_get_ncobmc_mode_rd(cpi, x, xd, sqr_blk, mi_row, mi_col,
&mbmi->ncobmc_mode[0]);
xd->mi += hbs * xd->mi_stride;
av1_get_ncobmc_mode_rd(cpi, x, xd, sqr_blk, mi_row + hbs, mi_col,
&mbmi->ncobmc_mode[1]);
} else {
av1_get_ncobmc_mode_rd(cpi, x, xd, sqr_blk, mi_row, mi_col,
&mbmi->ncobmc_mode[0]);
}
// restore the info
av1_setup_src_planes(x, cpi->source, mi_row, mi_col);
set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
}
#endif // CONFIG_NCOBMC_ADAPT_WEIGHT
#endif // CONFIG_MOTION_VAR && (CONFIG_NCOBMC || CONFIG_NCOBMC_ADAPT_WEIGHT)
void av1_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
int mi_row, int mi_col) {
......@@ -2006,7 +2059,8 @@ static void encode_b(const AV1_COMP *const cpi, const TileInfo *const tile,
#endif
PICK_MODE_CONTEXT *ctx, int *rate) {
MACROBLOCK *const x = &td->mb;
#if (CONFIG_MOTION_VAR && CONFIG_NCOBMC) | CONFIG_EXT_DELTA_Q
#if (CONFIG_MOTION_VAR && CONFIG_NCOBMC) | CONFIG_EXT_DELTA_Q | \
CONFIG_NCOBMC_ADAPT_WEIGHT
MACROBLOCKD *xd = &x->e_mbd;
MB_MODE_INFO *mbmi;
#if CONFIG_MOTION_VAR && CONFIG_NCOBMC
......@@ -2019,11 +2073,15 @@ static void encode_b(const AV1_COMP *const cpi, const TileInfo *const tile,
x->e_mbd.mi[0]->mbmi.partition = partition;
#endif
update_state(cpi, td, ctx, mi_row, mi_col, bsize, dry_run);
#if CONFIG_MOTION_VAR && CONFIG_NCOBMC
#if CONFIG_MOTION_VAR && (CONFIG_NCOBMC || CONFIG_NCOBMC_ADAPT_WEIGHT)
mbmi = &xd->mi[0]->mbmi;
#if CONFIG_WARPED_MOTION
set_ref_ptrs(&cpi->common, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
#endif
#endif
#if CONFIG_MOTION_VAR && (CONFIG_NCOBMC || CONFIG_NCOBMC_ADAPT_WEIGHT)
#if CONFIG_NCOBMC
const MOTION_MODE motion_allowed = motion_mode_allowed(
#if CONFIG_GLOBAL_MOTION
0, xd->global_motion,
......@@ -2032,6 +2090,20 @@ static void encode_b(const AV1_COMP *const cpi, const TileInfo *const tile,
xd,
#endif
xd->mi[0]);
#elif CONFIG_NCOBMC_ADAPT_WEIGHT
const MOTION_MODE motion_allowed =
motion_mode_allowed_wrapper(0,
#if CONFIG_GLOBAL_MOTION
0, xd->global_motion,
#endif // CONFIG_GLOBAL_MOTION
#if CONFIG_WARPED_MOTION
xd,
#endif
xd->mi[0]);
#endif
#endif // CONFIG_MOTION_VAR && (CONFIG_NCOBMC || CONFIG_NCOBMC_ADAPT_WEIGHT)
#if CONFIG_MOTION_VAR && CONFIG_NCOBMC
check_ncobmc = is_inter_block(mbmi) && motion_allowed >= OBMC_CAUSAL;
if (!dry_run && check_ncobmc) {
av1_check_ncobmc_rd(cpi, x, mi_row, mi_col);
......@@ -2043,6 +2115,16 @@ static void encode_b(const AV1_COMP *const cpi, const TileInfo *const tile,
#if CONFIG_LV_MAP
av1_set_coeff_buffer(cpi, x, mi_row, mi_col);
#endif
#if CONFIG_NCOBMC_ADAPT_WEIGHT
if (dry_run == OUTPUT_ENABLED && motion_allowed == NCOBMC_ADAPT_WEIGHT) {
get_ncobmc_intrpl_pred(cpi, td, mi_row, mi_col, bsize);
av1_check_ncobmc_adapt_weight_rd(cpi, x, mi_row, mi_col);
av1_setup_dst_planes(x->e_mbd.plane, bsize,
get_frame_new_buffer(&cpi->common), mi_row, mi_col);
}
#endif // CONFIG_NCOBMC_ADAPT_WEIGHT
encode_superblock(cpi, td, tp, dry_run, mi_row, mi_col, bsize, rate);
#if CONFIG_LV_MAP
......@@ -4418,12 +4500,17 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
if (best_rdc.rate < INT_MAX && best_rdc.dist < INT64_MAX &&
pc_tree->index != 3) {
if (bsize == cm->sb_size) {
#if CONFIG_MOTION_VAR && CONFIG_NCOBMC
#if CONFIG_MOTION_VAR && (CONFIG_NCOBMC || CONFIG_NCOBMC_ADAPT_WEIGHT)
set_mode_info_sb(cpi, td, tile_info, tp, mi_row, mi_col, bsize, pc_tree);
#endif
#if CONFIG_LV_MAP
x->cb_offset = 0;
#endif
#if CONFIG_NCOBMC_ADAPT_WEIGHT
set_sb_mi_boundaries(cm, xd, mi_row, mi_col);
#endif
encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, OUTPUT_ENABLED, bsize,
pc_tree, NULL);
} else {
......@@ -5110,6 +5197,10 @@ static void encode_frame_internal(AV1_COMP *cpi) {
cpi->source->y_height);
}
#if CONFIG_NCOBMC_ADAPT_WEIGHT
alloc_ncobmc_pred_buffer(xd);
#endif
#if CONFIG_GLOBAL_MOTION
av1_zero(rdc->global_motion_used);
av1_zero(cpi->gmparams_cost);
......@@ -5360,6 +5451,9 @@ static void encode_frame_internal(AV1_COMP *cpi) {
aom_usec_timer_mark(&emr_timer);
cpi->time_encode_sb_row += aom_usec_timer_elapsed(&emr_timer);
}
#if CONFIG_NCOBMC_ADAPT_WEIGHT
free_ncobmc_pred_buffer(xd);
#endif
#if 0
// Keep record of the total distortion this time around for future use
......@@ -6080,6 +6174,8 @@ static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, block_size);
#if !CONFIG_NCOBMC_ADAPT_WEIGHT
#if CONFIG_MOTION_VAR
if (mbmi->motion_mode == OBMC_CAUSAL) {
#if CONFIG_NCOBMC
......@@ -6090,6 +6186,17 @@ static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
}
#endif // CONFIG_MOTION_VAR
#else
if (mbmi->motion_mode == OBMC_CAUSAL) {
av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
} else if (mbmi->motion_mode == NCOBMC_ADAPT_WEIGHT &&
dry_run == OUTPUT_ENABLED) {
int p;
for (p = 0; p < MAX_MB_PLANE; ++p) {
get_pred_from_intrpl_buf(xd, mi_row, mi_col, block_size, p);
}
}
#endif
av1_encode_sb((AV1_COMMON *)cm, x, block_size, mi_row, mi_col);
#if CONFIG_VAR_TX
......
......@@ -49,6 +49,9 @@
#include "av1/encoder/hash_motion.h"
#endif
#include "av1/encoder/mbgraph.h"
#if CONFIG_NCOBMC_ADAPT_WEIGHT
#include "av1/common/ncobmc_kernels.h"
#endif // CONFIG_NCOBMC_ADAPT_WEIGHT
#include "av1/encoder/picklpf.h"
#if CONFIG_LOOP_RESTORATION
#include "av1/encoder/pickrst.h"
......@@ -93,6 +96,7 @@ FRAME_COUNTS aggregate_fc_per_type[FRAME_CONTEXTS];
// mv. Choose a very high value for
// now so that HIGH_PRECISION is always
// chosen.
// #define OUTPUT_YUV_REC
#ifdef OUTPUT_YUV_DENOISED
FILE *yuv_denoised_file = NULL;
......@@ -2401,6 +2405,10 @@ AV1_COMP *av1_create_compressor(AV1EncoderConfig *oxcf,
cm->free_mi = av1_enc_free_mi;
cm->setup_mi = av1_enc_setup_mi;
#if CONFIG_NCOBMC_ADAPT_WEIGHT
get_default_ncobmc_kernels(cm);
#endif // CONFIG_NCOBMC_ADAPT_WEIGHT
CHECK_MEM_ERROR(cm, cm->fc,
(FRAME_CONTEXT *)aom_memalign(32, sizeof(*cm->fc)));
CHECK_MEM_ERROR(cm, cm->frame_contexts,
......@@ -2984,7 +2992,6 @@ void av1_remove_compressor(AV1_COMP *cpi) {
#ifdef OUTPUT_YUV_REC
fclose(yuv_rec_file);
#endif
#if 0
if (keyfile)
......@@ -3130,7 +3137,7 @@ static void check_show_existing_frame(AV1_COMP *cpi) {
void aom_write_one_yuv_frame(AV1_COMMON *cm, YV12_BUFFER_CONFIG *s) {
uint8_t *src = s->y_buffer;
int h = cm->height;
if (yuv_rec_file == NULL) return;
#if CONFIG_HIGHBITDEPTH
if (s->flags & YV12_FLAG_HIGHBITDEPTH) {
uint16_t *src16 = CONVERT_TO_SHORTPTR(s->y_buffer);
......@@ -4989,6 +4996,10 @@ static void encode_frame_to_data_rate(AV1_COMP *cpi, size_t *size,
// Pick the loop filter level for the frame.
loopfilter_frame(cpi, cm);
#ifdef OUTPUT_YUV_REC
aom_write_one_yuv_frame(cm, cm->frame_to_show);
#endif
// Build the bitstream
av1_pack_bitstream(cpi, dest, size);
......
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