Commit 6d5392e634 for ffmpeg
commit 6d5392e634f9fb3a15a7a616401a31e6b18acf0a
Author: Niklas Haas <git@haasn.dev>
Date: Sun Sep 27 16:04:41 2026 +0200
swscale/ops: add SwsPixelType to SwsClearOp
Since SwsOp.type will be deprecated. This is an array, to make my life easier
w.r.t. the LINEAR -> CLEAR promotion.
Signed-off-by: Niklas Haas <git@haasn.dev>
diff --git a/libswscale/format.c b/libswscale/format.c
index a8988d00ba..7e653c5101 100644
--- a/libswscale/format.c
+++ b/libswscale/format.c
@@ -1058,16 +1058,22 @@ static SwsClearOp fmt_clear(const SwsFormat *fmt)
const AVPixFmtDescriptor *desc = fmt_desc_decoded(fmt->format);
const bool has_chroma = desc->nb_components >= 3;
const bool has_alpha = desc->flags & AV_PIX_FMT_FLAG_ALPHA;
+ const SwsPixelType type = fmt_pixel_type(desc);
+
+ SwsClearOp c = {
+ .mask = SWS_COMP_NONE,
+ };
- SwsClearOp c = {0};
if (!has_chroma) {
c.mask |= SWS_COMP(1) | SWS_COMP(2);
c.value[1] = c.value[2] = Q(0);
+ c.type[1] = c.type[2] = type;
}
if (!has_alpha) {
c.mask |= SWS_COMP(3);
c.value[3] = Q(0);
+ c.type[3] = type;
}
return c;
@@ -1200,6 +1206,7 @@ static int encode_pixfmt(SwsOpList *ops, const SwsFormat *fmt)
RET(ff_sws_op_list_append(ops, &(SwsOp) {
.op = SWS_OP_CLEAR,
.type = pixel_type,
+ .clear.type[3] = pixel_type,
.clear.mask = SWS_COMP(3),
.clear.value[3] = Q(0),
}));
diff --git a/libswscale/ops.h b/libswscale/ops.h
index ec866f4914..8f5b8bbf9d 100644
--- a/libswscale/ops.h
+++ b/libswscale/ops.h
@@ -146,7 +146,8 @@ typedef struct SwsShiftOp {
} SwsShiftOp;
typedef struct SwsClearOp {
- SwsCompMask mask; /* mask of components to clear */
+ SwsPixelType type[4]; /* type of each value */
+ SwsCompMask mask; /* mask of components to clear */
AVRational64 value[4]; /* value to set */
} SwsClearOp;
diff --git a/libswscale/ops_memcpy.c b/libswscale/ops_memcpy.c
index 5940381ea0..52ba64b0c3 100644
--- a/libswscale/ops_memcpy.c
+++ b/libswscale/ops_memcpy.c
@@ -112,7 +112,7 @@ static int compile(SwsContext *ctx, const SwsOpList *ops, SwsCompiledOp *out)
* can't memset on multi-byte sequences */
uint8_t val = op->clear.value[i].num & 0xFF;
uint32_t ref = val;
- switch (ff_sws_pixel_type_size(op->type)) {
+ switch (ff_sws_pixel_type_size(op->clear.type[i])) {
case 2: ref *= 0x101; break;
case 4: ref *= 0x1010101; break;
}
diff --git a/libswscale/ops_optimizer.c b/libswscale/ops_optimizer.c
index 0d7f2438df..4726ca9bf2 100644
--- a/libswscale/ops_optimizer.c
+++ b/libswscale/ops_optimizer.c
@@ -43,6 +43,8 @@ static bool op_commute_clear(SwsOp *op, SwsOp *next)
av_assert1(op->op == SWS_OP_CLEAR);
switch (next->op) {
case SWS_OP_CONVERT:
+ for (int i = 0; i < 4; i++)
+ op->clear.type[i] = next->convert.to;
op->type = next->convert.to;
av_fallthrough;
case SWS_OP_LSHIFT:
@@ -56,12 +58,18 @@ static bool op_commute_clear(SwsOp *op, SwsOp *next)
return true;
case SWS_OP_FILTER_H:
case SWS_OP_FILTER_V:
+ for (int i = 0; i < 4; i++)
+ op->clear.type[i] = next->filter.type;
op->type = next->filter.type;
return true;
- case SWS_OP_SWIZZLE:
+ case SWS_OP_SWIZZLE: {
+ const SwsClearOp orig = op->clear;
+ for (int i = 0; i < 4; i++)
+ op->clear.type[i] = orig.type[next->swizzle.in[i]];
ff_sws_comp_mask_swizzle(&op->clear.mask, &next->swizzle);
ff_sws_apply_op_q(next, op->clear.value);
return true;
+ }
case SWS_OP_SWAP_BYTES:
switch (next->type) {
case SWS_PIXEL_U16:
@@ -280,6 +288,7 @@ static bool extract_constant_rows(SwsLinearOp *c, const SwsOpPad inputs[4],
if (const_row && (mask & SWS_MASK_ROW(i))) {
clear.mask |= SWS_COMP(i);
clear.value[i] = c->m[i][4];
+ clear.type[i] = c->type[i];
for (int j = 0; j < 5; j++)
c->m[i][j] = Q(i == j);
ret = true;
@@ -490,8 +499,10 @@ retry:
/* Transitive clear */
if (next->op == SWS_OP_CLEAR) {
for (int i = 0; i < 4; i++) {
- if (SWS_COMP_TEST(next->clear.mask, i))
+ if (SWS_COMP_TEST(next->clear.mask, i)) {
op->clear.value[i] = next->clear.value[i];
+ op->clear.type[i] = next->clear.type[i];
+ }
}
op->clear.mask |= next->clear.mask;
ff_sws_op_list_remove_at(ops, n + 1, 1);
@@ -508,7 +519,7 @@ retry:
for (int i = 0; i < 4; i++) {
if (!next->lin.m[i][j].num)
continue;
- av_assert0(next->lin.type[i] == op->type);
+ av_assert0(next->lin.type[i] == op->clear.type[j]);
const AVRational64 kx = ff_mul_q64(next->lin.m[i][j], x);
next->lin.m[i][4] = ff_add_q64(next->lin.m[i][4], kx);
next->lin.m[i][j] = Q(0);