simplify the Histogram struct, to only store max_value and last_nz

we don't need to store the whole distribution in order to compute the alpha

Later, we can incorporate the max_value / last_non_zero bookkeeping
in SSE2 directly.

Change-Id: I748ccea4ac17965d7afcab91845ef01be3aa3e15
This commit is contained in:
Pascal Massimino
2014-12-10 10:44:57 +01:00
parent 37e395fd1c
commit bad775715a
6 changed files with 59 additions and 33 deletions

View File

@ -111,28 +111,28 @@ static int FinalAlphaValue(int alpha) {
}
static int GetAlpha(const VP8Histogram* const histo) {
int max_value = 0, last_non_zero = 1;
int k;
int alpha;
for (k = 0; k <= MAX_COEFF_THRESH; ++k) {
const int value = histo->distribution[k];
if (value > 0) {
if (value > max_value) max_value = value;
last_non_zero = k;
}
}
// 'alpha' will later be clipped to [0..MAX_ALPHA] range, clamping outer
// values which happen to be mostly noise. This leaves the maximum precision
// for handling the useful small values which contribute most.
alpha = (max_value > 1) ? ALPHA_SCALE * last_non_zero / max_value : 0;
const int max_value = histo->max_value;
const int last_non_zero = histo->last_non_zero;
const int alpha =
(max_value > 1) ? ALPHA_SCALE * last_non_zero / max_value : 0;
return alpha;
}
static void InitHistogram(VP8Histogram* const histo) {
histo->max_value = 0;
histo->last_non_zero = 1;
}
static void MergeHistograms(const VP8Histogram* const in,
VP8Histogram* const out) {
int i;
for (i = 0; i <= MAX_COEFF_THRESH; ++i) {
out->distribution[i] += in->distribution[i];
if (in->max_value > out->max_value) {
out->max_value = in->max_value;
}
if (in->last_non_zero > out->last_non_zero) {
out->last_non_zero = in->last_non_zero;
}
}
@ -245,9 +245,10 @@ static int MBAnalyzeBestIntra16Mode(VP8EncIterator* const it) {
VP8MakeLuma16Preds(it);
for (mode = 0; mode < max_mode; ++mode) {
VP8Histogram histo = { { 0 } };
VP8Histogram histo;
int alpha;
InitHistogram(&histo);
VP8CollectHistogram(it->yuv_in_ + Y_OFF,
it->yuv_p_ + VP8I16ModeOffsets[mode],
0, 16, &histo);
@ -266,8 +267,9 @@ static int MBAnalyzeBestIntra4Mode(VP8EncIterator* const it,
uint8_t modes[16];
const int max_mode = MAX_INTRA4_MODE;
int i4_alpha;
VP8Histogram total_histo = { { 0 } };
VP8Histogram total_histo;
int cur_histo = 0;
InitHistogram(&total_histo);
VP8IteratorStartI4(it);
do {
@ -280,7 +282,7 @@ static int MBAnalyzeBestIntra4Mode(VP8EncIterator* const it,
for (mode = 0; mode < max_mode; ++mode) {
int alpha;
memset(&histos[cur_histo], 0, sizeof(histos[cur_histo]));
InitHistogram(&histos[cur_histo]);
VP8CollectHistogram(src, it->yuv_p_ + VP8I4ModeOffsets[mode],
0, 1, &histos[cur_histo]);
alpha = GetAlpha(&histos[cur_histo]);
@ -311,8 +313,9 @@ static int MBAnalyzeBestUVMode(VP8EncIterator* const it) {
VP8MakeChroma8Preds(it);
for (mode = 0; mode < max_mode; ++mode) {
VP8Histogram histo = { { 0 } };
VP8Histogram histo;
int alpha;
InitHistogram(&histo);
VP8CollectHistogram(it->yuv_in_ + U_OFF,
it->yuv_p_ + VP8UVModeOffsets[mode],
16, 16 + 4 + 4, &histo);

View File

@ -141,14 +141,6 @@ static WEBP_INLINE int QUANTDIV(uint32_t n, uint32_t iQ, uint32_t B) {
return (int)((n * iQ + B) >> QFIX);
}
// size of histogram used by CollectHistogram.
#define MAX_COEFF_THRESH 31
typedef struct VP8Histogram VP8Histogram;
struct VP8Histogram {
// TODO(skal): we only need to store the max_value and last_non_zero actually.
int distribution[MAX_COEFF_THRESH + 1];
};
// Uncomment the following to remove token-buffer code:
// #define DISABLE_TOKEN_BUFFER