This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit 8e362b7b51e7f9491be982d2238b06f904e51021 Author: Kacper Michajłow <[email protected]> AuthorDate: Sun Oct 25 06:03:38 2026 +0100 Commit: Kacper Michajłow <[email protected]> CommitDate: Wed Oct 28 19:22:28 2026 +0000 swscale: scale X'Y'Z' to X'Y'Z' on the codes A scaled conversion between two XYZ formats decoded the codes into gamma 2.2 RGB, scaled that and encoded it back, which quantizes twice and clips every color outside the BT.709 gamut. Scale the codes like those of an RGB format instead, as the unscaled conversion already did, and round the result to 12 bits, which keeps the 4 padding bits zero. The slice contexts of the graph take the XYZ flags of their parent for that. Signed-off-by: Kacper Michajłow <[email protected]> --- libswscale/graph.c | 8 +++++--- libswscale/swscale.c | 26 ++++++++++++++++++++++++-- tests/ref/fate/filter-pixfmts-scale | 4 ++-- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/libswscale/graph.c b/libswscale/graph.c index cc8e5cf7a2..e9ee32052a 100644 --- a/libswscale/graph.c +++ b/libswscale/graph.c @@ -450,7 +450,6 @@ static int init_legacy_subpass(SwsGraph *graph, SwsContext *sws, SwsInternal *c = sws_internal(sws); const int src_w = sws->src_w, src_h = sws->src_h; const int dst_w = sws->dst_w, dst_h = sws->dst_h; - const int unscaled = src_w == dst_w && src_h == dst_h; int align = c->dst_slice_align; SwsPass *pass = NULL; int ret; @@ -485,7 +484,7 @@ static int init_legacy_subpass(SwsGraph *graph, SwsContext *sws, } } - if (c->srcXYZ && !(c->dstXYZ && unscaled)) { + if (c->srcXYZ && !c->dstXYZ) { ret = ff_sws_graph_add_pass(graph, AV_PIX_FMT_RGB48, src_w, src_h, input, 0, 1, run_xyz2rgb, NULL, c, NULL, &input); if (ret < 0) { @@ -541,10 +540,13 @@ static int init_legacy_subpass(SwsGraph *graph, SwsContext *sws, c2->srcColorspaceTable[i] = c->srcColorspaceTable[i]; c2->dstColorspaceTable[i] = c->dstColorspaceTable[i]; } + + c2->srcXYZ = c->srcXYZ; + c2->dstXYZ = c->dstXYZ; } } - if (c->dstXYZ && !(c->srcXYZ && unscaled)) { + if (c->dstXYZ && !c->srcXYZ) { ret = ff_sws_graph_add_pass(graph, AV_PIX_FMT_RGB48, dst_w, dst_h, pass, 0, 1, run_rgb2xyz, NULL, c, NULL, &pass); if (ret < 0) diff --git a/libswscale/swscale.c b/libswscale/swscale.c index 3b2c63cff0..0ba3458b6d 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -254,6 +254,23 @@ static void lumRangeFromJpeg16_c(int16_t *_dst, int width, dst[i] = ((int64_t) dst[i] * coeff + offset) >> 18; } +static void round_xyz12(uint8_t *plane, int stride, int width, int height, int y, + int big_endian) +{ + uint8_t *ptr = plane + stride * y; + for (int i = 0; i < height; i++) { + for (int j = 0; j < 3 * width; j++) { + unsigned v = big_endian ? AV_RB16(ptr + 2 * j) : AV_RL16(ptr + 2 * j); + v = FFMIN(v + 8, UINT16_MAX) & 0xFFF0; + if (big_endian) + AV_WB16(ptr + 2 * j, v); + else + AV_WL16(ptr + 2 * j, v); + } + ptr += stride; + } +} + #define DEBUG_SWSCALE_BUFFERS 0 #define DEBUG_BUFFERS(...) \ @@ -552,6 +569,11 @@ int ff_swscale(SwsInternal *c, const uint8_t *const src[], const int srcStride[] fillPlane(dst[3], dstStride[3], length, height, offset, 255); } + /* XYZ is scaled on its codes like 16-bit RGB */ + if (c->srcXYZ && c->dstXYZ) + round_xyz12(dst[0], dstStride[0], dstW, dstY - lastDstY, lastDstY - dstSliceY, + isBE(dstFormat)); + #if HAVE_MMXEXT_INLINE if (av_get_cpu_flags() & AV_CPU_FLAG_MMXEXT) __asm__ volatile ("sfence" ::: "memory"); @@ -1123,7 +1145,7 @@ static int scale_internal(SwsContext *sws, src2[0] = base; } - if (c->srcXYZ && !(c->dstXYZ && sws->src_w==sws->dst_w && sws->src_h==sws->dst_h)) { + if (c->srcXYZ && !c->dstXYZ) { uint8_t *base; av_fast_malloc(&c->xyz_scratch, &c->xyz_scratch_allocated, @@ -1191,7 +1213,7 @@ static int scale_internal(SwsContext *sws, dst2, dstStride2, dstSliceY, dstSliceH); } - if (c->dstXYZ && !(c->srcXYZ && sws->src_w==sws->dst_w && sws->src_h==sws->dst_h)) { + if (c->dstXYZ && !c->srcXYZ) { uint8_t *dst; if (scale_dst) { diff --git a/tests/ref/fate/filter-pixfmts-scale b/tests/ref/fate/filter-pixfmts-scale index 3a7b34ad96..900227f7c3 100644 --- a/tests/ref/fate/filter-pixfmts-scale +++ b/tests/ref/fate/filter-pixfmts-scale @@ -117,8 +117,8 @@ xv36be 4d084adca0228d7750d1e2e877e0d79b xv36le de9c74e94dc19c828e1572aa283d8aca xv48be 9e58d1a045df100b0dec116e13be5b4e xv48le fd873d53609b2fbdfe99470f515a234c -xyz12be 0866f8e5493ea93f4523a9e873a14b1e -xyz12le d6990efe1c7141227054cbcda28ea6fb +xyz12be 5390b76c745f71cbd6db031bd424c941 +xyz12le aba95a389ce26cb603ffe4072d1791d9 y210le 7c2aef142d88ab343ec01acd45f38466 y212le 39a3c0c843041ad4501b3107dd91ef17 y216le 17be2999e97d36b8ed903f07ef428c09 -- 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]
