This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit a3d9acfaed39bded9261339304b1cf4f149fdcaa Author: Niklas Haas <[email protected]> AuthorDate: Tue Oct 20 20:55:04 2026 +0200 Commit: Niklas Haas <[email protected]> CommitDate: Tue Oct 20 21:33:01 2026 +0000 swscale/ops: switch SwsComps from SoA to AoS And name them SwsOpPad instead. This is a purely cosmetic refactor that makes some parts of the code easier, since it allows taking pointers to specific output pads without having to thread through the index as well. Signed-off-by: Niklas Haas <[email protected]> --- libswscale/format.c | 8 +- libswscale/ops.c | 190 +++++++++++++++++++++++++-------------------- libswscale/ops.h | 16 ++-- libswscale/ops_dispatch.c | 6 +- libswscale/ops_optimizer.c | 40 +++++----- libswscale/uops.c | 25 +++--- 6 files changed, 150 insertions(+), 135 deletions(-) diff --git a/libswscale/format.c b/libswscale/format.c index 4f75adcc0f..1167c0446c 100644 --- a/libswscale/format.c +++ b/libswscale/format.c @@ -1093,7 +1093,7 @@ static int decode_pixfmt(SwsOpList *ops, const SwsFormat *fmt) SwsReadWriteOp rw_op; SwsSwizzleOp swizzle; SwsPackOp unpack; - SwsComps *comps = &ops->comps_src; + SwsOpPad *inputs = ops->inputs; SwsShiftOp shift; RET(fmt_analyze(fmt->format, &rw_op, &unpack, &swizzle, &shift, @@ -1106,7 +1106,7 @@ static int decode_pixfmt(SwsOpList *ops, const SwsFormat *fmt) const int swapped = ff_sws_pixel_type_size(raw_type) > 1 && (desc->flags & AV_PIX_FMT_FLAG_BE) != NATIVE_ENDIAN_FLAG; for (int i = 0; i < rw_op.elems; i++) { - comps->flags[i] = (integer ? SWS_COMP_EXACT : 0) | + inputs[i].flags = (integer ? SWS_COMP_EXACT : 0) | (swapped ? SWS_COMP_SWAPPED : 0); } @@ -1118,8 +1118,8 @@ static int decode_pixfmt(SwsOpList *ops, const SwsFormat *fmt) for (int c = 0; c < desc->nb_components; c++) { const int bits = desc->comp[c].depth + shift.amount; const int idx = swizzle.in[is_ya ? 3 * c : c]; - comps->min[idx] = Q(0); - comps->max[idx] = intmax_q64(bits); + inputs[idx].min = Q(0); + inputs[idx].max = intmax_q64(bits); } } diff --git a/libswscale/ops.c b/libswscale/ops.c index 800a41befa..07159b57d8 100644 --- a/libswscale/ops.c +++ b/libswscale/ops.c @@ -287,31 +287,34 @@ static SwsCompFlags merge_comp_flags(SwsCompFlags a, SwsCompFlags b) return ((a & b) & flags_and) | ((a | b) & flags_or); } -static void apply_filter_weights(SwsComps *comps, const SwsComps *prev, +static void apply_filter_weights(SwsOpPad outputs[4], const SwsOpPad inputs[4], const SwsFilterWeights *weights) { const AVRational64 posw = { weights->sum_positive, SWS_FILTER_SCALE }; const AVRational64 negw = { weights->sum_negative, SWS_FILTER_SCALE }; for (int i = 0; i < 4; i++) { - comps->flags[i] = prev->flags[i] & SWS_COMP_DIRTY; - comps->dep_in[i] = prev->dep_in[i]; + outputs[i].flags = inputs[i].flags & SWS_COMP_DIRTY; + outputs[i].dep_in = inputs[i].dep_in; /* Only point sampling preserves exactness */ if (weights->filter_size != 1) - comps->flags[i] &= ~SWS_COMP_EXACT; + outputs[i].flags &= ~SWS_COMP_EXACT; /* Update min/max assuming extremes */ - comps->min[i] = ff_add_q64(ff_mul_q64(prev->min[i], posw), - ff_mul_q64(prev->max[i], negw)); - comps->max[i] = ff_add_q64(ff_mul_q64(prev->min[i], negw), - ff_mul_q64(prev->max[i], posw)); + outputs[i].min = ff_add_q64(ff_mul_q64(inputs[i].min, posw), + ff_mul_q64(inputs[i].max, negw)); + outputs[i].max = ff_add_q64(ff_mul_q64(inputs[i].min, negw), + ff_mul_q64(inputs[i].max, posw)); } } /* Infer + propagate known information about components */ void ff_sws_op_list_update_comps(SwsOpList *ops) { - SwsComps prev = { .flags = { - SWS_COMP_GARBAGE, SWS_COMP_GARBAGE, SWS_COMP_GARBAGE, SWS_COMP_GARBAGE, - }}; + SwsOpPad prev[4] = { + { .flags = SWS_COMP_GARBAGE }, + { .flags = SWS_COMP_GARBAGE }, + { .flags = SWS_COMP_GARBAGE }, + { .flags = SWS_COMP_GARBAGE }, + }; /* Forwards pass, propagates knowledge about the incoming pixel values */ for (int n = 0; n < ops->num_ops; n++) { @@ -326,29 +329,40 @@ void ff_sws_op_list_update_comps(SwsOpList *ops) case SWS_OP_FILTER_V: case SWS_OP_LUT_3D: break; /* special cases, handled below */ - default: - memcpy(op->comps.min, prev.min, sizeof(prev.min)); - memcpy(op->comps.max, prev.max, sizeof(prev.max)); - ff_sws_apply_op_q(op, op->comps.min); - ff_sws_apply_op_q(op, op->comps.max); + default: { + AVRational64 min[4], max[4]; + for (int i = 0; i < 4; i++) { + min[i] = prev[i].min; + max[i] = prev[i].max; + } + ff_sws_apply_op_q(op, min); + ff_sws_apply_op_q(op, max); + for (int i = 0; i < 4; i++) { + op->outputs[i].min = min[i]; + op->outputs[i].max = max[i]; + } break; } + } for (int i = 0; i < 4; i++) { - op->comps.flags[i] = SWS_COMP_IDENTITY; - op->comps.dep_in[i] = SWS_COMP_NONE; + op->outputs[i].flags = SWS_COMP_IDENTITY; + op->outputs[i].dep_in = SWS_COMP_NONE; } #define FORWARD(I, J, EXPR) do { \ - SwsCompFlags flags = prev.flags[J]; \ - op->comps.flags[I] = merge_comp_flags(op->comps.flags[I], (EXPR)); \ - op->comps.dep_in[I] |= prev.dep_in[J]; \ + SwsOpPad *dst = &op->outputs[I]; \ + const SwsOpPad *src = &prev[J]; \ + SwsCompFlags flags = src->flags; \ + dst->flags = merge_comp_flags(dst->flags, (EXPR)); \ + dst->dep_in |= src->dep_in; \ } while (0) #define RESET(I) do { \ - op->comps.flags[I] = SWS_COMP_GARBAGE; \ - op->comps.min[I] = op->comps.max[I] = (AVRational64) {0}; \ - op->comps.dep_in[I] = SWS_COMP_NONE; \ + SwsOpPad *dst = &op->outputs[I]; \ + dst->flags = SWS_COMP_GARBAGE; \ + dst->min = dst->max = (AVRational64) {0}; \ + dst->dep_in = SWS_COMP_NONE; \ } while (0) switch (op->op) { @@ -363,11 +377,13 @@ void ff_sws_op_list_update_comps(SwsOpList *ops) case SWS_RW_PLANAR: idx = ops->plane_src[i]; break; } - av_assert0(!(ops->comps_src.flags[idx] & SWS_COMP_GARBAGE)); - op->comps.flags[i] = ops->comps_src.flags[idx] & SWS_COMP_DIRTY; - op->comps.min[i] = ops->comps_src.min[idx]; - op->comps.max[i] = ops->comps_src.max[idx]; - op->comps.dep_in[i] = SWS_COMP(i); + const SwsOpPad *src = &ops->inputs[idx]; + SwsOpPad *dst = &op->outputs[i]; + av_assert0(!(src->flags & SWS_COMP_GARBAGE)); + dst->flags = src->flags & SWS_COMP_DIRTY; + dst->min = src->min; + dst->max = src->max; + dst->dep_in = SWS_COMP(i); /** * Don't mark packed or fractional reads as a copy, because the @@ -377,24 +393,24 @@ void ff_sws_op_list_update_comps(SwsOpList *ops) * is already covered by the no-op check. */ if (op->rw.mode == SWS_RW_PLANAR && !op->rw.frac) - op->comps.flags[i] |= SWS_COMP_COPY; + dst->flags |= SWS_COMP_COPY; } if (op->rw.filter.op) { - const SwsComps prev = op->comps; - apply_filter_weights(&op->comps, &prev, op->rw.filter.kernel); + memcpy(prev, op->outputs, sizeof(prev)); + apply_filter_weights(op->outputs, prev, op->rw.filter.kernel); } break; case SWS_OP_SWAP_BYTES: for (int i = 0; i < 4; i++) { FORWARD(i, i, (flags ^ SWS_COMP_SWAPPED) & SWS_COMP_DIRTY); - op->comps.min[i] = prev.min[i]; - op->comps.max[i] = prev.max[i]; + op->outputs[i].min = prev[i].min; + op->outputs[i].max = prev[i].max; } break; case SWS_OP_WRITE: for (int i = 0; i < op->rw.elems; i++) - av_assert1(!(prev.flags[i] & SWS_COMP_GARBAGE)); + av_assert1(!(prev[i].flags & SWS_COMP_GARBAGE)); for (int i = 0; i < 4; i++) FORWARD(i, i, flags); break; @@ -405,27 +421,30 @@ void ff_sws_op_list_update_comps(SwsOpList *ops) break; case SWS_OP_MIN: case SWS_OP_MAX: { - AVRational64 *bound = op->op == SWS_OP_MIN ? op->comps.max : op->comps.min; for (int i = 0; i < 4; i++) { + SwsOpPad *dst = &op->outputs[i]; FORWARD(i, i, flags); if (op->clamp.limit[i].den) - op->comps.flags[i] &= SWS_COMP_DIRTY; - if (!bound[i].den) /* reset undefined bounds to known range */ - bound[i] = op->clamp.limit[i]; + dst->flags &= SWS_COMP_DIRTY; + + /* Reset undefined bounds to known range */ + AVRational64 *bound = op->op == SWS_OP_MIN ? &dst->max : &dst->min; + if (!bound->den) + *bound = op->clamp.limit[i]; } break; } case SWS_OP_DITHER: for (int i = 0; i < 4; i++) { FORWARD(i, i, flags); - op->comps.min[i] = prev.min[i]; - op->comps.max[i] = prev.max[i]; + op->outputs[i].min = prev[i].min; + op->outputs[i].max = prev[i].max; if (op->dither.y_offset[i] < 0) continue; /* Strip zero flag because of the nonzero dithering offset */ - op->comps.flags[i] &= ~SWS_COMP_ZERO & SWS_COMP_DIRTY; - op->comps.min[i] = ff_add_q64(op->comps.min[i], op->dither.min); - op->comps.max[i] = ff_add_q64(op->comps.max[i], op->dither.max); + op->outputs[i].flags &= ~SWS_COMP_ZERO & SWS_COMP_DIRTY; + op->outputs[i].min = ff_add_q64(op->outputs[i].min, op->dither.min); + op->outputs[i].max = ff_add_q64(op->outputs[i].max, op->dither.max); } break; case SWS_OP_UNPACK: @@ -434,8 +453,8 @@ void ff_sws_op_list_update_comps(SwsOpList *ops) if (pattern) { av_assert1(pattern < 32); FORWARD(i, 0, flags & SWS_COMP_DIRTY); - op->comps.min[i] = Q(0); - op->comps.max[i] = Q((1ULL << pattern) - 1); + op->outputs[i].min = Q(0); + op->outputs[i].max = Q((1ULL << pattern) - 1); } else RESET(i); } @@ -451,11 +470,11 @@ void ff_sws_op_list_update_comps(SwsOpList *ops) case SWS_OP_CLEAR: for (int i = 0; i < 4; i++) { if (SWS_COMP_TEST(op->clear.mask, i)) { - op->comps.flags[i] = SWS_COMP_CONST; + op->outputs[i].flags = SWS_COMP_CONST; if (op->clear.value[i].num == 0) - op->comps.flags[i] |= SWS_COMP_ZERO; + op->outputs[i].flags |= SWS_COMP_ZERO; if (op->clear.value[i].den == 1) - op->comps.flags[i] |= SWS_COMP_EXACT; + op->outputs[i].flags |= SWS_COMP_EXACT; } else { FORWARD(i, i, flags); } @@ -468,56 +487,56 @@ void ff_sws_op_list_update_comps(SwsOpList *ops) case SWS_OP_CONVERT: for (int i = 0; i < 4; i++) { FORWARD(i, i, flags); - if (!(prev.flags[i] & SWS_COMP_EXACT)) - op->comps.flags[i] &= SWS_COMP_DIRTY; + if (!(prev[i].flags & SWS_COMP_EXACT)) + op->outputs[i].flags &= SWS_COMP_DIRTY; if (ff_sws_pixel_type_is_int(op->convert.to)) - op->comps.flags[i] |= SWS_COMP_EXACT; + op->outputs[i].flags |= SWS_COMP_EXACT; } break; case SWS_OP_LINEAR: for (int i = 0; i < 4; i++) { - AVRational64 min = Q(0), max = Q(0); + SwsOpPad *dst = &op->outputs[i]; bool first = true; + dst->min = dst->max = Q(0); for (int j = 0; j < 4; j++) { + const SwsOpPad *src = &prev[j]; const AVRational64 k = op->lin.m[i][j]; - AVRational64 mink = ff_mul_q64(prev.min[j], k); - AVRational64 maxk = ff_mul_q64(prev.max[j], k); + AVRational64 mink = ff_mul_q64(src->min, k); + AVRational64 maxk = ff_mul_q64(src->max, k); if (k.num) { FORWARD(i, j, flags); if (k.den != 1) /* fractional coefficient */ - op->comps.flags[i] &= ~SWS_COMP_EXACT; + dst->flags &= ~SWS_COMP_EXACT; if (k.num < 0) FFSWAP(AVRational64, mink, maxk); - min = ff_add_q64(min, mink); - max = ff_add_q64(max, maxk); + dst->min = ff_add_q64(dst->min, mink); + dst->max = ff_add_q64(dst->max, maxk); if (!first || ff_cmp_q64(k, Q(1))) - op->comps.flags[i] &= SWS_COMP_DIRTY; + dst->flags &= SWS_COMP_DIRTY; first = false; } } if (op->lin.m[i][4].num) { /* nonzero offset */ - op->comps.flags[i] &= ~SWS_COMP_ZERO & SWS_COMP_DIRTY; + dst->flags &= ~SWS_COMP_ZERO & SWS_COMP_DIRTY; if (op->lin.m[i][4].den != 1) /* fractional offset */ - op->comps.flags[i] &= ~SWS_COMP_EXACT; - min = ff_add_q64(min, op->lin.m[i][4]); - max = ff_add_q64(max, op->lin.m[i][4]); + dst->flags &= ~SWS_COMP_EXACT; + dst->min = ff_add_q64(dst->min, op->lin.m[i][4]); + dst->max = ff_add_q64(dst->max, op->lin.m[i][4]); } - op->comps.min[i] = min; - op->comps.max[i] = max; } break; case SWS_OP_SCALE: for (int i = 0; i < 4; i++) { FORWARD(i, i, flags & SWS_COMP_DIRTY); if (op->scale.factor.den != 1) /* fractional scale */ - op->comps.flags[i] &= ~SWS_COMP_EXACT; + op->outputs[i].flags &= ~SWS_COMP_EXACT; if (op->scale.factor.num < 0) - FFSWAP(AVRational64, op->comps.min[i], op->comps.max[i]); + FFSWAP(AVRational64, op->outputs[i].min, op->outputs[i].max); } break; case SWS_OP_FILTER_H: case SWS_OP_FILTER_V: { - apply_filter_weights(&op->comps, &prev, op->filter.kernel); + apply_filter_weights(op->outputs, prev, op->filter.kernel); break; } case SWS_OP_LUT_3D: @@ -527,20 +546,20 @@ void ff_sws_op_list_update_comps(SwsOpList *ops) for (int j = 0; j < 3; j++) FORWARD(i, j, flags & SWS_COMP_GARBAGE); /* LUT output domain is always scaled to full 16-bit range */ - op->comps.min[i] = Q(0); - op->comps.max[i] = Q(UINT16_MAX); + op->outputs[i].min = Q(0); + op->outputs[i].max = Q(UINT16_MAX); } /* Pass through alpha channel untouched */ FORWARD(3, 3, flags); - op->comps.min[3] = prev.min[3]; - op->comps.max[3] = prev.max[3]; + op->outputs[3].min = prev[3].min; + op->outputs[3].max = prev[3].max; break; case SWS_OP_INVALID: case SWS_OP_TYPE_NB: av_unreachable("Invalid operation type!"); } - prev = op->comps; + memcpy(prev, op->outputs, sizeof(prev)); } /* Backwards pass, solves for output component dependencies */ @@ -551,7 +570,7 @@ void ff_sws_op_list_update_comps(SwsOpList *ops) SwsCompMask need_in[4] = {0}; for (int i = 0; i < 4; i++) { - op->comps.dep_out[i] = need_out[i]; + op->outputs[i].dep_out = need_out[i]; if (!need_out[i]) RESET(i); } @@ -1018,29 +1037,28 @@ void ff_sws_op_list_print(void *log, int lev, int lev_extra, av_log(log, lev, "%s\n", bp->str); for (int i = 0; i < 4; i++) { + const SwsOpPad *pad = &op->outputs[i]; if (!SWS_COMP_TEST(mask, i)) continue; av_bprint_clear(bp); av_bprintf(bp, " %c: %3s,", "XYZW"[i], ff_sws_pixel_type_name(op_result_type(op))); - print_deps(bp, op->comps.dep_in[i]); + print_deps(bp, pad->dep_in); av_bprintf(bp, " ->"); - print_deps(bp, op->comps.dep_out[i]); - av_bprintf(bp, " %7s", describe_comp_flags(op->comps.flags[i])); + print_deps(bp, pad->dep_out); + av_bprintf(bp, " %7s", describe_comp_flags(pad->flags)); - const AVRational64 min = op->comps.min[i]; - const AVRational64 max = op->comps.max[i]; - if (min.den || max.den) { - if (op->comps.flags[i] & SWS_COMP_ZERO) { + if (pad->min.den || pad->max.den) { + if (pad->flags & SWS_COMP_ZERO) { /* don't print any value */ - } else if (op->comps.flags[i] & SWS_COMP_CONST) { + } else if (pad->flags & SWS_COMP_CONST) { av_bprintf(bp, " = "); - av_assert1(ff_cmp_q64(min, max) == 0); - print_q(bp, min); + av_assert1(ff_cmp_q64(pad->min, pad->max) == 0); + print_q(bp, pad->min); } else { av_bprintf(bp, " in ["); - print_q(bp, min); + print_q(bp, pad->min); av_bprintf(bp, ", "); - print_q(bp, max); + print_q(bp, pad->max); av_bprintf(bp, "]"); } } diff --git a/libswscale/ops.h b/libswscale/ops.h index a6dc28621a..35263b9d74 100644 --- a/libswscale/ops.h +++ b/libswscale/ops.h @@ -83,16 +83,16 @@ typedef enum SwsCompFlags { SWS_COMP_CONST = 1 << 5, /* value is a fixed constant */ } SwsCompFlags; -typedef struct SwsComps { - SwsCompFlags flags[4]; /* knowledge about (output) component contents */ +typedef struct SwsOpPad { + SwsCompFlags flags; /* knowledge about (output) component contents */ /* Keeps track of the known possible value range, or {0, 0} for undefined * or (unknown range) floating point inputs */ - AVRational64 min[4], max[4]; + AVRational64 min, max; /* Keeps track of input (forward) and output (reverse) dependencies */ - SwsCompMask dep_in[4], dep_out[4]; -} SwsComps; + SwsCompMask dep_in, dep_out; +} SwsOpPad; typedef enum SwsReadWriteMode { /** @@ -263,10 +263,10 @@ typedef struct SwsOp { * Note that backends may rely on the presence and accuracy of this * metadata for all operations, during ff_sws_ops_compile(). */ - SwsComps comps; + SwsOpPad outputs[4]; } SwsOp; -#define SWS_OP_NEEDED(op, idx) (!((op)->comps.flags[idx] & SWS_COMP_GARBAGE)) +#define SWS_OP_NEEDED(op, idx) (!((op)->outputs[idx].flags & SWS_COMP_GARBAGE)) /* Compute SwsCompMask from a mask of needed components */ SwsCompMask ff_sws_comp_mask_needed(const SwsOp *op); @@ -313,7 +313,7 @@ typedef struct SwsOpList { * The default value of {0} is safe to pass in the case that no additional * information is known. */ - SwsComps comps_src; + SwsOpPad inputs[4]; } SwsOpList; SwsOpList *ff_sws_op_list_alloc(void); diff --git a/libswscale/ops_dispatch.c b/libswscale/ops_dispatch.c index a0d049f616..3177f4b667 100644 --- a/libswscale/ops_dispatch.c +++ b/libswscale/ops_dispatch.c @@ -482,12 +482,12 @@ static void op_list_get_plane_copy(const SwsOpList *ops, SwsPass *pass) const SwsOp *prev = &ops->ops[ops->num_ops - 2]; int *plane_copy = pass->output->plane_copy; for (int i = 0; i < write->rw.elems; i++) { - SwsCompFlags flags = prev->comps.flags[i]; + SwsCompFlags flags = prev->outputs[i].flags; if (!(flags & SWS_COMP_COPY)) continue; const int out_idx = ops->plane_dst[i]; - switch (prev->comps.dep_in[i]) { + switch (prev->outputs[i].dep_in) { case SWS_COMP(0): plane_copy[out_idx] = ops->plane_src[0]; break; case SWS_COMP(1): plane_copy[out_idx] = ops->plane_src[1]; break; case SWS_COMP(2): plane_copy[out_idx] = ops->plane_src[2]; break; @@ -707,7 +707,7 @@ static SwsCompMask plane_mask_flags(const SwsOp *op, SwsCompFlags flags) { SwsCompMask planes = 0; for (int c = 0; c < 4; c++) { - if (op->comps.flags[c] & flags) + if (op->outputs[c].flags & flags) planes |= SWS_COMP(c); } diff --git a/libswscale/ops_optimizer.c b/libswscale/ops_optimizer.c index 77e6d01682..bd1723f053 100644 --- a/libswscale/ops_optimizer.c +++ b/libswscale/ops_optimizer.c @@ -235,7 +235,7 @@ static int exact_log2_q64(const AVRational64 x) * the corresponding scaling factor, or 0 otherwise. */ static bool extract_scalar(const SwsLinearOp *c, - const SwsComps *comps, const SwsComps *prev, + const SwsOpPad outputs[4], const SwsOpPad inputs[4], SwsScaleOp *out_scale) { SwsScaleOp scale = {0}; @@ -246,8 +246,8 @@ static bool extract_scalar(const SwsLinearOp *c, for (int i = 0; i < 4; i++) { const AVRational64 s = c->m[i][i]; - if ((prev->flags[i] & SWS_COMP_ZERO) || - (comps->flags[i] & SWS_COMP_GARBAGE)) + if ((inputs[i].flags & SWS_COMP_ZERO) || + (outputs[i].flags & SWS_COMP_GARBAGE)) continue; if (scale.factor.den && ff_cmp_q64(s, scale.factor)) return false; @@ -260,7 +260,7 @@ static bool extract_scalar(const SwsLinearOp *c, } /* Extracts an integer clear operation (subset) from the given linear op. */ -static bool extract_constant_rows(SwsLinearOp *c, const SwsComps *prev, +static bool extract_constant_rows(SwsLinearOp *c, const SwsOpPad inputs[4], SwsClearOp *out_clear) { const uint32_t mask = ff_sws_linear_mask(c); @@ -271,7 +271,7 @@ static bool extract_constant_rows(SwsLinearOp *c, const SwsComps *prev, bool const_row = c->m[i][4].den == 1; /* offset is integer */ for (int j = 0; j < 4; j++) { const_row &= c->m[i][j].num == 0 || /* scalar is zero */ - (prev->flags[j] & SWS_COMP_ZERO); /* input is zero */ + (inputs[j].flags & SWS_COMP_ZERO); /* input is zero */ } if (const_row && (mask & SWS_MASK_ROW(i))) { clear.mask |= SWS_COMP(i); @@ -289,7 +289,7 @@ static bool extract_constant_rows(SwsLinearOp *c, const SwsComps *prev, /* Unswizzle a linear operation by aligning single-input rows with * their corresponding diagonal */ -static bool extract_swizzle(SwsLinearOp *op, const SwsComps *prev, +static bool extract_swizzle(SwsLinearOp *op, const SwsOpPad inputs[4], SwsSwizzleOp *out_swiz) { SwsSwizzleOp swiz = SWS_SWIZZLE(0, 1, 2, 3); @@ -299,7 +299,7 @@ static bool extract_swizzle(SwsLinearOp *op, const SwsComps *prev, uint32_t nonzero = 0; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { - if (!c.m[i][j].num || (prev->flags[j] & SWS_COMP_ZERO)) + if (!c.m[i][j].num || (inputs[j].flags & SWS_COMP_ZERO)) continue; nonzero |= SWS_MASK(i, j); } @@ -332,7 +332,7 @@ static bool extract_swizzle(SwsLinearOp *op, const SwsComps *prev, static int op_result_is_exact(const SwsOp *op) { for (int i = 0; i < 4; i++) { - if (SWS_OP_NEEDED(op, i) && !(op->comps.flags[i] & SWS_COMP_EXACT)) + if (SWS_OP_NEEDED(op, i) && !(op->outputs[i].flags & SWS_COMP_EXACT)) return false; } @@ -464,8 +464,8 @@ retry: if (!SWS_COMP_TEST(op->clear.mask, i)) continue; - if ((prev->comps.flags[i] & SWS_COMP_ZERO) && - !(prev->comps.flags[i] & SWS_COMP_GARBAGE) && + if ((prev->outputs[i].flags & SWS_COMP_ZERO) && + !(prev->outputs[i].flags & SWS_COMP_GARBAGE) && op->clear.value[i].num == 0) { /* Redundant clear-to-zero of zero component */ @@ -585,7 +585,7 @@ retry: for (int i = 0; i < 4; i++) { if (!SWS_OP_NEEDED(op, i) || !op->clamp.limit[i].den) continue; - if (ff_cmp_q64(op->clamp.limit[i], prev->comps.max[i]) >= 0) + if (ff_cmp_q64(op->clamp.limit[i], prev->outputs[i].max) >= 0) op->clamp.limit[i] = (AVRational64) {0}; /* no-op */ else noop = false; @@ -601,7 +601,7 @@ retry: for (int i = 0; i < 4; i++) { if (!SWS_OP_NEEDED(op, i) || !op->clamp.limit[i].den) continue; - if (ff_cmp_q64(prev->comps.min[i], op->clamp.limit[i]) >= 0) + if (ff_cmp_q64(prev->outputs[i].min, op->clamp.limit[i]) >= 0) op->clamp.limit[i] = (AVRational64) {0}; else noop = false; @@ -617,7 +617,7 @@ retry: for (int i = 0; i < 4; i++) { if (op->dither.y_offset[i] < 0) continue; - if (!SWS_OP_NEEDED(op, i) || (prev->comps.flags[i] & SWS_COMP_EXACT)) { + if (!SWS_OP_NEEDED(op, i) || (prev->outputs[i].flags & SWS_COMP_EXACT)) { op->dither.y_offset[i] = -1; /* unnecessary dither */ goto retry; } else { @@ -664,7 +664,7 @@ retry: /* Optimize away zero columns */ for (int j = 0; j < 4; j++) { const uint32_t col = SWS_MASK_COL(j); - if (!(prev->comps.flags[j] & SWS_COMP_ZERO) || !(mask & col)) + if (!(prev->outputs[j].flags & SWS_COMP_ZERO) || !(mask & col)) continue; for (int i = 0; i < 4; i++) op->lin.m[i][j] = Q(i == j); @@ -682,7 +682,7 @@ retry: } /* Convert constant rows to explicit clear instruction */ - if (extract_constant_rows(&op->lin, &prev->comps, &clear)) { + if (extract_constant_rows(&op->lin, prev->outputs, &clear)) { RET(ff_sws_op_list_insert_at(ops, n + 1, &(SwsOp) { .op = SWS_OP_CLEAR, .type = op->type, @@ -692,14 +692,14 @@ retry: } /* Multiplication by scalar constant */ - if (extract_scalar(&op->lin, &op->comps, &prev->comps, &scale)) { + if (extract_scalar(&op->lin, op->outputs, prev->outputs, &scale)) { op->op = SWS_OP_SCALE; op->scale = scale; goto retry; } /* Swizzle by fixed pattern */ - if (extract_swizzle(&op->lin, &prev->comps, &swizzle)) { + if (extract_swizzle(&op->lin, prev->outputs, &swizzle)) { RET(ff_sws_op_list_insert_at(ops, n, &(SwsOp) { .op = SWS_OP_SWIZZLE, .type = op->type, @@ -1203,9 +1203,9 @@ int ff_sws_op_list_split_at(SwsOpList *ops1, SwsOpList **out_ops2, int index) for (int i = 0; i < nb_planes; i++) { const int idx = swiz_wr.in[i]; ops1->plane_dst[i] = ops2->plane_src[i] = i; - ops2->comps_src.flags[i] = prev->comps.flags[idx]; - ops2->comps_src.min[i] = prev->comps.min[idx]; - ops2->comps_src.max[i] = prev->comps.max[idx]; + ops2->inputs[i].flags = prev->outputs[idx].flags; + ops2->inputs[i].min = prev->outputs[idx].min; + ops2->inputs[i].max = prev->outputs[idx].max; } ff_sws_op_list_remove_at(ops1, index, ops1->num_ops - index); diff --git a/libswscale/uops.c b/libswscale/uops.c index 21396daf70..8d6ad36692 100644 --- a/libswscale/uops.c +++ b/libswscale/uops.c @@ -228,18 +228,15 @@ static bool exact_product_f32(float a, float b) return !b || result == a; } -static bool exact_prod(SwsPixelType type, SwsPixel coef, - const SwsComps *comps, int idx) +static bool exact_prod(SwsPixelType type, SwsPixel coef, const SwsOpPad *input) { - const AVRational64 minq = comps->min[idx]; - const AVRational64 maxq = comps->max[idx]; if (ff_sws_pixel_type_is_int(type)) return true; - else if (!minq.den || !maxq.den) + else if (!input->min.den || !input->max.den) return false; /* unknown bounds */ - const SwsPixel min = ff_sws_pixel_from_q64(type, minq); - const SwsPixel max = ff_sws_pixel_from_q64(type, maxq); + const SwsPixel min = ff_sws_pixel_from_q64(type, input->min); + const SwsPixel max = ff_sws_pixel_from_q64(type, input->max); switch (type) { case SWS_PIXEL_F32: return exact_product_f32(coef.f32, min.f32) && @@ -476,7 +473,7 @@ static int translate_dither_op(SwsUOpList *ops, SwsUOpFlags flags, const SwsOp * static int translate_linear_op(SwsContext *ctx, SwsUOpList *ops, SwsUOpFlags flags, const SwsOp *op, - const SwsComps *input) + const SwsOpPad inputs[4]) { SwsUOp uop = { .type = op->type, @@ -502,7 +499,7 @@ static int translate_linear_op(SwsContext *ctx, SwsUOpList *ops, uop.par.lin.zero |= SWS_MASK(i, j); else if (j < 4 && k.num == k.den) uop.par.lin.one |= SWS_MASK(i, j); - else if (j < 4 && nonzero && (!bitexact || exact_prod(uop.type, px, input, j))) + else if (j < 4 && nonzero && (!bitexact || exact_prod(uop.type, px, &inputs[j]))) exact |= SWS_MASK(i, j); if (k.num != 0) nonzero = true; @@ -519,7 +516,7 @@ static int translate_linear_op(SwsContext *ctx, SwsUOpList *ops, } static int translate_op(SwsContext *ctx, SwsUOpList *uops, SwsUOpFlags flags, - const SwsOp *op, const SwsComps *input) + const SwsOp *op, const SwsOpPad inputs[4]) { switch (op->op) { case SWS_OP_FILTER_H: @@ -533,7 +530,7 @@ static int translate_op(SwsContext *ctx, SwsUOpList *uops, SwsUOpFlags flags, case SWS_OP_DITHER: return translate_dither_op(uops, flags, op); case SWS_OP_LINEAR: - return translate_linear_op(ctx, uops, flags, op, input); + return translate_linear_op(ctx, uops, flags, op, inputs); default: break; } @@ -618,17 +615,17 @@ static int translate_op(SwsContext *ctx, SwsUOpList *uops, SwsUOpFlags flags, int ff_sws_ops_translate(SwsContext *ctx, const SwsOpList *ops, SwsUOpFlags flags, SwsUOpList *uops) { - SwsComps input = ops->comps_src; + const SwsOpPad *inputs = ops->inputs; for (int i = 0; i < ops->num_ops; i++) { const SwsOp *op = &ops->ops[i]; const int pixel_size = ff_sws_pixel_type_size(op->type); if (pixel_size > uops->pixel_size_max) uops->pixel_size_max = pixel_size; - int ret = translate_op(ctx, uops, flags, op, &input); + int ret = translate_op(ctx, uops, flags, op, inputs); if (ret < 0) return ret; - input = ops->ops[i].comps; + inputs = op->outputs; } return ff_sws_uop_list_optimize(ctx, flags, uops); -- To stop receiving notification emails like this one, please contact [email protected]. _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
