From: Michael Niedermayer <[email protected]>

Signed-off-by: Anton Khirnov <[email protected]>
---
 libswscale/rgb2rgb.c          |    3 +++
 libswscale/rgb2rgb.h          |    4 ++++
 libswscale/rgb2rgb_template.c |   19 +++++++++++++++++++
 libswscale/swscale_unscaled.c |   26 ++++++++++++++++++++++++++
 4 files changed, 52 insertions(+)

diff --git a/libswscale/rgb2rgb.c b/libswscale/rgb2rgb.c
index 21adfe1..3fb3921 100644
--- a/libswscale/rgb2rgb.c
+++ b/libswscale/rgb2rgb.c
@@ -82,6 +82,9 @@ void (*planar2x)(const uint8_t *src, uint8_t *dst, int width, 
int height,
 void (*interleaveBytes)(const uint8_t *src1, const uint8_t *src2, uint8_t *dst,
                         int width, int height, int src1Stride,
                         int src2Stride, int dstStride);
+void (*deinterleaveBytes)(const uint8_t *src, uint8_t *dst1, uint8_t *dst2,
+                          int width, int height, int srcStride,
+                          int dst1Stride, int dst2Stride);
 void (*vu9_to_vu12)(const uint8_t *src1, const uint8_t *src2,
                     uint8_t *dst1, uint8_t *dst2,
                     int width, int height,
diff --git a/libswscale/rgb2rgb.h b/libswscale/rgb2rgb.h
index 79c378d..f47b04e 100644
--- a/libswscale/rgb2rgb.h
+++ b/libswscale/rgb2rgb.h
@@ -129,6 +129,10 @@ extern void (*interleaveBytes)(const uint8_t *src1, const 
uint8_t *src2, uint8_t
                                int width, int height, int src1Stride,
                                int src2Stride, int dstStride);
 
+extern void (*deinterleaveBytes)(const uint8_t *src, uint8_t *dst1, uint8_t 
*dst2,
+                                 int width, int height, int srcStride,
+                                 int dst1Stride, int dst2Stride);
+
 extern void (*vu9_to_vu12)(const uint8_t *src1, const uint8_t *src2,
                            uint8_t *dst1, uint8_t *dst2,
                            int width, int height,
diff --git a/libswscale/rgb2rgb_template.c b/libswscale/rgb2rgb_template.c
index 3da2b0b..65ea5dd 100644
--- a/libswscale/rgb2rgb_template.c
+++ b/libswscale/rgb2rgb_template.c
@@ -708,6 +708,24 @@ static void interleaveBytes_c(const uint8_t *src1, const 
uint8_t *src2,
     }
 }
 
+static void deinterleaveBytes_c(const uint8_t *src, uint8_t *dst1, uint8_t 
*dst2,
+                                int width, int height, int srcStride,
+                                int dst1Stride, int dst2Stride)
+{
+    int h;
+
+    for (h = 0; h < height; h++) {
+        int w;
+        for (w = 0; w < width; w++) {
+            dst1[w] = src[2 * w + 0];
+            dst2[w] = src[2 * w + 1];
+        }
+        src  += srcStride;
+        dst1 += dst1Stride;
+        dst2 += dst2Stride;
+    }
+}
+
 static inline void vu9_to_vu12_c(const uint8_t *src1, const uint8_t *src2,
                                  uint8_t *dst1, uint8_t *dst2,
                                  int width, int height,
@@ -937,6 +955,7 @@ static av_cold void rgb2rgb_init_c(void)
     planar2x           = planar2x_c;
     rgb24toyv12        = rgb24toyv12_c;
     interleaveBytes    = interleaveBytes_c;
+    deinterleaveBytes  = deinterleaveBytes_c;
     vu9_to_vu12        = vu9_to_vu12_c;
     yvu9_to_yuy2       = yvu9_to_yuy2_c;
 
diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c
index 8c207b1..61f0d47 100644
--- a/libswscale/swscale_unscaled.c
+++ b/libswscale/swscale_unscaled.c
@@ -155,6 +155,27 @@ static int planarToNv12Wrapper(SwsContext *c, const 
uint8_t *src[],
     return srcSliceH;
 }
 
+static int nv12ToPlanarWrapper(SwsContext *c, const uint8_t *src[],
+                               int srcStride[], int srcSliceY,
+                               int srcSliceH, uint8_t *dstParam[],
+                               int dstStride[])
+{
+    uint8_t *dst1 = dstParam[1] + dstStride[1] * srcSliceY / 2;
+    uint8_t *dst2 = dstParam[2] + dstStride[2] * srcSliceY / 2;
+
+    copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
+              dstParam[0], dstStride[0]);
+
+    if (c->srcFormat == AV_PIX_FMT_NV12)
+        deinterleaveBytes(src[1], dst1, dst2,c->srcW / 2, srcSliceH / 2,
+                          srcStride[1], dstStride[1], dstStride[2]);
+    else
+        deinterleaveBytes(src[1], dst2, dst1, c->srcW / 2, srcSliceH / 2,
+                          srcStride[1], dstStride[2], dstStride[1]);
+
+    return srcSliceH;
+}
+
 static int planarToYuy2Wrapper(SwsContext *c, const uint8_t *src[],
                                int srcStride[], int srcSliceY, int srcSliceH,
                                uint8_t *dstParam[], int dstStride[])
@@ -981,6 +1002,11 @@ void ff_get_unscaled_swscale(SwsContext *c)
         (dstFormat == AV_PIX_FMT_NV12 || dstFormat == AV_PIX_FMT_NV21)) {
         c->swscale = planarToNv12Wrapper;
     }
+    /* nv12_to_yv12 */
+    if (dstFormat == AV_PIX_FMT_YUV420P &&
+        (srcFormat == AV_PIX_FMT_NV12 || srcFormat == AV_PIX_FMT_NV21)) {
+        c->swscale = nv12ToPlanarWrapper;
+    }
     /* yuv2bgr */
     if ((srcFormat == AV_PIX_FMT_YUV420P || srcFormat == AV_PIX_FMT_YUV422P ||
          srcFormat == AV_PIX_FMT_YUVA420P) && isAnyRGB(dstFormat) &&
-- 
1.7.10.4

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to