mirror of
https://github.com/webmproject/libwebp.git
synced 2025-01-27 15:12:54 +01:00
Merge "simplify the Histogram struct, to only store max_value and last_nz"
This commit is contained in:
commit
8ed9c00d5e
@ -151,13 +151,22 @@ typedef int (*VP8QuantizeBlockWHT)(int16_t in[16], int16_t out[16],
|
|||||||
const struct VP8Matrix* const mtx);
|
const struct VP8Matrix* const mtx);
|
||||||
extern VP8QuantizeBlockWHT VP8EncQuantizeBlockWHT;
|
extern VP8QuantizeBlockWHT VP8EncQuantizeBlockWHT;
|
||||||
|
|
||||||
// Collect histogram for susceptibility calculation and accumulate in histo[].
|
extern const int VP8DspScan[16 + 4 + 4];
|
||||||
struct VP8Histogram;
|
|
||||||
|
// Collect histogram for susceptibility calculation.
|
||||||
|
#define MAX_COEFF_THRESH 31 // size of histogram used by CollectHistogram.
|
||||||
|
typedef struct {
|
||||||
|
// We only need to store max_value and last_non_zero, not the distribution.
|
||||||
|
int max_value;
|
||||||
|
int last_non_zero;
|
||||||
|
} VP8Histogram;
|
||||||
typedef void (*VP8CHisto)(const uint8_t* ref, const uint8_t* pred,
|
typedef void (*VP8CHisto)(const uint8_t* ref, const uint8_t* pred,
|
||||||
int start_block, int end_block,
|
int start_block, int end_block,
|
||||||
struct VP8Histogram* const histo);
|
VP8Histogram* const histo);
|
||||||
extern const int VP8DspScan[16 + 4 + 4];
|
|
||||||
extern VP8CHisto VP8CollectHistogram;
|
extern VP8CHisto VP8CollectHistogram;
|
||||||
|
// General-purpose util function to help VP8CollectHistogram().
|
||||||
|
void VP8LSetHistogramData(const int distribution[MAX_COEFF_THRESH + 1],
|
||||||
|
VP8Histogram* const histo);
|
||||||
|
|
||||||
// must be called before using any of the above
|
// must be called before using any of the above
|
||||||
WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspInit(void);
|
WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspInit(void);
|
||||||
|
@ -40,10 +40,27 @@ const int VP8DspScan[16 + 4 + 4] = {
|
|||||||
8 + 0 * BPS, 12 + 0 * BPS, 8 + 4 * BPS, 12 + 4 * BPS // V
|
8 + 0 * BPS, 12 + 0 * BPS, 8 + 4 * BPS, 12 + 4 * BPS // V
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// general-purpose util function
|
||||||
|
void VP8LSetHistogramData(const int distribution[MAX_COEFF_THRESH + 1],
|
||||||
|
VP8Histogram* const histo) {
|
||||||
|
int max_value = 0, last_non_zero = 1;
|
||||||
|
int k;
|
||||||
|
for (k = 0; k <= MAX_COEFF_THRESH; ++k) {
|
||||||
|
const int value = distribution[k];
|
||||||
|
if (value > 0) {
|
||||||
|
if (value > max_value) max_value = value;
|
||||||
|
last_non_zero = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
histo->max_value = max_value;
|
||||||
|
histo->last_non_zero = last_non_zero;
|
||||||
|
}
|
||||||
|
|
||||||
static void CollectHistogram(const uint8_t* ref, const uint8_t* pred,
|
static void CollectHistogram(const uint8_t* ref, const uint8_t* pred,
|
||||||
int start_block, int end_block,
|
int start_block, int end_block,
|
||||||
VP8Histogram* const histo) {
|
VP8Histogram* const histo) {
|
||||||
int j;
|
int j;
|
||||||
|
int distribution[MAX_COEFF_THRESH + 1] = { 0 };
|
||||||
for (j = start_block; j < end_block; ++j) {
|
for (j = start_block; j < end_block; ++j) {
|
||||||
int k;
|
int k;
|
||||||
int16_t out[16];
|
int16_t out[16];
|
||||||
@ -54,9 +71,10 @@ static void CollectHistogram(const uint8_t* ref, const uint8_t* pred,
|
|||||||
for (k = 0; k < 16; ++k) {
|
for (k = 0; k < 16; ++k) {
|
||||||
const int v = abs(out[k]) >> 3; // TODO(skal): add rounding?
|
const int v = abs(out[k]) >> 3; // TODO(skal): add rounding?
|
||||||
const int clipped_value = clip_max(v, MAX_COEFF_THRESH);
|
const int clipped_value = clip_max(v, MAX_COEFF_THRESH);
|
||||||
histo->distribution[clipped_value]++;
|
++distribution[clipped_value];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
VP8LSetHistogramData(distribution, histo);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -727,6 +727,7 @@ static void CollectHistogram(const uint8_t* ref, const uint8_t* pred,
|
|||||||
VP8Histogram* const histo) {
|
VP8Histogram* const histo) {
|
||||||
const uint16x8_t max_coeff_thresh = vdupq_n_u16(MAX_COEFF_THRESH);
|
const uint16x8_t max_coeff_thresh = vdupq_n_u16(MAX_COEFF_THRESH);
|
||||||
int j;
|
int j;
|
||||||
|
int distribution[MAX_COEFF_THRESH + 1] = { 0 };
|
||||||
for (j = start_block; j < end_block; ++j) {
|
for (j = start_block; j < end_block; ++j) {
|
||||||
int16_t out[16];
|
int16_t out[16];
|
||||||
FTransform(ref + VP8DspScan[j], pred + VP8DspScan[j], out);
|
FTransform(ref + VP8DspScan[j], pred + VP8DspScan[j], out);
|
||||||
@ -744,10 +745,11 @@ static void CollectHistogram(const uint8_t* ref, const uint8_t* pred,
|
|||||||
vst1q_s16(out + 8, vreinterpretq_s16_u16(b3));
|
vst1q_s16(out + 8, vreinterpretq_s16_u16(b3));
|
||||||
// Convert coefficients to bin.
|
// Convert coefficients to bin.
|
||||||
for (k = 0; k < 16; ++k) {
|
for (k = 0; k < 16; ++k) {
|
||||||
histo->distribution[out[k]]++;
|
++distribution[out[k]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
VP8LSetHistogramData(distribution, histo);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -59,6 +59,7 @@ static void CollectHistogram(const uint8_t* ref, const uint8_t* pred,
|
|||||||
VP8Histogram* const histo) {
|
VP8Histogram* const histo) {
|
||||||
const __m128i max_coeff_thresh = _mm_set1_epi16(MAX_COEFF_THRESH);
|
const __m128i max_coeff_thresh = _mm_set1_epi16(MAX_COEFF_THRESH);
|
||||||
int j;
|
int j;
|
||||||
|
int distribution[MAX_COEFF_THRESH + 1] = { 0 };
|
||||||
for (j = start_block; j < end_block; ++j) {
|
for (j = start_block; j < end_block; ++j) {
|
||||||
int16_t out[16];
|
int16_t out[16];
|
||||||
int k;
|
int k;
|
||||||
@ -91,9 +92,10 @@ static void CollectHistogram(const uint8_t* ref, const uint8_t* pred,
|
|||||||
|
|
||||||
// Convert coefficients to bin.
|
// Convert coefficients to bin.
|
||||||
for (k = 0; k < 16; ++k) {
|
for (k = 0; k < 16; ++k) {
|
||||||
histo->distribution[out[k]]++;
|
++distribution[out[k]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
VP8LSetHistogramData(distribution, histo);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -111,28 +111,28 @@ static int FinalAlphaValue(int alpha) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int GetAlpha(const VP8Histogram* const histo) {
|
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
|
// 'alpha' will later be clipped to [0..MAX_ALPHA] range, clamping outer
|
||||||
// values which happen to be mostly noise. This leaves the maximum precision
|
// values which happen to be mostly noise. This leaves the maximum precision
|
||||||
// for handling the useful small values which contribute most.
|
// 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;
|
return alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void InitHistogram(VP8Histogram* const histo) {
|
||||||
|
histo->max_value = 0;
|
||||||
|
histo->last_non_zero = 1;
|
||||||
|
}
|
||||||
|
|
||||||
static void MergeHistograms(const VP8Histogram* const in,
|
static void MergeHistograms(const VP8Histogram* const in,
|
||||||
VP8Histogram* const out) {
|
VP8Histogram* const out) {
|
||||||
int i;
|
if (in->max_value > out->max_value) {
|
||||||
for (i = 0; i <= MAX_COEFF_THRESH; ++i) {
|
out->max_value = in->max_value;
|
||||||
out->distribution[i] += in->distribution[i];
|
}
|
||||||
|
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);
|
VP8MakeLuma16Preds(it);
|
||||||
for (mode = 0; mode < max_mode; ++mode) {
|
for (mode = 0; mode < max_mode; ++mode) {
|
||||||
VP8Histogram histo = { { 0 } };
|
VP8Histogram histo;
|
||||||
int alpha;
|
int alpha;
|
||||||
|
|
||||||
|
InitHistogram(&histo);
|
||||||
VP8CollectHistogram(it->yuv_in_ + Y_OFF,
|
VP8CollectHistogram(it->yuv_in_ + Y_OFF,
|
||||||
it->yuv_p_ + VP8I16ModeOffsets[mode],
|
it->yuv_p_ + VP8I16ModeOffsets[mode],
|
||||||
0, 16, &histo);
|
0, 16, &histo);
|
||||||
@ -266,8 +267,9 @@ static int MBAnalyzeBestIntra4Mode(VP8EncIterator* const it,
|
|||||||
uint8_t modes[16];
|
uint8_t modes[16];
|
||||||
const int max_mode = MAX_INTRA4_MODE;
|
const int max_mode = MAX_INTRA4_MODE;
|
||||||
int i4_alpha;
|
int i4_alpha;
|
||||||
VP8Histogram total_histo = { { 0 } };
|
VP8Histogram total_histo;
|
||||||
int cur_histo = 0;
|
int cur_histo = 0;
|
||||||
|
InitHistogram(&total_histo);
|
||||||
|
|
||||||
VP8IteratorStartI4(it);
|
VP8IteratorStartI4(it);
|
||||||
do {
|
do {
|
||||||
@ -280,7 +282,7 @@ static int MBAnalyzeBestIntra4Mode(VP8EncIterator* const it,
|
|||||||
for (mode = 0; mode < max_mode; ++mode) {
|
for (mode = 0; mode < max_mode; ++mode) {
|
||||||
int alpha;
|
int alpha;
|
||||||
|
|
||||||
memset(&histos[cur_histo], 0, sizeof(histos[cur_histo]));
|
InitHistogram(&histos[cur_histo]);
|
||||||
VP8CollectHistogram(src, it->yuv_p_ + VP8I4ModeOffsets[mode],
|
VP8CollectHistogram(src, it->yuv_p_ + VP8I4ModeOffsets[mode],
|
||||||
0, 1, &histos[cur_histo]);
|
0, 1, &histos[cur_histo]);
|
||||||
alpha = GetAlpha(&histos[cur_histo]);
|
alpha = GetAlpha(&histos[cur_histo]);
|
||||||
@ -311,8 +313,9 @@ static int MBAnalyzeBestUVMode(VP8EncIterator* const it) {
|
|||||||
|
|
||||||
VP8MakeChroma8Preds(it);
|
VP8MakeChroma8Preds(it);
|
||||||
for (mode = 0; mode < max_mode; ++mode) {
|
for (mode = 0; mode < max_mode; ++mode) {
|
||||||
VP8Histogram histo = { { 0 } };
|
VP8Histogram histo;
|
||||||
int alpha;
|
int alpha;
|
||||||
|
InitHistogram(&histo);
|
||||||
VP8CollectHistogram(it->yuv_in_ + U_OFF,
|
VP8CollectHistogram(it->yuv_in_ + U_OFF,
|
||||||
it->yuv_p_ + VP8UVModeOffsets[mode],
|
it->yuv_p_ + VP8UVModeOffsets[mode],
|
||||||
16, 16 + 4 + 4, &histo);
|
16, 16 + 4 + 4, &histo);
|
||||||
|
@ -141,14 +141,6 @@ static WEBP_INLINE int QUANTDIV(uint32_t n, uint32_t iQ, uint32_t B) {
|
|||||||
return (int)((n * iQ + B) >> QFIX);
|
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:
|
// Uncomment the following to remove token-buffer code:
|
||||||
// #define DISABLE_TOKEN_BUFFER
|
// #define DISABLE_TOKEN_BUFFER
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user