History

avcodec/ffv1enc: reduce stack usage

Fixes failures in some systems since 171060d5dc54d1526abde736a711ce234df632f2. This can be further improved by only allocating the arrays when needed.

James Almer committed 1 year ago

Commit 702239b1 parent fee5b0a2 files · +26 −29Browse files

Unified · Split

2 files
  1. libavcodec/ffv1.h +4 −0
  2. libavcodec/ffv1enc.c +22 −29
libavcodec/ffv1.h+4−0
@@ -111,6 +111,10 @@ typedef struct FFV1SliceContext { · 110 unmodified lines
111 uint16_t fltmap [4][65536]; //halffloat encode & decode111 uint16_t fltmap [4][65536]; //halffloat encode & decode
112 uint32_t fltmap32[4][65536]; //float decode112 uint32_t fltmap32[4][65536]; //float decode
113 };113 };
114 struct Unit {
115 uint32_t val; //this is unneeded if you accept a dereference on each access
116 uint16_t ndx;
117 } unit[4][65536];
114} FFV1SliceContext;118} FFV1SliceContext;
115 119
116typedef struct FFV1Context {120typedef struct FFV1Context {
libavcodec/ffv1enc.c+22−29
@@ -1194,15 +1194,9 @@ static void encode_histogram_remap(FFV1Context *f, FFV1SliceContext *sc) · 1193 unmodified lines
1194 }1194 }
1195}1195}
1196 1196
1197typedef struct Unit {
1198 uint32_t val; //this is unneeded if you accept a dereference on each access
1199 uint16_t ndx;
1200} Unit;
1201
1202static void load_rgb_float32_frame(FFV1Context *f, FFV1SliceContext *sc,1197static void load_rgb_float32_frame(FFV1Context *f, FFV1SliceContext *sc,
1203 const uint8_t *src[4],1198 const uint8_t *src[4],
1204 int w, int h, const int stride[4],1199 int w, int h, const int stride[4])
1205 Unit unit[4][65536])
1206{1200{
1207 int x, y;1201 int x, y;
1208 int transparency = f->transparency;1202 int transparency = f->transparency;
@@ -1226,18 +1220,18 @@ static void load_rgb_float32_frame(FFV1Context *f, FFV1SliceContext *sc, · 17 unmodified lines
1226 }1220 }
1227 // We cannot build a histogram as we do for 16bit, we need a bit of magic here1221 // We cannot build a histogram as we do for 16bit, we need a bit of magic here
1228 // Its possible to reduce the memory needed at the cost of more dereferencing1222 // Its possible to reduce the memory needed at the cost of more dereferencing
1229 unit[0][i].val = g;1223 sc->unit[0][i].val = g;
1230 unit[0][i].ndx = x + y*w;1224 sc->unit[0][i].ndx = x + y*w;
1231 1225
1232 unit[1][i].val = b;1226 sc->unit[1][i].val = b;
1233 unit[1][i].ndx = x + y*w;1227 sc->unit[1][i].ndx = x + y*w;
1234 1228
1235 unit[2][i].val = r;1229 sc->unit[2][i].val = r;
1236 unit[2][i].ndx = x + y*w;1230 sc->unit[2][i].ndx = x + y*w;
1237 1231
1238 if (transparency) {1232 if (transparency) {
1239 unit[3][i].val = a;1233 sc->unit[3][i].val = a;
1240 unit[3][i].ndx = x + y*w;1234 sc->unit[3][i].ndx = x + y*w;
1241 }1235 }
1242 i++;1236 i++;
1243 }1237 }
@@ -1245,11 +1239,11 @@ static void load_rgb_float32_frame(FFV1Context *f, FFV1SliceContext *sc, · 1 unmodified line
1245 1239
1246 //TODO switch to radix sort1240 //TODO switch to radix sort
1247#define CMP(A,B) ((A)->val - (int64_t)(B)->val)1241#define CMP(A,B) ((A)->val - (int64_t)(B)->val)
1248 AV_QSORT(unit[0], i, Unit, CMP);1242 AV_QSORT(sc->unit[0], i, struct Unit, CMP);
1249 AV_QSORT(unit[1], i, Unit, CMP);1243 AV_QSORT(sc->unit[1], i, struct Unit, CMP);
1250 AV_QSORT(unit[2], i, Unit, CMP);1244 AV_QSORT(sc->unit[2], i, struct Unit, CMP);
1251 if (transparency)1245 if (transparency)
1252 AV_QSORT(unit[3], i, Unit, CMP);1246 AV_QSORT(sc->unit[3], i, struct Unit, CMP);
1253}1247}
1254 1248
1255typedef struct RemapEncoderState {1249typedef struct RemapEncoderState {
@@ -1296,7 +1290,7 @@ static inline void encode_mul(RemapEncoderState *s, int mul_index) · 40 unmodified lines
1296 }1290 }
1297}1291}
1298 1292
1299static int encode_float32_remap_segment(FFV1SliceContext *sc, Unit unit[4][65536],1293static int encode_float32_remap_segment(FFV1SliceContext *sc,
1300 RemapEncoderState *state_arg, int update, int final)1294 RemapEncoderState *state_arg, int update, int final)
1301{1295{
1302 RemapEncoderState s;1296 RemapEncoderState s;
@@ -1324,7 +1318,7 @@ static int encode_float32_remap_segment(FFV1SliceContext *sc, Unit unit[4][65536 · 21 unmodified lines
1324 val = 1LL<<32;1318 val = 1LL<<32;
1325 }1319 }
1326 } else1320 } else
1327 val = unit[s.p][s.i].val;1321 val = sc->unit[s.p][s.i].val;
1328 1322
1329 if (s.last_val != val) {1323 if (s.last_val != val) {
1330 int64_t delta = 0;1324 int64_t delta = 0;
@@ -1376,7 +1370,7 @@ static int encode_float32_remap_segment(FFV1SliceContext *sc, Unit unit[4][65536 · 45 unmodified lines
1376 1370
1377 av_assert2(s.i == s.pixel_num || s.last_val + (val - s.last_val) * current_mul + delta == unit[s.p][s.i].val);1371 av_assert2(s.i == s.pixel_num || s.last_val + (val - s.last_val) * current_mul + delta == unit[s.p][s.i].val);
1378 if (s.i < s.pixel_num)1372 if (s.i < s.pixel_num)
1379 s.last_val = unit[s.p][s.i].val;1373 s.last_val = sc->unit[s.p][s.i].val;
1380 }1374 }
1381 s.current_mul_index = ((s.last_val + 1) * s.mul_count) >> 32;1375 s.current_mul_index = ((s.last_val + 1) * s.mul_count) >> 32;
1382 if (!s.run)1376 if (!s.run)
@@ -1384,7 +1378,7 @@ static int encode_float32_remap_segment(FFV1SliceContext *sc, Unit unit[4][65536 · 1 unmodified line
1384 s.compact_index ++;1378 s.compact_index ++;
1385 }1379 }
1386 if (final && s.i < s.pixel_num)1380 if (final && s.i < s.pixel_num)
1387 sc->bitmap[s.p][unit[s.p][s.i].ndx] = s.compact_index;1381 sc->bitmap[s.p][sc->unit[s.p][s.i].ndx] = s.compact_index;
1388 }1382 }
1389 1383
1390 if (update) {1384 if (update) {
@@ -1394,7 +1388,7 @@ static int encode_float32_remap_segment(FFV1SliceContext *sc, Unit unit[4][65536 · 3 unmodified lines
1394}1388}
1395 1389
1396static void encode_float32_remap(FFV1Context *f, FFV1SliceContext *sc,1390static void encode_float32_remap(FFV1Context *f, FFV1SliceContext *sc,
1397 const uint8_t *src[4], Unit unit[4][65536])1391 const uint8_t *src[4])
1398{1392{
1399 RemapEncoderState s;1393 RemapEncoderState s;
1400 s.pixel_num = sc->slice_width * sc->slice_height;1394 s.pixel_num = sc->slice_width * sc->slice_height;
@@ -1411,7 +1405,7 @@ static void encode_float32_remap(FFV1Context *f, FFV1SliceContext *sc, · 10 unmodified lines
1411 s.mul_count = 1;1405 s.mul_count = 1;
1412 1406
1413 for (int i= 0; i<s.pixel_num; i++) {1407 for (int i= 0; i<s.pixel_num; i++) {
1414 int64_t val = unit[p][i].val;1408 int64_t val = sc->unit[p][i].val;
1415 if (val != last_val) {1409 if (val != last_val) {
1416 av_assert2(last_val < val);1410 av_assert2(last_val < val);
1417 for(int si= 0; si < FF_ARRAY_ELEMS(score_tab); si++) {1411 for(int si= 0; si < FF_ARRAY_ELEMS(score_tab); si++) {
@@ -1431,7 +1425,7 @@ static void encode_float32_remap(FFV1Context *f, FFV1SliceContext *sc, · 13 unmodified lines
1431 s.mul[0] = -1 << best_index;1425 s.mul[0] = -1 << best_index;
1432 s.mul[s.mul_count] = 1;1426 s.mul[s.mul_count] = 1;
1433 1427
1434 encode_float32_remap_segment(sc, unit, &s, 1, 1);1428 encode_float32_remap_segment(sc, &s, 1, 1);
1435 1429
1436 sc->c = s.rc;1430 sc->c = s.rc;
1437 }1431 }
@@ -1559,9 +1553,8 @@ retry: · 121 unmodified lines
1559 1553
1560 encode_histogram_remap(f, sc);1554 encode_histogram_remap(f, sc);
1561 } else {1555 } else {
1562 Unit pairs[4][65536];1556 load_rgb_float32_frame(f, sc, planes, width, height, p->linesize);
1563 load_rgb_float32_frame(f, sc, planes, width, height, p->linesize, pairs);1557 encode_float32_remap(f, sc, planes);
1564 encode_float32_remap(f, sc, planes, pairs);
1565 }1558 }
1566 }1559 }
1567 1560

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t