diff --git a/libswscale/aarch64/ops_asmgen.c b/libswscale/aarch64/ops_asmgen.c index 626ce00e5e..cca1913630 100644 --- a/libswscale/aarch64/ops_asmgen.c +++ b/libswscale/aarch64/ops_asmgen.c @@ -851,7 +851,7 @@ static void asmgen_op_pack(SwsAArch64Context *s, const SwsAArch64OpImplParams *p } /*********************************************************************/ -/* logical left shift of raw pixel values by (u8) */ +/* logical left shift of raw pixel values */ /* AARCH64_SWS_OP_LSHIFT */ static void asmgen_op_lshift(SwsAArch64Context *s, const SwsAArch64OpImplParams *p) @@ -865,7 +865,7 @@ static void asmgen_op_lshift(SwsAArch64Context *s, const SwsAArch64OpImplParams } /*********************************************************************/ -/* right shift of raw pixel values by (u8) */ +/* right shift of raw pixel values */ /* AARCH64_SWS_OP_RSHIFT */ static void asmgen_op_rshift(SwsAArch64Context *s, const SwsAArch64OpImplParams *p) @@ -1012,7 +1012,7 @@ static void asmgen_op_expand(SwsAArch64Context *s, const SwsAArch64OpImplParams } /*********************************************************************/ -/* numeric minimum (q4) */ +/* numeric minimum */ /* AARCH64_SWS_OP_MIN */ static void asmgen_op_min(SwsAArch64Context *s, const SwsAArch64OpImplParams *p) @@ -1036,7 +1036,7 @@ static void asmgen_op_min(SwsAArch64Context *s, const SwsAArch64OpImplParams *p) } /*********************************************************************/ -/* numeric maximum (q4) */ +/* numeric maximum */ /* AARCH64_SWS_OP_MAX */ static void asmgen_op_max(SwsAArch64Context *s, const SwsAArch64OpImplParams *p) @@ -1060,7 +1060,7 @@ static void asmgen_op_max(SwsAArch64Context *s, const SwsAArch64OpImplParams *p) } /*********************************************************************/ -/* multiplication by scalar (q) */ +/* multiplication by scalar */ /* AARCH64_SWS_OP_SCALE */ static void asmgen_op_scale(SwsAArch64Context *s, const SwsAArch64OpImplParams *p) diff --git a/libswscale/aarch64/ops_impl_conv.c b/libswscale/aarch64/ops_impl_conv.c index fdc398392f..8f37af0101 100644 --- a/libswscale/aarch64/ops_impl_conv.c +++ b/libswscale/aarch64/ops_impl_conv.c @@ -181,14 +181,14 @@ static int convert_to_aarch64_impl(SwsContext *ctx, const SwsOpList *ops, int n, break; case AARCH64_SWS_OP_LSHIFT: case AARCH64_SWS_OP_RSHIFT: - out->shift = op->c.u; + out->shift = op->shift.amount; break; case AARCH64_SWS_OP_CLEAR: out->mask = 0; - MASK_SET(out->mask, 0, !!op->c.q4[0].den); - MASK_SET(out->mask, 1, !!op->c.q4[1].den); - MASK_SET(out->mask, 2, !!op->c.q4[2].den); - MASK_SET(out->mask, 3, !!op->c.q4[3].den); + MASK_SET(out->mask, 0, !!op->clear.value[0].den); + MASK_SET(out->mask, 1, !!op->clear.value[1].den); + MASK_SET(out->mask, 2, !!op->clear.value[2].den); + MASK_SET(out->mask, 3, !!op->clear.value[3].den); break; case AARCH64_SWS_OP_EXPAND: case AARCH64_SWS_OP_CONVERT: diff --git a/libswscale/format.c b/libswscale/format.c index 6fa279cc18..a26349585a 100644 --- a/libswscale/format.c +++ b/libswscale/format.c @@ -827,7 +827,7 @@ static int cmp_comp(const void *a, const void *b) { } static int fmt_analyze_regular(const AVPixFmtDescriptor *desc, SwsReadWriteOp *rw_op, - SwsSwizzleOp *swizzle, int *shift) + SwsSwizzleOp *swizzle, SwsShiftOp *shift) { if (desc->nb_components == 2) { /* YA formats */ @@ -848,7 +848,7 @@ static int fmt_analyze_regular(const AVPixFmtDescriptor *desc, SwsReadWriteOp *r *swizzle = swiz; } - *shift = desc->comp[0].shift; + *shift = (SwsShiftOp) { desc->comp[0].shift }; *rw_op = (SwsReadWriteOp) { .elems = desc->nb_components, .packed = desc->nb_components > 1 && !(desc->flags & AV_PIX_FMT_FLAG_PLANAR), @@ -857,8 +857,9 @@ static int fmt_analyze_regular(const AVPixFmtDescriptor *desc, SwsReadWriteOp *r } static int fmt_analyze(enum AVPixelFormat fmt, SwsReadWriteOp *rw_op, - SwsPackOp *pack_op, SwsSwizzleOp *swizzle, int *shift, - SwsPixelType *pixel_type, SwsPixelType *raw_type) + SwsPackOp *pack_op, SwsSwizzleOp *swizzle, + SwsShiftOp *shift, SwsPixelType *pixel_type, + SwsPixelType *raw_type) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); if (!desc) @@ -889,7 +890,7 @@ static int fmt_analyze(enum AVPixelFormat fmt, SwsReadWriteOp *rw_op, *rw_op = info.rw; *pack_op = info.pack; *swizzle = info.swizzle; - *shift = info.shift; + *shift = (SwsShiftOp) { info.shift }; if (info.pack.pattern[0]) { const int sum = info.pack.pattern[0] + info.pack.pattern[1] + @@ -923,17 +924,17 @@ static SwsSwizzleOp swizzle_inv(SwsSwizzleOp swiz) { * it will end up getting pushed towards the output or optimized away entirely * by the optimization pass. */ -static SwsConst fmt_clear(enum AVPixelFormat fmt) +static SwsClearOp fmt_clear(enum AVPixelFormat fmt) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); const bool has_chroma = desc->nb_components >= 3; const bool has_alpha = desc->flags & AV_PIX_FMT_FLAG_ALPHA; - SwsConst c = {0}; + SwsClearOp c = {0}; if (!has_chroma) - c.q4[1] = c.q4[2] = Q0; + c.value[1] = c.value[2] = Q0; if (!has_alpha) - c.q4[3] = Q0; + c.value[3] = Q0; return c; } @@ -952,7 +953,7 @@ int ff_sws_decode_pixfmt(SwsOpList *ops, enum AVPixelFormat fmt) SwsSwizzleOp swizzle; SwsPackOp unpack; SwsComps *comps = &ops->comps_src; - int shift; + SwsShiftOp shift; RET(fmt_analyze(fmt, &rw_op, &unpack, &swizzle, &shift, &pixel_type, &raw_type)); @@ -974,7 +975,7 @@ int ff_sws_decode_pixfmt(SwsOpList *ops, enum AVPixelFormat fmt) * canonical order {Y, U, V, A} */ const int is_ya = desc->nb_components == 2; for (int c = 0; c < desc->nb_components; c++) { - const int bits = desc->comp[c].depth + shift; + const int bits = desc->comp[c].depth + shift.amount; const int idx = swizzle.in[is_ya ? 3 * c : c]; comps->min[idx] = Q0; if (bits < 32) /* FIXME: AVRational is limited to INT_MAX */ @@ -1016,18 +1017,18 @@ int ff_sws_decode_pixfmt(SwsOpList *ops, enum AVPixelFormat fmt) .swizzle = swizzle, })); - if (shift) { + if (shift.amount) { RET(ff_sws_op_list_append(ops, &(SwsOp) { - .op = SWS_OP_RSHIFT, - .type = pixel_type, - .c.u = shift, + .op = SWS_OP_RSHIFT, + .type = pixel_type, + .shift = shift, })); } RET(ff_sws_op_list_append(ops, &(SwsOp) { - .op = SWS_OP_CLEAR, - .type = pixel_type, - .c = fmt_clear(fmt), + .op = SWS_OP_CLEAR, + .type = pixel_type, + .clear = fmt_clear(fmt), })); return 0; @@ -1040,16 +1041,16 @@ int ff_sws_encode_pixfmt(SwsOpList *ops, enum AVPixelFormat fmt) SwsReadWriteOp rw_op; SwsSwizzleOp swizzle; SwsPackOp pack; - int shift; + SwsShiftOp shift; RET(fmt_analyze(fmt, &rw_op, &pack, &swizzle, &shift, &pixel_type, &raw_type)); - if (shift) { + if (shift.amount) { RET(ff_sws_op_list_append(ops, &(SwsOp) { - .op = SWS_OP_LSHIFT, - .type = pixel_type, - .c.u = shift, + .op = SWS_OP_LSHIFT, + .type = pixel_type, + .shift = shift, })); } @@ -1059,7 +1060,7 @@ int ff_sws_encode_pixfmt(SwsOpList *ops, enum AVPixelFormat fmt) RET(ff_sws_op_list_append(ops, &(SwsOp) { .op = SWS_OP_CLEAR, .type = pixel_type, - .c.q4[3] = Q0, + .clear.value[3] = Q0, })); } @@ -1513,26 +1514,26 @@ int ff_sws_encode_colors(SwsContext *ctx, SwsPixelType type, })); if (!(dst->desc->flags & AV_PIX_FMT_FLAG_FLOAT)) { - SwsConst range = {0}; + SwsClampOp range = {0}; 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.limit[idx] = Q((1 << dst->desc->comp[i].depth) - 1); } RET(fmt_dither(ctx, ops, type, src, dst)); RET(ff_sws_op_list_append(ops, &(SwsOp) { - .op = SWS_OP_MAX, - .type = type, - .c.q4 = { Q0, Q0, Q0, Q0 }, + .op = SWS_OP_MAX, + .type = type, + .clamp = {{ Q0, Q0, Q0, Q0 }}, })); RET(ff_sws_op_list_append(ops, &(SwsOp) { - .op = SWS_OP_MIN, - .type = type, - .c = range, + .op = SWS_OP_MIN, + .type = type, + .clamp = range, })); } diff --git a/libswscale/ops.c b/libswscale/ops.c index 7661fc6d9d..ad26b5cc95 100644 --- a/libswscale/ops.c +++ b/libswscale/ops.c @@ -177,13 +177,13 @@ void ff_sws_apply_op_q(const SwsOp *op, AVRational x[4]) return; case SWS_OP_CLEAR: for (int i = 0; i < 4; i++) { - if (op->c.q4[i].den) - x[i] = op->c.q4[i]; + if (op->clear.value[i].den) + x[i] = op->clear.value[i]; } return; case SWS_OP_LSHIFT: { av_assert1(ff_sws_pixel_type_is_int(op->type)); - AVRational mult = Q(1 << op->c.u); + AVRational mult = Q(1 << op->shift.amount); for (int i = 0; i < 4; i++) x[i] = x[i].den ? av_mul_q(x[i], mult) : x[i]; return; @@ -191,7 +191,7 @@ void ff_sws_apply_op_q(const SwsOp *op, AVRational x[4]) case SWS_OP_RSHIFT: { av_assert1(ff_sws_pixel_type_is_int(op->type)); for (int i = 0; i < 4; i++) - x[i] = x[i].den ? Q((x[i].num / x[i].den) >> op->c.u) : x[i]; + x[i] = x[i].den ? Q((x[i].num / x[i].den) >> op->shift.amount) : x[i]; return; } case SWS_OP_SWIZZLE: { @@ -219,11 +219,11 @@ void ff_sws_apply_op_q(const SwsOp *op, AVRational x[4]) return; case SWS_OP_MIN: for (int i = 0; i < 4; i++) - x[i] = av_min_q(x[i], op->c.q4[i]); + x[i] = av_min_q(x[i], op->clamp.limit[i]); return; case SWS_OP_MAX: for (int i = 0; i < 4; i++) - x[i] = av_max_q(x[i], op->c.q4[i]); + x[i] = av_max_q(x[i], op->clamp.limit[i]); return; case SWS_OP_LINEAR: { av_assert1(!ff_sws_pixel_type_is_int(op->type)); @@ -238,7 +238,7 @@ void ff_sws_apply_op_q(const SwsOp *op, AVRational x[4]) } case SWS_OP_SCALE: for (int i = 0; i < 4; i++) - x[i] = x[i].den ? av_mul_q(x[i], op->c.q) : x[i]; + x[i] = x[i].den ? av_mul_q(x[i], op->scale.factor) : x[i]; return; case SWS_OP_FILTER_H: case SWS_OP_FILTER_V: @@ -362,11 +362,11 @@ void ff_sws_op_list_update_comps(SwsOpList *ops) break; case SWS_OP_MIN: propagate_flags(op, &prev); - clear_undefined_values(op->comps.max, op->c.q4); + clear_undefined_values(op->comps.max, op->clamp.limit); break; case SWS_OP_MAX: propagate_flags(op, &prev); - clear_undefined_values(op->comps.min, op->c.q4); + clear_undefined_values(op->comps.min, op->clamp.limit); break; case SWS_OP_DITHER: for (int i = 0; i < 4; i++) { @@ -405,11 +405,11 @@ void ff_sws_op_list_update_comps(SwsOpList *ops) } case SWS_OP_CLEAR: for (int i = 0; i < 4; i++) { - if (op->c.q4[i].den) { + if (op->clear.value[i].den) { op->comps.flags[i] = 0; - if (op->c.q4[i].num == 0) + if (op->clear.value[i].num == 0) op->comps.flags[i] |= SWS_COMP_ZERO; - if (op->c.q4[i].den == 1) + if (op->clear.value[i].den == 1) op->comps.flags[i] |= SWS_COMP_EXACT; } else { op->comps.flags[i] = prev.flags[i]; @@ -460,9 +460,9 @@ void ff_sws_op_list_update_comps(SwsOpList *ops) case SWS_OP_SCALE: for (int i = 0; i < 4; i++) { op->comps.flags[i] = prev.flags[i]; - if (op->c.q.den != 1) /* fractional scale */ + if (op->scale.factor.den != 1) /* fractional scale */ op->comps.flags[i] &= ~SWS_COMP_EXACT; - if (op->c.q.num < 0) + if (op->scale.factor.num < 0) FFSWAP(AVRational, op->comps.min[i], op->comps.max[i]); } break; @@ -524,7 +524,7 @@ void ff_sws_op_list_update_comps(SwsOpList *ops) break; case SWS_OP_CLEAR: for (int i = 0; i < 4; i++) { - if (!op->c.q4[i].den) + if (!op->clear.value[i].den) need_in[i] = need_out[i]; } break; @@ -839,10 +839,10 @@ void ff_sws_op_desc(AVBPrint *bp, const SwsOp *op) op->rw.filter == SWS_OP_FILTER_H ? 'H' : 'V'); break; case SWS_OP_LSHIFT: - av_bprintf(bp, "%-20s: << %u", name, op->c.u); + av_bprintf(bp, "%-20s: << %u", name, op->shift.amount); break; case SWS_OP_RSHIFT: - av_bprintf(bp, "%-20s: >> %u", name, op->c.u); + av_bprintf(bp, "%-20s: >> %u", name, op->shift.amount); break; case SWS_OP_PACK: case SWS_OP_UNPACK: @@ -852,7 +852,7 @@ void ff_sws_op_desc(AVBPrint *bp, const SwsOp *op) break; case SWS_OP_CLEAR: av_bprintf(bp, "%-20s: ", name); - print_q4(bp, op->c.q4, true, op->comps.flags); + print_q4(bp, op->clear.value, true, op->comps.flags); break; case SWS_OP_SWIZZLE: av_bprintf(bp, "%-20s: %d%d%d%d", name, @@ -872,11 +872,11 @@ void ff_sws_op_desc(AVBPrint *bp, const SwsOp *op) break; case SWS_OP_MIN: av_bprintf(bp, "%-20s: x <= ", name); - print_q4(bp, op->c.q4, true, op->comps.flags); + print_q4(bp, op->clamp.limit, true, op->comps.flags); break; case SWS_OP_MAX: av_bprintf(bp, "%-20s: ", name); - print_q4(bp, op->c.q4, true, op->comps.flags); + print_q4(bp, op->clamp.limit, true, op->comps.flags); av_bprintf(bp, " <= x"); break; case SWS_OP_LINEAR: @@ -892,9 +892,9 @@ void ff_sws_op_desc(AVBPrint *bp, const SwsOp *op) av_bprintf(bp, "]"); break; case SWS_OP_SCALE: - av_bprintf(bp, "%-20s: * %d", name, op->c.q.num); - if (op->c.q.den != 1) - av_bprintf(bp, "/%d", op->c.q.den); + av_bprintf(bp, "%-20s: * %d", name, op->scale.factor.num); + if (op->scale.factor.den != 1) + av_bprintf(bp, "/%d", op->scale.factor.den); break; case SWS_OP_FILTER_H: case SWS_OP_FILTER_V: { diff --git a/libswscale/ops.h b/libswscale/ops.h index a9e24ff5a9..c1723dfc6a 100644 --- a/libswscale/ops.h +++ b/libswscale/ops.h @@ -55,15 +55,15 @@ typedef enum SwsOpType { /* Bit manipulation operations. Defined for integers only. */ SWS_OP_UNPACK, /* split tightly packed data into components */ SWS_OP_PACK, /* compress components into tightly packed data */ - SWS_OP_LSHIFT, /* logical left shift of raw pixel values by (u8) */ - SWS_OP_RSHIFT, /* right shift of raw pixel values by (u8) */ + SWS_OP_LSHIFT, /* logical left shift of raw pixel values */ + SWS_OP_RSHIFT, /* right shift of raw pixel values */ /* Generic arithmetic. Defined and implemented for all types */ SWS_OP_CLEAR, /* clear pixel values */ SWS_OP_CONVERT, /* convert (cast) between formats */ - SWS_OP_MIN, /* numeric minimum (q4) */ - SWS_OP_MAX, /* numeric maximum (q4) */ - SWS_OP_SCALE, /* multiplication by scalar (q) */ + SWS_OP_MIN, /* numeric minimum */ + SWS_OP_MAX, /* numeric maximum */ + SWS_OP_SCALE, /* multiplication by scalar */ /* Floating-point only arithmetic operations. */ SWS_OP_LINEAR, /* generalized linear affine transform */ @@ -87,16 +87,6 @@ typedef enum SwsCompFlags { #define SWS_OP_NEEDED(op, idx) (!((op)->comps.flags[idx] & SWS_COMP_GARBAGE)) -typedef union SwsConst { - /* Generic constant value */ - AVRational q4[4]; - AVRational q; - unsigned u; -} SwsConst; - -static_assert(sizeof(SwsConst) == sizeof(AVRational) * 4, - "First field of SwsConst should span the entire union"); - typedef struct SwsComps { SwsCompFlags flags[4]; /* knowledge about (output) component contents */ bool unused[4]; /* which input components are definitely unused */ @@ -152,11 +142,27 @@ typedef struct SwsSwizzleOp { #define SWS_SWIZZLE(X,Y,Z,W) ((SwsSwizzleOp) { .in = {X, Y, Z, W} }) +typedef struct SwsShiftOp { + uint8_t amount; /* number of bits to shift */ +} SwsShiftOp; + +typedef struct SwsClearOp { + AVRational value[4]; /* value to set, or {0, 0} for no-op */ +} SwsClearOp; + typedef struct SwsConvertOp { SwsPixelType to; /* type of pixel to convert to */ bool expand; /* if true, integers are expanded to the full range */ } SwsConvertOp; +typedef struct SwsClampOp { + AVRational limit[4]; /* per-component min/max value */ +} SwsClampOp; + +typedef struct SwsScaleOp { + AVRational factor; /* scalar multiplication factor */ +} SwsScaleOp; + typedef struct SwsDitherOp { AVRational *matrix; /* tightly packed dither matrix (refstruct) */ AVRational min, max; /* minimum/maximum value in `matrix` */ @@ -217,10 +223,13 @@ typedef struct SwsOp { SwsReadWriteOp rw; SwsPackOp pack; SwsSwizzleOp swizzle; + SwsShiftOp shift; + SwsClearOp clear; SwsConvertOp convert; + SwsClampOp clamp; + SwsScaleOp scale; SwsDitherOp dither; SwsFilterOp filter; - SwsConst c; }; /** diff --git a/libswscale/ops_chain.c b/libswscale/ops_chain.c index a2cfd3aaf9..1730fdfe61 100644 --- a/libswscale/ops_chain.c +++ b/libswscale/ops_chain.c @@ -115,7 +115,9 @@ 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) && entry->unused[i] != !!op->c.q4[i].den) + if (!SWS_OP_NEEDED(op, i)) + continue; + if (entry->unused[i] != !!op->clear.value[i].den) return 0; } } @@ -147,9 +149,9 @@ static int op_match(const SwsOp *op, const SwsOpEntry *entry) return score; case SWS_OP_CLEAR: for (int i = 0; i < 4; i++) { - if (!op->c.q4[i].den || !SWS_OP_NEEDED(op, i)) + if (!op->clear.value[i].den || !SWS_OP_NEEDED(op, i)) continue; - if (av_cmp_q(op->c.q4[i], Q(entry->clear_value))) + if (av_cmp_q(op->clear.value[i], Q(entry->clear_value))) return 0; } return score; @@ -188,7 +190,7 @@ static int op_match(const SwsOp *op, const SwsOpEntry *entry) score += av_popcount(SWS_MASK_ALL ^ entry->linear_mask); return score; case SWS_OP_SCALE: - return av_cmp_q(op->c.q, entry->scale) ? 0 : score; + return av_cmp_q(op->scale.factor, entry->scale) ? 0 : score; case SWS_OP_FILTER_H: case SWS_OP_FILTER_V: return score; @@ -265,14 +267,14 @@ int ff_sws_op_compile_tables(SwsContext *ctx, const SwsOpTable *const tables[], int ff_sws_setup_shift(const SwsImplParams *params, SwsImplResult *out) { - out->priv.u8[0] = params->op->c.u; + out->priv.u8[0] = params->op->shift.amount; return 0; } int ff_sws_setup_scale(const SwsImplParams *params, SwsImplResult *out) { const SwsOp *op = params->op; - const AVRational factor = op->c.q; + const AVRational factor = op->scale.factor; switch (op->type) { 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; @@ -288,7 +290,7 @@ 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]; + const AVRational limit = op->clamp.limit[i]; switch (op->type) { 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; @@ -305,7 +307,7 @@ 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]; + const AVRational value = op->clear.value[i]; if (!value.den) continue; switch (op->type) { diff --git a/libswscale/ops_memcpy.c b/libswscale/ops_memcpy.c index a84067da6d..b7b56900ee 100644 --- a/libswscale/ops_memcpy.c +++ b/libswscale/ops_memcpy.c @@ -86,20 +86,20 @@ static int compile(SwsContext *ctx, SwsOpList *ops, SwsCompiledOp *out) case SWS_OP_CLEAR: for (int i = 0; i < 4; i++) { - if (!op->c.q4[i].den) + if (!op->clear.value[i].den) continue; - if (op->c.q4[i].den != 1) + if (op->clear.value[i].den != 1) return AVERROR(ENOTSUP); /* Ensure all bytes to be cleared are the same, because we * can't memset on multi-byte sequences */ - uint8_t val = op->c.q4[i].num & 0xFF; + uint8_t val = op->clear.value[i].num & 0xFF; uint32_t ref = val; switch (ff_sws_pixel_type_size(op->type)) { case 2: ref *= 0x101; break; case 4: ref *= 0x1010101; break; } - if (ref != op->c.q4[i].num) + if (ref != op->clear.value[i].num) return AVERROR(ENOTSUP); p.clear_value[i] = val; p.index[i] = -1; diff --git a/libswscale/ops_optimizer.c b/libswscale/ops_optimizer.c index fd3c1ef969..f44a44e1b7 100644 --- a/libswscale/ops_optimizer.c +++ b/libswscale/ops_optimizer.c @@ -39,7 +39,7 @@ */ static bool op_commute_clear(SwsOp *op, SwsOp *next) { - SwsOp tmp; + SwsClearOp tmp; av_assert1(op->op == SWS_OP_CLEAR); switch (next->op) { @@ -56,21 +56,21 @@ static bool op_commute_clear(SwsOp *op, SwsOp *next) case SWS_OP_SWIZZLE: case SWS_OP_FILTER_H: case SWS_OP_FILTER_V: - ff_sws_apply_op_q(next, op->c.q4); + ff_sws_apply_op_q(next, op->clear.value); return true; case SWS_OP_SWAP_BYTES: switch (next->type) { case SWS_PIXEL_U16: - ff_sws_apply_op_q(next, op->c.q4); /* always works */ + ff_sws_apply_op_q(next, op->clear.value); /* always works */ return true; case SWS_PIXEL_U32: for (int i = 0; i < 4; i++) { - uint32_t v = av_bswap32(op->c.q4[i].num); + uint32_t v = av_bswap32(op->clear.value[i].num); if (v > INT_MAX) return false; /* can't represent as AVRational anymore */ - tmp.c.q4[i] = Q(v); + tmp.value[i] = Q(v); } - op->c = tmp.c; + op->clear = tmp; return true; default: return false; @@ -124,14 +124,14 @@ static bool op_commute_swizzle(SwsOp *op, SwsOp *next) */ case SWS_OP_MIN: case SWS_OP_MAX: { - const SwsConst c = next->c; + const SwsClampOp c = next->clamp; for (int i = 0; i < 4; i++) { if (!SWS_OP_NEEDED(op, i)) continue; const int j = op->swizzle.in[i]; - if (seen[j] && av_cmp_q(next->c.q4[j], c.q4[i])) + if (seen[j] && av_cmp_q(next->clamp.limit[j], c.limit[i])) return false; - next->c.q4[j] = c.q4[i]; + next->clamp.limit[j] = c.limit[i]; seen[j] = true; } return true; @@ -238,9 +238,9 @@ static int exact_log2_q(const AVRational x) * the corresponding scaling factor, or 0 otherwise. */ static bool extract_scalar(const SwsLinearOp *c, SwsComps comps, SwsComps prev, - SwsConst *out_scale) + SwsScaleOp *out_scale) { - SwsConst scale = {0}; + SwsScaleOp scale = {0}; /* There are components not on the main diagonal */ if (c->mask & ~SWS_MASK_DIAG4) @@ -251,21 +251,21 @@ static bool extract_scalar(const SwsLinearOp *c, SwsComps comps, SwsComps prev, if ((prev.flags[i] & SWS_COMP_ZERO) || (comps.flags[i] & SWS_COMP_GARBAGE)) continue; - if (scale.q.den && av_cmp_q(s, scale.q)) + if (scale.factor.den && av_cmp_q(s, scale.factor)) return false; - scale.q = s; + scale.factor = s; } - if (scale.q.den) + if (scale.factor.den) *out_scale = scale; - return scale.q.den; + return scale.factor.den; } /* Extracts an integer clear operation (subset) from the given linear op. */ static bool extract_constant_rows(SwsLinearOp *c, SwsComps prev, - SwsConst *out_clear) + SwsClearOp *out_clear) { - SwsConst clear = {0}; + SwsClearOp clear = {0}; bool ret = false; for (int i = 0; i < 4; i++) { @@ -275,7 +275,7 @@ static bool extract_constant_rows(SwsLinearOp *c, SwsComps prev, (prev.flags[j] & SWS_COMP_ZERO); /* input is zero */ } if (const_row && (c->mask & SWS_MASK_ROW(i))) { - clear.q4[i] = c->m[i][4]; + clear.value[i] = c->m[i][4]; for (int j = 0; j < 5; j++) c->m[i][j] = Q(i == j); c->mask &= ~SWS_MASK_ROW(i); @@ -428,13 +428,13 @@ retry: case SWS_OP_RSHIFT: /* Two shifts in the same direction */ if (next->op == op->op) { - op->c.u += next->c.u; + op->shift.amount += next->shift.amount; ff_sws_op_list_remove_at(ops, n + 1, 1); goto retry; } /* No-op shift */ - if (!op->c.u) { + if (!op->shift.amount) { ff_sws_op_list_remove_at(ops, n, 1); goto retry; } @@ -442,19 +442,19 @@ retry: case SWS_OP_CLEAR: for (int i = 0; i < 4; i++) { - if (!op->c.q4[i].den) + if (!op->clear.value[i].den) continue; if ((prev->comps.flags[i] & SWS_COMP_ZERO) && !(prev->comps.flags[i] & SWS_COMP_GARBAGE) && - op->c.q4[i].num == 0) + op->clear.value[i].num == 0) { /* Redundant clear-to-zero of zero component */ - op->c.q4[i].den = 0; + op->clear.value[i].den = 0; } else if (!SWS_OP_NEEDED(op, i)) { /* Unnecessary clear of unused component */ - op->c.q4[i] = (AVRational) {0, 0}; - } else if (op->c.q4[i].den) { + op->clear.value[i] = (AVRational) {0, 0}; + } else if (op->clear.value[i].den) { noop = false; } } @@ -467,8 +467,8 @@ retry: /* Transitive clear */ if (next->op == SWS_OP_CLEAR) { for (int i = 0; i < 4; i++) { - if (next->c.q4[i].den) - op->c.q4[i] = next->c.q4[i]; + if (next->clear.value[i].den) + op->clear.value[i] = next->clear.value[i]; } ff_sws_op_list_remove_at(ops, n + 1, 1); goto retry; @@ -548,7 +548,8 @@ retry: if (next->op == SWS_OP_SCALE && !op->convert.expand && ff_sws_pixel_type_is_int(op->type) && ff_sws_pixel_type_is_int(op->convert.to) && - !av_cmp_q(next->c.q, ff_sws_pixel_expand(op->type, op->convert.to))) + !av_cmp_q(next->scale.factor, + ff_sws_pixel_expand(op->type, op->convert.to))) { op->convert.expand = true; ff_sws_op_list_remove_at(ops, n + 1, 1); @@ -558,9 +559,9 @@ retry: case SWS_OP_MIN: for (int i = 0; i < 4; i++) { - if (!SWS_OP_NEEDED(op, i) || !op->c.q4[i].den) + if (!SWS_OP_NEEDED(op, i) || !op->clamp.limit[i].den) continue; - if (av_cmp_q(op->c.q4[i], prev->comps.max[i]) < 0) + if (av_cmp_q(op->clamp.limit[i], prev->comps.max[i]) < 0) noop = false; } @@ -572,9 +573,9 @@ retry: case SWS_OP_MAX: for (int i = 0; i < 4; i++) { - if (!SWS_OP_NEEDED(op, i) || !op->c.q4[i].den) + if (!SWS_OP_NEEDED(op, i) || !op->clamp.limit[i].den) continue; - if (av_cmp_q(prev->comps.min[i], op->c.q4[i]) < 0) + if (av_cmp_q(prev->comps.min[i], op->clamp.limit[i]) < 0) noop = false; } @@ -604,7 +605,8 @@ retry: case SWS_OP_LINEAR: { SwsSwizzleOp swizzle; - SwsConst c; + SwsClearOp clear; + SwsScaleOp scale; /* No-op (identity) linear operation */ if (!op->lin.mask) { @@ -654,20 +656,20 @@ retry: } /* Convert constant rows to explicit clear instruction */ - if (extract_constant_rows(&op->lin, prev->comps, &c)) { + if (extract_constant_rows(&op->lin, prev->comps, &clear)) { RET(ff_sws_op_list_insert_at(ops, n + 1, &(SwsOp) { .op = SWS_OP_CLEAR, .type = op->type, .comps = op->comps, - .c = c, + .clear = clear, })); goto retry; } /* Multiplication by scalar constant */ - if (extract_scalar(&op->lin, op->comps, prev->comps, &c)) { - op->op = SWS_OP_SCALE; - op->c = c; + if (extract_scalar(&op->lin, op->comps, prev->comps, &scale)) { + op->op = SWS_OP_SCALE; + op->scale = scale; goto retry; } @@ -684,20 +686,20 @@ retry: } case SWS_OP_SCALE: { - const int factor2 = exact_log2_q(op->c.q); + const int factor2 = exact_log2_q(op->scale.factor); /* No-op scaling */ - if (op->c.q.num == 1 && op->c.q.den == 1) { + if (op->scale.factor.num == 1 && op->scale.factor.den == 1) { ff_sws_op_list_remove_at(ops, n, 1); goto retry; } /* Merge consecutive scaling operations (that don't overflow) */ if (next->op == SWS_OP_SCALE) { - int64_t p = op->c.q.num * (int64_t) next->c.q.num; - int64_t q = op->c.q.den * (int64_t) next->c.q.den; + int64_t p = op->scale.factor.num * (int64_t) next->scale.factor.num; + int64_t q = op->scale.factor.den * (int64_t) next->scale.factor.den; if (FFABS(p) <= INT_MAX && FFABS(q) <= INT_MAX) { - av_reduce(&op->c.q.num, &op->c.q.den, p, q, INT_MAX); + av_reduce(&op->scale.factor.num, &op->scale.factor.den, p, q, INT_MAX); ff_sws_op_list_remove_at(ops, n + 1, 1); goto retry; } @@ -706,7 +708,7 @@ retry: /* Scaling by exact power of two */ if (factor2 && ff_sws_pixel_type_is_int(op->type)) { op->op = factor2 > 0 ? SWS_OP_LSHIFT : SWS_OP_RSHIFT; - op->c.u = FFABS(factor2); + op->shift.amount = FFABS(factor2); goto retry; } break; @@ -760,7 +762,7 @@ retry: case SWS_OP_SCALE: /* Scaling by integer before conversion to int */ - if (op->c.q.den == 1 && next->op == SWS_OP_CONVERT && + if (op->scale.factor.den == 1 && next->op == SWS_OP_CONVERT && ff_sws_pixel_type_is_int(next->convert.to)) { op->type = next->convert.to; @@ -812,9 +814,9 @@ int ff_sws_solve_shuffle(const SwsOpList *const ops, uint8_t shuffle[], case SWS_OP_CLEAR: for (int i = 0; i < 4; i++) { - if (!op->c.q4[i].den) + if (!op->clear.value[i].den) continue; - if (op->c.q4[i].num != 0 || !clear_val) + if (op->clear.value[i].num != 0 || !clear_val) return AVERROR(ENOTSUP); mask[i] = 0x1010101ul * clear_val; } diff --git a/libswscale/tests/sws_ops.c b/libswscale/tests/sws_ops.c index 02049156e7..05378be18d 100644 --- a/libswscale/tests/sws_ops.c +++ b/libswscale/tests/sws_ops.c @@ -65,11 +65,16 @@ static int register_op(SwsContext *ctx, void *opaque, SwsOp *op) } break; case SWS_OP_SCALE: + op->scale.factor = (AVRational) { 0, 1 }; + break; case SWS_OP_MIN: case SWS_OP_MAX: + for (int i = 0; i < 4; i++) + op->clamp.limit[i] = (AVRational) { 0, 1 }; + break; case SWS_OP_CLEAR: for (int i = 0; i < 4; i++) - op->c.q4[i] = (AVRational) { 0, !!op->c.q4[i].den }; + op->clear.value[i] = (AVRational) { 0, !!op->clear.value[i].den }; break; case SWS_OP_DITHER: /* Strip arbitrary offset */ diff --git a/libswscale/vulkan/ops.c b/libswscale/vulkan/ops.c index fece479cd3..adf81864a4 100644 --- a/libswscale/vulkan/ops.c +++ b/libswscale/vulkan/ops.c @@ -274,32 +274,32 @@ static int add_ops_glsl(VulkanPriv *p, FFVulkanOpsCtx *s, } case SWS_OP_CLEAR: { for (int i = 0; i < 4; i++) { - if (!op->c.q4[i].den) + if (!op->clear.value[i].den) continue; av_bprintf(&shd->src, " %s.%c = %s"QSTR";\n", type_name, - "xyzw"[i], type_s, QTYPE(op->c.q4[i])); + "xyzw"[i], type_s, QTYPE(op->clear.value[i])); } break; } case SWS_OP_SCALE: av_bprintf(&shd->src, " %s = %s * "QSTR";\n", - type_name, type_name, QTYPE(op->c.q)); + type_name, type_name, QTYPE(op->scale.factor)); break; case SWS_OP_MIN: case SWS_OP_MAX: for (int i = 0; i < 4; i++) { - if (!op->c.q4[i].den) + if (!op->clamp.limit[i].den) continue; av_bprintf(&shd->src, " %s.%c = %s(%s.%c, "QSTR");\n", type_name, "xyzw"[i], op->op == SWS_OP_MIN ? "min" : "max", - type_name, "xyzw"[i], QTYPE(op->c.q4[i])); + type_name, "xyzw"[i], QTYPE(op->clamp.limit[i])); } break; case SWS_OP_LSHIFT: case SWS_OP_RSHIFT: av_bprintf(&shd->src, " %s %s= %i;\n", type_name, - op->op == SWS_OP_LSHIFT ? "<<" : ">>", op->c.u); + op->op == SWS_OP_LSHIFT ? "<<" : ">>", op->shift.amount); break; case SWS_OP_CONVERT: if (ff_sws_pixel_type_is_int(cur_type) && op->convert.expand) { diff --git a/libswscale/x86/ops.c b/libswscale/x86/ops.c index 734ffbac27..ab113aa780 100644 --- a/libswscale/x86/ops.c +++ b/libswscale/x86/ops.c @@ -133,7 +133,7 @@ static int setup_clear(const SwsImplParams *params, SwsImplResult *out) { const SwsOp *op = params->op; for (int i = 0; i < 4; i++) - out->priv.u32[i] = (uint32_t) op->c.q4[i].num; + out->priv.u32[i] = (uint32_t) op->clear.value[i].num; return 0; } @@ -165,7 +165,7 @@ static int setup_clear(const SwsImplParams *params, SwsImplResult *out) static int setup_shift(const SwsImplParams *params, SwsImplResult *out) { - out->priv.u16[0] = params->op->c.u; + out->priv.u16[0] = params->op->shift.amount; return 0; } @@ -944,7 +944,7 @@ static void normalize_clear(SwsOp *op) ff_sws_setup_clear(&(const SwsImplParams) { .op = op }, &res); for (int i = 0; i < 4; i++) { - if (!op->c.q4[i].den) + if (!op->clear.value[i].den) continue; switch (ff_sws_pixel_type_size(op->type)) { case 1: c.u32 = 0x1010101U * res.priv.u8[i]; break; @@ -952,8 +952,8 @@ static void normalize_clear(SwsOp *op) case 4: c.u32 = res.priv.u32[i]; break; } - op->c.q4[i].num = c.i; - op->c.q4[i].den = 1; + op->clear.value[i].num = c.i; + op->clear.value[i].den = 1; } } diff --git a/tests/checkasm/sw_ops.c b/tests/checkasm/sw_ops.c index 570fbfc825..39a053172c 100644 --- a/tests/checkasm/sw_ops.c +++ b/tests/checkasm/sw_ops.c @@ -498,45 +498,45 @@ static void check_clear(void) const AVRational zero = (AVRational) { 0, 1}; const AVRational none = {0}; - const SwsConst patterns[] = { + const SwsClearOp patterns[] = { /* Zero only */ - {.q4 = { none, none, none, zero }}, - {.q4 = { zero, none, none, none }}, + {{ none, none, none, zero }}, + {{ zero, none, none, none }}, /* Alpha only */ - {.q4 = { none, none, none, alpha }}, - {.q4 = { alpha, none, none, none }}, + {{ none, none, none, alpha }}, + {{ alpha, none, none, none }}, /* Chroma only */ - {.q4 = { chroma, chroma, none, none }}, - {.q4 = { none, chroma, chroma, none }}, - {.q4 = { none, none, chroma, chroma }}, - {.q4 = { chroma, none, chroma, none }}, - {.q4 = { none, chroma, none, chroma }}, + {{ chroma, chroma, none, none }}, + {{ none, chroma, chroma, none }}, + {{ none, none, chroma, chroma }}, + {{ chroma, none, chroma, none }}, + {{ none, chroma, none, chroma }}, /* Alpha+chroma */ - {.q4 = { chroma, chroma, none, alpha }}, - {.q4 = { none, chroma, chroma, alpha }}, - {.q4 = { alpha, none, chroma, chroma }}, - {.q4 = { chroma, none, chroma, alpha }}, - {.q4 = { alpha, chroma, none, chroma }}, + {{ chroma, chroma, none, alpha }}, + {{ none, chroma, chroma, alpha }}, + {{ alpha, none, chroma, chroma }}, + {{ chroma, none, chroma, alpha }}, + {{ alpha, chroma, none, chroma }}, /* Random values */ - {.q4 = { none, rndq(t), rndq(t), rndq(t) }}, - {.q4 = { none, rndq(t), rndq(t), rndq(t) }}, - {.q4 = { none, rndq(t), rndq(t), rndq(t) }}, - {.q4 = { none, rndq(t), rndq(t), rndq(t) }}, + {{ none, rndq(t), rndq(t), rndq(t) }}, + {{ none, rndq(t), rndq(t), rndq(t) }}, + {{ none, rndq(t), rndq(t), rndq(t) }}, + {{ none, rndq(t), rndq(t), rndq(t) }}, }; for (int i = 0; i < FF_ARRAY_ELEMS(patterns); i++) { CHECK(FMT("clear_pattern_%s[%d]", type, i), 4, 4, t, t, { - .op = SWS_OP_CLEAR, - .type = t, - .c = patterns[i], + .op = SWS_OP_CLEAR, + .type = t, + .clear = patterns[i], }); } } else if (!ff_sws_pixel_type_is_int(t)) { /* Floating point YUV doesn't exist, only alpha needs to be cleared */ CHECK(FMT("clear_alpha_%s", type), 4, 4, t, t, { - .op = SWS_OP_CLEAR, - .type = t, - .c.q4[3] = { 0, 1 }, + .op = SWS_OP_CLEAR, + .type = t, + .clear.value[3] = { 0, 1 }, }); } } @@ -551,15 +551,15 @@ static void check_shift(void) for (int shift = 1; shift <= 8; shift++) { CHECK_COMMON(FMT("lshift%d_%s", shift, type), t, t, { - .op = SWS_OP_LSHIFT, - .type = t, - .c.u = shift, + .op = SWS_OP_LSHIFT, + .type = t, + .shift = { shift }, }); CHECK_COMMON(FMT("rshift%d_%s", shift, type), t, t, { - .op = SWS_OP_RSHIFT, - .type = t, - .c.u = shift, + .op = SWS_OP_RSHIFT, + .type = t, + .shift = { shift }, }); } } @@ -697,13 +697,13 @@ static void check_min_max(void) CHECK_COMMON(FMT("min_%s", type), t, t, { .op = SWS_OP_MIN, .type = t, - .c.q4 = { rndq(t), rndq(t), rndq(t), rndq(t) }, + .clamp = {{ rndq(t), rndq(t), rndq(t), rndq(t) }}, }); CHECK_COMMON(FMT("max_%s", type), t, t, { .op = SWS_OP_MAX, .type = t, - .c.q4 = { rndq(t), rndq(t), rndq(t), rndq(t) }, + .clamp = {{ rndq(t), rndq(t), rndq(t), rndq(t) }}, }); } } @@ -776,15 +776,15 @@ static void check_scale(void) const unsigned scale = rnd() & max; const unsigned range = max / (scale ? scale : 1); CHECK_COMMON_RANGE(FMT("scale_%s", type), range, t, t, { - .op = SWS_OP_SCALE, - .type = t, - .c.q = { scale, 1 }, + .op = SWS_OP_SCALE, + .type = t, + .scale = {{ scale, 1 }}, }); } else { CHECK_COMMON(FMT("scale_%s", type), t, t, { - .op = SWS_OP_SCALE, - .type = t, - .c.q = rndq(t), + .op = SWS_OP_SCALE, + .type = t, + .scale = { rndq(t) }, }); } }