encoder speed-up: hardcode special level values

1-3% faster

Change-Id: Ib2131989fbf819bcbfa6456adbeea0ba27c914f7
This commit is contained in:
Pascal Massimino 2011-07-12 15:52:43 -07:00
parent c558bdad28
commit c915fb2aa7
3 changed files with 30 additions and 8 deletions

View File

@ -55,7 +55,7 @@ const uint16_t VP8EntropyCost[256] = {
// 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]).
static const uint16_t kLevelCodes[MAX_VARIABLE_LEVEL][2] = {
const uint16_t VP8LevelCodes[MAX_VARIABLE_LEVEL][2] = {
{0x001, 0x000}, {0x007, 0x001}, {0x00f, 0x005},
{0x00f, 0x00d}, {0x033, 0x003}, {0x033, 0x003}, {0x033, 0x023},
{0x033, 0x023}, {0x033, 0x023}, {0x033, 0x023}, {0x0d3, 0x013},
@ -337,8 +337,8 @@ const uint16_t VP8LevelFixedCosts[2048] = {
};
static int VariableLevelCost(int level, const uint8_t probas[NUM_PROBAS]) {
int pattern = kLevelCodes[level - 1][0];
int bits = kLevelCodes[level - 1][1];
int pattern = VP8LevelCodes[level - 1][0];
int bits = VP8LevelCodes[level - 1][1];
int cost = 0;
int i;
for (i = 2; pattern; ++i) {

View File

@ -33,6 +33,7 @@ static inline uint64_t VP8BranchCost(uint64_t nb, uint64_t total,
}
// Level cost calculations
extern const uint16_t VP8LevelCodes[MAX_VARIABLE_LEVEL][2];
void VP8CalculateLevelCosts(VP8Proba* const proba);
static inline int VP8LevelCost(const uint16_t* const table, int level) {
return VP8LevelFixedCosts[level]

View File

@ -101,6 +101,9 @@ static int Record(int bit, uint64_t* const stats) {
return bit;
}
// We keep the table free variant around for reference, in case.
#define USE_LEVEL_CODE_TABLE
// Simulate block coding, but only record statistics.
// Note: no need to record the fixed probas.
static int RecordCoeffs(int ctx, VP8Residual* res) {
@ -111,14 +114,16 @@ static int RecordCoeffs(int ctx, VP8Residual* res) {
}
while (1) {
const int v = abs(res->coeffs[n++]);
int v = res->coeffs[n++];
if (!Record(v != 0, s[1])) {
s = res->stats[VP8EncBands[n]][0];
continue;
}
if (!Record(v > 1, s[2])) {
if (!Record(2u < (unsigned int)(v + 1), s[2])) { // v = -1 or 1
s = res->stats[VP8EncBands[n]][1];
} else {
v = abs(v);
#if !defined(USE_LEVEL_CODE_TABLE)
if (!Record(v > 4, s[3])) {
if (Record(v != 2, s[4]))
Record(v == 4, s[5]);
@ -129,6 +134,20 @@ static int RecordCoeffs(int ctx, VP8Residual* res) {
} else {
Record((v >= 3 + (8 << 3)), s[10]);
}
#else
if (v > MAX_VARIABLE_LEVEL)
v = MAX_VARIABLE_LEVEL;
{
const int bits = VP8LevelCodes[v - 1][1];
int pattern = VP8LevelCodes[v - 1][0];
int i;
for (i = 0; (pattern >>= 1) != 0; ++i) {
const int mask = 2 << i;
if (pattern & 1) Record(!!(bits & mask), s[3 + i]);
}
}
#endif
s = res->stats[VP8EncBands[n]][2];
}
if (n == 16 || !Record(n <= res->last, s[0])) {
@ -213,16 +232,18 @@ static int GetResidualCost(int ctx, const VP8Residual* const res) {
return cost;
}
while (n <= res->last) {
const int v = abs(res->coeffs[n++]);
cost += VP8LevelCost(t, v);
const int v = res->coeffs[n++];
if (v == 0) {
cost += VP8LevelCost(t, 0);
p = res->prob[VP8EncBands[n]][0];
t = res->cost[VP8EncBands[n]][0];
continue;
} else if (v == 1) {
} else 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];
} else {
cost += VP8LevelCost(t, abs(v));
p = res->prob[VP8EncBands[n]][2];
t = res->cost[VP8EncBands[n]][2];
}