OLD | NEW |
1 // Copyright 2011 Google Inc. All Rights Reserved. | 1 // Copyright 2011 Google Inc. All Rights Reserved. |
2 // | 2 // |
3 // This code is licensed under the same terms as WebM: | 3 // This code is licensed under the same terms as WebM: |
4 // Software License Agreement: http://www.webmproject.org/license/software/ | 4 // Software License Agreement: http://www.webmproject.org/license/software/ |
5 // Additional IP Rights Grant: http://www.webmproject.org/license/additional/ | 5 // Additional IP Rights Grant: http://www.webmproject.org/license/additional/ |
6 // ----------------------------------------------------------------------------- | 6 // ----------------------------------------------------------------------------- |
7 // | 7 // |
8 // Macroblock analysis | 8 // Macroblock analysis |
9 // | 9 // |
10 // Author: Skal (pascal.massimino@gmail.com) | 10 // Author: Skal (pascal.massimino@gmail.com) |
11 | 11 |
12 #include <stdlib.h> | 12 #include <stdlib.h> |
13 #include <string.h> | 13 #include <string.h> |
14 #include <assert.h> | 14 #include <assert.h> |
15 | 15 |
16 #include "./vp8enci.h" | 16 #include "./vp8enci.h" |
17 #include "./cost.h" | 17 #include "./cost.h" |
18 #include "../utils/utils.h" | 18 #include "../utils/utils.h" |
19 | 19 |
20 #if defined(__cplusplus) || defined(c_plusplus) | 20 #if defined(__cplusplus) || defined(c_plusplus) |
21 extern "C" { | 21 extern "C" { |
22 #endif | 22 #endif |
23 | 23 |
24 #define MAX_ITERS_K_MEANS 6 | 24 #define MAX_ITERS_K_MEANS 6 |
25 | 25 |
26 static int ClipAlpha(int alpha) { | |
27 return alpha < 0 ? 0 : alpha > 255 ? 255 : alpha; | |
28 } | |
29 | |
30 //------------------------------------------------------------------------------ | 26 //------------------------------------------------------------------------------ |
31 // Smooth the segment map by replacing isolated block by the majority of its | 27 // Smooth the segment map by replacing isolated block by the majority of its |
32 // neighbours. | 28 // neighbours. |
33 | 29 |
34 static void SmoothSegmentMap(VP8Encoder* const enc) { | 30 static void SmoothSegmentMap(VP8Encoder* const enc) { |
35 int n, x, y; | 31 int n, x, y; |
36 const int w = enc->mb_w_; | 32 const int w = enc->mb_w_; |
37 const int h = enc->mb_h_; | 33 const int h = enc->mb_h_; |
38 const int majority_cnt_3_x_3_grid = 5; | 34 const int majority_cnt_3_x_3_grid = 5; |
39 uint8_t* const tmp = (uint8_t*)WebPSafeMalloc((uint64_t)w * h, sizeof(*tmp)); | 35 uint8_t* const tmp = (uint8_t*)WebPSafeMalloc((uint64_t)w * h, sizeof(*tmp)); |
(...skipping 25 matching lines...) Expand all Loading... |
65 for (y = 1; y < h - 1; ++y) { | 61 for (y = 1; y < h - 1; ++y) { |
66 for (x = 1; x < w - 1; ++x) { | 62 for (x = 1; x < w - 1; ++x) { |
67 VP8MBInfo* const mb = &enc->mb_info_[x + w * y]; | 63 VP8MBInfo* const mb = &enc->mb_info_[x + w * y]; |
68 mb->segment_ = tmp[x + y * w]; | 64 mb->segment_ = tmp[x + y * w]; |
69 } | 65 } |
70 } | 66 } |
71 free(tmp); | 67 free(tmp); |
72 } | 68 } |
73 | 69 |
74 //------------------------------------------------------------------------------ | 70 //------------------------------------------------------------------------------ |
75 // Finalize Segment probability based on the coding tree | 71 // set segment susceptibility alpha_ / beta_ |
76 | |
77 static int GetProba(int a, int b) { | |
78 int proba; | |
79 const int total = a + b; | |
80 if (total == 0) return 255; // that's the default probability. | |
81 proba = (255 * a + total / 2) / total; | |
82 return proba; | |
83 } | |
84 | |
85 static void SetSegmentProbas(VP8Encoder* const enc) { | |
86 int p[NUM_MB_SEGMENTS] = { 0 }; | |
87 int n; | |
88 | |
89 for (n = 0; n < enc->mb_w_ * enc->mb_h_; ++n) { | |
90 const VP8MBInfo* const mb = &enc->mb_info_[n]; | |
91 p[mb->segment_]++; | |
92 } | |
93 if (enc->pic_->stats) { | |
94 for (n = 0; n < NUM_MB_SEGMENTS; ++n) { | |
95 enc->pic_->stats->segment_size[n] = p[n]; | |
96 } | |
97 } | |
98 if (enc->segment_hdr_.num_segments_ > 1) { | |
99 uint8_t* const probas = enc->proba_.segments_; | |
100 probas[0] = GetProba(p[0] + p[1], p[2] + p[3]); | |
101 probas[1] = GetProba(p[0], p[1]); | |
102 probas[2] = GetProba(p[2], p[3]); | |
103 | |
104 enc->segment_hdr_.update_map_ = | |
105 (probas[0] != 255) || (probas[1] != 255) || (probas[2] != 255); | |
106 enc->segment_hdr_.size_ = | |
107 p[0] * (VP8BitCost(0, probas[0]) + VP8BitCost(0, probas[1])) + | |
108 p[1] * (VP8BitCost(0, probas[0]) + VP8BitCost(1, probas[1])) + | |
109 p[2] * (VP8BitCost(1, probas[0]) + VP8BitCost(0, probas[2])) + | |
110 p[3] * (VP8BitCost(1, probas[0]) + VP8BitCost(1, probas[2])); | |
111 } else { | |
112 enc->segment_hdr_.update_map_ = 0; | |
113 enc->segment_hdr_.size_ = 0; | |
114 } | |
115 } | |
116 | 72 |
117 static WEBP_INLINE int clip(int v, int m, int M) { | 73 static WEBP_INLINE int clip(int v, int m, int M) { |
118 return v < m ? m : v > M ? M : v; | 74 return (v < m) ? m : (v > M) ? M : v; |
119 } | 75 } |
120 | 76 |
121 static void SetSegmentAlphas(VP8Encoder* const enc, | 77 static void SetSegmentAlphas(VP8Encoder* const enc, |
122 const int centers[NUM_MB_SEGMENTS], | 78 const int centers[NUM_MB_SEGMENTS], |
123 int mid) { | 79 int mid) { |
124 const int nb = enc->segment_hdr_.num_segments_; | 80 const int nb = enc->segment_hdr_.num_segments_; |
125 int min = centers[0], max = centers[0]; | 81 int min = centers[0], max = centers[0]; |
126 int n; | 82 int n; |
127 | 83 |
128 if (nb > 1) { | 84 if (nb > 1) { |
129 for (n = 0; n < nb; ++n) { | 85 for (n = 0; n < nb; ++n) { |
130 if (min > centers[n]) min = centers[n]; | 86 if (min > centers[n]) min = centers[n]; |
131 if (max < centers[n]) max = centers[n]; | 87 if (max < centers[n]) max = centers[n]; |
132 } | 88 } |
133 } | 89 } |
134 if (max == min) max = min + 1; | 90 if (max == min) max = min + 1; |
135 assert(mid <= max && mid >= min); | 91 assert(mid <= max && mid >= min); |
136 for (n = 0; n < nb; ++n) { | 92 for (n = 0; n < nb; ++n) { |
137 const int alpha = 255 * (centers[n] - mid) / (max - min); | 93 const int alpha = 255 * (centers[n] - mid) / (max - min); |
138 const int beta = 255 * (centers[n] - min) / (max - min); | 94 const int beta = 255 * (centers[n] - min) / (max - min); |
139 enc->dqm_[n].alpha_ = clip(alpha, -127, 127); | 95 enc->dqm_[n].alpha_ = clip(alpha, -127, 127); |
140 enc->dqm_[n].beta_ = clip(beta, 0, 255); | 96 enc->dqm_[n].beta_ = clip(beta, 0, 255); |
141 } | 97 } |
142 } | 98 } |
143 | 99 |
144 //------------------------------------------------------------------------------ | 100 //------------------------------------------------------------------------------ |
| 101 // Compute susceptibility based on DCT-coeff histograms: |
| 102 // the higher, the "easier" the macroblock is to compress. |
| 103 |
| 104 #define MAX_ALPHA 255 // 8b of precision for susceptibilities. |
| 105 #define ALPHA_SCALE (2 * MAX_ALPHA) // scaling factor for alpha. |
| 106 #define DEFAULT_ALPHA (-1) |
| 107 #define IS_BETTER_ALPHA(alpha, best_alpha) ((alpha) > (best_alpha)) |
| 108 |
| 109 static int FinalAlphaValue(int alpha) { |
| 110 alpha = MAX_ALPHA - alpha; |
| 111 return clip(alpha, 0, MAX_ALPHA); |
| 112 } |
| 113 |
| 114 static int GetAlpha(const VP8Histogram* const histo) { |
| 115 int max_value = 0, last_non_zero = 1; |
| 116 int k; |
| 117 int alpha; |
| 118 for (k = 0; k <= MAX_COEFF_THRESH; ++k) { |
| 119 const int value = histo->distribution[k]; |
| 120 if (value > 0) { |
| 121 if (value > max_value) max_value = value; |
| 122 last_non_zero = k; |
| 123 } |
| 124 } |
| 125 // 'alpha' will later be clipped to [0..MAX_ALPHA] range, clamping outer |
| 126 // values which happen to be mostly noise. This leaves the maximum precision |
| 127 // for handling the useful small values which contribute most. |
| 128 alpha = (max_value > 1) ? ALPHA_SCALE * last_non_zero / max_value : 0; |
| 129 return alpha; |
| 130 } |
| 131 |
| 132 static void MergeHistograms(const VP8Histogram* const in, |
| 133 VP8Histogram* const out) { |
| 134 int i; |
| 135 for (i = 0; i <= MAX_COEFF_THRESH; ++i) { |
| 136 out->distribution[i] += in->distribution[i]; |
| 137 } |
| 138 } |
| 139 |
| 140 //------------------------------------------------------------------------------ |
145 // Simplified k-Means, to assign Nb segments based on alpha-histogram | 141 // Simplified k-Means, to assign Nb segments based on alpha-histogram |
146 | 142 |
147 static void AssignSegments(VP8Encoder* const enc, const int alphas[256]) { | 143 static void AssignSegments(VP8Encoder* const enc, |
| 144 const int alphas[MAX_ALPHA + 1]) { |
148 const int nb = enc->segment_hdr_.num_segments_; | 145 const int nb = enc->segment_hdr_.num_segments_; |
149 int centers[NUM_MB_SEGMENTS]; | 146 int centers[NUM_MB_SEGMENTS]; |
150 int weighted_average = 0; | 147 int weighted_average = 0; |
151 int map[256]; | 148 int map[MAX_ALPHA + 1]; |
152 int a, n, k; | 149 int a, n, k; |
153 int min_a = 0, max_a = 255, range_a; | 150 int min_a = 0, max_a = MAX_ALPHA, range_a; |
154 // 'int' type is ok for histo, and won't overflow | 151 // 'int' type is ok for histo, and won't overflow |
155 int accum[NUM_MB_SEGMENTS], dist_accum[NUM_MB_SEGMENTS]; | 152 int accum[NUM_MB_SEGMENTS], dist_accum[NUM_MB_SEGMENTS]; |
156 | 153 |
157 // bracket the input | 154 // bracket the input |
158 for (n = 0; n < 256 && alphas[n] == 0; ++n) {} | 155 for (n = 0; n <= MAX_ALPHA && alphas[n] == 0; ++n) {} |
159 min_a = n; | 156 min_a = n; |
160 for (n = 255; n > min_a && alphas[n] == 0; --n) {} | 157 for (n = MAX_ALPHA; n > min_a && alphas[n] == 0; --n) {} |
161 max_a = n; | 158 max_a = n; |
162 range_a = max_a - min_a; | 159 range_a = max_a - min_a; |
163 | 160 |
164 // Spread initial centers evenly | 161 // Spread initial centers evenly |
165 for (n = 1, k = 0; n < 2 * nb; n += 2) { | 162 for (n = 1, k = 0; n < 2 * nb; n += 2) { |
166 centers[k++] = min_a + (n * range_a) / (2 * nb); | 163 centers[k++] = min_a + (n * range_a) / (2 * nb); |
167 } | 164 } |
168 | 165 |
169 for (k = 0; k < MAX_ITERS_K_MEANS; ++k) { // few iters are enough | 166 for (k = 0; k < MAX_ITERS_K_MEANS; ++k) { // few iters are enough |
170 int total_weight; | 167 int total_weight; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 } | 200 } |
204 weighted_average = (weighted_average + total_weight / 2) / total_weight; | 201 weighted_average = (weighted_average + total_weight / 2) / total_weight; |
205 if (displaced < 5) break; // no need to keep on looping... | 202 if (displaced < 5) break; // no need to keep on looping... |
206 } | 203 } |
207 | 204 |
208 // Map each original value to the closest centroid | 205 // Map each original value to the closest centroid |
209 for (n = 0; n < enc->mb_w_ * enc->mb_h_; ++n) { | 206 for (n = 0; n < enc->mb_w_ * enc->mb_h_; ++n) { |
210 VP8MBInfo* const mb = &enc->mb_info_[n]; | 207 VP8MBInfo* const mb = &enc->mb_info_[n]; |
211 const int alpha = mb->alpha_; | 208 const int alpha = mb->alpha_; |
212 mb->segment_ = map[alpha]; | 209 mb->segment_ = map[alpha]; |
213 mb->alpha_ = centers[map[alpha]]; // just for the record. | 210 mb->alpha_ = centers[map[alpha]]; // for the record. |
214 } | 211 } |
215 | 212 |
216 if (nb > 1) { | 213 if (nb > 1) { |
217 const int smooth = (enc->config_->preprocessing & 1); | 214 const int smooth = (enc->config_->preprocessing & 1); |
218 if (smooth) SmoothSegmentMap(enc); | 215 if (smooth) SmoothSegmentMap(enc); |
219 } | 216 } |
220 | 217 |
221 SetSegmentProbas(enc); // Assign final proba | |
222 SetSegmentAlphas(enc, centers, weighted_average); // pick some alphas. | 218 SetSegmentAlphas(enc, centers, weighted_average); // pick some alphas. |
223 } | 219 } |
224 | 220 |
225 //------------------------------------------------------------------------------ | 221 //------------------------------------------------------------------------------ |
226 // Macroblock analysis: collect histogram for each mode, deduce the maximal | 222 // Macroblock analysis: collect histogram for each mode, deduce the maximal |
227 // susceptibility and set best modes for this macroblock. | 223 // susceptibility and set best modes for this macroblock. |
228 // Segment assignment is done later. | 224 // Segment assignment is done later. |
229 | 225 |
230 // Number of modes to inspect for alpha_ evaluation. For high-quality settings, | 226 // Number of modes to inspect for alpha_ evaluation. For high-quality settings |
231 // we don't need to test all the possible modes during the analysis phase. | 227 // (method >= FAST_ANALYSIS_METHOD) we don't need to test all the possible modes |
| 228 // during the analysis phase. |
| 229 #define FAST_ANALYSIS_METHOD 4 // method above which we do partial analysis |
232 #define MAX_INTRA16_MODE 2 | 230 #define MAX_INTRA16_MODE 2 |
233 #define MAX_INTRA4_MODE 2 | 231 #define MAX_INTRA4_MODE 2 |
234 #define MAX_UV_MODE 2 | 232 #define MAX_UV_MODE 2 |
235 | 233 |
236 static int MBAnalyzeBestIntra16Mode(VP8EncIterator* const it) { | 234 static int MBAnalyzeBestIntra16Mode(VP8EncIterator* const it) { |
237 const int max_mode = (it->enc_->method_ >= 3) ? MAX_INTRA16_MODE : 4; | 235 const int max_mode = |
| 236 (it->enc_->method_ >= FAST_ANALYSIS_METHOD) ? MAX_INTRA16_MODE |
| 237 : NUM_PRED_MODES; |
238 int mode; | 238 int mode; |
239 int best_alpha = -1; | 239 int best_alpha = DEFAULT_ALPHA; |
240 int best_mode = 0; | 240 int best_mode = 0; |
241 | 241 |
242 VP8MakeLuma16Preds(it); | 242 VP8MakeLuma16Preds(it); |
243 for (mode = 0; mode < max_mode; ++mode) { | 243 for (mode = 0; mode < max_mode; ++mode) { |
244 const int alpha = VP8CollectHistogram(it->yuv_in_ + Y_OFF, | 244 VP8Histogram histo = { { 0 } }; |
245 it->yuv_p_ + VP8I16ModeOffsets[mode], | 245 int alpha; |
246 0, 16); | 246 |
247 if (alpha > best_alpha) { | 247 VP8CollectHistogram(it->yuv_in_ + Y_OFF, |
| 248 it->yuv_p_ + VP8I16ModeOffsets[mode], |
| 249 0, 16, &histo); |
| 250 alpha = GetAlpha(&histo); |
| 251 if (IS_BETTER_ALPHA(alpha, best_alpha)) { |
248 best_alpha = alpha; | 252 best_alpha = alpha; |
249 best_mode = mode; | 253 best_mode = mode; |
250 } | 254 } |
251 } | 255 } |
252 VP8SetIntra16Mode(it, best_mode); | 256 VP8SetIntra16Mode(it, best_mode); |
253 return best_alpha; | 257 return best_alpha; |
254 } | 258 } |
255 | 259 |
256 static int MBAnalyzeBestIntra4Mode(VP8EncIterator* const it, | 260 static int MBAnalyzeBestIntra4Mode(VP8EncIterator* const it, |
257 int best_alpha) { | 261 int best_alpha) { |
258 uint8_t modes[16]; | 262 uint8_t modes[16]; |
259 const int max_mode = (it->enc_->method_ >= 3) ? MAX_INTRA4_MODE : NUM_BMODES; | 263 const int max_mode = |
260 int i4_alpha = 0; | 264 (it->enc_->method_ >= FAST_ANALYSIS_METHOD) ? MAX_INTRA4_MODE |
| 265 : NUM_BMODES; |
| 266 int i4_alpha; |
| 267 VP8Histogram total_histo = { { 0 } }; |
| 268 int cur_histo = 0; |
| 269 |
261 VP8IteratorStartI4(it); | 270 VP8IteratorStartI4(it); |
262 do { | 271 do { |
263 int mode; | 272 int mode; |
264 int best_mode_alpha = -1; | 273 int best_mode_alpha = DEFAULT_ALPHA; |
| 274 VP8Histogram histos[2]; |
265 const uint8_t* const src = it->yuv_in_ + Y_OFF + VP8Scan[it->i4_]; | 275 const uint8_t* const src = it->yuv_in_ + Y_OFF + VP8Scan[it->i4_]; |
266 | 276 |
267 VP8MakeIntra4Preds(it); | 277 VP8MakeIntra4Preds(it); |
268 for (mode = 0; mode < max_mode; ++mode) { | 278 for (mode = 0; mode < max_mode; ++mode) { |
269 const int alpha = VP8CollectHistogram(src, | 279 int alpha; |
270 it->yuv_p_ + VP8I4ModeOffsets[mode], | 280 |
271 0, 1); | 281 memset(&histos[cur_histo], 0, sizeof(histos[cur_histo])); |
272 if (alpha > best_mode_alpha) { | 282 VP8CollectHistogram(src, it->yuv_p_ + VP8I4ModeOffsets[mode], |
| 283 0, 1, &histos[cur_histo]); |
| 284 alpha = GetAlpha(&histos[cur_histo]); |
| 285 if (IS_BETTER_ALPHA(alpha, best_mode_alpha)) { |
273 best_mode_alpha = alpha; | 286 best_mode_alpha = alpha; |
274 modes[it->i4_] = mode; | 287 modes[it->i4_] = mode; |
| 288 cur_histo ^= 1; // keep track of best histo so far. |
275 } | 289 } |
276 } | 290 } |
277 i4_alpha += best_mode_alpha; | 291 // accumulate best histogram |
| 292 MergeHistograms(&histos[cur_histo ^ 1], &total_histo); |
278 // Note: we reuse the original samples for predictors | 293 // Note: we reuse the original samples for predictors |
279 } while (VP8IteratorRotateI4(it, it->yuv_in_ + Y_OFF)); | 294 } while (VP8IteratorRotateI4(it, it->yuv_in_ + Y_OFF)); |
280 | 295 |
281 if (i4_alpha > best_alpha) { | 296 i4_alpha = GetAlpha(&total_histo); |
| 297 if (IS_BETTER_ALPHA(i4_alpha, best_alpha)) { |
282 VP8SetIntra4Mode(it, modes); | 298 VP8SetIntra4Mode(it, modes); |
283 best_alpha = ClipAlpha(i4_alpha); | 299 best_alpha = i4_alpha; |
284 } | 300 } |
285 return best_alpha; | 301 return best_alpha; |
286 } | 302 } |
287 | 303 |
288 static int MBAnalyzeBestUVMode(VP8EncIterator* const it) { | 304 static int MBAnalyzeBestUVMode(VP8EncIterator* const it) { |
289 int best_alpha = -1; | 305 int best_alpha = DEFAULT_ALPHA; |
290 int best_mode = 0; | 306 int best_mode = 0; |
291 const int max_mode = (it->enc_->method_ >= 3) ? MAX_UV_MODE : 4; | 307 const int max_mode = |
| 308 (it->enc_->method_ >= FAST_ANALYSIS_METHOD) ? MAX_UV_MODE |
| 309 : NUM_PRED_MODES; |
292 int mode; | 310 int mode; |
293 VP8MakeChroma8Preds(it); | 311 VP8MakeChroma8Preds(it); |
294 for (mode = 0; mode < max_mode; ++mode) { | 312 for (mode = 0; mode < max_mode; ++mode) { |
295 const int alpha = VP8CollectHistogram(it->yuv_in_ + U_OFF, | 313 VP8Histogram histo = { { 0 } }; |
296 it->yuv_p_ + VP8UVModeOffsets[mode], | 314 int alpha; |
297 16, 16 + 4 + 4); | 315 VP8CollectHistogram(it->yuv_in_ + U_OFF, |
298 if (alpha > best_alpha) { | 316 it->yuv_p_ + VP8UVModeOffsets[mode], |
| 317 16, 16 + 4 + 4, &histo); |
| 318 alpha = GetAlpha(&histo); |
| 319 if (IS_BETTER_ALPHA(alpha, best_alpha)) { |
299 best_alpha = alpha; | 320 best_alpha = alpha; |
300 best_mode = mode; | 321 best_mode = mode; |
301 } | 322 } |
302 } | 323 } |
303 VP8SetIntraUVMode(it, best_mode); | 324 VP8SetIntraUVMode(it, best_mode); |
304 return best_alpha; | 325 return best_alpha; |
305 } | 326 } |
306 | 327 |
307 static void MBAnalyze(VP8EncIterator* const it, | 328 static void MBAnalyze(VP8EncIterator* const it, |
308 int alphas[256], int* const uv_alpha) { | 329 int alphas[MAX_ALPHA + 1], |
| 330 int* const alpha, int* const uv_alpha) { |
309 const VP8Encoder* const enc = it->enc_; | 331 const VP8Encoder* const enc = it->enc_; |
310 int best_alpha, best_uv_alpha; | 332 int best_alpha, best_uv_alpha; |
311 | 333 |
312 VP8SetIntra16Mode(it, 0); // default: Intra16, DC_PRED | 334 VP8SetIntra16Mode(it, 0); // default: Intra16, DC_PRED |
313 VP8SetSkip(it, 0); // not skipped | 335 VP8SetSkip(it, 0); // not skipped |
314 VP8SetSegment(it, 0); // default segment, spec-wise. | 336 VP8SetSegment(it, 0); // default segment, spec-wise. |
315 | 337 |
316 best_alpha = MBAnalyzeBestIntra16Mode(it); | 338 best_alpha = MBAnalyzeBestIntra16Mode(it); |
317 if (enc->method_ != 3) { | 339 if (enc->method_ >= 5) { |
318 // We go and make a fast decision for intra4/intra16. | 340 // We go and make a fast decision for intra4/intra16. |
319 // It's usually not a good and definitive pick, but helps seeding the stats | 341 // It's usually not a good and definitive pick, but helps seeding the stats |
320 // about level bit-cost. | 342 // about level bit-cost. |
321 // TODO(skal): improve criterion. | 343 // TODO(skal): improve criterion. |
322 best_alpha = MBAnalyzeBestIntra4Mode(it, best_alpha); | 344 best_alpha = MBAnalyzeBestIntra4Mode(it, best_alpha); |
323 } | 345 } |
324 best_uv_alpha = MBAnalyzeBestUVMode(it); | 346 best_uv_alpha = MBAnalyzeBestUVMode(it); |
325 | 347 |
326 // Final susceptibility mix | 348 // Final susceptibility mix |
327 best_alpha = (best_alpha + best_uv_alpha + 1) / 2; | 349 best_alpha = (3 * best_alpha + best_uv_alpha + 2) >> 2; |
| 350 best_alpha = FinalAlphaValue(best_alpha); |
328 alphas[best_alpha]++; | 351 alphas[best_alpha]++; |
| 352 it->mb_->alpha_ = best_alpha; // for later remapping. |
| 353 |
| 354 // Accumulate for later complexity analysis. |
| 355 *alpha += best_alpha; // mixed susceptibility (not just luma) |
329 *uv_alpha += best_uv_alpha; | 356 *uv_alpha += best_uv_alpha; |
330 it->mb_->alpha_ = best_alpha; // Informative only. | 357 } |
| 358 |
| 359 static void DefaultMBInfo(VP8MBInfo* const mb) { |
| 360 mb->type_ = 1; // I16x16 |
| 361 mb->uv_mode_ = 0; |
| 362 mb->skip_ = 0; // not skipped |
| 363 mb->segment_ = 0; // default segment |
| 364 mb->alpha_ = 0; |
331 } | 365 } |
332 | 366 |
333 //------------------------------------------------------------------------------ | 367 //------------------------------------------------------------------------------ |
334 // Main analysis loop: | 368 // Main analysis loop: |
335 // Collect all susceptibilities for each macroblock and record their | 369 // Collect all susceptibilities for each macroblock and record their |
336 // distribution in alphas[]. Segments is assigned a-posteriori, based on | 370 // distribution in alphas[]. Segments is assigned a-posteriori, based on |
337 // this histogram. | 371 // this histogram. |
338 // We also pick an intra16 prediction mode, which shouldn't be considered | 372 // We also pick an intra16 prediction mode, which shouldn't be considered |
339 // final except for fast-encode settings. We can also pick some intra4 modes | 373 // final except for fast-encode settings. We can also pick some intra4 modes |
340 // and decide intra4/intra16, but that's usually almost always a bad choice at | 374 // and decide intra4/intra16, but that's usually almost always a bad choice at |
341 // this stage. | 375 // this stage. |
342 | 376 |
| 377 static void ResetAllMBInfo(VP8Encoder* const enc) { |
| 378 int n; |
| 379 for (n = 0; n < enc->mb_w_ * enc->mb_h_; ++n) { |
| 380 DefaultMBInfo(&enc->mb_info_[n]); |
| 381 } |
| 382 // Default susceptibilities. |
| 383 enc->dqm_[0].alpha_ = 0; |
| 384 enc->dqm_[0].beta_ = 0; |
| 385 // Note: we can't compute this alpha_ / uv_alpha_. |
| 386 WebPReportProgress(enc->pic_, enc->percent_ + 20, &enc->percent_); |
| 387 } |
| 388 |
343 int VP8EncAnalyze(VP8Encoder* const enc) { | 389 int VP8EncAnalyze(VP8Encoder* const enc) { |
344 int ok = 1; | 390 int ok = 1; |
345 int alphas[256] = { 0 }; | 391 const int do_segments = |
346 VP8EncIterator it; | 392 enc->config_->emulate_jpeg_size || // We need the complexity evaluation. |
| 393 (enc->segment_hdr_.num_segments_ > 1) || |
| 394 (enc->method_ == 0); // for method 0, we need preds_[] to be filled. |
| 395 enc->alpha_ = 0; |
| 396 enc->uv_alpha_ = 0; |
| 397 if (do_segments) { |
| 398 int alphas[MAX_ALPHA + 1] = { 0 }; |
| 399 VP8EncIterator it; |
347 | 400 |
348 VP8IteratorInit(enc, &it); | 401 VP8IteratorInit(enc, &it); |
349 enc->uv_alpha_ = 0; | 402 do { |
350 do { | 403 VP8IteratorImport(&it); |
351 VP8IteratorImport(&it); | 404 MBAnalyze(&it, alphas, &enc->alpha_, &enc->uv_alpha_); |
352 MBAnalyze(&it, alphas, &enc->uv_alpha_); | 405 ok = VP8IteratorProgress(&it, 20); |
353 ok = VP8IteratorProgress(&it, 20); | 406 // Let's pretend we have perfect lossless reconstruction. |
354 // Let's pretend we have perfect lossless reconstruction. | 407 } while (ok && VP8IteratorNext(&it, it.yuv_in_)); |
355 } while (ok && VP8IteratorNext(&it, it.yuv_in_)); | 408 enc->alpha_ /= enc->mb_w_ * enc->mb_h_; |
356 enc->uv_alpha_ /= enc->mb_w_ * enc->mb_h_; | 409 enc->uv_alpha_ /= enc->mb_w_ * enc->mb_h_; |
357 if (ok) AssignSegments(enc, alphas); | 410 if (ok) AssignSegments(enc, alphas); |
358 | 411 } else { // Use only one default segment. |
| 412 ResetAllMBInfo(enc); |
| 413 } |
359 return ok; | 414 return ok; |
360 } | 415 } |
361 | 416 |
362 #if defined(__cplusplus) || defined(c_plusplus) | 417 #if defined(__cplusplus) || defined(c_plusplus) |
363 } // extern "C" | 418 } // extern "C" |
364 #endif | 419 #endif |
OLD | NEW |