Enable full mv search once again.

- Updates function search_mv_full so that it compiles and handles
  non-square blocks.
- Enables compilation of search_mv_full.
- Sets full search radius to 32.
- Enables selecting full mv search with "--me full".
This commit is contained in:
Arttu Ylä-Outinen 2015-11-20 09:50:01 +02:00
parent 70306ea9bd
commit 0e33049d9e
6 changed files with 52 additions and 34 deletions

View file

@ -54,6 +54,7 @@ http://ultravideo.cs.tut.fi/#encoder for more information.
--me <string> : Set integer motion estimation algorithm ["hexbs"] --me <string> : Set integer motion estimation algorithm ["hexbs"]
"hexbs": Hexagon Based Search (faster) "hexbs": Hexagon Based Search (faster)
"tz": Test Zone Search (better quality) "tz": Test Zone Search (better quality)
"full": Full Search (super slow)
--subme <integer> : Set fractional pixel motion estimation level [1]. --subme <integer> : Set fractional pixel motion estimation level [1].
0: only integer motion estimation 0: only integer motion estimation
1: fractional pixel motion estimation enabled 1: fractional pixel motion estimation enabled

View file

@ -311,6 +311,7 @@ void print_help(void)
" --me <string> : Set integer motion estimation algorithm [\"hexbs\"]\n" " --me <string> : Set integer motion estimation algorithm [\"hexbs\"]\n"
" \"hexbs\": Hexagon Based Search (faster)\n" " \"hexbs\": Hexagon Based Search (faster)\n"
" \"tz\": Test Zone Search (better quality)\n" " \"tz\": Test Zone Search (better quality)\n"
" \"full\": Full Search (super slow)\n"
" --no-transform-skip : Disable transform skip\n" " --no-transform-skip : Disable transform skip\n"
" --aud : Use access unit delimiters\n" " --aud : Use access unit delimiters\n"
" --cqmfile <string> : Custom Quantization Matrices from a file\n" " --cqmfile <string> : Custom Quantization Matrices from a file\n"

View file

@ -267,7 +267,7 @@ static int parse_slice_specification(const char* const arg, int32_t * const nsli
int kvz_config_parse(kvz_config *cfg, const char *name, const char *value) int kvz_config_parse(kvz_config *cfg, const char *name, const char *value)
{ {
static const char * const me_names[] = { "hexbs", "tz", NULL }; static const char * const me_names[] = { "hexbs", "tz", "full", NULL };
static const char * const source_scan_type_names[] = { "progressive", "tff", "bff", NULL }; static const char * const source_scan_type_names[] = { "progressive", "tff", "bff", NULL };
static const char * const overscan_names[] = { "undef", "show", "crop", NULL }; static const char * const overscan_names[] = { "undef", "show", "crop", NULL };

View file

@ -80,6 +80,7 @@ typedef struct kvz_encoder kvz_encoder;
enum kvz_ime_algorithm { enum kvz_ime_algorithm {
KVZ_IME_HEXBS = 0, KVZ_IME_HEXBS = 0,
KVZ_IME_TZ = 1, KVZ_IME_TZ = 1,
KVZ_IME_FULL = 2,
}; };
/** /**

View file

@ -21,6 +21,6 @@
****************************************************************************/ ****************************************************************************/
// KVZ_API_VERSION is incremented every time the public api changes. // KVZ_API_VERSION is incremented every time the public api changes.
#define KVZ_API_VERSION 9 #define KVZ_API_VERSION 10
#endif // KVAZAAR_VERSION_H_ #endif // KVAZAAR_VERSION_H_

View file

@ -32,10 +32,6 @@
#include "rdo.h" #include "rdo.h"
// Temporarily for debugging.
#define SEARCH_MV_FULL_RADIUS 0
static uint32_t get_ep_ex_golomb_bitcost(uint32_t symbol, uint32_t count) static uint32_t get_ep_ex_golomb_bitcost(uint32_t symbol, uint32_t count)
{ {
int32_t num_bins = 0; int32_t num_bins = 0;
@ -761,21 +757,26 @@ static unsigned hexagon_search(const encoder_state_t * const state,
} }
#if SEARCH_MV_FULL_RADIUS #define IME_FULL_SEARCH_RADIUS 32
static unsigned search_mv_full(unsigned depth, static unsigned search_mv_full(const encoder_state_t * const state,
const picture *pic, const picture *ref, unsigned width, unsigned height,
const vector2d *orig, vector2d *mv_in_out, const kvz_picture *pic, const kvz_picture *ref,
int16_t mv_cand[2][2], int16_t merge_cand[MRG_MAX_NUM_CANDS][3], const vector2d_t *orig, vector2d_t *mv_in_out,
int16_t mv_cand[2][2], inter_merge_cand_t merge_cand[MRG_MAX_NUM_CANDS],
int16_t num_cand, int32_t ref_idx, uint32_t *bitcost_out) int16_t num_cand, int32_t ref_idx, uint32_t *bitcost_out)
{ {
vector2d mv = { mv_in_out->x >> 2, mv_in_out->y >> 2 }; vector2d_t mv = { mv_in_out->x >> 2, mv_in_out->y >> 2 };
int block_width = CU_WIDTH_FROM_DEPTH(depth);
unsigned best_cost = UINT32_MAX; unsigned best_cost = UINT32_MAX;
int x, y;
uint32_t best_bitcost = 0, bitcost; uint32_t best_bitcost = 0, bitcost;
vector2d min_mv, max_mv; const int max_lcu_below = state->encoder_control->owf ? 1 : -1;
/*if (abs(mv.x) > SEARCH_MV_FULL_RADIUS || abs(mv.y) > SEARCH_MV_FULL_RADIUS) { int (*calc_mvd)(const encoder_state_t * const,
int, int, int,
int16_t[2][2], inter_merge_cand_t[MRG_MAX_NUM_CANDS],
int16_t, int32_t, uint32_t *) =
state->encoder_control->cfg->mv_rdo ? kvz_calc_mvd_cost_cabac : calc_mvd_cost;
/*if (abs(mv.x) > IME_FULL_SEARCH_RADIUS || abs(mv.y) > IME_FULL_SEARCH_RADIUS) {
best_cost = calc_sad(pic, ref, orig->x, orig->y, best_cost = calc_sad(pic, ref, orig->x, orig->y,
orig->x, orig->y, orig->x, orig->y,
block_width, block_width); block_width, block_width);
@ -783,18 +784,23 @@ static unsigned search_mv_full(unsigned depth,
mv.y = 0; mv.y = 0;
}*/ }*/
min_mv.x = mv.x - SEARCH_MV_FULL_RADIUS; vector2d_t min_mv = {
min_mv.y = mv.y - SEARCH_MV_FULL_RADIUS; mv.x - IME_FULL_SEARCH_RADIUS,
max_mv.x = mv.x + SEARCH_MV_FULL_RADIUS; mv.y - IME_FULL_SEARCH_RADIUS,
max_mv.y = mv.y + SEARCH_MV_FULL_RADIUS; };
vector2d_t max_mv = {
mv.x + IME_FULL_SEARCH_RADIUS,
mv.y + IME_FULL_SEARCH_RADIUS,
};
for (y = min_mv.y; y < max_mv.y; ++y) { for (int y = min_mv.y; y < max_mv.y; ++y) {
for (x = min_mv.x; x < max_mv.x; ++x) { for (int x = min_mv.x; x < max_mv.x; ++x) {
unsigned cost = calc_sad(pic, ref, orig->x, orig->y, unsigned cost = kvz_image_calc_sad(pic, ref, orig->x, orig->y,
orig->x + x, orig->x + x,
orig->y + y, orig->y + y,
block_width, block_width); width, height,
cost += calc_mvd_cost(x, y, mv_cand,merge_cand,num_cand,ref_idx, &bitcost); max_lcu_below);
cost += calc_mvd(state, x, y, 2, mv_cand, merge_cand, num_cand, ref_idx, &bitcost);
if (cost < best_cost) { if (cost < best_cost) {
best_cost = cost; best_cost = cost;
best_bitcost = bitcost; best_bitcost = bitcost;
@ -811,7 +817,6 @@ static unsigned search_mv_full(unsigned depth,
return best_cost; return best_cost;
} }
#endif
/** /**
@ -1023,12 +1028,8 @@ static void search_pu_inter_ref(const encoder_state_t * const state,
} }
} }
#if SEARCH_MV_FULL_RADIUS
temp_cost += search_mv_full(depth, frame, ref_pic, &orig, &mv, mv_cand, merge_cand, num_cand, ref_idx, &temp_bitcost);
#else
switch (state->encoder_control->cfg->ime_algorithm) { switch (state->encoder_control->cfg->ime_algorithm) {
case KVZ_IME_TZ: case KVZ_IME_TZ:
// TODO: Make tz search work with non-square blocks.
temp_cost += tz_search(state, temp_cost += tz_search(state,
width, height, width, height,
frame->source, frame->source,
@ -1042,6 +1043,20 @@ static void search_pu_inter_ref(const encoder_state_t * const state,
&temp_bitcost); &temp_bitcost);
break; break;
case KVZ_IME_FULL:
temp_cost += search_mv_full(state,
width, height,
frame->source,
ref_image,
&orig,
&mv,
mv_cand,
merge_cand,
num_cand,
ref_idx,
&temp_bitcost);
break;
default: default:
temp_cost += hexagon_search(state, temp_cost += hexagon_search(state,
width, height, width, height,
@ -1055,8 +1070,8 @@ static void search_pu_inter_ref(const encoder_state_t * const state,
ref_idx, ref_idx,
&temp_bitcost); &temp_bitcost);
break; break;
} }
#endif
if (state->encoder_control->cfg->fme_level > 0) { if (state->encoder_control->cfg->fme_level > 0) {
temp_cost = search_frac(state, temp_cost = search_frac(state,
width, height, width, height,