diff options
author | RĂ©mi Verschelde <rverschelde@gmail.com> | 2019-10-27 13:54:05 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-10-27 13:54:05 +0100 |
commit | 61785bcc7d49cc2c6f1a351ed591dbf31748625b (patch) | |
tree | d47cd77a94c7b96d9c2f3800f6304f2ee5663d34 /thirdparty/libwebp/src/enc/quant_enc.c | |
parent | 2751cea0d4ed0bf99d870067dc8114701083d485 (diff) | |
parent | 074d421dca94ec4ddadfbfa62268bda219bab46c (diff) |
Merge pull request #33109 from volzhs/libwebp-1.0.3
Update libwebp to 1.0.3
Diffstat (limited to 'thirdparty/libwebp/src/enc/quant_enc.c')
-rw-r--r-- | thirdparty/libwebp/src/enc/quant_enc.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/thirdparty/libwebp/src/enc/quant_enc.c b/thirdparty/libwebp/src/enc/quant_enc.c index 03c682e3ae..01eb565c7f 100644 --- a/thirdparty/libwebp/src/enc/quant_enc.c +++ b/thirdparty/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 } |