Browse Source

avcodec/ffv1: Store remap flag per slice

This allows switching it on conditionally and also for non float,
it may improve compression for RGB data that was paletted
or other synthetic images

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Michael Niedermayer 1 month ago
parent
commit
9bad2634ee

+ 1 - 0
libavcodec/ffv1.h

@@ -84,6 +84,7 @@ typedef struct FFV1SliceContext {
     int slice_coding_mode;
     int slice_rct_by_coef;
     int slice_rct_ry_coef;
+    int remap;
 
     // RefStruct reference, array of MAX_PLANES elements
     PlaneContext *plane;

+ 8 - 0
libavcodec/ffv1dec.c

@@ -220,6 +220,14 @@ static int decode_slice_header(const FFV1Context *f,
                 return AVERROR_INVALIDDATA;
             }
         }
+        if (f->combined_version >= 0x40004) {
+            sc->remap = ff_ffv1_get_symbol(c, state, 0);
+            if (sc->remap > 1U ||
+                sc->remap == 1 && !f->flt) {
+                av_log(f->avctx, AV_LOG_ERROR, "unsupported remap %d\n", sc->remap);
+                return AVERROR_INVALIDDATA;
+            }
+        }
     }
 
     return 0;

+ 2 - 2
libavcodec/ffv1dec_template.c

@@ -155,7 +155,7 @@ static int RENAME(decode_rgb_frame)(FFV1Context *f, FFV1SliceContext *sc,
 
     memset(RENAME(sc->sample_buffer), 0, 8 * (w + 6) * sizeof(*RENAME(sc->sample_buffer)));
 
-    if (f->flt) {
+    if (sc->remap) {
         for (int p= 0; p<3 + transparency; p++) {
             int j = 0;
             int lu = 0;
@@ -199,7 +199,7 @@ static int RENAME(decode_rgb_frame)(FFV1Context *f, FFV1SliceContext *sc,
                 b += g;
                 r += g;
             }
-            if (f->flt) {
+            if (sc->remap) {
                 r = sc->fltmap[0][r & 0xFFFF];
                 g = sc->fltmap[1][g & 0xFFFF];
                 b = sc->fltmap[2][b & 0xFFFF];

+ 3 - 0
libavcodec/ffv1enc.c

@@ -946,6 +946,8 @@ static int encode_init_internal(AVCodecContext *avctx)
         }
 
         ff_build_rac_states(&s->slices[j].c, 0.05 * (1LL << 32), 256 - 8);
+
+        s->slices[j].remap = s->flt;
     }
 
     if ((ret = ff_ffv1_init_slices_state(s)) < 0)
@@ -1000,6 +1002,7 @@ static void encode_slice_header(FFV1Context *f, FFV1SliceContext *sc)
             put_symbol(c, state, sc->slice_rct_by_coef, 0);
             put_symbol(c, state, sc->slice_rct_ry_coef, 0);
         }
+        put_symbol(c, state, sc->remap, 0);
     }
 }
 

+ 2 - 2
libavcodec/ffv1enc_template.c

@@ -148,7 +148,7 @@ static int RENAME(encode_rgb_frame)(FFV1Context *f, FFV1SliceContext *sc,
     memset(RENAME(sc->sample_buffer), 0, ring_size * MAX_PLANES *
            (w + 6) * sizeof(*RENAME(sc->sample_buffer)));
 
-    if (f->flt) {
+    if (sc->remap) {
         memset(sc->fltmap, 0, sizeof(sc->fltmap));
 
         for (y = 0; y < h; y++) {
@@ -221,7 +221,7 @@ static int RENAME(encode_rgb_frame)(FFV1Context *f, FFV1SliceContext *sc,
                 r = *((const uint16_t *)(src[2] + x*2 + stride[2]*y));
             }
 
-            if (f->flt) {
+            if (sc->remap) {
                 r = sc->fltmap[0][r];
                 g = sc->fltmap[1][g];
                 b = sc->fltmap[2][b];