Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(165)

Side by Side Diff: third_party/libwebp/enc/filter.c

Issue 116213006: Update libwebp to 0.4.0 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: After Blink Roll Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « third_party/libwebp/enc/cost.c ('k') | third_party/libwebp/enc/frame.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
11 // 11 //
12 // Author: somnath@google.com (Somnath Banerjee) 12 // Author: somnath@google.com (Somnath Banerjee)
13 13
14 #include <assert.h>
14 #include "./vp8enci.h" 15 #include "./vp8enci.h"
15 16
16 #if defined(__cplusplus) || defined(c_plusplus) 17 // This table gives, for a given sharpness, the filtering strength to be
17 extern "C" { 18 // used (at least) in order to filter a given edge step delta.
18 #endif 19 // This is constructed by brute force inspection: for all delta, we iterate
20 // over all possible filtering strength / thresh until needs_filter() returns
21 // true.
22 #define MAX_DELTA_SIZE 64
23 static const uint8_t kLevelsFromDelta[8][MAX_DELTA_SIZE] = {
24 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
25 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
26 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
27 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63 },
28 { 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 17, 18,
29 20, 21, 23, 24, 26, 27, 29, 30, 32, 33, 35, 36, 38, 39, 41, 42,
30 44, 45, 47, 48, 50, 51, 53, 54, 56, 57, 59, 60, 62, 63, 63, 63,
31 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63 },
32 { 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 13, 14, 16, 17, 19,
33 20, 22, 23, 25, 26, 28, 29, 31, 32, 34, 35, 37, 38, 40, 41, 43,
34 44, 46, 47, 49, 50, 52, 53, 55, 56, 58, 59, 61, 62, 63, 63, 63,
35 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63 },
36 { 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 13, 15, 16, 18, 19,
37 21, 22, 24, 25, 27, 28, 30, 31, 33, 34, 36, 37, 39, 40, 42, 43,
38 45, 46, 48, 49, 51, 52, 54, 55, 57, 58, 60, 61, 63, 63, 63, 63,
39 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63 },
40 { 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 14, 15, 17, 18, 20,
41 21, 23, 24, 26, 27, 29, 30, 32, 33, 35, 36, 38, 39, 41, 42, 44,
42 45, 47, 48, 50, 51, 53, 54, 56, 57, 59, 60, 62, 63, 63, 63, 63,
43 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63 },
44 { 0, 1, 2, 4, 5, 7, 8, 9, 11, 12, 13, 15, 16, 17, 19, 20,
45 22, 23, 25, 26, 28, 29, 31, 32, 34, 35, 37, 38, 40, 41, 43, 44,
46 46, 47, 49, 50, 52, 53, 55, 56, 58, 59, 61, 62, 63, 63, 63, 63,
47 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63 },
48 { 0, 1, 2, 4, 5, 7, 8, 9, 11, 12, 13, 15, 16, 18, 19, 21,
49 22, 24, 25, 27, 28, 30, 31, 33, 34, 36, 37, 39, 40, 42, 43, 45,
50 46, 48, 49, 51, 52, 54, 55, 57, 58, 60, 61, 63, 63, 63, 63, 63,
51 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63 },
52 { 0, 1, 2, 4, 5, 7, 8, 9, 11, 12, 14, 15, 17, 18, 20, 21,
53 23, 24, 26, 27, 29, 30, 32, 33, 35, 36, 38, 39, 41, 42, 44, 45,
54 47, 48, 50, 51, 53, 54, 56, 57, 59, 60, 62, 63, 63, 63, 63, 63,
55 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63 }
56 };
19 57
58 int VP8FilterStrengthFromDelta(int sharpness, int delta) {
59 const int pos = (delta < MAX_DELTA_SIZE) ? delta : MAX_DELTA_SIZE - 1;
60 assert(sharpness >= 0 && sharpness <= 7);
61 return kLevelsFromDelta[sharpness][pos];
62 }
63
64 // -----------------------------------------------------------------------------
20 // NOTE: clip1, tables and InitTables are repeated entries of dsp.c 65 // NOTE: clip1, tables and InitTables are repeated entries of dsp.c
21 static uint8_t abs0[255 + 255 + 1]; // abs(i) 66 static uint8_t abs0[255 + 255 + 1]; // abs(i)
22 static uint8_t abs1[255 + 255 + 1]; // abs(i)>>1 67 static uint8_t abs1[255 + 255 + 1]; // abs(i)>>1
23 static int8_t sclip1[1020 + 1020 + 1]; // clips [-1020, 1020] to [-128, 127] 68 static int8_t sclip1[1020 + 1020 + 1]; // clips [-1020, 1020] to [-128, 127]
24 static int8_t sclip2[112 + 112 + 1]; // clips [-112, 112] to [-16, 15] 69 static int8_t sclip2[112 + 112 + 1]; // clips [-112, 112] to [-16, 15]
25 static uint8_t clip1[255 + 510 + 1]; // clips [-255,510] to [0,255] 70 static uint8_t clip1[255 + 510 + 1]; // clips [-255,510] to [0,255]
26 71
27 static int tables_ok = 0; 72 static int tables_ok = 0;
28 73
29 static void InitTables(void) { 74 static void InitTables(void) {
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 } 378 }
334 } 379 }
335 return VP8SSIMGet(&s); 380 return VP8SSIMGet(&s);
336 } 381 }
337 382
338 //------------------------------------------------------------------------------ 383 //------------------------------------------------------------------------------
339 // Exposed APIs: Encoder should call the following 3 functions to adjust 384 // Exposed APIs: Encoder should call the following 3 functions to adjust
340 // loop filter strength 385 // loop filter strength
341 386
342 void VP8InitFilter(VP8EncIterator* const it) { 387 void VP8InitFilter(VP8EncIterator* const it) {
343 int s, i; 388 if (it->lf_stats_ != NULL) {
344 if (!it->lf_stats_) return; 389 int s, i;
345 390 InitTables();
346 InitTables(); 391 for (s = 0; s < NUM_MB_SEGMENTS; s++) {
347 for (s = 0; s < NUM_MB_SEGMENTS; s++) { 392 for (i = 0; i < MAX_LF_LEVELS; i++) {
348 for (i = 0; i < MAX_LF_LEVELS; i++) { 393 (*it->lf_stats_)[s][i] = 0;
349 (*it->lf_stats_)[s][i] = 0; 394 }
350 } 395 }
351 } 396 }
352 } 397 }
353 398
354 void VP8StoreFilterStats(VP8EncIterator* const it) { 399 void VP8StoreFilterStats(VP8EncIterator* const it) {
355 int d; 400 int d;
401 VP8Encoder* const enc = it->enc_;
356 const int s = it->mb_->segment_; 402 const int s = it->mb_->segment_;
357 const int level0 = it->enc_->dqm_[s].fstrength_; // TODO: ref_lf_delta[] 403 const int level0 = enc->dqm_[s].fstrength_; // TODO: ref_lf_delta[]
358 404
359 // explore +/-quant range of values around level0 405 // explore +/-quant range of values around level0
360 const int delta_min = -it->enc_->dqm_[s].quant_; 406 const int delta_min = -enc->dqm_[s].quant_;
361 const int delta_max = it->enc_->dqm_[s].quant_; 407 const int delta_max = enc->dqm_[s].quant_;
362 const int step_size = (delta_max - delta_min >= 4) ? 4 : 1; 408 const int step_size = (delta_max - delta_min >= 4) ? 4 : 1;
363 409
364 if (!it->lf_stats_) return; 410 if (it->lf_stats_ == NULL) return;
365 411
366 // NOTE: Currently we are applying filter only across the sublock edges 412 // NOTE: Currently we are applying filter only across the sublock edges
367 // There are two reasons for that. 413 // There are two reasons for that.
368 // 1. Applying filter on macro block edges will change the pixels in 414 // 1. Applying filter on macro block edges will change the pixels in
369 // the left and top macro blocks. That will be hard to restore 415 // the left and top macro blocks. That will be hard to restore
370 // 2. Macro Blocks on the bottom and right are not yet compressed. So we 416 // 2. Macro Blocks on the bottom and right are not yet compressed. So we
371 // cannot apply filter on the right and bottom macro block edges. 417 // cannot apply filter on the right and bottom macro block edges.
372 if (it->mb_->type_ == 1 && it->mb_->skip_) return; 418 if (it->mb_->type_ == 1 && it->mb_->skip_) return;
373 419
374 // Always try filter level zero 420 // Always try filter level zero
375 (*it->lf_stats_)[s][0] += GetMBSSIM(it->yuv_in_, it->yuv_out_); 421 (*it->lf_stats_)[s][0] += GetMBSSIM(it->yuv_in_, it->yuv_out_);
376 422
377 for (d = delta_min; d <= delta_max; d += step_size) { 423 for (d = delta_min; d <= delta_max; d += step_size) {
378 const int level = level0 + d; 424 const int level = level0 + d;
379 if (level <= 0 || level >= MAX_LF_LEVELS) { 425 if (level <= 0 || level >= MAX_LF_LEVELS) {
380 continue; 426 continue;
381 } 427 }
382 DoFilter(it, level); 428 DoFilter(it, level);
383 (*it->lf_stats_)[s][level] += GetMBSSIM(it->yuv_in_, it->yuv_out2_); 429 (*it->lf_stats_)[s][level] += GetMBSSIM(it->yuv_in_, it->yuv_out2_);
384 } 430 }
385 } 431 }
386 432
387 void VP8AdjustFilterStrength(VP8EncIterator* const it) { 433 void VP8AdjustFilterStrength(VP8EncIterator* const it) {
388 int s;
389 VP8Encoder* const enc = it->enc_; 434 VP8Encoder* const enc = it->enc_;
390 435 if (it->lf_stats_ != NULL) {
391 if (!it->lf_stats_) { 436 int s;
392 return; 437 for (s = 0; s < NUM_MB_SEGMENTS; s++) {
393 } 438 int i, best_level = 0;
394 for (s = 0; s < NUM_MB_SEGMENTS; s++) { 439 // Improvement over filter level 0 should be at least 1e-5 (relatively)
395 int i, best_level = 0; 440 double best_v = 1.00001 * (*it->lf_stats_)[s][0];
396 // Improvement over filter level 0 should be at least 1e-5 (relatively) 441 for (i = 1; i < MAX_LF_LEVELS; i++) {
397 double best_v = 1.00001 * (*it->lf_stats_)[s][0]; 442 const double v = (*it->lf_stats_)[s][i];
398 for (i = 1; i < MAX_LF_LEVELS; i++) { 443 if (v > best_v) {
399 const double v = (*it->lf_stats_)[s][i]; 444 best_v = v;
400 if (v > best_v) { 445 best_level = i;
401 best_v = v; 446 }
402 best_level = i; 447 }
448 enc->dqm_[s].fstrength_ = best_level;
449 }
450 } else if (enc->config_->filter_strength > 0) {
451 int max_level = 0;
452 int s;
453 for (s = 0; s < NUM_MB_SEGMENTS; s++) {
454 VP8SegmentInfo* const dqm = &enc->dqm_[s];
455 // this '>> 3' accounts for some inverse WHT scaling
456 const int delta = (dqm->max_edge_ * dqm->y2_.q_[1]) >> 3;
457 const int level =
458 VP8FilterStrengthFromDelta(enc->filter_hdr_.sharpness_, delta);
459 if (level > dqm->fstrength_) {
460 dqm->fstrength_ = level;
461 }
462 if (max_level < dqm->fstrength_) {
463 max_level = dqm->fstrength_;
403 } 464 }
404 } 465 }
405 enc->dqm_[s].fstrength_ = best_level; 466 enc->filter_hdr_.level_ = max_level;
406 } 467 }
407 } 468 }
408 469
409 #if defined(__cplusplus) || defined(c_plusplus) 470 // -----------------------------------------------------------------------------
410 } // extern "C" 471
411 #endif
OLDNEW
« no previous file with comments | « third_party/libwebp/enc/cost.c ('k') | third_party/libwebp/enc/frame.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698