OLD | NEW |
1 // Copyright 2011 Google Inc. All Rights Reserved. | 1 // Copyright 2011 Google Inc. All Rights Reserved. |
2 // | 2 // |
3 // Use of this source code is governed by a BSD-style license | 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 | 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 | 5 // tree. An additional intellectual property rights grant can be found |
6 // in the file PATENTS. All contributing project authors may | 6 // in the file PATENTS. All contributing project authors may |
7 // be found in the AUTHORS file in the root of the source tree. | 7 // be found in the AUTHORS file in the root of the source tree. |
8 // ----------------------------------------------------------------------------- | 8 // ----------------------------------------------------------------------------- |
9 // | 9 // |
10 // Selecting filter level | 10 // Selecting filter level |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 } | 78 } |
79 if (level < 1) level = 1; | 79 if (level < 1) level = 1; |
80 return level; | 80 return level; |
81 } | 81 } |
82 | 82 |
83 static void DoFilter(const VP8EncIterator* const it, int level) { | 83 static void DoFilter(const VP8EncIterator* const it, int level) { |
84 const VP8Encoder* const enc = it->enc_; | 84 const VP8Encoder* const enc = it->enc_; |
85 const int ilevel = GetILevel(enc->config_->filter_sharpness, level); | 85 const int ilevel = GetILevel(enc->config_->filter_sharpness, level); |
86 const int limit = 2 * level + ilevel; | 86 const int limit = 2 * level + ilevel; |
87 | 87 |
88 uint8_t* const y_dst = it->yuv_out2_ + Y_OFF; | 88 uint8_t* const y_dst = it->yuv_out2_ + Y_OFF_ENC; |
89 uint8_t* const u_dst = it->yuv_out2_ + U_OFF; | 89 uint8_t* const u_dst = it->yuv_out2_ + U_OFF_ENC; |
90 uint8_t* const v_dst = it->yuv_out2_ + V_OFF; | 90 uint8_t* const v_dst = it->yuv_out2_ + V_OFF_ENC; |
91 | 91 |
92 // copy current block to yuv_out2_ | 92 // copy current block to yuv_out2_ |
93 memcpy(y_dst, it->yuv_out_, YUV_SIZE * sizeof(uint8_t)); | 93 memcpy(y_dst, it->yuv_out_, YUV_SIZE_ENC * sizeof(uint8_t)); |
94 | 94 |
95 if (enc->filter_hdr_.simple_ == 1) { // simple | 95 if (enc->filter_hdr_.simple_ == 1) { // simple |
96 VP8SimpleHFilter16i(y_dst, BPS, limit); | 96 VP8SimpleHFilter16i(y_dst, BPS, limit); |
97 VP8SimpleVFilter16i(y_dst, BPS, limit); | 97 VP8SimpleVFilter16i(y_dst, BPS, limit); |
98 } else { // complex | 98 } else { // complex |
99 const int hev_thresh = (level >= 40) ? 2 : (level >= 15) ? 1 : 0; | 99 const int hev_thresh = (level >= 40) ? 2 : (level >= 15) ? 1 : 0; |
100 VP8HFilter16i(y_dst, BPS, limit, ilevel, hev_thresh); | 100 VP8HFilter16i(y_dst, BPS, limit, ilevel, hev_thresh); |
101 VP8HFilter8i(u_dst, v_dst, BPS, limit, ilevel, hev_thresh); | 101 VP8HFilter8i(u_dst, v_dst, BPS, limit, ilevel, hev_thresh); |
102 VP8VFilter16i(y_dst, BPS, limit, ilevel, hev_thresh); | 102 VP8VFilter16i(y_dst, BPS, limit, ilevel, hev_thresh); |
103 VP8VFilter8i(u_dst, v_dst, BPS, limit, ilevel, hev_thresh); | 103 VP8VFilter8i(u_dst, v_dst, BPS, limit, ilevel, hev_thresh); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 } | 188 } |
189 } | 189 } |
190 | 190 |
191 static double GetMBSSIM(const uint8_t* yuv1, const uint8_t* yuv2) { | 191 static double GetMBSSIM(const uint8_t* yuv1, const uint8_t* yuv2) { |
192 int x, y; | 192 int x, y; |
193 DistoStats s = { .0, .0, .0, .0, .0, .0 }; | 193 DistoStats s = { .0, .0, .0, .0, .0, .0 }; |
194 | 194 |
195 // compute SSIM in a 10 x 10 window | 195 // compute SSIM in a 10 x 10 window |
196 for (x = 3; x < 13; x++) { | 196 for (x = 3; x < 13; x++) { |
197 for (y = 3; y < 13; y++) { | 197 for (y = 3; y < 13; y++) { |
198 VP8SSIMAccumulate(yuv1 + Y_OFF, BPS, yuv2 + Y_OFF, BPS, x, y, 16, 16, &s); | 198 VP8SSIMAccumulate(yuv1 + Y_OFF_ENC, BPS, yuv2 + Y_OFF_ENC, BPS, |
| 199 x, y, 16, 16, &s); |
199 } | 200 } |
200 } | 201 } |
201 for (x = 1; x < 7; x++) { | 202 for (x = 1; x < 7; x++) { |
202 for (y = 1; y < 7; y++) { | 203 for (y = 1; y < 7; y++) { |
203 VP8SSIMAccumulate(yuv1 + U_OFF, BPS, yuv2 + U_OFF, BPS, x, y, 8, 8, &s); | 204 VP8SSIMAccumulate(yuv1 + U_OFF_ENC, BPS, yuv2 + U_OFF_ENC, BPS, |
204 VP8SSIMAccumulate(yuv1 + V_OFF, BPS, yuv2 + V_OFF, BPS, x, y, 8, 8, &s); | 205 x, y, 8, 8, &s); |
| 206 VP8SSIMAccumulate(yuv1 + V_OFF_ENC, BPS, yuv2 + V_OFF_ENC, BPS, |
| 207 x, y, 8, 8, &s); |
205 } | 208 } |
206 } | 209 } |
207 return VP8SSIMGet(&s); | 210 return VP8SSIMGet(&s); |
208 } | 211 } |
209 | 212 |
210 //------------------------------------------------------------------------------ | 213 //------------------------------------------------------------------------------ |
211 // Exposed APIs: Encoder should call the following 3 functions to adjust | 214 // Exposed APIs: Encoder should call the following 3 functions to adjust |
212 // loop filter strength | 215 // loop filter strength |
213 | 216 |
214 void VP8InitFilter(VP8EncIterator* const it) { | 217 void VP8InitFilter(VP8EncIterator* const it) { |
215 if (it->lf_stats_ != NULL) { | 218 if (it->lf_stats_ != NULL) { |
216 int s, i; | 219 int s, i; |
217 for (s = 0; s < NUM_MB_SEGMENTS; s++) { | 220 for (s = 0; s < NUM_MB_SEGMENTS; s++) { |
218 for (i = 0; i < MAX_LF_LEVELS; i++) { | 221 for (i = 0; i < MAX_LF_LEVELS; i++) { |
219 (*it->lf_stats_)[s][i] = 0; | 222 (*it->lf_stats_)[s][i] = 0; |
220 } | 223 } |
221 } | 224 } |
222 } | 225 } |
223 } | 226 } |
224 | 227 |
225 void VP8StoreFilterStats(VP8EncIterator* const it) { | 228 void VP8StoreFilterStats(VP8EncIterator* const it) { |
226 int d; | 229 int d; |
227 VP8Encoder* const enc = it->enc_; | 230 VP8Encoder* const enc = it->enc_; |
228 const int s = it->mb_->segment_; | 231 const int s = it->mb_->segment_; |
229 const int level0 = enc->dqm_[s].fstrength_; // TODO: ref_lf_delta[] | 232 const int level0 = enc->dqm_[s].fstrength_; |
230 | 233 |
231 // explore +/-quant range of values around level0 | 234 // explore +/-quant range of values around level0 |
232 const int delta_min = -enc->dqm_[s].quant_; | 235 const int delta_min = -enc->dqm_[s].quant_; |
233 const int delta_max = enc->dqm_[s].quant_; | 236 const int delta_max = enc->dqm_[s].quant_; |
234 const int step_size = (delta_max - delta_min >= 4) ? 4 : 1; | 237 const int step_size = (delta_max - delta_min >= 4) ? 4 : 1; |
235 | 238 |
236 if (it->lf_stats_ == NULL) return; | 239 if (it->lf_stats_ == NULL) return; |
237 | 240 |
238 // NOTE: Currently we are applying filter only across the sublock edges | 241 // NOTE: Currently we are applying filter only across the sublock edges |
239 // There are two reasons for that. | 242 // There are two reasons for that. |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 } | 290 } |
288 if (max_level < dqm->fstrength_) { | 291 if (max_level < dqm->fstrength_) { |
289 max_level = dqm->fstrength_; | 292 max_level = dqm->fstrength_; |
290 } | 293 } |
291 } | 294 } |
292 enc->filter_hdr_.level_ = max_level; | 295 enc->filter_hdr_.level_ = max_level; |
293 } | 296 } |
294 } | 297 } |
295 | 298 |
296 // ----------------------------------------------------------------------------- | 299 // ----------------------------------------------------------------------------- |
OLD | NEW |