On Wed, Aug 28, 2024 at 10:43 PM Ramiro Polla <ramiro.po...@gmail.com> wrote: > > The current code subsamples by dropping 3/4 pixels to calculate the > chroma components. This commit calculates the average of 4 rgb pixels > before calculating the chroma components, putting it in line with the > mmxext implementation. > --- > libswscale/rgb2rgb_template.c | 88 ++++++++++++++++------------------- > 1 file changed, 41 insertions(+), 47 deletions(-)
New patch attached removes another occurrence of the comment about chrominance data only being taken from every second line. It also flips the patch order so this is the first one in the patchset (and therefore checkasm doesn't fail on x86). I'll push the patchset in a couple of days if there are no more comments.
From ef9c957a3e5867a49cd308a3b16aead9994861cf Mon Sep 17 00:00:00 2001 From: Ramiro Polla <ramiro.polla@gmail.com> Date: Wed, 28 Aug 2024 19:51:55 +0200 Subject: [PATCH v3 1/4] swscale/rgb2rgb: improve chroma conversion in ff_rgb24toyv12_c The current code subsamples by dropping 3/4 pixels to calculate the chroma components. This commit calculates the average of 4 rgb pixels before calculating the chroma components, putting it in line with the mmxext implementation. --- libswscale/rgb2rgb.h | 2 - libswscale/rgb2rgb_template.c | 88 ++++++++++++++++------------------- 2 files changed, 41 insertions(+), 49 deletions(-) diff --git a/libswscale/rgb2rgb.h b/libswscale/rgb2rgb.h index f3951d523e..e3b0883901 100644 --- a/libswscale/rgb2rgb.h +++ b/libswscale/rgb2rgb.h @@ -121,8 +121,6 @@ extern void (*yuv422ptouyvy)(const uint8_t *ysrc, const uint8_t *usrc, const uin /** * Height should be a multiple of 2 and width should be a multiple of 2. * (If this is a problem for anyone then tell me, and I will fix it.) - * Chrominance data is only taken from every second line, others are ignored. - * FIXME: Write high quality version. */ extern void (*ff_rgb24toyv12)(const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t *vdst, int width, int height, diff --git a/libswscale/rgb2rgb_template.c b/libswscale/rgb2rgb_template.c index 42c69801ba..32d90d44fe 100644 --- a/libswscale/rgb2rgb_template.c +++ b/libswscale/rgb2rgb_template.c @@ -642,9 +642,6 @@ static inline void uyvytoyv12_c(const uint8_t *src, uint8_t *ydst, /** * Height should be a multiple of 2 and width should be a multiple of 2. * (If this is a problem for anyone then tell me, and I will fix it.) - * Chrominance data is only taken from every second line, - * others are ignored in the C version. - * FIXME: Write HQ version. */ void ff_rgb24toyv12_c(const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t *vdst, int width, int height, int lumStride, @@ -655,55 +652,52 @@ void ff_rgb24toyv12_c(const uint8_t *src, uint8_t *ydst, uint8_t *udst, int32_t rv = rgb2yuv[RV_IDX], gv = rgb2yuv[GV_IDX], bv = rgb2yuv[BV_IDX]; int y; const int chromWidth = width >> 1; + const uint8_t *src1 = src; + const uint8_t *src2 = src1 + srcStride; + uint8_t *ydst1 = ydst; + uint8_t *ydst2 = ydst + lumStride; for (y = 0; y < height; y += 2) { int i; for (i = 0; i < chromWidth; i++) { - unsigned int b = src[6 * i + 0]; - unsigned int g = src[6 * i + 1]; - unsigned int r = src[6 * i + 2]; - - unsigned int Y = ((ry * r + gy * g + by * b) >> RGB2YUV_SHIFT) + 16; - unsigned int V = ((rv * r + gv * g + bv * b) >> RGB2YUV_SHIFT) + 128; - unsigned int U = ((ru * r + gu * g + bu * b) >> RGB2YUV_SHIFT) + 128; - - udst[i] = U; - vdst[i] = V; - ydst[2 * i] = Y; - - b = src[6 * i + 3]; - g = src[6 * i + 4]; - r = src[6 * i + 5]; - - Y = ((ry * r + gy * g + by * b) >> RGB2YUV_SHIFT) + 16; - ydst[2 * i + 1] = Y; + unsigned int b11 = src1[6 * i + 0]; + unsigned int g11 = src1[6 * i + 1]; + unsigned int r11 = src1[6 * i + 2]; + unsigned int b12 = src1[6 * i + 3]; + unsigned int g12 = src1[6 * i + 4]; + unsigned int r12 = src1[6 * i + 5]; + unsigned int b21 = src2[6 * i + 0]; + unsigned int g21 = src2[6 * i + 1]; + unsigned int r21 = src2[6 * i + 2]; + unsigned int b22 = src2[6 * i + 3]; + unsigned int g22 = src2[6 * i + 4]; + unsigned int r22 = src2[6 * i + 5]; + + unsigned int Y11 = ((ry * r11 + gy * g11 + by * b11) >> RGB2YUV_SHIFT) + 16; + unsigned int Y12 = ((ry * r12 + gy * g12 + by * b12) >> RGB2YUV_SHIFT) + 16; + unsigned int Y21 = ((ry * r21 + gy * g21 + by * b21) >> RGB2YUV_SHIFT) + 16; + unsigned int Y22 = ((ry * r22 + gy * g22 + by * b22) >> RGB2YUV_SHIFT) + 16; + + unsigned int bx = (b11 + b12 + b21 + b22) >> 2; + unsigned int gx = (g11 + g12 + g21 + g22) >> 2; + unsigned int rx = (r11 + r12 + r21 + r22) >> 2; + + unsigned int U = ((ru * rx + gu * gx + bu * bx) >> RGB2YUV_SHIFT) + 128; + unsigned int V = ((rv * rx + gv * gx + bv * bx) >> RGB2YUV_SHIFT) + 128; + + ydst1[2 * i + 0] = Y11; + ydst1[2 * i + 1] = Y12; + ydst2[2 * i + 0] = Y21; + ydst2[2 * i + 1] = Y22; + udst[i] = U; + vdst[i] = V; } - ydst += lumStride; - src += srcStride; - - if (y+1 == height) - break; - - for (i = 0; i < chromWidth; i++) { - unsigned int b = src[6 * i + 0]; - unsigned int g = src[6 * i + 1]; - unsigned int r = src[6 * i + 2]; - - unsigned int Y = ((ry * r + gy * g + by * b) >> RGB2YUV_SHIFT) + 16; - - ydst[2 * i] = Y; - - b = src[6 * i + 3]; - g = src[6 * i + 4]; - r = src[6 * i + 5]; - - Y = ((ry * r + gy * g + by * b) >> RGB2YUV_SHIFT) + 16; - ydst[2 * i + 1] = Y; - } - udst += chromStride; - vdst += chromStride; - ydst += lumStride; - src += srcStride; + src1 += srcStride * 2; + src2 += srcStride * 2; + ydst1 += lumStride * 2; + ydst2 += lumStride * 2; + udst += chromStride; + vdst += chromStride; } } -- 2.30.2
_______________________________________________ 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".