mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-25 13:18:22 +01:00
speed up GetResidualCost()
* treat the last coeff as a special case * re-arrange the inner code to be shorter * replace some VP8EncBands[n] by n, for n = 0 or 1 Change-Id: I71e17b014cffad7b073e787fde06260905a6953f
This commit is contained in:
parent
ba2aa0fdda
commit
f76191f9db
@ -113,7 +113,8 @@ static int Record(int bit, proba_t* const stats) {
|
|||||||
// Note: no need to record the fixed probas.
|
// Note: no need to record the fixed probas.
|
||||||
static int RecordCoeffs(int ctx, const VP8Residual* const res) {
|
static int RecordCoeffs(int ctx, const VP8Residual* const res) {
|
||||||
int n = res->first;
|
int n = res->first;
|
||||||
proba_t* s = res->stats[VP8EncBands[n]][ctx];
|
// should be stats[VP8EncBands[n]], but it's equivalent for n=0 or 1
|
||||||
|
proba_t* s = res->stats[n][ctx];
|
||||||
if (res->last < 0) {
|
if (res->last < 0) {
|
||||||
Record(0, s + 0);
|
Record(0, s + 0);
|
||||||
return 0;
|
return 0;
|
||||||
@ -282,16 +283,17 @@ static void SetResidualCoeffs(const int16_t* const coeffs,
|
|||||||
|
|
||||||
static int GetResidualCost(int ctx, const VP8Residual* const res) {
|
static int GetResidualCost(int ctx, const VP8Residual* const res) {
|
||||||
int n = res->first;
|
int n = res->first;
|
||||||
int p0 = res->prob[VP8EncBands[n]][ctx][0];
|
// should be prob[VP8EncBands[n]], but it's equivalent for n=0 or 1
|
||||||
const uint16_t* t = res->cost[VP8EncBands[n]][ctx];
|
int p0 = res->prob[n][ctx][0];
|
||||||
|
const uint16_t* t = res->cost[n][ctx];
|
||||||
int cost;
|
int cost;
|
||||||
|
|
||||||
if (res->last < 0) {
|
if (res->last < 0) {
|
||||||
return VP8BitCost(0, p0);
|
return VP8BitCost(0, p0);
|
||||||
}
|
}
|
||||||
cost = 0;
|
cost = 0;
|
||||||
while (n <= res->last) {
|
while (n < res->last) {
|
||||||
const int v = res->coeffs[n];
|
int v = res->coeffs[n];
|
||||||
const int b = VP8EncBands[n + 1];
|
const int b = VP8EncBands[n + 1];
|
||||||
++n;
|
++n;
|
||||||
if (v == 0) {
|
if (v == 0) {
|
||||||
@ -300,19 +302,28 @@ static int GetResidualCost(int ctx, const VP8Residual* const res) {
|
|||||||
t = res->cost[b][0];
|
t = res->cost[b][0];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
v = abs(v);
|
||||||
cost += VP8BitCost(1, p0);
|
cost += VP8BitCost(1, p0);
|
||||||
if (2u >= (unsigned int)(v + 1)) { // v = -1 or 1
|
cost += VP8LevelCost(t, v);
|
||||||
// short-case for "VP8LevelCost(t, 1)" (256 is VP8LevelFixedCosts[1]):
|
{
|
||||||
cost += 256 + t[1];
|
const int ctx = (v == 1) ? 1 : 2;
|
||||||
p0 = res->prob[b][1][0];
|
p0 = res->prob[b][ctx][0];
|
||||||
t = res->cost[b][1];
|
t = res->cost[b][ctx];
|
||||||
} else {
|
}
|
||||||
cost += VP8LevelCost(t, abs(v));
|
}
|
||||||
p0 = res->prob[b][2][0];
|
// Last coefficient is always non-zero
|
||||||
t = res->cost[b][2];
|
{
|
||||||
|
const int v = abs(res->coeffs[n]);
|
||||||
|
assert(v != 0);
|
||||||
|
cost += VP8BitCost(1, p0);
|
||||||
|
cost += VP8LevelCost(t, v);
|
||||||
|
if (n < 15) {
|
||||||
|
const int b = VP8EncBands[n + 1];
|
||||||
|
const int ctx = (v == 1) ? 1 : 2;
|
||||||
|
const int p0 = res->prob[b][ctx][0];
|
||||||
|
cost += VP8BitCost(0, p0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (n < 16) cost += VP8BitCost(0, p0);
|
|
||||||
return cost;
|
return cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,7 +394,8 @@ int VP8GetCostUV(VP8EncIterator* const it, const VP8ModeScore* const rd) {
|
|||||||
|
|
||||||
static int PutCoeffs(VP8BitWriter* const bw, int ctx, const VP8Residual* res) {
|
static int PutCoeffs(VP8BitWriter* const bw, int ctx, const VP8Residual* res) {
|
||||||
int n = res->first;
|
int n = res->first;
|
||||||
const uint8_t* p = res->prob[VP8EncBands[n]][ctx];
|
// should be prob[VP8EncBands[n]], but it's equivalent for n=0 or 1
|
||||||
|
const uint8_t* p = res->prob[n][ctx];
|
||||||
if (!VP8PutBit(bw, res->last >= 0, p[0])) {
|
if (!VP8PutBit(bw, res->last >= 0, p[0])) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user