[FFmpeg-devel] [PATCH] swscale: RGBA64 output (broken)
Paul B Mahol
onemda at gmail.com
Mon Feb 25 13:14:57 CET 2013
Signed-off-by: Paul B Mahol <onemda at gmail.com>
---
libswscale/output.c | 188 +++++++++++++++++++++++++++++++++++++++++++++++++++
libswscale/utils.c | 4 +-
libswscale/yuv2rgb.c | 50 ++++++++++++++
3 files changed, 240 insertions(+), 2 deletions(-)
diff --git a/libswscale/output.c b/libswscale/output.c
index d9745fb..f91f254 100644
--- a/libswscale/output.c
+++ b/libswscale/output.c
@@ -674,6 +674,182 @@ YUV2PACKEDWRAPPER(yuv2, 422, uyvy422, AV_PIX_FMT_UYVY422)
}
static av_always_inline void
+yuv2rgba64_X_c_template(SwsContext *c, const int16_t *lumFilter,
+ const int32_t **lumSrc, int lumFilterSize,
+ const int16_t *chrFilter, const int32_t **chrUSrc,
+ const int32_t **chrVSrc, int chrFilterSize,
+ const int32_t **alpSrc, uint16_t *dest, int dstW,
+ int y, enum AVPixelFormat target)
+{
+ int i;
+
+ for (i = 0; i < ((dstW + 1) >> 1); i++) {
+ int j;
+ int Y1 = -0x40000000;
+ int Y2 = -0x40000000;
+ int U = -128 << 23; // 19
+ int V = -128 << 23;
+ int R, G, B, A;
+
+ for (j = 0; j < lumFilterSize; j++) {
+ Y1 += lumSrc[j][i * 2] * (unsigned)lumFilter[j];
+ Y2 += lumSrc[j][i * 2 + 1] * (unsigned)lumFilter[j];
+ }
+ for (j = 0; j < chrFilterSize; j++) {;
+ U += chrUSrc[j][i] * (unsigned)chrFilter[j];
+ V += chrVSrc[j][i] * (unsigned)chrFilter[j];
+ }
+
+ // 8bit: 12+15=27; 16-bit: 12+19=31
+ Y1 >>= 14; // 10
+ Y1 += 0x10000;
+ Y2 >>= 14;
+ Y2 += 0x10000;
+ U >>= 14;
+ V >>= 14;
+
+ // 8bit: 27 -> 17bit, 16bit: 31 - 14 = 17bit
+ Y1 -= c->yuv2rgb_y_offset;
+ Y2 -= c->yuv2rgb_y_offset;
+ Y1 *= c->yuv2rgb_y_coeff;
+ Y2 *= c->yuv2rgb_y_coeff;
+ Y1 += 1 << 13; // 21
+ Y2 += 1 << 13;
+ // 8bit: 17 + 13bit = 30bit, 16bit: 17 + 13bit = 30bit
+
+ R = V * c->yuv2rgb_v2r_coeff;
+ G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
+ B = U * c->yuv2rgb_u2b_coeff;
+
+ // 8bit: 30 - 22 = 8bit, 16bit: 30bit - 14 = 16bit
+ output_pixel(&dest[0], av_clip_uintp2(B_R + Y1, 30) >> 14);
+ output_pixel(&dest[1], av_clip_uintp2( G + Y1, 30) >> 14);
+ output_pixel(&dest[2], av_clip_uintp2(R_B + Y1, 30) >> 14);
+ output_pixel(&dest[3], av_clip_uintp2(B_R + Y2, 30) >> 14);
+ output_pixel(&dest[4], av_clip_uintp2(B_R + Y2, 30) >> 14);
+ output_pixel(&dest[5], av_clip_uintp2( G + Y2, 30) >> 14);
+ output_pixel(&dest[6], av_clip_uintp2(R_B + Y2, 30) >> 14);
+ output_pixel(&dest[7], av_clip_uintp2(B_R + Y2, 30) >> 14);
+ dest += 8;
+ }
+}
+
+static av_always_inline void
+yuv2rgba64_2_c_template(SwsContext *c, const int32_t *buf[2],
+ const int32_t *ubuf[2], const int32_t *vbuf[2],
+ const int32_t *abuf[2], uint16_t *dest, int dstW,
+ int yalpha, int uvalpha, int y,
+ enum AVPixelFormat target)
+{
+ const int32_t *buf0 = buf[0], *buf1 = buf[1],
+ *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
+ *vbuf0 = vbuf[0], *vbuf1 = vbuf[1];
+ int yalpha1 = 4096 - yalpha;
+ int uvalpha1 = 4096 - uvalpha;
+ int i;
+
+ for (i = 0; i < ((dstW + 1) >> 1); i++) {
+ int Y1 = (buf0[i * 2] * yalpha1 + buf1[i * 2] * yalpha) >> 14;
+ int Y2 = (buf0[i * 2 + 1] * yalpha1 + buf1[i * 2 + 1] * yalpha) >> 14;
+ int U = (ubuf0[i] * uvalpha1 + ubuf1[i] * uvalpha + (-128 << 23)) >> 14;
+ int V = (vbuf0[i] * uvalpha1 + vbuf1[i] * uvalpha + (-128 << 23)) >> 14;
+ int R, G, B;
+
+ Y1 -= c->yuv2rgb_y_offset;
+ Y2 -= c->yuv2rgb_y_offset;
+ Y1 *= c->yuv2rgb_y_coeff;
+ Y2 *= c->yuv2rgb_y_coeff;
+ Y1 += 1 << 13;
+ Y2 += 1 << 13;
+
+ R = V * c->yuv2rgb_v2r_coeff;
+ G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
+ B = U * c->yuv2rgb_u2b_coeff;
+
+ output_pixel(&dest[0], av_clip_uintp2(B_R + Y1, 30) >> 14);
+ output_pixel(&dest[1], av_clip_uintp2( G + Y1, 30) >> 14);
+ output_pixel(&dest[2], av_clip_uintp2(R_B + Y1, 30) >> 14);
+ output_pixel(&dest[3], av_clip_uintp2(B_R + Y2, 30) >> 14);
+ output_pixel(&dest[4], av_clip_uintp2(B_R + Y2, 30) >> 14);
+ output_pixel(&dest[5], av_clip_uintp2( G + Y2, 30) >> 14);
+ output_pixel(&dest[6], av_clip_uintp2(R_B + Y2, 30) >> 14);
+ output_pixel(&dest[7], av_clip_uintp2(B_R + Y2, 30) >> 14);
+ dest += 8;
+ }
+}
+
+static av_always_inline void
+yuv2rgba64_1_c_template(SwsContext *c, const int32_t *buf0,
+ const int32_t *ubuf[2], const int32_t *vbuf[2],
+ const int32_t *abuf0, uint16_t *dest, int dstW,
+ int uvalpha, int y, enum AVPixelFormat target)
+{
+ const int32_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0];
+ int i;
+
+ if (uvalpha < 2048) {
+ for (i = 0; i < ((dstW + 1) >> 1); i++) {
+ int Y1 = (buf0[i * 2] ) >> 2;
+ int Y2 = (buf0[i * 2 + 1]) >> 2;
+ int U = (ubuf0[i] + (-128 << 11)) >> 2;
+ int V = (vbuf0[i] + (-128 << 11)) >> 2;
+ int R, G, B;
+
+ Y1 -= c->yuv2rgb_y_offset;
+ Y2 -= c->yuv2rgb_y_offset;
+ Y1 *= c->yuv2rgb_y_coeff;
+ Y2 *= c->yuv2rgb_y_coeff;
+ Y1 += 1 << 13;
+ Y2 += 1 << 13;
+
+ R = V * c->yuv2rgb_v2r_coeff;
+ G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
+ B = U * c->yuv2rgb_u2b_coeff;
+
+ output_pixel(&dest[0], av_clip_uintp2(B_R + Y1, 30) >> 14);
+ output_pixel(&dest[1], av_clip_uintp2( G + Y1, 30) >> 14);
+ output_pixel(&dest[2], av_clip_uintp2(R_B + Y1, 30) >> 14);
+ output_pixel(&dest[3], av_clip_uintp2(B_R + Y2, 30) >> 14);
+ output_pixel(&dest[4], av_clip_uintp2(B_R + Y2, 30) >> 14);
+ output_pixel(&dest[5], av_clip_uintp2( G + Y2, 30) >> 14);
+ output_pixel(&dest[6], av_clip_uintp2(R_B + Y2, 30) >> 14);
+ output_pixel(&dest[7], av_clip_uintp2(B_R + Y2, 30) >> 14);
+ dest += 8;
+ }
+ } else {
+ const int32_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1];
+ for (i = 0; i < ((dstW + 1) >> 1); i++) {
+ int Y1 = (buf0[i * 2] ) >> 2;
+ int Y2 = (buf0[i * 2 + 1]) >> 2;
+ int U = (ubuf0[i] + ubuf1[i] + (-128 << 12)) >> 3;
+ int V = (vbuf0[i] + vbuf1[i] + (-128 << 12)) >> 3;
+ int R, G, B;
+
+ Y1 -= c->yuv2rgb_y_offset;
+ Y2 -= c->yuv2rgb_y_offset;
+ Y1 *= c->yuv2rgb_y_coeff;
+ Y2 *= c->yuv2rgb_y_coeff;
+ Y1 += 1 << 13;
+ Y2 += 1 << 13;
+
+ R = V * c->yuv2rgb_v2r_coeff;
+ G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
+ B = U * c->yuv2rgb_u2b_coeff;
+
+ output_pixel(&dest[0], av_clip_uintp2(B_R + Y1, 30) >> 14);
+ output_pixel(&dest[1], av_clip_uintp2( G + Y1, 30) >> 14);
+ output_pixel(&dest[2], av_clip_uintp2(R_B + Y1, 30) >> 14);
+ output_pixel(&dest[3], av_clip_uintp2(B_R + Y2, 30) >> 14);
+ output_pixel(&dest[4], av_clip_uintp2(B_R + Y2, 30) >> 14);
+ output_pixel(&dest[5], av_clip_uintp2( G + Y2, 30) >> 14);
+ output_pixel(&dest[6], av_clip_uintp2(R_B + Y2, 30) >> 14);
+ output_pixel(&dest[7], av_clip_uintp2(B_R + Y2, 30) >> 14);
+ dest += 8;
+ }
+ }
+}
+
+static av_always_inline void
yuv2rgb48_X_c_template(SwsContext *c, const int16_t *lumFilter,
const int32_t **lumSrc, int lumFilterSize,
const int16_t *chrFilter, const int32_t **chrUSrc,
@@ -895,6 +1071,8 @@ YUV2PACKED16WRAPPER(yuv2, rgb48, rgb48be, AV_PIX_FMT_RGB48BE)
YUV2PACKED16WRAPPER(yuv2, rgb48, rgb48le, AV_PIX_FMT_RGB48LE)
YUV2PACKED16WRAPPER(yuv2, rgb48, bgr48be, AV_PIX_FMT_BGR48BE)
YUV2PACKED16WRAPPER(yuv2, rgb48, bgr48le, AV_PIX_FMT_BGR48LE)
+YUV2PACKED16WRAPPER(yuv2, rgba64, rgba64be, AV_PIX_FMT_RGBA64BE)
+YUV2PACKED16WRAPPER(yuv2, rgba64, rgba64le, AV_PIX_FMT_RGBA64LE)
/*
* Write out 2 RGB pixels in the target pixel format. This function takes a
@@ -1581,6 +1759,16 @@ av_cold void ff_sws_init_output_funcs(SwsContext *c,
} else {
YUV_PACKED:
switch (dstFormat) {
+ case AV_PIX_FMT_RGBA64LE:
+ *yuv2packed1 = yuv2rgba64le_1_c;
+ *yuv2packed2 = yuv2rgba64le_2_c;
+ *yuv2packedX = yuv2rgba64le_X_c;
+ break;
+ case AV_PIX_FMT_RGBA64BE:
+ *yuv2packed1 = yuv2rgba64be_1_c;
+ *yuv2packed2 = yuv2rgba64be_2_c;
+ *yuv2packedX = yuv2rgba64be_X_c;
+ break;
case AV_PIX_FMT_RGB48LE:
*yuv2packed1 = yuv2rgb48le_1_c;
*yuv2packed2 = yuv2rgb48le_2_c;
diff --git a/libswscale/utils.c b/libswscale/utils.c
index 932cf94..e3cf10d 100644
--- a/libswscale/utils.c
+++ b/libswscale/utils.c
@@ -136,8 +136,8 @@ static const FormatEntry format_entries[AV_PIX_FMT_NB] = {
[AV_PIX_FMT_YUVA444P16LE]= { 1, 1 },
[AV_PIX_FMT_RGB48BE] = { 1, 1 },
[AV_PIX_FMT_RGB48LE] = { 1, 1 },
- [AV_PIX_FMT_RGBA64BE] = { 1, 0 },
- [AV_PIX_FMT_RGBA64LE] = { 1, 0 },
+ [AV_PIX_FMT_RGBA64BE] = { 1, 1 },
+ [AV_PIX_FMT_RGBA64LE] = { 1, 1 },
[AV_PIX_FMT_RGB565BE] = { 1, 1 },
[AV_PIX_FMT_RGB565LE] = { 1, 1 },
[AV_PIX_FMT_RGB555BE] = { 1, 1 },
diff --git a/libswscale/yuv2rgb.c b/libswscale/yuv2rgb.c
index d12abda..e3dee18 100644
--- a/libswscale/yuv2rgb.c
+++ b/libswscale/yuv2rgb.c
@@ -109,6 +109,18 @@ const int *sws_getCoefficients(int colorspace)
dst[12 * i + 8] = dst[12 * i + 9] = g[Y]; \
dst[12 * i + 10] = dst[12 * i + 11] = b[Y];
+#define PUTRGBA64(dst, ysrc, asrc, i) \
+ Y = ysrc[ 2 * i]; \
+ dst[16 * i + 0] = dst[16 * i + 1] = r[Y]; \
+ dst[16 * i + 2] = dst[16 * i + 3] = g[Y]; \
+ dst[16 * i + 4] = dst[16 * i + 5] = b[Y]; \
+ dst[16 * i + 6] = dst[16 * i + 7] = asrc[2 * i]; \
+ Y = ysrc[ 2 * i + 1]; \
+ dst[16 * i + 8] = dst[16 * i + 9] = r[Y]; \
+ dst[16 * i + 10] = dst[16 * i + 11] = g[Y]; \
+ dst[16 * i + 12] = dst[16 * i + 13] = b[Y]; \
+ dst[16 * i + 14] = dst[16 * i + 15] = asrc[2 * i + 1];
+
#define PUTBGR48(dst, src, i) \
Y = src[2 * i]; \
dst[12 * i + 0] = dst[12 * i + 1] = b[Y]; \
@@ -170,6 +182,40 @@ const int *sws_getCoefficients(int colorspace)
ENDYUV2RGBLINE(dst_delta, 0) \
ENDYUV2RGBFUNC()
+YUV2RGBFUNC(yuv2rgb_c_64, uint8_t, 0)
+ LOADCHROMA(0);
+ PUTRGBA64(dst_1, py_1, pa_1, 0);
+ PUTRGBA64(dst_2, py_2, pa_2, 0);
+
+ LOADCHROMA(1);
+ PUTRGBA64(dst_2, py_2, pa_2, 1);
+ PUTRGBA64(dst_1, py_1, pa_1, 1);
+
+ LOADCHROMA(2);
+ PUTRGBA64(dst_1, py_1, pa_1, 2);
+ PUTRGBA64(dst_2, py_2, pa_2, 2);
+
+ LOADCHROMA(3);
+ PUTRGBA64(dst_2, py_2, pa_1, 3);
+ PUTRGBA64(dst_1, py_1, pa_2, 3);
+ pa_1 += 8; \
+ pa_2 += 8; \
+ENDYUV2RGBLINE(64, 0)
+ LOADCHROMA(0);
+ PUTRGBA64(dst_1, py_1, pa_1, 0);
+ PUTRGBA64(dst_2, py_2, pa_2, 0);
+
+ LOADCHROMA(1);
+ PUTRGBA64(dst_2, py_2, pa_1, 1);
+ PUTRGBA64(dst_1, py_1, pa_2, 1);
+ pa_1 += 4; \
+ pa_2 += 4; \
+ENDYUV2RGBLINE(64, 1)
+ LOADCHROMA(0);
+ PUTRGBA64(dst_1, py_1, pa_1, 0);
+ PUTRGBA64(dst_2, py_2, pa_2, 0);
+ENDYUV2RGBFUNC()
+
YUV2RGBFUNC(yuv2rgb_c_48, uint8_t, 0)
LOADCHROMA(0);
PUTRGB48(dst_1, py_1, 0);
@@ -625,6 +671,9 @@ SwsFunc ff_yuv2rgb_get_func_ptr(SwsContext *c)
av_get_pix_fmt_name(c->srcFormat), av_get_pix_fmt_name(c->dstFormat));
switch (c->dstFormat) {
+ case AV_PIX_FMT_RGBA64BE:
+ case AV_PIX_FMT_RGBA64LE:
+ return yuv2rgb_c_64;
case AV_PIX_FMT_BGR48BE:
case AV_PIX_FMT_BGR48LE:
return yuv2rgb_c_bgr48;
@@ -893,6 +942,7 @@ av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4],
fill_gv_table(c->table_gV, 1, cgv);
break;
case 32:
+ case 64:
base = (c->dstFormat == AV_PIX_FMT_RGB32_1 ||
c->dstFormat == AV_PIX_FMT_BGR32_1) ? 8 : 0;
rbase = base + (isRgb ? 16 : 0);
--
1.7.11.4
More information about the ffmpeg-devel
mailing list