diff --git a/libswscale/ops_optimizer.c b/libswscale/ops_optimizer.c index bcdeb19be5..5319a954df 100644 --- a/libswscale/ops_optimizer.c +++ b/libswscale/ops_optimizer.c @@ -405,6 +405,34 @@ retry: ff_sws_op_list_remove_at(ops, n + 1, 1); goto retry; } + + /* Swizzle planes instead of components, if possible */ + if (prev->op == SWS_OP_READ && !prev->rw.packed) { + for (int dst = 0; dst < prev->rw.elems; dst++) { + const int src = op->swizzle.in[dst]; + if (src > dst && src < prev->rw.elems) { + FFSWAP(int, ops->order_src.in[dst], ops->order_src.in[src]); + for (int i = dst; i < 4; i++) { + if (op->swizzle.in[i] == dst) + op->swizzle.in[i] = src; + else if (op->swizzle.in[i] == src) + op->swizzle.in[i] = dst; + } + goto retry; + } + } + } + + if (next->op == SWS_OP_WRITE && !next->rw.packed) { + for (int dst = 0; dst < next->rw.elems; dst++) { + const int src = op->swizzle.in[dst]; + if (src > dst && src < next->rw.elems) { + FFSWAP(int, ops->order_dst.in[dst], ops->order_dst.in[src]); + FFSWAP(int, op->swizzle.in[dst], op->swizzle.in[src]); + goto retry; + } + } + } break; case SWS_OP_CONVERT: diff --git a/tests/ref/fate/sws-ops-list b/tests/ref/fate/sws-ops-list index b69b1ab299..429b46b371 100644 --- a/tests/ref/fate/sws-ops-list +++ b/tests/ref/fate/sws-ops-list @@ -1 +1 @@ -8312bc72ff9e05a8a6ab8d1c394783d6 +30ceeaa73f093642f28c1f17b3ee4e3e