PR #23341 opened by michaelni URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23341 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23341.patch
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 <[email protected]> # Summary of changes Briefly describe what this PR does and why. <!-- If this PR requires new FATE test samples, attach them to the PR and list their target paths below (relative to the fate-suite root). Attached filenames must match the sample's filename: ```fate-samples # e.g. vorbis/new-sample.ogg ``` --> >From 1f10ab5e97debaff6e38216c10df3dd941c3dd22 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Thu, 4 Jun 2026 20:50:45 +0200 Subject: [PATCH] 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 <[email protected]> --- libswscale/swscale.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/libswscale/swscale.c b/libswscale/swscale.c index 558e332eb2..c0cdd17b78 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -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); -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
