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
This commit is contained in:
skal 2013-07-26 17:08:37 -07:00 committed by James Zern
parent 8924a3a704
commit de4d4ad598
4 changed files with 51 additions and 57 deletions

View File

@ -24,12 +24,11 @@ extern "C" {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
static void InitLeft(VP8EncIterator* const it) { static void InitLeft(VP8EncIterator* const it) {
const VP8Encoder* const enc = it->enc_; it->y_left_[-1] = it->u_left_[-1] = it->v_left_[-1] =
enc->y_left_[-1] = enc->u_left_[-1] = enc->v_left_[-1] =
(it->y_ > 0) ? 129 : 127; (it->y_ > 0) ? 129 : 127;
memset(enc->y_left_, 129, 16); memset(it->y_left_, 129, 16);
memset(enc->u_left_, 129, 8); memset(it->u_left_, 129, 8);
memset(enc->v_left_, 129, 8); memset(it->v_left_, 129, 8);
it->left_nz_[8] = 0; 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_)); 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_; VP8Encoder* const enc = it->enc_;
it->x_ = 0; it->x_ = 0;
it->y_ = 0; it->y_ = y;
it->y_offset_ = 0; it->bw_ = &enc->parts_[y & (enc->num_parts_ - 1)];
it->uv_offset_ = 0; it->preds_ = enc->preds_ + y * 4 * enc->preds_w_;
it->mb_ = enc->mb_info_;
it->preds_ = enc->preds_;
it->nz_ = enc->nz_; it->nz_ = enc->nz_;
it->bw_ = &enc->parts_[0]; it->mb_ = enc->mb_info_ + y * enc->mb_w_;
it->done_ = enc->mb_w_* enc->mb_h_; 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); InitTop(it);
InitLeft(it); InitLeft(it);
memset(it->bit_count_, 0, sizeof(it->bit_count_)); 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->yuv_p_ = enc->yuv_p_;
it->lf_stats_ = enc->lf_stats_; it->lf_stats_ = enc->lf_stats_;
it->percent0_ = enc->percent_; 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); VP8IteratorReset(it);
} }
int VP8IteratorProgress(const VP8EncIterator* const it, int delta) { int VP8IteratorProgress(const VP8EncIterator* const it, int delta) {
VP8Encoder* const enc = it->enc_; 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) const int percent = (enc->mb_h_ <= 1)
? it->percent0_ ? it->percent0_
: it->percent0_ + delta * it->y_ / (enc->mb_h_ - 1); : it->percent0_ + delta * it->y_ / (enc->mb_h_ - 1);
@ -247,23 +253,23 @@ void VP8IteratorBytesToNz(VP8EncIterator* const it) {
int VP8IteratorNext(VP8EncIterator* const it, int VP8IteratorNext(VP8EncIterator* const it,
const uint8_t* const block_to_save) { const uint8_t* const block_to_save) {
VP8Encoder* const enc = it->enc_; VP8Encoder* const enc = it->enc_;
if (block_to_save) { if (block_to_save != NULL) {
const int x = it->x_, y = it->y_; const int x = it->x_, y = it->y_;
const uint8_t* const ysrc = block_to_save + Y_OFF; const uint8_t* const ysrc = block_to_save + Y_OFF;
const uint8_t* const usrc = block_to_save + U_OFF; const uint8_t* const usrc = block_to_save + U_OFF;
if (x < enc->mb_w_ - 1) { // left if (x < enc->mb_w_ - 1) { // left
int i; int i;
for (i = 0; i < 16; ++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) { for (i = 0; i < 8; ++i) {
enc->u_left_[i] = usrc[7 + i * BPS]; it->u_left_[i] = usrc[7 + i * BPS];
enc->v_left_[i] = usrc[15 + i * BPS]; it->v_left_[i] = usrc[15 + i * BPS];
} }
// top-left (before 'top'!) // top-left (before 'top'!)
enc->y_left_[-1] = enc->y_top_[x * 16 + 15]; it->y_left_[-1] = enc->y_top_[x * 16 + 15];
enc->u_left_[-1] = enc->uv_top_[x * 16 + 0 + 7]; it->u_left_[-1] = enc->uv_top_[x * 16 + 0 + 7];
enc->v_left_[-1] = enc->uv_top_[x * 16 + 8 + 7]; it->v_left_[-1] = enc->uv_top_[x * 16 + 8 + 7];
} }
if (y < enc->mb_h_ - 1) { // top if (y < enc->mb_h_ - 1) { // top
memcpy(enc->y_top_ + x * 16, ysrc + 15 * BPS, 16); 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->preds_ += 4;
it->nz_++; it->mb_ += 1;
it->x_++; it->nz_ += 1;
it->x_ += 1;
if (it->x_ == enc->mb_w_) { if (it->x_ == enc->mb_w_) {
it->x_ = 0; VP8IteratorSetRow(it, ++it->y_);
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);
} }
return (0 < --it->done_); return (0 < --it->count_down_);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -370,7 +371,7 @@ void VP8IteratorStartI4(VP8EncIterator* const it) {
// Import the boundary samples // Import the boundary samples
for (i = 0; i < 17; ++i) { // left 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 for (i = 0; i < 16; ++i) { // top
it->i4_boundary_[17 + i] = enc->y_top_[it->x_ * 16 + i]; it->i4_boundary_[17 + i] = enc->y_top_[it->x_ * 16 + i];

View File

@ -368,14 +368,14 @@ const int VP8I4ModeOffsets[NUM_BMODES] = {
void VP8MakeLuma16Preds(const VP8EncIterator* const it) { void VP8MakeLuma16Preds(const VP8EncIterator* const it) {
const VP8Encoder* const enc = it->enc_; 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; const uint8_t* const top = it->y_ ? enc->y_top_ + it->x_ * 16 : NULL;
VP8EncPredLuma16(it->yuv_p_, left, top); VP8EncPredLuma16(it->yuv_p_, left, top);
} }
void VP8MakeChroma8Preds(const VP8EncIterator* const it) { void VP8MakeChroma8Preds(const VP8EncIterator* const it) {
const VP8Encoder* const enc = it->enc_; 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; const uint8_t* const top = it->y_ ? enc->uv_top_ + it->x_ * 16 : NULL;
VP8EncPredChroma8(it->yuv_p_, left, top); VP8EncPredChroma8(it->yuv_p_, left, top);
} }

View File

@ -271,7 +271,6 @@ typedef struct {
// right neighbouring data (samples, predictions, contexts, ...) // right neighbouring data (samples, predictions, contexts, ...)
typedef struct { typedef struct {
int x_, y_; // current macroblock int x_, y_; // current macroblock
int y_offset_, uv_offset_; // offset to the luma / chroma planes
int y_stride_, uv_stride_; // respective strides int y_stride_, uv_stride_; // respective strides
uint8_t* yuv_in_; // borrowed from enc_ (for now) uint8_t* yuv_in_; // borrowed from enc_ (for now)
uint8_t* yuv_out_; // '' uint8_t* yuv_out_; // ''
@ -292,22 +291,29 @@ typedef struct {
uint64_t uv_bits_; // macroblock bit-cost for chroma uint64_t uv_bits_; // macroblock bit-cost for chroma
LFStats* lf_stats_; // filter stats (borrowed from enc_) LFStats* lf_stats_; // filter stats (borrowed from enc_)
int do_trellis_; // if true, perform extra level optimisation 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 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; } VP8EncIterator;
// in iterator.c // in iterator.c
// must be called first. // must be called first
void VP8IteratorInit(VP8Encoder* const enc, VP8EncIterator* const it); void VP8IteratorInit(VP8Encoder* const enc, VP8EncIterator* const it);
// restart a scan. // restart a scan
void VP8IteratorReset(VP8EncIterator* const it); void VP8IteratorReset(VP8EncIterator* const it);
// reset iterator position to row 'y'
void VP8IteratorSetRow(VP8EncIterator* const it, int y);
// import samples from source // import samples from source
void VP8IteratorImport(const VP8EncIterator* const it); void VP8IteratorImport(const VP8EncIterator* const it);
// export decimated samples // export decimated samples
void VP8IteratorExport(const VP8EncIterator* const it); void VP8IteratorExport(const VP8EncIterator* const it);
// go to next macroblock. Returns !done_. If *block_to_save is non-null, will // go to next macroblock. Returns false if not finished. If *block_to_save is
// save the boundary values to top_/left_ arrays. block_to_save can be // non-null, will save the boundary values to top_/left_ arrays. block_to_save
// it->yuv_out_ or it->yuv_in_. // can be it->yuv_out_ or it->yuv_in_.
int VP8IteratorNext(VP8EncIterator* const it, int VP8IteratorNext(VP8EncIterator* const it,
const uint8_t* const block_to_save); const uint8_t* const block_to_save);
// Report progression based on macroblock rows. Return 0 for user-abort request. // 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* yuv_p_; // scratch buffer for prediction
uint8_t *y_top_; // top luma samples. uint8_t *y_top_; // top luma samples.
uint8_t *uv_top_; // top u/v samples. uint8_t *uv_top_; // top u/v samples.
// U and V are packed into 16 pixels (8 U + 8 V) // U and V are packed into 16 bytes (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) LFStats *lf_stats_; // autofilter stats (if NULL, autofilter is off)
}; };

View File

@ -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 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 cache_size = (3 * YUV_SIZE + PRED_SIZE) * sizeof(uint8_t);
const size_t info_size = mb_w * mb_h * sizeof(VP8MBInfo); const size_t info_size = mb_w * mb_h * sizeof(VP8MBInfo);
const size_t samples_size = (2 * top_stride + // top-luma/u/v const size_t samples_size = 2 * top_stride * sizeof(uint8_t) // top-luma/u/v
16 + 16 + 16 + 8 + 1 + // left y/u/v + ALIGN_CST; // align all
2 * ALIGN_CST) // align all
* sizeof(uint8_t);
const size_t lf_stats_size = const size_t lf_stats_size =
config->autofilter ? sizeof(LFStats) + ALIGN_CST : 0; config->autofilter ? sizeof(LFStats) + ALIGN_CST : 0;
VP8Encoder* enc; VP8Encoder* enc;
@ -255,13 +253,6 @@ static VP8Encoder* InitVP8Encoder(const WebPConfig* const config,
enc->y_top_ = (uint8_t*)mem; enc->y_top_ = (uint8_t*)mem;
enc->uv_top_ = enc->y_top_ + top_stride; enc->uv_top_ = enc->y_top_ + top_stride;
mem += 2 * 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); assert(mem <= (uint8_t*)enc + size);
enc->config_ = config; enc->config_ = config;