mirror of
https://mirror.skon.top/https://github.com/FFmpeg/FFmpeg
synced 2026-04-20 21:00:41 +08:00
swscale/ops_chain: simplify SwsClearOp checking
Since this now has an explicit mask, we can just check that directly, instead of relying on the unused comps hack/trick. Additionally, this also allows us to distinguish between fixed value and arbitrary value clears by just having the SwsOpEntry contain NAN values iff they support any clear value. Signed-off-by: Niklas Haas <git@haasn.dev>
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
};
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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) \
|
||||
|
||||
Reference in New Issue
Block a user