aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2013-11-19 14:17:26 +0100
committerMichael Niedermayer <michaelni@gmx.at>2013-11-19 15:13:48 +0100
commitef627bf9ecddfa888d4c6e4fd633852798c3b4a9 (patch)
treeacda9d2b5e84c4435999c1b7d4462f2a951c4215
parent722fb81dc5c8546eb6498629db7c8ebe2f9545c2 (diff)
downloadffmpeg-ef627bf9ecddfa888d4c6e4fd633852798c3b4a9.tar.gz
swscale: add nv12/nv21->yuv420 converter
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--libswscale/rgb2rgb.c3
-rw-r--r--libswscale/rgb2rgb.h4
-rw-r--r--libswscale/rgb2rgb_template.c19
-rw-r--r--libswscale/swscale_unscaled.c26
4 files changed, 52 insertions, 0 deletions
diff --git a/libswscale/rgb2rgb.c b/libswscale/rgb2rgb.c
index ec9ff7151f..cf877fbae0 100644
--- a/libswscale/rgb2rgb.c
+++ b/libswscale/rgb2rgb.c
@@ -83,6 +83,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 340cc70205..5df5dea420 100644
--- a/libswscale/rgb2rgb.h
+++ b/libswscale/rgb2rgb.h
@@ -135,6 +135,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 98e3a1472e..56e735f6ca 100644
--- a/libswscale/rgb2rgb_template.c
+++ b/libswscale/rgb2rgb_template.c
@@ -693,6 +693,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,
@@ -922,6 +940,7 @@ static av_cold void rgb2rgb_init_c(void)
planar2x = planar2x_c;
ff_rgb24toyv12 = ff_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 9f6d8193d8..bd9e7a59e2 100644
--- a/libswscale/swscale_unscaled.c
+++ b/libswscale/swscale_unscaled.c
@@ -176,6 +176,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[])
@@ -1212,6 +1233,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) &&