diff options
Diffstat (limited to 'third_party/libwebp/enc/vp8enci.h')
-rw-r--r-- | third_party/libwebp/enc/vp8enci.h | 118 |
1 files changed, 71 insertions, 47 deletions
diff --git a/third_party/libwebp/enc/vp8enci.h b/third_party/libwebp/enc/vp8enci.h index 37004a5..6164703 100644 --- a/third_party/libwebp/enc/vp8enci.h +++ b/third_party/libwebp/enc/vp8enci.h @@ -16,6 +16,7 @@ #include "../webp/encode.h" #include "../dsp/dsp.h" #include "../utils/bit_writer.h" +#include "../utils/thread.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { @@ -26,12 +27,9 @@ extern "C" { // version numbers #define ENC_MAJ_VERSION 0 -#define ENC_MIN_VERSION 2 +#define ENC_MIN_VERSION 3 #define ENC_REV_VERSION 0 -// size of histogram used by CollectHistogram. -#define MAX_COEFF_THRESH 64 - // intra prediction modes enum { B_DC_PRED = 0, // 4x4 modes B_TM_PRED = 1, @@ -47,7 +45,8 @@ enum { B_DC_PRED = 0, // 4x4 modes // Luma16 or UV modes DC_PRED = B_DC_PRED, V_PRED = B_VE_PRED, - H_PRED = B_HE_PRED, TM_PRED = B_TM_PRED + H_PRED = B_HE_PRED, TM_PRED = B_TM_PRED, + NUM_PRED_MODES = 4 }; enum { NUM_MB_SEGMENTS = 4, @@ -60,6 +59,13 @@ enum { NUM_MB_SEGMENTS = 4, MAX_VARIABLE_LEVEL = 67 // last (inclusive) level with variable cost }; +typedef enum { // Rate-distortion optimization levels + RD_OPT_NONE = 0, // no rd-opt + RD_OPT_BASIC = 1, // basic scoring (no trellis) + RD_OPT_TRELLIS = 2, // perform trellis-quant on the final decision only + RD_OPT_TRELLIS_ALL = 3 // trellis-quant for every scoring (much slower) +} VP8RDLevel; + // YUV-cache parameters. Cache is 16-pixels wide. // The original or reconstructed samples can be accessed using VP8Scan[] // The predicted blocks can be accessed using offsets to yuv_p_ and @@ -160,13 +166,24 @@ typedef int64_t score_t; // type used for scores, rate, distortion static WEBP_INLINE int QUANTDIV(int n, int iQ, int B) { return (n * iQ + B) >> QFIX; } -extern const uint8_t VP8Zigzag[16]; + +// size of histogram used by CollectHistogram. +#define MAX_COEFF_THRESH 31 +typedef struct VP8Histogram VP8Histogram; +struct VP8Histogram { + // TODO(skal): we only need to store the max_value and last_non_zero actually. + int distribution[MAX_COEFF_THRESH + 1]; +}; + +// Uncomment the following to remove token-buffer code: +// #define DISABLE_TOKEN_BUFFER //------------------------------------------------------------------------------ // Headers +typedef uint32_t proba_t; // 16b + 16b typedef uint8_t ProbaArray[NUM_CTX][NUM_PROBAS]; -typedef uint64_t StatsArray[NUM_CTX][NUM_PROBAS][2]; +typedef proba_t StatsArray[NUM_CTX][NUM_PROBAS]; typedef uint16_t CostArray[NUM_CTX][MAX_VARIABLE_LEVEL + 1]; typedef double LFStats[NUM_MB_SEGMENTS][MAX_LF_LEVELS]; // filter stats @@ -185,8 +202,9 @@ typedef struct { uint8_t segments_[3]; // probabilities for segment tree uint8_t skip_proba_; // final probability of being skipped. ProbaArray coeffs_[NUM_TYPES][NUM_BANDS]; // 924 bytes - StatsArray stats_[NUM_TYPES][NUM_BANDS]; // 7.4k + StatsArray stats_[NUM_TYPES][NUM_BANDS]; // 4224 bytes CostArray level_cost_[NUM_TYPES][NUM_BANDS]; // 11.4k + int dirty_; // if true, need to call VP8CalculateLevelCosts() int use_skip_proba_; // Note: we always use skip_proba for now. int nb_skip_; // number of skipped blocks } VP8Proba; @@ -312,44 +330,37 @@ void VP8SetSegment(const VP8EncIterator* const it, int segment); //------------------------------------------------------------------------------ // Paginated token buffer -// WIP: #define USE_TOKEN_BUFFER - -#ifdef USE_TOKEN_BUFFER - -#define MAX_NUM_TOKEN 2048 - -typedef struct VP8Tokens VP8Tokens; -struct VP8Tokens { - uint16_t tokens_[MAX_NUM_TOKEN]; // bit#15: bit, bits 0..14: slot - int left_; - VP8Tokens* next_; -}; +typedef struct VP8Tokens VP8Tokens; // struct details in token.c typedef struct { - VP8Tokens* rows_; - uint16_t* tokens_; // set to (*last_)->tokens_ - VP8Tokens** last_; - int left_; - int error_; // true in case of malloc error +#if !defined(DISABLE_TOKEN_BUFFER) + VP8Tokens* pages_; // first page + VP8Tokens** last_page_; // last page + uint16_t* tokens_; // set to (*last_page_)->tokens_ + int left_; // how many free tokens left before the page is full. +#endif + int error_; // true in case of malloc error } VP8TBuffer; void VP8TBufferInit(VP8TBuffer* const b); // initialize an empty buffer -int VP8TBufferNewPage(VP8TBuffer* const b); // allocate a new page -void VP8TBufferClear(VP8TBuffer* const b); // de-allocate memory - -int VP8EmitTokens(const VP8TBuffer* const b, VP8BitWriter* const bw, - const uint8_t* const probas); - -static WEBP_INLINE int VP8AddToken(VP8TBuffer* const b, - int bit, int proba_idx) { - if (b->left_ > 0 || VP8TBufferNewPage(b)) { - const int slot = --b->left_; - b->tokens_[slot] = (bit << 15) | proba_idx; - } - return bit; -} +void VP8TBufferClear(VP8TBuffer* const b); // de-allocate pages memory + +#if !defined(DISABLE_TOKEN_BUFFER) -#endif // USE_TOKEN_BUFFER +// Finalizes bitstream when probabilities are known. +// Deletes the allocated token memory if final_pass is true. +int VP8EmitTokens(VP8TBuffer* const b, VP8BitWriter* const bw, + const uint8_t* const probas, int final_pass); + +// record the coding of coefficients without knowing the probabilities yet +int VP8RecordCoeffTokens(int ctx, int coeff_type, int first, int last, + const int16_t* const coeffs, + VP8TBuffer* const tokens); + +// unused for now +void VP8TokenToStats(const VP8TBuffer* const b, proba_t* const stats); + +#endif // !DISABLE_TOKEN_BUFFER //------------------------------------------------------------------------------ // VP8Encoder @@ -374,6 +385,7 @@ struct VP8Encoder { // per-partition boolean decoders. VP8BitWriter bw_; // part0 VP8BitWriter parts_[MAX_NUM_PARTITIONS]; // token partitions + VP8TBuffer tokens_; // token buffer int percent_; // for progress @@ -381,6 +393,7 @@ struct VP8Encoder { int has_alpha_; uint8_t* alpha_data_; // non-NULL if transparency is present uint32_t alpha_data_size_; + WebPWorker alpha_worker_; // enhancement layer int use_layer_; @@ -392,6 +405,7 @@ struct VP8Encoder { VP8SegmentInfo dqm_[NUM_MB_SEGMENTS]; int base_quant_; // nominal quantizer value. Only used // for relative coding of segments' quant. + int alpha_; // global susceptibility (<=> complexity) int uv_alpha_; // U/V quantization susceptibility // global offset of quantizers, shared by all segments int dq_y1_dc_; @@ -407,9 +421,12 @@ struct VP8Encoder { int block_count_[3]; // quality/speed settings - int method_; // 0=fastest, 6=best/slowest. - int rd_opt_level_; // Deduced from method_. - int max_i4_header_bits_; // partition #0 safeness factor + int method_; // 0=fastest, 6=best/slowest. + VP8RDLevel rd_opt_level_; // Deduced from method_. + int max_i4_header_bits_; // partition #0 safeness factor + int thread_level_; // derived from config->thread_level + int do_search_; // derived from config->target_XXX + int use_tokens_; // if true, use token buffer // Memory VP8MBInfo* mb_info_; // contextual macroblock infos (mb_w_ + 1) @@ -453,6 +470,11 @@ void VP8EncFreeBitWriters(VP8Encoder* const enc); // in frame.c extern const uint8_t VP8EncBands[16 + 1]; +extern const uint8_t VP8Cat3[]; +extern const uint8_t VP8Cat4[]; +extern const uint8_t VP8Cat5[]; +extern const uint8_t VP8Cat6[]; + // Form all the four Intra16x16 predictions in the yuv_p_ cache void VP8MakeLuma16Preds(const VP8EncIterator* const it); // Form all the four Chroma8x8 predictions in the yuv_p_ cache @@ -464,9 +486,9 @@ void VP8MakeIntra4Preds(const VP8EncIterator* const it); int VP8GetCostLuma16(VP8EncIterator* const it, const VP8ModeScore* const rd); int VP8GetCostLuma4(VP8EncIterator* const it, const int16_t levels[16]); int VP8GetCostUV(VP8EncIterator* const it, const VP8ModeScore* const rd); -// Main stat / coding passes +// Main coding calls int VP8EncLoop(VP8Encoder* const enc); -int VP8StatLoop(VP8Encoder* const enc); +int VP8EncTokenLoop(VP8Encoder* const enc); // in webpenc.c // Assign an error code to a picture. Return false for convenience. @@ -483,12 +505,14 @@ int VP8EncAnalyze(VP8Encoder* const enc); // Sets up segment's quantization values, base_quant_ and filter strengths. void VP8SetSegmentParams(VP8Encoder* const enc, float quality); // Pick best modes and fills the levels. Returns true if skipped. -int VP8Decimate(VP8EncIterator* const it, VP8ModeScore* const rd, int rd_opt); +int VP8Decimate(VP8EncIterator* const it, VP8ModeScore* const rd, + VP8RDLevel rd_opt); // in alpha.c void VP8EncInitAlpha(VP8Encoder* const enc); // initialize alpha compression +int VP8EncStartAlpha(VP8Encoder* const enc); // start alpha coding process int VP8EncFinishAlpha(VP8Encoder* const enc); // finalize compressed data -void VP8EncDeleteAlpha(VP8Encoder* const enc); // delete compressed data +int VP8EncDeleteAlpha(VP8Encoder* const enc); // delete compressed data // in layer.c void VP8EncInitLayer(VP8Encoder* const enc); // init everything |