1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-08-04 22:03:09 +02:00

avcodec/ffv1: Use dual run coder for fltmap

This improves compression by 0.1% overall and 44% for the changed table
I tried several other things but so far this is the best
compromise between complexity and compression

This can also be extended to 32 and 64bit floats

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
Michael Niedermayer
2025-03-05 02:21:03 +01:00
parent 9bad2634ee
commit 1bce40cb73
2 changed files with 32 additions and 8 deletions

View File

@ -159,12 +159,25 @@ static int RENAME(decode_rgb_frame)(FFV1Context *f, FFV1SliceContext *sc,
for (int p= 0; p<3 + transparency; p++) { for (int p= 0; p<3 + transparency; p++) {
int j = 0; int j = 0;
int lu = 0; int lu = 0;
uint8_t state[2] = {128, 128}; uint8_t state[2][32];
memset(state, 128, sizeof(state));
for (int i= 0; i<65536; i++) { for (int i= 0; i<65536; i++) {
int u = get_rac(&sc->c, state + lu); int run = get_symbol_inline(&sc->c, state[lu], 0);
sc->fltmap[p][j] = i ^ ((i&0x8000) ? 0 : 0x7FFF); if (run > 65536U - i)
j+= u; return AVERROR_INVALIDDATA;
lu = u; if (lu) {
lu ^= !run;
while (run--) {
sc->fltmap[p][j++] = i ^ ((i&0x8000) ? 0 : 0x7FFF);
i++;
}
} else {
i += run;
if (i != 65536)
sc->fltmap[p][j++] = i ^ ((i&0x8000) ? 0 : 0x7FFF);
lu ^= !run;
}
} }
} }
} }

View File

@ -177,16 +177,27 @@ static int RENAME(encode_rgb_frame)(FFV1Context *f, FFV1SliceContext *sc,
for (int p= 0; p<3 + transparency; p++) { for (int p= 0; p<3 + transparency; p++) {
int j = 0; int j = 0;
int lu = 0; int lu = 0;
uint8_t state[2] = {128, 128}; uint8_t state[2][32];
int run = 0;
memset(state, 128, sizeof(state));
for (int i= 0; i<65536; i++) { for (int i= 0; i<65536; i++) {
int ri = i ^ ((i&0x8000) ? 0 : 0x7FFF); int ri = i ^ ((i&0x8000) ? 0 : 0x7FFF);
int u = sc->fltmap[p][ri]; int u = sc->fltmap[p][ri];
sc->fltmap[p][ri] = j; sc->fltmap[p][ri] = j;
j+= u; j+= u;
put_rac(&sc->c, state + lu, u);
if (lu == u) {
run ++;
} else {
put_symbol_inline(&sc->c, state[lu], run, 0, NULL, NULL);
if (run == 0)
lu = u; lu = u;
run = 0;
} }
} }
if (run)
put_symbol(&sc->c, state[lu], run, 0);
}
} }
for (y = 0; y < h; y++) { for (y = 0; y < h; y++) {