rtc: Optimize set_block_thresholds()
Initialization of 'rd->threshes' is done only
for the modes evaluated in non-rd realtime
encoding.
Instruction Count
cpu Test-set Reduction(%)
7 rtc 0.187
7 rtc-derf 1.046
8 rtc 0.240
8 rtc-derf 1.420
9 rtc 0.324
9 rtc-derf 2.052
10 rtc 0.371
10 rtc-derf 2.242
Change-Id: I47f9afc3dce9b8bc196a7a758e74b5b77818b87d
diff --git a/av1/encoder/nonrd_opt.h b/av1/encoder/nonrd_opt.h
index d80e48d..9fcb724 100644
--- a/av1/encoder/nonrd_opt.h
+++ b/av1/encoder/nonrd_opt.h
@@ -14,6 +14,27 @@
#include "av1/encoder/rdopt_utils.h"
+#define RTC_INTER_MODES (4)
+#define RTC_INTRA_MODES (4)
+#define RTC_MODES (AOMMAX(RTC_INTER_MODES, RTC_INTRA_MODES))
+
+static const PREDICTION_MODE intra_mode_list[] = { DC_PRED, V_PRED, H_PRED,
+ SMOOTH_PRED };
+
+static const PREDICTION_MODE inter_mode_list[] = { NEARESTMV, NEARMV, GLOBALMV,
+ NEWMV };
+
+static const THR_MODES mode_idx[REF_FRAMES][RTC_MODES] = {
+ { THR_DC, THR_V_PRED, THR_H_PRED, THR_SMOOTH },
+ { THR_NEARESTMV, THR_NEARMV, THR_GLOBALMV, THR_NEWMV },
+ { THR_NEARESTL2, THR_NEARL2, THR_GLOBALL2, THR_NEWL2 },
+ { THR_NEARESTL3, THR_NEARL3, THR_GLOBALL3, THR_NEWL3 },
+ { THR_NEARESTG, THR_NEARG, THR_GLOBALG, THR_NEWG },
+ { THR_NEARESTB, THR_NEARB, THR_GLOBALB, THR_NEWB },
+ { THR_NEARESTA2, THR_NEARA2, THR_GLOBALA2, THR_NEWA2 },
+ { THR_NEARESTA, THR_NEARA, THR_GLOBALA, THR_NEWA },
+};
+
/*!\brief Finds predicted motion vectors for a block.
*
* \ingroup nonrd_mode_search
diff --git a/av1/encoder/nonrd_pickmode.c b/av1/encoder/nonrd_pickmode.c
index 39c2a87..c4d8288 100644
--- a/av1/encoder/nonrd_pickmode.c
+++ b/av1/encoder/nonrd_pickmode.c
@@ -83,9 +83,6 @@
#define NUM_INTER_MODES_RT 9
#define NUM_COMP_INTER_MODES_RT (6)
#define NUM_INTER_MODES_REDUCED 8
-#define RTC_INTER_MODES (4)
-#define RTC_INTRA_MODES (4)
-#define RTC_MODES (AOMMAX(RTC_INTER_MODES, RTC_INTRA_MODES))
static const REF_MODE ref_mode_set_rt[NUM_INTER_MODES_RT] = {
{ LAST_FRAME, NEARESTMV }, { LAST_FRAME, NEARMV },
@@ -104,17 +101,6 @@
{ GOLDEN_FRAME, GLOBALMV }, { GOLDEN_FRAME, NEWMV },
};
-static const THR_MODES mode_idx[REF_FRAMES][RTC_MODES] = {
- { THR_DC, THR_V_PRED, THR_H_PRED, THR_SMOOTH },
- { THR_NEARESTMV, THR_NEARMV, THR_GLOBALMV, THR_NEWMV },
- { THR_NEARESTL2, THR_NEARL2, THR_GLOBALL2, THR_NEWL2 },
- { THR_NEARESTL3, THR_NEARL3, THR_GLOBALL3, THR_NEWL3 },
- { THR_NEARESTG, THR_NEARG, THR_GLOBALG, THR_NEWG },
- { THR_NEARESTB, THR_NEARB, THR_GLOBALB, THR_NEWB },
- { THR_NEARESTA2, THR_NEARA2, THR_GLOBALA2, THR_NEWA2 },
- { THR_NEARESTA, THR_NEARA, THR_GLOBALA, THR_NEWA },
-};
-
static const COMP_REF_MODE comp_ref_mode_set[NUM_COMP_INTER_MODES_RT] = {
{ { LAST_FRAME, GOLDEN_FRAME }, GLOBAL_GLOBALMV },
{ { LAST_FRAME, GOLDEN_FRAME }, NEAREST_NEARESTMV },
@@ -124,9 +110,6 @@
{ { LAST_FRAME, ALTREF_FRAME }, NEAREST_NEARESTMV },
};
-static const PREDICTION_MODE intra_mode_list[] = { DC_PRED, V_PRED, H_PRED,
- SMOOTH_PRED };
-
static const INTER_FILTER filters_ref_set[9] = {
{ EIGHTTAP_REGULAR, EIGHTTAP_REGULAR }, { EIGHTTAP_SMOOTH, EIGHTTAP_SMOOTH },
{ EIGHTTAP_REGULAR, EIGHTTAP_SMOOTH }, { EIGHTTAP_SMOOTH, EIGHTTAP_REGULAR },
@@ -135,20 +118,6 @@
{ MULTITAP_SHARP, EIGHTTAP_SMOOTH }
};
-static INLINE int mode_offset(const PREDICTION_MODE mode) {
- if (mode >= NEARESTMV) {
- return INTER_OFFSET(mode);
- } else {
- switch (mode) {
- case DC_PRED: return 0;
- case V_PRED: return 1;
- case H_PRED: return 2;
- case SMOOTH_PRED: return 3;
- default: assert(0); return -1;
- }
- }
-}
-
enum {
// INTER_ALL = (1 << NEARESTMV) | (1 << NEARMV) | (1 << NEWMV),
INTER_NEAREST = (1 << NEARESTMV),
diff --git a/av1/encoder/rd.c b/av1/encoder/rd.c
index 665ea48..98c4fbe 100644
--- a/av1/encoder/rd.c
+++ b/av1/encoder/rd.c
@@ -32,6 +32,7 @@
#include "av1/encoder/cost.h"
#include "av1/encoder/encodemv.h"
#include "av1/encoder/encoder.h"
+#include "av1/encoder/nonrd_opt.h"
#include "av1/encoder/ratectrl.h"
#include "av1/encoder/rd.h"
@@ -507,8 +508,26 @@
}
}
-static void set_block_thresholds(const AV1_COMMON *cm, RD_OPT *rd) {
+static void set_block_thresholds(const AV1_COMMON *cm, RD_OPT *rd,
+ int use_nonrd_pick_mode) {
int i, bsize, segment_id;
+ THR_MODES mode_indices[RTC_REFS * RTC_MODES] = { 0 };
+ int num_modes_count = use_nonrd_pick_mode ? 0 : MAX_MODES;
+
+ if (use_nonrd_pick_mode) {
+ for (int r_idx = 0; r_idx < RTC_REFS; r_idx++) {
+ const MV_REFERENCE_FRAME ref = real_time_ref_combos[r_idx][0];
+ if (ref != INTRA_FRAME) {
+ for (i = 0; i < RTC_INTER_MODES; i++)
+ mode_indices[num_modes_count++] =
+ mode_idx[ref][mode_offset(inter_mode_list[i])];
+ } else {
+ for (i = 0; i < RTC_INTRA_MODES; i++)
+ mode_indices[num_modes_count++] =
+ mode_idx[ref][mode_offset(intra_mode_list[i])];
+ }
+ }
+ }
for (segment_id = 0; segment_id < MAX_SEGMENTS; ++segment_id) {
const int qindex = clamp(
@@ -523,10 +542,13 @@
const int t = q * rd_thresh_block_size_factor[bsize];
const int thresh_max = INT_MAX / t;
- for (i = 0; i < MAX_MODES; ++i)
- rd->threshes[segment_id][bsize][i] = rd->thresh_mult[i] < thresh_max
- ? rd->thresh_mult[i] * t / 4
- : INT_MAX;
+ for (i = 0; i < num_modes_count; ++i) {
+ const int mode_index = use_nonrd_pick_mode ? mode_indices[i] : i;
+ rd->threshes[segment_id][bsize][mode_index] =
+ rd->thresh_mult[mode_index] < thresh_max
+ ? rd->thresh_mult[mode_index] * t / 4
+ : INT_MAX;
+ }
}
}
}
@@ -748,7 +770,7 @@
av1_set_error_per_bit(&x->errorperbit, rd->RDMULT);
- set_block_thresholds(cm, rd);
+ set_block_thresholds(cm, rd, cpi->sf.rt_sf.use_nonrd_pick_mode);
populate_unified_cost_update_freq(cpi->oxcf.cost_upd_freq, sf);
const INTER_MODE_SPEED_FEATURES *const inter_sf = &cpi->sf.inter_sf;
diff --git a/av1/encoder/rd.h b/av1/encoder/rd.h
index 8d0277e..96d53c9 100644
--- a/av1/encoder/rd.h
+++ b/av1/encoder/rd.h
@@ -56,6 +56,28 @@
// Factor to weigh the rate for switchable interp filters.
#define SWITCHABLE_INTERP_RATE_FACTOR 1
+#define RTC_REFS 4
+static const MV_REFERENCE_FRAME real_time_ref_combos[RTC_REFS][2] = {
+ { LAST_FRAME, NONE_FRAME },
+ { ALTREF_FRAME, NONE_FRAME },
+ { GOLDEN_FRAME, NONE_FRAME },
+ { INTRA_FRAME, NONE_FRAME }
+};
+
+static INLINE int mode_offset(const PREDICTION_MODE mode) {
+ if (mode >= NEARESTMV) {
+ return INTER_OFFSET(mode);
+ } else {
+ switch (mode) {
+ case DC_PRED: return 0;
+ case V_PRED: return 1;
+ case H_PRED: return 2;
+ case SMOOTH_PRED: return 3;
+ default: assert(0); return -1;
+ }
+ }
+}
+
enum {
// Default initialization when we are not using winner mode framework. e.g.
// intrabc
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index a1d5778..bb61ef0 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -3703,13 +3703,6 @@
{ ALTREF_FRAME, INTRA_FRAME }, { BWDREF_FRAME, INTRA_FRAME },
};
-static const MV_REFERENCE_FRAME real_time_ref_combos[][2] = {
- { LAST_FRAME, NONE_FRAME },
- { ALTREF_FRAME, NONE_FRAME },
- { GOLDEN_FRAME, NONE_FRAME },
- { INTRA_FRAME, NONE_FRAME }
-};
-
typedef enum { REF_SET_FULL, REF_SET_REDUCED, REF_SET_REALTIME } REF_SET;
static AOM_INLINE void default_skip_mask(mode_skip_mask_t *mask,