Do a binary search to get the optimum cache bits.
This speeds up the lossless encoder by a bit (1-2%), without impacting the compression density. Change-Id: Ied6fb38fab58eef9ded078697e0463fe7c560b26
This commit is contained in:
parent
24ca3678f9
commit
5f0cfa80ff
@ -12,7 +12,6 @@
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "./backward_references.h"
|
#include "./backward_references.h"
|
||||||
#include "./histogram.h"
|
#include "./histogram.h"
|
||||||
@ -26,6 +25,8 @@
|
|||||||
#define HASH_SIZE (1 << HASH_BITS)
|
#define HASH_SIZE (1 << HASH_BITS)
|
||||||
#define HASH_MULTIPLIER (0xc6a4a7935bd1e995ULL)
|
#define HASH_MULTIPLIER (0xc6a4a7935bd1e995ULL)
|
||||||
|
|
||||||
|
#define MAX_ENTROPY (1e30f)
|
||||||
|
|
||||||
// 1M window (4M bytes) minus 120 special codes for short distances.
|
// 1M window (4M bytes) minus 120 special codes for short distances.
|
||||||
#define WINDOW_SIZE ((1 << 20) - 120)
|
#define WINDOW_SIZE ((1 << 20) - 120)
|
||||||
|
|
||||||
@ -833,7 +834,7 @@ static double ComputeCacheEntropy(const uint32_t* const argb,
|
|||||||
|
|
||||||
if (use_color_cache) {
|
if (use_color_cache) {
|
||||||
cc_init = VP8LColorCacheInit(&hashers, cache_bits);
|
cc_init = VP8LColorCacheInit(&hashers, cache_bits);
|
||||||
if (!cc_init) return 1e99;
|
if (!cc_init) return MAX_ENTROPY;
|
||||||
}
|
}
|
||||||
|
|
||||||
VP8LHistogramInit(&histo, cache_bits);
|
VP8LHistogramInit(&histo, cache_bits);
|
||||||
@ -873,27 +874,38 @@ int VP8LCalculateEstimateForCacheSize(const uint32_t* const argb,
|
|||||||
int xsize, int ysize, int quality,
|
int xsize, int ysize, int quality,
|
||||||
int* const best_cache_bits) {
|
int* const best_cache_bits) {
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
int cache_bits;
|
int eval_low = 1;
|
||||||
// Number of tries to get optimal cache-bits after finding a local minima.
|
int eval_high = 1;
|
||||||
const int max_tries_after_min = 3 + (quality >> 4);
|
double entropy_low = MAX_ENTROPY;
|
||||||
int num_tries_after_min = 0;
|
double entropy_high = MAX_ENTROPY;
|
||||||
double lowest_entropy = 1e99;
|
int cache_bits_low = 0;
|
||||||
|
int cache_bits_high = MAX_COLOR_CACHE_BITS;
|
||||||
VP8LBackwardRefs refs;
|
VP8LBackwardRefs refs;
|
||||||
|
|
||||||
if (!VP8LBackwardRefsAlloc(&refs, xsize * ysize) ||
|
if (!VP8LBackwardRefsAlloc(&refs, xsize * ysize) ||
|
||||||
!BackwardReferencesHashChain(xsize, ysize, argb, 0, quality, &refs)) {
|
!BackwardReferencesHashChain(xsize, ysize, argb, 0, quality, &refs)) {
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
// The entropy is generally lower for higher cache_bits. Start searching from
|
// Do a binary search to find the optimal entropy for cache_bits.
|
||||||
// the highest value and settle for a local minima.
|
while (cache_bits_high - cache_bits_low > 1) {
|
||||||
for (cache_bits = MAX_COLOR_CACHE_BITS;
|
if (eval_low) {
|
||||||
cache_bits >= 0 && num_tries_after_min < max_tries_after_min;
|
entropy_low =
|
||||||
--cache_bits, ++num_tries_after_min) {
|
ComputeCacheEntropy(argb, xsize, ysize, &refs, cache_bits_low);
|
||||||
const double cur_entropy = ComputeCacheEntropy(argb, xsize, ysize,
|
eval_low = 0;
|
||||||
&refs, cache_bits);
|
}
|
||||||
if (cur_entropy < lowest_entropy) {
|
if (eval_high) {
|
||||||
*best_cache_bits = cache_bits;
|
entropy_high =
|
||||||
lowest_entropy = cur_entropy;
|
ComputeCacheEntropy(argb, xsize, ysize, &refs, cache_bits_high);
|
||||||
num_tries_after_min = 0;
|
eval_high = 0;
|
||||||
|
}
|
||||||
|
if (entropy_high < entropy_low) {
|
||||||
|
*best_cache_bits = cache_bits_high;
|
||||||
|
cache_bits_low = (cache_bits_low + cache_bits_high) / 2;
|
||||||
|
eval_low = 1;
|
||||||
|
} else {
|
||||||
|
*best_cache_bits = cache_bits_low;
|
||||||
|
cache_bits_high = (cache_bits_low + cache_bits_high) / 2;
|
||||||
|
eval_high = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ok = 1;
|
ok = 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user