| 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 |