Tune BackwardReferencesLz77 for low_effort (m=0).

- Lower the threshold parameters for HashChainFindCopy.

For 1000 image PNG corpus (m=0), this change yields speedup of 15-20% at
lower quality range (0.25% drop in compression density) and about 10%
for higher quality range without any drop in the compression density.
Following is the compression stats (before/after) for method = 0:
         Before           After
         bpp/MPs          bpp/MPs
q=0      2.8615/18.000    2.8651/18.631
q=5      2.8615/18.216    2.8650/20.517
q=10     2.8572/18.070    2.8650/21.992
q=15     2.8519/18.371    2.8584/21.747
q=20     2.8454/18.975    2.8515/20.448
q=25     2.8230/8.531     2.8253/9.585
// Compression density remains same for q-range [30-100]
q=30     2.7310/7.706     2.7310/8.028
q=35     2.7253/6.855     2.7253/7.184
q=40     2.7231/6.364     2.7231/6.604
q=45     2.7216/5.844     2.7216/6.223
q=50     2.7196/5.210     2.7196/5.731
q=55     2.7208/4.766     2.7208/4.970
q=60     2.7195/4.495     2.7195/4.602
q=65     2.7185/4.024     2.7185/4.236
q=70     2.7174/3.699     2.7174/3.861
q=75     2.7164/3.449     2.7164/3.605
q=80     2.7161/3.222     2.7161/3.038
q=85     2.7153/2.919     2.7153/2.946
q=90     2.7145/2.766     2.7145/2.771
q=95     2.7124/2.548     2.7124/2.575
q=100    2.6873/2.253     2.6873/2.335

Change-Id: I0e17581fb71f6094032ad06c6203350bd502f9a1
This commit is contained in:
Vikas Arora 2014-12-22 17:00:30 +00:00 committed by James Zern
parent b0b973c39b
commit ea08466d34
3 changed files with 20 additions and 12 deletions

View File

@ -58,6 +58,8 @@ static int DistanceToPlaneCode(int xsize, int dist) {
return dist + 120; return dist + 120;
} }
// TODO(vikasa): Evaluate loading (and comparing) 32/64 bits for the inner while
// loop.
static WEBP_INLINE int FindMatchLength(const uint32_t* const array1, static WEBP_INLINE int FindMatchLength(const uint32_t* const array1,
const uint32_t* const array2, const uint32_t* const array2,
int best_len_match, int best_len_match,
@ -228,9 +230,13 @@ static void HashChainInsert(VP8LHashChain* const p,
} }
static void GetParamsForHashChainFindCopy( static void GetParamsForHashChainFindCopy(
int quality, int* iter_max, int* len_for_unit_dist) { int quality, int low_effort, int* iter_max, int* len_for_unit_dist) {
*iter_max = 8 + (quality * quality) / 40; *iter_max = 8 + (quality * quality) / 40;
*len_for_unit_dist = 32 + (96 * quality) / 100; *len_for_unit_dist = 32 + (96 * quality) / 100;
if (low_effort) {
*iter_max -= 2;
*len_for_unit_dist /= 4;
}
} }
static int GetWindowSizeForHashChain(int quality, int xsize) { static int GetWindowSizeForHashChain(int quality, int xsize) {
@ -370,8 +376,8 @@ static int BackwardReferencesRle(int xsize, int ysize,
} }
static int BackwardReferencesLz77(int xsize, int ysize, static int BackwardReferencesLz77(int xsize, int ysize,
const uint32_t* const argb, const uint32_t* const argb, int cache_bits,
int cache_bits, int quality, int quality, int low_effort,
VP8LHashChain* const hash_chain, VP8LHashChain* const hash_chain,
VP8LBackwardRefs* const refs) { VP8LBackwardRefs* const refs) {
int i; int i;
@ -382,7 +388,8 @@ static int BackwardReferencesLz77(int xsize, int ysize,
VP8LColorCache hashers; VP8LColorCache hashers;
int iter_max, len_for_unit_dist; int iter_max, len_for_unit_dist;
const int window_size = GetWindowSizeForHashChain(quality, xsize); const int window_size = GetWindowSizeForHashChain(quality, xsize);
GetParamsForHashChainFindCopy(quality, &iter_max, &len_for_unit_dist); GetParamsForHashChainFindCopy(quality, low_effort, &iter_max,
&len_for_unit_dist);
if (use_color_cache) { if (use_color_cache) {
cc_init = VP8LColorCacheInit(&hashers, cache_bits); cc_init = VP8LColorCacheInit(&hashers, cache_bits);
@ -402,7 +409,7 @@ static int BackwardReferencesLz77(int xsize, int ysize,
int len2 = 0; int len2 = 0;
int k; int k;
HashChainInsert(hash_chain, &argb[i], i); HashChainInsert(hash_chain, &argb[i], i);
if (len < (max_len >> 2)) { if ((len < (max_len >> 2)) && !low_effort) {
// Evaluate Alternative#2: Insert the pixel at 'i' as literal, and code // Evaluate Alternative#2: Insert the pixel at 'i' as literal, and code
// the pixels starting at 'i + 1' using backward reference. // the pixels starting at 'i + 1' using backward reference.
HashChainFindCopy(hash_chain, i + 1, xsize, argb, max_len - 1, HashChainFindCopy(hash_chain, i + 1, xsize, argb, max_len - 1,
@ -582,7 +589,7 @@ static int BackwardReferencesHashChainDistanceOnly(
const int min_distance_code = 2; const int min_distance_code = 2;
int iter_max, len_for_unit_dist; int iter_max, len_for_unit_dist;
const int window_size = GetWindowSizeForHashChain(quality, xsize); const int window_size = GetWindowSizeForHashChain(quality, xsize);
GetParamsForHashChainFindCopy(quality, &iter_max, &len_for_unit_dist); GetParamsForHashChainFindCopy(quality, 0, &iter_max, &len_for_unit_dist);
if (cost == NULL || cost_model == NULL) goto Error; if (cost == NULL || cost_model == NULL) goto Error;
@ -892,7 +899,7 @@ static int CalculateBestCacheSize(const uint32_t* const argb,
// Local color cache is disabled. // Local color cache is disabled.
return 1; return 1;
} }
if (!BackwardReferencesLz77(xsize, ysize, argb, cache_bits_low, quality, if (!BackwardReferencesLz77(xsize, ysize, argb, cache_bits_low, quality, 0,
hash_chain, refs)) { hash_chain, refs)) {
return 0; return 0;
} }
@ -961,7 +968,7 @@ static int BackwardRefsWithLocalCache(const uint32_t* const argb,
VP8LBackwardRefs* VP8LGetBackwardReferences( VP8LBackwardRefs* VP8LGetBackwardReferences(
int width, int height, const uint32_t* const argb, int quality, int width, int height, const uint32_t* const argb, int quality,
int* cache_bits, VP8LHashChain* const hash_chain, int low_effort, int* cache_bits, VP8LHashChain* const hash_chain,
VP8LBackwardRefs refs_array[2]) { VP8LBackwardRefs refs_array[2]) {
int lz77_is_useful; int lz77_is_useful;
int lz77_computed; int lz77_computed;
@ -985,7 +992,7 @@ VP8LBackwardRefs* VP8LGetBackwardReferences(
} }
} else { } else {
if (!BackwardReferencesLz77(width, height, argb, *cache_bits, quality, if (!BackwardReferencesLz77(width, height, argb, *cache_bits, quality,
hash_chain, refs_lz77)) { low_effort, hash_chain, refs_lz77)) {
goto Error; goto Error;
} }
} }

View File

@ -192,7 +192,7 @@ static WEBP_INLINE void VP8LRefsCursorNext(VP8LRefsCursor* const c) {
// refs[0] or refs[1]. // refs[0] or refs[1].
VP8LBackwardRefs* VP8LGetBackwardReferences( VP8LBackwardRefs* VP8LGetBackwardReferences(
int width, int height, const uint32_t* const argb, int quality, int width, int height, const uint32_t* const argb, int quality,
int* cache_bits, VP8LHashChain* const hash_chain, int low_effort, int* cache_bits, VP8LHashChain* const hash_chain,
VP8LBackwardRefs refs[2]); VP8LBackwardRefs refs[2]);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -685,7 +685,7 @@ static WebPEncodingError EncodeImageNoHuffman(VP8LBitWriter* const bw,
} }
// Calculate backward references from ARGB image. // Calculate backward references from ARGB image.
refs = VP8LGetBackwardReferences(width, height, argb, quality, &cache_bits, refs = VP8LGetBackwardReferences(width, height, argb, quality, 0, &cache_bits,
hash_chain, refs_array); hash_chain, refs_array);
if (refs == NULL) { if (refs == NULL) {
err = VP8_ENC_ERROR_OUT_OF_MEMORY; err = VP8_ENC_ERROR_OUT_OF_MEMORY;
@ -785,7 +785,8 @@ static WebPEncodingError EncodeImageInternal(VP8LBitWriter* const bw,
// of refs_array[0] or refs_array[1]. // of refs_array[0] or refs_array[1].
// Calculate backward references from ARGB image. // Calculate backward references from ARGB image.
best_refs = VP8LGetBackwardReferences(width, height, argb, quality, best_refs = VP8LGetBackwardReferences(width, height, argb, quality,
cache_bits, hash_chain, refs_array); low_effort, cache_bits, hash_chain,
refs_array);
if (best_refs == NULL || !VP8LBackwardRefsCopy(best_refs, &refs)) { if (best_refs == NULL || !VP8LBackwardRefsCopy(best_refs, &refs)) {
err = VP8_ENC_ERROR_OUT_OF_MEMORY; err = VP8_ENC_ERROR_OUT_OF_MEMORY;
goto Error; goto Error;