| @@ -903,6 +903,9 @@ av_cold int ff_ffv1_encode_setup_plane_info(AVCodecContext *avctx, · 902 unmodified lines |
| 903 | 903 | } |
| 904 | 904 | av_assert0(s->bits_per_raw_sample >= 8); |
| 905 | 905 | |
| 906 | + if (s->remap_mode < 0) |
| 907 | + s->remap_mode = s->flt ? 2 : 0; |
| 908 | + |
| 906 | 909 | return av_pix_fmt_get_chroma_sub_sample(pix_fmt, &s->chroma_h_shift, &s->chroma_v_shift); |
| 907 | 910 | } |
| 908 | 911 | |
| @@ -958,7 +961,7 @@ static int encode_init_internal(AVCodecContext *avctx) · 49 unmodified lines |
| 958 | 961 | |
| 959 | 962 | ff_build_rac_states(&s->slices[j].c, 0.05 * (1LL << 32), 256 - 8); |
| 960 | 963 | |
| 961 | | − s->slices[j].remap = s->flt; |
| 964 | + s->slices[j].remap = s->remap_mode; |
| 962 | 965 | } |
| 963 | 966 | |
| 964 | 967 | if ((ret = ff_ffv1_init_slices_state(s)) < 0) |
| @@ -1115,6 +1118,7 @@ static void choose_rct_params(const FFV1Context *f, FFV1SliceContext *sc, · 150 unmodified lines |
| 1115 | 1118 | static void encode_remap(FFV1Context *f, FFV1SliceContext *sc) |
| 1116 | 1119 | { |
| 1117 | 1120 | int transparency = f->transparency; |
| 1121 | + int flip = sc->remap == 2 ? 0x7FFF : 0; |
| 1118 | 1122 | |
| 1119 | 1123 | for (int p= 0; p<3 + transparency; p++) { |
| 1120 | 1124 | int j = 0; |
| @@ -1123,7 +1127,7 @@ static void encode_remap(FFV1Context *f, FFV1SliceContext *sc) · 2 unmodified lines |
| 1123 | 1127 | int run = 0; |
| 1124 | 1128 | memset(state, 128, sizeof(state)); |
| 1125 | 1129 | for (int i= 0; i<65536; i++) { |
| 1126 | | − int ri = i ^ ((i&0x8000) ? 0 : 0x7FFF); |
| 1130 | + int ri = i ^ ((i&0x8000) ? 0 : flip); |
| 1127 | 1131 | int u = sc->fltmap[p][ri]; |
| 1128 | 1132 | sc->fltmap[p][ri] = j; |
| 1129 | 1133 | j+= u; |
| @@ -1249,7 +1253,7 @@ size_t ff_ffv1_encode_buffer_size(AVCodecContext *avctx) · 119 unmodified lines |
| 1249 | 1253 | maxsize += f->slice_count * 800; //for slice header |
| 1250 | 1254 | if (f->version > 3) { |
| 1251 | 1255 | maxsize *= f->bits_per_raw_sample + 1; |
| 1252 | | − if (f->flt) //remap table |
| 1256 | + if (f->remap_mode) |
| 1253 | 1257 | maxsize += f->slice_count * 70000 * (1 + 2*f->chroma_planes + f->transparency); |
| 1254 | 1258 | } else { |
| 1255 | 1259 | 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[] = { · 176 unmodified lines |
| 1432 | 1436 | { .i64 = QTABLE_8BIT }, INT_MIN, INT_MAX, VE, .unit = "qtable" }, |
| 1433 | 1437 | { "greater8bit", NULL, 0, AV_OPT_TYPE_CONST, |
| 1434 | 1438 | { .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 | + |
| 1435 | 1449 | |
| 1436 | 1450 | { NULL } |
| 1437 | 1451 | }; |