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

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

Issue 10832153: libwebp: update snapshot to v0.2.0-rc1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 4 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
OLDNEW
1 // Copyright 2011 Google Inc. 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 // Quantization 8 // Quantization
9 // 9 //
10 // Author: Skal (pascal.massimino@gmail.com) 10 // Author: Skal (pascal.massimino@gmail.com)
11 11
12 #include <assert.h> 12 #include <assert.h>
13 #include <math.h> 13 #include <math.h>
14 14
15 #include "vp8enci.h" 15 #include "./vp8enci.h"
16 #include "cost.h" 16 #include "./cost.h"
17 17
18 #define DO_TRELLIS_I4 1 18 #define DO_TRELLIS_I4 1
19 #define DO_TRELLIS_I16 1 // not a huge gain, but ok at low bitrate. 19 #define DO_TRELLIS_I16 1 // not a huge gain, but ok at low bitrate.
20 #define DO_TRELLIS_UV 0 // disable trellis for UV. Risky. Not worth. 20 #define DO_TRELLIS_UV 0 // disable trellis for UV. Risky. Not worth.
21 #define USE_TDISTO 1 21 #define USE_TDISTO 1
22 22
23 #define MID_ALPHA 64 // neutral value for susceptibility 23 #define MID_ALPHA 64 // neutral value for susceptibility
24 #define MIN_ALPHA 30 // lowest usable value for susceptibility 24 #define MIN_ALPHA 30 // lowest usable value for susceptibility
25 #define MAX_ALPHA 100 // higher meaninful value for susceptibility 25 #define MAX_ALPHA 100 // higher meaninful value for susceptibility
26 26
27 #define SNS_TO_DQ 0.9 // Scaling constant between the sns value and the QP 27 #define SNS_TO_DQ 0.9 // Scaling constant between the sns value and the QP
28 // power-law modulation. Must be strictly less than 1. 28 // power-law modulation. Must be strictly less than 1.
29 29
30 #define MULT_8B(a, b) (((a) * (b) + 128) >> 8) 30 #define MULT_8B(a, b) (((a) * (b) + 128) >> 8)
31 31
32 #if defined(__cplusplus) || defined(c_plusplus) 32 #if defined(__cplusplus) || defined(c_plusplus)
33 extern "C" { 33 extern "C" {
34 #endif 34 #endif
35 35
36 //------------------------------------------------------------------------------ 36 //------------------------------------------------------------------------------
37 37
38 static inline int clip(int v, int m, int M) { 38 static WEBP_INLINE int clip(int v, int m, int M) {
39 return v < m ? m : v > M ? M : v; 39 return v < m ? m : v > M ? M : v;
40 } 40 }
41 41
42 static const uint8_t kZigzag[16] = { 42 static const uint8_t kZigzag[16] = {
43 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 43 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
44 }; 44 };
45 45
46 static const uint8_t kDcTable[128] = { 46 static const uint8_t kDcTable[128] = {
47 4, 5, 6, 7, 8, 9, 10, 10, 47 4, 5, 6, 7, 8, 9, 10, 10,
48 11, 12, 13, 14, 15, 16, 17, 17, 48 11, 12, 13, 14, 15, 16, 17, 17,
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 // Must be ordered using {DC_PRED, TM_PRED, V_PRED, H_PRED} as index 292 // Must be ordered using {DC_PRED, TM_PRED, V_PRED, H_PRED} as index
293 const int VP8I16ModeOffsets[4] = { I16DC16, I16TM16, I16VE16, I16HE16 }; 293 const int VP8I16ModeOffsets[4] = { I16DC16, I16TM16, I16VE16, I16HE16 };
294 const int VP8UVModeOffsets[4] = { C8DC8, C8TM8, C8VE8, C8HE8 }; 294 const int VP8UVModeOffsets[4] = { C8DC8, C8TM8, C8VE8, C8HE8 };
295 295
296 // Must be indexed using {B_DC_PRED -> B_HU_PRED} as index 296 // Must be indexed using {B_DC_PRED -> B_HU_PRED} as index
297 const int VP8I4ModeOffsets[NUM_BMODES] = { 297 const int VP8I4ModeOffsets[NUM_BMODES] = {
298 I4DC4, I4TM4, I4VE4, I4HE4, I4RD4, I4VR4, I4LD4, I4VL4, I4HD4, I4HU4 298 I4DC4, I4TM4, I4VE4, I4HE4, I4RD4, I4VR4, I4LD4, I4VL4, I4HD4, I4HU4
299 }; 299 };
300 300
301 void VP8MakeLuma16Preds(const VP8EncIterator* const it) { 301 void VP8MakeLuma16Preds(const VP8EncIterator* const it) {
302 VP8Encoder* const enc = it->enc_; 302 const VP8Encoder* const enc = it->enc_;
303 const uint8_t* left = it->x_ ? enc->y_left_ : NULL; 303 const uint8_t* const left = it->x_ ? enc->y_left_ : NULL;
304 const uint8_t* top = it->y_ ? enc->y_top_ + it->x_ * 16 : NULL; 304 const uint8_t* const top = it->y_ ? enc->y_top_ + it->x_ * 16 : NULL;
305 VP8EncPredLuma16(it->yuv_p_, left, top); 305 VP8EncPredLuma16(it->yuv_p_, left, top);
306 } 306 }
307 307
308 void VP8MakeChroma8Preds(const VP8EncIterator* const it) { 308 void VP8MakeChroma8Preds(const VP8EncIterator* const it) {
309 VP8Encoder* const enc = it->enc_; 309 const VP8Encoder* const enc = it->enc_;
310 const uint8_t* left = it->x_ ? enc->u_left_ : NULL; 310 const uint8_t* const left = it->x_ ? enc->u_left_ : NULL;
311 const uint8_t* top = it->y_ ? enc->uv_top_ + it->x_ * 16 : NULL; 311 const uint8_t* const top = it->y_ ? enc->uv_top_ + it->x_ * 16 : NULL;
312 VP8EncPredChroma8(it->yuv_p_, left, top); 312 VP8EncPredChroma8(it->yuv_p_, left, top);
313 } 313 }
314 314
315 void VP8MakeIntra4Preds(const VP8EncIterator* const it) { 315 void VP8MakeIntra4Preds(const VP8EncIterator* const it) {
316 VP8EncPredLuma4(it->yuv_p_, it->i4_top_); 316 VP8EncPredLuma4(it->yuv_p_, it->i4_top_);
317 } 317 }
318 318
319 //------------------------------------------------------------------------------ 319 //------------------------------------------------------------------------------
320 // Quantize 320 // Quantize
321 321
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 } Node; 399 } Node;
400 400
401 // If a coefficient was quantized to a value Q (using a neutral bias), 401 // If a coefficient was quantized to a value Q (using a neutral bias),
402 // we test all alternate possibilities between [Q-MIN_DELTA, Q+MAX_DELTA] 402 // we test all alternate possibilities between [Q-MIN_DELTA, Q+MAX_DELTA]
403 // We don't test negative values though. 403 // We don't test negative values though.
404 #define MIN_DELTA 0 // how much lower level to try 404 #define MIN_DELTA 0 // how much lower level to try
405 #define MAX_DELTA 1 // how much higher 405 #define MAX_DELTA 1 // how much higher
406 #define NUM_NODES (MIN_DELTA + 1 + MAX_DELTA) 406 #define NUM_NODES (MIN_DELTA + 1 + MAX_DELTA)
407 #define NODE(n, l) (nodes[(n) + 1][(l) + MIN_DELTA]) 407 #define NODE(n, l) (nodes[(n) + 1][(l) + MIN_DELTA])
408 408
409 static inline void SetRDScore(int lambda, VP8ModeScore* const rd) { 409 static WEBP_INLINE void SetRDScore(int lambda, VP8ModeScore* const rd) {
410 // TODO: incorporate the "* 256" in the tables? 410 // TODO: incorporate the "* 256" in the tables?
411 rd->score = rd->R * lambda + 256 * (rd->D + rd->SD); 411 rd->score = rd->R * lambda + 256 * (rd->D + rd->SD);
412 } 412 }
413 413
414 static inline score_t RDScoreTrellis(int lambda, score_t rate, 414 static WEBP_INLINE score_t RDScoreTrellis(int lambda, score_t rate,
415 score_t distortion) { 415 score_t distortion) {
416 return rate * lambda + 256 * distortion; 416 return rate * lambda + 256 * distortion;
417 } 417 }
418 418
419 static int TrellisQuantizeBlock(const VP8EncIterator* const it, 419 static int TrellisQuantizeBlock(const VP8EncIterator* const it,
420 int16_t in[16], int16_t out[16], 420 int16_t in[16], int16_t out[16],
421 int ctx0, int coeff_type, 421 int ctx0, int coeff_type,
422 const VP8Matrix* const mtx, 422 const VP8Matrix* const mtx,
423 int lambda) { 423 int lambda) {
424 ProbaArray* const last_costs = it->enc_->proba_.coeffs_[coeff_type]; 424 ProbaArray* const last_costs = it->enc_->proba_.coeffs_[coeff_type];
425 CostArray* const costs = it->enc_->proba_.level_cost_[coeff_type]; 425 CostArray* const costs = it->enc_->proba_.level_cost_[coeff_type];
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 uint8_t* const tmp = *a; 693 uint8_t* const tmp = *a;
694 *a = *b; 694 *a = *b;
695 *b = tmp; 695 *b = tmp;
696 } 696 }
697 697
698 static void SwapOut(VP8EncIterator* const it) { 698 static void SwapOut(VP8EncIterator* const it) {
699 SwapPtr(&it->yuv_out_, &it->yuv_out2_); 699 SwapPtr(&it->yuv_out_, &it->yuv_out2_);
700 } 700 }
701 701
702 static void PickBestIntra16(VP8EncIterator* const it, VP8ModeScore* const rd) { 702 static void PickBestIntra16(VP8EncIterator* const it, VP8ModeScore* const rd) {
703 VP8Encoder* const enc = it->enc_; 703 const VP8Encoder* const enc = it->enc_;
704 const VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_]; 704 const VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_];
705 const int lambda = dqm->lambda_i16_; 705 const int lambda = dqm->lambda_i16_;
706 const int tlambda = dqm->tlambda_; 706 const int tlambda = dqm->tlambda_;
707 const uint8_t* const src = it->yuv_in_ + Y_OFF; 707 const uint8_t* const src = it->yuv_in_ + Y_OFF;
708 VP8ModeScore rd16; 708 VP8ModeScore rd16;
709 int mode; 709 int mode;
710 710
711 rd->mode_i16 = -1; 711 rd->mode_i16 = -1;
712 for (mode = 0; mode < 4; ++mode) { 712 for (mode = 0; mode < 4; ++mode) {
713 uint8_t* const tmp_dst = it->yuv_out2_ + Y_OFF; // scratch buffer 713 uint8_t* const tmp_dst = it->yuv_out2_ + Y_OFF; // scratch buffer
(...skipping 21 matching lines...) Expand all
735 } 735 }
736 } 736 }
737 SetRDScore(dqm->lambda_mode_, rd); // finalize score for mode decision. 737 SetRDScore(dqm->lambda_mode_, rd); // finalize score for mode decision.
738 VP8SetIntra16Mode(it, rd->mode_i16); 738 VP8SetIntra16Mode(it, rd->mode_i16);
739 } 739 }
740 740
741 //------------------------------------------------------------------------------ 741 //------------------------------------------------------------------------------
742 742
743 // return the cost array corresponding to the surrounding prediction modes. 743 // return the cost array corresponding to the surrounding prediction modes.
744 static const uint16_t* GetCostModeI4(VP8EncIterator* const it, 744 static const uint16_t* GetCostModeI4(VP8EncIterator* const it,
745 const int modes[16]) { 745 const uint8_t modes[16]) {
746 const int preds_w = it->enc_->preds_w_; 746 const int preds_w = it->enc_->preds_w_;
747 const int x = (it->i4_ & 3), y = it->i4_ >> 2; 747 const int x = (it->i4_ & 3), y = it->i4_ >> 2;
748 const int left = (x == 0) ? it->preds_[y * preds_w - 1] : modes[it->i4_ - 1]; 748 const int left = (x == 0) ? it->preds_[y * preds_w - 1] : modes[it->i4_ - 1];
749 const int top = (y == 0) ? it->preds_[-preds_w + x] : modes[it->i4_ - 4]; 749 const int top = (y == 0) ? it->preds_[-preds_w + x] : modes[it->i4_ - 4];
750 return VP8FixedCostsI4[top][left]; 750 return VP8FixedCostsI4[top][left];
751 } 751 }
752 752
753 static int PickBestIntra4(VP8EncIterator* const it, VP8ModeScore* const rd) { 753 static int PickBestIntra4(VP8EncIterator* const it, VP8ModeScore* const rd) {
754 VP8Encoder* const enc = it->enc_; 754 const VP8Encoder* const enc = it->enc_;
755 const VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_]; 755 const VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_];
756 const int lambda = dqm->lambda_i4_; 756 const int lambda = dqm->lambda_i4_;
757 const int tlambda = dqm->tlambda_; 757 const int tlambda = dqm->tlambda_;
758 const uint8_t* const src0 = it->yuv_in_ + Y_OFF; 758 const uint8_t* const src0 = it->yuv_in_ + Y_OFF;
759 uint8_t* const best_blocks = it->yuv_out2_ + Y_OFF; 759 uint8_t* const best_blocks = it->yuv_out2_ + Y_OFF;
760 int total_header_bits = 0; 760 int total_header_bits = 0;
761 VP8ModeScore rd_best; 761 VP8ModeScore rd_best;
762 762
763 if (enc->max_i4_header_bits_ == 0) { 763 if (enc->max_i4_header_bits_ == 0) {
764 return 0; 764 return 0;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 CopyScore(rd, &rd_best); 820 CopyScore(rd, &rd_best);
821 VP8SetIntra4Mode(it, rd->modes_i4); 821 VP8SetIntra4Mode(it, rd->modes_i4);
822 SwapOut(it); 822 SwapOut(it);
823 memcpy(rd->y_ac_levels, rd_best.y_ac_levels, sizeof(rd->y_ac_levels)); 823 memcpy(rd->y_ac_levels, rd_best.y_ac_levels, sizeof(rd->y_ac_levels));
824 return 1; // select intra4x4 over intra16x16 824 return 1; // select intra4x4 over intra16x16
825 } 825 }
826 826
827 //------------------------------------------------------------------------------ 827 //------------------------------------------------------------------------------
828 828
829 static void PickBestUV(VP8EncIterator* const it, VP8ModeScore* const rd) { 829 static void PickBestUV(VP8EncIterator* const it, VP8ModeScore* const rd) {
830 VP8Encoder* const enc = it->enc_; 830 const VP8Encoder* const enc = it->enc_;
831 const VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_]; 831 const VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_];
832 const int lambda = dqm->lambda_uv_; 832 const int lambda = dqm->lambda_uv_;
833 const uint8_t* const src = it->yuv_in_ + U_OFF; 833 const uint8_t* const src = it->yuv_in_ + U_OFF;
834 uint8_t* const tmp_dst = it->yuv_out2_ + U_OFF; // scratch buffer 834 uint8_t* const tmp_dst = it->yuv_out2_ + U_OFF; // scratch buffer
835 uint8_t* const dst0 = it->yuv_out_ + U_OFF; 835 uint8_t* const dst0 = it->yuv_out_ + U_OFF;
836 VP8ModeScore rd_best; 836 VP8ModeScore rd_best;
837 int mode; 837 int mode;
838 838
839 rd->mode_uv = -1; 839 rd->mode_uv = -1;
840 InitScore(&rd_best); 840 InitScore(&rd_best);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
921 SimpleQuantize(it, rd); 921 SimpleQuantize(it, rd);
922 } 922 }
923 is_skipped = (rd->nz == 0); 923 is_skipped = (rd->nz == 0);
924 VP8SetSkip(it, is_skipped); 924 VP8SetSkip(it, is_skipped);
925 return is_skipped; 925 return is_skipped;
926 } 926 }
927 927
928 #if defined(__cplusplus) || defined(c_plusplus) 928 #if defined(__cplusplus) || defined(c_plusplus)
929 } // extern "C" 929 } // extern "C"
930 #endif 930 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698