• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2011 Google Inc. All Rights Reserved.
2 //
3 // Use of this source code is governed by a BSD-style license
4 // that can be found in the COPYING file in the root of the source
5 // tree. An additional intellectual property rights grant can be found
6 // in the file PATENTS. All contributing project authors may
7 // be found in the AUTHORS file in the root of the source tree.
8 // -----------------------------------------------------------------------------
9 //
10 //   Quantization
11 //
12 // Author: Skal (pascal.massimino@gmail.com)
13 
14 #include <assert.h>
15 #include <math.h>
16 #include <stdlib.h>  // for abs()
17 
18 #include "src/dsp/quant.h"
19 #include "src/enc/vp8i_enc.h"
20 #include "src/enc/cost_enc.h"
21 
22 #define DO_TRELLIS_I4  1
23 #define DO_TRELLIS_I16 1   // not a huge gain, but ok at low bitrate.
24 #define DO_TRELLIS_UV  0   // disable trellis for UV. Risky. Not worth.
25 #define USE_TDISTO 1
26 
27 #define MID_ALPHA 64      // neutral value for susceptibility
28 #define MIN_ALPHA 30      // lowest usable value for susceptibility
29 #define MAX_ALPHA 100     // higher meaningful value for susceptibility
30 
31 #define SNS_TO_DQ 0.9     // Scaling constant between the sns value and the QP
32                           // power-law modulation. Must be strictly less than 1.
33 
34 // number of non-zero coeffs below which we consider the block very flat
35 // (and apply a penalty to complex predictions)
36 #define FLATNESS_LIMIT_I16 10      // I16 mode
37 #define FLATNESS_LIMIT_I4  3       // I4 mode
38 #define FLATNESS_LIMIT_UV  2       // UV mode
39 #define FLATNESS_PENALTY   140     // roughly ~1bit per block
40 
41 #define MULT_8B(a, b) (((a) * (b) + 128) >> 8)
42 
43 #define RD_DISTO_MULT      256  // distortion multiplier (equivalent of lambda)
44 
45 // #define DEBUG_BLOCK
46 
47 //------------------------------------------------------------------------------
48 
49 #if defined(DEBUG_BLOCK)
50 
51 #include <stdio.h>
52 #include <stdlib.h>
53 
PrintBlockInfo(const VP8EncIterator * const it,const VP8ModeScore * const rd)54 static void PrintBlockInfo(const VP8EncIterator* const it,
55                            const VP8ModeScore* const rd) {
56   int i, j;
57   const int is_i16 = (it->mb_->type_ == 1);
58   const uint8_t* const y_in = it->yuv_in_ + Y_OFF_ENC;
59   const uint8_t* const y_out = it->yuv_out_ + Y_OFF_ENC;
60   const uint8_t* const uv_in = it->yuv_in_ + U_OFF_ENC;
61   const uint8_t* const uv_out = it->yuv_out_ + U_OFF_ENC;
62   printf("SOURCE / OUTPUT / ABS DELTA\n");
63   for (j = 0; j < 16; ++j) {
64     for (i = 0; i < 16; ++i) printf("%3d ", y_in[i + j * BPS]);
65     printf("     ");
66     for (i = 0; i < 16; ++i) printf("%3d ", y_out[i + j * BPS]);
67     printf("     ");
68     for (i = 0; i < 16; ++i) {
69       printf("%1d ", abs(y_in[i + j * BPS] - y_out[i + j * BPS]));
70     }
71     printf("\n");
72   }
73   printf("\n");   // newline before the U/V block
74   for (j = 0; j < 8; ++j) {
75     for (i = 0; i < 8; ++i) printf("%3d ", uv_in[i + j * BPS]);
76     printf(" ");
77     for (i = 8; i < 16; ++i) printf("%3d ", uv_in[i + j * BPS]);
78     printf("    ");
79     for (i = 0; i < 8; ++i) printf("%3d ", uv_out[i + j * BPS]);
80     printf(" ");
81     for (i = 8; i < 16; ++i) printf("%3d ", uv_out[i + j * BPS]);
82     printf("   ");
83     for (i = 0; i < 8; ++i) {
84       printf("%1d ", abs(uv_out[i + j * BPS] - uv_in[i + j * BPS]));
85     }
86     printf(" ");
87     for (i = 8; i < 16; ++i) {
88       printf("%1d ", abs(uv_out[i + j * BPS] - uv_in[i + j * BPS]));
89     }
90     printf("\n");
91   }
92   printf("\nD:%d SD:%d R:%d H:%d nz:0x%x score:%d\n",
93     (int)rd->D, (int)rd->SD, (int)rd->R, (int)rd->H, (int)rd->nz,
94     (int)rd->score);
95   if (is_i16) {
96     printf("Mode: %d\n", rd->mode_i16);
97     printf("y_dc_levels:");
98     for (i = 0; i < 16; ++i) printf("%3d ", rd->y_dc_levels[i]);
99     printf("\n");
100   } else {
101     printf("Modes[16]: ");
102     for (i = 0; i < 16; ++i) printf("%d ", rd->modes_i4[i]);
103     printf("\n");
104   }
105   printf("y_ac_levels:\n");
106   for (j = 0; j < 16; ++j) {
107     for (i = is_i16 ? 1 : 0; i < 16; ++i) {
108       printf("%4d ", rd->y_ac_levels[j][i]);
109     }
110     printf("\n");
111   }
112   printf("\n");
113   printf("uv_levels (mode=%d):\n", rd->mode_uv);
114   for (j = 0; j < 8; ++j) {
115     for (i = 0; i < 16; ++i) {
116       printf("%4d ", rd->uv_levels[j][i]);
117     }
118     printf("\n");
119   }
120 }
121 
122 #endif   // DEBUG_BLOCK
123 
124 //------------------------------------------------------------------------------
125 
clip(int v,int m,int M)126 static WEBP_INLINE int clip(int v, int m, int M) {
127   return v < m ? m : v > M ? M : v;
128 }
129 
130 static const uint8_t kZigzag[16] = {
131   0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
132 };
133 
134 static const uint8_t kDcTable[128] = {
135   4,     5,   6,   7,   8,   9,  10,  10,
136   11,   12,  13,  14,  15,  16,  17,  17,
137   18,   19,  20,  20,  21,  21,  22,  22,
138   23,   23,  24,  25,  25,  26,  27,  28,
139   29,   30,  31,  32,  33,  34,  35,  36,
140   37,   37,  38,  39,  40,  41,  42,  43,
141   44,   45,  46,  46,  47,  48,  49,  50,
142   51,   52,  53,  54,  55,  56,  57,  58,
143   59,   60,  61,  62,  63,  64,  65,  66,
144   67,   68,  69,  70,  71,  72,  73,  74,
145   75,   76,  76,  77,  78,  79,  80,  81,
146   82,   83,  84,  85,  86,  87,  88,  89,
147   91,   93,  95,  96,  98, 100, 101, 102,
148   104, 106, 108, 110, 112, 114, 116, 118,
149   122, 124, 126, 128, 130, 132, 134, 136,
150   138, 140, 143, 145, 148, 151, 154, 157
151 };
152 
153 static const uint16_t kAcTable[128] = {
154   4,     5,   6,   7,   8,   9,  10,  11,
155   12,   13,  14,  15,  16,  17,  18,  19,
156   20,   21,  22,  23,  24,  25,  26,  27,
157   28,   29,  30,  31,  32,  33,  34,  35,
158   36,   37,  38,  39,  40,  41,  42,  43,
159   44,   45,  46,  47,  48,  49,  50,  51,
160   52,   53,  54,  55,  56,  57,  58,  60,
161   62,   64,  66,  68,  70,  72,  74,  76,
162   78,   80,  82,  84,  86,  88,  90,  92,
163   94,   96,  98, 100, 102, 104, 106, 108,
164   110, 112, 114, 116, 119, 122, 125, 128,
165   131, 134, 137, 140, 143, 146, 149, 152,
166   155, 158, 161, 164, 167, 170, 173, 177,
167   181, 185, 189, 193, 197, 201, 205, 209,
168   213, 217, 221, 225, 229, 234, 239, 245,
169   249, 254, 259, 264, 269, 274, 279, 284
170 };
171 
172 static const uint16_t kAcTable2[128] = {
173   8,     8,   9,  10,  12,  13,  15,  17,
174   18,   20,  21,  23,  24,  26,  27,  29,
175   31,   32,  34,  35,  37,  38,  40,  41,
176   43,   44,  46,  48,  49,  51,  52,  54,
177   55,   57,  58,  60,  62,  63,  65,  66,
178   68,   69,  71,  72,  74,  75,  77,  79,
179   80,   82,  83,  85,  86,  88,  89,  93,
180   96,   99, 102, 105, 108, 111, 114, 117,
181   120, 124, 127, 130, 133, 136, 139, 142,
182   145, 148, 151, 155, 158, 161, 164, 167,
183   170, 173, 176, 179, 184, 189, 193, 198,
184   203, 207, 212, 217, 221, 226, 230, 235,
185   240, 244, 249, 254, 258, 263, 268, 274,
186   280, 286, 292, 299, 305, 311, 317, 323,
187   330, 336, 342, 348, 354, 362, 370, 379,
188   385, 393, 401, 409, 416, 424, 432, 440
189 };
190 
191 static const uint8_t kBiasMatrices[3][2] = {  // [luma-ac,luma-dc,chroma][dc,ac]
192   { 96, 110 }, { 96, 108 }, { 110, 115 }
193 };
194 
195 // Sharpening by (slightly) raising the hi-frequency coeffs.
196 // Hack-ish but helpful for mid-bitrate range. Use with care.
197 #define SHARPEN_BITS 11  // number of descaling bits for sharpening bias
198 static const uint8_t kFreqSharpening[16] = {
199   0,  30, 60, 90,
200   30, 60, 90, 90,
201   60, 90, 90, 90,
202   90, 90, 90, 90
203 };
204 
205 //------------------------------------------------------------------------------
206 // Initialize quantization parameters in VP8Matrix
207 
208 // Returns the average quantizer
ExpandMatrix(VP8Matrix * const m,int type)209 static int ExpandMatrix(VP8Matrix* const m, int type) {
210   int i, sum;
211   for (i = 0; i < 2; ++i) {
212     const int is_ac_coeff = (i > 0);
213     const int bias = kBiasMatrices[type][is_ac_coeff];
214     m->iq_[i] = (1 << QFIX) / m->q_[i];
215     m->bias_[i] = BIAS(bias);
216     // zthresh_ is the exact value such that QUANTDIV(coeff, iQ, B) is:
217     //   * zero if coeff <= zthresh
218     //   * non-zero if coeff > zthresh
219     m->zthresh_[i] = ((1 << QFIX) - 1 - m->bias_[i]) / m->iq_[i];
220   }
221   for (i = 2; i < 16; ++i) {
222     m->q_[i] = m->q_[1];
223     m->iq_[i] = m->iq_[1];
224     m->bias_[i] = m->bias_[1];
225     m->zthresh_[i] = m->zthresh_[1];
226   }
227   for (sum = 0, i = 0; i < 16; ++i) {
228     if (type == 0) {  // we only use sharpening for AC luma coeffs
229       m->sharpen_[i] = (kFreqSharpening[i] * m->q_[i]) >> SHARPEN_BITS;
230     } else {
231       m->sharpen_[i] = 0;
232     }
233     sum += m->q_[i];
234   }
235   return (sum + 8) >> 4;
236 }
237 
CheckLambdaValue(int * const v)238 static void CheckLambdaValue(int* const v) { if (*v < 1) *v = 1; }
239 
SetupMatrices(VP8Encoder * enc)240 static void SetupMatrices(VP8Encoder* enc) {
241   int i;
242   const int tlambda_scale =
243     (enc->method_ >= 4) ? enc->config_->sns_strength
244                         : 0;
245   const int num_segments = enc->segment_hdr_.num_segments_;
246   for (i = 0; i < num_segments; ++i) {
247     VP8SegmentInfo* const m = &enc->dqm_[i];
248     const int q = m->quant_;
249     int q_i4, q_i16, q_uv;
250     m->y1_.q_[0] = kDcTable[clip(q + enc->dq_y1_dc_, 0, 127)];
251     m->y1_.q_[1] = kAcTable[clip(q,                  0, 127)];
252 
253     m->y2_.q_[0] = kDcTable[ clip(q + enc->dq_y2_dc_, 0, 127)] * 2;
254     m->y2_.q_[1] = kAcTable2[clip(q + enc->dq_y2_ac_, 0, 127)];
255 
256     m->uv_.q_[0] = kDcTable[clip(q + enc->dq_uv_dc_, 0, 117)];
257     m->uv_.q_[1] = kAcTable[clip(q + enc->dq_uv_ac_, 0, 127)];
258 
259     q_i4  = ExpandMatrix(&m->y1_, 0);
260     q_i16 = ExpandMatrix(&m->y2_, 1);
261     q_uv  = ExpandMatrix(&m->uv_, 2);
262 
263     m->lambda_i4_          = (3 * q_i4 * q_i4) >> 7;
264     m->lambda_i16_         = (3 * q_i16 * q_i16);
265     m->lambda_uv_          = (3 * q_uv * q_uv) >> 6;
266     m->lambda_mode_        = (1 * q_i4 * q_i4) >> 7;
267     m->lambda_trellis_i4_  = (7 * q_i4 * q_i4) >> 3;
268     m->lambda_trellis_i16_ = (q_i16 * q_i16) >> 2;
269     m->lambda_trellis_uv_  = (q_uv * q_uv) << 1;
270     m->tlambda_            = (tlambda_scale * q_i4) >> 5;
271 
272     // none of these constants should be < 1
273     CheckLambdaValue(&m->lambda_i4_);
274     CheckLambdaValue(&m->lambda_i16_);
275     CheckLambdaValue(&m->lambda_uv_);
276     CheckLambdaValue(&m->lambda_mode_);
277     CheckLambdaValue(&m->lambda_trellis_i4_);
278     CheckLambdaValue(&m->lambda_trellis_i16_);
279     CheckLambdaValue(&m->lambda_trellis_uv_);
280     CheckLambdaValue(&m->tlambda_);
281 
282     m->min_disto_ = 20 * m->y1_.q_[0];   // quantization-aware min disto
283     m->max_edge_  = 0;
284 
285     m->i4_penalty_ = 1000 * q_i4 * q_i4;
286   }
287 }
288 
289 //------------------------------------------------------------------------------
290 // Initialize filtering parameters
291 
292 // Very small filter-strength values have close to no visual effect. So we can
293 // save a little decoding-CPU by turning filtering off for these.
294 #define FSTRENGTH_CUTOFF 2
295 
SetupFilterStrength(VP8Encoder * const enc)296 static void SetupFilterStrength(VP8Encoder* const enc) {
297   int i;
298   // level0 is in [0..500]. Using '-f 50' as filter_strength is mid-filtering.
299   const int level0 = 5 * enc->config_->filter_strength;
300   for (i = 0; i < NUM_MB_SEGMENTS; ++i) {
301     VP8SegmentInfo* const m = &enc->dqm_[i];
302     // We focus on the quantization of AC coeffs.
303     const int qstep = kAcTable[clip(m->quant_, 0, 127)] >> 2;
304     const int base_strength =
305         VP8FilterStrengthFromDelta(enc->filter_hdr_.sharpness_, qstep);
306     // Segments with lower complexity ('beta') will be less filtered.
307     const int f = base_strength * level0 / (256 + m->beta_);
308     m->fstrength_ = (f < FSTRENGTH_CUTOFF) ? 0 : (f > 63) ? 63 : f;
309   }
310   // We record the initial strength (mainly for the case of 1-segment only).
311   enc->filter_hdr_.level_ = enc->dqm_[0].fstrength_;
312   enc->filter_hdr_.simple_ = (enc->config_->filter_type == 0);
313   enc->filter_hdr_.sharpness_ = enc->config_->filter_sharpness;
314 }
315 
316 //------------------------------------------------------------------------------
317 
318 // Note: if you change the values below, remember that the max range
319 // allowed by the syntax for DQ_UV is [-16,16].
320 #define MAX_DQ_UV (6)
321 #define MIN_DQ_UV (-4)
322 
323 // We want to emulate jpeg-like behaviour where the expected "good" quality
324 // is around q=75. Internally, our "good" middle is around c=50. So we
325 // map accordingly using linear piece-wise function
QualityToCompression(double c)326 static double QualityToCompression(double c) {
327   const double linear_c = (c < 0.75) ? c * (2. / 3.) : 2. * c - 1.;
328   // The file size roughly scales as pow(quantizer, 3.). Actually, the
329   // exponent is somewhere between 2.8 and 3.2, but we're mostly interested
330   // in the mid-quant range. So we scale the compressibility inversely to
331   // this power-law: quant ~= compression ^ 1/3. This law holds well for
332   // low quant. Finer modeling for high-quant would make use of kAcTable[]
333   // more explicitly.
334   const double v = pow(linear_c, 1 / 3.);
335   return v;
336 }
337 
QualityToJPEGCompression(double c,double alpha)338 static double QualityToJPEGCompression(double c, double alpha) {
339   // We map the complexity 'alpha' and quality setting 'c' to a compression
340   // exponent empirically matched to the compression curve of libjpeg6b.
341   // On average, the WebP output size will be roughly similar to that of a
342   // JPEG file compressed with same quality factor.
343   const double amin = 0.30;
344   const double amax = 0.85;
345   const double exp_min = 0.4;
346   const double exp_max = 0.9;
347   const double slope = (exp_min - exp_max) / (amax - amin);
348   // Linearly interpolate 'expn' from exp_min to exp_max
349   // in the [amin, amax] range.
350   const double expn = (alpha > amax) ? exp_min
351                     : (alpha < amin) ? exp_max
352                     : exp_max + slope * (alpha - amin);
353   const double v = pow(c, expn);
354   return v;
355 }
356 
SegmentsAreEquivalent(const VP8SegmentInfo * const S1,const VP8SegmentInfo * const S2)357 static int SegmentsAreEquivalent(const VP8SegmentInfo* const S1,
358                                  const VP8SegmentInfo* const S2) {
359   return (S1->quant_ == S2->quant_) && (S1->fstrength_ == S2->fstrength_);
360 }
361 
SimplifySegments(VP8Encoder * const enc)362 static void SimplifySegments(VP8Encoder* const enc) {
363   int map[NUM_MB_SEGMENTS] = { 0, 1, 2, 3 };
364   // 'num_segments_' is previously validated and <= NUM_MB_SEGMENTS, but an
365   // explicit check is needed to avoid a spurious warning about 'i' exceeding
366   // array bounds of 'dqm_' with some compilers (noticed with gcc-4.9).
367   const int num_segments = (enc->segment_hdr_.num_segments_ < NUM_MB_SEGMENTS)
368                                ? enc->segment_hdr_.num_segments_
369                                : NUM_MB_SEGMENTS;
370   int num_final_segments = 1;
371   int s1, s2;
372   for (s1 = 1; s1 < num_segments; ++s1) {    // find similar segments
373     const VP8SegmentInfo* const S1 = &enc->dqm_[s1];
374     int found = 0;
375     // check if we already have similar segment
376     for (s2 = 0; s2 < num_final_segments; ++s2) {
377       const VP8SegmentInfo* const S2 = &enc->dqm_[s2];
378       if (SegmentsAreEquivalent(S1, S2)) {
379         found = 1;
380         break;
381       }
382     }
383     map[s1] = s2;
384     if (!found) {
385       if (num_final_segments != s1) {
386         enc->dqm_[num_final_segments] = enc->dqm_[s1];
387       }
388       ++num_final_segments;
389     }
390   }
391   if (num_final_segments < num_segments) {  // Remap
392     int i = enc->mb_w_ * enc->mb_h_;
393     while (i-- > 0) enc->mb_info_[i].segment_ = map[enc->mb_info_[i].segment_];
394     enc->segment_hdr_.num_segments_ = num_final_segments;
395     // Replicate the trailing segment infos (it's mostly cosmetics)
396     for (i = num_final_segments; i < num_segments; ++i) {
397       enc->dqm_[i] = enc->dqm_[num_final_segments - 1];
398     }
399   }
400 }
401 
VP8SetSegmentParams(VP8Encoder * const enc,float quality)402 void VP8SetSegmentParams(VP8Encoder* const enc, float quality) {
403   int i;
404   int dq_uv_ac, dq_uv_dc;
405   const int num_segments = enc->segment_hdr_.num_segments_;
406   const double amp = SNS_TO_DQ * enc->config_->sns_strength / 100. / 128.;
407   const double Q = quality / 100.;
408   const double c_base = enc->config_->emulate_jpeg_size ?
409       QualityToJPEGCompression(Q, enc->alpha_ / 255.) :
410       QualityToCompression(Q);
411   for (i = 0; i < num_segments; ++i) {
412     // We modulate the base coefficient to accommodate for the quantization
413     // susceptibility and allow denser segments to be quantized more.
414     const double expn = 1. - amp * enc->dqm_[i].alpha_;
415     const double c = pow(c_base, expn);
416     const int q = (int)(127. * (1. - c));
417     assert(expn > 0.);
418     enc->dqm_[i].quant_ = clip(q, 0, 127);
419   }
420 
421   // purely indicative in the bitstream (except for the 1-segment case)
422   enc->base_quant_ = enc->dqm_[0].quant_;
423 
424   // fill-in values for the unused segments (required by the syntax)
425   for (i = num_segments; i < NUM_MB_SEGMENTS; ++i) {
426     enc->dqm_[i].quant_ = enc->base_quant_;
427   }
428 
429   // uv_alpha_ is normally spread around ~60. The useful range is
430   // typically ~30 (quite bad) to ~100 (ok to decimate UV more).
431   // We map it to the safe maximal range of MAX/MIN_DQ_UV for dq_uv.
432   dq_uv_ac = (enc->uv_alpha_ - MID_ALPHA) * (MAX_DQ_UV - MIN_DQ_UV)
433                                           / (MAX_ALPHA - MIN_ALPHA);
434   // we rescale by the user-defined strength of adaptation
435   dq_uv_ac = dq_uv_ac * enc->config_->sns_strength / 100;
436   // and make it safe.
437   dq_uv_ac = clip(dq_uv_ac, MIN_DQ_UV, MAX_DQ_UV);
438   // We also boost the dc-uv-quant a little, based on sns-strength, since
439   // U/V channels are quite more reactive to high quants (flat DC-blocks
440   // tend to appear, and are unpleasant).
441   dq_uv_dc = -4 * enc->config_->sns_strength / 100;
442   dq_uv_dc = clip(dq_uv_dc, -15, 15);   // 4bit-signed max allowed
443 
444   enc->dq_y1_dc_ = 0;       // TODO(skal): dq-lum
445   enc->dq_y2_dc_ = 0;
446   enc->dq_y2_ac_ = 0;
447   enc->dq_uv_dc_ = dq_uv_dc;
448   enc->dq_uv_ac_ = dq_uv_ac;
449 
450   SetupFilterStrength(enc);   // initialize segments' filtering, eventually
451 
452   if (num_segments > 1) SimplifySegments(enc);
453 
454   SetupMatrices(enc);         // finalize quantization matrices
455 }
456 
457 //------------------------------------------------------------------------------
458 // Form the predictions in cache
459 
460 // Must be ordered using {DC_PRED, TM_PRED, V_PRED, H_PRED} as index
461 const uint16_t VP8I16ModeOffsets[4] = { I16DC16, I16TM16, I16VE16, I16HE16 };
462 const uint16_t VP8UVModeOffsets[4] = { C8DC8, C8TM8, C8VE8, C8HE8 };
463 
464 // Must be indexed using {B_DC_PRED -> B_HU_PRED} as index
465 const uint16_t VP8I4ModeOffsets[NUM_BMODES] = {
466   I4DC4, I4TM4, I4VE4, I4HE4, I4RD4, I4VR4, I4LD4, I4VL4, I4HD4, I4HU4
467 };
468 
VP8MakeLuma16Preds(const VP8EncIterator * const it)469 void VP8MakeLuma16Preds(const VP8EncIterator* const it) {
470   const uint8_t* const left = it->x_ ? it->y_left_ : NULL;
471   const uint8_t* const top = it->y_ ? it->y_top_ : NULL;
472   VP8EncPredLuma16(it->yuv_p_, left, top);
473 }
474 
VP8MakeChroma8Preds(const VP8EncIterator * const it)475 void VP8MakeChroma8Preds(const VP8EncIterator* const it) {
476   const uint8_t* const left = it->x_ ? it->u_left_ : NULL;
477   const uint8_t* const top = it->y_ ? it->uv_top_ : NULL;
478   VP8EncPredChroma8(it->yuv_p_, left, top);
479 }
480 
VP8MakeIntra4Preds(const VP8EncIterator * const it)481 void VP8MakeIntra4Preds(const VP8EncIterator* const it) {
482   VP8EncPredLuma4(it->yuv_p_, it->i4_top_);
483 }
484 
485 //------------------------------------------------------------------------------
486 // Quantize
487 
488 // Layout:
489 // +----+----+
490 // |YYYY|UUVV| 0
491 // |YYYY|UUVV| 4
492 // |YYYY|....| 8
493 // |YYYY|....| 12
494 // +----+----+
495 
496 const uint16_t VP8Scan[16] = {  // Luma
497   0 +  0 * BPS,  4 +  0 * BPS, 8 +  0 * BPS, 12 +  0 * BPS,
498   0 +  4 * BPS,  4 +  4 * BPS, 8 +  4 * BPS, 12 +  4 * BPS,
499   0 +  8 * BPS,  4 +  8 * BPS, 8 +  8 * BPS, 12 +  8 * BPS,
500   0 + 12 * BPS,  4 + 12 * BPS, 8 + 12 * BPS, 12 + 12 * BPS,
501 };
502 
503 static const uint16_t VP8ScanUV[4 + 4] = {
504   0 + 0 * BPS,   4 + 0 * BPS, 0 + 4 * BPS,  4 + 4 * BPS,    // U
505   8 + 0 * BPS,  12 + 0 * BPS, 8 + 4 * BPS, 12 + 4 * BPS     // V
506 };
507 
508 //------------------------------------------------------------------------------
509 // Distortion measurement
510 
511 static const uint16_t kWeightY[16] = {
512   38, 32, 20, 9, 32, 28, 17, 7, 20, 17, 10, 4, 9, 7, 4, 2
513 };
514 
515 static const uint16_t kWeightTrellis[16] = {
516 #if USE_TDISTO == 0
517   16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
518 #else
519   30, 27, 19, 11,
520   27, 24, 17, 10,
521   19, 17, 12,  8,
522   11, 10,  8,  6
523 #endif
524 };
525 
526 // Init/Copy the common fields in score.
InitScore(VP8ModeScore * const rd)527 static void InitScore(VP8ModeScore* const rd) {
528   rd->D  = 0;
529   rd->SD = 0;
530   rd->R  = 0;
531   rd->H  = 0;
532   rd->nz = 0;
533   rd->score = MAX_COST;
534 }
535 
CopyScore(VP8ModeScore * const dst,const VP8ModeScore * const src)536 static void CopyScore(VP8ModeScore* const dst, const VP8ModeScore* const src) {
537   dst->D  = src->D;
538   dst->SD = src->SD;
539   dst->R  = src->R;
540   dst->H  = src->H;
541   dst->nz = src->nz;      // note that nz is not accumulated, but just copied.
542   dst->score = src->score;
543 }
544 
AddScore(VP8ModeScore * const dst,const VP8ModeScore * const src)545 static void AddScore(VP8ModeScore* const dst, const VP8ModeScore* const src) {
546   dst->D  += src->D;
547   dst->SD += src->SD;
548   dst->R  += src->R;
549   dst->H  += src->H;
550   dst->nz |= src->nz;     // here, new nz bits are accumulated.
551   dst->score += src->score;
552 }
553 
554 //------------------------------------------------------------------------------
555 // Performs trellis-optimized quantization.
556 
557 // Trellis node
558 typedef struct {
559   int8_t prev;            // best previous node
560   int8_t sign;            // sign of coeff_i
561   int16_t level;          // level
562 } Node;
563 
564 // Score state
565 typedef struct {
566   score_t score;          // partial RD score
567   const uint16_t* costs;  // shortcut to cost tables
568 } ScoreState;
569 
570 // If a coefficient was quantized to a value Q (using a neutral bias),
571 // we test all alternate possibilities between [Q-MIN_DELTA, Q+MAX_DELTA]
572 // We don't test negative values though.
573 #define MIN_DELTA 0   // how much lower level to try
574 #define MAX_DELTA 1   // how much higher
575 #define NUM_NODES (MIN_DELTA + 1 + MAX_DELTA)
576 #define NODE(n, l) (nodes[(n)][(l) + MIN_DELTA])
577 #define SCORE_STATE(n, l) (score_states[n][(l) + MIN_DELTA])
578 
SetRDScore(int lambda,VP8ModeScore * const rd)579 static WEBP_INLINE void SetRDScore(int lambda, VP8ModeScore* const rd) {
580   rd->score = (rd->R + rd->H) * lambda + RD_DISTO_MULT * (rd->D + rd->SD);
581 }
582 
RDScoreTrellis(int lambda,score_t rate,score_t distortion)583 static WEBP_INLINE score_t RDScoreTrellis(int lambda, score_t rate,
584                                           score_t distortion) {
585   return rate * lambda + RD_DISTO_MULT * distortion;
586 }
587 
TrellisQuantizeBlock(const VP8Encoder * const enc,int16_t in[16],int16_t out[16],int ctx0,int coeff_type,const VP8Matrix * const mtx,int lambda)588 static int TrellisQuantizeBlock(const VP8Encoder* const enc,
589                                 int16_t in[16], int16_t out[16],
590                                 int ctx0, int coeff_type,
591                                 const VP8Matrix* const mtx,
592                                 int lambda) {
593   const ProbaArray* const probas = enc->proba_.coeffs_[coeff_type];
594   CostArrayPtr const costs =
595       (CostArrayPtr)enc->proba_.remapped_costs_[coeff_type];
596   const int first = (coeff_type == 0) ? 1 : 0;
597   Node nodes[16][NUM_NODES];
598   ScoreState score_states[2][NUM_NODES];
599   ScoreState* ss_cur = &SCORE_STATE(0, MIN_DELTA);
600   ScoreState* ss_prev = &SCORE_STATE(1, MIN_DELTA);
601   int best_path[3] = {-1, -1, -1};   // store best-last/best-level/best-previous
602   score_t best_score;
603   int n, m, p, last;
604 
605   {
606     score_t cost;
607     const int thresh = mtx->q_[1] * mtx->q_[1] / 4;
608     const int last_proba = probas[VP8EncBands[first]][ctx0][0];
609 
610     // compute the position of the last interesting coefficient
611     last = first - 1;
612     for (n = 15; n >= first; --n) {
613       const int j = kZigzag[n];
614       const int err = in[j] * in[j];
615       if (err > thresh) {
616         last = n;
617         break;
618       }
619     }
620     // we don't need to go inspect up to n = 16 coeffs. We can just go up
621     // to last + 1 (inclusive) without losing much.
622     if (last < 15) ++last;
623 
624     // compute 'skip' score. This is the max score one can do.
625     cost = VP8BitCost(0, last_proba);
626     best_score = RDScoreTrellis(lambda, cost, 0);
627 
628     // initialize source node.
629     for (m = -MIN_DELTA; m <= MAX_DELTA; ++m) {
630       const score_t rate = (ctx0 == 0) ? VP8BitCost(1, last_proba) : 0;
631       ss_cur[m].score = RDScoreTrellis(lambda, rate, 0);
632       ss_cur[m].costs = costs[first][ctx0];
633     }
634   }
635 
636   // traverse trellis.
637   for (n = first; n <= last; ++n) {
638     const int j = kZigzag[n];
639     const uint32_t Q  = mtx->q_[j];
640     const uint32_t iQ = mtx->iq_[j];
641     const uint32_t B = BIAS(0x00);     // neutral bias
642     // note: it's important to take sign of the _original_ coeff,
643     // so we don't have to consider level < 0 afterward.
644     const int sign = (in[j] < 0);
645     const uint32_t coeff0 = (sign ? -in[j] : in[j]) + mtx->sharpen_[j];
646     int level0 = QUANTDIV(coeff0, iQ, B);
647     int thresh_level = QUANTDIV(coeff0, iQ, BIAS(0x80));
648     if (thresh_level > MAX_LEVEL) thresh_level = MAX_LEVEL;
649     if (level0 > MAX_LEVEL) level0 = MAX_LEVEL;
650 
651     {   // Swap current and previous score states
652       ScoreState* const tmp = ss_cur;
653       ss_cur = ss_prev;
654       ss_prev = tmp;
655     }
656 
657     // test all alternate level values around level0.
658     for (m = -MIN_DELTA; m <= MAX_DELTA; ++m) {
659       Node* const cur = &NODE(n, m);
660       int level = level0 + m;
661       const int ctx = (level > 2) ? 2 : level;
662       const int band = VP8EncBands[n + 1];
663       score_t base_score;
664       score_t best_cur_score = MAX_COST;
665       int best_prev = 0;   // default, in case
666 
667       ss_cur[m].score = MAX_COST;
668       ss_cur[m].costs = costs[n + 1][ctx];
669       if (level < 0 || level > thresh_level) {
670         // Node is dead.
671         continue;
672       }
673 
674       {
675         // Compute delta_error = how much coding this level will
676         // subtract to max_error as distortion.
677         // Here, distortion = sum of (|coeff_i| - level_i * Q_i)^2
678         const int new_error = coeff0 - level * Q;
679         const int delta_error =
680             kWeightTrellis[j] * (new_error * new_error - coeff0 * coeff0);
681         base_score = RDScoreTrellis(lambda, 0, delta_error);
682       }
683 
684       // Inspect all possible non-dead predecessors. Retain only the best one.
685       for (p = -MIN_DELTA; p <= MAX_DELTA; ++p) {
686         // Dead nodes (with ss_prev[p].score >= MAX_COST) are automatically
687         // eliminated since their score can't be better than the current best.
688         const score_t cost = VP8LevelCost(ss_prev[p].costs, level);
689         // Examine node assuming it's a non-terminal one.
690         const score_t score =
691             base_score + ss_prev[p].score + RDScoreTrellis(lambda, cost, 0);
692         if (score < best_cur_score) {
693           best_cur_score = score;
694           best_prev = p;
695         }
696       }
697       // Store best finding in current node.
698       cur->sign = sign;
699       cur->level = level;
700       cur->prev = best_prev;
701       ss_cur[m].score = best_cur_score;
702 
703       // Now, record best terminal node (and thus best entry in the graph).
704       if (level != 0) {
705         const score_t last_pos_cost =
706             (n < 15) ? VP8BitCost(0, probas[band][ctx][0]) : 0;
707         const score_t last_pos_score = RDScoreTrellis(lambda, last_pos_cost, 0);
708         const score_t score = best_cur_score + last_pos_score;
709         if (score < best_score) {
710           best_score = score;
711           best_path[0] = n;                     // best eob position
712           best_path[1] = m;                     // best node index
713           best_path[2] = best_prev;             // best predecessor
714         }
715       }
716     }
717   }
718 
719   // Fresh start
720   memset(in + first, 0, (16 - first) * sizeof(*in));
721   memset(out + first, 0, (16 - first) * sizeof(*out));
722   if (best_path[0] == -1) {
723     return 0;   // skip!
724   }
725 
726   {
727     // Unwind the best path.
728     // Note: best-prev on terminal node is not necessarily equal to the
729     // best_prev for non-terminal. So we patch best_path[2] in.
730     int nz = 0;
731     int best_node = best_path[1];
732     n = best_path[0];
733     NODE(n, best_node).prev = best_path[2];   // force best-prev for terminal
734 
735     for (; n >= first; --n) {
736       const Node* const node = &NODE(n, best_node);
737       const int j = kZigzag[n];
738       out[n] = node->sign ? -node->level : node->level;
739       nz |= node->level;
740       in[j] = out[n] * mtx->q_[j];
741       best_node = node->prev;
742     }
743     return (nz != 0);
744   }
745 }
746 
747 #undef NODE
748 
749 //------------------------------------------------------------------------------
750 // Performs: difference, transform, quantize, back-transform, add
751 // all at once. Output is the reconstructed block in *yuv_out, and the
752 // quantized levels in *levels.
753 
ReconstructIntra16(VP8EncIterator * const it,VP8ModeScore * const rd,uint8_t * const yuv_out,int mode)754 static int ReconstructIntra16(VP8EncIterator* const it,
755                               VP8ModeScore* const rd,
756                               uint8_t* const yuv_out,
757                               int mode) {
758   const VP8Encoder* const enc = it->enc_;
759   const uint8_t* const ref = it->yuv_p_ + VP8I16ModeOffsets[mode];
760   const uint8_t* const src = it->yuv_in_ + Y_OFF_ENC;
761   const VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_];
762   int nz = 0;
763   int n;
764   int16_t tmp[16][16], dc_tmp[16];
765 
766   for (n = 0; n < 16; n += 2) {
767     VP8FTransform2(src + VP8Scan[n], ref + VP8Scan[n], tmp[n]);
768   }
769   VP8FTransformWHT(tmp[0], dc_tmp);
770   nz |= VP8EncQuantizeBlockWHT(dc_tmp, rd->y_dc_levels, &dqm->y2_) << 24;
771 
772   if (DO_TRELLIS_I16 && it->do_trellis_) {
773     int x, y;
774     VP8IteratorNzToBytes(it);
775     for (y = 0, n = 0; y < 4; ++y) {
776       for (x = 0; x < 4; ++x, ++n) {
777         const int ctx = it->top_nz_[x] + it->left_nz_[y];
778         const int non_zero =
779             TrellisQuantizeBlock(enc, tmp[n], rd->y_ac_levels[n], ctx, 0,
780                                  &dqm->y1_, dqm->lambda_trellis_i16_);
781         it->top_nz_[x] = it->left_nz_[y] = non_zero;
782         rd->y_ac_levels[n][0] = 0;
783         nz |= non_zero << n;
784       }
785     }
786   } else {
787     for (n = 0; n < 16; n += 2) {
788       // Zero-out the first coeff, so that: a) nz is correct below, and
789       // b) finding 'last' non-zero coeffs in SetResidualCoeffs() is simplified.
790       tmp[n][0] = tmp[n + 1][0] = 0;
791       nz |= VP8EncQuantize2Blocks(tmp[n], rd->y_ac_levels[n], &dqm->y1_) << n;
792       assert(rd->y_ac_levels[n + 0][0] == 0);
793       assert(rd->y_ac_levels[n + 1][0] == 0);
794     }
795   }
796 
797   // Transform back
798   VP8TransformWHT(dc_tmp, tmp[0]);
799   for (n = 0; n < 16; n += 2) {
800     VP8ITransform(ref + VP8Scan[n], tmp[n], yuv_out + VP8Scan[n], 1);
801   }
802 
803   return nz;
804 }
805 
ReconstructIntra4(VP8EncIterator * const it,int16_t levels[16],const uint8_t * const src,uint8_t * const yuv_out,int mode)806 static int ReconstructIntra4(VP8EncIterator* const it,
807                              int16_t levels[16],
808                              const uint8_t* const src,
809                              uint8_t* const yuv_out,
810                              int mode) {
811   const VP8Encoder* const enc = it->enc_;
812   const uint8_t* const ref = it->yuv_p_ + VP8I4ModeOffsets[mode];
813   const VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_];
814   int nz = 0;
815   int16_t tmp[16];
816 
817   VP8FTransform(src, ref, tmp);
818   if (DO_TRELLIS_I4 && it->do_trellis_) {
819     const int x = it->i4_ & 3, y = it->i4_ >> 2;
820     const int ctx = it->top_nz_[x] + it->left_nz_[y];
821     nz = TrellisQuantizeBlock(enc, tmp, levels, ctx, 3, &dqm->y1_,
822                               dqm->lambda_trellis_i4_);
823   } else {
824     nz = VP8EncQuantizeBlock(tmp, levels, &dqm->y1_);
825   }
826   VP8ITransform(ref, tmp, yuv_out, 0);
827   return nz;
828 }
829 
830 //------------------------------------------------------------------------------
831 // DC-error diffusion
832 
833 // Diffusion weights. We under-correct a bit (15/16th of the error is actually
834 // diffused) to avoid 'rainbow' chessboard pattern of blocks at q~=0.
835 #define C1 7    // fraction of error sent to the 4x4 block below
836 #define C2 8    // fraction of error sent to the 4x4 block on the right
837 #define DSHIFT 4
838 #define DSCALE 1   // storage descaling, needed to make the error fit int8_t
839 
840 // Quantize as usual, but also compute and return the quantization error.
841 // Error is already divided by DSHIFT.
QuantizeSingle(int16_t * const v,const VP8Matrix * const mtx)842 static int QuantizeSingle(int16_t* const v, const VP8Matrix* const mtx) {
843   int V = *v;
844   const int sign = (V < 0);
845   if (sign) V = -V;
846   if (V > (int)mtx->zthresh_[0]) {
847     const int qV = QUANTDIV(V, mtx->iq_[0], mtx->bias_[0]) * mtx->q_[0];
848     const int err = (V - qV);
849     *v = sign ? -qV : qV;
850     return (sign ? -err : err) >> DSCALE;
851   }
852   *v = 0;
853   return (sign ? -V : V) >> DSCALE;
854 }
855 
CorrectDCValues(const VP8EncIterator * const it,const VP8Matrix * const mtx,int16_t tmp[][16],VP8ModeScore * const rd)856 static void CorrectDCValues(const VP8EncIterator* const it,
857                             const VP8Matrix* const mtx,
858                             int16_t tmp[][16], VP8ModeScore* const rd) {
859   //         | top[0] | top[1]
860   // --------+--------+---------
861   // left[0] | tmp[0]   tmp[1]  <->   err0 err1
862   // left[1] | tmp[2]   tmp[3]        err2 err3
863   //
864   // Final errors {err1,err2,err3} are preserved and later restored
865   // as top[]/left[] on the next block.
866   int ch;
867   for (ch = 0; ch <= 1; ++ch) {
868     const int8_t* const top = it->top_derr_[it->x_][ch];
869     const int8_t* const left = it->left_derr_[ch];
870     int16_t (* const c)[16] = &tmp[ch * 4];
871     int err0, err1, err2, err3;
872     c[0][0] += (C1 * top[0] + C2 * left[0]) >> (DSHIFT - DSCALE);
873     err0 = QuantizeSingle(&c[0][0], mtx);
874     c[1][0] += (C1 * top[1] + C2 * err0) >> (DSHIFT - DSCALE);
875     err1 = QuantizeSingle(&c[1][0], mtx);
876     c[2][0] += (C1 * err0 + C2 * left[1]) >> (DSHIFT - DSCALE);
877     err2 = QuantizeSingle(&c[2][0], mtx);
878     c[3][0] += (C1 * err1 + C2 * err2) >> (DSHIFT - DSCALE);
879     err3 = QuantizeSingle(&c[3][0], mtx);
880     // error 'err' is bounded by mtx->q_[0] which is 132 at max. Hence
881     // err >> DSCALE will fit in an int8_t type if DSCALE>=1.
882     assert(abs(err1) <= 127 && abs(err2) <= 127 && abs(err3) <= 127);
883     rd->derr[ch][0] = (int8_t)err1;
884     rd->derr[ch][1] = (int8_t)err2;
885     rd->derr[ch][2] = (int8_t)err3;
886   }
887 }
888 
StoreDiffusionErrors(VP8EncIterator * const it,const VP8ModeScore * const rd)889 static void StoreDiffusionErrors(VP8EncIterator* const it,
890                                  const VP8ModeScore* const rd) {
891   int ch;
892   for (ch = 0; ch <= 1; ++ch) {
893     int8_t* const top = it->top_derr_[it->x_][ch];
894     int8_t* const left = it->left_derr_[ch];
895     left[0] = rd->derr[ch][0];            // restore err1
896     left[1] = 3 * rd->derr[ch][2] >> 2;   //     ... 3/4th of err3
897     top[0]  = rd->derr[ch][1];            //     ... err2
898     top[1]  = rd->derr[ch][2] - left[1];  //     ... 1/4th of err3.
899   }
900 }
901 
902 #undef C1
903 #undef C2
904 #undef DSHIFT
905 #undef DSCALE
906 
907 //------------------------------------------------------------------------------
908 
ReconstructUV(VP8EncIterator * const it,VP8ModeScore * const rd,uint8_t * const yuv_out,int mode)909 static int ReconstructUV(VP8EncIterator* const it, VP8ModeScore* const rd,
910                          uint8_t* const yuv_out, int mode) {
911   const VP8Encoder* const enc = it->enc_;
912   const uint8_t* const ref = it->yuv_p_ + VP8UVModeOffsets[mode];
913   const uint8_t* const src = it->yuv_in_ + U_OFF_ENC;
914   const VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_];
915   int nz = 0;
916   int n;
917   int16_t tmp[8][16];
918 
919   for (n = 0; n < 8; n += 2) {
920     VP8FTransform2(src + VP8ScanUV[n], ref + VP8ScanUV[n], tmp[n]);
921   }
922   if (it->top_derr_ != NULL) CorrectDCValues(it, &dqm->uv_, tmp, rd);
923 
924   if (DO_TRELLIS_UV && it->do_trellis_) {
925     int ch, x, y;
926     for (ch = 0, n = 0; ch <= 2; ch += 2) {
927       for (y = 0; y < 2; ++y) {
928         for (x = 0; x < 2; ++x, ++n) {
929           const int ctx = it->top_nz_[4 + ch + x] + it->left_nz_[4 + ch + y];
930           const int non_zero =
931               TrellisQuantizeBlock(enc, tmp[n], rd->uv_levels[n], ctx, 2,
932                                    &dqm->uv_, dqm->lambda_trellis_uv_);
933           it->top_nz_[4 + ch + x] = it->left_nz_[4 + ch + y] = non_zero;
934           nz |= non_zero << n;
935         }
936       }
937     }
938   } else {
939     for (n = 0; n < 8; n += 2) {
940       nz |= VP8EncQuantize2Blocks(tmp[n], rd->uv_levels[n], &dqm->uv_) << n;
941     }
942   }
943 
944   for (n = 0; n < 8; n += 2) {
945     VP8ITransform(ref + VP8ScanUV[n], tmp[n], yuv_out + VP8ScanUV[n], 1);
946   }
947   return (nz << 16);
948 }
949 
950 //------------------------------------------------------------------------------
951 // RD-opt decision. Reconstruct each modes, evalue distortion and bit-cost.
952 // Pick the mode is lower RD-cost = Rate + lambda * Distortion.
953 
StoreMaxDelta(VP8SegmentInfo * const dqm,const int16_t DCs[16])954 static void StoreMaxDelta(VP8SegmentInfo* const dqm, const int16_t DCs[16]) {
955   // We look at the first three AC coefficients to determine what is the average
956   // delta between each sub-4x4 block.
957   const int v0 = abs(DCs[1]);
958   const int v1 = abs(DCs[2]);
959   const int v2 = abs(DCs[4]);
960   int max_v = (v1 > v0) ? v1 : v0;
961   max_v = (v2 > max_v) ? v2 : max_v;
962   if (max_v > dqm->max_edge_) dqm->max_edge_ = max_v;
963 }
964 
SwapModeScore(VP8ModeScore ** a,VP8ModeScore ** b)965 static void SwapModeScore(VP8ModeScore** a, VP8ModeScore** b) {
966   VP8ModeScore* const tmp = *a;
967   *a = *b;
968   *b = tmp;
969 }
970 
SwapPtr(uint8_t ** a,uint8_t ** b)971 static void SwapPtr(uint8_t** a, uint8_t** b) {
972   uint8_t* const tmp = *a;
973   *a = *b;
974   *b = tmp;
975 }
976 
SwapOut(VP8EncIterator * const it)977 static void SwapOut(VP8EncIterator* const it) {
978   SwapPtr(&it->yuv_out_, &it->yuv_out2_);
979 }
980 
PickBestIntra16(VP8EncIterator * const it,VP8ModeScore * rd)981 static void PickBestIntra16(VP8EncIterator* const it, VP8ModeScore* rd) {
982   const int kNumBlocks = 16;
983   VP8SegmentInfo* const dqm = &it->enc_->dqm_[it->mb_->segment_];
984   const int lambda = dqm->lambda_i16_;
985   const int tlambda = dqm->tlambda_;
986   const uint8_t* const src = it->yuv_in_ + Y_OFF_ENC;
987   VP8ModeScore rd_tmp;
988   VP8ModeScore* rd_cur = &rd_tmp;
989   VP8ModeScore* rd_best = rd;
990   int mode;
991 
992   rd->mode_i16 = -1;
993   for (mode = 0; mode < NUM_PRED_MODES; ++mode) {
994     uint8_t* const tmp_dst = it->yuv_out2_ + Y_OFF_ENC;  // scratch buffer
995     rd_cur->mode_i16 = mode;
996 
997     // Reconstruct
998     rd_cur->nz = ReconstructIntra16(it, rd_cur, tmp_dst, mode);
999 
1000     // Measure RD-score
1001     rd_cur->D = VP8SSE16x16(src, tmp_dst);
1002     rd_cur->SD =
1003         tlambda ? MULT_8B(tlambda, VP8TDisto16x16(src, tmp_dst, kWeightY)) : 0;
1004     rd_cur->H = VP8FixedCostsI16[mode];
1005     rd_cur->R = VP8GetCostLuma16(it, rd_cur);
1006     if (mode > 0 &&
1007         IsFlat(rd_cur->y_ac_levels[0], kNumBlocks, FLATNESS_LIMIT_I16)) {
1008       // penalty to avoid flat area to be mispredicted by complex mode
1009       rd_cur->R += FLATNESS_PENALTY * kNumBlocks;
1010     }
1011 
1012     // Since we always examine Intra16 first, we can overwrite *rd directly.
1013     SetRDScore(lambda, rd_cur);
1014     if (mode == 0 || rd_cur->score < rd_best->score) {
1015       SwapModeScore(&rd_cur, &rd_best);
1016       SwapOut(it);
1017     }
1018   }
1019   if (rd_best != rd) {
1020     memcpy(rd, rd_best, sizeof(*rd));
1021   }
1022   SetRDScore(dqm->lambda_mode_, rd);   // finalize score for mode decision.
1023   VP8SetIntra16Mode(it, rd->mode_i16);
1024 
1025   // we have a blocky macroblock (only DCs are non-zero) with fairly high
1026   // distortion, record max delta so we can later adjust the minimal filtering
1027   // strength needed to smooth these blocks out.
1028   if ((rd->nz & 0x100ffff) == 0x1000000 && rd->D > dqm->min_disto_) {
1029     StoreMaxDelta(dqm, rd->y_dc_levels);
1030   }
1031 }
1032 
1033 //------------------------------------------------------------------------------
1034 
1035 // return the cost array corresponding to the surrounding prediction modes.
GetCostModeI4(VP8EncIterator * const it,const uint8_t modes[16])1036 static const uint16_t* GetCostModeI4(VP8EncIterator* const it,
1037                                      const uint8_t modes[16]) {
1038   const int preds_w = it->enc_->preds_w_;
1039   const int x = (it->i4_ & 3), y = it->i4_ >> 2;
1040   const int left = (x == 0) ? it->preds_[y * preds_w - 1] : modes[it->i4_ - 1];
1041   const int top = (y == 0) ? it->preds_[-preds_w + x] : modes[it->i4_ - 4];
1042   return VP8FixedCostsI4[top][left];
1043 }
1044 
PickBestIntra4(VP8EncIterator * const it,VP8ModeScore * const rd)1045 static int PickBestIntra4(VP8EncIterator* const it, VP8ModeScore* const rd) {
1046   const VP8Encoder* const enc = it->enc_;
1047   const VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_];
1048   const int lambda = dqm->lambda_i4_;
1049   const int tlambda = dqm->tlambda_;
1050   const uint8_t* const src0 = it->yuv_in_ + Y_OFF_ENC;
1051   uint8_t* const best_blocks = it->yuv_out2_ + Y_OFF_ENC;
1052   int total_header_bits = 0;
1053   VP8ModeScore rd_best;
1054 
1055   if (enc->max_i4_header_bits_ == 0) {
1056     return 0;
1057   }
1058 
1059   InitScore(&rd_best);
1060   rd_best.H = 211;  // '211' is the value of VP8BitCost(0, 145)
1061   SetRDScore(dqm->lambda_mode_, &rd_best);
1062   VP8IteratorStartI4(it);
1063   do {
1064     const int kNumBlocks = 1;
1065     VP8ModeScore rd_i4;
1066     int mode;
1067     int best_mode = -1;
1068     const uint8_t* const src = src0 + VP8Scan[it->i4_];
1069     const uint16_t* const mode_costs = GetCostModeI4(it, rd->modes_i4);
1070     uint8_t* best_block = best_blocks + VP8Scan[it->i4_];
1071     uint8_t* tmp_dst = it->yuv_p_ + I4TMP;    // scratch buffer.
1072 
1073     InitScore(&rd_i4);
1074     VP8MakeIntra4Preds(it);
1075     for (mode = 0; mode < NUM_BMODES; ++mode) {
1076       VP8ModeScore rd_tmp;
1077       int16_t tmp_levels[16];
1078 
1079       // Reconstruct
1080       rd_tmp.nz =
1081           ReconstructIntra4(it, tmp_levels, src, tmp_dst, mode) << it->i4_;
1082 
1083       // Compute RD-score
1084       rd_tmp.D = VP8SSE4x4(src, tmp_dst);
1085       rd_tmp.SD =
1086           tlambda ? MULT_8B(tlambda, VP8TDisto4x4(src, tmp_dst, kWeightY))
1087                   : 0;
1088       rd_tmp.H = mode_costs[mode];
1089 
1090       // Add flatness penalty
1091       if (mode > 0 && IsFlat(tmp_levels, kNumBlocks, FLATNESS_LIMIT_I4)) {
1092         rd_tmp.R = FLATNESS_PENALTY * kNumBlocks;
1093       } else {
1094         rd_tmp.R = 0;
1095       }
1096 
1097       // early-out check
1098       SetRDScore(lambda, &rd_tmp);
1099       if (best_mode >= 0 && rd_tmp.score >= rd_i4.score) continue;
1100 
1101       // finish computing score
1102       rd_tmp.R += VP8GetCostLuma4(it, tmp_levels);
1103       SetRDScore(lambda, &rd_tmp);
1104 
1105       if (best_mode < 0 || rd_tmp.score < rd_i4.score) {
1106         CopyScore(&rd_i4, &rd_tmp);
1107         best_mode = mode;
1108         SwapPtr(&tmp_dst, &best_block);
1109         memcpy(rd_best.y_ac_levels[it->i4_], tmp_levels,
1110                sizeof(rd_best.y_ac_levels[it->i4_]));
1111       }
1112     }
1113     SetRDScore(dqm->lambda_mode_, &rd_i4);
1114     AddScore(&rd_best, &rd_i4);
1115     if (rd_best.score >= rd->score) {
1116       return 0;
1117     }
1118     total_header_bits += (int)rd_i4.H;   // <- equal to mode_costs[best_mode];
1119     if (total_header_bits > enc->max_i4_header_bits_) {
1120       return 0;
1121     }
1122     // Copy selected samples if not in the right place already.
1123     if (best_block != best_blocks + VP8Scan[it->i4_]) {
1124       VP8Copy4x4(best_block, best_blocks + VP8Scan[it->i4_]);
1125     }
1126     rd->modes_i4[it->i4_] = best_mode;
1127     it->top_nz_[it->i4_ & 3] = it->left_nz_[it->i4_ >> 2] = (rd_i4.nz ? 1 : 0);
1128   } while (VP8IteratorRotateI4(it, best_blocks));
1129 
1130   // finalize state
1131   CopyScore(rd, &rd_best);
1132   VP8SetIntra4Mode(it, rd->modes_i4);
1133   SwapOut(it);
1134   memcpy(rd->y_ac_levels, rd_best.y_ac_levels, sizeof(rd->y_ac_levels));
1135   return 1;   // select intra4x4 over intra16x16
1136 }
1137 
1138 //------------------------------------------------------------------------------
1139 
PickBestUV(VP8EncIterator * const it,VP8ModeScore * const rd)1140 static void PickBestUV(VP8EncIterator* const it, VP8ModeScore* const rd) {
1141   const int kNumBlocks = 8;
1142   const VP8SegmentInfo* const dqm = &it->enc_->dqm_[it->mb_->segment_];
1143   const int lambda = dqm->lambda_uv_;
1144   const uint8_t* const src = it->yuv_in_ + U_OFF_ENC;
1145   uint8_t* tmp_dst = it->yuv_out2_ + U_OFF_ENC;  // scratch buffer
1146   uint8_t* dst0 = it->yuv_out_ + U_OFF_ENC;
1147   uint8_t* dst = dst0;
1148   VP8ModeScore rd_best;
1149   int mode;
1150 
1151   rd->mode_uv = -1;
1152   InitScore(&rd_best);
1153   for (mode = 0; mode < NUM_PRED_MODES; ++mode) {
1154     VP8ModeScore rd_uv;
1155 
1156     // Reconstruct
1157     rd_uv.nz = ReconstructUV(it, &rd_uv, tmp_dst, mode);
1158 
1159     // Compute RD-score
1160     rd_uv.D  = VP8SSE16x8(src, tmp_dst);
1161     rd_uv.SD = 0;    // not calling TDisto here: it tends to flatten areas.
1162     rd_uv.H  = VP8FixedCostsUV[mode];
1163     rd_uv.R  = VP8GetCostUV(it, &rd_uv);
1164     if (mode > 0 && IsFlat(rd_uv.uv_levels[0], kNumBlocks, FLATNESS_LIMIT_UV)) {
1165       rd_uv.R += FLATNESS_PENALTY * kNumBlocks;
1166     }
1167 
1168     SetRDScore(lambda, &rd_uv);
1169     if (mode == 0 || rd_uv.score < rd_best.score) {
1170       CopyScore(&rd_best, &rd_uv);
1171       rd->mode_uv = mode;
1172       memcpy(rd->uv_levels, rd_uv.uv_levels, sizeof(rd->uv_levels));
1173       if (it->top_derr_ != NULL) {
1174         memcpy(rd->derr, rd_uv.derr, sizeof(rd_uv.derr));
1175       }
1176       SwapPtr(&dst, &tmp_dst);
1177     }
1178   }
1179   VP8SetIntraUVMode(it, rd->mode_uv);
1180   AddScore(rd, &rd_best);
1181   if (dst != dst0) {   // copy 16x8 block if needed
1182     VP8Copy16x8(dst, dst0);
1183   }
1184   if (it->top_derr_ != NULL) {  // store diffusion errors for next block
1185     StoreDiffusionErrors(it, rd);
1186   }
1187 }
1188 
1189 //------------------------------------------------------------------------------
1190 // Final reconstruction and quantization.
1191 
SimpleQuantize(VP8EncIterator * const it,VP8ModeScore * const rd)1192 static void SimpleQuantize(VP8EncIterator* const it, VP8ModeScore* const rd) {
1193   const VP8Encoder* const enc = it->enc_;
1194   const int is_i16 = (it->mb_->type_ == 1);
1195   int nz = 0;
1196 
1197   if (is_i16) {
1198     nz = ReconstructIntra16(it, rd, it->yuv_out_ + Y_OFF_ENC, it->preds_[0]);
1199   } else {
1200     VP8IteratorStartI4(it);
1201     do {
1202       const int mode =
1203           it->preds_[(it->i4_ & 3) + (it->i4_ >> 2) * enc->preds_w_];
1204       const uint8_t* const src = it->yuv_in_ + Y_OFF_ENC + VP8Scan[it->i4_];
1205       uint8_t* const dst = it->yuv_out_ + Y_OFF_ENC + VP8Scan[it->i4_];
1206       VP8MakeIntra4Preds(it);
1207       nz |= ReconstructIntra4(it, rd->y_ac_levels[it->i4_],
1208                               src, dst, mode) << it->i4_;
1209     } while (VP8IteratorRotateI4(it, it->yuv_out_ + Y_OFF_ENC));
1210   }
1211 
1212   nz |= ReconstructUV(it, rd, it->yuv_out_ + U_OFF_ENC, it->mb_->uv_mode_);
1213   rd->nz = nz;
1214 }
1215 
1216 // Refine intra16/intra4 sub-modes based on distortion only (not rate).
RefineUsingDistortion(VP8EncIterator * const it,int try_both_modes,int refine_uv_mode,VP8ModeScore * const rd)1217 static void RefineUsingDistortion(VP8EncIterator* const it,
1218                                   int try_both_modes, int refine_uv_mode,
1219                                   VP8ModeScore* const rd) {
1220   score_t best_score = MAX_COST;
1221   int nz = 0;
1222   int mode;
1223   int is_i16 = try_both_modes || (it->mb_->type_ == 1);
1224 
1225   const VP8SegmentInfo* const dqm = &it->enc_->dqm_[it->mb_->segment_];
1226   // Some empiric constants, of approximate order of magnitude.
1227   const int lambda_d_i16 = 106;
1228   const int lambda_d_i4 = 11;
1229   const int lambda_d_uv = 120;
1230   score_t score_i4 = dqm->i4_penalty_;
1231   score_t i4_bit_sum = 0;
1232   const score_t bit_limit = try_both_modes ? it->enc_->mb_header_limit_
1233                                            : MAX_COST;  // no early-out allowed
1234 
1235   if (is_i16) {   // First, evaluate Intra16 distortion
1236     int best_mode = -1;
1237     const uint8_t* const src = it->yuv_in_ + Y_OFF_ENC;
1238     for (mode = 0; mode < NUM_PRED_MODES; ++mode) {
1239       const uint8_t* const ref = it->yuv_p_ + VP8I16ModeOffsets[mode];
1240       const score_t score = (score_t)VP8SSE16x16(src, ref) * RD_DISTO_MULT
1241                           + VP8FixedCostsI16[mode] * lambda_d_i16;
1242       if (mode > 0 && VP8FixedCostsI16[mode] > bit_limit) {
1243         continue;
1244       }
1245       if (score < best_score) {
1246         best_mode = mode;
1247         best_score = score;
1248       }
1249     }
1250     VP8SetIntra16Mode(it, best_mode);
1251     // we'll reconstruct later, if i16 mode actually gets selected
1252   }
1253 
1254   // Next, evaluate Intra4
1255   if (try_both_modes || !is_i16) {
1256     // We don't evaluate the rate here, but just account for it through a
1257     // constant penalty (i4 mode usually needs more bits compared to i16).
1258     is_i16 = 0;
1259     VP8IteratorStartI4(it);
1260     do {
1261       int best_i4_mode = -1;
1262       score_t best_i4_score = MAX_COST;
1263       const uint8_t* const src = it->yuv_in_ + Y_OFF_ENC + VP8Scan[it->i4_];
1264       const uint16_t* const mode_costs = GetCostModeI4(it, rd->modes_i4);
1265 
1266       VP8MakeIntra4Preds(it);
1267       for (mode = 0; mode < NUM_BMODES; ++mode) {
1268         const uint8_t* const ref = it->yuv_p_ + VP8I4ModeOffsets[mode];
1269         const score_t score = VP8SSE4x4(src, ref) * RD_DISTO_MULT
1270                             + mode_costs[mode] * lambda_d_i4;
1271         if (score < best_i4_score) {
1272           best_i4_mode = mode;
1273           best_i4_score = score;
1274         }
1275       }
1276       i4_bit_sum += mode_costs[best_i4_mode];
1277       rd->modes_i4[it->i4_] = best_i4_mode;
1278       score_i4 += best_i4_score;
1279       if (score_i4 >= best_score || i4_bit_sum > bit_limit) {
1280         // Intra4 won't be better than Intra16. Bail out and pick Intra16.
1281         is_i16 = 1;
1282         break;
1283       } else {  // reconstruct partial block inside yuv_out2_ buffer
1284         uint8_t* const tmp_dst = it->yuv_out2_ + Y_OFF_ENC + VP8Scan[it->i4_];
1285         nz |= ReconstructIntra4(it, rd->y_ac_levels[it->i4_],
1286                                 src, tmp_dst, best_i4_mode) << it->i4_;
1287       }
1288     } while (VP8IteratorRotateI4(it, it->yuv_out2_ + Y_OFF_ENC));
1289   }
1290 
1291   // Final reconstruction, depending on which mode is selected.
1292   if (!is_i16) {
1293     VP8SetIntra4Mode(it, rd->modes_i4);
1294     SwapOut(it);
1295     best_score = score_i4;
1296   } else {
1297     nz = ReconstructIntra16(it, rd, it->yuv_out_ + Y_OFF_ENC, it->preds_[0]);
1298   }
1299 
1300   // ... and UV!
1301   if (refine_uv_mode) {
1302     int best_mode = -1;
1303     score_t best_uv_score = MAX_COST;
1304     const uint8_t* const src = it->yuv_in_ + U_OFF_ENC;
1305     for (mode = 0; mode < NUM_PRED_MODES; ++mode) {
1306       const uint8_t* const ref = it->yuv_p_ + VP8UVModeOffsets[mode];
1307       const score_t score = VP8SSE16x8(src, ref) * RD_DISTO_MULT
1308                           + VP8FixedCostsUV[mode] * lambda_d_uv;
1309       if (score < best_uv_score) {
1310         best_mode = mode;
1311         best_uv_score = score;
1312       }
1313     }
1314     VP8SetIntraUVMode(it, best_mode);
1315   }
1316   nz |= ReconstructUV(it, rd, it->yuv_out_ + U_OFF_ENC, it->mb_->uv_mode_);
1317 
1318   rd->nz = nz;
1319   rd->score = best_score;
1320 }
1321 
1322 //------------------------------------------------------------------------------
1323 // Entry point
1324 
VP8Decimate(VP8EncIterator * const it,VP8ModeScore * const rd,VP8RDLevel rd_opt)1325 int VP8Decimate(VP8EncIterator* const it, VP8ModeScore* const rd,
1326                 VP8RDLevel rd_opt) {
1327   int is_skipped;
1328   const int method = it->enc_->method_;
1329 
1330   InitScore(rd);
1331 
1332   // We can perform predictions for Luma16x16 and Chroma8x8 already.
1333   // Luma4x4 predictions needs to be done as-we-go.
1334   VP8MakeLuma16Preds(it);
1335   VP8MakeChroma8Preds(it);
1336 
1337   if (rd_opt > RD_OPT_NONE) {
1338     it->do_trellis_ = (rd_opt >= RD_OPT_TRELLIS_ALL);
1339     PickBestIntra16(it, rd);
1340     if (method >= 2) {
1341       PickBestIntra4(it, rd);
1342     }
1343     PickBestUV(it, rd);
1344     if (rd_opt == RD_OPT_TRELLIS) {   // finish off with trellis-optim now
1345       it->do_trellis_ = 1;
1346       SimpleQuantize(it, rd);
1347     }
1348   } else {
1349     // At this point we have heuristically decided intra16 / intra4.
1350     // For method >= 2, pick the best intra4/intra16 based on SSE (~tad slower).
1351     // For method <= 1, we don't re-examine the decision but just go ahead with
1352     // quantization/reconstruction.
1353     RefineUsingDistortion(it, (method >= 2), (method >= 1), rd);
1354   }
1355   is_skipped = (rd->nz == 0);
1356   VP8SetSkip(it, is_skipped);
1357   return is_skipped;
1358 }
1359