swscale: support sliced input with cascaded scaling contexts

Previously scale_cascaded() assumed the whole source frame arrived in a
single sws_scale() call, and the dispatcher only routed full-frame calls
to it. A partial input slice fell through to ff_swscale() on the parent
dispatcher context, whose scaler state (c->desc) is never initialized in
cascade mode, causing a NULL dereference / crash.

Top-down sliced output is bit-exact with full-frame scaling; bottom-up
matches swscale's pre-existing (non-cascade) slice behaviour for
subsampled intermediate formats.

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
Michael Niedermayer
2026-06-04 20:50:45 +02:00
committed by michaelni
parent 6049b4d7bc
commit 10f2abc41f
+11 -1
View File
@@ -1003,6 +1003,16 @@ static int scale_cascaded(SwsInternal *c,
0, dstH0);
if (ret < 0)
return ret;
/* The first stage assembles the full intermediate image from the input,
* one slice at a time (it is itself a regular slice-capable context). The
* second stage scales that whole intermediate to the output in one step,
* so it can only run once the entire source has been consumed. The first
* stage resets its slice direction to 0 at end of frame; until then the
* intermediate is incomplete and this call produces no output lines. */
if (sws_internal(c->cascaded_context[0])->sliceDir != 0)
return 0;
ret = scale_internal(c->cascaded_context[1],
(const uint8_t * const * )c->cascaded_tmp[0], c->cascaded_tmpStride[0],
0, dstH0, dstSlice, dstStride, dstSliceY, dstSliceH);
@@ -1067,7 +1077,7 @@ static int scale_internal(SwsContext *sws,
return scale_gamma(c, srcSlice, srcStride, srcSliceY, srcSliceH,
dstSlice, dstStride, dstSliceY, dstSliceH);
if (c->cascaded_context[0] && srcSliceY == 0 && srcSliceH == c->cascaded_context[0]->src_h)
if (c->cascaded_context[0])
return scale_cascaded(c, srcSlice, srcStride, srcSliceY, srcSliceH,
dstSlice, dstStride, dstSliceY, dstSliceH);