summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/libwebp/src/enc/quant_enc.c
diff options
context:
space:
mode:
authorAndré Klitzing <aklitzing@gmail.com>2019-07-19 11:48:50 +0200
committerAndré Klitzing <aklitzing@gmail.com>2019-07-22 13:37:27 +0200
commitd4861c2a836f323e1c4694bf7830e69ef845b8ce (patch)
tree703fbdb0483211688efc93895fcfe1e9be32fc1f /src/3rdparty/libwebp/src/enc/quant_enc.c
parent7bdf0823b64e53a90f7a54151afada3aaceb7ba1 (diff)
Update bundled libwebp to version 1.0.3
[ChangeLog][Third-Party Code] Update bundled libwebp to version 1.0.3 Change-Id: I7aef89e209923af0e516024c26ebce4a8158d4d1 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io> Reviewed-by: Liang Qi <liang.qi@qt.io>
Diffstat (limited to 'src/3rdparty/libwebp/src/enc/quant_enc.c')
-rw-r--r--src/3rdparty/libwebp/src/enc/quant_enc.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/src/3rdparty/libwebp/src/enc/quant_enc.c b/src/3rdparty/libwebp/src/enc/quant_enc.c
index 03c682e..01eb565 100644
--- a/src/3rdparty/libwebp/src/enc/quant_enc.c
+++ b/src/3rdparty/libwebp/src/enc/quant_enc.c
@@ -33,7 +33,7 @@
// number of non-zero coeffs below which we consider the block very flat
// (and apply a penalty to complex predictions)
-#define FLATNESS_LIMIT_I16 10 // I16 mode
+#define FLATNESS_LIMIT_I16 0 // I16 mode (special case)
#define FLATNESS_LIMIT_I4 3 // I4 mode
#define FLATNESS_LIMIT_UV 2 // UV mode
#define FLATNESS_PENALTY 140 // roughly ~1bit per block
@@ -988,6 +988,7 @@ static void PickBestIntra16(VP8EncIterator* const it, VP8ModeScore* rd) {
VP8ModeScore* rd_cur = &rd_tmp;
VP8ModeScore* rd_best = rd;
int mode;
+ int is_flat = IsFlatSource16(it->yuv_in_ + Y_OFF_ENC);
rd->mode_i16 = -1;
for (mode = 0; mode < NUM_PRED_MODES; ++mode) {
@@ -1003,10 +1004,14 @@ static void PickBestIntra16(VP8EncIterator* const it, VP8ModeScore* rd) {
tlambda ? MULT_8B(tlambda, VP8TDisto16x16(src, tmp_dst, kWeightY)) : 0;
rd_cur->H = VP8FixedCostsI16[mode];
rd_cur->R = VP8GetCostLuma16(it, rd_cur);
- if (mode > 0 &&
- IsFlat(rd_cur->y_ac_levels[0], kNumBlocks, FLATNESS_LIMIT_I16)) {
- // penalty to avoid flat area to be mispredicted by complex mode
- rd_cur->R += FLATNESS_PENALTY * kNumBlocks;
+ if (is_flat) {
+ // refine the first impression (which was in pixel space)
+ is_flat = IsFlat(rd_cur->y_ac_levels[0], kNumBlocks, FLATNESS_LIMIT_I16);
+ if (is_flat) {
+ // Block is very flat. We put emphasis on the distortion being very low!
+ rd_cur->D *= 2;
+ rd_cur->SD *= 2;
+ }
}
// Since we always examine Intra16 first, we can overwrite *rd directly.
@@ -1087,7 +1092,8 @@ static int PickBestIntra4(VP8EncIterator* const it, VP8ModeScore* const rd) {
: 0;
rd_tmp.H = mode_costs[mode];
- // Add flatness penalty
+ // Add flatness penalty, to avoid flat area to be mispredicted
+ // by a complex mode.
if (mode > 0 && IsFlat(tmp_levels, kNumBlocks, FLATNESS_LIMIT_I4)) {
rd_tmp.R = FLATNESS_PENALTY * kNumBlocks;
} else {
@@ -1242,11 +1248,19 @@ static void RefineUsingDistortion(VP8EncIterator* const it,
if (mode > 0 && VP8FixedCostsI16[mode] > bit_limit) {
continue;
}
+
if (score < best_score) {
best_mode = mode;
best_score = score;
}
}
+ if (it->x_ == 0 || it->y_ == 0) {
+ // avoid starting a checkerboard resonance from the border. See bug #432.
+ if (IsFlatSource16(src)) {
+ best_mode = (it->x_ == 0) ? 0 : 2;
+ try_both_modes = 0; // stick to i16
+ }
+ }
VP8SetIntra16Mode(it, best_mode);
// we'll reconstruct later, if i16 mode actually gets selected
}