summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDeepa K G <deepa.kg@ittiam.com>2023-02-16 21:47:24 +0530
committerDeepa K G <deepa.kg@ittiam.com>2023-02-21 18:05:23 +0530
commitc4ee2b2f033d377427017b2b8244e5f29fe80961 (patch)
tree2d480f8668a898404f8ef9a9623454c4f70c2b14
parentb737865480d2f1355a972f2f9b3b3a0f34a9ef83 (diff)
downloadlibvpx-c4ee2b2f033d377427017b2b8244e5f29fe80961.tar
libvpx-c4ee2b2f033d377427017b2b8244e5f29fe80961.tar.gz
libvpx-c4ee2b2f033d377427017b2b8244e5f29fe80961.tar.bz2
libvpx-c4ee2b2f033d377427017b2b8244e5f29fe80961.zip
Skip redundant iterations in joint motion search 
In joint_motion_search, there are four iterations. Even iterations search in the first reference frame and odd iterations search in the second. The last two iterations use the search result of the first two iterations as the start point. If the search result does not change,last two iterations are not necessary and can be skipped. Instruction Count cpu-used Reduction(%) 0 1.411 Change-Id: Ie583c9f75dd0a22bbdfb432ccdd62eea6ec4fce8
-rw-r--r--vp9/encoder/vp9_rdopt.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index 498bc0fbd..201bf416d 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -1862,6 +1862,19 @@ static int check_best_zero_mv(const VP9_COMP *cpi,
return 1;
}
+static INLINE int skip_iters(const int_mv iter_mvs[][2], int ite, int id) {
+ if (ite >= 2 && iter_mvs[ite - 2][!id].as_int == iter_mvs[ite][!id].as_int) {
+ int_mv cur_fullpel_mv, prev_fullpel_mv;
+ cur_fullpel_mv.as_mv.row = iter_mvs[ite][id].as_mv.row >> 3;
+ cur_fullpel_mv.as_mv.col = iter_mvs[ite][id].as_mv.col >> 3;
+ prev_fullpel_mv.as_mv.row = iter_mvs[ite - 2][id].as_mv.row >> 3;
+ prev_fullpel_mv.as_mv.col = iter_mvs[ite - 2][id].as_mv.col >> 3;
+ if (cur_fullpel_mv.as_int == prev_fullpel_mv.as_int) return 1;
+ }
+ return 0;
+}
+
+#define NUM_ITERS 4
static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
int_mv *frame_mv, int mi_row, int mi_col,
int_mv single_newmv[MAX_REF_FRAMES],
@@ -1874,6 +1887,7 @@ static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
const int refs[2] = { mi->ref_frame[0],
mi->ref_frame[1] < 0 ? 0 : mi->ref_frame[1] };
int_mv ref_mv[2];
+ int_mv iter_mvs[NUM_ITERS][2];
int ite, ref;
const InterpKernel *kernel = vp9_filter_kernels[mi->interp_filter];
struct scale_factors sf;
@@ -1909,6 +1923,7 @@ static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
}
frame_mv[refs[ref]].as_int = single_newmv[refs[ref]].as_int;
+ iter_mvs[0][ref].as_int = single_newmv[refs[ref]].as_int;
}
// Since we have scaled the reference frames to match the size of the current
@@ -1923,7 +1938,7 @@ static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
// Allow joint search multiple times iteratively for each reference frame
// and break out of the search loop if it couldn't find a better mv.
- for (ite = 0; ite < 4; ite++) {
+ for (ite = 0; ite < NUM_ITERS; ite++) {
struct buf_2d ref_yv12[2];
uint32_t bestsme = UINT_MAX;
int sadpb = x->sadperbit16;
@@ -1935,6 +1950,11 @@ static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
// odd iterations search in the second. The predictor
// found for the 'other' reference frame is factored in.
+ // Skip further iterations of search if in the previous iteration, the
+ // motion vector of the searched ref frame is unchanged, and the other ref
+ // frame's full-pixel mv is unchanged.
+ if (skip_iters(iter_mvs, ite, id)) break;
+
// Initialized here because of compiler problem in Visual Studio.
ref_yv12[0] = xd->plane[0].pre[0];
ref_yv12[1] = xd->plane[0].pre[1];
@@ -2000,6 +2020,10 @@ static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
} else {
break;
}
+ if (ite < NUM_ITERS - 1) {
+ iter_mvs[ite + 1][0].as_int = frame_mv[refs[0]].as_int;
+ iter_mvs[ite + 1][1].as_int = frame_mv[refs[1]].as_int;
+ }
}
*rate_mv = 0;