From 5f1caf2987f3b97b8c905da6d8b0970b357a13ff Mon Sep 17 00:00:00 2001 From: Vincent Rabaud Date: Thu, 22 Sep 2016 14:03:25 +0200 Subject: [PATCH] Small LZ77 speedups. The most common conditions are re-ordered and cached. iter_min was recently introduced to make sure enough iterations are made in cases where there are many matches (mostly uniform regions). Now that those are properly analyzed, it becomes useless. Change-Id: Id3010ee4ec66b84d602fcb926f91eb9155ad27f4 --- src/enc/backward_references.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/enc/backward_references.c b/src/enc/backward_references.c index 9993b517..56268860 100644 --- a/src/enc/backward_references.c +++ b/src/enc/backward_references.c @@ -247,7 +247,6 @@ int VP8LHashChainFill(VP8LHashChain* const p, int quality, int low_effort) { const int size = xsize * ysize; const int iter_max = GetMaxItersForQuality(quality); - const int iter_min = iter_max - quality / 10; const uint32_t window_size = GetWindowSizeForHashChain(quality, xsize); int pos; int argb_comp; @@ -331,6 +330,7 @@ int VP8LHashChainFill(VP8LHashChain* const p, int quality, int iter = iter_max; int best_length = 0; uint32_t best_distance = 0; + uint32_t best_argb; const int min_pos = (base_position > window_size) ? base_position - window_size : 0; const int length_max = (max_len < 256) ? max_len : 256; @@ -360,26 +360,21 @@ int VP8LHashChainFill(VP8LHashChain* const p, int quality, // Skip the for loop if we already have the maximum. if (best_length == MAX_LENGTH) pos = min_pos - 1; } + best_argb = argb_start[best_length]; - for (; pos >= min_pos; pos = chain[pos]) { + for (; pos >= min_pos && --iter; pos = chain[pos]) { int curr_length; - if (--iter < 0) { - break; - } assert(base_position > (uint32_t)pos); - curr_length = - FindMatchLength(argb + pos, argb_start, best_length, max_len); + if (argb[pos + best_length] != best_argb) continue; + + curr_length = VP8LVectorMismatch(argb + pos, argb_start, max_len); if (best_length < curr_length) { best_length = curr_length; best_distance = base_position - pos; - // Stop if we have reached the maximum length. Otherwise, make sure - // we have executed a minimum number of iterations depending on the - // quality. - if ((best_length == MAX_LENGTH) || - (curr_length >= length_max && iter < iter_min)) { - break; - } + best_argb = argb_start[best_length]; + // Stop if we have reached a good enough length. + if (best_length >= length_max) break; } } // We have the best match but in case the two intervals continue matching