On Thu, 19 Dec 2024 22:34:05 -0300 James Almer <jamr...@gmail.com> wrote: > On 12/18/2024 11:24 AM, Niklas Haas wrote: > > From: Niklas Haas <g...@haasn.dev> > > > > Fixes: ticket #9520 > > Signed-off-by: Niklas Haas <g...@haasn.dev> > > Sponsored-by: Sovereign Tech Fund > > --- > > libswscale/swscale.c | 2 + > > libswscale/swscale_unscaled.c | 81 ++++++++++++++++++++++++++++++++++- > > 2 files changed, 81 insertions(+), 2 deletions(-) > > > > diff --git a/libswscale/swscale.c b/libswscale/swscale.c > > index 96634acfd6..bd5b6370db 100644 > > --- a/libswscale/swscale.c > > +++ b/libswscale/swscale.c > > @@ -910,6 +910,8 @@ void ff_update_palette(SwsInternal *c, const uint32_t > > *pal) > > case AV_PIX_FMT_BGR32_1: > > #if HAVE_BIGENDIAN > > case AV_PIX_FMT_BGR24: > > + case AV_PIX_FMT_BGRP: > > + case AV_PIX_FMT_BGRAP: > > These don't exist. And GBRP/GBRAP would need c->pal_rgb to be ordered in > a different way.
Simply fixing BGRP -> GBRP should make it work; in theory. > > > #endif > > c->pal_rgb[i]= a + (r<<8) + (g<<16) + ((unsigned)b<<24); > > break; > > diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c > > index c7ad6b014a..973ffe0299 100644 > > --- a/libswscale/swscale_unscaled.c > > +++ b/libswscale/swscale_unscaled.c > > @@ -509,6 +509,34 @@ static void gray8aToPacked24(const uint8_t *src, > > uint8_t *dst, int num_pixels, > > } > > } > > > > +static void gray8aToPlanar8(const uint8_t *src, uint8_t *dstG, uint8_t > > *dstB, > > + uint8_t *dstR, uint8_t *dstA, int num_pixels, > > + const uint8_t *palette) > > +{ > > + for (int i = 0; i < num_pixels; i++) { > > + const uint8_t *rgb = &palette[src[i << 1] * 4]; > > + dstB[i] = rgb[0]; > > + dstG[i] = rgb[1]; > > + dstR[i] = rgb[2]; > > + if (dstA) > > + dstA[i] = src[(i << 1) + 1]; > > + } > > +} > > + > > +static void pal8ToPlanar8(const uint8_t *src, uint8_t *dstG, uint8_t *dstB, > > + uint8_t *dstR, uint8_t *dstA, int num_pixels, > > + const uint8_t *palette) > > +{ > > + for (int i = 0; i < num_pixels; i++) { > > + const uint8_t *rgba = &palette[src[i] * 4]; > > Does this work in both big and little endian? c->pal_rgb is uint32_t, > and ff_update_palette() sets it in a native endian way. Yes. For little endian, we hit the default branch: c->pal_rgb[i]= b + (g<<8) + (r<<16) + ((unsigned)a<<24); And this is also the order that pal8ToPlanar8 accesses the values in. But in retrospect, I find this a bit confusing. I'll change it to use GBRA order instead, matching the plane order. > > + dstB[i] = rgba[0]; > > + dstG[i] = rgba[1]; > > + dstR[i] = rgba[2]; > > + if (dstA) > > + dstA[i] = rgba[3]; > > + } > > +} > > + > > static int bswap_16bpc(SwsInternal *c, const uint8_t *const src[], > > const int srcStride[], int srcSliceY, int > > srcSliceH, > > uint8_t *const dst[], const int dstStride[]) > > @@ -610,6 +638,45 @@ static int palToRgbWrapper(SwsInternal *c, const > > uint8_t *const src[], const int > > return srcSliceH; > > } > > > > +static int palToGbrpWrapper(SwsInternal *c, const uint8_t *const src[], > > + const int srcStride[], int srcSliceY, int > > srcSliceH, > > + uint8_t *const dst[], const int dstStride[]) > > +{ > > + const enum AVPixelFormat srcFormat = c->opts.src_format; > > + const enum AVPixelFormat dstFormat = c->opts.dst_format; > > + void (*conv)(const uint8_t *src, uint8_t *dstG, uint8_t *dstB, uint8_t > > *dstR, > > + uint8_t *dstA, int num_pixels, const uint8_t *palette) = > > NULL; > > + > > + const int num_planes = isALPHA(dstFormat) ? 4 : 3; > > + const uint8_t *srcPtr = src[0]; > > + uint8_t *dstPtr[4] = {0}; > > + for (int i = 0; i < num_planes; i++) > > + dstPtr[i] = dst[i] + dstStride[i] * srcSliceY; > > + > > + if (srcFormat == AV_PIX_FMT_YA8) { > > + switch (dstFormat) { > > + case AV_PIX_FMT_GBRP: conv = gray8aToPlanar8; break; > > + case AV_PIX_FMT_GBRAP: conv = gray8aToPlanar8; break; > > + } > > + } else if (usePal(srcFormat)) { > > + switch (dstFormat) { > > + case AV_PIX_FMT_GBRP: conv = pal8ToPlanar8; break; > > + case AV_PIX_FMT_GBRAP: conv = pal8ToPlanar8; break; > > + } > > + } > > + > > + av_assert1(conv); > > + for (int y = 0; y < srcSliceH; y++) { > > + conv(srcPtr, dstPtr[0], dstPtr[1], dstPtr[2], dstPtr[3], > > c->opts.src_w, > > + (uint8_t *) c->pal_rgb); > > + srcPtr += srcStride[0]; > > + for (int i = 0; i < num_planes; i++) > > + dstPtr[i] += dstStride[i]; > > + } > > + > > + return srcSliceH; > > +} > > + > > static void packed16togbra16(const uint8_t *src, int srcStride, > > uint16_t *dst[], const int dstStride[], int > > srcSliceH, > > int src_alpha, int swap, int shift, int > > width) > > @@ -2529,8 +2596,18 @@ void ff_get_unscaled_swscale(SwsInternal *c) > > IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRAPF32)) > > c->convert_unscaled = bswap_32bpc; > > > > - if (usePal(srcFormat) && isByteRGB(dstFormat)) > > - c->convert_unscaled = palToRgbWrapper; > > + if (usePal(srcFormat)) { > > + switch (dstFormat) { > > + case AV_PIX_FMT_GBRP: > > + case AV_PIX_FMT_GBRAP: > > + c->convert_unscaled = palToGbrpWrapper; > > + break; > > + default: > > + if (isByteRGB(dstFormat)) > > + c->convert_unscaled = palToRgbWrapper; > > + break; > > + } > > + } > > > > if (srcFormat == AV_PIX_FMT_YUV422P) { > > if (dstFormat == AV_PIX_FMT_YUYV422) > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".