mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-26 13:48:21 +01:00
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:
parent
8924a3a704
commit
de4d4ad598
@ -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];
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user