diff --git a/libswscale/aarch64/ops.c b/libswscale/aarch64/ops.c index 4b204efd08..753aef51ae 100644 --- a/libswscale/aarch64/ops.c +++ b/libswscale/aarch64/ops.c @@ -143,12 +143,14 @@ static int aarch64_setup(SwsOpList *ops, int block_size, int n, } break; case SWS_OP_CLEAR: + ff_sws_setup_clear(&(const SwsImplParams) { .op = op }, out); + break; case SWS_OP_MIN: case SWS_OP_MAX: - ff_sws_setup_q4(&(const SwsImplParams) { .op = op }, out); + ff_sws_setup_clamp(&(const SwsImplParams) { .op = op }, out); break; case SWS_OP_SCALE: - ff_sws_setup_q(&(const SwsImplParams) { .op = op }, out); + ff_sws_setup_scale(&(const SwsImplParams) { .op = op }, out); break; case SWS_OP_LINEAR: return aarch64_setup_linear(p, op, out); diff --git a/libswscale/ops_chain.c b/libswscale/ops_chain.c index 65bd3029d3..a2cfd3aaf9 100644 --- a/libswscale/ops_chain.c +++ b/libswscale/ops_chain.c @@ -263,33 +263,56 @@ int ff_sws_op_compile_tables(SwsContext *ctx, const SwsOpTable *const tables[], #define q2pixel(type, q) ((q).den ? (type) (q).num / (q).den : 0) -int ff_sws_setup_u8(const SwsImplParams *params, SwsImplResult *out) +int ff_sws_setup_shift(const SwsImplParams *params, SwsImplResult *out) { out->priv.u8[0] = params->op->c.u; return 0; } -int ff_sws_setup_q(const SwsImplParams *params, SwsImplResult *out) +int ff_sws_setup_scale(const SwsImplParams *params, SwsImplResult *out) { const SwsOp *op = params->op; + const AVRational factor = op->c.q; switch (op->type) { - case SWS_PIXEL_U8: out->priv.u8[0] = q2pixel(uint8_t, op->c.q); return 0; - case SWS_PIXEL_U16: out->priv.u16[0] = q2pixel(uint16_t, op->c.q); return 0; - case SWS_PIXEL_U32: out->priv.u32[0] = q2pixel(uint32_t, op->c.q); return 0; - case SWS_PIXEL_F32: out->priv.f32[0] = q2pixel(float, op->c.q); return 0; + case SWS_PIXEL_U8: out->priv.u8[0] = q2pixel(uint8_t, factor); break; + case SWS_PIXEL_U16: out->priv.u16[0] = q2pixel(uint16_t, factor); break; + case SWS_PIXEL_U32: out->priv.u32[0] = q2pixel(uint32_t, factor); break; + case SWS_PIXEL_F32: out->priv.f32[0] = q2pixel(float, factor); break; default: return AVERROR(EINVAL); } + + return 0; } -int ff_sws_setup_q4(const SwsImplParams *params, SwsImplResult *out) +int ff_sws_setup_clamp(const SwsImplParams *params, SwsImplResult *out) { const SwsOp *op = params->op; for (int i = 0; i < 4; i++) { + const AVRational limit = op->c.q4[i]; switch (op->type) { - case SWS_PIXEL_U8: out->priv.u8[i] = q2pixel(uint8_t, op->c.q4[i]); break; - case SWS_PIXEL_U16: out->priv.u16[i] = q2pixel(uint16_t, op->c.q4[i]); break; - case SWS_PIXEL_U32: out->priv.u32[i] = q2pixel(uint32_t, op->c.q4[i]); break; - case SWS_PIXEL_F32: out->priv.f32[i] = q2pixel(float, op->c.q4[i]); break; + case SWS_PIXEL_U8: out->priv.u8[i] = q2pixel(uint8_t, limit); break; + case SWS_PIXEL_U16: out->priv.u16[i] = q2pixel(uint16_t, limit); break; + case SWS_PIXEL_U32: out->priv.u32[i] = q2pixel(uint32_t, limit); break; + case SWS_PIXEL_F32: out->priv.f32[i] = q2pixel(float, limit); break; + default: return AVERROR(EINVAL); + } + } + + return 0; +} + +int ff_sws_setup_clear(const SwsImplParams *params, SwsImplResult *out) +{ + const SwsOp *op = params->op; + for (int i = 0; i < 4; i++) { + const AVRational value = op->c.q4[i]; + if (!value.den) + continue; + switch (op->type) { + case SWS_PIXEL_U8: out->priv.u8[i] = q2pixel(uint8_t, value); break; + case SWS_PIXEL_U16: out->priv.u16[i] = q2pixel(uint16_t, value); break; + case SWS_PIXEL_U32: out->priv.u32[i] = q2pixel(uint32_t, value); break; + case SWS_PIXEL_F32: out->priv.f32[i] = q2pixel(float, value); break; default: return AVERROR(EINVAL); } } diff --git a/libswscale/ops_chain.h b/libswscale/ops_chain.h index f9afe2b733..fc0cd930f8 100644 --- a/libswscale/ops_chain.h +++ b/libswscale/ops_chain.h @@ -140,10 +140,11 @@ typedef struct SwsOpEntry { bool (*check)(const SwsImplParams *params); /* optional, return true if supported */ } SwsOpEntry; -/* Setup helpers */ -int ff_sws_setup_u8(const SwsImplParams *params, SwsImplResult *out); -int ff_sws_setup_q(const SwsImplParams *params, SwsImplResult *out); -int ff_sws_setup_q4(const SwsImplParams *params, SwsImplResult *out); +/* Setup helpers for common/trivial operation types */ +int ff_sws_setup_shift(const SwsImplParams *params, SwsImplResult *out); +int ff_sws_setup_scale(const SwsImplParams *params, SwsImplResult *out); +int ff_sws_setup_clamp(const SwsImplParams *params, SwsImplResult *out); +int ff_sws_setup_clear(const SwsImplParams *params, SwsImplResult *out); static inline void ff_op_priv_free(SwsOpPriv *priv) { diff --git a/libswscale/ops_tmpl_common.c b/libswscale/ops_tmpl_common.c index 5a0a399f32..3817a437e5 100644 --- a/libswscale/ops_tmpl_common.c +++ b/libswscale/ops_tmpl_common.c @@ -85,7 +85,7 @@ DECL_IMPL(clear##_##X##Y##Z##W) } \ \ DECL_ENTRY(clear##_##X##Y##Z##W, \ - .setup = ff_sws_setup_q4, \ + .setup = ff_sws_setup_clear, \ .op = SWS_OP_CLEAR, \ .flexible = true, \ .unused = { !X, !Y, !Z, !W }, \ @@ -141,13 +141,13 @@ DECL_PATTERN(max) WRAP_COMMON_PATTERNS(min, .op = SWS_OP_MIN, - .setup = ff_sws_setup_q4, + .setup = ff_sws_setup_clamp, .flexible = true, ); WRAP_COMMON_PATTERNS(max, .op = SWS_OP_MAX, - .setup = ff_sws_setup_q4, + .setup = ff_sws_setup_clamp, .flexible = true, ); @@ -172,7 +172,7 @@ DECL_PATTERN(scale) WRAP_COMMON_PATTERNS(scale, .op = SWS_OP_SCALE, - .setup = ff_sws_setup_q, + .setup = ff_sws_setup_scale, .flexible = true, ); diff --git a/libswscale/ops_tmpl_int.c b/libswscale/ops_tmpl_int.c index 960d0d9527..b010513bc5 100644 --- a/libswscale/ops_tmpl_int.c +++ b/libswscale/ops_tmpl_int.c @@ -383,13 +383,13 @@ DECL_PATTERN(rshift) WRAP_COMMON_PATTERNS(lshift, .op = SWS_OP_LSHIFT, - .setup = ff_sws_setup_u8, + .setup = ff_sws_setup_shift, .flexible = true, ); WRAP_COMMON_PATTERNS(rshift, .op = SWS_OP_RSHIFT, - .setup = ff_sws_setup_u8, + .setup = ff_sws_setup_shift, .flexible = true, ); #endif /* BIT_DEPTH != 8 */ diff --git a/libswscale/x86/ops.c b/libswscale/x86/ops.c index 51c65c8ebb..734ffbac27 100644 --- a/libswscale/x86/ops.c +++ b/libswscale/x86/ops.c @@ -185,20 +185,20 @@ static int setup_shift(const SwsImplParams *params, SwsImplResult *out) #define DECL_MIN_MAX(EXT) \ DECL_COMMON_PATTERNS(F32, min##EXT, \ .op = SWS_OP_MIN, \ - .setup = ff_sws_setup_q4, \ + .setup = ff_sws_setup_clamp, \ .flexible = true, \ ); \ \ DECL_COMMON_PATTERNS(F32, max##EXT, \ .op = SWS_OP_MAX, \ - .setup = ff_sws_setup_q4, \ + .setup = ff_sws_setup_clamp, \ .flexible = true, \ ); #define DECL_SCALE(EXT) \ DECL_COMMON_PATTERNS(F32, scale##EXT, \ .op = SWS_OP_SCALE, \ - .setup = ff_sws_setup_q, \ + .setup = ff_sws_setup_scale, \ .flexible = true, \ ); @@ -941,7 +941,7 @@ static void normalize_clear(SwsOp *op) int i; } c; - ff_sws_setup_q4(&(const SwsImplParams) { .op = op }, &res); + ff_sws_setup_clear(&(const SwsImplParams) { .op = op }, &res); for (int i = 0; i < 4; i++) { if (!op->c.q4[i].den)