From: Jingning Han Date: Mon, 23 Nov 2015 23:05:18 +0000 (-0800) Subject: Integrate motion vector stack into codec X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e5c57c580a64b7767ba44524590cc68102769092;p=libvpx Integrate motion vector stack into codec This commit ports the motion vector stack from motion field analyzer to the encoding and decoding pipeline. Change-Id: Ie283c1e1a15b4c17a1c7c175ce322bf053bb7840 --- diff --git a/vp10/common/blockd.h b/vp10/common/blockd.h index 0ea70d371..eeeb69c9f 100644 --- a/vp10/common/blockd.h +++ b/vp10/common/blockd.h @@ -254,6 +254,11 @@ typedef struct macroblockd { // dimension in the unit of 8x8 block of the current block uint8_t n8_w, n8_h; +#if CONFIG_REF_MV + uint8_t ref_mv_count[MAX_REF_FRAMES]; + CANDIDATE_MV ref_mv_stack[MAX_REF_FRAMES][MAX_REF_MV_STACK_SIZE]; +#endif + #if CONFIG_VP9_HIGHBITDEPTH /* Bit depth: 8, 10, 12 */ int bd; diff --git a/vp10/common/mv.h b/vp10/common/mv.h index 4cc263820..289c591ed 100644 --- a/vp10/common/mv.h +++ b/vp10/common/mv.h @@ -34,6 +34,13 @@ typedef struct mv32 { int32_t col; } MV32; +#if CONFIG_REF_MV +typedef struct candidate_mv { + int_mv this_mv; + int weight; +} CANDIDATE_MV; +#endif + static INLINE int is_zero_mv(const MV *mv) { return *((const uint32_t *)mv) == 0; } diff --git a/vp10/common/mvref_common.c b/vp10/common/mvref_common.c index 851f30aa0..347064336 100644 --- a/vp10/common/mvref_common.c +++ b/vp10/common/mvref_common.c @@ -17,7 +17,7 @@ static void scan_row_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd, const MV_REFERENCE_FRAME ref_frame, int row_offset, CANDIDATE_MV *ref_mv_stack, - int *refmv_count) { + uint8_t *refmv_count) { const TileInfo *const tile = &xd->tile; int i; @@ -66,7 +66,7 @@ static void scan_col_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd, const MV_REFERENCE_FRAME ref_frame, int col_offset, CANDIDATE_MV *ref_mv_stack, - int *refmv_count) { + uint8_t *refmv_count) { const TileInfo *const tile = &xd->tile; int i; @@ -115,7 +115,7 @@ static void scan_blk_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd, const MV_REFERENCE_FRAME ref_frame, int row_offset, int col_offset, CANDIDATE_MV *ref_mv_stack, - int *refmv_count) { + uint8_t *refmv_count) { const TileInfo *const tile = &xd->tile; POSITION mi_pos; @@ -154,29 +154,30 @@ static void scan_blk_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd, static void setup_ref_mv_list(const VP10_COMMON *cm, const MACROBLOCKD *xd, MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame, + uint8_t *refmv_count, + CANDIDATE_MV *ref_mv_stack, int_mv *mv_ref_list, int block, int mi_row, int mi_col, uint8_t *mode_context) { - int idx, refmv_count = 0, nearest_refmv_count = 0; + int idx, nearest_refmv_count = 0; const int bw = num_8x8_blocks_wide_lookup[mi->mbmi.sb_type] << 3; const int bh = num_8x8_blocks_high_lookup[mi->mbmi.sb_type] << 3; - CANDIDATE_MV ref_mv_stack[MAX_REF_MV_STACK_SIZE]; CANDIDATE_MV tmp_mv; int len, nr_len; (void) mode_context; - memset(ref_mv_stack, 0, sizeof(ref_mv_stack)); + *refmv_count = 0; // Scan the first above row mode info. scan_row_mbmi(cm, xd, mi_row, mi_col, block, ref_frame, - -1, ref_mv_stack, &refmv_count); + -1, ref_mv_stack, refmv_count); // Scan the first left column mode info. scan_col_mbmi(cm, xd, mi_row, mi_col, block, ref_frame, - -1, ref_mv_stack, &refmv_count); + -1, ref_mv_stack, refmv_count); - nearest_refmv_count = refmv_count; + nearest_refmv_count = *refmv_count; // Analyze the top-left corner block mode info. // scan_blk_mbmi(cm, xd, mi_row, mi_col, block, ref_frame, @@ -184,22 +185,22 @@ static void setup_ref_mv_list(const VP10_COMMON *cm, const MACROBLOCKD *xd, // Scan the second outer area. scan_row_mbmi(cm, xd, mi_row, mi_col, block, ref_frame, - -2, ref_mv_stack, &refmv_count); + -2, ref_mv_stack, refmv_count); scan_col_mbmi(cm, xd, mi_row, mi_col, block, ref_frame, - -2, ref_mv_stack, &refmv_count); + -2, ref_mv_stack, refmv_count); // Scan the third outer area. scan_row_mbmi(cm, xd, mi_row, mi_col, block, ref_frame, - -3, ref_mv_stack, &refmv_count); + -3, ref_mv_stack, refmv_count); scan_col_mbmi(cm, xd, mi_row, mi_col, block, ref_frame, - -3, ref_mv_stack, &refmv_count); + -3, ref_mv_stack, refmv_count); // Scan the fourth outer area. scan_row_mbmi(cm, xd, mi_row, mi_col, block, ref_frame, - -4, ref_mv_stack, &refmv_count); + -4, ref_mv_stack, refmv_count); // Scan the third left row mode info. scan_col_mbmi(cm, xd, mi_row, mi_col, block, ref_frame, - -4, ref_mv_stack, &refmv_count); + -4, ref_mv_stack, refmv_count); // Rank the likelihood and assign nearest and near mvs. len = nearest_refmv_count; @@ -216,7 +217,7 @@ static void setup_ref_mv_list(const VP10_COMMON *cm, const MACROBLOCKD *xd, len = nr_len; } - len = refmv_count; + len = *refmv_count; while (len > nearest_refmv_count) { nr_len = nearest_refmv_count; for (idx = nearest_refmv_count + 1; idx < len; ++idx) { @@ -230,7 +231,7 @@ static void setup_ref_mv_list(const VP10_COMMON *cm, const MACROBLOCKD *xd, len = nr_len; } - for (idx = 0; idx < VPXMIN(MAX_MV_REF_CANDIDATES, refmv_count); ++idx) { + for (idx = 0; idx < VPXMIN(MAX_MV_REF_CANDIDATES, *refmv_count); ++idx) { mv_ref_list[idx].as_int = ref_mv_stack[idx].this_mv.as_int; clamp_mv_ref(&mv_ref_list[idx].as_mv, bw, bh, xd); } @@ -373,6 +374,10 @@ static void find_mv_refs_idx(const VP10_COMMON *cm, const MACROBLOCKD *xd, void vp10_find_mv_refs(const VP10_COMMON *cm, const MACROBLOCKD *xd, MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame, +#if CONFIG_REF_MV + uint8_t *ref_mv_count, + CANDIDATE_MV *ref_mv_stack, +#endif int_mv *mv_ref_list, int mi_row, int mi_col, find_mv_refs_sync sync, void *const data, @@ -381,8 +386,8 @@ void vp10_find_mv_refs(const VP10_COMMON *cm, const MACROBLOCKD *xd, mi_row, mi_col, sync, data, mode_context); #if CONFIG_REF_MV - setup_ref_mv_list(cm, xd, mi, ref_frame, mv_ref_list, -1, - mi_row, mi_col, mode_context); + setup_ref_mv_list(cm, xd, mi, ref_frame, ref_mv_count, ref_mv_stack, + mv_ref_list, -1, mi_row, mi_col, mode_context); #endif } diff --git a/vp10/common/mvref_common.h b/vp10/common/mvref_common.h index 410be4c68..6b408785f 100644 --- a/vp10/common/mvref_common.h +++ b/vp10/common/mvref_common.h @@ -24,13 +24,6 @@ typedef struct position { int col; } POSITION; -#if CONFIG_REF_MV -typedef struct candidate_mv { - int_mv this_mv; - int weight; -} CANDIDATE_MV; -#endif - typedef enum { BOTH_ZERO = 0, ZERO_PLUS_PREDICTED = 1, @@ -204,10 +197,14 @@ static INLINE int is_inside(const TileInfo *const tile, typedef void (*find_mv_refs_sync)(void *const data, int mi_row); void vp10_find_mv_refs(const VP10_COMMON *cm, const MACROBLOCKD *xd, - MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame, - int_mv *mv_ref_list, int mi_row, int mi_col, - find_mv_refs_sync sync, void *const data, - uint8_t *mode_context); + MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame, +#if CONFIG_REF_MV + uint8_t *ref_mv_count, + CANDIDATE_MV *ref_mv_stack, +#endif + int_mv *mv_ref_list, int mi_row, int mi_col, + find_mv_refs_sync sync, void *const data, + uint8_t *mode_context); // check a list of motion vectors by sad score using a number rows of pixels // above and a number cols of pixels in the left to select the one with best diff --git a/vp10/decoder/decodemv.c b/vp10/decoder/decodemv.c index ea21c8bf5..edc2716cc 100644 --- a/vp10/decoder/decodemv.c +++ b/vp10/decoder/decodemv.c @@ -786,8 +786,13 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi, "Reference frame has invalid dimensions"); vp10_setup_pre_planes(xd, ref, ref_buf->buf, mi_row, mi_col, &ref_buf->sf); - vp10_find_mv_refs(cm, xd, mi, frame, ref_mvs[frame], - mi_row, mi_col, fpm_sync, (void *)pbi, inter_mode_ctx); + vp10_find_mv_refs(cm, xd, mi, frame, +#if CONFIG_REF_MV + &xd->ref_mv_count[frame], + xd->ref_mv_stack[frame], +#endif + ref_mvs[frame], + mi_row, mi_col, fpm_sync, (void *)pbi, inter_mode_ctx); } if (segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) { diff --git a/vp10/encoder/block.h b/vp10/encoder/block.h index 55ec46eec..62de0bc37 100644 --- a/vp10/encoder/block.h +++ b/vp10/encoder/block.h @@ -13,6 +13,9 @@ #include "vp10/common/entropymv.h" #include "vp10/common/entropy.h" +#if CONFIG_REF_MV +#include "vp10/common/mvref_common.h" +#endif #ifdef __cplusplus extern "C" { @@ -50,6 +53,10 @@ typedef unsigned int vp10_coeff_cost[PLANE_TYPES][REF_TYPES][COEF_BANDS][2] typedef struct { int_mv ref_mvs[MAX_REF_FRAMES][MAX_MV_REF_CANDIDATES]; uint8_t mode_context[MAX_REF_FRAMES]; +#if CONFIG_REF_MV + uint8_t ref_mv_count[MAX_REF_FRAMES]; + CANDIDATE_MV ref_mv_stack[MAX_REF_FRAMES][MAX_REF_MV_STACK_SIZE]; +#endif } MB_MODE_INFO_EXT; typedef struct { diff --git a/vp10/encoder/rdopt.c b/vp10/encoder/rdopt.c index 1f2378451..370821451 100644 --- a/vp10/encoder/rdopt.c +++ b/vp10/encoder/rdopt.c @@ -3902,8 +3902,13 @@ static void setup_buffer_inter( vp10_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf); // Gets an initial list of candidate vectors from neighbours and orders them - vp10_find_mv_refs(cm, xd, mi, ref_frame, candidates, mi_row, mi_col, - NULL, NULL, mbmi_ext->mode_context); + vp10_find_mv_refs(cm, xd, mi, ref_frame, +#if CONFIG_REF_MV + &mbmi_ext->ref_mv_count[ref_frame], + mbmi_ext->ref_mv_stack[ref_frame], +#endif + candidates, mi_row, mi_col, + NULL, NULL, mbmi_ext->mode_context); // Candidate refinement carried out at encoder and decoder vp10_find_best_ref_mvs(cm->allow_high_precision_mv, candidates,