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

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

Issue 1546003002: libwebp: update to 0.5.0 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase around clang-cl fix Created 5 years 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
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 // frame coding and analysis 10 // frame coding and analysis
11 // 11 //
12 // Author: Skal (pascal.massimino@gmail.com) 12 // Author: Skal (pascal.massimino@gmail.com)
13 13
14 #include <string.h> 14 #include <string.h>
15 #include <math.h> 15 #include <math.h>
16 16
17 #include "./cost.h"
17 #include "./vp8enci.h" 18 #include "./vp8enci.h"
18 #include "./cost.h" 19 #include "../dsp/dsp.h"
19 #include "../webp/format_constants.h" // RIFF constants 20 #include "../webp/format_constants.h" // RIFF constants
20 21
21 #define SEGMENT_VISU 0 22 #define SEGMENT_VISU 0
22 #define DEBUG_SEARCH 0 // useful to track search convergence 23 #define DEBUG_SEARCH 0 // useful to track search convergence
23 24
24 //------------------------------------------------------------------------------ 25 //------------------------------------------------------------------------------
25 // multi-pass convergence 26 // multi-pass convergence
26 27
27 #define HEADER_SIZE_ESTIMATE (RIFF_HEADER_SIZE + CHUNK_HEADER_SIZE + \ 28 #define HEADER_SIZE_ESTIMATE (RIFF_HEADER_SIZE + CHUNK_HEADER_SIZE + \
28 VP8_FRAME_HEADER_SIZE) 29 VP8_FRAME_HEADER_SIZE)
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 s->dq = Clamp(dq, -30.f, 30.f); 75 s->dq = Clamp(dq, -30.f, 30.f);
75 s->last_q = s->q; 76 s->last_q = s->q;
76 s->last_value = s->value; 77 s->last_value = s->value;
77 s->q = Clamp(s->q + s->dq, 0.f, 100.f); 78 s->q = Clamp(s->q + s->dq, 0.f, 100.f);
78 return s->q; 79 return s->q;
79 } 80 }
80 81
81 //------------------------------------------------------------------------------ 82 //------------------------------------------------------------------------------
82 // Tables for level coding 83 // Tables for level coding
83 84
84 const uint8_t VP8EncBands[16 + 1] = {
85 0, 1, 2, 3, 6, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7,
86 0 // sentinel
87 };
88
89 const uint8_t VP8Cat3[] = { 173, 148, 140 }; 85 const uint8_t VP8Cat3[] = { 173, 148, 140 };
90 const uint8_t VP8Cat4[] = { 176, 155, 140, 135 }; 86 const uint8_t VP8Cat4[] = { 176, 155, 140, 135 };
91 const uint8_t VP8Cat5[] = { 180, 157, 141, 134, 130 }; 87 const uint8_t VP8Cat5[] = { 180, 157, 141, 134, 130 };
92 const uint8_t VP8Cat6[] = 88 const uint8_t VP8Cat6[] =
93 { 254, 254, 243, 230, 196, 177, 153, 140, 133, 130, 129 }; 89 { 254, 254, 243, 230, 196, 177, 153, 140, 133, 130, 129 };
94 90
95 //------------------------------------------------------------------------------ 91 //------------------------------------------------------------------------------
96 // Reset the statistics about: number of skips, token proba, level cost,... 92 // Reset the statistics about: number of skips, token proba, level cost,...
97 93
98 static void ResetStats(VP8Encoder* const enc) { 94 static void ResetStats(VP8Encoder* const enc) {
99 VP8Proba* const proba = &enc->proba_; 95 VP8EncProba* const proba = &enc->proba_;
100 VP8CalculateLevelCosts(proba); 96 VP8CalculateLevelCosts(proba);
101 proba->nb_skip_ = 0; 97 proba->nb_skip_ = 0;
102 } 98 }
103 99
104 //------------------------------------------------------------------------------ 100 //------------------------------------------------------------------------------
105 // Skip decision probability 101 // Skip decision probability
106 102
107 #define SKIP_PROBA_THRESHOLD 250 // value below which using skip_proba is OK. 103 #define SKIP_PROBA_THRESHOLD 250 // value below which using skip_proba is OK.
108 104
109 static int CalcSkipProba(uint64_t nb, uint64_t total) { 105 static int CalcSkipProba(uint64_t nb, uint64_t total) {
110 return (int)(total ? (total - nb) * 255 / total : 255); 106 return (int)(total ? (total - nb) * 255 / total : 255);
111 } 107 }
112 108
113 // Returns the bit-cost for coding the skip probability. 109 // Returns the bit-cost for coding the skip probability.
114 static int FinalizeSkipProba(VP8Encoder* const enc) { 110 static int FinalizeSkipProba(VP8Encoder* const enc) {
115 VP8Proba* const proba = &enc->proba_; 111 VP8EncProba* const proba = &enc->proba_;
116 const int nb_mbs = enc->mb_w_ * enc->mb_h_; 112 const int nb_mbs = enc->mb_w_ * enc->mb_h_;
117 const int nb_events = proba->nb_skip_; 113 const int nb_events = proba->nb_skip_;
118 int size; 114 int size;
119 proba->skip_proba_ = CalcSkipProba(nb_events, nb_mbs); 115 proba->skip_proba_ = CalcSkipProba(nb_events, nb_mbs);
120 proba->use_skip_proba_ = (proba->skip_proba_ < SKIP_PROBA_THRESHOLD); 116 proba->use_skip_proba_ = (proba->skip_proba_ < SKIP_PROBA_THRESHOLD);
121 size = 256; // 'use_skip_proba' bit 117 size = 256; // 'use_skip_proba' bit
122 if (proba->use_skip_proba_) { 118 if (proba->use_skip_proba_) {
123 size += nb_events * VP8BitCost(1, proba->skip_proba_) 119 size += nb_events * VP8BitCost(1, proba->skip_proba_)
124 + (nb_mbs - nb_events) * VP8BitCost(0, proba->skip_proba_); 120 + (nb_mbs - nb_events) * VP8BitCost(0, proba->skip_proba_);
125 size += 8 * 256; // cost of signaling the skip_proba_ itself. 121 size += 8 * 256; // cost of signaling the skip_proba_ itself.
126 } 122 }
127 return size; 123 return size;
128 } 124 }
129 125
130 // Collect statistics and deduce probabilities for next coding pass. 126 // Collect statistics and deduce probabilities for next coding pass.
131 // Return the total bit-cost for coding the probability updates. 127 // Return the total bit-cost for coding the probability updates.
132 static int CalcTokenProba(int nb, int total) { 128 static int CalcTokenProba(int nb, int total) {
133 assert(nb <= total); 129 assert(nb <= total);
134 return nb ? (255 - nb * 255 / total) : 255; 130 return nb ? (255 - nb * 255 / total) : 255;
135 } 131 }
136 132
137 // Cost of coding 'nb' 1's and 'total-nb' 0's using 'proba' probability. 133 // Cost of coding 'nb' 1's and 'total-nb' 0's using 'proba' probability.
138 static int BranchCost(int nb, int total, int proba) { 134 static int BranchCost(int nb, int total, int proba) {
139 return nb * VP8BitCost(1, proba) + (total - nb) * VP8BitCost(0, proba); 135 return nb * VP8BitCost(1, proba) + (total - nb) * VP8BitCost(0, proba);
140 } 136 }
141 137
142 static void ResetTokenStats(VP8Encoder* const enc) { 138 static void ResetTokenStats(VP8Encoder* const enc) {
143 VP8Proba* const proba = &enc->proba_; 139 VP8EncProba* const proba = &enc->proba_;
144 memset(proba->stats_, 0, sizeof(proba->stats_)); 140 memset(proba->stats_, 0, sizeof(proba->stats_));
145 } 141 }
146 142
147 static int FinalizeTokenProbas(VP8Proba* const proba) { 143 static int FinalizeTokenProbas(VP8EncProba* const proba) {
148 int has_changed = 0; 144 int has_changed = 0;
149 int size = 0; 145 int size = 0;
150 int t, b, c, p; 146 int t, b, c, p;
151 for (t = 0; t < NUM_TYPES; ++t) { 147 for (t = 0; t < NUM_TYPES; ++t) {
152 for (b = 0; b < NUM_BANDS; ++b) { 148 for (b = 0; b < NUM_BANDS; ++b) {
153 for (c = 0; c < NUM_CTX; ++c) { 149 for (c = 0; c < NUM_CTX; ++c) {
154 for (p = 0; p < NUM_PROBAS; ++p) { 150 for (p = 0; p < NUM_PROBAS; ++p) {
155 const proba_t stats = proba->stats_[t][b][c][p]; 151 const proba_t stats = proba->stats_[t][b][c][p];
156 const int nb = (stats >> 0) & 0xffff; 152 const int nb = (stats >> 0) & 0xffff;
157 const int total = (stats >> 16) & 0xffff; 153 const int total = (stats >> 16) & 0xffff;
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 enc->sse_[2] = 0; 465 enc->sse_[2] = 0;
470 // Note: enc->sse_[3] is managed by alpha.c 466 // Note: enc->sse_[3] is managed by alpha.c
471 enc->sse_count_ = 0; 467 enc->sse_count_ = 0;
472 } 468 }
473 469
474 static void StoreSSE(const VP8EncIterator* const it) { 470 static void StoreSSE(const VP8EncIterator* const it) {
475 VP8Encoder* const enc = it->enc_; 471 VP8Encoder* const enc = it->enc_;
476 const uint8_t* const in = it->yuv_in_; 472 const uint8_t* const in = it->yuv_in_;
477 const uint8_t* const out = it->yuv_out_; 473 const uint8_t* const out = it->yuv_out_;
478 // Note: not totally accurate at boundary. And doesn't include in-loop filter. 474 // Note: not totally accurate at boundary. And doesn't include in-loop filter.
479 enc->sse_[0] += VP8SSE16x16(in + Y_OFF, out + Y_OFF); 475 enc->sse_[0] += VP8SSE16x16(in + Y_OFF_ENC, out + Y_OFF_ENC);
480 enc->sse_[1] += VP8SSE8x8(in + U_OFF, out + U_OFF); 476 enc->sse_[1] += VP8SSE8x8(in + U_OFF_ENC, out + U_OFF_ENC);
481 enc->sse_[2] += VP8SSE8x8(in + V_OFF, out + V_OFF); 477 enc->sse_[2] += VP8SSE8x8(in + V_OFF_ENC, out + V_OFF_ENC);
482 enc->sse_count_ += 16 * 16; 478 enc->sse_count_ += 16 * 16;
483 } 479 }
484 480
485 static void StoreSideInfo(const VP8EncIterator* const it) { 481 static void StoreSideInfo(const VP8EncIterator* const it) {
486 VP8Encoder* const enc = it->enc_; 482 VP8Encoder* const enc = it->enc_;
487 const VP8MBInfo* const mb = it->mb_; 483 const VP8MBInfo* const mb = it->mb_;
488 WebPPicture* const pic = enc->pic_; 484 WebPPicture* const pic = enc->pic_;
489 485
490 if (pic->stats != NULL) { 486 if (pic->stats != NULL) {
491 StoreSSE(it); 487 StoreSSE(it);
(...skipping 12 matching lines...) Expand all
504 case 5: *info = mb->uv_mode_; break; 500 case 5: *info = mb->uv_mode_; break;
505 case 6: { 501 case 6: {
506 const int b = (int)((it->luma_bits_ + it->uv_bits_ + 7) >> 3); 502 const int b = (int)((it->luma_bits_ + it->uv_bits_ + 7) >> 3);
507 *info = (b > 255) ? 255 : b; break; 503 *info = (b > 255) ? 255 : b; break;
508 } 504 }
509 case 7: *info = mb->alpha_; break; 505 case 7: *info = mb->alpha_; break;
510 default: *info = 0; break; 506 default: *info = 0; break;
511 } 507 }
512 } 508 }
513 #if SEGMENT_VISU // visualize segments and prediction modes 509 #if SEGMENT_VISU // visualize segments and prediction modes
514 SetBlock(it->yuv_out_ + Y_OFF, mb->segment_ * 64, 16); 510 SetBlock(it->yuv_out_ + Y_OFF_ENC, mb->segment_ * 64, 16);
515 SetBlock(it->yuv_out_ + U_OFF, it->preds_[0] * 64, 8); 511 SetBlock(it->yuv_out_ + U_OFF_ENC, it->preds_[0] * 64, 8);
516 SetBlock(it->yuv_out_ + V_OFF, mb->uv_mode_ * 64, 8); 512 SetBlock(it->yuv_out_ + V_OFF_ENC, mb->uv_mode_ * 64, 8);
517 #endif 513 #endif
518 } 514 }
519 515
520 static double GetPSNR(uint64_t mse, uint64_t size) { 516 static double GetPSNR(uint64_t mse, uint64_t size) {
521 return (mse > 0 && size > 0) ? 10. * log10(255. * 255. * size / mse) : 99; 517 return (mse > 0 && size > 0) ? 10. * log10(255. * 255. * size / mse) : 99;
522 } 518 }
523 519
524 //------------------------------------------------------------------------------ 520 //------------------------------------------------------------------------------
525 // StatLoop(): only collect statistics (number of skips, token usage, ...). 521 // StatLoop(): only collect statistics (number of skips, token usage, ...).
526 // This is used for deciding optimal probabilities. It also modifies the 522 // This is used for deciding optimal probabilities. It also modifies the
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 #if !defined(DISABLE_TOKEN_BUFFER) 732 #if !defined(DISABLE_TOKEN_BUFFER)
737 733
738 #define MIN_COUNT 96 // minimum number of macroblocks before updating stats 734 #define MIN_COUNT 96 // minimum number of macroblocks before updating stats
739 735
740 int VP8EncTokenLoop(VP8Encoder* const enc) { 736 int VP8EncTokenLoop(VP8Encoder* const enc) {
741 // Roughly refresh the proba eight times per pass 737 // Roughly refresh the proba eight times per pass
742 int max_count = (enc->mb_w_ * enc->mb_h_) >> 3; 738 int max_count = (enc->mb_w_ * enc->mb_h_) >> 3;
743 int num_pass_left = enc->config_->pass; 739 int num_pass_left = enc->config_->pass;
744 const int do_search = enc->do_search_; 740 const int do_search = enc->do_search_;
745 VP8EncIterator it; 741 VP8EncIterator it;
746 VP8Proba* const proba = &enc->proba_; 742 VP8EncProba* const proba = &enc->proba_;
747 const VP8RDLevel rd_opt = enc->rd_opt_level_; 743 const VP8RDLevel rd_opt = enc->rd_opt_level_;
748 const uint64_t pixel_count = enc->mb_w_ * enc->mb_h_ * 384; 744 const uint64_t pixel_count = enc->mb_w_ * enc->mb_h_ * 384;
749 PassStats stats; 745 PassStats stats;
750 int ok; 746 int ok;
751 747
752 InitPassStats(enc, &stats); 748 InitPassStats(enc, &stats);
753 ok = PreLoopInitialize(enc); 749 ok = PreLoopInitialize(enc);
754 if (!ok) return 0; 750 if (!ok) return 0;
755 751
756 if (max_count < MIN_COUNT) max_count = MIN_COUNT; 752 if (max_count < MIN_COUNT) max_count = MIN_COUNT;
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
845 841
846 int VP8EncTokenLoop(VP8Encoder* const enc) { 842 int VP8EncTokenLoop(VP8Encoder* const enc) {
847 (void)enc; 843 (void)enc;
848 return 0; // we shouldn't be here. 844 return 0; // we shouldn't be here.
849 } 845 }
850 846
851 #endif // DISABLE_TOKEN_BUFFER 847 #endif // DISABLE_TOKEN_BUFFER
852 848
853 //------------------------------------------------------------------------------ 849 //------------------------------------------------------------------------------
854 850
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698