From 353d20df59075d442e943f00c7fcb8bc7784089b Mon Sep 17 00:00:00 2001
From: Pedro Arthur <bygrandao@gmail.com>
Date: Sun, 21 Jun 2015 21:57:16 -0300
Subject: [PATCH] swscale: plug chroma horizontal scaling

---
 libswscale/slice.c            | 66 +++++++++++++++++++++++++++++++------------
 libswscale/swscale.c          | 13 +++++++--
 libswscale/swscale_internal.h |  1 +
 3 files changed, 59 insertions(+), 21 deletions(-)

diff --git a/libswscale/slice.c b/libswscale/slice.c
index 95dc9b7..770b974 100644
--- a/libswscale/slice.c
+++ b/libswscale/slice.c
@@ -368,13 +368,24 @@ static int init_desc_chscale(SwsFilterDescriptor *desc, SwsSlice *src, SwsSlice
 int ff_init_filters(SwsContext * c)
 {
     int i;
-    int numDescPerChannel;
-    int need_convert = c->lumToYV12 || c->readLumPlanar || c->alpToYV12 || c->readAlpPlanar;
+    int index;
+    int num_ydesc;
+    int num_cdesc;
+    int need_lum_conv = c->lumToYV12 || c->readLumPlanar || c->alpToYV12 || c->readAlpPlanar;
+    int need_chr_conv = c->chrToYV12 || c->readChrPlanar;
+    int srcIdx, dstIdx;
 
-    numDescPerChannel= need_convert ? 2 : 1;
-    c->numSlice = numDescPerChannel + 1;
+    uint32_t * pal = usePal(c->srcFormat) ? c->pal_yuv : (uint32_t*)c->input_rgb2yuv_table;
 
-    c->numDesc = (c->needs_hcscale ? 2 : 1) * numDescPerChannel;
+    num_ydesc = need_lum_conv ? 2 : 1;
+    num_cdesc = c->needs_hcscale ? (need_chr_conv ? 2 : 1) : 0;
+
+    c->numSlice = FFMAX(num_ydesc, num_cdesc) + 1;
+    c->numDesc = num_ydesc + num_cdesc;
+    c->descIndex[0] = num_ydesc;
+    c->descIndex[1] = num_ydesc + num_cdesc;
+
+    
 
     c->desc = av_malloc_array(sizeof(SwsFilterDescriptor), c->numDesc);
     c->slice = av_malloc_array(sizeof(SwsSlice), c->numSlice);
@@ -383,24 +394,43 @@ int ff_init_filters(SwsContext * c)
         alloc_slice(&c->slice[i], c->srcFormat, c->vLumFilterSize, c->vChrFilterSize, c->chrSrcHSubSample, c->chrSrcVSubSample);
     alloc_slice(&c->slice[i], c->srcFormat, c->vLumFilterSize, c->vChrFilterSize, c->chrDstHSubSample, c->chrDstVSubSample);
 
-    i = 0;
-    if (need_convert)
-    {
-        init_desc_fmt_convert(&c->desc[i], &c->slice[i], &c->slice[i+1], usePal(c->srcFormat) ? c->pal_yuv : (uint32_t*)c->input_rgb2yuv_table);
-        init_slice_1(&c->slice[i+1], c->formatConvBuffer, (c->formatConvBuffer + FFALIGN(c->srcW*2+78, 16)), c->srcW, 0, c->vLumFilterSize);
-        c->desc[i].alpha = c->alpPixBuf != 0;
+    index = 0;
+    srcIdx = 0;
+    dstIdx = 1;
 
-        if (c->needs_hcscale)
-            init_desc_cfmt_convert(&c->desc[i+numDescPerChannel], &c->slice[i], &c->slice[i+1], usePal(c->srcFormat) ? c->pal_yuv : (uint32_t*)c->input_rgb2yuv_table);
+    // temp slice for color space conversion
+    if (need_lum_conv || need_chr_conv)
+        init_slice_1(&c->slice[dstIdx], c->formatConvBuffer, (c->formatConvBuffer + FFALIGN(c->srcW*2+78, 16)), c->srcW, 0, c->vLumFilterSize);
 
-        ++i;
+    if (need_lum_conv)
+    {
+        init_desc_fmt_convert(&c->desc[index], &c->slice[srcIdx], &c->slice[dstIdx], pal);
+        c->desc[index].alpha = c->alpPixBuf != 0;
+        ++index;
+        srcIdx = dstIdx;
     }
 
-    
-    init_desc_hscale(&c->desc[i], &c->slice[i], &c->slice[i+1], c->hLumFilter, c->hLumFilterPos, c->hLumFilterSize, c->lumXInc);
-    c->desc[i].alpha = c->alpPixBuf != 0;
+
+    dstIdx = FFMAX(num_ydesc, num_cdesc);
+    init_desc_hscale(&c->desc[index], &c->slice[index], &c->slice[dstIdx], c->hLumFilter, c->hLumFilterPos, c->hLumFilterSize, c->lumXInc);
+    c->desc[index].alpha = c->alpPixBuf != 0;
+
+
+    ++index;
     if (c->needs_hcscale)
-        init_desc_chscale(&c->desc[i+numDescPerChannel], &c->slice[i], &c->slice[i+1], c->hChrFilter, c->hChrFilterPos, c->hChrFilterSize, c->chrXInc);
+    {
+        srcIdx = 0;
+        dstIdx = 1;
+        if (need_chr_conv)
+        {
+            init_desc_cfmt_convert(&c->desc[index], &c->slice[srcIdx], &c->slice[dstIdx], pal);
+            ++index;
+            srcIdx = dstIdx;
+        }
+
+        dstIdx = FFMAX(num_ydesc, num_cdesc);
+        init_desc_chscale(&c->desc[index], &c->slice[srcIdx], &c->slice[dstIdx], c->hChrFilter, c->hChrFilterPos, c->hChrFilterSize, c->chrXInc);
+    }
 
     return 1;
 }
diff --git a/libswscale/swscale.c b/libswscale/swscale.c
index eaaefc3..4770f13 100644
--- a/libswscale/swscale.c
+++ b/libswscale/swscale.c
@@ -375,9 +375,11 @@ static int swscale(SwsContext *c, const uint8_t *src[],
 
     int numDesc = c->numDesc;
     int lumStart = 0;
-    int lumEnd = c->needs_hcscale ? numDesc / 2 : numDesc;
+    int lumEnd = c->descIndex[0];
+    int chrStart = lumEnd;
+    int chrEnd = c->descIndex[1];
     SwsSlice *src_slice = &c->slice[lumStart];
-    SwsSlice *dst_slice = &c->slice[lumEnd];
+    SwsSlice *dst_slice = &c->slice[c->numSlice-1];
     SwsFilterDescriptor *desc = c->desc;
     int16_t **line_pool[4];
 
@@ -549,17 +551,22 @@ static int swscale(SwsContext *c, const uint8_t *src[],
                 src[2] + (lastInChrBuf + 1 - chrSrcSliceY) * srcStride[2],
                 src[3] + (lastInChrBuf + 1 - chrSrcSliceY) * srcStride[3],
             };
+            int i;
             chrBufIndex++;
             av_assert0(chrBufIndex < 2 * vChrBufSize);
             av_assert0(lastInChrBuf + 1 - chrSrcSliceY < (chrSrcSliceH));
             av_assert0(lastInChrBuf + 1 - chrSrcSliceY >= 0);
             // FIXME replace parameters through context struct (some at least)
-
+#if NEW_FILTER
+            for (i = chrStart; i < chrEnd; ++i)
+                desc[i].process(c, &desc[i], lastInChrBuf + 1, 1);
+#else
             if (c->needs_hcscale)
                 hcscale(c, chrUPixBuf[chrBufIndex], chrVPixBuf[chrBufIndex],
                         chrDstW, src1, chrSrcW, chrXInc,
                         hChrFilter, hChrFilterPos, hChrFilterSize,
                         formatConvBuffer, pal);
+#endif
             lastInChrBuf++;
             DEBUG_BUFFERS("\t\tchrBufIndex %d: lastInChrBuf: %d\n",
                           chrBufIndex, lastInChrBuf);
diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h
index f7d4f56..0ba37bd 100644
--- a/libswscale/swscale_internal.h
+++ b/libswscale/swscale_internal.h
@@ -323,6 +323,7 @@ typedef struct SwsContext {
     uint16_t *inv_gamma;
 
     int numDesc;
+    int descIndex[2];
     int numSlice;
     struct SwsSlice *slice;
     struct SwsFilterDescriptor *desc;
-- 
1.9.1

