* [FFmpeg-devel] [PR] swscale/ops: PPC / bigendian fixes (PR #22231)
@ 2026-02-20 16:53 Niklas Haas via ffmpeg-devel
0 siblings, 0 replies; only message in thread
From: Niklas Haas via ffmpeg-devel @ 2026-02-20 16:53 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Niklas Haas
PR #22231 opened by Niklas Haas (haasn)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22231
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22231.patch
Discovered by FATE. One of them is what appears to be a compiler bug, but the format.c refactor commit should hopefully fix that one incidentally.
>From e0c7f2024dca894aaadf70f912f4cf2dd4dfe0e4 Mon Sep 17 00:00:00 2001
From: Niklas Haas <git@haasn.dev>
Date: Fri, 20 Feb 2026 16:59:07 +0100
Subject: [PATCH 1/3] swscale/format: don't mark single byte formats as byte
swapped
Fixes a bug where all format lists contained redundant byte swapped
annotations on big-endian platforms, even for single-byte formats.
---
libswscale/format.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/libswscale/format.c b/libswscale/format.c
index e0434a2024..a6dd7c6d72 100644
--- a/libswscale/format.c
+++ b/libswscale/format.c
@@ -906,7 +906,8 @@ int ff_sws_decode_pixfmt(SwsOpList *ops, enum AVPixelFormat fmt)
/* Set baseline pixel content flags */
const int integer = ff_sws_pixel_type_is_int(raw_type);
- const int swapped = (desc->flags & AV_PIX_FMT_FLAG_BE) != NATIVE_ENDIAN_FLAG;
+ const int swapped = ff_sws_pixel_type_size(raw_type) > 1 &&
+ (desc->flags & AV_PIX_FMT_FLAG_BE) != NATIVE_ENDIAN_FLAG;
for (int i = 0; i < rw_op.elems; i++) {
comps->flags[i] = (integer ? SWS_COMP_EXACT : 0) |
(swapped ? SWS_COMP_SWAPPED : 0);
@@ -1027,7 +1028,8 @@ int ff_sws_encode_pixfmt(SwsOpList *ops, enum AVPixelFormat fmt)
}));
}
- if ((desc->flags & AV_PIX_FMT_FLAG_BE) != NATIVE_ENDIAN_FLAG) {
+ if (ff_sws_pixel_type_size(raw_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 = raw_type,
--
2.52.0
>From ebf52161f83db823d148837f8d7e2877afba65ce Mon Sep 17 00:00:00 2001
From: Niklas Haas <git@haasn.dev>
Date: Fri, 20 Feb 2026 17:39:46 +0100
Subject: [PATCH 2/3] swscale/format: pass SwsFormat by ref instead of by value
where possible
The one exception is in adapt_colors(), which mutates these structs on
its own stack anyways.
---
libswscale/format.c | 66 +++++++++++++++++++-------------------
libswscale/format.h | 4 +--
libswscale/graph.c | 66 ++++++++++++++++++++------------------
libswscale/ops.c | 12 +++----
libswscale/ops.h | 4 +--
libswscale/tests/sws_ops.c | 4 +--
6 files changed, 79 insertions(+), 77 deletions(-)
diff --git a/libswscale/format.c b/libswscale/format.c
index a6dd7c6d72..11fef305ff 100644
--- a/libswscale/format.c
+++ b/libswscale/format.c
@@ -1050,7 +1050,7 @@ static inline AVRational av_neg_q(AVRational x)
return (AVRational) { -x.num, x.den };
}
-static SwsLinearOp fmt_encode_range(const SwsFormat fmt, bool *incomplete)
+static SwsLinearOp fmt_encode_range(const SwsFormat *fmt, bool *incomplete)
{
SwsLinearOp c = { .m = {
{ Q1, Q0, Q0, Q0, Q0 },
@@ -1059,22 +1059,22 @@ static SwsLinearOp fmt_encode_range(const SwsFormat fmt, bool *incomplete)
{ Q0, Q0, Q0, Q1, Q0 },
}};
- const int depth0 = fmt.desc->comp[0].depth;
- const int depth1 = fmt.desc->comp[1].depth;
- const int depth2 = fmt.desc->comp[2].depth;
- const int depth3 = fmt.desc->comp[3].depth;
+ const int depth0 = fmt->desc->comp[0].depth;
+ const int depth1 = fmt->desc->comp[1].depth;
+ const int depth2 = fmt->desc->comp[2].depth;
+ const int depth3 = fmt->desc->comp[3].depth;
- if (fmt.desc->flags & AV_PIX_FMT_FLAG_FLOAT)
+ if (fmt->desc->flags & AV_PIX_FMT_FLAG_FLOAT)
return c; /* floats are directly output as-is */
- if (fmt.csp == AVCOL_SPC_RGB || (fmt.desc->flags & AV_PIX_FMT_FLAG_XYZ)) {
+ if (fmt->csp == AVCOL_SPC_RGB || (fmt->desc->flags & AV_PIX_FMT_FLAG_XYZ)) {
c.m[0][0] = Q((1 << depth0) - 1);
c.m[1][1] = Q((1 << depth1) - 1);
c.m[2][2] = Q((1 << depth2) - 1);
- } else if (fmt.range == AVCOL_RANGE_JPEG) {
+ } else if (fmt->range == AVCOL_RANGE_JPEG) {
/* Full range YUV */
c.m[0][0] = Q((1 << depth0) - 1);
- if (fmt.desc->nb_components >= 3) {
+ if (fmt->desc->nb_components >= 3) {
/* This follows the ITU-R convention, which is slightly different
* from the JFIF convention. */
c.m[1][1] = Q((1 << depth1) - 1);
@@ -1084,11 +1084,11 @@ static SwsLinearOp fmt_encode_range(const SwsFormat fmt, bool *incomplete)
}
} else {
/* Limited range YUV */
- if (fmt.range == AVCOL_RANGE_UNSPECIFIED)
+ if (fmt->range == AVCOL_RANGE_UNSPECIFIED)
*incomplete = true;
c.m[0][0] = Q(219 << (depth0 - 8));
c.m[0][4] = Q( 16 << (depth0 - 8));
- if (fmt.desc->nb_components >= 3) {
+ if (fmt->desc->nb_components >= 3) {
c.m[1][1] = Q(224 << (depth1 - 8));
c.m[2][2] = Q(224 << (depth2 - 8));
c.m[1][4] = Q(128 << (depth1 - 8));
@@ -1096,12 +1096,12 @@ static SwsLinearOp fmt_encode_range(const SwsFormat fmt, bool *incomplete)
}
}
- if (fmt.desc->flags & AV_PIX_FMT_FLAG_ALPHA) {
- const bool is_ya = fmt.desc->nb_components == 2;
+ if (fmt->desc->flags & AV_PIX_FMT_FLAG_ALPHA) {
+ const bool is_ya = fmt->desc->nb_components == 2;
c.m[3][3] = Q((1 << (is_ya ? depth1 : depth3)) - 1);
}
- if (fmt.format == AV_PIX_FMT_MONOWHITE) {
+ if (fmt->format == AV_PIX_FMT_MONOWHITE) {
/* This format is inverted, 0 = white, 1 = black */
c.m[0][4] = av_add_q(c.m[0][4], c.m[0][0]);
c.m[0][0] = av_neg_q(c.m[0][0]);
@@ -1111,7 +1111,7 @@ static SwsLinearOp fmt_encode_range(const SwsFormat fmt, bool *incomplete)
return c;
}
-static SwsLinearOp fmt_decode_range(const SwsFormat fmt, bool *incomplete)
+static SwsLinearOp fmt_decode_range(const SwsFormat *fmt, bool *incomplete)
{
SwsLinearOp c = fmt_encode_range(fmt, incomplete);
@@ -1123,7 +1123,7 @@ static SwsLinearOp fmt_decode_range(const SwsFormat fmt, bool *incomplete)
}
/* Explicitly initialize alpha for sanity */
- if (!(fmt.desc->flags & AV_PIX_FMT_FLAG_ALPHA))
+ if (!(fmt->desc->flags & AV_PIX_FMT_FLAG_ALPHA))
c.m[3][4] = Q1;
c.mask = ff_sws_linear_mask(c);
@@ -1189,15 +1189,15 @@ 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)
+ const SwsFormat *src, const SwsFormat *dst)
{
SwsDither mode = ctx->dither;
SwsDitherOp dither;
- const int bpc = dst.desc->comp[0].depth;
+ const int bpc = dst->desc->comp[0].depth;
if (mode == SWS_DITHER_AUTO) {
/* Visual threshold of perception: 12 bits for SDR, 14 bits for HDR */
- const int jnd_bits = trc_is_hdr(dst.color.trc) ? 14 : 12;
+ const int jnd_bits = trc_is_hdr(dst->color.trc) ? 14 : 12;
mode = bpc >= jnd_bits ? SWS_DITHER_NONE : SWS_DITHER_BAYER;
}
@@ -1234,7 +1234,7 @@ static int fmt_dither(SwsContext *ctx, SwsOpList *ops,
for (int i = 0; i < 4; i++)
dither.y_offset[i] = offsets_16x16[i];
- if (src.desc->nb_components < 3 && bpc >= 8) {
+ if (src->desc->nb_components < 3 && bpc >= 8) {
/**
* For high-bit-depth sources without chroma, use same matrix
* offset for all color channels. This prevents introducing color
@@ -1284,13 +1284,13 @@ linear_mat3(const AVRational m00, const AVRational m01, const AVRational m02,
}
int ff_sws_decode_colors(SwsContext *ctx, SwsPixelType type,
- SwsOpList *ops, const SwsFormat fmt, bool *incomplete)
+ SwsOpList *ops, const SwsFormat *fmt, bool *incomplete)
{
- const AVLumaCoefficients *c = av_csp_luma_coeffs_from_avcsp(fmt.csp);
+ const AVLumaCoefficients *c = av_csp_luma_coeffs_from_avcsp(fmt->csp);
RET(ff_sws_op_list_append(ops, &(SwsOp) {
.op = SWS_OP_CONVERT,
- .type = fmt_pixel_type(fmt.format),
+ .type = fmt_pixel_type(fmt->format),
.convert.to = type,
}));
@@ -1302,7 +1302,7 @@ int ff_sws_decode_colors(SwsContext *ctx, SwsPixelType type,
}));
/* Final step, decode colorspace */
- switch (fmt.csp) {
+ switch (fmt->csp) {
case AVCOL_SPC_RGB:
return 0;
case AVCOL_SPC_UNSPECIFIED:
@@ -1366,12 +1366,12 @@ int ff_sws_decode_colors(SwsContext *ctx, SwsPixelType type,
}
int ff_sws_encode_colors(SwsContext *ctx, SwsPixelType type,
- SwsOpList *ops, const SwsFormat src,
- const SwsFormat dst, bool *incomplete)
+ SwsOpList *ops, const SwsFormat *src,
+ const SwsFormat *dst, bool *incomplete)
{
- const AVLumaCoefficients *c = av_csp_luma_coeffs_from_avcsp(dst.csp);
+ const AVLumaCoefficients *c = av_csp_luma_coeffs_from_avcsp(dst->csp);
- switch (dst.csp) {
+ switch (dst->csp) {
case AVCOL_SPC_RGB:
break;
case AVCOL_SPC_UNSPECIFIED:
@@ -1437,14 +1437,14 @@ int ff_sws_encode_colors(SwsContext *ctx, SwsPixelType type,
.lin = fmt_encode_range(dst, incomplete),
}));
- if (!(dst.desc->flags & AV_PIX_FMT_FLAG_FLOAT)) {
+ if (!(dst->desc->flags & AV_PIX_FMT_FLAG_FLOAT)) {
SwsConst range = {0};
- const bool is_ya = dst.desc->nb_components == 2;
- for (int i = 0; i < dst.desc->nb_components; i++) {
+ const bool is_ya = dst->desc->nb_components == 2;
+ for (int i = 0; i < dst->desc->nb_components; i++) {
/* Clamp to legal pixel range */
const int idx = i * (is_ya ? 3 : 1);
- range.q4[idx] = Q((1 << dst.desc->comp[i].depth) - 1);
+ range.q4[idx] = Q((1 << dst->desc->comp[i].depth) - 1);
}
RET(fmt_dither(ctx, ops, type, src, dst));
@@ -1464,7 +1464,7 @@ int ff_sws_encode_colors(SwsContext *ctx, SwsPixelType type,
return ff_sws_op_list_append(ops, &(SwsOp) {
.type = type,
.op = SWS_OP_CONVERT,
- .convert.to = fmt_pixel_type(dst.format),
+ .convert.to = fmt_pixel_type(dst->format),
});
}
diff --git a/libswscale/format.h b/libswscale/format.h
index fbb65d6805..fe37b3a32e 100644
--- a/libswscale/format.h
+++ b/libswscale/format.h
@@ -167,9 +167,9 @@ int ff_sws_encode_pixfmt(SwsOpList *ops, enum AVPixelFormat fmt);
* Returns 0 on success, or a negative error code on failure.
*/
int ff_sws_decode_colors(SwsContext *ctx, SwsPixelType type, SwsOpList *ops,
- const SwsFormat fmt, bool *incomplete);
+ const SwsFormat *fmt, bool *incomplete);
int ff_sws_encode_colors(SwsContext *ctx, SwsPixelType type, SwsOpList *ops,
- const SwsFormat src, const SwsFormat dst,
+ const SwsFormat *src, const SwsFormat *dst,
bool *incomplete);
#endif /* SWSCALE_FORMAT_H */
diff --git a/libswscale/graph.c b/libswscale/graph.c
index e47b2d07f2..c81988e4ed 100644
--- a/libswscale/graph.c
+++ b/libswscale/graph.c
@@ -395,8 +395,9 @@ static int init_legacy_subpass(SwsGraph *graph, SwsContext *sws,
return 0;
}
-static int add_legacy_sws_pass(SwsGraph *graph, SwsFormat src, SwsFormat dst,
- SwsPass *input, SwsPass **output)
+static int add_legacy_sws_pass(SwsGraph *graph, const SwsFormat *src,
+ const SwsFormat *dst, SwsPass *input,
+ SwsPass **output)
{
int ret, warned = 0;
SwsContext *const ctx = graph->ctx;
@@ -409,20 +410,20 @@ static int add_legacy_sws_pass(SwsGraph *graph, SwsFormat src, SwsFormat dst,
sws->alpha_blend = ctx->alpha_blend;
sws->gamma_flag = ctx->gamma_flag;
- sws->src_w = src.width;
- sws->src_h = src.height;
- sws->src_format = src.format;
- sws->src_range = src.range == AVCOL_RANGE_JPEG;
+ sws->src_w = src->width;
+ sws->src_h = src->height;
+ sws->src_format = src->format;
+ sws->src_range = src->range == AVCOL_RANGE_JPEG;
- sws->dst_w = dst.width;
- sws->dst_h = dst.height;
- sws->dst_format = dst.format;
- sws->dst_range = dst.range == AVCOL_RANGE_JPEG;
- get_chroma_pos(graph, &sws->src_h_chr_pos, &sws->src_v_chr_pos, &src);
- get_chroma_pos(graph, &sws->dst_h_chr_pos, &sws->dst_v_chr_pos, &dst);
+ sws->dst_w = dst->width;
+ sws->dst_h = dst->height;
+ sws->dst_format = dst->format;
+ sws->dst_range = dst->range == AVCOL_RANGE_JPEG;
+ get_chroma_pos(graph, &sws->src_h_chr_pos, &sws->src_v_chr_pos, src);
+ get_chroma_pos(graph, &sws->dst_h_chr_pos, &sws->dst_v_chr_pos, dst);
- graph->incomplete |= src.range == AVCOL_RANGE_UNSPECIFIED;
- graph->incomplete |= dst.range == AVCOL_RANGE_UNSPECIFIED;
+ graph->incomplete |= src->range == AVCOL_RANGE_UNSPECIFIED;
+ graph->incomplete |= dst->range == AVCOL_RANGE_UNSPECIFIED;
/* Allow overriding chroma position with the legacy API */
legacy_chr_pos(graph, &sws->src_h_chr_pos, ctx->src_h_chr_pos, &warned);
@@ -447,12 +448,12 @@ static int add_legacy_sws_pass(SwsGraph *graph, SwsFormat src, SwsFormat dst,
(int **)&table, &out_full,
&brightness, &contrast, &saturation);
- inv_table = sws_getCoefficients(src.csp);
- table = sws_getCoefficients(dst.csp);
+ inv_table = sws_getCoefficients(src->csp);
+ table = sws_getCoefficients(dst->csp);
- graph->incomplete |= src.csp != dst.csp &&
- (src.csp == AVCOL_SPC_UNSPECIFIED ||
- dst.csp == AVCOL_SPC_UNSPECIFIED);
+ graph->incomplete |= src->csp != dst->csp &&
+ (src->csp == AVCOL_SPC_UNSPECIFIED ||
+ dst->csp == AVCOL_SPC_UNSPECIFIED);
sws_setColorspaceDetails(sws, inv_table, in_full, table, out_full,
brightness, contrast, saturation);
@@ -466,8 +467,9 @@ static int add_legacy_sws_pass(SwsGraph *graph, SwsFormat src, SwsFormat dst,
*********************/
#if CONFIG_UNSTABLE
-static int add_convert_pass(SwsGraph *graph, SwsFormat src, SwsFormat dst,
- SwsPass *input, SwsPass **output)
+static int add_convert_pass(SwsGraph *graph, const SwsFormat *src,
+ const SwsFormat *dst, SwsPass *input,
+ SwsPass **output)
{
const SwsPixelType type = SWS_PIXEL_F32;
@@ -480,23 +482,23 @@ static int add_convert_pass(SwsGraph *graph, SwsFormat src, SwsFormat dst,
goto fail;
/* The new format conversion layer cannot scale for now */
- if (src.width != dst.width || src.height != dst.height ||
- src.desc->log2_chroma_h || src.desc->log2_chroma_w ||
- dst.desc->log2_chroma_h || dst.desc->log2_chroma_w)
+ if (src->width != dst->width || src->height != dst->height ||
+ src->desc->log2_chroma_h || src->desc->log2_chroma_w ||
+ dst->desc->log2_chroma_h || dst->desc->log2_chroma_w)
goto fail;
/* The new code does not yet support alpha blending */
- if (src.desc->flags & AV_PIX_FMT_FLAG_ALPHA &&
+ if (src->desc->flags & AV_PIX_FMT_FLAG_ALPHA &&
ctx->alpha_blend != SWS_ALPHA_BLEND_NONE)
goto fail;
ops = ff_sws_op_list_alloc();
if (!ops)
return AVERROR(ENOMEM);
- ops->src = src;
- ops->dst = dst;
+ ops->src = *src;
+ ops->dst = *dst;
- ret = ff_sws_decode_pixfmt(ops, src.format);
+ ret = ff_sws_decode_pixfmt(ops, src->format);
if (ret < 0)
goto fail;
ret = ff_sws_decode_colors(ctx, type, ops, src, &graph->incomplete);
@@ -505,12 +507,12 @@ static int add_convert_pass(SwsGraph *graph, SwsFormat src, SwsFormat dst,
ret = ff_sws_encode_colors(ctx, type, ops, src, dst, &graph->incomplete);
if (ret < 0)
goto fail;
- ret = ff_sws_encode_pixfmt(ops, dst.format);
+ ret = ff_sws_encode_pixfmt(ops, dst->format);
if (ret < 0)
goto fail;
av_log(ctx, AV_LOG_VERBOSE, "Conversion pass for %s -> %s:\n",
- av_get_pix_fmt_name(src.format), av_get_pix_fmt_name(dst.format));
+ av_get_pix_fmt_name(src->format), av_get_pix_fmt_name(dst->format));
av_log(ctx, AV_LOG_DEBUG, "Unoptimized operation list:\n");
ff_sws_op_list_print(ctx, AV_LOG_DEBUG, ops);
@@ -605,7 +607,7 @@ static int adapt_colors(SwsGraph *graph, SwsFormat src, SwsFormat dst,
if (fmt_in != src.format) {
SwsFormat tmp = src;
tmp.format = fmt_in;
- ret = add_convert_pass(graph, src, tmp, input, &input);
+ ret = add_convert_pass(graph, &src, &tmp, input, &input);
if (ret < 0)
return ret;
}
@@ -647,7 +649,7 @@ static int init_passes(SwsGraph *graph)
src.color = dst.color;
if (!ff_fmt_equal(&src, &dst)) {
- ret = add_convert_pass(graph, src, dst, pass, &pass);
+ ret = add_convert_pass(graph, &src, &dst, pass, &pass);
if (ret < 0)
return ret;
}
diff --git a/libswscale/ops.c b/libswscale/ops.c
index 900077584a..edadbb572d 100644
--- a/libswscale/ops.c
+++ b/libswscale/ops.c
@@ -1110,8 +1110,8 @@ static int rw_pixel_bits(const SwsOp *op)
return elems * size * bits;
}
-int ff_sws_compile_pass(SwsGraph *graph, SwsOpList *ops, int flags, SwsFormat dst,
- SwsPass *input, SwsPass **output)
+int ff_sws_compile_pass(SwsGraph *graph, SwsOpList *ops, int flags,
+ const SwsFormat *dst, SwsPass *input, SwsPass **output)
{
SwsContext *ctx = graph->ctx;
SwsOpPass *p = NULL;
@@ -1155,8 +1155,8 @@ int ff_sws_compile_pass(SwsGraph *graph, SwsOpList *ops, int flags, SwsFormat ds
p->pixel_bits_in = rw_pixel_bits(read);
p->pixel_bits_out = rw_pixel_bits(write);
p->exec_base = (SwsOpExec) {
- .width = dst.width,
- .height = dst.height,
+ .width = dst->width,
+ .height = dst->height,
.block_size_in = p->comp.block_size * p->pixel_bits_in >> 3,
.block_size_out = p->comp.block_size * p->pixel_bits_out >> 3,
};
@@ -1166,8 +1166,8 @@ int ff_sws_compile_pass(SwsGraph *graph, SwsOpList *ops, int flags, SwsFormat ds
p->idx_out[i] = i < p->planes_out ? ops->order_dst.in[i] : -1;
}
- pass = ff_sws_graph_add_pass(graph, dst.format, dst.width, dst.height, input,
- 1, p, op_pass_run);
+ pass = ff_sws_graph_add_pass(graph, dst->format, dst->width, dst->height,
+ input, 1, p, op_pass_run);
if (!pass) {
ret = AVERROR(ENOMEM);
goto fail;
diff --git a/libswscale/ops.h b/libswscale/ops.h
index 9f93c12fa8..e04c5ff9f5 100644
--- a/libswscale/ops.h
+++ b/libswscale/ops.h
@@ -296,7 +296,7 @@ enum SwsOpCompileFlags {
*
* Note: `ops` may be modified by this function.
*/
-int ff_sws_compile_pass(SwsGraph *graph, SwsOpList *ops, int flags, SwsFormat dst,
- SwsPass *input, SwsPass **output);
+int ff_sws_compile_pass(SwsGraph *graph, SwsOpList *ops, int flags,
+ const SwsFormat *dst, SwsPass *input, SwsPass **output);
#endif
diff --git a/libswscale/tests/sws_ops.c b/libswscale/tests/sws_ops.c
index bf84128291..9bad2ddff7 100644
--- a/libswscale/tests/sws_ops.c
+++ b/libswscale/tests/sws_ops.c
@@ -46,9 +46,9 @@ static int run_test(SwsContext *const ctx, AVFrame *frame,
if (ff_sws_decode_pixfmt(ops, src.format) < 0)
goto fail;
- if (ff_sws_decode_colors(ctx, SWS_PIXEL_F32, ops, src, &incomplete) < 0)
+ if (ff_sws_decode_colors(ctx, SWS_PIXEL_F32, ops, &src, &incomplete) < 0)
goto fail;
- if (ff_sws_encode_colors(ctx, SWS_PIXEL_F32, ops, src, dst, &incomplete) < 0)
+ if (ff_sws_encode_colors(ctx, SWS_PIXEL_F32, ops, &src, &dst, &incomplete) < 0)
goto fail;
if (ff_sws_encode_pixfmt(ops, dst.format) < 0)
goto fail;
--
2.52.0
>From c79352897b8c33ad12826fcb317780c33eb2ddf0 Mon Sep 17 00:00:00 2001
From: Niklas Haas <git@haasn.dev>
Date: Fri, 20 Feb 2026 17:50:39 +0100
Subject: [PATCH 3/3] tests/swscale: disable fate-sws-ops-list on BE platforms
The issue is that every le/be pair ends up with a swapped op list:
rgb24 -> rgb48be:
[ u8 XXXX -> +++X] SWS_OP_READ : 3 elem(s) packed >> 0
[ u8 ...X -> +++X] SWS_OP_CONVERT : u8 -> u16 (expand)
- [u16 ...X -> zzzX] SWS_OP_SWAP_BYTES
- [u16 ...X -> zzzX] SWS_OP_WRITE : 3 elem(s) packed >> 0
+ [u16 ...X -> +++X] SWS_OP_WRITE : 3 elem(s) packed >> 0
(X = unused, z = byteswapped, + = exact, 0 = zero)
rgb24 -> rgb48le:
[ u8 XXXX -> +++X] SWS_OP_READ : 3 elem(s) packed >> 0
[ u8 ...X -> +++X] SWS_OP_CONVERT : u8 -> u16 (expand)
- [u16 ...X -> +++X] SWS_OP_WRITE : 3 elem(s) packed >> 0
+ [u16 ...X -> zzzX] SWS_OP_SWAP_BYTES
+ [u16 ...X -> zzzX] SWS_OP_WRITE : 3 elem(s) packed >> 0
(X = unused, z = byteswapped, + = exact, 0 = zero)
I'm not sure of a good work-around that's not needlessly difficult to
implement, so just disable it on BE platforms for now. The actual underlying
conversions should still be covered by the sws-unscaled test.
---
tests/fate/libswscale.mak | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/tests/fate/libswscale.mak b/tests/fate/libswscale.mak
index 8d87c39ebf..db4d132c49 100644
--- a/tests/fate/libswscale.mak
+++ b/tests/fate/libswscale.mak
@@ -36,9 +36,13 @@ FATE_LIBSWSCALE-$(CONFIG_UNSTABLE) += fate-sws-unscaled
fate-sws-unscaled: libswscale/tests/swscale$(EXESUF)
fate-sws-unscaled: CMD = run libswscale/tests/swscale$(EXESUF) -unscaled 1 -flags 0x100000 -v 16
+ifneq ($(HAVE_BIGENDIAN),yes)
+# Disable on big endian because big endian platforms generate different op
+# lists for le vs be formats; this breaks the checksum otherwise
FATE_LIBSWSCALE-$(CONFIG_UNSTABLE) += fate-sws-ops-list
fate-sws-ops-list: libswscale/tests/sws_ops$(EXESUF)
fate-sws-ops-list: CMD = run libswscale/tests/sws_ops$(EXESUF) | do_md5sum | cut -d" " -f1
+endif
FATE_LIBSWSCALE += $(FATE_LIBSWSCALE-yes)
FATE_LIBSWSCALE_SAMPLES += $(FATE_LIBSWSCALE_SAMPLES-yes)
--
2.52.0
_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-02-20 18:42 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-02-20 16:53 [FFmpeg-devel] [PR] swscale/ops: PPC / bigendian fixes (PR #22231) Niklas Haas via ffmpeg-devel
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git