diff options
Diffstat (limited to 'drivers/webp/enc/vp8enci.h')
-rw-r--r-- | drivers/webp/enc/vp8enci.h | 203 |
1 files changed, 79 insertions, 124 deletions
diff --git a/drivers/webp/enc/vp8enci.h b/drivers/webp/enc/vp8enci.h index 71adf6c38a..a77778c0d8 100644 --- a/drivers/webp/enc/vp8enci.h +++ b/drivers/webp/enc/vp8enci.h @@ -1,10 +1,8 @@ // Copyright 2011 Google Inc. All Rights Reserved. // -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. +// This code is licensed under the same terms as WebM: +// Software License Agreement: http://www.webmproject.org/license/software/ +// Additional IP Rights Grant: http://www.webmproject.org/license/additional/ // ----------------------------------------------------------------------------- // // WebP encoder: internal header. @@ -18,9 +16,8 @@ #include "../webp/encode.h" #include "../dsp/dsp.h" #include "../utils/bit_writer.h" -#include "../utils/thread.h" -#ifdef __cplusplus +#if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif @@ -29,9 +26,12 @@ extern "C" { // version numbers #define ENC_MAJ_VERSION 0 -#define ENC_MIN_VERSION 4 +#define ENC_MIN_VERSION 2 #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,8 +47,7 @@ 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, - NUM_PRED_MODES = 4 + H_PRED = B_HE_PRED, TM_PRED = B_TM_PRED }; enum { NUM_MB_SEGMENTS = 4, @@ -57,24 +56,16 @@ enum { NUM_MB_SEGMENTS = 4, NUM_BANDS = 8, NUM_CTX = 3, NUM_PROBAS = 11, - MAX_LF_LEVELS = 64, // Maximum loop filter level - MAX_VARIABLE_LEVEL = 67, // last (inclusive) level with variable cost - MAX_LEVEL = 2047 // max level (note: max codable is 2047 + 67) + MAX_LF_LEVELS = 64, // Maximum loop filter level + 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 // the arrays VP8*ModeOffsets[]; // +----+ YUV Samples area. See VP8Scan[] for accessing the blocks. -// Y_OFF |YYYY| <- original samples ('yuv_in_') +// Y_OFF |YYYY| <- original samples (enc->yuv_in_) // |YYYY| // |YYYY| // |YYYY| @@ -169,17 +160,7 @@ 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; } - -// 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 +extern const uint8_t VP8Zigzag[16]; //------------------------------------------------------------------------------ // Headers @@ -248,19 +229,16 @@ typedef struct { int beta_; // filter-susceptibility, range [0,255]. int quant_; // final segment quantizer. int fstrength_; // final in-loop filtering strength - int max_edge_; // max edge delta (for filtering strength) - int min_disto_; // minimum distortion required to trigger filtering record // reactivities int lambda_i16_, lambda_i4_, lambda_uv_; int lambda_mode_, lambda_trellis_, tlambda_; int lambda_trellis_i16_, lambda_trellis_i4_, lambda_trellis_uv_; } VP8SegmentInfo; -// Handy transient struct to accumulate score and info during RD-optimization +// Handy transcient struct to accumulate score and info during RD-optimization // and mode evaluation. typedef struct { - score_t D, SD; // Distortion, spectral distortion - score_t H, R, score; // header bits, rate, score. + score_t D, SD, R, score; // Distortion, spectral distortion, rate, score. int16_t y_dc_levels[16]; // Quantized levels for luma-DC, luma-AC, chroma. int16_t y_ac_levels[16][16]; int16_t uv_levels[4 + 4][16]; @@ -274,11 +252,12 @@ typedef struct { // right neighbouring data (samples, predictions, contexts, ...) typedef struct { int x_, y_; // current macroblock + int y_offset_, uv_offset_; // offset to the luma / chroma planes int y_stride_, uv_stride_; // respective strides - uint8_t* yuv_in_; // input samples - uint8_t* yuv_out_; // output samples - uint8_t* yuv_out2_; // secondary buffer swapped with yuv_out_. - uint8_t* yuv_p_; // scratch buffer for prediction + uint8_t* yuv_in_; // borrowed from enc_ (for now) + uint8_t* yuv_out_; // '' + uint8_t* yuv_out2_; // '' + uint8_t* yuv_p_; // '' VP8Encoder* enc_; // back-pointer VP8MBInfo* mb_; // current macroblock VP8BitWriter* bw_; // current bit-writer @@ -294,43 +273,24 @@ typedef struct { uint64_t uv_bits_; // macroblock bit-cost for chroma LFStats* lf_stats_; // filter stats (borrowed from enc_) int do_trellis_; // if true, perform extra level optimisation - int count_down_; // number of mb still to be processed - int count_down0_; // starting counter value (for progress) + int done_; // true when scan is finished int percent0_; // saved initial progress percent - - uint8_t* y_left_; // left luma samples (addressable from index -1 to 15). - uint8_t* u_left_; // left u samples (addressable from index -1 to 7) - uint8_t* v_left_; // left v samples (addressable from index -1 to 7) - - uint8_t* y_top_; // top luma samples at position 'x_' - uint8_t* uv_top_; // top u/v samples at position 'x_', packed as 16 bytes - - // memory for storing y/u/v_left_ and yuv_in_/out_* - uint8_t yuv_left_mem_[17 + 16 + 16 + 8 + ALIGN_CST]; // memory for *_left_ - uint8_t yuv_mem_[3 * YUV_SIZE + PRED_SIZE + ALIGN_CST]; // memory for yuv_* } VP8EncIterator; // in iterator.c -// must be called first +// must be called first. void VP8IteratorInit(VP8Encoder* const enc, VP8EncIterator* const it); -// restart a scan +// restart a scan. void VP8IteratorReset(VP8EncIterator* const it); -// reset iterator position to row 'y' -void VP8IteratorSetRow(VP8EncIterator* const it, int y); -// set count down (=number of iterations to go) -void VP8IteratorSetCountDown(VP8EncIterator* const it, int count_down); -// return true if iteration is finished -int VP8IteratorIsDone(const VP8EncIterator* const it); -// Import uncompressed samples from source. -// If tmp_32 is not NULL, import boundary samples too. -// tmp_32 is a 32-bytes scratch buffer that must be aligned in memory. -void VP8IteratorImport(VP8EncIterator* const it, uint8_t* tmp_32); +// import samples from source +void VP8IteratorImport(const VP8EncIterator* const it); // export decimated samples void VP8IteratorExport(const VP8EncIterator* const it); -// go to next macroblock. Returns false if not finished. -int VP8IteratorNext(VP8EncIterator* const it); -// save the yuv_out_ boundary values to top_/left_ arrays for next iterations. -void VP8IteratorSaveBoundary(VP8EncIterator* const it); +// go to next macroblock. Returns !done_. If *block_to_save is non-null, will +// save the boundary values to top_/left_ arrays. block_to_save can be +// it->yuv_out_ or it->yuv_in_. +int VP8IteratorNext(VP8EncIterator* const it, + const uint8_t* const block_to_save); // Report progression based on macroblock rows. Return 0 for user-abort request. int VP8IteratorProgress(const VP8EncIterator* const it, int final_delta_percent); @@ -354,40 +314,44 @@ void VP8SetSegment(const VP8EncIterator* const it, int segment); //------------------------------------------------------------------------------ // Paginated token buffer -typedef struct VP8Tokens VP8Tokens; // struct details in token.c - -typedef struct { -#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 -void VP8TBufferClear(VP8TBuffer* const b); // de-allocate pages memory +// WIP: #define USE_TOKEN_BUFFER -#if !defined(DISABLE_TOKEN_BUFFER) +#ifdef 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); +#define MAX_NUM_TOKEN 2048 -// 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); +typedef struct VP8Tokens VP8Tokens; +struct VP8Tokens { + uint16_t tokens_[MAX_NUM_TOKEN]; // bit#15: bit, bits 0..14: slot + int left_; + VP8Tokens* next_; +}; -// Estimate the final coded size given a set of 'probas'. -size_t VP8EstimateTokenSize(VP8TBuffer* const b, const uint8_t* const probas); +typedef struct { + VP8Tokens* rows_; + uint16_t* tokens_; // set to (*last_)->tokens_ + VP8Tokens** last_; + int left_; + int error_; // true in case of malloc error +} VP8TBuffer; -// unused for now -void VP8TokenToStats(const VP8TBuffer* const b, proba_t* const stats); +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; +} -#endif // !DISABLE_TOKEN_BUFFER +#endif // USE_TOKEN_BUFFER //------------------------------------------------------------------------------ // VP8Encoder @@ -412,7 +376,6 @@ struct VP8Encoder { // per-partition boolean decoders. VP8BitWriter bw_; // part0 VP8BitWriter parts_[MAX_NUM_PARTITIONS]; // token partitions - VP8TBuffer tokens_; // token buffer int percent_; // for progress @@ -420,7 +383,6 @@ 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_; @@ -432,7 +394,6 @@ 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_; @@ -448,20 +409,25 @@ struct VP8Encoder { int block_count_[3]; // quality/speed settings - 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 + int method_; // 0=fastest, 6=best/slowest. + int rd_opt_level_; // Deduced from method_. + int max_i4_header_bits_; // partition #0 safeness factor // Memory VP8MBInfo* mb_info_; // contextual macroblock infos (mb_w_ + 1) uint8_t* preds_; // predictions modes: (4*mb_w+1) * (4*mb_h+1) uint32_t* nz_; // non-zero bit context: mb_w+1 + uint8_t* yuv_in_; // input samples + uint8_t* yuv_out_; // output samples + uint8_t* yuv_out2_; // secondary scratch out-buffer. swapped with yuv_out_. + uint8_t* yuv_p_; // scratch buffer for prediction uint8_t *y_top_; // top luma samples. uint8_t *uv_top_; // top u/v samples. - // U and V are packed into 16 bytes (8 U + 8 V) + // U and V are packed into 16 pixels (8 U + 8 V) + uint8_t *y_left_; // left luma samples (adressable from index -1 to 15). + uint8_t *u_left_; // left u samples (adressable from index -1 to 7) + uint8_t *v_left_; // left v samples (adressable from index -1 to 7) + LFStats *lf_stats_; // autofilter stats (if NULL, autofilter is off) }; @@ -489,11 +455,6 @@ 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 @@ -505,9 +466,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 coding calls +// Main stat / coding passes int VP8EncLoop(VP8Encoder* const enc); -int VP8EncTokenLoop(VP8Encoder* const enc); +int VP8StatLoop(VP8Encoder* const enc); // in webpenc.c // Assign an error code to a picture. Return false for convenience. @@ -524,14 +485,12 @@ 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, - VP8RDLevel rd_opt); +int VP8Decimate(VP8EncIterator* const it, VP8ModeScore* const rd, int 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 -int VP8EncDeleteAlpha(VP8Encoder* const enc); // delete compressed data +void VP8EncDeleteAlpha(VP8Encoder* const enc); // delete compressed data // in layer.c void VP8EncInitLayer(VP8Encoder* const enc); // init everything @@ -557,13 +516,9 @@ void VP8InitFilter(VP8EncIterator* const it); void VP8StoreFilterStats(VP8EncIterator* const it); void VP8AdjustFilterStrength(VP8EncIterator* const it); -// returns the approximate filtering strength needed to smooth a edge -// step of 'delta', given a sharpness parameter 'sharpness'. -int VP8FilterStrengthFromDelta(int sharpness, int delta); - //------------------------------------------------------------------------------ -#ifdef __cplusplus +#if defined(__cplusplus) || defined(c_plusplus) } // extern "C" #endif |