[FFmpeg-devel] [PATCH 4/5] sws/output: convert 1 and 2 type yuv2rgb to tableless solution

Michael Niedermayer michaelni at gmx.at
Sun Apr 14 12:17:21 CEST 2013


Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
---
 libswscale/output.c |  131 ++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 89 insertions(+), 42 deletions(-)

diff --git a/libswscale/output.c b/libswscale/output.c
index 8429efc..3d7c0e1 100644
--- a/libswscale/output.c
+++ b/libswscale/output.c
@@ -1212,6 +1212,10 @@ yuv2rgb_2_c_template(SwsContext *c, const int16_t *buf[2],
                      int yalpha, int uvalpha, int y,
                      enum AVPixelFormat target, int hasAlpha)
 {
+    int isBGR = c->dstFormat == AV_PIX_FMT_ABGR   || c->dstFormat == AV_PIX_FMT_BGRA   || c->dstFormat == AV_PIX_FMT_BGR24
+             || c->dstFormat == AV_PIX_FMT_BGR565LE || c->dstFormat == AV_PIX_FMT_BGR555LE || c->dstFormat == AV_PIX_FMT_BGR444LE
+             || c->dstFormat == AV_PIX_FMT_BGR565BE || c->dstFormat == AV_PIX_FMT_BGR555BE || c->dstFormat == AV_PIX_FMT_BGR444BE
+             || c->dstFormat == AV_PIX_FMT_BGR8     || c->dstFormat == AV_PIX_FMT_BGR4 || c->dstFormat == AV_PIX_FMT_BGR4_BYTE;
     const int16_t *buf0  = buf[0],  *buf1  = buf[1],
                   *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
                   *vbuf0 = vbuf[0], *vbuf1 = vbuf[1],
@@ -1222,24 +1226,40 @@ yuv2rgb_2_c_template(SwsContext *c, const int16_t *buf[2],
     int i;
 
     for (i = 0; i < ((dstW + 1) >> 1); i++) {
-        int Y1 = (buf0[i * 2]     * yalpha1  + buf1[i * 2]     * yalpha)  >> 19;
-        int Y2 = (buf0[i * 2 + 1] * yalpha1  + buf1[i * 2 + 1] * yalpha)  >> 19;
-        int U  = (ubuf0[i]        * uvalpha1 + ubuf1[i]        * uvalpha) >> 19;
-        int V  = (vbuf0[i]        * uvalpha1 + vbuf1[i]        * uvalpha) >> 19;
-        int A1, A2;
-        const void *r =  c->table_rV[V + YUVRGB_TABLE_HEADROOM],
-                   *g = (c->table_gU[U + YUVRGB_TABLE_HEADROOM] + c->table_gV[V + YUVRGB_TABLE_HEADROOM]),
-                   *b =  c->table_bU[U + YUVRGB_TABLE_HEADROOM];
+        int Y1 = (buf0[i * 2]     * yalpha1  + buf1[i * 2]     * yalpha)  >> 10;
+        int Y2 = (buf0[i * 2 + 1] * yalpha1  + buf1[i * 2 + 1] * yalpha)  >> 10;
+        int U  = (ubuf0[i]        * uvalpha1 + ubuf1[i]        * uvalpha) >> 10;
+        int V  = (vbuf0[i]        * uvalpha1 + vbuf1[i]        * uvalpha) >> 10;
+        int A1, A2, R, G, B;
 
         if (hasAlpha) {
-            A1 = (abuf0[i * 2    ] * yalpha1 + abuf1[i * 2    ] * yalpha) >> 19;
-            A2 = (abuf0[i * 2 + 1] * yalpha1 + abuf1[i * 2 + 1] * yalpha) >> 19;
-            A1 = av_clip_uint8(A1);
-            A2 = av_clip_uint8(A2);
+            A1 = (abuf0[i * 2    ] * yalpha1 + abuf1[i * 2    ] * yalpha);
+            A2 = (abuf0[i * 2 + 1] * yalpha1 + abuf1[i * 2 + 1] * yalpha);
         }
+        U += (-128 << 9);
+        V += (-128 << 9);
+        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;
 
-        yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
-                      r, g, b, y, target, hasAlpha);
+        R = V * c->yuv2rgb_v2r_coeff;
+        G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
+        B =                            U * c->yuv2rgb_u2b_coeff;
+
+        yuv2rgb_write2(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
+                       R, G, B, y, target, hasAlpha, isBGR, 27);
+    }
+    if ((!isBE(c->dstFormat)) != (!HAVE_BIGENDIAN)) {
+        const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->dstFormat);
+        uint16_t *dest16 = (uint16_t*)dest;
+        if (6-1 > desc->comp[0].depth_minus1 && desc->comp[0].depth_minus1 > 3-1) {
+            for (i = 0; i < dstW; i++) {
+                dest16[i] = av_bswap16(dest16[i]);
+            }
+        }
     }
 }
 
@@ -1250,51 +1270,78 @@ yuv2rgb_1_c_template(SwsContext *c, const int16_t *buf0,
                      int uvalpha, int y, enum AVPixelFormat target,
                      int hasAlpha)
 {
+    int isBGR = c->dstFormat == AV_PIX_FMT_ABGR   || c->dstFormat == AV_PIX_FMT_BGRA   || c->dstFormat == AV_PIX_FMT_BGR24
+             || c->dstFormat == AV_PIX_FMT_BGR565LE || c->dstFormat == AV_PIX_FMT_BGR555LE || c->dstFormat == AV_PIX_FMT_BGR444LE
+             || c->dstFormat == AV_PIX_FMT_BGR565BE || c->dstFormat == AV_PIX_FMT_BGR555BE || c->dstFormat == AV_PIX_FMT_BGR444BE
+             || c->dstFormat == AV_PIX_FMT_BGR8     || c->dstFormat == AV_PIX_FMT_BGR4 || c->dstFormat == AV_PIX_FMT_BGR4_BYTE;
     const int16_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    ] + 64) >> 7;
-            int Y2 = (buf0[i * 2 + 1] + 64) >> 7;
-            int U  = (ubuf0[i]        + 64) >> 7;
-            int V  = (vbuf0[i]        + 64) >> 7;
-            int A1, A2;
-            const void *r =  c->table_rV[V + YUVRGB_TABLE_HEADROOM],
-                       *g = (c->table_gU[U + YUVRGB_TABLE_HEADROOM] + c->table_gV[V + YUVRGB_TABLE_HEADROOM]),
-                       *b =  c->table_bU[U + YUVRGB_TABLE_HEADROOM];
+            int Y1 = buf0[i * 2    ] << 2;
+            int Y2 = buf0[i * 2 + 1] << 2;
+            int U  = ubuf0[i]        << 2;
+            int V  = vbuf0[i]        << 2;
+            int A1, A2, R, G, B;
 
             if (hasAlpha) {
-                A1 = abuf0[i * 2    ] * 255 + 16384 >> 15;
-                A2 = abuf0[i * 2 + 1] * 255 + 16384 >> 15;
-                A1 = av_clip_uint8(A1);
-                A2 = av_clip_uint8(A2);
+                A1 = abuf0[i * 2    ];
+                A2 = abuf0[i * 2 + 1];
             }
+            U += (-128 << 9);
+            V += (-128 << 9);
+            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;
 
-            yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
-                          r, g, b, y, target, hasAlpha);
+            R = V * c->yuv2rgb_v2r_coeff;
+            G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
+            B =                            U * c->yuv2rgb_u2b_coeff;
+
+            yuv2rgb_write2(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
+                        R, G, B, y, target, hasAlpha, isBGR, 15);
         }
     } else {
         const int16_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1];
         for (i = 0; i < ((dstW + 1) >> 1); i++) {
-            int Y1 = (buf0[i * 2    ]     +  64) >> 7;
-            int Y2 = (buf0[i * 2 + 1]     +  64) >> 7;
-            int U  = (ubuf0[i] + ubuf1[i] + 128) >> 8;
-            int V  = (vbuf0[i] + vbuf1[i] + 128) >> 8;
-            int A1, A2;
-            const void *r =  c->table_rV[V + YUVRGB_TABLE_HEADROOM],
-                       *g = (c->table_gU[U + YUVRGB_TABLE_HEADROOM] + c->table_gV[V + YUVRGB_TABLE_HEADROOM]),
-                       *b =  c->table_bU[U + YUVRGB_TABLE_HEADROOM];
+            int Y1 =  buf0[i * 2    ] << 2;
+            int Y2 =  buf0[i * 2 + 1] << 2;
+            int U  = (ubuf0[i] + ubuf1[i]) << 1;
+            int V  = (vbuf0[i] + vbuf1[i]) << 1;
+            int A1, A2, R, G, B;
 
             if (hasAlpha) {
-                A1 = (abuf0[i * 2    ] + 64) >> 7;
-                A2 = (abuf0[i * 2 + 1] + 64) >> 7;
-                A1 = av_clip_uint8(A1);
-                A2 = av_clip_uint8(A2);
+                A1 = abuf0[i * 2    ];
+                A2 = abuf0[i * 2 + 1];
             }
+            U += (-128 << 9);
+            V += (-128 << 9);
+            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;
 
-            yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
-                          r, g, b, y, target, hasAlpha);
+            yuv2rgb_write2(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
+                        R, G, B, y, target, hasAlpha, isBGR, 15);
+        }
+    }
+    if ((!isBE(c->dstFormat)) != (!HAVE_BIGENDIAN)) {
+        const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->dstFormat);
+        uint16_t *dest16 = (uint16_t*)dest;
+        if (6-1 > desc->comp[0].depth_minus1 && desc->comp[0].depth_minus1 > 3-1) {
+            for (i = 0; i < dstW; i++) {
+                dest16[i] = av_bswap16(dest16[i]);
+            }
         }
     }
 }
-- 
1.7.9.5



More information about the ffmpeg-devel mailing list