From f9b93714764ef4dde7f672d5791b2e1c38b12e2c Mon Sep 17 00:00:00 2001 From: Angie Chiang Date: Fri, 16 Aug 2019 14:17:18 -0700 Subject: [PATCH] Add MotionField and MotionFieldInfo Also add related buffer alloc/free functions. Change-Id: I77dde3dd991f6b21b5c2c1ffa72300ce7738fd50 --- vp9/encoder/vp9_encoder.h | 35 --------------- vp9/encoder/vp9_non_greedy_mv.c | 79 ++++++++++++++++++++++++++++++--- vp9/encoder/vp9_non_greedy_mv.h | 67 +++++++++++++++++++++++++++- 3 files changed, 139 insertions(+), 42 deletions(-) diff --git a/vp9/encoder/vp9_encoder.h b/vp9/encoder/vp9_encoder.h index f157fdfc5..256007230 100644 --- a/vp9/encoder/vp9_encoder.h +++ b/vp9/encoder/vp9_encoder.h @@ -302,7 +302,6 @@ typedef struct TplDepStats { } TplDepStats; #if CONFIG_NON_GREEDY_MV -#define SQUARE_BLOCK_SIZES 4 #define ZERO_MV_MODE 0 #define NEW_MV_MODE 1 @@ -329,40 +328,6 @@ typedef struct TplDepFrame { } TplDepFrame; #if CONFIG_NON_GREEDY_MV -static INLINE int get_square_block_idx(BLOCK_SIZE bsize) { - if (bsize == BLOCK_4X4) { - return 0; - } - if (bsize == BLOCK_8X8) { - return 1; - } - if (bsize == BLOCK_16X16) { - return 2; - } - if (bsize == BLOCK_32X32) { - return 3; - } - assert(0 && "ERROR: non-square block size"); - return -1; -} - -static INLINE BLOCK_SIZE square_block_idx_to_bsize(int square_block_idx) { - if (square_block_idx == 0) { - return BLOCK_4X4; - } - if (square_block_idx == 1) { - return BLOCK_8X8; - } - if (square_block_idx == 2) { - return BLOCK_16X16; - } - if (square_block_idx == 3) { - return BLOCK_32X32; - } - assert(0 && "ERROR: invalid square_block_idx"); - return BLOCK_INVALID; -} - static INLINE int_mv *get_pyramid_mv(const TplDepFrame *tpl_frame, int rf_idx, BLOCK_SIZE bsize, int mi_row, int mi_col) { return &tpl_frame->pyramid_mv_arr[rf_idx][get_square_block_idx(bsize)] diff --git a/vp9/encoder/vp9_non_greedy_mv.c b/vp9/encoder/vp9_non_greedy_mv.c index 8022c6103..1a8d57db7 100644 --- a/vp9/encoder/vp9_non_greedy_mv.c +++ b/vp9/encoder/vp9_non_greedy_mv.c @@ -164,6 +164,72 @@ static const int log2_table[LOG2_TABLE_SIZE] = { 10484282, }; +static int mi_size_to_block_size(int mi_bsize, int mi_num) { + return (mi_num % mi_bsize) ? mi_num / mi_bsize + 1 : mi_num / mi_bsize; +} + +void vp9_alloc_motion_field_info(MotionFieldInfo *motion_field_info, + int frame_num, int mi_rows, int mi_cols) { + int frame_idx, rf_idx, square_block_idx; + motion_field_info->frame_num = frame_num; + motion_field_info->motion_field_array = + vpx_calloc(frame_num, sizeof(*motion_field_info->motion_field_array)); + for (frame_idx = 0; frame_idx < frame_num; ++frame_idx) { + for (rf_idx = 0; rf_idx < 3; ++rf_idx) { + for (square_block_idx = 0; square_block_idx < SQUARE_BLOCK_SIZES; + ++square_block_idx) { + BLOCK_SIZE bsize = square_block_idx_to_bsize(square_block_idx); + const int mi_height = num_8x8_blocks_high_lookup[bsize]; + const int mi_width = num_8x8_blocks_wide_lookup[bsize]; + const int block_rows = mi_size_to_block_size(mi_height, mi_rows); + const int block_cols = mi_size_to_block_size(mi_width, mi_cols); + MotionField *motion_field = + &motion_field_info + ->motion_field_array[frame_idx][rf_idx][square_block_idx]; + vp9_alloc_motion_field(motion_field, bsize, block_rows, block_cols); + } + } + } +} + +void vp9_alloc_motion_field(MotionField *motion_field, BLOCK_SIZE bsize, + int block_rows, int block_cols) { + motion_field->ready = 0; + motion_field->bsize = bsize; + motion_field->block_rows = block_rows; + motion_field->block_cols = block_cols; + motion_field->mf = + vpx_calloc(block_rows * block_cols, sizeof(*motion_field->mf)); + assert(motion_field->mf != NULL); + motion_field->local_structure = vpx_calloc( + block_rows * block_cols, sizeof(*motion_field->local_structure)); + assert(motion_field->local_structure != NULL); +} + +void vp9_free_motion_field(MotionField *motion_field) { + vpx_free(motion_field->mf); + vpx_free(motion_field->local_structure); + vp9_zero(*motion_field); +} + +void vp9_free_motion_field_info(MotionFieldInfo *motion_field_info) { + int frame_idx, rf_idx, square_block_idx; + for (frame_idx = 0; frame_idx < motion_field_info->frame_num; ++frame_idx) { + for (rf_idx = 0; rf_idx < 3; ++rf_idx) { + for (square_block_idx = 0; square_block_idx < SQUARE_BLOCK_SIZES; + ++square_block_idx) { + MotionField *motion_field = + &motion_field_info + ->motion_field_array[frame_idx][rf_idx][square_block_idx]; + vp9_free_motion_field(motion_field); + } + } + } + vpx_free(motion_field_info->motion_field_array); + motion_field_info->motion_field_array = NULL; + motion_field_info->frame_num = 0; +} + static int64_t log2_approximation(int64_t v) { assert(v > 0); if (v < LOG2_TABLE_SIZE) { @@ -206,8 +272,9 @@ int64_t vp9_nb_mvs_inconsistency(const MV *mv, const int_mv *nb_full_mvs, } static MV get_smooth_motion_vector(const MV search_mv, const MV *tmp_mf, - const int (*M)[4], int rows, int cols, - int row, int col, float alpha) { + const int (*M)[MF_LOCAL_STRUCTURE_SIZE], + int rows, int cols, int row, int col, + float alpha) { const MV tmp_mv = tmp_mf[row * cols + col]; int idx_row, idx_col; float avg_nb_mv[2] = { 0.0f, 0.0f }; @@ -260,7 +327,8 @@ static MV get_smooth_motion_vector(const MV search_mv, const MV *tmp_mf, return mv; } -void vp9_get_smooth_motion_field(const MV *scaled_search_mf, const int (*M)[4], +void vp9_get_smooth_motion_field(const MV *scaled_search_mf, + const int (*M)[MF_LOCAL_STRUCTURE_SIZE], int rows, int cols, float alpha, int num_iters, MV *smooth_mf) { // note: the scaled_search_mf and smooth_mf are all scaled by macroblock size @@ -298,11 +366,12 @@ void vp9_get_smooth_motion_field(const MV *scaled_search_mf, const int (*M)[4], void vp9_get_local_structure(const YV12_BUFFER_CONFIG *ref_frame, const vp9_variance_fn_ptr_t *fn_ptr, int mi_rows, - int mi_cols, BLOCK_SIZE bsize, int (*M)[4]) { + int mi_cols, BLOCK_SIZE bsize, + int (*M)[MF_LOCAL_STRUCTURE_SIZE]) { int stride = ref_frame->y_stride; const int mi_height = num_8x8_blocks_high_lookup[bsize]; const int mi_width = num_8x8_blocks_wide_lookup[bsize]; - int cols = mi_cols / mi_width; + int cols = mi_size_to_block_size(mi_width, mi_cols); int mi_row, mi_col; for (mi_row = 0; mi_row < mi_rows; mi_row += mi_height) { for (mi_col = 0; mi_col < mi_cols; mi_col += mi_width) { diff --git a/vp9/encoder/vp9_non_greedy_mv.h b/vp9/encoder/vp9_non_greedy_mv.h index 5230ba375..ed6438c11 100644 --- a/vp9/encoder/vp9_non_greedy_mv.h +++ b/vp9/encoder/vp9_non_greedy_mv.h @@ -21,17 +21,80 @@ extern "C" { #endif #define NB_MVS_NUM 4 #define LOG2_PRECISION 20 +#define MF_LOCAL_STRUCTURE_SIZE 4 +#define SQUARE_BLOCK_SIZES 4 + +typedef struct MotionField { + int ready; + BLOCK_SIZE bsize; + int block_rows; + int block_cols; + int (*local_structure)[MF_LOCAL_STRUCTURE_SIZE]; + MV *mf; + int mv_log_scale; +} MotionField; + +typedef struct MotionFieldInfo { + int frame_num; + MotionField (*motion_field_array)[3][SQUARE_BLOCK_SIZES]; +} MotionFieldInfo; + +static INLINE int get_square_block_idx(BLOCK_SIZE bsize) { + if (bsize == BLOCK_4X4) { + return 0; + } + if (bsize == BLOCK_8X8) { + return 1; + } + if (bsize == BLOCK_16X16) { + return 2; + } + if (bsize == BLOCK_32X32) { + return 3; + } + assert(0 && "ERROR: non-square block size"); + return -1; +} + +static INLINE BLOCK_SIZE square_block_idx_to_bsize(int square_block_idx) { + if (square_block_idx == 0) { + return BLOCK_4X4; + } + if (square_block_idx == 1) { + return BLOCK_8X8; + } + if (square_block_idx == 2) { + return BLOCK_16X16; + } + if (square_block_idx == 3) { + return BLOCK_32X32; + } + assert(0 && "ERROR: invalid square_block_idx"); + return BLOCK_INVALID; +} + +void vp9_alloc_motion_field_info(MotionFieldInfo *motion_field_info, + int gop_size, int block_rows, int block_cols); + +void vp9_alloc_motion_field(MotionField *motion_field, BLOCK_SIZE bsize, + int block_rows, int block_cols); + +void vp9_free_motion_field(MotionField *motion_field); + +void vp9_free_motion_field_info(MotionFieldInfo *motion_field_info); int64_t vp9_nb_mvs_inconsistency(const MV *mv, const int_mv *nb_full_mvs, int mv_num); -void vp9_get_smooth_motion_field(const MV *search_mf, const int (*M)[4], +void vp9_get_smooth_motion_field(const MV *search_mf, + const int (*M)[MF_LOCAL_STRUCTURE_SIZE], int rows, int cols, float alpha, int num_iters, MV *smooth_mf); void vp9_get_local_structure(const YV12_BUFFER_CONFIG *ref_frame, const vp9_variance_fn_ptr_t *fn_ptr, int mi_rows, - int mi_cols, BLOCK_SIZE bsize, int (*M)[4]); + int mi_cols, BLOCK_SIZE bsize, + int (*M)[MF_LOCAL_STRUCTURE_SIZE]); #ifdef __cplusplus } // extern "C" -- 2.40.0