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]

Reply via email to