speed-up GetResidualCost()
+ misc cosmetics and code polishing Change-Id: I5830cd2f268d64c072b1cbccc0a4674833875055
This commit is contained in:
parent
378086bd0a
commit
28a9d9b41a
@ -33,7 +33,7 @@ static int IsValidColorspace(int webp_csp_mode) {
|
||||
|
||||
static VP8StatusCode CheckDecBuffer(const WebPDecBuffer* const buffer) {
|
||||
int ok = 1;
|
||||
WEBP_CSP_MODE mode = buffer->colorspace;
|
||||
const WEBP_CSP_MODE mode = buffer->colorspace;
|
||||
const int width = buffer->width;
|
||||
const int height = buffer->height;
|
||||
if (!IsValidColorspace(mode)) {
|
||||
@ -65,22 +65,21 @@ static VP8StatusCode CheckDecBuffer(const WebPDecBuffer* const buffer) {
|
||||
static VP8StatusCode AllocateBuffer(WebPDecBuffer* const buffer) {
|
||||
const int w = buffer->width;
|
||||
const int h = buffer->height;
|
||||
const WEBP_CSP_MODE mode = buffer->colorspace;
|
||||
|
||||
if (w <= 0 || h <= 0 || !IsValidColorspace(buffer->colorspace)) {
|
||||
if (w <= 0 || h <= 0 || !IsValidColorspace(mode)) {
|
||||
return VP8_STATUS_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (!buffer->is_external_memory && buffer->private_memory == NULL) {
|
||||
uint8_t* output;
|
||||
WEBP_CSP_MODE mode = buffer->colorspace;
|
||||
int stride;
|
||||
int uv_stride = 0, a_stride = 0;
|
||||
int uv_size = 0;
|
||||
uint64_t size, a_size = 0, total_size;
|
||||
uint64_t a_size = 0, total_size;
|
||||
// We need memory and it hasn't been allocated yet.
|
||||
// => initialize output buffer, now that dimensions are known.
|
||||
stride = w * kModeBpp[mode];
|
||||
size = (uint64_t)stride * h;
|
||||
const int stride = w * kModeBpp[mode];
|
||||
const uint64_t size = (uint64_t)stride * h;
|
||||
|
||||
if (mode >= MODE_YUV) {
|
||||
uv_stride = (w + 1) / 2;
|
||||
@ -150,7 +149,7 @@ VP8StatusCode WebPAllocateDecBuffer(int w, int h,
|
||||
if (options->scaled_width <= 0 || options->scaled_height <= 0) {
|
||||
return VP8_STATUS_INVALID_PARAM;
|
||||
}
|
||||
w = options->scaled_width;
|
||||
w = options->scaled_width;
|
||||
h = options->scaled_height;
|
||||
}
|
||||
}
|
||||
@ -166,13 +165,13 @@ VP8StatusCode WebPAllocateDecBuffer(int w, int h,
|
||||
|
||||
int WebPInitDecBufferInternal(WebPDecBuffer* const buffer, int version) {
|
||||
if (version != WEBP_DECODER_ABI_VERSION) return 0; // version mismatch
|
||||
if (!buffer) return 0;
|
||||
if (buffer == NULL) return 0;
|
||||
memset(buffer, 0, sizeof(*buffer));
|
||||
return 1;
|
||||
}
|
||||
|
||||
void WebPFreeDecBuffer(WebPDecBuffer* const buffer) {
|
||||
if (buffer) {
|
||||
if (buffer != NULL) {
|
||||
if (!buffer->is_external_memory)
|
||||
free(buffer->private_memory);
|
||||
buffer->private_memory = NULL;
|
||||
@ -181,9 +180,9 @@ void WebPFreeDecBuffer(WebPDecBuffer* const buffer) {
|
||||
|
||||
void WebPCopyDecBuffer(const WebPDecBuffer* const src,
|
||||
WebPDecBuffer* const dst) {
|
||||
if (src && dst) {
|
||||
if (src != NULL && dst != NULL) {
|
||||
*dst = *src;
|
||||
if (src->private_memory) {
|
||||
if (src->private_memory != NULL) {
|
||||
dst->is_external_memory = 1; // dst buffer doesn't own the memory.
|
||||
dst->private_memory = NULL;
|
||||
}
|
||||
@ -192,9 +191,9 @@ void WebPCopyDecBuffer(const WebPDecBuffer* const src,
|
||||
|
||||
// Copy and transfer ownership from src to dst (beware of parameter order!)
|
||||
void WebPGrabDecBuffer(WebPDecBuffer* const src, WebPDecBuffer* const dst) {
|
||||
if (src && dst) {
|
||||
if (src != NULL && dst != NULL) {
|
||||
*dst = *src;
|
||||
if (src->private_memory) {
|
||||
if (src->private_memory != NULL) {
|
||||
src->is_external_memory = 1; // src relinquishes ownership
|
||||
src->private_memory = NULL;
|
||||
}
|
||||
|
@ -78,24 +78,24 @@ static const uint8_t kFilterExtraRows[3] = { 0, 2, 8 };
|
||||
static int AllocateMemory(VP8Decoder* const dec) {
|
||||
const int num_caches = dec->num_caches_;
|
||||
const int mb_w = dec->mb_w_;
|
||||
const int intra_pred_mode_size = 4 * mb_w * sizeof(uint8_t);
|
||||
const int top_size = (16 + 8 + 8) * mb_w;
|
||||
const int mb_info_size = (mb_w + 1) * sizeof(VP8MB);
|
||||
const int f_info_size =
|
||||
(dec->filter_type_ > 0) ?
|
||||
mb_w * (dec->use_threads_ ? 2 : 1) * sizeof(VP8FInfo)
|
||||
: 0;
|
||||
const int yuv_size = YUV_SIZE * sizeof(*dec->yuv_b_);
|
||||
const int coeffs_size = 384 * sizeof(*dec->coeffs_);
|
||||
const int cache_height = (16 * num_caches
|
||||
+ kFilterExtraRows[dec->filter_type_]) * 3 / 2;
|
||||
const int cache_size = top_size * cache_height;
|
||||
const int alpha_size =
|
||||
dec->alpha_data_ ? (dec->pic_hdr_.width_ * dec->pic_hdr_.height_) : 0;
|
||||
const int needed = intra_pred_mode_size
|
||||
+ top_size + mb_info_size + f_info_size
|
||||
+ yuv_size + coeffs_size
|
||||
+ cache_size + alpha_size + ALIGN_MASK;
|
||||
const size_t intra_pred_mode_size = 4 * mb_w * sizeof(uint8_t);
|
||||
const size_t top_size = (16 + 8 + 8) * mb_w;
|
||||
const size_t mb_info_size = (mb_w + 1) * sizeof(VP8MB);
|
||||
const size_t f_info_size =
|
||||
(dec->filter_type_ > 0) ?
|
||||
mb_w * (dec->use_threads_ ? 2 : 1) * sizeof(VP8FInfo)
|
||||
: 0;
|
||||
const size_t yuv_size = YUV_SIZE * sizeof(*dec->yuv_b_);
|
||||
const size_t coeffs_size = 384 * sizeof(*dec->coeffs_);
|
||||
const size_t cache_height = (16 * num_caches
|
||||
+ kFilterExtraRows[dec->filter_type_]) * 3 / 2;
|
||||
const size_t cache_size = top_size * cache_height;
|
||||
const size_t alpha_size =
|
||||
dec->alpha_data_ ? (dec->pic_hdr_.width_ * dec->pic_hdr_.height_) : 0;
|
||||
const size_t needed = intra_pred_mode_size
|
||||
+ top_size + mb_info_size + f_info_size
|
||||
+ yuv_size + coeffs_size
|
||||
+ cache_size + alpha_size + ALIGN_MASK;
|
||||
uint8_t* mem;
|
||||
|
||||
if (needed > dec->mem_size_) {
|
||||
|
38
src/dec/io.c
38
src/dec/io.c
@ -32,11 +32,12 @@ static int EmitYUV(const VP8Io* const io, WebPDecParams* const p) {
|
||||
const int mb_w = io->mb_w;
|
||||
const int mb_h = io->mb_h;
|
||||
const int uv_w = (mb_w + 1) / 2;
|
||||
const int uv_h = (mb_h + 1) / 2;
|
||||
int j;
|
||||
for (j = 0; j < mb_h; ++j) {
|
||||
memcpy(y_dst + j * buf->y_stride, io->y + j * io->y_stride, mb_w);
|
||||
}
|
||||
for (j = 0; j < (mb_h + 1) / 2; ++j) {
|
||||
for (j = 0; j < uv_h; ++j) {
|
||||
memcpy(u_dst + j * buf->u_stride, io->u + j * io->uv_stride, uv_w);
|
||||
memcpy(v_dst + j * buf->v_stride, io->v + j * io->uv_stride, uv_w);
|
||||
}
|
||||
@ -127,7 +128,7 @@ static int EmitFancyRGB(const VP8Io* const io, WebPDecParams* const p) {
|
||||
// are not lagging one line behind but are already written.
|
||||
upsample(p->tmp_y, cur_y, top_u, top_v, cur_u, cur_v,
|
||||
dst - buf->stride, dst, mb_w);
|
||||
num_lines_out++;
|
||||
++num_lines_out;
|
||||
}
|
||||
// Loop over each output pairs of row.
|
||||
for (; y + 2 < y_end; y += 2) {
|
||||
@ -166,13 +167,13 @@ static int EmitFancyRGB(const VP8Io* const io, WebPDecParams* const p) {
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static int EmitAlphaYUV(const VP8Io* const io, WebPDecParams* const p) {
|
||||
const int mb_w = io->mb_w;
|
||||
const int mb_h = io->mb_h;
|
||||
int j;
|
||||
const WebPYUVABuffer* const buf = &p->output->u.YUVA;
|
||||
uint8_t* dst = buf->a + io->mb_y * buf->a_stride;
|
||||
const uint8_t* alpha = io->a;
|
||||
if (alpha) {
|
||||
if (alpha != NULL) {
|
||||
int j;
|
||||
const int mb_w = io->mb_w;
|
||||
const int mb_h = io->mb_h;
|
||||
const WebPYUVABuffer* const buf = &p->output->u.YUVA;
|
||||
uint8_t* dst = buf->a + io->mb_y * buf->a_stride;
|
||||
for (j = 0; j < mb_h; ++j) {
|
||||
memcpy(dst, alpha, mb_w * sizeof(*dst));
|
||||
alpha += io->width;
|
||||
@ -331,7 +332,7 @@ static int Rescale(const uint8_t* src, int src_stride,
|
||||
wrk->y_accum -= wrk->y_sub;
|
||||
while (wrk->y_accum <= 0) { // emit output row(s)
|
||||
ExportRow(wrk);
|
||||
num_lines_out++;
|
||||
++num_lines_out;
|
||||
}
|
||||
}
|
||||
return num_lines_out;
|
||||
@ -347,7 +348,7 @@ static int EmitRescaledYUV(const VP8Io* const io, WebPDecParams* const p) {
|
||||
}
|
||||
|
||||
static int EmitRescaledAlphaYUV(const VP8Io* const io, WebPDecParams* const p) {
|
||||
if (io->a) {
|
||||
if (io->a != NULL) {
|
||||
Rescale(io->a, io->width, io->mb_h, &p->scaler_a);
|
||||
}
|
||||
return 0;
|
||||
@ -440,7 +441,7 @@ static int ExportRGB(WebPDecParams* const p, int y_pos) {
|
||||
convert(p->scaler_y.dst, p->scaler_u.dst, p->scaler_v.dst,
|
||||
dst, p->scaler_y.dst_width);
|
||||
dst += buf->stride;
|
||||
num_lines_out++;
|
||||
++num_lines_out;
|
||||
}
|
||||
return num_lines_out;
|
||||
}
|
||||
@ -479,7 +480,7 @@ static int ExportAlpha(WebPDecParams* const p, int y_pos) {
|
||||
dst[4 * i] = p->scaler_a.dst[i];
|
||||
}
|
||||
dst += buf->stride;
|
||||
num_lines_out++;
|
||||
++num_lines_out;
|
||||
}
|
||||
return num_lines_out;
|
||||
}
|
||||
@ -498,18 +499,21 @@ static int ExportAlphaRGBA4444(WebPDecParams* const p, int y_pos) {
|
||||
dst[2 * i] = (dst[2 * i] & 0xf0) | alpha_val;
|
||||
}
|
||||
dst += buf->stride;
|
||||
num_lines_out++;
|
||||
++num_lines_out;
|
||||
}
|
||||
return num_lines_out;
|
||||
}
|
||||
|
||||
static int EmitRescaledAlphaRGB(const VP8Io* const io, WebPDecParams* const p) {
|
||||
if (io->a) {
|
||||
if (io->a != NULL) {
|
||||
int (* const output_func)(WebPDecParams* const, int) =
|
||||
(p->output->colorspace == MODE_RGBA_4444) ? ExportAlphaRGBA4444
|
||||
: ExportAlpha;
|
||||
WebPRescaler* const scaler = &p->scaler_a;
|
||||
int j = 0, pos = 0;
|
||||
while (j < io->mb_h) {
|
||||
j += Import(io->a + j * io->width, io->width, io->mb_h - j, &p->scaler_a);
|
||||
pos += (p->output->colorspace == MODE_RGBA_4444) ?
|
||||
ExportAlphaRGBA4444(p, pos) : ExportAlpha(p, pos);
|
||||
j += Import(io->a + j * io->width, io->width, io->mb_h - j, scaler);
|
||||
pos += output_func(p, pos);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -250,7 +250,7 @@ struct VP8Decoder {
|
||||
|
||||
// main memory chunk for the above data. Persistent.
|
||||
void* mem_;
|
||||
int mem_size_;
|
||||
size_t mem_size_;
|
||||
|
||||
// Per macroblock non-persistent infos.
|
||||
int mb_x_, mb_y_; // current position, in macroblock units
|
||||
|
@ -50,9 +50,9 @@ const uint16_t VP8EntropyCost[256] = {
|
||||
//------------------------------------------------------------------------------
|
||||
// Level cost tables
|
||||
|
||||
// For each given level, the following table given the pattern of contexts
|
||||
// to use for coding it (in [][0]) as well as the bit value to use for
|
||||
// each context (in [][1]).
|
||||
// For each given level, the following table gives the pattern of contexts to
|
||||
// use for coding it (in [][0]) as well as the bit value to use for each
|
||||
// context (in [][1]).
|
||||
const uint16_t VP8LevelCodes[MAX_VARIABLE_LEVEL][2] = {
|
||||
{0x001, 0x000}, {0x007, 0x001}, {0x00f, 0x005},
|
||||
{0x00f, 0x00d}, {0x033, 0x003}, {0x033, 0x003}, {0x033, 0x023},
|
||||
|
@ -62,6 +62,8 @@ static void ResetStats(VP8Encoder* const enc, int precalc_cost) {
|
||||
//------------------------------------------------------------------------------
|
||||
// Skip decision probability
|
||||
|
||||
#define SKIP_PROBA_THRESHOLD 250 // value below which using skip_proba is OK.
|
||||
|
||||
static int CalcSkipProba(uint64_t nb, uint64_t total) {
|
||||
return (int)(total ? (total - nb) * 255 / total : 255);
|
||||
}
|
||||
@ -73,7 +75,7 @@ static int FinalizeSkipProba(VP8Encoder* const enc) {
|
||||
const int nb_events = proba->nb_skip_;
|
||||
int size;
|
||||
proba->skip_proba_ = CalcSkipProba(nb_events, nb_mbs);
|
||||
proba->use_skip_proba_ = (proba->skip_proba_ < 250);
|
||||
proba->use_skip_proba_ = (proba->skip_proba_ < SKIP_PROBA_THRESHOLD);
|
||||
size = 256; // 'use_skip_proba' bit
|
||||
if (proba->use_skip_proba_) {
|
||||
size += nb_events * VP8BitCost(1, proba->skip_proba_)
|
||||
@ -222,42 +224,47 @@ static int GetResidualCost(int ctx, const VP8Residual* const res) {
|
||||
int n = res->first;
|
||||
const uint8_t* p = res->prob[VP8EncBands[n]][ctx];
|
||||
const uint16_t *t = res->cost[VP8EncBands[n]][ctx];
|
||||
int last_p0 = p[0];
|
||||
int cost;
|
||||
|
||||
cost = VP8BitCost(res->last >= 0, p[0]);
|
||||
if (res->last < 0) {
|
||||
return cost;
|
||||
return VP8BitCost(0, last_p0);
|
||||
}
|
||||
cost = 0;
|
||||
while (n <= res->last) {
|
||||
const int v = res->coeffs[n++];
|
||||
const int v = res->coeffs[n];
|
||||
const int b = VP8EncBands[n + 1];
|
||||
++n;
|
||||
if (v == 0) {
|
||||
cost += VP8LevelCost(t, 0);
|
||||
p = res->prob[VP8EncBands[n]][0];
|
||||
t = res->cost[VP8EncBands[n]][0];
|
||||
p = res->prob[b][0];
|
||||
t = res->cost[b][0];
|
||||
continue;
|
||||
} else if (2u >= (unsigned int)(v + 1)) { // v = -1 or 1
|
||||
}
|
||||
cost += VP8BitCost(1, last_p0);
|
||||
if (2u >= (unsigned int)(v + 1)) { // v = -1 or 1
|
||||
cost += VP8LevelCost(t, 1);
|
||||
p = res->prob[VP8EncBands[n]][1];
|
||||
t = res->cost[VP8EncBands[n]][1];
|
||||
p = res->prob[b][1];
|
||||
t = res->cost[b][1];
|
||||
} else {
|
||||
cost += VP8LevelCost(t, abs(v));
|
||||
p = res->prob[VP8EncBands[n]][2];
|
||||
t = res->cost[VP8EncBands[n]][2];
|
||||
}
|
||||
if (n < 16) {
|
||||
cost += VP8BitCost(n <= res->last, p[0]);
|
||||
p = res->prob[b][2];
|
||||
t = res->cost[b][2];
|
||||
}
|
||||
last_p0 = p[0];
|
||||
}
|
||||
if (n < 16) cost += VP8BitCost(0, last_p0);
|
||||
return cost;
|
||||
}
|
||||
|
||||
int VP8GetCostLuma4(VP8EncIterator* const it, const int16_t levels[16]) {
|
||||
const int x = (it->i4_ & 3), y = (it->i4_ >> 2);
|
||||
VP8Residual res;
|
||||
VP8Encoder* const enc = it->enc_;
|
||||
int R = 0;
|
||||
int ctx;
|
||||
|
||||
InitResidual(0, 3, it->enc_, &res);
|
||||
InitResidual(0, 3, enc, &res);
|
||||
ctx = it->top_nz_[x] + it->left_nz_[y];
|
||||
SetResidualCoeffs(levels, &res);
|
||||
R += GetResidualCost(ctx, &res);
|
||||
@ -266,18 +273,19 @@ int VP8GetCostLuma4(VP8EncIterator* const it, const int16_t levels[16]) {
|
||||
|
||||
int VP8GetCostLuma16(VP8EncIterator* const it, const VP8ModeScore* const rd) {
|
||||
VP8Residual res;
|
||||
VP8Encoder* const enc = it->enc_;
|
||||
int x, y;
|
||||
int R = 0;
|
||||
|
||||
VP8IteratorNzToBytes(it); // re-import the non-zero context
|
||||
|
||||
// DC
|
||||
InitResidual(0, 1, it->enc_, &res);
|
||||
InitResidual(0, 1, enc, &res);
|
||||
SetResidualCoeffs(rd->y_dc_levels, &res);
|
||||
R += GetResidualCost(it->top_nz_[8] + it->left_nz_[8], &res);
|
||||
|
||||
// AC
|
||||
InitResidual(1, 0, it->enc_, &res);
|
||||
InitResidual(1, 0, enc, &res);
|
||||
for (y = 0; y < 4; ++y) {
|
||||
for (x = 0; x < 4; ++x) {
|
||||
const int ctx = it->top_nz_[x] + it->left_nz_[y];
|
||||
@ -291,12 +299,13 @@ int VP8GetCostLuma16(VP8EncIterator* const it, const VP8ModeScore* const rd) {
|
||||
|
||||
int VP8GetCostUV(VP8EncIterator* const it, const VP8ModeScore* const rd) {
|
||||
VP8Residual res;
|
||||
VP8Encoder* const enc = it->enc_;
|
||||
int ch, x, y;
|
||||
int R = 0;
|
||||
|
||||
VP8IteratorNzToBytes(it); // re-import the non-zero context
|
||||
|
||||
InitResidual(0, 2, it->enc_, &res);
|
||||
InitResidual(0, 2, enc, &res);
|
||||
for (ch = 0; ch <= 2; ch += 2) {
|
||||
for (y = 0; y < 2; ++y) {
|
||||
for (x = 0; x < 2; ++x) {
|
||||
@ -392,18 +401,19 @@ static void CodeResiduals(VP8BitWriter* const bw,
|
||||
uint64_t pos1, pos2, pos3;
|
||||
const int i16 = (it->mb_->type_ == 1);
|
||||
const int segment = it->mb_->segment_;
|
||||
VP8Encoder* const enc = it->enc_;
|
||||
|
||||
VP8IteratorNzToBytes(it);
|
||||
|
||||
pos1 = VP8BitWriterPos(bw);
|
||||
if (i16) {
|
||||
InitResidual(0, 1, it->enc_, &res);
|
||||
InitResidual(0, 1, enc, &res);
|
||||
SetResidualCoeffs(rd->y_dc_levels, &res);
|
||||
it->top_nz_[8] = it->left_nz_[8] =
|
||||
PutCoeffs(bw, it->top_nz_[8] + it->left_nz_[8], &res);
|
||||
InitResidual(1, 0, it->enc_, &res);
|
||||
InitResidual(1, 0, enc, &res);
|
||||
} else {
|
||||
InitResidual(0, 3, it->enc_, &res);
|
||||
InitResidual(0, 3, enc, &res);
|
||||
}
|
||||
|
||||
// luma-AC
|
||||
@ -417,7 +427,7 @@ static void CodeResiduals(VP8BitWriter* const bw,
|
||||
pos2 = VP8BitWriterPos(bw);
|
||||
|
||||
// U/V
|
||||
InitResidual(0, 2, it->enc_, &res);
|
||||
InitResidual(0, 2, enc, &res);
|
||||
for (ch = 0; ch <= 2; ch += 2) {
|
||||
for (y = 0; y < 2; ++y) {
|
||||
for (x = 0; x < 2; ++x) {
|
||||
@ -442,17 +452,18 @@ static void RecordResiduals(VP8EncIterator* const it,
|
||||
const VP8ModeScore* const rd) {
|
||||
int x, y, ch;
|
||||
VP8Residual res;
|
||||
VP8Encoder* const enc = it->enc_;
|
||||
|
||||
VP8IteratorNzToBytes(it);
|
||||
|
||||
if (it->mb_->type_ == 1) { // i16x16
|
||||
InitResidual(0, 1, it->enc_, &res);
|
||||
InitResidual(0, 1, enc, &res);
|
||||
SetResidualCoeffs(rd->y_dc_levels, &res);
|
||||
it->top_nz_[8] = it->left_nz_[8] =
|
||||
RecordCoeffs(it->top_nz_[8] + it->left_nz_[8], &res);
|
||||
InitResidual(1, 0, it->enc_, &res);
|
||||
InitResidual(1, 0, enc, &res);
|
||||
} else {
|
||||
InitResidual(0, 3, it->enc_, &res);
|
||||
InitResidual(0, 3, enc, &res);
|
||||
}
|
||||
|
||||
// luma-AC
|
||||
@ -465,7 +476,7 @@ static void RecordResiduals(VP8EncIterator* const it,
|
||||
}
|
||||
|
||||
// U/V
|
||||
InitResidual(0, 2, it->enc_, &res);
|
||||
InitResidual(0, 2, enc, &res);
|
||||
for (ch = 0; ch <= 2; ch += 2) {
|
||||
for (y = 0; y < 2; ++y) {
|
||||
for (x = 0; x < 2; ++x) {
|
||||
|
@ -24,7 +24,7 @@ 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_) > 0 ? 129 : 127;
|
||||
(it->y_ > 0) ? 129 : 127;
|
||||
memset(enc->y_left_, 129, 16);
|
||||
memset(enc->u_left_, 129, 8);
|
||||
memset(enc->v_left_, 129, 8);
|
||||
@ -33,7 +33,7 @@ static void InitLeft(VP8EncIterator* const it) {
|
||||
|
||||
static void InitTop(VP8EncIterator* const it) {
|
||||
const VP8Encoder* const enc = it->enc_;
|
||||
const int top_size = enc->mb_w_ * 16;
|
||||
const size_t top_size = enc->mb_w_ * 16;
|
||||
memset(enc->y_top_, 127, 2 * top_size);
|
||||
memset(enc->nz_, 0, enc->mb_w_ * sizeof(*enc->nz_));
|
||||
}
|
||||
@ -102,12 +102,12 @@ void VP8IteratorImport(const VP8EncIterator* const it) {
|
||||
const VP8Encoder* const enc = it->enc_;
|
||||
const int x = it->x_, y = it->y_;
|
||||
const WebPPicture* const pic = enc->pic_;
|
||||
const uint8_t* ysrc = pic->y + (y * pic->y_stride + x) * 16;
|
||||
const uint8_t* usrc = pic->u + (y * pic->uv_stride + x) * 8;
|
||||
const uint8_t* vsrc = pic->v + (y * pic->uv_stride + x) * 8;
|
||||
uint8_t* ydst = it->yuv_in_ + Y_OFF;
|
||||
uint8_t* udst = it->yuv_in_ + U_OFF;
|
||||
uint8_t* vdst = it->yuv_in_ + V_OFF;
|
||||
const uint8_t* const ysrc = pic->y + (y * pic->y_stride + x) * 16;
|
||||
const uint8_t* const usrc = pic->u + (y * pic->uv_stride + x) * 8;
|
||||
const uint8_t* const vsrc = pic->v + (y * pic->uv_stride + x) * 8;
|
||||
uint8_t* const ydst = it->yuv_in_ + Y_OFF;
|
||||
uint8_t* const udst = it->yuv_in_ + U_OFF;
|
||||
uint8_t* const vdst = it->yuv_in_ + V_OFF;
|
||||
int w = (pic->width - x * 16);
|
||||
int h = (pic->height - y * 16);
|
||||
|
||||
@ -118,8 +118,8 @@ void VP8IteratorImport(const VP8EncIterator* const it) {
|
||||
ImportBlock(ysrc, pic->y_stride, ydst, w, h, 16);
|
||||
|
||||
{ // U/V planes
|
||||
const int uv_w = (w + 1) / 2;
|
||||
const int uv_h = (h + 1) / 2;
|
||||
const int uv_w = (w + 1) >> 1;
|
||||
const int uv_h = (h + 1) >> 1;
|
||||
ImportBlock(usrc, pic->uv_stride, udst, uv_w, uv_h, 8);
|
||||
ImportBlock(vsrc, pic->uv_stride, vdst, uv_w, uv_h, 8);
|
||||
}
|
||||
@ -158,8 +158,8 @@ void VP8IteratorExport(const VP8EncIterator* const it) {
|
||||
ExportBlock(ysrc, ydst, pic->y_stride, w, h);
|
||||
|
||||
{ // U/V planes
|
||||
const int uv_w = (w + 1) / 2;
|
||||
const int uv_h = (h + 1) / 2;
|
||||
const int uv_w = (w + 1) >> 1;
|
||||
const int uv_h = (h + 1) >> 1;
|
||||
ExportBlock(usrc, udst, pic->uv_stride, uv_w, uv_h);
|
||||
ExportBlock(vsrc, vdst, pic->uv_stride, uv_w, uv_h);
|
||||
}
|
||||
@ -185,47 +185,51 @@ void VP8IteratorExport(const VP8EncIterator* const it) {
|
||||
|
||||
void VP8IteratorNzToBytes(VP8EncIterator* const it) {
|
||||
const int tnz = it->nz_[0], lnz = it->nz_[-1];
|
||||
int* const top_nz = it->top_nz_;
|
||||
int* const left_nz = it->left_nz_;
|
||||
|
||||
// Top-Y
|
||||
it->top_nz_[0] = BIT(tnz, 12);
|
||||
it->top_nz_[1] = BIT(tnz, 13);
|
||||
it->top_nz_[2] = BIT(tnz, 14);
|
||||
it->top_nz_[3] = BIT(tnz, 15);
|
||||
top_nz[0] = BIT(tnz, 12);
|
||||
top_nz[1] = BIT(tnz, 13);
|
||||
top_nz[2] = BIT(tnz, 14);
|
||||
top_nz[3] = BIT(tnz, 15);
|
||||
// Top-U
|
||||
it->top_nz_[4] = BIT(tnz, 18);
|
||||
it->top_nz_[5] = BIT(tnz, 19);
|
||||
top_nz[4] = BIT(tnz, 18);
|
||||
top_nz[5] = BIT(tnz, 19);
|
||||
// Top-V
|
||||
it->top_nz_[6] = BIT(tnz, 22);
|
||||
it->top_nz_[7] = BIT(tnz, 23);
|
||||
top_nz[6] = BIT(tnz, 22);
|
||||
top_nz[7] = BIT(tnz, 23);
|
||||
// DC
|
||||
it->top_nz_[8] = BIT(tnz, 24);
|
||||
top_nz[8] = BIT(tnz, 24);
|
||||
|
||||
// left-Y
|
||||
it->left_nz_[0] = BIT(lnz, 3);
|
||||
it->left_nz_[1] = BIT(lnz, 7);
|
||||
it->left_nz_[2] = BIT(lnz, 11);
|
||||
it->left_nz_[3] = BIT(lnz, 15);
|
||||
left_nz[0] = BIT(lnz, 3);
|
||||
left_nz[1] = BIT(lnz, 7);
|
||||
left_nz[2] = BIT(lnz, 11);
|
||||
left_nz[3] = BIT(lnz, 15);
|
||||
// left-U
|
||||
it->left_nz_[4] = BIT(lnz, 17);
|
||||
it->left_nz_[5] = BIT(lnz, 19);
|
||||
left_nz[4] = BIT(lnz, 17);
|
||||
left_nz[5] = BIT(lnz, 19);
|
||||
// left-V
|
||||
it->left_nz_[6] = BIT(lnz, 21);
|
||||
it->left_nz_[7] = BIT(lnz, 23);
|
||||
left_nz[6] = BIT(lnz, 21);
|
||||
left_nz[7] = BIT(lnz, 23);
|
||||
// left-DC is special, iterated separately
|
||||
}
|
||||
|
||||
void VP8IteratorBytesToNz(VP8EncIterator* const it) {
|
||||
uint32_t nz = 0;
|
||||
const int* const top_nz = it->top_nz_;
|
||||
const int* const left_nz = it->left_nz_;
|
||||
// top
|
||||
nz |= (it->top_nz_[0] << 12) | (it->top_nz_[1] << 13);
|
||||
nz |= (it->top_nz_[2] << 14) | (it->top_nz_[3] << 15);
|
||||
nz |= (it->top_nz_[4] << 18) | (it->top_nz_[5] << 19);
|
||||
nz |= (it->top_nz_[6] << 22) | (it->top_nz_[7] << 23);
|
||||
nz |= (it->top_nz_[8] << 24); // we propagate the _top_ bit, esp. for intra4
|
||||
nz |= (top_nz[0] << 12) | (top_nz[1] << 13);
|
||||
nz |= (top_nz[2] << 14) | (top_nz[3] << 15);
|
||||
nz |= (top_nz[4] << 18) | (top_nz[5] << 19);
|
||||
nz |= (top_nz[6] << 22) | (top_nz[7] << 23);
|
||||
nz |= (top_nz[8] << 24); // we propagate the _top_ bit, esp. for intra4
|
||||
// left
|
||||
nz |= (it->left_nz_[0] << 3) | (it->left_nz_[1] << 7);
|
||||
nz |= (it->left_nz_[2] << 11);
|
||||
nz |= (it->left_nz_[4] << 17) | (it->left_nz_[6] << 21);
|
||||
nz |= (left_nz[0] << 3) | (left_nz[1] << 7);
|
||||
nz |= (left_nz[2] << 11);
|
||||
nz |= (left_nz[4] << 17) | (left_nz[6] << 21);
|
||||
|
||||
*it->nz_ = nz;
|
||||
}
|
||||
@ -281,8 +285,8 @@ int VP8IteratorNext(VP8EncIterator* const it,
|
||||
// Helper function to set mode properties
|
||||
|
||||
void VP8SetIntra16Mode(const VP8EncIterator* const it, int mode) {
|
||||
int y;
|
||||
uint8_t* preds = it->preds_;
|
||||
int y;
|
||||
for (y = 0; y < 4; ++y) {
|
||||
memset(preds, mode, 4);
|
||||
preds += it->enc_->preds_w_;
|
||||
@ -291,9 +295,10 @@ void VP8SetIntra16Mode(const VP8EncIterator* const it, int mode) {
|
||||
}
|
||||
|
||||
void VP8SetIntra4Mode(const VP8EncIterator* const it, int modes[16]) {
|
||||
int x, y;
|
||||
uint8_t* preds = it->preds_;
|
||||
int y;
|
||||
for (y = 0; y < 4; ++y) {
|
||||
int x;
|
||||
for (x = 0; x < 4; ++x) {
|
||||
preds[x] = modes[x + y * 4];
|
||||
}
|
||||
@ -354,7 +359,7 @@ static const uint8_t VP8TopLeftI4[16] = {
|
||||
};
|
||||
|
||||
void VP8IteratorStartI4(VP8EncIterator* const it) {
|
||||
VP8Encoder* const enc = it->enc_;
|
||||
const VP8Encoder* const enc = it->enc_;
|
||||
int i;
|
||||
|
||||
it->i4_ = 0; // first 4x4 sub-block
|
||||
@ -400,7 +405,7 @@ int VP8IteratorRotateI4(VP8EncIterator* const it,
|
||||
}
|
||||
}
|
||||
// move pointers to next sub-block
|
||||
it->i4_++;
|
||||
++it->i4_;
|
||||
if (it->i4_ == 16) { // we're done
|
||||
return 0;
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ extern "C" {
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int WebPPictureAlloc(WebPPicture* const picture) {
|
||||
if (picture) {
|
||||
if (picture != NULL) {
|
||||
const WebPEncCSP uv_csp = picture->colorspace & WEBP_CSP_UV_MASK;
|
||||
const int has_alpha = picture->colorspace & WEBP_CSP_ALPHA_BIT;
|
||||
const int width = picture->width;
|
||||
@ -108,7 +108,7 @@ int WebPPictureAlloc(WebPPicture* const picture) {
|
||||
// into 'dst'. Mark 'dst' as not owning any memory. 'src' can be NULL.
|
||||
static void WebPPictureGrabSpecs(const WebPPicture* const src,
|
||||
WebPPicture* const dst) {
|
||||
if (src) *dst = *src;
|
||||
if (src != NULL) *dst = *src;
|
||||
dst->y = dst->u = dst->v = NULL;
|
||||
dst->u0 = dst->v0 = NULL;
|
||||
dst->a = NULL;
|
||||
@ -116,7 +116,7 @@ static void WebPPictureGrabSpecs(const WebPPicture* const src,
|
||||
|
||||
// Release memory owned by 'picture'.
|
||||
void WebPPictureFree(WebPPicture* const picture) {
|
||||
if (picture) {
|
||||
if (picture != NULL) {
|
||||
free(picture->y);
|
||||
WebPPictureGrabSpecs(NULL, picture);
|
||||
}
|
||||
@ -125,7 +125,7 @@ void WebPPictureFree(WebPPicture* const picture) {
|
||||
//------------------------------------------------------------------------------
|
||||
// Picture copying
|
||||
|
||||
// TODO(skal): move to dsp/ ?
|
||||
// Not worth moving to dsp/enc.c (only used here).
|
||||
static void CopyPlane(const uint8_t* src, int src_stride,
|
||||
uint8_t* dst, int dst_stride, int width, int height) {
|
||||
while (height-- > 0) {
|
||||
@ -195,13 +195,13 @@ int WebPPictureCrop(WebPPicture* const pic,
|
||||
tmp.v, tmp.uv_stride, HALVE(width), HALVE(height));
|
||||
}
|
||||
|
||||
if (tmp.a) {
|
||||
if (tmp.a != NULL) {
|
||||
const int a_offset = top * pic->a_stride + left;
|
||||
CopyPlane(pic->a + a_offset, pic->a_stride,
|
||||
tmp.a, tmp.a_stride, width, height);
|
||||
}
|
||||
#ifdef WEBP_EXPERIMENTAL_FEATURES
|
||||
if (tmp.u0) {
|
||||
if (tmp.u0 != NULL) {
|
||||
int w = width;
|
||||
int l = left;
|
||||
if (tmp.colorspace == WEBP_YUV422) {
|
||||
@ -348,12 +348,12 @@ int WebPPictureRescale(WebPPicture* const pic, int width, int height) {
|
||||
tmp.v,
|
||||
HALVE(width), HALVE(height), tmp.uv_stride, work);
|
||||
|
||||
if (tmp.a) {
|
||||
if (tmp.a != NULL) {
|
||||
RescalePlane(pic->a, prev_width, prev_height, pic->a_stride,
|
||||
tmp.a, width, height, tmp.a_stride, work);
|
||||
}
|
||||
#ifdef WEBP_EXPERIMENTAL_FEATURES
|
||||
if (tmp.u0) {
|
||||
if (tmp.u0 != NULL) {
|
||||
int s = 1;
|
||||
if ((tmp.colorspace & WEBP_CSP_UV_MASK) == WEBP_YUV422) {
|
||||
s = 2;
|
||||
@ -382,7 +382,7 @@ typedef struct {
|
||||
size_t* size;
|
||||
} WebPMemoryWriter;
|
||||
|
||||
static void InitMemoryWriter(WebPMemoryWriter* const writer) {
|
||||
static void WebPMemoryWriterInit(WebPMemoryWriter* const writer) {
|
||||
*writer->mem = NULL;
|
||||
*writer->size = 0;
|
||||
writer->max_size = 0;
|
||||
@ -412,7 +412,7 @@ static int WebPMemoryWrite(const uint8_t* data, size_t data_size,
|
||||
*w->mem = new_mem;
|
||||
w->max_size = next_max_size;
|
||||
}
|
||||
if (data_size) {
|
||||
if (data_size > 0) {
|
||||
memcpy((*w->mem) + (*w->size), data, data_size);
|
||||
*w->size += data_size;
|
||||
}
|
||||
@ -683,7 +683,7 @@ static size_t Encode(const uint8_t* rgba, int width, int height, int stride,
|
||||
|
||||
wrt.mem = output;
|
||||
wrt.size = &output_size;
|
||||
InitMemoryWriter(&wrt);
|
||||
WebPMemoryWriterInit(&wrt);
|
||||
|
||||
ok = import(&pic, rgba, stride) && WebPEncode(&config, &pic);
|
||||
WebPPictureFree(&pic);
|
||||
|
@ -299,16 +299,16 @@ const int VP8I4ModeOffsets[NUM_BMODES] = {
|
||||
};
|
||||
|
||||
void VP8MakeLuma16Preds(const VP8EncIterator* const it) {
|
||||
VP8Encoder* const enc = it->enc_;
|
||||
const uint8_t* left = it->x_ ? enc->y_left_ : NULL;
|
||||
const uint8_t* top = it->y_ ? enc->y_top_ + it->x_ * 16 : NULL;
|
||||
const VP8Encoder* const enc = it->enc_;
|
||||
const uint8_t* const left = it->x_ ? enc->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) {
|
||||
VP8Encoder* const enc = it->enc_;
|
||||
const uint8_t* left = it->x_ ? enc->u_left_ : NULL;
|
||||
const uint8_t* top = it->y_ ? enc->uv_top_ + it->x_ * 16 : NULL;
|
||||
const VP8Encoder* const enc = it->enc_;
|
||||
const uint8_t* const left = it->x_ ? enc->u_left_ : NULL;
|
||||
const uint8_t* const top = it->y_ ? enc->uv_top_ + it->x_ * 16 : NULL;
|
||||
VP8EncPredChroma8(it->yuv_p_, left, top);
|
||||
}
|
||||
|
||||
@ -700,7 +700,7 @@ static void SwapOut(VP8EncIterator* const it) {
|
||||
}
|
||||
|
||||
static void PickBestIntra16(VP8EncIterator* const it, VP8ModeScore* const rd) {
|
||||
VP8Encoder* const enc = it->enc_;
|
||||
const VP8Encoder* const enc = it->enc_;
|
||||
const VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_];
|
||||
const int lambda = dqm->lambda_i16_;
|
||||
const int tlambda = dqm->tlambda_;
|
||||
@ -751,7 +751,7 @@ static const uint16_t* GetCostModeI4(VP8EncIterator* const it,
|
||||
}
|
||||
|
||||
static int PickBestIntra4(VP8EncIterator* const it, VP8ModeScore* const rd) {
|
||||
VP8Encoder* const enc = it->enc_;
|
||||
const VP8Encoder* const enc = it->enc_;
|
||||
const VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_];
|
||||
const int lambda = dqm->lambda_i4_;
|
||||
const int tlambda = dqm->tlambda_;
|
||||
@ -827,7 +827,7 @@ static int PickBestIntra4(VP8EncIterator* const it, VP8ModeScore* const rd) {
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static void PickBestUV(VP8EncIterator* const it, VP8ModeScore* const rd) {
|
||||
VP8Encoder* const enc = it->enc_;
|
||||
const VP8Encoder* const enc = it->enc_;
|
||||
const VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_];
|
||||
const int lambda = dqm->lambda_uv_;
|
||||
const uint8_t* const src = it->yuv_in_ + U_OFF;
|
||||
|
@ -136,13 +136,13 @@ static WebPEncodingError PutVP8FrameHeader(const WebPPicture* const pic,
|
||||
| (profile << 1) // profile (3b)
|
||||
| (1 << 4) // visible (1b)
|
||||
| ((uint32_t)size0 << 5); // partition length (19b)
|
||||
vp8_frm_hdr[0] = bits & 0xff;
|
||||
vp8_frm_hdr[1] = (bits >> 8) & 0xff;
|
||||
vp8_frm_hdr[0] = (bits >> 0) & 0xff;
|
||||
vp8_frm_hdr[1] = (bits >> 8) & 0xff;
|
||||
vp8_frm_hdr[2] = (bits >> 16) & 0xff;
|
||||
// signature
|
||||
vp8_frm_hdr[3] = (KSIGNATURE >> 16) & 0xff;
|
||||
vp8_frm_hdr[4] = (KSIGNATURE >> 8) & 0xff;
|
||||
vp8_frm_hdr[5] = (KSIGNATURE >> 0) & 0xff;
|
||||
vp8_frm_hdr[4] = (KSIGNATURE >> 8) & 0xff;
|
||||
vp8_frm_hdr[5] = (KSIGNATURE >> 0) & 0xff;
|
||||
// dimensions
|
||||
vp8_frm_hdr[6] = pic->width & 0xff;
|
||||
vp8_frm_hdr[7] = pic->width >> 8;
|
||||
|
Loading…
x
Reference in New Issue
Block a user