From de4d4ad59816ae254c30d4a10e65359abf7cea9d Mon Sep 17 00:00:00 2001 From: skal Date: Fri, 26 Jul 2013 17:08:37 -0700 Subject: [PATCH] VP8EncIterator clean-up - remove unused fields from iterator - introduce VP8IteratorSetRow() too - rename 'done_' to 'countdown_' - bring y_left_/u_left_/v_left_ from VP8Encoder Change-Id: Idc1c15743157936e4cbb7002ebb5cc3c90e7f92a --- src/enc/iterator.c | 65 +++++++++++++++++++++++----------------------- src/enc/quant.c | 4 +-- src/enc/vp8enci.h | 26 ++++++++++--------- src/enc/webpenc.c | 13 ++-------- 4 files changed, 51 insertions(+), 57 deletions(-) diff --git a/src/enc/iterator.c b/src/enc/iterator.c index 07466590..cec8afa3 100644 --- a/src/enc/iterator.c +++ b/src/enc/iterator.c @@ -24,12 +24,11 @@ extern "C" { //------------------------------------------------------------------------------ static void InitLeft(VP8EncIterator* const it) { - const VP8Encoder* const enc = it->enc_; - enc->y_left_[-1] = enc->u_left_[-1] = enc->v_left_[-1] = + it->y_left_[-1] = it->u_left_[-1] = it->v_left_[-1] = (it->y_ > 0) ? 129 : 127; - memset(enc->y_left_, 129, 16); - memset(enc->u_left_, 129, 8); - memset(enc->v_left_, 129, 8); + memset(it->y_left_, 129, 16); + memset(it->u_left_, 129, 8); + memset(it->v_left_, 129, 8); it->left_nz_[8] = 0; } @@ -40,17 +39,21 @@ static void InitTop(VP8EncIterator* const it) { memset(enc->nz_, 0, enc->mb_w_ * sizeof(*enc->nz_)); } -void VP8IteratorReset(VP8EncIterator* const it) { +void VP8IteratorSetRow(VP8EncIterator* const it, int y) { VP8Encoder* const enc = it->enc_; it->x_ = 0; - it->y_ = 0; - it->y_offset_ = 0; - it->uv_offset_ = 0; - it->mb_ = enc->mb_info_; - it->preds_ = enc->preds_; + it->y_ = y; + it->bw_ = &enc->parts_[y & (enc->num_parts_ - 1)]; + it->preds_ = enc->preds_ + y * 4 * enc->preds_w_; it->nz_ = enc->nz_; - it->bw_ = &enc->parts_[0]; - it->done_ = enc->mb_w_* enc->mb_h_; + it->mb_ = enc->mb_info_ + y * enc->mb_w_; + InitLeft(it); +} + +void VP8IteratorReset(VP8EncIterator* const it) { + VP8Encoder* const enc = it->enc_; + VP8IteratorSetRow(it, 0); + it->count_down_ = enc->mb_w_ * enc->mb_h_; InitTop(it); InitLeft(it); memset(it->bit_count_, 0, sizeof(it->bit_count_)); @@ -68,12 +71,15 @@ void VP8IteratorInit(VP8Encoder* const enc, VP8EncIterator* const it) { it->yuv_p_ = enc->yuv_p_; it->lf_stats_ = enc->lf_stats_; it->percent0_ = enc->percent_; + it->y_left_ = (uint8_t*)DO_ALIGN(it->yuv_left_mem_ + 1); + it->u_left_ = it->y_left_ + 16 + 16; + it->v_left_ = it->u_left_ + 16; VP8IteratorReset(it); } int VP8IteratorProgress(const VP8EncIterator* const it, int delta) { VP8Encoder* const enc = it->enc_; - if (delta && enc->pic_->progress_hook) { + if (delta && enc->pic_->progress_hook != NULL) { const int percent = (enc->mb_h_ <= 1) ? it->percent0_ : it->percent0_ + delta * it->y_ / (enc->mb_h_ - 1); @@ -247,23 +253,23 @@ void VP8IteratorBytesToNz(VP8EncIterator* const it) { int VP8IteratorNext(VP8EncIterator* const it, const uint8_t* const block_to_save) { VP8Encoder* const enc = it->enc_; - if (block_to_save) { + if (block_to_save != NULL) { const int x = it->x_, y = it->y_; const uint8_t* const ysrc = block_to_save + Y_OFF; const uint8_t* const usrc = block_to_save + U_OFF; if (x < enc->mb_w_ - 1) { // left int i; for (i = 0; i < 16; ++i) { - enc->y_left_[i] = ysrc[15 + i * BPS]; + it->y_left_[i] = ysrc[15 + i * BPS]; } for (i = 0; i < 8; ++i) { - enc->u_left_[i] = usrc[7 + i * BPS]; - enc->v_left_[i] = usrc[15 + i * BPS]; + it->u_left_[i] = usrc[7 + i * BPS]; + it->v_left_[i] = usrc[15 + i * BPS]; } // top-left (before 'top'!) - enc->y_left_[-1] = enc->y_top_[x * 16 + 15]; - enc->u_left_[-1] = enc->uv_top_[x * 16 + 0 + 7]; - enc->v_left_[-1] = enc->uv_top_[x * 16 + 8 + 7]; + it->y_left_[-1] = enc->y_top_[x * 16 + 15]; + it->u_left_[-1] = enc->uv_top_[x * 16 + 0 + 7]; + it->v_left_[-1] = enc->uv_top_[x * 16 + 8 + 7]; } if (y < enc->mb_h_ - 1) { // top memcpy(enc->y_top_ + x * 16, ysrc + 15 * BPS, 16); @@ -271,19 +277,14 @@ int VP8IteratorNext(VP8EncIterator* const it, } } - it->mb_++; it->preds_ += 4; - it->nz_++; - it->x_++; + it->mb_ += 1; + it->nz_ += 1; + it->x_ += 1; if (it->x_ == enc->mb_w_) { - it->x_ = 0; - it->y_++; - it->bw_ = &enc->parts_[it->y_ & (enc->num_parts_ - 1)]; - it->preds_ = enc->preds_ + it->y_ * 4 * enc->preds_w_; - it->nz_ = enc->nz_; - InitLeft(it); + VP8IteratorSetRow(it, ++it->y_); } - return (0 < --it->done_); + return (0 < --it->count_down_); } //------------------------------------------------------------------------------ @@ -370,7 +371,7 @@ void VP8IteratorStartI4(VP8EncIterator* const it) { // Import the boundary samples for (i = 0; i < 17; ++i) { // left - it->i4_boundary_[i] = enc->y_left_[15 - i]; + it->i4_boundary_[i] = it->y_left_[15 - i]; } for (i = 0; i < 16; ++i) { // top it->i4_boundary_[17 + i] = enc->y_top_[it->x_ * 16 + i]; diff --git a/src/enc/quant.c b/src/enc/quant.c index 462d4e9e..ffeaec30 100644 --- a/src/enc/quant.c +++ b/src/enc/quant.c @@ -368,14 +368,14 @@ const int VP8I4ModeOffsets[NUM_BMODES] = { void VP8MakeLuma16Preds(const VP8EncIterator* const it) { const VP8Encoder* const enc = it->enc_; - const uint8_t* const left = it->x_ ? enc->y_left_ : NULL; + const uint8_t* const left = it->x_ ? it->y_left_ : NULL; const uint8_t* const top = it->y_ ? enc->y_top_ + it->x_ * 16 : NULL; VP8EncPredLuma16(it->yuv_p_, left, top); } void VP8MakeChroma8Preds(const VP8EncIterator* const it) { const VP8Encoder* const enc = it->enc_; - const uint8_t* const left = it->x_ ? enc->u_left_ : NULL; + const uint8_t* const left = it->x_ ? it->u_left_ : NULL; const uint8_t* const top = it->y_ ? enc->uv_top_ + it->x_ * 16 : NULL; VP8EncPredChroma8(it->yuv_p_, left, top); } diff --git a/src/enc/vp8enci.h b/src/enc/vp8enci.h index 61d56be5..e3a3ee8b 100644 --- a/src/enc/vp8enci.h +++ b/src/enc/vp8enci.h @@ -271,7 +271,6 @@ 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_; // borrowed from enc_ (for now) uint8_t* yuv_out_; // '' @@ -292,22 +291,29 @@ 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 done_; // true when scan is finished + int count_down_; // number of mb still to be processed 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 yuv_left_mem_[17 + 16 + 16 + 8 + ALIGN_CST]; // memory for *_left_ } 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); // import samples from source void VP8IteratorImport(const VP8EncIterator* const it); // export decimated samples void VP8IteratorExport(const 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_. +// go to next macroblock. Returns false if not finished. 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. @@ -441,11 +447,7 @@ struct VP8Encoder { 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 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) - + // U and V are packed into 16 bytes (8 U + 8 V) LFStats *lf_stats_; // autofilter stats (if NULL, autofilter is off) }; diff --git a/src/enc/webpenc.c b/src/enc/webpenc.c index c86bff0d..4a56c841 100644 --- a/src/enc/webpenc.c +++ b/src/enc/webpenc.c @@ -178,10 +178,8 @@ static VP8Encoder* InitVP8Encoder(const WebPConfig* const config, const size_t nz_size = (mb_w + 1) * sizeof(uint32_t) + ALIGN_CST; const size_t cache_size = (3 * YUV_SIZE + PRED_SIZE) * sizeof(uint8_t); const size_t info_size = mb_w * mb_h * sizeof(VP8MBInfo); - const size_t samples_size = (2 * top_stride + // top-luma/u/v - 16 + 16 + 16 + 8 + 1 + // left y/u/v - 2 * ALIGN_CST) // align all - * sizeof(uint8_t); + const size_t samples_size = 2 * top_stride * sizeof(uint8_t) // top-luma/u/v + + ALIGN_CST; // align all const size_t lf_stats_size = config->autofilter ? sizeof(LFStats) + ALIGN_CST : 0; VP8Encoder* enc; @@ -255,13 +253,6 @@ static VP8Encoder* InitVP8Encoder(const WebPConfig* const config, enc->y_top_ = (uint8_t*)mem; enc->uv_top_ = enc->y_top_ + top_stride; mem += 2 * top_stride; - mem = (uint8_t*)DO_ALIGN(mem + 1); - enc->y_left_ = (uint8_t*)mem; - mem += 16 + 16; - enc->u_left_ = (uint8_t*)mem; - mem += 16; - enc->v_left_ = (uint8_t*)mem; - mem += 8; assert(mem <= (uint8_t*)enc + size); enc->config_ = config;