diff --git a/libswscale/ops_chain.c b/libswscale/ops_chain.c index 7072f8c437..abc2683f4e 100644 --- a/libswscale/ops_chain.c +++ b/libswscale/ops_chain.c @@ -112,16 +112,6 @@ static int op_match(const SwsOp *op, const SwsOpEntry *entry) } } - if (op->op == SWS_OP_CLEAR) { - /* Clear pattern must match exactly, regardless of `entry->flexible` */ - for (int i = 0; i < 4; i++) { - if (!SWS_OP_NEEDED(op, i)) - continue; - if (entry->unused[i] != SWS_COMP_TEST(op->clear.mask, i)) - return 0; - } - } - /* Flexible variants always match, but lower the score to prioritize more * specific implementations if they exist */ if (entry->flexible) @@ -148,10 +138,15 @@ static int op_match(const SwsOp *op, const SwsOpEntry *entry) } return score; case SWS_OP_CLEAR: + /* Clear mask must match exactly */ + if (op->clear.mask != entry->clear.mask) + return 0; for (int i = 0; i < 4; i++) { if (!SWS_COMP_TEST(op->clear.mask, i) || !SWS_OP_NEEDED(op, i)) continue; - if (av_cmp_q(op->clear.value[i], Q(entry->clear_value))) + else if (!entry->clear.value[i].den) + continue; /* Any clear value supported */ + else if (av_cmp_q(op->clear.value[i], entry->clear.value[i])) return 0; } return score; diff --git a/libswscale/ops_chain.h b/libswscale/ops_chain.h index fc0cd930f8..31e0e6a403 100644 --- a/libswscale/ops_chain.h +++ b/libswscale/ops_chain.h @@ -128,9 +128,9 @@ typedef struct SwsOpEntry { SwsPackOp pack; SwsSwizzleOp swizzle; SwsConvertOp convert; + SwsClearOp clear; uint32_t linear_mask; /* subset of SwsLinearOp */ int dither_size; /* subset of SwsDitherOp */ - int clear_value; /* clear value for integer clears */ AVRational scale; /* scale factor for SWS_OP_SCALE */ }; diff --git a/libswscale/ops_tmpl_common.c b/libswscale/ops_tmpl_common.c index 0763a08b1c..34016d062d 100644 --- a/libswscale/ops_tmpl_common.c +++ b/libswscale/ops_tmpl_common.c @@ -84,8 +84,7 @@ DECL_IMPL(clear, clear##_##X##Y##Z##W, X, Y, Z, W) DECL_ENTRY(clear##_##X##Y##Z##W, \ .setup = ff_sws_setup_clear, \ .op = SWS_OP_CLEAR, \ - .flexible = true, \ - .unused = { !X, !Y, !Z, !W }, \ + .clear.mask = SWS_COMP_MASK(!X, !Y, !Z, !W), \ ); WRAP_CLEAR(1, 1, 1, 0) /* rgba alpha */ diff --git a/libswscale/x86/ops.c b/libswscale/x86/ops.c index 5e95e80eac..0545dd3d6d 100644 --- a/libswscale/x86/ops.c +++ b/libswscale/x86/ops.c @@ -118,15 +118,15 @@ static int setup_swap_bytes(const SwsImplParams *params, SwsImplResult *out) #define DECL_CLEAR_ALPHA(EXT, IDX) \ DECL_ASM(U8, clear_alpha##IDX##EXT, \ .op = SWS_OP_CLEAR, \ - .clear_value = -1, \ - .unused[IDX] = true, \ + .clear.mask = SWS_COMP(IDX), \ + .clear.value[IDX] = { -1, 1 }, \ ); \ #define DECL_CLEAR_ZERO(EXT, IDX) \ DECL_ASM(U8, clear_zero##IDX##EXT, \ .op = SWS_OP_CLEAR, \ - .clear_value = 0, \ - .unused[IDX] = true, \ + .clear.mask = SWS_COMP(IDX), \ + .clear.value[IDX] = { 0, 1 }, \ ); static int setup_clear(const SwsImplParams *params, SwsImplResult *out) @@ -141,7 +141,7 @@ static int setup_clear(const SwsImplParams *params, SwsImplResult *out) DECL_PATTERN(U8, clear##EXT, X, Y, Z, W, \ .op = SWS_OP_CLEAR, \ .setup = setup_clear, \ - .flexible = true, \ + .clear.mask = SWS_COMP_MASK(!X, !Y, !Z, !W), \ ); #define DECL_SWIZZLE(EXT, X, Y, Z, W) \