changeset 29475:a697eafd804d

Vertical yuv -> yuv16 scaler.
author ramiro
date Fri, 14 Aug 2009 15:52:40 +0000
parents 1abc7bcda064
children dc1a6d06b090
files libswscale/swscale.c libswscale/swscale_template.c
diffstat 2 files changed, 101 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/libswscale/swscale.c	Fri Aug 14 09:31:16 2009 +0000
+++ b/libswscale/swscale.c	Fri Aug 14 15:52:40 2009 +0000
@@ -74,6 +74,7 @@
 #include "swscale.h"
 #include "swscale_internal.h"
 #include "rgb2rgb.h"
+#include "libavutil/intreadwrite.h"
 #include "libavutil/x86_cpu.h"
 #include "libavutil/bswap.h"
 
@@ -474,6 +475,86 @@
     }
 }
 
+static av_always_inline void yuv2yuvX16inC_template(const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
+                                                    const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
+                                                    const int16_t **alpSrc, uint16_t *dest, uint16_t *uDest, uint16_t *vDest, uint16_t *aDest,
+                                                    int dstW, int chrDstW, int big_endian)
+{
+    //FIXME Optimize (just quickly written not optimized..)
+    int i;
+
+    for (i = 0; i < dstW; i++) {
+        int val = 1 << 10;
+        int j;
+
+        for (j = 0; j < lumFilterSize; j++)
+            val += lumSrc[j][i] * lumFilter[j];
+
+        if (big_endian) {
+            AV_WB16(&dest[i], av_clip_uint16(val >> 11));
+        } else {
+            AV_WL16(&dest[i], av_clip_uint16(val >> 11));
+        }
+    }
+
+    if (uDest) {
+        for (i = 0; i < chrDstW; i++) {
+            int u = 1 << 10;
+            int v = 1 << 10;
+            int j;
+
+            for (j = 0; j < chrFilterSize; j++) {
+                u += chrSrc[j][i       ] * chrFilter[j];
+                v += chrSrc[j][i + VOFW] * chrFilter[j];
+            }
+
+            if (big_endian) {
+                AV_WB16(&uDest[i], av_clip_uint16(u >> 11));
+                AV_WB16(&vDest[i], av_clip_uint16(v >> 11));
+            } else {
+                AV_WL16(&uDest[i], av_clip_uint16(u >> 11));
+                AV_WL16(&vDest[i], av_clip_uint16(v >> 11));
+            }
+        }
+    }
+
+    if (CONFIG_SWSCALE_ALPHA && aDest) {
+        for (i = 0; i < dstW; i++) {
+            int val = 1 << 10;
+            int j;
+
+            for (j = 0; j < lumFilterSize; j++)
+                val += alpSrc[j][i] * lumFilter[j];
+
+            if (big_endian) {
+                AV_WB16(&aDest[i], av_clip_uint16(val >> 11));
+            } else {
+                AV_WL16(&aDest[i], av_clip_uint16(val >> 11));
+            }
+        }
+    }
+}
+
+static inline void yuv2yuvX16inC(const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
+                                 const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
+                                 const int16_t **alpSrc, uint16_t *dest, uint16_t *uDest, uint16_t *vDest, uint16_t *aDest, int dstW, int chrDstW,
+                                 enum PixelFormat dstFormat)
+{
+    if (isBE(dstFormat)) {
+        yuv2yuvX16inC_template(lumFilter, lumSrc, lumFilterSize,
+                               chrFilter, chrSrc, chrFilterSize,
+                               alpSrc,
+                               dest, uDest, vDest, aDest,
+                               dstW, chrDstW, 1);
+    } else {
+        yuv2yuvX16inC_template(lumFilter, lumSrc, lumFilterSize,
+                               chrFilter, chrSrc, chrFilterSize,
+                               alpSrc,
+                               dest, uDest, vDest, aDest,
+                               dstW, chrDstW, 0);
+    }
+}
+
 static inline void yuv2yuvXinC(const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
                                const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
                                const int16_t **alpSrc, uint8_t *dest, uint8_t *uDest, uint8_t *vDest, uint8_t *aDest, int dstW, int chrDstW)
--- a/libswscale/swscale_template.c	Fri Aug 14 09:31:16 2009 +0000
+++ b/libswscale/swscale_template.c	Fri Aug 14 15:52:40 2009 +0000
@@ -2813,6 +2813,15 @@
             {
                 const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
                 if ((dstY&chrSkipMask) || isGray(dstFormat)) uDest=vDest= NULL; //FIXME split functions in lumi / chromi
+                if (is16BPS(dstFormat))
+                {
+                    yuv2yuvX16inC(
+                        vLumFilter+dstY*vLumFilterSize   , lumSrcPtr, vLumFilterSize,
+                        vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
+                        alpSrcPtr, (uint16_t *) dest, (uint16_t *) uDest, (uint16_t *) vDest, (uint16_t *) aDest, dstW, chrDstW,
+                        dstFormat);
+                }
+                else
                 if (vLumFilterSize == 1 && vChrFilterSize == 1) // unscaled YV12
                 {
                     int16_t *lumBuf = lumPixBuf[0];
@@ -2898,10 +2907,21 @@
             {
                 const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
                 if ((dstY&chrSkipMask) || isGray(dstFormat)) uDest=vDest= NULL; //FIXME split functions in lumi / chromi
+                if (is16BPS(dstFormat))
+                {
+                    yuv2yuvX16inC(
+                        vLumFilter+dstY*vLumFilterSize   , lumSrcPtr, vLumFilterSize,
+                        vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
+                        alpSrcPtr, (uint16_t *) dest, (uint16_t *) uDest, (uint16_t *) vDest, (uint16_t *) aDest, dstW, chrDstW,
+                        dstFormat);
+                }
+                else
+                {
                 yuv2yuvXinC(
                     vLumFilter+dstY*vLumFilterSize   , lumSrcPtr, vLumFilterSize,
                     vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
                     alpSrcPtr, dest, uDest, vDest, aDest, dstW, chrDstW);
+                }
             }
             else
             {