This also means that if a plane*slice has only 1 color nothing is stored after the remap table This also corrects the RCT offset to the exact value after remap not a fixed 65536
Unified · Split
| @@ -219,6 +219,43 @@ void ff_ffv1_clear_slice_state(const FFV1Context *f, FFV1SliceContext *sc) · 218 unmodified lines | ||
| 219 | 219 | } |
| 220 | 220 | } |
| 221 | 221 | |
| 222 | +void ff_ffv1_compute_bits_per_plane(const FFV1Context *f, FFV1SliceContext *sc, int bits[4], int *offset, int mask[4], int bits_per_raw_sample) | |
| 223 | +{ | |
| 224 | + // to simplify we use the remap_count as the symbol range in each plane | |
| 225 | + if (!sc->remap) { | |
| 226 | + sc->remap_count[0] = | |
| 227 | + sc->remap_count[1] = | |
| 228 | + sc->remap_count[2] = | |
| 229 | + sc->remap_count[3] = 1 << (bits_per_raw_sample > 0 ? bits_per_raw_sample : 8); | |
| 230 | + } | |
| 231 | + | |
| 232 | + if (sc->remap) | |
| 233 | + av_assert0(bits_per_raw_sample > 8); //breaks with lbd, needs review if added | |
| 234 | + | |
| 235 | + //bits with no RCT | |
| 236 | + for (int p=0; p<3+f->transparency; p++) { | |
| 237 | + bits[p] = av_ceil_log2(sc->remap_count[p]); | |
| 238 | + if (mask) | |
| 239 | + mask[p] = (1<<bits[p]) - 1; | |
| 240 | + } | |
| 241 | + | |
| 242 | + //RCT | |
| 243 | + if (sc->slice_coding_mode == 0) { | |
| 244 | + *offset = sc->remap_count[0]; | |
| 245 | + | |
| 246 | + bits[0] = av_ceil_log2(FFMAX3(sc->remap_count[0], sc->remap_count[1], sc->remap_count[2])); | |
| 247 | + bits[1] = av_ceil_log2(sc->remap_count[0] + sc->remap_count[1]); | |
| 248 | + bits[2] = av_ceil_log2(sc->remap_count[0] + sc->remap_count[2]); | |
| 249 | + | |
| 250 | + //old version coded a bit more than needed | |
| 251 | + if (f->combined_version < 0x40008) { | |
| 252 | + bits[0]++; | |
| 253 | + if(f->transparency) | |
| 254 | + bits[3]++; | |
| 255 | + } | |
| 256 | + } | |
| 257 | +} | |
| 258 | + | |
| 222 | 259 | int ff_ffv1_get_symbol(RangeCoder *c, uint8_t *state, int is_signed) |
| 223 | 260 | { |
| 224 | 261 | return get_symbol_inline(c, state, is_signed); |
| @@ -106,6 +106,7 @@ typedef struct FFV1SliceContext { · 105 unmodified lines | ||
| 106 | 106 | uint64_t (*rc_stat2[MAX_QUANT_TABLES])[32][2]; |
| 107 | 107 | }; |
| 108 | 108 | }; |
| 109 | + int remap_count[4]; | |
| 109 | 110 | |
| 110 | 111 | uint16_t *bitmap [4]; //float encode |
| 111 | 112 | uint16_t *fltmap [4]; //halffloat encode & decode |
| @@ -199,6 +200,7 @@ int ff_ffv1_parse_header(FFV1Context *f, RangeCoder *c, uint8_t *state); · 87 unmodified lines | ||
| 199 | 200 | int ff_ffv1_read_extra_header(FFV1Context *f); |
| 200 | 201 | int ff_ffv1_read_quant_tables(RangeCoder *c, |
| 201 | 202 | int16_t quant_table[MAX_CONTEXT_INPUTS][256]); |
| 203 | +void ff_ffv1_compute_bits_per_plane(const FFV1Context *f, FFV1SliceContext *sc, int bits[4], int offset[1], int mask[4], int bits_per_raw_sample); | |
| 202 | 204 | int ff_ffv1_get_symbol(RangeCoder *c, uint8_t *state, int is_signed); |
| 203 | 205 | |
| 204 | 206 | /** |
| @@ -99,6 +99,16 @@ static int decode_plane(FFV1Context *f, FFV1SliceContext *sc, · 98 unmodified lines | ||
| 99 | 99 | { |
| 100 | 100 | int x, y; |
| 101 | 101 | int16_t *sample[2]; |
| 102 | + int bits; | |
| 103 | + unsigned mask; | |
| 104 | + | |
| 105 | + if (sc->remap) { | |
| 106 | + bits = av_ceil_log2(sc->remap_count[remap_index]); | |
| 107 | + mask = (1<<bits)-1; | |
| 108 | + } else { | |
| 109 | + bits = f->avctx->bits_per_raw_sample; | |
| 110 | + } | |
| 111 | + | |
| 102 | 112 | sample[0] = sc->sample_buffer + 3; |
| 103 | 113 | sample[1] = sc->sample_buffer + w + 6 + 3; |
| 104 | 114 | |
| @@ -125,18 +135,18 @@ static int decode_plane(FFV1Context *f, FFV1SliceContext *sc, · 20 unmodified lines | ||
| 125 | 135 | for (x = 0; x < w; x++) |
| 126 | 136 | src[x*pixel_stride + stride * y] = sample[1][x]; |
| 127 | 137 | } else { |
| 128 | − int ret = decode_line(f, sc, gb, w, sample, plane_index, f->avctx->bits_per_raw_sample, ac); | |
| 138 | + int ret = decode_line(f, sc, gb, w, sample, plane_index, bits, ac); | |
| 129 | 139 | if (ret < 0) |
| 130 | 140 | return ret; |
| 131 | 141 | |
| 132 | 142 | if (sc->remap) { |
| 133 | 143 | if (f->packed_at_lsb || f->avctx->bits_per_raw_sample == 16) { |
| 134 | 144 | for (x = 0; x < w; x++) { |
| 135 | − ((uint16_t*)(src + stride*y))[x*pixel_stride] = sc->fltmap[remap_index][sample[1][x] & 0xFFFF]; | |
| 145 | + ((uint16_t*)(src + stride*y))[x*pixel_stride] = sc->fltmap[remap_index][sample[1][x] & mask]; | |
| 136 | 146 | } |
| 137 | 147 | } else { |
| 138 | 148 | for (x = 0; x < w; x++) { |
| 139 | − int v = sc->fltmap[remap_index][sample[1][x] & 0xFFFF]; | |
| 149 | + int v = sc->fltmap[remap_index][sample[1][x] & mask]; | |
| 140 | 150 | ((uint16_t*)(src + stride*y))[x*pixel_stride] = v << (16 - f->avctx->bits_per_raw_sample) | v >> (2 * f->avctx->bits_per_raw_sample - 16); |
| 141 | 151 | } |
| 142 | 152 | } |
| @@ -337,6 +347,7 @@ static int decode_remap(FFV1Context *f, FFV1SliceContext *sc) · 194 unmodified lines | ||
| 337 | 347 | } |
| 338 | 348 | lu ^= !run; |
| 339 | 349 | } |
| 350 | + sc->remap_count[p] = j; | |
| 340 | 351 | } |
| 341 | 352 | return 0; |
| 342 | 353 | } |
| @@ -36,6 +36,12 @@ RENAME(decode_line)(FFV1Context *f, FFV1SliceContext *sc, · 35 unmodified lines | ||
| 36 | 36 | int run_mode = 0; |
| 37 | 37 | int run_index = sc->run_index; |
| 38 | 38 | |
| 39 | + if (bits == 0) { | |
| 40 | + for (x = 0; x < w; x++) | |
| 41 | + sample[1][x] = 0; | |
| 42 | + return 0; | |
| 43 | + } | |
| 44 | + | |
| 39 | 45 | if (is_input_end(c, gb, ac)) |
| 40 | 46 | return AVERROR_INVALIDDATA; |
| 41 | 47 | |
| @@ -138,10 +144,12 @@ static int RENAME(decode_rgb_frame)(FFV1Context *f, FFV1SliceContext *sc, · 96 unmodified lines | ||
| 138 | 144 | int x, y, p; |
| 139 | 145 | TYPE *sample[4][2]; |
| 140 | 146 | int lbd = f->avctx->bits_per_raw_sample <= 8; |
| 141 | − int bits = f->avctx->bits_per_raw_sample > 0 ? FFMIN(f->avctx->bits_per_raw_sample, 16) : 8; | |
| 142 | − int offset = 1 << bits; | |
| 147 | + int bits[4], offset; | |
| 143 | 148 | int transparency = f->transparency; |
| 144 | 149 | int ac = f->ac; |
| 150 | + unsigned mask[4]; | |
| 151 | + | |
| 152 | + ff_ffv1_compute_bits_per_plane(f, sc, bits, &offset, mask, f->avctx->bits_per_raw_sample); | |
| 145 | 153 | |
| 146 | 154 | if (sc->slice_coding_mode == 1) |
| 147 | 155 | ac = 1; |
| @@ -165,10 +173,10 @@ static int RENAME(decode_rgb_frame)(FFV1Context *f, FFV1SliceContext *sc, · 17 unmodified lines | ||
| 165 | 173 | |
| 166 | 174 | sample[p][1][-1]= sample[p][0][0 ]; |
| 167 | 175 | sample[p][0][ w]= sample[p][0][w-1]; |
| 168 | − if (lbd && sc->slice_coding_mode == 0) | |
| 176 | + if (bits[p] == 9) | |
| 169 | 177 | ret = RENAME(decode_line)(f, sc, gb, w, sample[p], (p + 1)/2, 9, ac); |
| 170 | 178 | else |
| 171 | − ret = RENAME(decode_line)(f, sc, gb, w, sample[p], (p + 1)/2, bits + (sc->slice_coding_mode != 1), ac); | |
| 179 | + ret = RENAME(decode_line)(f, sc, gb, w, sample[p], (p + 1)/2, bits[p], ac); | |
| 172 | 180 | if (ret < 0) |
| 173 | 181 | return ret; |
| 174 | 182 | } |
| @@ -187,17 +195,17 @@ static int RENAME(decode_rgb_frame)(FFV1Context *f, FFV1SliceContext *sc, · 12 unmodified lines | ||
| 187 | 195 | } |
| 188 | 196 | if (sc->remap) { |
| 189 | 197 | if (f->avctx->bits_per_raw_sample == 32) { |
| 190 | − g = sc->fltmap32[0][g & 0xFFFF]; | |
| 191 | − b = sc->fltmap32[1][b & 0xFFFF]; | |
| 192 | − r = sc->fltmap32[2][r & 0xFFFF]; | |
| 198 | + g = sc->fltmap32[0][g & mask[0]]; | |
| 199 | + b = sc->fltmap32[1][b & mask[1]]; | |
| 200 | + r = sc->fltmap32[2][r & mask[2]]; | |
| 193 | 201 | if (transparency) |
| 194 | − a = sc->fltmap32[3][a & 0xFFFF]; | |
| 202 | + a = sc->fltmap32[3][a & mask[3]]; | |
| 195 | 203 | } else { |
| 196 | − g = sc->fltmap[0][g & 0xFFFF]; | |
| 197 | − b = sc->fltmap[1][b & 0xFFFF]; | |
| 198 | − r = sc->fltmap[2][r & 0xFFFF]; | |
| 204 | + g = sc->fltmap[0][g & mask[0]]; | |
| 205 | + b = sc->fltmap[1][b & mask[1]]; | |
| 206 | + r = sc->fltmap[2][r & mask[2]]; | |
| 199 | 207 | if (transparency) |
| 200 | − a = sc->fltmap[3][a & 0xFFFF]; | |
| 208 | + a = sc->fltmap[3][a & mask[3]]; | |
| 201 | 209 | } |
| 202 | 210 | } |
| 203 | 211 | |
| @@ -433,7 +433,7 @@ static void set_micro_version(FFV1Context *f) · 432 unmodified lines | ||
| 433 | 433 | if (f->version == 3) { |
| 434 | 434 | f->micro_version = 4; |
| 435 | 435 | } else if (f->version == 4) { |
| 436 | − f->micro_version = 7; | |
| 436 | + f->micro_version = 8; | |
| 437 | 437 | } else |
| 438 | 438 | av_assert0(0); |
| 439 | 439 | |
| @@ -1216,6 +1216,7 @@ static void encode_histogram_remap(FFV1Context *f, FFV1SliceContext *sc) · 776 unmodified lines | ||
| 1216 | 1216 | } |
| 1217 | 1217 | if (run) |
| 1218 | 1218 | put_symbol(&sc->c, state[lu], run, 0); |
| 1219 | + sc->remap_count[p] = j; | |
| 1219 | 1220 | } |
| 1220 | 1221 | } |
| 1221 | 1222 | |
| @@ -1370,7 +1371,8 @@ static int encode_float32_remap_segment(FFV1SliceContext *sc, · 148 unmodified lines | ||
| 1370 | 1371 | mul[ current_mul_index ] *= -1; |
| 1371 | 1372 | put_symbol_inline(&rc, state[0][2], mul[ current_mul_index ], 0, NULL, NULL); |
| 1372 | 1373 | } |
| 1373 | − compact_index ++; | |
| 1374 | + if (i < pixel_num) | |
| 1375 | + compact_index ++; | |
| 1374 | 1376 | } |
| 1375 | 1377 | } |
| 1376 | 1378 | if (!run || run1final) |
| @@ -1380,6 +1382,8 @@ static int encode_float32_remap_segment(FFV1SliceContext *sc, · 3 unmodified lines | ||
| 1380 | 1382 | |
| 1381 | 1383 | if (update) { |
| 1382 | 1384 | sc->c = rc; |
| 1385 | + av_assert0(compact_index <= 65535); | |
| 1386 | + sc->remap_count[p] = compact_index + 1; | |
| 1383 | 1387 | } |
| 1384 | 1388 | return get_rac_count(&rc); |
| 1385 | 1389 | } |
| @@ -1492,10 +1496,11 @@ static int encode_float32_rgb_frame(FFV1Context *f, FFV1SliceContext *sc, · 106 unmodified lines | ||
| 1492 | 1496 | const int ring_size = f->context_model ? 3 : 2; |
| 1493 | 1497 | int32_t *sample[4][3]; |
| 1494 | 1498 | const int pass1 = !!(f->avctx->flags & AV_CODEC_FLAG_PASS1); |
| 1495 | − int bits = 16; //TODO explain this in the specifciation, we have 32bits in but really encode max 16 | |
| 1496 | − int offset = 1 << bits; | |
| 1499 | + int bits[4], offset; | |
| 1497 | 1500 | int transparency = f->transparency; |
| 1498 | 1501 | |
| 1502 | + ff_ffv1_compute_bits_per_plane(f, sc, bits, &offset, NULL, f->bits_per_raw_sample); | |
| 1503 | + | |
| 1499 | 1504 | sc->run_index = 0; |
| 1500 | 1505 | |
| 1501 | 1506 | memset(RENAME(sc->sample_buffer), 0, ring_size * MAX_PLANES * |
| @@ -1532,7 +1537,7 @@ static int encode_float32_rgb_frame(FFV1Context *f, FFV1SliceContext *sc, · 30 unmodified lines | ||
| 1532 | 1537 | sample[p][0][-1] = sample[p][1][0 ]; |
| 1533 | 1538 | sample[p][1][ w] = sample[p][1][w-1]; |
| 1534 | 1539 | ret = encode_line32(f, sc, f->avctx, w, sample[p], (p + 1) / 2, |
| 1535 | − bits + (sc->slice_coding_mode != 1), ac, pass1); | |
| 1540 | + bits[p], ac, pass1); | |
| 1536 | 1541 | if (ret < 0) |
| 1537 | 1542 | return ret; |
| 1538 | 1543 | } |
| @@ -35,6 +35,9 @@ RENAME(encode_line)(FFV1Context *f, FFV1SliceContext *sc, · 34 unmodified lines | ||
| 35 | 35 | int run_count = 0; |
| 36 | 36 | int run_mode = 0; |
| 37 | 37 | |
| 38 | + if (bits == 0) | |
| 39 | + return 0; | |
| 40 | + | |
| 38 | 41 | if (ac != AC_GOLOMB_RICE) { |
| 39 | 42 | if (c->bytestream_end - c->bytestream < w * 35) { |
| 40 | 43 | av_log(logctx, AV_LOG_ERROR, "encoded Range Coder frame too large\n"); |
| @@ -172,11 +175,12 @@ static int RENAME(encode_rgb_frame)(FFV1Context *f, FFV1SliceContext *sc, · 131 unmodified lines | ||
| 172 | 175 | const int pass1 = !!(f->avctx->flags & AV_CODEC_FLAG_PASS1); |
| 173 | 176 | int lbd = f->bits_per_raw_sample <= 8; |
| 174 | 177 | int packed = !src[1]; |
| 175 | − int bits = f->bits_per_raw_sample > 0 ? f->bits_per_raw_sample : 8; | |
| 176 | − int offset = 1 << bits; | |
| 178 | + int bits[4], offset; | |
| 177 | 179 | int transparency = f->transparency; |
| 178 | 180 | int packed_size = (3 + transparency)*2; |
| 179 | 181 | |
| 182 | + ff_ffv1_compute_bits_per_plane(f, sc, bits, &offset, NULL, f->bits_per_raw_sample); | |
| 183 | + | |
| 180 | 184 | sc->run_index = 0; |
| 181 | 185 | |
| 182 | 186 | memset(RENAME(sc->sample_buffer), 0, ring_size * MAX_PLANES * |
| @@ -239,11 +243,11 @@ static int RENAME(encode_rgb_frame)(FFV1Context *f, FFV1SliceContext *sc, · 56 unmodified lines | ||
| 239 | 243 | int ret; |
| 240 | 244 | sample[p][0][-1] = sample[p][1][0 ]; |
| 241 | 245 | sample[p][1][ w] = sample[p][1][w-1]; |
| 242 | − if (lbd && sc->slice_coding_mode == 0) | |
| 246 | + if (bits[p] == 9) | |
| 243 | 247 | ret = RENAME(encode_line)(f, sc, f->avctx, w, sample[p], (p + 1) / 2, 9, ac, pass1); |
| 244 | 248 | else |
| 245 | 249 | ret = RENAME(encode_line)(f, sc, f->avctx, w, sample[p], (p + 1) / 2, |
| 246 | − bits + (sc->slice_coding_mode != 1), ac, pass1); | |
| 250 | + bits[p], ac, pass1); | |
| 247 | 251 | if (ret < 0) |
| 248 | 252 | return ret; |
| 249 | 253 | } |