1
0
mirror of https://git.ffmpeg.org/ffmpeg.git synced 2026-10-24 02:09:03 +03:00

swscale/ops_optimizer: eliminate unneeded SWS_OP_MIN/MAX components

The current code only checks to see if the entire operation is a no-op,
but doesn't allow removing unneeded components from the operation.

Results in a large number of minor improvements, e.g.

 rgba 16x16 -> ya8 16x16:
   u8_read_packed_xyzw
   u8_to_f32_xyzw
   f32_linear_x_xxx00
   f32_dither_x_0_16x16
-  f32_min_xw
+  f32_min_x
   f32_to_u8_xw
   u8_permute_xyz_y_w
   u8_write_packed_xy

or:

 rgba 16x16 -> yuva444p10le 16x16:
   u8_read_packed_xyzw
   u8_to_f32_xyzw
   f32_linear_xyzw_xxx0x_xxx0x_xxx0x_000x0
   f32_dither_xyzw_0_3_2_5_16x16
-  f32_min_xyzw
+  f32_min_w
   f32_to_u16_xyzw
   u16_write_planar_xyzw

And some major ones, e.g.

 yuva444p 16x16 -> gbrap 16x16:
-  u8_read_planar_xyzw
-  u8_to_f32_xyzw
+  u8_read_planar_x
+  u8_write_planar_x
+ Sub-pass #1:
+  u8_read_planar_xyz
+  u8_to_f32_xyz
   f32_linear_xyz_x0x0x_xxx0x_xx00x
   f32_dither_xyz_0_3_2_16x16
-  f32_max_xyzw
-  f32_min_xyzw
-  f32_to_u8_xyzw
-  u8_write_planar_xyzw
+  f32_max_xyz
+  f32_min_xyz
+  f32_to_u8_xyz
+  u8_write_planar_xyz

Which is now split between two subpasses, one for the no-op alpha
copy and one for the yuv444 -> gbrp conversion. This has been
previously blocked by the SWS_OP_MIN/MAX clamp on the RGB channels
marking the alpha channel as dirty, even though it should be a no-op
on the alpha channel.

Signed-off-by: Niklas Haas <git@haasn.dev>
This commit is contained in:
Niklas Haas
2026-08-04 14:43:29 +02:00
parent d3d74f0ce4
commit 770a1ef28d
4 changed files with 21 additions and 3 deletions

View File

@@ -243,8 +243,12 @@ ENTRY(ff_sws_scale_16_u8_0111_neon, { .uop = SWS_UOP_SCALE,
ENTRY(ff_sws_scale_16_u16_0001_neon, { .uop = SWS_UOP_SCALE, .block_size = 16, .type = SWS_PIXEL_U16, .mask = 0x1 })
ENTRY(ff_sws_scale_16_u16_0111_neon, { .uop = SWS_UOP_SCALE, .block_size = 16, .type = SWS_PIXEL_U16, .mask = 0x7 })
ENTRY(ff_sws_min_8_f32_0001_neon, { .uop = SWS_UOP_MIN, .block_size = 8, .type = SWS_PIXEL_F32, .mask = 0x1 })
ENTRY(ff_sws_min_8_f32_0010_neon, { .uop = SWS_UOP_MIN, .block_size = 8, .type = SWS_PIXEL_F32, .mask = 0x2 })
ENTRY(ff_sws_min_8_f32_0011_neon, { .uop = SWS_UOP_MIN, .block_size = 8, .type = SWS_PIXEL_F32, .mask = 0x3 })
ENTRY(ff_sws_min_8_f32_0100_neon, { .uop = SWS_UOP_MIN, .block_size = 8, .type = SWS_PIXEL_F32, .mask = 0x4 })
ENTRY(ff_sws_min_8_f32_0101_neon, { .uop = SWS_UOP_MIN, .block_size = 8, .type = SWS_PIXEL_F32, .mask = 0x5 })
ENTRY(ff_sws_min_8_f32_0111_neon, { .uop = SWS_UOP_MIN, .block_size = 8, .type = SWS_PIXEL_F32, .mask = 0x7 })
ENTRY(ff_sws_min_8_f32_1000_neon, { .uop = SWS_UOP_MIN, .block_size = 8, .type = SWS_PIXEL_F32, .mask = 0x8 })
ENTRY(ff_sws_min_8_f32_1001_neon, { .uop = SWS_UOP_MIN, .block_size = 8, .type = SWS_PIXEL_F32, .mask = 0x9 })
ENTRY(ff_sws_min_8_f32_1110_neon, { .uop = SWS_UOP_MIN, .block_size = 8, .type = SWS_PIXEL_F32, .mask = 0xe })
ENTRY(ff_sws_min_8_f32_1111_neon, { .uop = SWS_UOP_MIN, .block_size = 8, .type = SWS_PIXEL_F32, .mask = 0xf })

View File

@@ -581,7 +581,9 @@ retry:
for (int i = 0; i < 4; i++) {
if (!SWS_OP_NEEDED(op, i) || !op->clamp.limit[i].den)
continue;
if (av_cmp_q64(op->clamp.limit[i], prev->comps.max[i]) < 0)
if (av_cmp_q64(op->clamp.limit[i], prev->comps.max[i]) >= 0)
op->clamp.limit[i] = (AVRational64) {0}; /* no-op */
else
noop = false;
}
@@ -595,7 +597,9 @@ retry:
for (int i = 0; i < 4; i++) {
if (!SWS_OP_NEEDED(op, i) || !op->clamp.limit[i].den)
continue;
if (av_cmp_q64(prev->comps.min[i], op->clamp.limit[i]) < 0)
if (av_cmp_q64(prev->comps.min[i], op->clamp.limit[i]) >= 0)
op->clamp.limit[i] = (AVRational64) {0};
else
noop = false;
}

View File

@@ -987,15 +987,23 @@
MACRO(__VA_ARGS__, f32_add_xyzw , .type = SWS_PIXEL_F32, .uop = SWS_UOP_ADD , .mask = 0xf)
#define SWS_FOR_F32_MIN(MACRO, ...) \
MACRO(__VA_ARGS__, f32_min_x , SWS_PIXEL_F32, SWS_UOP_MIN , 0x1) \
MACRO(__VA_ARGS__, f32_min_y , SWS_PIXEL_F32, SWS_UOP_MIN , 0x2) \
MACRO(__VA_ARGS__, f32_min_xy , SWS_PIXEL_F32, SWS_UOP_MIN , 0x3) \
MACRO(__VA_ARGS__, f32_min_z , SWS_PIXEL_F32, SWS_UOP_MIN , 0x4) \
MACRO(__VA_ARGS__, f32_min_xz , SWS_PIXEL_F32, SWS_UOP_MIN , 0x5) \
MACRO(__VA_ARGS__, f32_min_xyz , SWS_PIXEL_F32, SWS_UOP_MIN , 0x7) \
MACRO(__VA_ARGS__, f32_min_w , SWS_PIXEL_F32, SWS_UOP_MIN , 0x8) \
MACRO(__VA_ARGS__, f32_min_xw , SWS_PIXEL_F32, SWS_UOP_MIN , 0x9) \
MACRO(__VA_ARGS__, f32_min_yzw , SWS_PIXEL_F32, SWS_UOP_MIN , 0xe) \
MACRO(__VA_ARGS__, f32_min_xyzw , SWS_PIXEL_F32, SWS_UOP_MIN , 0xf)
#define SWS_FOR_STRUCT_F32_MIN(MACRO, ...) \
MACRO(__VA_ARGS__, f32_min_x , .type = SWS_PIXEL_F32, .uop = SWS_UOP_MIN , .mask = 0x1) \
MACRO(__VA_ARGS__, f32_min_y , .type = SWS_PIXEL_F32, .uop = SWS_UOP_MIN , .mask = 0x2) \
MACRO(__VA_ARGS__, f32_min_xy , .type = SWS_PIXEL_F32, .uop = SWS_UOP_MIN , .mask = 0x3) \
MACRO(__VA_ARGS__, f32_min_z , .type = SWS_PIXEL_F32, .uop = SWS_UOP_MIN , .mask = 0x4) \
MACRO(__VA_ARGS__, f32_min_xz , .type = SWS_PIXEL_F32, .uop = SWS_UOP_MIN , .mask = 0x5) \
MACRO(__VA_ARGS__, f32_min_xyz , .type = SWS_PIXEL_F32, .uop = SWS_UOP_MIN , .mask = 0x7) \
MACRO(__VA_ARGS__, f32_min_w , .type = SWS_PIXEL_F32, .uop = SWS_UOP_MIN , .mask = 0x8) \
MACRO(__VA_ARGS__, f32_min_xw , .type = SWS_PIXEL_F32, .uop = SWS_UOP_MIN , .mask = 0x9) \
MACRO(__VA_ARGS__, f32_min_yzw , .type = SWS_PIXEL_F32, .uop = SWS_UOP_MIN , .mask = 0xe) \
MACRO(__VA_ARGS__, f32_min_xyzw , .type = SWS_PIXEL_F32, .uop = SWS_UOP_MIN , .mask = 0xf)
@@ -1003,12 +1011,14 @@
MACRO(__VA_ARGS__, f32_max_x , SWS_PIXEL_F32, SWS_UOP_MAX , 0x1) \
MACRO(__VA_ARGS__, f32_max_xy , SWS_PIXEL_F32, SWS_UOP_MAX , 0x3) \
MACRO(__VA_ARGS__, f32_max_xyz , SWS_PIXEL_F32, SWS_UOP_MAX , 0x7) \
MACRO(__VA_ARGS__, f32_max_w , SWS_PIXEL_F32, SWS_UOP_MAX , 0x8) \
MACRO(__VA_ARGS__, f32_max_xw , SWS_PIXEL_F32, SWS_UOP_MAX , 0x9) \
MACRO(__VA_ARGS__, f32_max_xyzw , SWS_PIXEL_F32, SWS_UOP_MAX , 0xf)
#define SWS_FOR_STRUCT_F32_MAX(MACRO, ...) \
MACRO(__VA_ARGS__, f32_max_x , .type = SWS_PIXEL_F32, .uop = SWS_UOP_MAX , .mask = 0x1) \
MACRO(__VA_ARGS__, f32_max_xy , .type = SWS_PIXEL_F32, .uop = SWS_UOP_MAX , .mask = 0x3) \
MACRO(__VA_ARGS__, f32_max_xyz , .type = SWS_PIXEL_F32, .uop = SWS_UOP_MAX , .mask = 0x7) \
MACRO(__VA_ARGS__, f32_max_w , .type = SWS_PIXEL_F32, .uop = SWS_UOP_MAX , .mask = 0x8) \
MACRO(__VA_ARGS__, f32_max_xw , .type = SWS_PIXEL_F32, .uop = SWS_UOP_MAX , .mask = 0x9) \
MACRO(__VA_ARGS__, f32_max_xyzw , .type = SWS_PIXEL_F32, .uop = SWS_UOP_MAX , .mask = 0xf)
#define SWS_FOR_F32_UNPACK(MACRO, ...)

View File

@@ -1 +1 @@
b1ad61c3b7751b8d88c8036076bac1e4
3dec8ca0edbf6a301f53b7782932c98f