Browse code

swscale: add nv12/nv21->yuv420 converter

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>

Michael Niedermayer authored on 2013/11/19 22:17:26
Showing 4 changed files
... ...
@@ -83,6 +83,9 @@ void (*planar2x)(const uint8_t *src, uint8_t *dst, int width, int height,
83 83
 void (*interleaveBytes)(const uint8_t *src1, const uint8_t *src2, uint8_t *dst,
84 84
                         int width, int height, int src1Stride,
85 85
                         int src2Stride, int dstStride);
86
+void (*deinterleaveBytes)(const uint8_t *src, uint8_t *dst1, uint8_t *dst2,
87
+                        int width, int height, int srcStride,
88
+                        int dst1Stride, int dst2Stride);
86 89
 void (*vu9_to_vu12)(const uint8_t *src1, const uint8_t *src2,
87 90
                     uint8_t *dst1, uint8_t *dst2,
88 91
                     int width, int height,
... ...
@@ -135,6 +135,10 @@ extern void (*interleaveBytes)(const uint8_t *src1, const uint8_t *src2, uint8_t
135 135
                                int width, int height, int src1Stride,
136 136
                                int src2Stride, int dstStride);
137 137
 
138
+extern void (*deinterleaveBytes)(const uint8_t *src, uint8_t *dst1, uint8_t *dst2,
139
+                                 int width, int height, int srcStride,
140
+                                 int dst1Stride, int dst2Stride);
141
+
138 142
 extern void (*vu9_to_vu12)(const uint8_t *src1, const uint8_t *src2,
139 143
                            uint8_t *dst1, uint8_t *dst2,
140 144
                            int width, int height,
... ...
@@ -693,6 +693,24 @@ static void interleaveBytes_c(const uint8_t *src1, const uint8_t *src2,
693 693
     }
694 694
 }
695 695
 
696
+static void deinterleaveBytes_c(const uint8_t *src, uint8_t *dst1, uint8_t *dst2,
697
+                                int width, int height, int srcStride,
698
+                                int dst1Stride, int dst2Stride)
699
+{
700
+    int h;
701
+
702
+    for (h = 0; h < height; h++) {
703
+        int w;
704
+        for (w = 0; w < width; w++) {
705
+            dst1[w] = src[2 * w + 0];
706
+            dst2[w] = src[2 * w + 1];
707
+        }
708
+        src += srcStride;
709
+        dst1 += dst1Stride;
710
+        dst2 += dst2Stride;
711
+    }
712
+}
713
+
696 714
 static inline void vu9_to_vu12_c(const uint8_t *src1, const uint8_t *src2,
697 715
                                  uint8_t *dst1, uint8_t *dst2,
698 716
                                  int width, int height,
... ...
@@ -922,6 +940,7 @@ static av_cold void rgb2rgb_init_c(void)
922 922
     planar2x           = planar2x_c;
923 923
     ff_rgb24toyv12     = ff_rgb24toyv12_c;
924 924
     interleaveBytes    = interleaveBytes_c;
925
+    deinterleaveBytes  = deinterleaveBytes_c;
925 926
     vu9_to_vu12        = vu9_to_vu12_c;
926 927
     yvu9_to_yuy2       = yvu9_to_yuy2_c;
927 928
 
... ...
@@ -176,6 +176,27 @@ static int planarToNv12Wrapper(SwsContext *c, const uint8_t *src[],
176 176
     return srcSliceH;
177 177
 }
178 178
 
179
+static int nv12ToPlanarWrapper(SwsContext *c, const uint8_t *src[],
180
+                               int srcStride[], int srcSliceY,
181
+                               int srcSliceH, uint8_t *dstParam[],
182
+                               int dstStride[])
183
+{
184
+    uint8_t *dst1 = dstParam[1] + dstStride[1] * srcSliceY / 2;
185
+    uint8_t *dst2 = dstParam[2] + dstStride[2] * srcSliceY / 2;
186
+
187
+    copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
188
+              dstParam[0], dstStride[0]);
189
+
190
+    if (c->srcFormat == AV_PIX_FMT_NV12)
191
+        deinterleaveBytes(src[1], dst1, dst2,c->srcW / 2, srcSliceH / 2,
192
+                          srcStride[1], dstStride[1], dstStride[2]);
193
+    else
194
+        deinterleaveBytes(src[1], dst2, dst1, c->srcW / 2, srcSliceH / 2,
195
+                          srcStride[1], dstStride[2], dstStride[1]);
196
+
197
+    return srcSliceH;
198
+}
199
+
179 200
 static int planarToYuy2Wrapper(SwsContext *c, const uint8_t *src[],
180 201
                                int srcStride[], int srcSliceY, int srcSliceH,
181 202
                                uint8_t *dstParam[], int dstStride[])
... ...
@@ -1212,6 +1233,11 @@ void ff_get_unscaled_swscale(SwsContext *c)
1212 1212
         (dstFormat == AV_PIX_FMT_NV12 || dstFormat == AV_PIX_FMT_NV21)) {
1213 1213
         c->swscale = planarToNv12Wrapper;
1214 1214
     }
1215
+    /* nv12_to_yv12 */
1216
+    if (dstFormat == AV_PIX_FMT_YUV420P &&
1217
+        (srcFormat == AV_PIX_FMT_NV12 || srcFormat == AV_PIX_FMT_NV21)) {
1218
+        c->swscale = nv12ToPlanarWrapper;
1219
+    }
1215 1220
     /* yuv2bgr */
1216 1221
     if ((srcFormat == AV_PIX_FMT_YUV420P || srcFormat == AV_PIX_FMT_YUV422P ||
1217 1222
          srcFormat == AV_PIX_FMT_YUVA420P) && isAnyRGB(dstFormat) &&