Skip to content

Commit 437cbd2

Browse files
committed
avcodec/ffv1: Implement jeromes idea of making remap flip optional
This also makes remap optional (which is a good idea even if we decide to keep flip fixed) Effect on compression (using 2 rawlsb, golomb rice, large context model with ACES_OT_VWG_SampleFrames -rw-r----- 1 michael michael 499101306 Mär 11 14:58 float-303503-try3d-m2.nut -rw-r----- 1 michael michael 503700199 Mär 11 14:57 float-303503-try3d-m1.nut -rw-r----- 1 michael michael 518150578 Mär 11 14:57 float-303503-try3d-m0.nut (the test above used the rawlsb patch, which is not applied yet) Reviewed-by: Jerome Martinez <[email protected]> Signed-off-by: Michael Niedermayer <[email protected]>
1 parent dcf6142 commit 437cbd2

File tree

3 files changed

+23
-7
lines changed

3 files changed

+23
-7
lines changed

libavcodec/ffv1.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ typedef struct FFV1Context {
137137
uint8_t (*initial_states[MAX_QUANT_TABLES])[32];
138138
int colorspace;
139139
int flt;
140+
int remap_mode;
140141

141142

142143
int use32bit;

libavcodec/ffv1dec.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,8 @@ static int decode_slice_header(const FFV1Context *f,
222222
}
223223
if (f->combined_version >= 0x40004) {
224224
sc->remap = ff_ffv1_get_symbol(c, state, 0);
225-
if (sc->remap > 1U ||
226-
sc->remap == 1 && !f->flt) {
225+
if (sc->remap > 2U ||
226+
sc->remap && !f->flt) {
227227
av_log(f->avctx, AV_LOG_ERROR, "unsupported remap %d\n", sc->remap);
228228
return AVERROR_INVALIDDATA;
229229
}
@@ -246,6 +246,7 @@ static void slice_set_damaged(FFV1Context *f, FFV1SliceContext *sc)
246246
static int decode_remap(FFV1Context *f, FFV1SliceContext *sc)
247247
{
248248
int transparency = f->transparency;
249+
int flip = sc->remap == 2 ? 0x7FFF : 0;
249250

250251
for (int p= 0; p<3 + transparency; p++) {
251252
int j = 0;
@@ -260,13 +261,13 @@ static int decode_remap(FFV1Context *f, FFV1SliceContext *sc)
260261
if (lu) {
261262
lu ^= !run;
262263
while (run--) {
263-
sc->fltmap[p][j++] = i ^ ((i&0x8000) ? 0 : 0x7FFF);
264+
sc->fltmap[p][j++] = i ^ ((i&0x8000) ? 0 : flip);
264265
i++;
265266
}
266267
} else {
267268
i += run;
268269
if (i != 65536)
269-
sc->fltmap[p][j++] = i ^ ((i&0x8000) ? 0 : 0x7FFF);
270+
sc->fltmap[p][j++] = i ^ ((i&0x8000) ? 0 : flip);
270271
lu ^= !run;
271272
}
272273
}

libavcodec/ffv1enc.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -903,6 +903,9 @@ av_cold int ff_ffv1_encode_setup_plane_info(AVCodecContext *avctx,
903903
}
904904
av_assert0(s->bits_per_raw_sample >= 8);
905905

906+
if (s->remap_mode < 0)
907+
s->remap_mode = s->flt ? 2 : 0;
908+
906909
return av_pix_fmt_get_chroma_sub_sample(pix_fmt, &s->chroma_h_shift, &s->chroma_v_shift);
907910
}
908911

@@ -958,7 +961,7 @@ static int encode_init_internal(AVCodecContext *avctx)
958961

959962
ff_build_rac_states(&s->slices[j].c, 0.05 * (1LL << 32), 256 - 8);
960963

961-
s->slices[j].remap = s->flt;
964+
s->slices[j].remap = s->remap_mode;
962965
}
963966

964967
if ((ret = ff_ffv1_init_slices_state(s)) < 0)
@@ -1115,6 +1118,7 @@ static void choose_rct_params(const FFV1Context *f, FFV1SliceContext *sc,
11151118
static void encode_remap(FFV1Context *f, FFV1SliceContext *sc)
11161119
{
11171120
int transparency = f->transparency;
1121+
int flip = sc->remap == 2 ? 0x7FFF : 0;
11181122

11191123
for (int p= 0; p<3 + transparency; p++) {
11201124
int j = 0;
@@ -1123,7 +1127,7 @@ static void encode_remap(FFV1Context *f, FFV1SliceContext *sc)
11231127
int run = 0;
11241128
memset(state, 128, sizeof(state));
11251129
for (int i= 0; i<65536; i++) {
1126-
int ri = i ^ ((i&0x8000) ? 0 : 0x7FFF);
1130+
int ri = i ^ ((i&0x8000) ? 0 : flip);
11271131
int u = sc->fltmap[p][ri];
11281132
sc->fltmap[p][ri] = j;
11291133
j+= u;
@@ -1249,7 +1253,7 @@ size_t ff_ffv1_encode_buffer_size(AVCodecContext *avctx)
12491253
maxsize += f->slice_count * 800; //for slice header
12501254
if (f->version > 3) {
12511255
maxsize *= f->bits_per_raw_sample + 1;
1252-
if (f->flt) //remap table
1256+
if (f->remap_mode)
12531257
maxsize += f->slice_count * 70000 * (1 + 2*f->chroma_planes + f->transparency);
12541258
} else {
12551259
maxsize += f->slice_count * 2 * (avctx->width + avctx->height); //for bug with slices that code some pixels more than once
@@ -1432,6 +1436,16 @@ static const AVOption options[] = {
14321436
{ .i64 = QTABLE_8BIT }, INT_MIN, INT_MAX, VE, .unit = "qtable" },
14331437
{ "greater8bit", NULL, 0, AV_OPT_TYPE_CONST,
14341438
{ .i64 = QTABLE_GT8BIT }, INT_MIN, INT_MAX, VE, .unit = "qtable" },
1439+
{ "remap_mode", "Remap Mode", OFFSET(remap_mode), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 2, VE, .unit = "remap_mode" },
1440+
{ "auto", "Automatic", 0, AV_OPT_TYPE_CONST,
1441+
{ .i64 = -1 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1442+
{ "off", "Disabled", 0, AV_OPT_TYPE_CONST,
1443+
{ .i64 = 0 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1444+
{ "dualrle", "Dual RLE", 0, AV_OPT_TYPE_CONST,
1445+
{ .i64 = 1 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1446+
{ "flipdualrle", "Dual RLE", 0, AV_OPT_TYPE_CONST,
1447+
{ .i64 = 2 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1448+
14351449

14361450
{ NULL }
14371451
};

0 commit comments

Comments
 (0)