Commit 53369160a6 for ffmpeg
commit 53369160a699c0f7fe5cd6ee5e6919a6946e4583
Author: Niklas Haas <git@haasn.dev>
Date: Tue Oct 20 22:25:24 2026 +0200
swscale/ops: nuke op->type across the board
In favor of using the derived types from the output pads, or the tagged
types where applicable (e.g. for clear ops).
A few assertions just fall out as a result of no longer having metadata
that could possibly diverge. One unused function was just deleted instead
of adapting it.
Signed-off-by: Niklas Haas <git@haasn.dev>
diff --git a/libswscale/format.c b/libswscale/format.c
index 7e653c5101..4af9c91b35 100644
--- a/libswscale/format.c
+++ b/libswscale/format.c
@@ -1130,48 +1130,41 @@ static int decode_pixfmt(SwsOpList *ops, const SwsFormat *fmt)
/* TODO: handle subsampled or semipacked input formats */
RET(ff_sws_op_list_append(ops, &(SwsOp) {
.op = SWS_OP_READ,
- .type = rw_op.type,
.rw = rw_op,
}));
if (swapped) {
RET(ff_sws_op_list_append(ops, &(SwsOp) {
- .op = SWS_OP_SWAP_BYTES,
- .type = rw_op.type,
+ .op = SWS_OP_SWAP_BYTES,
}));
}
if (unpack.pattern[0]) {
RET(ff_sws_op_list_append(ops, &(SwsOp) {
.op = SWS_OP_UNPACK,
- .type = rw_op.type,
.pack = unpack,
}));
RET(ff_sws_op_list_append(ops, &(SwsOp) {
.op = SWS_OP_CONVERT,
- .type = rw_op.type,
.convert.to = pixel_type,
}));
}
RET(ff_sws_op_list_append(ops, &(SwsOp) {
.op = SWS_OP_SWIZZLE,
- .type = pixel_type,
.swizzle = swizzle,
}));
if (shift.amount) {
RET(ff_sws_op_list_append(ops, &(SwsOp) {
.op = SWS_OP_RSHIFT,
- .type = pixel_type,
.shift = shift,
}));
}
RET(ff_sws_op_list_append(ops, &(SwsOp) {
.op = SWS_OP_CLEAR,
- .type = pixel_type,
.clear = fmt_clear(fmt),
}));
@@ -1195,7 +1188,6 @@ static int encode_pixfmt(SwsOpList *ops, const SwsFormat *fmt)
if (shift.amount) {
RET(ff_sws_op_list_append(ops, &(SwsOp) {
.op = SWS_OP_LSHIFT,
- .type = pixel_type,
.shift = shift,
}));
}
@@ -1205,7 +1197,6 @@ static int encode_pixfmt(SwsOpList *ops, const SwsFormat *fmt)
av_assert1(!(desc->flags & AV_PIX_FMT_FLAG_ALPHA));
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),
@@ -1214,20 +1205,17 @@ static int encode_pixfmt(SwsOpList *ops, const SwsFormat *fmt)
RET(ff_sws_op_list_append(ops, &(SwsOp) {
.op = SWS_OP_SWIZZLE,
- .type = pixel_type,
.swizzle = swizzle,
}));
if (pack.pattern[0]) {
RET(ff_sws_op_list_append(ops, &(SwsOp) {
.op = SWS_OP_CONVERT,
- .type = pixel_type,
.convert.to = rw_op.type,
}));
RET(ff_sws_op_list_append(ops, &(SwsOp) {
.op = SWS_OP_PACK,
- .type = rw_op.type,
.pack = pack,
}));
}
@@ -1235,14 +1223,12 @@ static int encode_pixfmt(SwsOpList *ops, const SwsFormat *fmt)
if (ff_sws_pixel_type_size(rw_op.type) > 1 &&
(desc->flags & AV_PIX_FMT_FLAG_BE) != NATIVE_ENDIAN_FLAG) {
RET(ff_sws_op_list_append(ops, &(SwsOp) {
- .op = SWS_OP_SWAP_BYTES,
- .type = rw_op.type,
+ .op = SWS_OP_SWAP_BYTES,
}));
}
RET(ff_sws_op_list_append(ops, &(SwsOp) {
.op = SWS_OP_WRITE,
- .type = rw_op.type,
.rw = rw_op,
}));
@@ -1400,7 +1386,6 @@ static bool trc_is_hdr(enum AVColorTransferCharacteristic trc)
}
static int fmt_dither(SwsContext *ctx, SwsOpList *ops,
- const SwsPixelType type,
const SwsFormat *src, const SwsFormat *dst)
{
SwsDither mode = ctx->dither;
@@ -1423,7 +1408,6 @@ static int fmt_dither(SwsContext *ctx, SwsOpList *ops,
*bias = (AVRational64) {1, 2};
return ff_sws_op_list_append(ops, &(SwsOp) {
.op = SWS_OP_DITHER,
- .type = type,
.dither.matrix = bias,
.dither.min = *bias,
.dither.max = *bias,
@@ -1477,7 +1461,6 @@ static int fmt_dither(SwsContext *ctx, SwsOpList *ops,
return ff_sws_op_list_append(ops, &(SwsOp) {
.op = SWS_OP_DITHER,
- .type = type,
.dither = dither,
});
case SWS_DITHER_ED:
@@ -1524,13 +1507,11 @@ static int decode_colors(SwsContext *ctx, SwsPixelType type, SwsOpList *ops,
RET(ff_sws_op_list_append(ops, &(SwsOp) {
.op = SWS_OP_CONVERT,
- .type = pixel_type,
.convert.to = type,
}));
/* Decode pixel format into standardized range */
RET(ff_sws_op_list_append(ops, &(SwsOp) {
- .type = type,
.op = SWS_OP_LINEAR,
.lin = fmt_decode_range(fmt, type, incomplete),
}));
@@ -1560,7 +1541,6 @@ static int decode_colors(SwsContext *ctx, SwsPixelType type, SwsOpList *ops,
AVRational m12 = av_mul_q(crg, m02);
return ff_sws_op_list_append(ops, &(SwsOp) {
- .type = type,
.op = SWS_OP_LINEAR,
.lin = linear_mat3(type,
q1, q0, m02,
@@ -1572,7 +1552,6 @@ static int decode_colors(SwsContext *ctx, SwsPixelType type, SwsOpList *ops,
case AVCOL_SPC_YCGCO:
return ff_sws_op_list_append(ops, &(SwsOp) {
- .type = type,
.op = SWS_OP_LINEAR,
.lin = linear_mat3(type,
q1, av_make_q(-1, 1), av_make_q( 1, 1),
@@ -1635,7 +1614,6 @@ static int encode_colors(SwsContext *ctx, SwsPixelType type, SwsOpList *ops,
AVRational m22 = av_mul_q(m20, av_div_q(c->cb, cr1));
RET(ff_sws_op_list_append(ops, &(SwsOp) {
- .type = type,
.op = SWS_OP_LINEAR,
.lin = linear_mat3(type,
c->cr, c->cg, c->cb,
@@ -1648,7 +1626,6 @@ static int encode_colors(SwsContext *ctx, SwsPixelType type, SwsOpList *ops,
case AVCOL_SPC_YCGCO:
RET(ff_sws_op_list_append(ops, &(SwsOp) {
- .type = type,
.op = SWS_OP_LINEAR,
.lin = linear_mat3(type,
av_make_q( 1, 4), av_make_q(1, 2), av_make_q( 1, 4),
@@ -1674,7 +1651,6 @@ static int encode_colors(SwsContext *ctx, SwsPixelType type, SwsOpList *ops,
}
RET(ff_sws_op_list_append(ops, &(SwsOp) {
- .type = type,
.op = SWS_OP_LINEAR,
.lin = fmt_encode_range(dst, type, incomplete),
}));
@@ -1689,22 +1665,19 @@ static int encode_colors(SwsContext *ctx, SwsPixelType type, SwsOpList *ops,
range.limit[idx] = intmax_q64(dst->desc->comp[i].depth);
}
- RET(fmt_dither(ctx, ops, type, src, dst));
+ RET(fmt_dither(ctx, ops, src, dst));
RET(ff_sws_op_list_append(ops, &(SwsOp) {
.op = SWS_OP_MAX,
- .type = type,
.clamp = {{ Q(0), Q(0), Q(0), Q(0) }},
}));
RET(ff_sws_op_list_append(ops, &(SwsOp) {
.op = SWS_OP_MIN,
- .type = type,
.clamp = range,
}));
}
return ff_sws_op_list_append(ops, &(SwsOp) {
- .type = type,
.op = SWS_OP_CONVERT,
.convert.to = pixel_type,
});
@@ -1768,7 +1741,6 @@ static int add_filter(SwsContext *ctx, SwsPixelType type, SwsOpList *ops,
}
return ff_sws_op_list_append(ops, &(SwsOp) {
- .type = type,
.op = filter,
.filter.kernel = kernel,
.filter.type = type,
@@ -1798,7 +1770,6 @@ static int apply_lut3d(SwsContext *ctx, SwsPixelType type, SwsOpList *ops,
const AVRational64 domain = Q(INPUT_LUT_SIZE - 1);
RET(ff_sws_op_list_append(ops, &(SwsOp) {
- .type = type,
.op = SWS_OP_LINEAR,
.lin = LINEAR_OP_DATA(type,
{ domain, Q(0), Q(0), Q(0), Q(0) },
@@ -1810,20 +1781,17 @@ static int apply_lut3d(SwsContext *ctx, SwsPixelType type, SwsOpList *ops,
RET(ff_sws_op_list_append(ops, &(SwsOp) {
.op = SWS_OP_MAX,
- .type = type,
.clamp = {{ Q(0), Q(0), Q(0) }},
}));
RET(ff_sws_op_list_append(ops, &(SwsOp) {
.op = SWS_OP_MIN,
- .type = type,
.clamp = {{ domain, domain, domain }},
}));
/* Apply the 3DLUT itself */
RET(ff_sws_op_list_append(ops, &(SwsOp) {
.op = SWS_OP_LUT_3D,
- .type = type,
.lut3d.lut = av_refstruct_ref_c(lut3d),
.lut3d.dynamic = lut3d->dynamic,
}));
@@ -1831,7 +1799,6 @@ static int apply_lut3d(SwsContext *ctx, SwsPixelType type, SwsOpList *ops,
/* Normalize back to [0, 1] */
const AVRational64 inv = ff_inv_q64(Q(UINT16_MAX));
RET(ff_sws_op_list_append(ops, &(SwsOp) {
- .type = type,
.op = SWS_OP_LINEAR,
.lin = LINEAR_OP_DATA(type,
{ inv, Q(0), Q(0), Q(0), Q(0) },
diff --git a/libswscale/ops.c b/libswscale/ops.c
index 85fd0b074e..4442ae7c81 100644
--- a/libswscale/ops.c
+++ b/libswscale/ops.c
@@ -209,7 +209,6 @@ void ff_sws_apply_op_q(const SwsOp *op, AVRational64 x[4])
case SWS_OP_WRITE:
return;
case SWS_OP_UNPACK: {
- av_assert1(ff_sws_pixel_type_is_int(op->type));
ff_sws_pack_op_decode(op, mask, shift);
unsigned val = x[0].num;
for (int i = 0; i < 4; i++)
@@ -217,7 +216,6 @@ void ff_sws_apply_op_q(const SwsOp *op, AVRational64 x[4])
return;
}
case SWS_OP_PACK: {
- av_assert1(ff_sws_pixel_type_is_int(op->type));
ff_sws_pack_op_decode(op, mask, shift);
unsigned val = 0;
for (int i = 0; i < 4; i++)
@@ -226,7 +224,7 @@ void ff_sws_apply_op_q(const SwsOp *op, AVRational64 x[4])
return;
}
case SWS_OP_SWAP_BYTES:
- switch (op->type) {
+ switch (ff_sws_op_input_type(op)) {
case SWS_PIXEL_U16:
for (int i = 0; i < 4; i++) {
av_assert2(x[i].num >= 0 && x[i].num <= UINT16_MAX);
@@ -249,14 +247,12 @@ void ff_sws_apply_op_q(const SwsOp *op, AVRational64 x[4])
}
return;
case SWS_OP_LSHIFT: {
- av_assert1(ff_sws_pixel_type_is_int(op->type));
AVRational64 mult = Q(1 << op->shift.amount);
for (int i = 0; i < 4; i++)
x[i] = x[i].den ? ff_mul_q64(x[i], mult) : x[i];
return;
}
case SWS_OP_RSHIFT: {
- av_assert1(ff_sws_pixel_type_is_int(op->type));
for (int i = 0; i < 4; i++)
x[i] = x[i].den ? Q((x[i].num / x[i].den) >> op->shift.amount) : x[i];
return;
@@ -274,7 +270,6 @@ void ff_sws_apply_op_q(const SwsOp *op, AVRational64 x[4])
}
return;
case SWS_OP_DITHER:
- av_assert1(!ff_sws_pixel_type_is_int(op->type));
for (int i = 0; i < 4; i++) {
if (op->dither.y_offset[i] >= 0 && x[i].den)
x[i] = ff_add_q64(x[i], ff_make_q64(1, 2));
@@ -870,17 +865,6 @@ bool ff_sws_op_list_is_noop(const SwsOpList *ops)
return true;
}
-int ff_sws_op_list_max_size(const SwsOpList *ops)
-{
- int max_size = 0;
- for (int i = 0; i < ops->num_ops; i++) {
- const int size = ff_sws_pixel_type_size(ops->ops[i].type);
- max_size = FFMAX(max_size, size);
- }
-
- return max_size;
-}
-
uint32_t ff_sws_linear_mask(const SwsLinearOp *c)
{
uint32_t mask = 0;
@@ -966,7 +950,6 @@ void ff_sws_op_desc(AVBPrint *bp, const SwsOp *op)
break;
case SWS_OP_READ:
case SWS_OP_WRITE:
- av_assert0(op->rw.type == op->type);
av_bprintf(bp, "%-20s: %dx %s %s >> %d", name,
op->rw.elems, ff_sws_pixel_type_name(op->rw.type),
rw_mode_names[op->rw.mode], op->rw.frac);
@@ -999,7 +982,7 @@ void ff_sws_op_desc(AVBPrint *bp, const SwsOp *op)
break;
case SWS_OP_CONVERT:
av_bprintf(bp, "%-20s: %s -> %s", name,
- ff_sws_pixel_type_name(op->type),
+ ff_sws_pixel_type_name(ff_sws_op_input_type(op)),
ff_sws_pixel_type_name(op->convert.to));
break;
case SWS_OP_DITHER:
diff --git a/libswscale/ops.h b/libswscale/ops.h
index 8dcabb2ead..613ff5e538 100644
--- a/libswscale/ops.h
+++ b/libswscale/ops.h
@@ -251,8 +251,7 @@ typedef struct SwsOp SwsOp;
typedef struct SwsOpList SwsOpList;
struct SwsOp {
- SwsOpType op; /* operation to perform */
- SwsPixelType type; /* pixel type to operate on */
+ SwsOpType op;
union {
SwsLinearOp lin;
SwsReadWriteOp rw;
@@ -373,11 +372,6 @@ const SwsOp *ff_sws_op_list_output(const SwsOpList *ops);
*/
bool ff_sws_op_list_is_noop(const SwsOpList *ops);
-/**
- * Returns the size of the largest pixel type used in `ops`.
- */
-int ff_sws_op_list_max_size(const SwsOpList *ops);
-
/**
* These will take over ownership of `op` and set it to {0}, even on failure.
*/
diff --git a/libswscale/ops_optimizer.c b/libswscale/ops_optimizer.c
index 4726ca9bf2..7d6b6de770 100644
--- a/libswscale/ops_optimizer.c
+++ b/libswscale/ops_optimizer.c
@@ -45,7 +45,6 @@ static bool op_commute_clear(SwsOp *op, SwsOp *next)
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:
case SWS_OP_RSHIFT:
@@ -60,7 +59,6 @@ static bool op_commute_clear(SwsOp *op, SwsOp *next)
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: {
const SwsClearOp orig = op->clear;
@@ -71,7 +69,7 @@ static bool op_commute_clear(SwsOp *op, SwsOp *next)
return true;
}
case SWS_OP_SWAP_BYTES:
- switch (next->type) {
+ switch (ff_sws_op_input_type(next)) {
case SWS_PIXEL_U16:
case SWS_PIXEL_U32:
ff_sws_apply_op_q(next, op->clear.value); /* always representable */
@@ -108,16 +106,12 @@ static bool op_commute_swizzle(SwsOp *op, SwsOp *next)
av_assert1(op->op == SWS_OP_SWIZZLE);
switch (next->op) {
case SWS_OP_CONVERT:
- op->type = next->convert.to;
- av_fallthrough;
case SWS_OP_SWAP_BYTES:
case SWS_OP_LSHIFT:
case SWS_OP_RSHIFT:
case SWS_OP_SCALE:
- return true;
case SWS_OP_FILTER_H:
case SWS_OP_FILTER_V:
- op->type = next->filter.type;
return true;
/**
@@ -191,12 +185,10 @@ static bool op_commute_filter(SwsOp *op, SwsOp *prev)
case SWS_OP_SWIZZLE:
case SWS_OP_SCALE:
case SWS_OP_DITHER:
- prev->type = op->filter.type;
return true;
case SWS_OP_LINEAR:
for (int i = 0; i < 4; i++)
prev->lin.type[i] = op->filter.type;
- prev->type = op->filter.type;
return true;
case SWS_OP_CONVERT:
case SWS_OP_INVALID:
@@ -375,11 +367,10 @@ retry:
/* Merge filter with prior conversion */
if (prev->op == SWS_OP_CONVERT) {
- int size_from = ff_sws_pixel_type_size(prev->type);
- int size_to = ff_sws_pixel_type_size(op->type);
- av_assert1(prev->convert.to == op->type);
+ const SwsPixelType input_type = ff_sws_op_input_type(prev);
+ int size_from = ff_sws_pixel_type_size(input_type);
+ int size_to = ff_sws_pixel_type_size(prev->convert.to);
if (size_from < size_to) {
- op->type = prev->type;
ff_sws_op_list_remove_at(ops, n - 1, 1);
goto retry;
}
@@ -427,7 +418,6 @@ retry:
op->rw.elems = nb_planes;
RET(ff_sws_op_list_insert_at(ops, n + 1, &(SwsOp) {
.op = SWS_OP_SWIZZLE,
- .type = op->rw.filter.op ? op->rw.filter.type : op->type,
.swizzle = swiz,
}));
goto retry;
@@ -445,7 +435,7 @@ retry:
case SWS_OP_UNPACK:
/* Redundant unpack+pack */
- if (next->op == SWS_OP_PACK && next->type == op->type &&
+ if (next->op == SWS_OP_PACK &&
next->pack.pattern[0] == op->pack.pattern[0] &&
next->pack.pattern[1] == op->pack.pattern[1] &&
next->pack.pattern[2] == op->pack.pattern[2] &&
@@ -585,14 +575,13 @@ retry:
case SWS_OP_CONVERT:
/* No-op conversion */
- if (op->type == op->convert.to) {
+ if (op->convert.to == ff_sws_op_input_type(op)) {
ff_sws_op_list_remove_at(ops, n, 1);
goto retry;
}
/* Transitive conversion */
if (next->op == SWS_OP_CONVERT) {
- av_assert1(op->convert.to == next->type);
op->convert.to = next->convert.to;
ff_sws_op_list_remove_at(ops, n + 1, 1);
goto retry;
@@ -704,7 +693,6 @@ retry:
if (extract_constant_rows(&op->lin, prev->outputs, &clear)) {
RET(ff_sws_op_list_insert_at(ops, n + 1, &(SwsOp) {
.op = SWS_OP_CLEAR,
- .type = op->type,
.clear = clear,
}));
goto retry;
@@ -721,7 +709,6 @@ retry:
if (extract_swizzle(&op->lin, prev->outputs, &swizzle)) {
RET(ff_sws_op_list_insert_at(ops, n, &(SwsOp) {
.op = SWS_OP_SWIZZLE,
- .type = op->type,
.swizzle = swizzle,
}));
goto retry;
@@ -746,7 +733,7 @@ retry:
}
/* Scaling by exact power of two */
- if (factor2 && ff_sws_pixel_type_is_int(op->type)) {
+ if (factor2 && ff_sws_pixel_type_is_int(ff_sws_op_input_type(op))) {
op->op = factor2 > 0 ? SWS_OP_LSHIFT : SWS_OP_RSHIFT;
op->shift.amount = FFABS(factor2);
goto retry;
@@ -815,7 +802,6 @@ retry:
ff_sws_pixel_type_is_int(next->convert.to) &&
op_result_is_exact(op))
{
- op->type = next->convert.to;
FFSWAP(SwsOp, *op, *next);
goto retry;
}
@@ -829,7 +815,6 @@ retry:
{
for (int i = 0; i < 4; i++)
op->lin.type[i] = next->convert.to;
- op->type = next->convert.to;
FFSWAP(SwsOp, *op, *next);
goto retry;
}
@@ -859,7 +844,6 @@ static int select_planes(SwsOpList *ops, SwsCompMask planes)
/* Insert swizzle to select desired planes */
int ret = ff_sws_op_list_insert_at(ops, ops->num_ops - 1, &(SwsOp) {
.op = SWS_OP_SWIZZLE,
- .type = write->type,
.swizzle = swiz,
});
if (ret < 0)
@@ -1215,7 +1199,7 @@ int ff_sws_op_list_split_at(SwsOpList *ops1, SwsOpList **out_ops2, int index)
}
/* Determine metadata for the intermediate format */
- const SwsPixelType type = op->type;
+ const SwsPixelType type = ff_sws_op_input_type(op);
ops2->src.format = get_planar_fmt(type, nb_planes);
ops2->src.desc = av_pix_fmt_desc_get(ops2->src.format);
get_input_size(ops1, &ops2->src);
@@ -1236,7 +1220,6 @@ int ff_sws_op_list_split_at(SwsOpList *ops1, SwsOpList **out_ops2, int index)
if (swiz_wr.mask != SWS_SWIZZLE(0, 1, 2, 3).mask) {
ret = ff_sws_op_list_append(ops1, &(SwsOp) {
.op = SWS_OP_SWIZZLE,
- .type = type,
.swizzle = swiz_wr,
});
if (ret < 0)
@@ -1245,7 +1228,6 @@ int ff_sws_op_list_split_at(SwsOpList *ops1, SwsOpList **out_ops2, int index)
ret = ff_sws_op_list_append(ops1, &(SwsOp) {
.op = SWS_OP_WRITE,
- .type = type,
.rw.type = type,
.rw.elems = nb_planes,
});
@@ -1254,7 +1236,6 @@ int ff_sws_op_list_split_at(SwsOpList *ops1, SwsOpList **out_ops2, int index)
ret = ff_sws_op_list_insert_at(ops2, 0, &(SwsOp) {
.op = SWS_OP_READ,
- .type = type,
.rw.type = type,
.rw.elems = nb_planes,
});
@@ -1264,7 +1245,6 @@ int ff_sws_op_list_split_at(SwsOpList *ops1, SwsOpList **out_ops2, int index)
if (swiz_rd.mask != SWS_SWIZZLE(0, 1, 2, 3).mask) {
ret = ff_sws_op_list_insert_at(ops2, 1, &(SwsOp) {
.op = SWS_OP_SWIZZLE,
- .type = type,
.swizzle = swiz_rd,
});
if (ret < 0)
diff --git a/libswscale/uops.c b/libswscale/uops.c
index 8d6ad36692..6f8b276d33 100644
--- a/libswscale/uops.c
+++ b/libswscale/uops.c
@@ -47,8 +47,6 @@ static const struct {
#undef UOP_NAME
};
-#define Q2PIXEL(val) ff_sws_pixel_from_q64(op->type, val)
-
void ff_sws_uop_name(const SwsUOp *op, char buf[SWS_UOP_NAME_MAX])
{
AVBPrint bp;
@@ -228,16 +226,16 @@ static bool exact_product_f32(float a, float b)
return !b || result == a;
}
-static bool exact_prod(SwsPixelType type, SwsPixel coef, const SwsOpPad *input)
+static bool exact_prod(SwsPixel coef, const SwsOpPad *input)
{
- if (ff_sws_pixel_type_is_int(type))
+ if (ff_sws_pixel_type_is_int(input->type))
return true;
else if (!input->min.den || !input->max.den)
return false; /* unknown bounds */
- const SwsPixel min = ff_sws_pixel_from_q64(type, input->min);
- const SwsPixel max = ff_sws_pixel_from_q64(type, input->max);
- switch (type) {
+ const SwsPixel min = ff_sws_pixel_from_q64(input->type, input->min);
+ const SwsPixel max = ff_sws_pixel_from_q64(input->type, input->max);
+ switch (input->type) {
case SWS_PIXEL_F32:
return exact_product_f32(coef.f32, min.f32) &&
exact_product_f32(coef.f32, max.f32);
@@ -253,10 +251,10 @@ static bool check_filter_fma(SwsContext *ctx, SwsUOpFlags flags, const SwsOp *op
return false;
if (!(ctx->flags & SWS_BITEXACT))
return true;
- if (!ff_sws_pixel_type_is_int(op->type))
+ if (!ff_sws_pixel_type_is_int(op->rw.type))
return false;
- const int bits = ff_sws_pixel_type_size(op->type) * 8;
+ const int bits = ff_sws_pixel_type_size(op->rw.type) * 8;
const uint64_t max_val = UINT64_MAX >> (64 - bits);
/* Maximum value representable losslessly as float. Note that this is
@@ -269,14 +267,14 @@ static int translate_rw_op(SwsContext *ctx, SwsUOpList *ops, SwsUOpFlags flags,
const SwsOp *op)
{
SwsUOp uop = {
- .type = op->type,
+ .type = op->rw.type,
.mask = SWS_COMP_MASK(op->rw.elems > 0, op->rw.elems > 1,
op->rw.elems > 2, op->rw.elems > 3),
};
/* Non-filtered reads don't care about the exact pixel contents */
if (!op->rw.filter.op)
- uop.type = pixel_type_to_int(op->type);
+ uop.type = pixel_type_to_int(op->rw.type);
const bool is_read = op->op == SWS_OP_READ;
if (op->rw.filter.op) {
@@ -333,7 +331,7 @@ static int translate_swizzle(SwsUOpList *ops, const SwsOp *op)
{
SwsUOp uop = {
.uop = SWS_UOP_PERMUTE,
- .type = pixel_type_to_int(op->type),
+ .type = pixel_type_to_int(ff_sws_op_input_type(op)),
.mask = ff_sws_comp_mask_needed(op),
};
SwsMoveUOp *par = &uop.par.move;
@@ -426,14 +424,14 @@ static int translate_swizzle(SwsUOpList *ops, const SwsOp *op)
static int translate_dither_op(SwsUOpList *ops, SwsUOpFlags flags, const SwsOp *op)
{
SwsUOp uop = {
- .type = op->type,
+ .type = ff_sws_op_input_type(op),
.uop = SWS_UOP_DITHER,
.par.dither.size_log2 = op->dither.size_log2,
};
if ((flags & SWS_UOP_FLAG_ADD) && op->dither.size_log2 == 0) {
/* Constant offset */
- const SwsPixel val = Q2PIXEL(op->dither.matrix[0]);
+ const SwsPixel val = ff_sws_pixel_from_q64(uop.type, op->dither.matrix[0]);
uop.uop = SWS_UOP_ADD;
for (int i = 0; i < 4; i++) {
if (!SWS_OP_NEEDED(op, i) || op->dither.y_offset[i] < 0)
@@ -465,7 +463,7 @@ static int translate_dither_op(SwsUOpList *ops, SwsUOpFlags flags, const SwsOp *
return AVERROR(ENOMEM);
for (int i = 0; i < size * size; i++)
- matrix[i] = Q2PIXEL(op->dither.matrix[i]);
+ matrix[i] = ff_sws_pixel_from_q64(uop.type, op->dither.matrix[i]);
memcpy(&matrix[size * size], matrix, (num_rows - size) * stride);
return ff_sws_uop_list_append(ops, &uop);
@@ -476,7 +474,7 @@ static int translate_linear_op(SwsContext *ctx, SwsUOpList *ops,
const SwsOpPad inputs[4])
{
SwsUOp uop = {
- .type = op->type,
+ .type = ff_sws_op_input_type(op),
.uop = SWS_UOP_LINEAR,
};
@@ -493,20 +491,20 @@ static int translate_linear_op(SwsContext *ctx, SwsUOpList *ops,
bool nonzero = (op->lin.m[i][4].num != 0);
for (int j = 0; j < 5; j++) {
const AVRational64 k = op->lin.m[i][j];
- const SwsPixel px = Q2PIXEL(k);
+ const SwsPixel px = ff_sws_pixel_from_q64(uop.type, k);
uop.data.mat4x5[i][j] = px;
if (k.num == 0)
uop.par.lin.zero |= SWS_MASK(i, j);
else if (j < 4 && k.num == k.den)
uop.par.lin.one |= SWS_MASK(i, j);
- else if (j < 4 && nonzero && (!bitexact || exact_prod(uop.type, px, &inputs[j])))
+ else if (j < 4 && nonzero && (!bitexact || exact_prod(px, &inputs[j])))
exact |= SWS_MASK(i, j);
if (k.num != 0)
nonzero = true;
}
}
- if ((flags & SWS_UOP_FLAG_FMA) && !ff_sws_pixel_type_is_int(op->type)) {
+ if ((flags & SWS_UOP_FLAG_FMA) && !ff_sws_pixel_type_is_int(uop.type)) {
/* multiplication by 1 and 0 are always exact by definition */
uop.uop = SWS_UOP_LINEAR_FMA;
uop.par.lin.exact = exact | uop.par.lin.zero | uop.par.lin.one;
@@ -537,8 +535,8 @@ static int translate_op(SwsContext *ctx, SwsUOpList *uops, SwsUOpFlags flags,
/* Default handling for "simple" ops */
SwsUOp uop = {
- .type = op->type,
.uop = SWS_UOP_INVALID,
+ .type = ff_sws_op_input_type(op),
.mask = ff_sws_comp_mask_needed(op),
};
@@ -568,23 +566,24 @@ static int translate_op(SwsContext *ctx, SwsUOpList *uops, SwsUOpFlags flags,
break;
case SWS_OP_CLEAR:
uop.uop = SWS_UOP_CLEAR;
- uop.type = pixel_type_to_int(op->type);
uop.mask &= op->clear.mask;
for (int i = 0; i < 4; i++) {
if (!SWS_COMP_TEST(op->clear.mask, i))
continue;
const AVRational64 v = op->clear.value[i];
- const SwsPixel px = Q2PIXEL(op->clear.value[i]);
+ const SwsPixelType type = op->clear.type[i];
+ const SwsPixel px = ff_sws_pixel_from_q64(type, v);
+ uop.type = pixel_type_to_int(type);
uop.data.vec4[i] = px;
if (v.num == 0)
uop.par.clear.zero |= SWS_COMP(i);
- else if (ff_sws_pixel_is_1s(op->type, px))
+ else if (ff_sws_pixel_is_1s(type, px))
uop.par.clear.one |= SWS_COMP(i);
}
break;
case SWS_OP_SCALE:
uop.uop = SWS_UOP_SCALE;
- uop.data.scalar = Q2PIXEL(op->scale.factor);
+ uop.data.scalar = ff_sws_pixel_from_q64(uop.type, op->scale.factor);
break;
case SWS_OP_MIN:
case SWS_OP_MAX:
@@ -592,12 +591,12 @@ static int translate_op(SwsContext *ctx, SwsUOpList *uops, SwsUOpFlags flags,
uop.mask &= ff_sws_comp_mask_q4(op->clamp.limit);
for (int i = 0; i < 4; i++) {
if (SWS_COMP_TEST(uop.mask, i))
- uop.data.vec4[i] = Q2PIXEL(op->clamp.limit[i]);
+ uop.data.vec4[i] = ff_sws_pixel_from_q64(uop.type, op->clamp.limit[i]);
}
break;
case SWS_OP_SWAP_BYTES:
uop.uop = SWS_UOP_SWAP_BYTES;
- uop.type = pixel_type_to_int(op->type);
+ uop.type = pixel_type_to_int(uop.type);
break;
case SWS_OP_LUT_3D:
uop.uop = SWS_UOP_LUT_3D;
@@ -616,11 +615,15 @@ int ff_sws_ops_translate(SwsContext *ctx, const SwsOpList *ops,
SwsUOpFlags flags, SwsUOpList *uops)
{
const SwsOpPad *inputs = ops->inputs;
- for (int i = 0; i < ops->num_ops; i++) {
- const SwsOp *op = &ops->ops[i];
- const int pixel_size = ff_sws_pixel_type_size(op->type);
- if (pixel_size > uops->pixel_size_max)
- uops->pixel_size_max = pixel_size;
+ for (int n = 0; n < ops->num_ops; n++) {
+ const SwsOp *op = &ops->ops[n];
+ for (int i = 0; i < 4; i++) {
+ if (!SWS_OP_NEEDED(op, i))
+ continue;
+ const int pixel_size = ff_sws_pixel_type_size(op->outputs[i].type);
+ if (pixel_size > uops->pixel_size_max)
+ uops->pixel_size_max = pixel_size;
+ }
int ret = translate_op(ctx, uops, flags, op, inputs);
if (ret < 0)
diff --git a/libswscale/vulkan/ops.c b/libswscale/vulkan/ops.c
index 7754abfe97..910aac11e3 100644
--- a/libswscale/vulkan/ops.c
+++ b/libswscale/vulkan/ops.c
@@ -548,13 +548,14 @@ static void define_shader_consts(SwsContext *sws, const SwsOpList *ops,
for (int n = 0; n < ops->num_ops; n++) {
const SwsOp *op = &ops->ops[n];
OpIDs *oid = &id->op[n];
+ SwsPixelType type_in = ff_sws_op_input_type(op);
switch (op->op) {
case SWS_OP_CLEAR:
for (int i = 0; i < 4; i++) {
if (!SWS_COMP_TEST(op->clear.mask, i))
continue;
AVRational64 cv = op->clear.value[i];
- if (op->type == SWS_PIXEL_F32) {
+ if (op->clear.type[i] == SWS_PIXEL_F32) {
float q = (float)cv.num/cv.den;
oid->comp[i] = spi_OpConstantFloat(spi, f32_type, q);
} else {
@@ -587,7 +588,7 @@ static void define_shader_consts(SwsContext *sws, const SwsOpList *ops,
}
case SWS_OP_SCALE: {
int tmp;
- if (op->type == SWS_PIXEL_F32) {
+ if (type_in == SWS_PIXEL_F32) {
float q = op->scale.factor.num/(float)op->scale.factor.den;
tmp = spi_OpConstantFloat(spi, f32_type, q);
tmp = spi_OpConstantComposite(spi, id->f32vec4_type,
@@ -608,7 +609,7 @@ static void define_shader_consts(SwsContext *sws, const SwsOpList *ops,
AVRational64 cl = op->clamp.limit[i];
if (!op->clamp.limit[i].den) {
continue;
- } else if (op->type == SWS_PIXEL_F32) {
+ } else if (type_in == SWS_PIXEL_F32) {
float q = (float)cl.num/((float)cl.den);
tmp = spi_OpConstantFloat(spi, f32_type, q);
} else {
@@ -781,8 +782,9 @@ static int insert_vmat_linear(SPICtx *spi, SPIRVIDs *id, const LinearIDs *lin,
static int insert_bitexact_linear(const SwsOp *op, SPICtx *spi, SPIRVIDs *id,
const LinearIDs *lin, int data)
{
- int type_s = op->type == SWS_PIXEL_F32 ? id->f32_type : id->u32_type;
- int type_v = op->type == SWS_PIXEL_F32 ? id->f32vec4_type : id->u32vec4_type;
+ const SwsPixelType op_type = ff_sws_op_input_type(op);
+ int type_s = op_type == SWS_PIXEL_F32 ? id->f32_type : id->u32_type;
+ int type_v = op_type == SWS_PIXEL_F32 ? id->f32vec4_type : id->u32vec4_type;
int tmp[4];
tmp[0] = spi_OpCompositeExtract(spi, type_s, data, 0);
@@ -799,7 +801,7 @@ static int insert_bitexact_linear(const SwsOp *op, SPICtx *spi, SPIRVIDs *id,
int res[4];
for (int j = 0; j < 4; j++) {
- res[j] = op->type == SWS_PIXEL_F32 ? id->f32_0 : id->u32_cid[0];
+ res[j] = op_type == SWS_PIXEL_F32 ? id->f32_0 : id->u32_cid[0];
if (op->lin.m[j][0].num)
res[j] = spi_OpFMul(spi, type_s, tmp[0], lin->m[j][0]);
@@ -1144,7 +1146,7 @@ static int add_ops_spirv(SwsContext *sws, VulkanPriv *p, FFVulkanOpsCtx *s,
/* Initialize main data state */
int data;
- if (ops->ops[0].type == SWS_PIXEL_F32)
+ if (ff_sws_op_output_type(&ops->ops[0]) == SWS_PIXEL_F32)
data = spi_OpCompositeConstruct(spi, id->f32vec4_type,
id->f32_0, id->f32_0,
id->f32_0, id->f32_0);
@@ -1157,13 +1159,15 @@ static int add_ops_spirv(SwsContext *sws, VulkanPriv *p, FFVulkanOpsCtx *s,
for (int n = 0; n < ops->num_ops; n++) {
const SwsOp *op = &ops->ops[n];
const OpIDs *oid = &id->op[n];
- SwsPixelType cur_type = op->op == SWS_OP_CONVERT ?
- op->convert.to : op->type;
- int type_v = cur_type == SWS_PIXEL_F32 ?
+ SwsPixelType type_in = ff_sws_op_input_type(op);
+ SwsPixelType type_out = ff_sws_op_output_type(op);
+ if (op->op == SWS_OP_WRITE)
+ type_out = type_in;
+ int type_v = type_out == SWS_PIXEL_F32 ?
id->f32vec4_type : id->u32vec4_type;
- int type_s = cur_type == SWS_PIXEL_F32 ?
+ int type_s = type_out == SWS_PIXEL_F32 ?
id->f32_type : id->u32_type;
- int uid = cur_type == SWS_PIXEL_F32 ?
+ int uid = type_out == SWS_PIXEL_F32 ?
id->f32_0 : id->u32_p;
switch (op->op) {
@@ -1224,9 +1228,9 @@ static int add_ops_spirv(SwsContext *sws, VulkanPriv *p, FFVulkanOpsCtx *s,
op->swizzle.in[3]);
break;
case SWS_OP_CONVERT:
- if (op->type == SWS_PIXEL_F32 && type_s == id->u32_type)
+ if (type_in == SWS_PIXEL_F32 && type_s == id->u32_type)
data = spi_OpConvertFToU(spi, type_v, data);
- else if (op->type != SWS_PIXEL_F32 && type_s == id->f32_type)
+ else if (type_in != SWS_PIXEL_F32 && type_s == id->f32_type)
data = spi_OpConvertUToF(spi, type_v, data);
break;
case SWS_OP_LSHIFT:
@@ -1236,14 +1240,14 @@ static int add_ops_spirv(SwsContext *sws, VulkanPriv *p, FFVulkanOpsCtx *s,
data = spi_OpShiftRightLogical(spi, type_v, data, oid->vec);
break;
case SWS_OP_SCALE:
- if (op->type == SWS_PIXEL_F32)
+ if (type_in == SWS_PIXEL_F32)
data = spi_OpFMul(spi, type_v, data, oid->vec);
else
data = spi_OpIMul(spi, type_v, data, oid->vec);
break;
case SWS_OP_MIN:
case SWS_OP_MAX: {
- int t = op->type == SWS_PIXEL_F32 ?
+ int t = type_in == SWS_PIXEL_F32 ?
op->op == SWS_OP_MIN ? GLSLstd450FMin : GLSLstd450FMax :
op->op == SWS_OP_MIN ? GLSLstd450UMin : GLSLstd450UMax;
for (int i = 0; i < 4; i++) {
@@ -1279,7 +1283,7 @@ static int add_ops_spirv(SwsContext *sws, VulkanPriv *p, FFVulkanOpsCtx *s,
break;
}
case SWS_OP_LINEAR: {
- if (op->type != SWS_PIXEL_F32)
+ if (type_in != SWS_PIXEL_F32)
return AVERROR(ENOTSUP);
if (sws->flags & SWS_BITEXACT)
data = insert_bitexact_linear(op, spi, id, &oid->lin, data);