[FFmpeg-devel] [PATCH] [BROKEN] swscale: RGBA64 output

Paul B Mahol onemda at gmail.com
Sun May 12 20:10:48 CEST 2013


Signed-off-by: Paul B Mahol <onemda at gmail.com>
---
 libswscale/output.c                 | 290 ++++++++++++++++++++++++++++++++++--
 libswscale/utils.c                  |   4 +-
 libswscale/yuv2rgb.c                |  86 +++++++++++
 tests/ref/fate/filter-pixdesc       |   2 +
 tests/ref/fate/filter-pixfmts-copy  |   2 +
 tests/ref/fate/filter-pixfmts-field |   2 +
 tests/ref/fate/filter-pixfmts-hflip |   2 +
 tests/ref/fate/filter-pixfmts-il    |   2 +
 tests/ref/fate/filter-pixfmts-null  |   2 +
 tests/ref/fate/filter-pixfmts-scale |   2 +
 tests/ref/fate/filter-pixfmts-vflip |   2 +
 11 files changed, 383 insertions(+), 13 deletions(-)

diff --git a/libswscale/output.c b/libswscale/output.c
index a0826d0..c82b04b 100644
--- a/libswscale/output.c
+++ b/libswscale/output.c
@@ -674,12 +674,248 @@ 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 hasAlpha)
+{
+    int i;
+
+    for (i = 0; i < ((dstW + 1) >> 1); i++) {
+        int j, A1 = 0, A2 = 0;
+        int Y1 = -0x40000000;
+        int Y2 = -0x40000000;
+        int U  = -128 << 23; // 19
+        int V  = -128 << 23;
+        int R, G, B;
+
+        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];
+        }
+
+        if (hasAlpha) {
+            A1 = -0x40000000;
+            A2 = -0x40000000;
+            for (j = 0; j < lumFilterSize; j++) {
+                A1 += alpSrc[j][i * 2]     * (unsigned)lumFilter[j];
+                A2 += alpSrc[j][i * 2 + 1] * (unsigned)lumFilter[j];
+            }
+            A1 >>= 14; // 10
+            A1 += 0x10000;
+            A2 >>= 14;
+            A2 += 0x10000;
+            A1 -= c->yuv2rgb_y_offset;
+            A2 -= c->yuv2rgb_y_offset;
+            A1 *= c->yuv2rgb_y_coeff;
+            A2 *= c->yuv2rgb_y_coeff;
+            A1 += 1 << 13; // 21
+            A2 += 1 << 13;
+        }
+
+        // 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(A1      , 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(A2      , 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, int hasAlpha)
+{
+    const int32_t *buf0  = buf[0],  *buf1  = buf[1],
+                  *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
+                  *vbuf0 = vbuf[0], *vbuf1 = vbuf[1],
+                  *abuf0 = hasAlpha ? abuf[0] : NULL,
+                  *abuf1 = hasAlpha ? abuf[1] : NULL;
+    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 A1, A2;
+        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;
+
+        if (hasAlpha) {
+            A1 = (abuf0[i * 2    ] * yalpha1 + abuf1[i * 2    ] * yalpha) >> 14;
+            A2 = (abuf0[i * 2 + 1] * yalpha1 + abuf1[i * 2 + 1] * yalpha) >> 14;
+
+            A1 -= c->yuv2rgb_y_offset;
+            A2 -= c->yuv2rgb_y_offset;
+            A1 *= c->yuv2rgb_y_coeff;
+            A2 *= c->yuv2rgb_y_coeff;
+            A1 += 1 << 13;
+            A2 += 1 << 13;
+        }
+
+        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(A1      , 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(A2      , 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, int hasAlpha)
+{
+    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;
+            int A1, A2;
+
+            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;
+
+            if (hasAlpha) {
+                A1 = abuf0[i * 2    ] >> 2;
+                A2 = abuf0[i * 2 + 1] >> 2;
+
+                A1 -= c->yuv2rgb_y_offset;
+                A2 -= c->yuv2rgb_y_offset;
+                A1 *= c->yuv2rgb_y_coeff;
+                A2 *= c->yuv2rgb_y_coeff;
+                A1 += 1 << 13;
+                A2 += 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(A1      , 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(A2      , 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;
+            int A1, A2;
+
+            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;
+
+            if (hasAlpha) {
+                A1 = abuf0[i * 2    ] >> 2;
+                A2 = abuf0[i * 2 + 1] >> 2;
+
+                A1 -= c->yuv2rgb_y_offset;
+                A2 -= c->yuv2rgb_y_offset;
+                A1 *= c->yuv2rgb_y_coeff;
+                A2 *= c->yuv2rgb_y_coeff;
+                A1 += 1 << 13;
+                A2 += 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(A1      , 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(A2      , 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,
                        const int32_t **chrVSrc, int chrFilterSize,
                        const int32_t **alpSrc, uint16_t *dest, int dstW,
-                       int y, enum AVPixelFormat target)
+                       int y, enum AVPixelFormat target, int hasAlpha)
 {
     int i;
 
@@ -737,7 +973,7 @@ yuv2rgb48_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)
+                       enum AVPixelFormat target, int hasAlpha)
 {
     const int32_t *buf0  = buf[0],  *buf1  = buf[1],
                   *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
@@ -778,7 +1014,7 @@ static av_always_inline void
 yuv2rgb48_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)
+                       int uvalpha, int y, enum AVPixelFormat target, int hasAlpha)
 {
     const int32_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0];
     int i;
@@ -845,7 +1081,7 @@ yuv2rgb48_1_c_template(SwsContext *c, const int32_t *buf0,
 #undef r_b
 #undef b_r
 
-#define YUV2PACKED16WRAPPER(name, base, ext, fmt) \
+#define YUV2PACKED16WRAPPER(name, base, ext, fmt, hasAlpha) \
 static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \
                         const int16_t **_lumSrc, int lumFilterSize, \
                         const int16_t *chrFilter, const int16_t **_chrUSrc, \
@@ -860,7 +1096,7 @@ static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \
     uint16_t *dest = (uint16_t *) _dest; \
     name ## base ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \
                           chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
-                          alpSrc, dest, dstW, y, fmt); \
+                          alpSrc, dest, dstW, y, fmt, hasAlpha); \
 } \
  \
 static void name ## ext ## _2_c(SwsContext *c, const int16_t *_buf[2], \
@@ -874,7 +1110,7 @@ static void name ## ext ## _2_c(SwsContext *c, const int16_t *_buf[2], \
                   **abuf = (const int32_t **) _abuf; \
     uint16_t *dest = (uint16_t *) _dest; \
     name ## base ## _2_c_template(c, buf, ubuf, vbuf, abuf, \
-                          dest, dstW, yalpha, uvalpha, y, fmt); \
+                          dest, dstW, yalpha, uvalpha, y, fmt, hasAlpha); \
 } \
  \
 static void name ## ext ## _1_c(SwsContext *c, const int16_t *_buf0, \
@@ -888,13 +1124,17 @@ static void name ## ext ## _1_c(SwsContext *c, const int16_t *_buf0, \
                   *abuf0 = (const int32_t *)  _abuf0; \
     uint16_t *dest = (uint16_t *) _dest; \
     name ## base ## _1_c_template(c, buf0, ubuf, vbuf, abuf0, dest, \
-                                  dstW, uvalpha, y, fmt); \
+                                  dstW, uvalpha, y, fmt, hasAlpha); \
 }
 
-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, rgb48, rgb48be, AV_PIX_FMT_RGB48BE, 0)
+YUV2PACKED16WRAPPER(yuv2, rgb48, rgb48le, AV_PIX_FMT_RGB48LE, 0)
+YUV2PACKED16WRAPPER(yuv2, rgb48, bgr48be, AV_PIX_FMT_BGR48BE, 0)
+YUV2PACKED16WRAPPER(yuv2, rgb48, bgr48le, AV_PIX_FMT_BGR48LE, 0)
+YUV2PACKED16WRAPPER(yuv2, rgba64, rgba64be, AV_PIX_FMT_RGBA64BE, 1)
+YUV2PACKED16WRAPPER(yuv2, rgba64, rgba64le, AV_PIX_FMT_RGBA64LE, 1)
+YUV2PACKED16WRAPPER(yuv2, rgba64, rgbx64be, AV_PIX_FMT_RGBA64BE, 0)
+YUV2PACKED16WRAPPER(yuv2, rgba64, rgbx64le, AV_PIX_FMT_RGBA64LE, 0)
 
 /*
  * Write out 2 RGB pixels in the target pixel format. This function takes a
@@ -1738,6 +1978,34 @@ av_cold void ff_sws_init_output_funcs(SwsContext *c,
     } else {
         YUV_PACKED:
         switch (dstFormat) {
+        case AV_PIX_FMT_RGBA64LE:
+#if CONFIG_SWSCALE_ALPHA
+            if (c->alpPixBuf) {
+                *yuv2packed1 = yuv2rgba64le_1_c;
+                *yuv2packed2 = yuv2rgba64le_2_c;
+                *yuv2packedX = yuv2rgba64le_X_c;
+            } else
+#endif /* CONFIG_SWSCALE_ALPHA */
+            {
+                *yuv2packed1 = yuv2rgbx64le_1_c;
+                *yuv2packed2 = yuv2rgbx64le_2_c;
+                *yuv2packedX = yuv2rgbx64le_X_c;
+            }
+            break;
+        case AV_PIX_FMT_RGBA64BE:
+#if CONFIG_SWSCALE_ALPHA
+            if (c->alpPixBuf) {
+                *yuv2packed1 = yuv2rgba64be_1_c;
+                *yuv2packed2 = yuv2rgba64be_2_c;
+                *yuv2packedX = yuv2rgba64be_X_c;
+            } else
+#endif /* CONFIG_SWSCALE_ALPHA */
+            {
+                *yuv2packed1 = yuv2rgbx64be_1_c;
+                *yuv2packed2 = yuv2rgbx64be_2_c;
+                *yuv2packedX = yuv2rgbx64be_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 b372e96..6bcd226 100644
--- a/libswscale/utils.c
+++ b/libswscale/utils.c
@@ -138,8 +138,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 dd33f47..d06ace5 100644
--- a/libswscale/yuv2rgb.c
+++ b/libswscale/yuv2rgb.c
@@ -109,6 +109,28 @@ 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 PUTRGB64(dst, ysrc, 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];     \
+    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];
+
+#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 +192,66 @@ const int *sws_getCoefficients(int colorspace)
     ENDYUV2RGBLINE(dst_delta, 0)                    \
     ENDYUV2RGBFUNC()
 
+YUV2RGBFUNC(yuva2rgba_c_64, uint8_t, 1)
+    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_2, 3);
+    PUTRGBA64(dst_1, py_1, pa_1, 3);
+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_2, 1);
+    PUTRGBA64(dst_1, py_1, pa_1, 1);
+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_64, uint8_t, 0)
+    LOADCHROMA(0);
+    PUTRGB64(dst_1, py_1, 0);
+    PUTRGB64(dst_2, py_2, 0);
+
+    LOADCHROMA(1);
+    PUTRGB64(dst_2, py_2, 1);
+    PUTRGB64(dst_1, py_1, 1);
+
+    LOADCHROMA(2);
+    PUTRGB64(dst_1, py_1, 2);
+    PUTRGB64(dst_2, py_2, 2);
+
+    LOADCHROMA(3);
+    PUTRGB64(dst_2, py_2, 3);
+    PUTRGB64(dst_1, py_1, 3);
+ENDYUV2RGBLINE(64, 0)
+    LOADCHROMA(0);
+    PUTRGB64(dst_1, py_1, 0);
+    PUTRGB64(dst_2, py_2, 0);
+
+    LOADCHROMA(1);
+    PUTRGB64(dst_2, py_2, 1);
+    PUTRGB64(dst_1, py_1, 1);
+ENDYUV2RGBLINE(64, 1)
+    LOADCHROMA(0);
+    PUTRGB64(dst_1, py_1, 0);
+    PUTRGB64(dst_2, py_2, 0);
+ENDYUV2RGBFUNC()
+
 YUV2RGBFUNC(yuv2rgb_c_48, uint8_t, 0)
     LOADCHROMA(0);
     PUTRGB48(dst_1, py_1, 0);
@@ -628,6 +710,9 @@ SwsFunc ff_yuv2rgb_get_func_ptr(SwsContext *c)
     case AV_PIX_FMT_BGR48BE:
     case AV_PIX_FMT_BGR48LE:
         return yuv2rgb_c_bgr48;
+    case AV_PIX_FMT_RGBA64BE:
+    case AV_PIX_FMT_RGBA64LE:
+        return (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat)) ? yuva2rgba_c_64 : yuv2rgb_c_64;
     case AV_PIX_FMT_RGB48BE:
     case AV_PIX_FMT_RGB48LE:
         return yuv2rgb_c_48;
@@ -893,6 +978,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);
diff --git a/tests/ref/fate/filter-pixdesc b/tests/ref/fate/filter-pixdesc
index 1387f4f..1ab928b 100644
--- a/tests/ref/fate/filter-pixdesc
+++ b/tests/ref/fate/filter-pixdesc
@@ -45,6 +45,8 @@ rgb565be            bc123b962629ead1a06af0c18cbb6e5f
 rgb565le            20757fafe4756e62d845b2ab4c0b8f93
 rgb8                e01614f5416dcc8ad365ad7a57afc9fb
 rgba                53796fa4c392a1b2659595b6a284f8c4
+rgba64be            d5729f8c76250a9b18cb149b396f1bfb
+rgba64le            fae0a6afdaee94cb98e3ab9a702c8ecc
 uyvy422             3f411f947e3ac8f842c88e717d68bd9a
 yuv410p             7dcf3f4770c8b494290ceacd2c2ce6db
 yuv411p             9461b188dab6f8b90d9a27e353a89f58
diff --git a/tests/ref/fate/filter-pixfmts-copy b/tests/ref/fate/filter-pixfmts-copy
index 3428408..dba8fec 100644
--- a/tests/ref/fate/filter-pixfmts-copy
+++ b/tests/ref/fate/filter-pixfmts-copy
@@ -46,6 +46,8 @@ rgb565be            bc123b962629ead1a06af0c18cbb6e5f
 rgb565le            20757fafe4756e62d845b2ab4c0b8f93
 rgb8                e01614f5416dcc8ad365ad7a57afc9fb
 rgba                53796fa4c392a1b2659595b6a284f8c4
+rgba64be            d5729f8c76250a9b18cb149b396f1bfb
+rgba64le            fae0a6afdaee94cb98e3ab9a702c8ecc
 uyvy422             3f411f947e3ac8f842c88e717d68bd9a
 xyz12be             e1e6718ae1c83e904fbdf903d62e5808
 xyz12le             24e8a22c1bd7d637edb731d10b7c54d0
diff --git a/tests/ref/fate/filter-pixfmts-field b/tests/ref/fate/filter-pixfmts-field
index dec6cb3..c1c7ea7 100644
--- a/tests/ref/fate/filter-pixfmts-field
+++ b/tests/ref/fate/filter-pixfmts-field
@@ -46,6 +46,8 @@ rgb565be            e8f3ebcbb9a5fff000eca8a312f89782
 rgb565le            53bbd558fb0dcd82f1fad83ea855c3ad
 rgb8                67bfdd4fa88b1ab9be876f42dfc75683
 rgba                d0ebdf1495bc6b7e9d3bfbe2813a9d16
+rgba64be            963f5e716b6de4cacf06c3ca9d02bee0
+rgba64le            b333503ba90d51d0cd21ff7e60acd492
 uyvy422             a6a52504a16f09b8f2ec2405bc8190b5
 xyz12be             9d904fb640dd024e668acb9dc7b3f11f
 xyz12le             7f93c7d2981f1976108e941afa1363f8
diff --git a/tests/ref/fate/filter-pixfmts-hflip b/tests/ref/fate/filter-pixfmts-hflip
index c9f942b..84a3519 100644
--- a/tests/ref/fate/filter-pixfmts-hflip
+++ b/tests/ref/fate/filter-pixfmts-hflip
@@ -44,6 +44,8 @@ rgb565be            6727e71974c8e5dad157925c10ee1532
 rgb565le            b0a2b4817775289cfc415bb951f9ae0c
 rgb8                22fdbd14ce296c1afa9bb4a6ea09b3fe
 rgba                a37789c4df73c3bd8648ad1fe9d3f991
+rgba64be            d5562166a3fef8a65c15898b8e792300
+rgba64le            babf9eb683b2886289562cf465da6738
 xyz12be             4738d2cb5321376d5eed70930f47a953
 xyz12le             51288f3440c8584406b332545d69c5a9
 yuv410p             a1280c2b9b562dba3c2d35a1e5fc4b23
diff --git a/tests/ref/fate/filter-pixfmts-il b/tests/ref/fate/filter-pixfmts-il
index e09b2aa..5e7dc5f 100644
--- a/tests/ref/fate/filter-pixfmts-il
+++ b/tests/ref/fate/filter-pixfmts-il
@@ -45,6 +45,8 @@ rgb565be            077604cc5dc91008b018264db73c8f0c
 rgb565le            a97549f25e63dd0dd404db41bbe05c07
 rgb8                a35d3c3b9b87261c7417076a8b18fdb8
 rgba                8ca9c8db589615ebbaa964be4ce62d08
+rgba64be            ca82ddd3f4182c21f8708cbe5368b57a
+rgba64le            53236255cdc370f549484008f61c04e8
 uyvy422             8be40aded4b407ff66305911ba5ce2ce
 xyz12be             1cbb1f72c6875934e66f50f499a62cc3
 xyz12le             ba8c6eab49e58eace392ef0aeedbf677
diff --git a/tests/ref/fate/filter-pixfmts-null b/tests/ref/fate/filter-pixfmts-null
index 3428408..dba8fec 100644
--- a/tests/ref/fate/filter-pixfmts-null
+++ b/tests/ref/fate/filter-pixfmts-null
@@ -46,6 +46,8 @@ rgb565be            bc123b962629ead1a06af0c18cbb6e5f
 rgb565le            20757fafe4756e62d845b2ab4c0b8f93
 rgb8                e01614f5416dcc8ad365ad7a57afc9fb
 rgba                53796fa4c392a1b2659595b6a284f8c4
+rgba64be            d5729f8c76250a9b18cb149b396f1bfb
+rgba64le            fae0a6afdaee94cb98e3ab9a702c8ecc
 uyvy422             3f411f947e3ac8f842c88e717d68bd9a
 xyz12be             e1e6718ae1c83e904fbdf903d62e5808
 xyz12le             24e8a22c1bd7d637edb731d10b7c54d0
diff --git a/tests/ref/fate/filter-pixfmts-scale b/tests/ref/fate/filter-pixfmts-scale
index 30d9eb9..b354ddd 100644
--- a/tests/ref/fate/filter-pixfmts-scale
+++ b/tests/ref/fate/filter-pixfmts-scale
@@ -46,6 +46,8 @@ rgb565be            5168b66e69c25351948085e5fc51bb3a
 rgb565le            301a4d41f0db3aaed341d812ed0d7927
 rgb8                8e5786e83099bc89d2e38a76e6dfcc52
 rgba                de6a65b8c01bdad84e575202ca8b66a0
+rgba64be            fdc6467660a45d6e9dad59339be2ec4c
+rgba64le            b208b8fdd403c1a24bbef0473a89d978
 uyvy422             479105bc4c7fbb4a33ca8745aa8c2de8
 xyz12be             e9be06091b6dd0b67598eaf8bd86a78e
 xyz12le             05a9bbd16d81183ef3db04447648e3b1
diff --git a/tests/ref/fate/filter-pixfmts-vflip b/tests/ref/fate/filter-pixfmts-vflip
index 6796183..70f5d5d 100644
--- a/tests/ref/fate/filter-pixfmts-vflip
+++ b/tests/ref/fate/filter-pixfmts-vflip
@@ -46,6 +46,8 @@ rgb565be            c70d86afbd68a073f2d4fe0eee3a9832
 rgb565le            991576c5d3308a73068a826543b3e7af
 rgb8                42230235c5a2a66c0f9a2fcd20f9f5cd
 rgba                a6973a2940a378d2a8284194da26eec0
+rgba64be            d438e49304f65a5b7c5f09fcc1b979df
+rgba64le            9acbefa0f25441491d780b57aac11346
 uyvy422             21c48162379321bb83ec2399535f9253
 xyz12be             7070af64e30fa689e3627b1dde7506f4
 xyz12le             4c4b31100b836638e7e61181997c49e1
-- 
1.7.11.2



More information about the ffmpeg-devel mailing list