You've already forked FFmpeg
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:
@ -159,12 +159,25 @@ static int RENAME(decode_rgb_frame)(FFV1Context *f, FFV1SliceContext *sc,
|
||||
for (int p= 0; p<3 + transparency; p++) {
|
||||
int j = 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++) {
|
||||
int u = get_rac(&sc->c, state + lu);
|
||||
sc->fltmap[p][j] = i ^ ((i&0x8000) ? 0 : 0x7FFF);
|
||||
j+= u;
|
||||
lu = u;
|
||||
int run = get_symbol_inline(&sc->c, state[lu], 0);
|
||||
if (run > 65536U - i)
|
||||
return AVERROR_INVALIDDATA;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -177,16 +177,27 @@ static int RENAME(encode_rgb_frame)(FFV1Context *f, FFV1SliceContext *sc,
|
||||
for (int p= 0; p<3 + transparency; p++) {
|
||||
int j = 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++) {
|
||||
int ri = i ^ ((i&0x8000) ? 0 : 0x7FFF);
|
||||
int u = sc->fltmap[p][ri];
|
||||
sc->fltmap[p][ri] = j;
|
||||
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;
|
||||
run = 0;
|
||||
}
|
||||
}
|
||||
if (run)
|
||||
put_symbol(&sc->c, state[lu], run, 0);
|
||||
}
|
||||
}
|
||||
|
||||
for (y = 0; y < h; y++) {
|
||||
|
Reference in New Issue
Block a user