This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit 291e849ee3938e70002bdea422cd99544358255b Author: Niklas Haas <[email protected]> AuthorDate: Thu Jun 18 13:27:09 2026 +0200 Commit: Niklas Haas <[email protected]> CommitDate: Tue Jun 23 11:48:13 2026 +0000 swscale/ops_optimizer: add ff_sws_op_list_split_planes() Can be used to extract a reduced subset of operations affecting only certain output planes, e.g. splitting an op list into a "memcpy" and a "non-memcpy" part, or splitting apart op lists for independent or subsampled planes. Sponsored-by: Sovereign Tech Fund Signed-off-by: Niklas Haas <[email protected]> --- libswscale/ops_internal.h | 13 ++++++++++ libswscale/ops_optimizer.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/libswscale/ops_internal.h b/libswscale/ops_internal.h index f1da34a272..54c79ba67a 100644 --- a/libswscale/ops_internal.h +++ b/libswscale/ops_internal.h @@ -97,4 +97,17 @@ int ff_sws_solve_shuffle(const SwsOpList *ops, uint8_t shuffle[], int size, */ int ff_sws_op_list_split_at(SwsOpList *ops1, SwsOpList **ops2, int index); +/** + * Reduce an op list into a reduced subset that operates only on a given + * subset of planes. No effect if the output is not planar, or if the plane + * mask is empty or equal to all planes. + * + * @param ops1 Updated in-place to contain only the selected planes. + * @param ops2 The removed remainder is returned here, or NULL if no-op. + * @param planes A mask of the plane indices to keep. + * + * Returns 0 or a negative error code. + */ +int ff_sws_op_list_split_planes(SwsOpList *ops1, SwsOpList **ops2, SwsCompMask planes); + #endif /* SWSCALE_OPS_INTERNAL_H */ diff --git a/libswscale/ops_optimizer.c b/libswscale/ops_optimizer.c index ebb9fa026f..34d2c9eccc 100644 --- a/libswscale/ops_optimizer.c +++ b/libswscale/ops_optimizer.c @@ -808,6 +808,68 @@ retry: return 0; } +static int select_planes(SwsOpList *ops, SwsCompMask planes) +{ + SwsSwizzleOp swiz = SWS_SWIZZLE(0, 1, 2, 3); + SwsOp *write = &ops->ops[ops->num_ops - 1]; + av_assert0(write->op == SWS_OP_WRITE); + + write->rw.elems = 0; + for (int src = 0; src < 4; src++) { + if (!SWS_COMP_TEST(planes, src)) + continue; /* plane not selected */ + const int dst = write->rw.elems++; + av_assert2(src >= dst); + swiz.in[dst] = src; + FFSWAP(int, ops->plane_dst[dst], ops->plane_dst[src]); + } + + /* Insert swizzle to select desired planes */ + int ret = ff_sws_op_list_insert_at(ops, ops->num_ops - 1, &(SwsOp) { + .op = SWS_OP_SWIZZLE, + .type = write->type, + .swizzle = swiz, + }); + if (ret < 0) + return ret; + + /* The optimizer will take care of the rest */ + return ff_sws_op_list_optimize(ops); +} + +int ff_sws_op_list_split_planes(SwsOpList *ops1, SwsOpList **out_ops2, SwsCompMask planes) +{ + const SwsOp *write = ff_sws_op_list_output(ops1); + if (!write || write->rw.mode != SWS_RW_PLANAR) { + *out_ops2 = NULL; + return 0; + } + + const SwsCompMask full = SWS_COMP_ELEMS(write->rw.elems); + const SwsCompMask mask1 = planes & full; + const SwsCompMask mask2 = full ^ mask1; + if (!mask1 || !mask2) { + /* Nothing to filter */ + *out_ops2 = NULL; + return 0; + } + + SwsOpList *ops2 = ff_sws_op_list_duplicate(ops1); + if (!ops2) + return AVERROR(ENOMEM); + + int ret; + if ((ret = select_planes(ops1, mask1)) < 0 || + (ret = select_planes(ops2, mask2)) < 0) + { + ff_sws_op_list_free(&ops2); + return ret; + } + + *out_ops2 = ops2; + return 0; +} + int ff_sws_solve_shuffle(const SwsOpList *const ops, uint8_t shuffle[], int size, uint8_t clear_val, int *read_bytes, int *write_bytes) _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
