This reduces stack space requirements my 1.5 mb and should fix fate
Showing the changes to libavcodec (1 of 1 file). Show all
Unified · Split
| @@ -1253,8 +1253,6 @@ static void load_rgb_float32_frame(FFV1Context *f, FFV1SliceContext *sc, · 1252 unmodified lines | ||
| 1253 | 1253 | } |
| 1254 | 1254 | |
| 1255 | 1255 | typedef struct RemapEncoderState { |
| 1256 | − int delta_stack[65536]; //We need to encode the run value before the adjustments, this stores the adjustments until we know the length of the run | |
| 1257 | − int16_t index_stack[65537]; //only needed with multiple segments | |
| 1258 | 1256 | uint8_t state[2][3][32]; |
| 1259 | 1257 | int mul[4096+1]; |
| 1260 | 1258 | RangeCoder rc; |
| @@ -1267,14 +1265,15 @@ typedef struct RemapEncoderState { · 6 unmodified lines | ||
| 1267 | 1265 | int pixel_num; |
| 1268 | 1266 | int p; |
| 1269 | 1267 | int current_mul_index; |
| 1268 | + int run1final; | |
| 1269 | + int64_t run1start_i; | |
| 1270 | + int64_t run1start_last_val; | |
| 1270 | 1271 | } RemapEncoderState; |
| 1271 | 1272 | |
| 1272 | 1273 | static inline void copy_state(RemapEncoderState *dst, const RemapEncoderState *src) |
| 1273 | 1274 | { |
| 1274 | 1275 | dst->rc = src->rc; |
| 1275 | 1276 | memcpy(dst->mul, src->mul, (src->mul_count + 1) * sizeof(src->mul[0])); |
| 1276 | − memcpy(dst->delta_stack, src->delta_stack, src->run * sizeof(src->delta_stack[0])); | |
| 1277 | − memcpy(dst->index_stack, src->index_stack, (src->run + 1) * sizeof(src->index_stack[0])); | |
| 1278 | 1277 | memcpy(dst->state, src->state, sizeof(dst->state)); |
| 1279 | 1278 | dst->lu = src->lu; |
| 1280 | 1279 | dst->run = src->run; |
| @@ -1285,6 +1284,9 @@ static inline void copy_state(RemapEncoderState *dst, const RemapEncoderState *s · 4 unmodified lines | ||
| 1285 | 1284 | dst->pixel_num = src->pixel_num; |
| 1286 | 1285 | dst->p = src->p; |
| 1287 | 1286 | dst->current_mul_index = src->current_mul_index; |
| 1287 | + dst->run1final = src->run1final; | |
| 1288 | + dst->run1start_i = src->run1start_i; | |
| 1289 | + dst->run1start_last_val = src->run1start_last_val; | |
| 1288 | 1290 | } |
| 1289 | 1291 | |
| 1290 | 1292 | static inline void encode_mul(RemapEncoderState *s, int mul_index) |
| @@ -1312,6 +1314,7 @@ static int encode_float32_remap_segment(FFV1SliceContext *sc, · 21 unmodified lines | ||
| 1312 | 1314 | s.lu = 0; |
| 1313 | 1315 | s.run = 0; |
| 1314 | 1316 | s.current_mul_index = -1; |
| 1317 | + s.run1final = 0; | |
| 1315 | 1318 | } |
| 1316 | 1319 | |
| 1317 | 1320 | for (; s.i < s.pixel_num+1; s.i++) { |
| @@ -1338,30 +1341,39 @@ static int encode_float32_remap_segment(FFV1SliceContext *sc, · 20 unmodified lines | ||
| 1338 | 1341 | |
| 1339 | 1342 | av_assert2(step > 0); |
| 1340 | 1343 | if (s.lu) { |
| 1341 | − s.index_stack[s.run] = s.current_mul_index; | |
| 1342 | − av_assert2(s.run < FF_ARRAY_ELEMS(s.delta_stack)); | |
| 1344 | + if (!s.run) { | |
| 1345 | + s.run1start_i = s.i - 1; | |
| 1346 | + s.run1start_last_val = s.last_val; | |
| 1347 | + } | |
| 1343 | 1348 | if (step == 1) { |
| 1344 | − s.delta_stack[s.run] = delta; | |
| 1349 | + if (s.run1final) { | |
| 1350 | + if (current_mul>1) | |
| 1351 | + put_symbol_inline(&s.rc, s.state[s.lu][1], delta, 1, NULL, NULL); | |
| 1352 | + } | |
| 1345 | 1353 | s.run ++; |
| 1346 | 1354 | av_assert2(s.last_val + current_mul + delta == val); |
| 1347 | 1355 | } else { |
| 1348 | − put_symbol_inline(&s.rc, s.state[s.lu][0], s.run, 0, NULL, NULL); | |
| 1349 | − | |
| 1350 | − for(int k=0; k<s.run; k++) { | |
| 1351 | − int stack_mul = s.mul[ s.index_stack[k] ]; | |
| 1352 | − if (stack_mul>1) | |
| 1353 | − put_symbol_inline(&s.rc, s.state[s.lu][1], s.delta_stack[k], 1, NULL, NULL); | |
| 1354 | − encode_mul(&s, s.index_stack[k+1]); | |
| 1356 | + if (s.run1final) { | |
| 1357 | + if (s.run == 0) | |
| 1358 | + s.lu ^= 1; | |
| 1359 | + s.i--; // we did not encode val so we need to backstep | |
| 1360 | + s.last_val += current_mul; | |
| 1361 | + } else { | |
| 1362 | + put_symbol_inline(&s.rc, s.state[s.lu][0], s.run, 0, NULL, NULL); | |
| 1363 | + s.i = s.run1start_i; | |
| 1364 | + s.last_val = s.run1start_last_val; // we could compute this instead of storing | |
| 1365 | + av_assert2(s.last_val >= 0 && s.i > 0); // first state is zero run so we cant have this in a one run and current_mul_index would be -1 | |
| 1366 | + if (s.run) | |
| 1367 | + s.current_mul_index = ((s.last_val + 1) * s.mul_count) >> 32; | |
| 1355 | 1368 | } |
| 1356 | − if (s.run == 0) | |
| 1357 | − s.lu ^= 1; | |
| 1369 | + s.run1final ^= 1; | |
| 1370 | + | |
| 1358 | 1371 | s.run = 0; |
| 1359 | − s.i--; // we did not encode val so we need to backstep | |
| 1360 | − s.last_val += current_mul; | |
| 1361 | 1372 | continue; |
| 1362 | 1373 | } |
| 1363 | 1374 | } else { |
| 1364 | 1375 | av_assert2(s.run == 0); |
| 1376 | + av_assert2(s.run1final == 0); | |
| 1365 | 1377 | put_symbol_inline(&s.rc, s.state[s.lu][0], step - 1, 0, NULL, NULL); |
| 1366 | 1378 | |
| 1367 | 1379 | if (current_mul > 1) |
| @@ -1373,12 +1385,14 @@ static int encode_float32_remap_segment(FFV1SliceContext *sc, · 5 unmodified lines | ||
| 1373 | 1385 | } |
| 1374 | 1386 | s.last_val = val; |
| 1375 | 1387 | s.current_mul_index = ((s.last_val + 1) * s.mul_count) >> 32; |
| 1376 | − if (!s.run) | |
| 1388 | + if (!s.run || s.run1final) { | |
| 1377 | 1389 | encode_mul(&s, s.current_mul_index); |
| 1378 | − s.compact_index ++; | |
| 1390 | + s.compact_index ++; | |
| 1391 | + } | |
| 1379 | 1392 | } |
| 1380 | − if (final && s.i < s.pixel_num) | |
| 1381 | − sc->bitmap[s.p][sc->unit[s.p][s.i].ndx] = s.compact_index; | |
| 1393 | + if (!s.run || s.run1final) | |
| 1394 | + if (final && s.i < s.pixel_num) | |
| 1395 | + sc->bitmap[s.p][sc->unit[s.p][s.i].ndx] = s.compact_index; | |
| 1382 | 1396 | } |
| 1383 | 1397 | |
| 1384 | 1398 | if (update) { |