summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Dufresne <nicolas.dufresne@collabora.com>2012-11-01 12:05:25 +0100
committerOlivier CrĂȘte <olivier.crete@collabora.com>2012-11-02 14:14:40 +0100
commitd263c3690d2cbc4d328dc4b9e81133608747ecb9 (patch)
tree0d8a0e712ad0fa3336a64e4c320a696ee8041380
parent108da2311490531002915f71306b64426df31678 (diff)
downloadgstreamer-plugins-base-d263c3690d2cbc4d328dc4b9e81133608747ecb9.tar.gz
ffmpegcolorspace: Add NV12/NV21 to I420 convertion
https://bugzilla.gnome.org/show_bug.cgi?id=687350
-rw-r--r--gst/ffmpegcolorspace/imgconvert.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/gst/ffmpegcolorspace/imgconvert.c b/gst/ffmpegcolorspace/imgconvert.c
index c670e25ff..54d325102 100644
--- a/gst/ffmpegcolorspace/imgconvert.c
+++ b/gst/ffmpegcolorspace/imgconvert.c
@@ -1555,6 +1555,41 @@ nv12_to_yuv444p (AVPicture * dst, const AVPicture * src, int width, int height)
}
}
+static void
+nv12_to_yuv420p (AVPicture * dst, const AVPicture * src, int width, int height)
+{
+ uint8_t *src_c = src->data[1];
+ uint8_t *dst_cb = dst->data[1];
+ uint8_t *dst_cr = dst->data[2];
+ int src_c_wrap, dst_cb_wrap, dst_cr_wrap;
+ int c_width, c_height, w, h;
+
+ /* Compute Cb/Cr width and height including odd cases */
+ c_width = width / 2 + (width & 1);
+ c_height = height / 2 + (height & 1);
+
+ /* Compute extra padding per line */
+ src_c_wrap = src->linesize[1] - c_width * 2;
+ dst_cb_wrap = dst->linesize[1] - c_width;
+ dst_cr_wrap = dst->linesize[2] - c_width;
+
+ /* Copy Y plane */
+ memcpy (dst->data[0], src->data[0], src->linesize[0] * height);
+
+ /* Split UY plane to seperate U and V planes */
+ for (h = c_height; h--;) {
+ for (w = c_width; w--;) {
+ *dst_cb++ = *src_c++;
+ *dst_cr++ = *src_c++;
+ }
+
+ /* Skip to next line */
+ src_c += src_c_wrap;
+ dst_cb += dst_cb_wrap;
+ dst_cr += dst_cr_wrap;
+ }
+}
+
#define nv21_to_nv12 nv12_to_nv21
static void
@@ -1642,6 +1677,41 @@ nv21_to_yuv444p (AVPicture * dst, const AVPicture * src, int width, int height)
}
static void
+nv21_to_yuv420p (AVPicture * dst, const AVPicture * src, int width, int height)
+{
+ uint8_t *src_c = src->data[1];
+ uint8_t *dst_cb = dst->data[1];
+ uint8_t *dst_cr = dst->data[2];
+ int src_c_wrap, dst_cb_wrap, dst_cr_wrap;
+ int c_width, c_height, w, h;
+
+ /* Compute Cb/Cr width and height including odd cases */
+ c_width = width / 2 + (width & 1);
+ c_height = height / 2 + (height & 1);
+
+ /* Compute extra padding per line */
+ src_c_wrap = src->linesize[1] - c_width * 2;
+ dst_cb_wrap = dst->linesize[1] - c_width;
+ dst_cr_wrap = dst->linesize[2] - c_width;
+
+ /* Copy Y plane */
+ memcpy (dst->data[0], src->data[0], src->linesize[0] * height);
+
+ /* Split UY plane to seperate U and V planes */
+ for (h = c_height; h--;) {
+ for (w = c_width; w--;) {
+ *dst_cr++ = *src_c++;
+ *dst_cb++ = *src_c++;
+ }
+
+ /* Skip to next line */
+ src_c += src_c_wrap;
+ dst_cb += dst_cb_wrap;
+ dst_cr += dst_cr_wrap;
+ }
+}
+
+static void
yuva420p_to_yuv420p (AVPicture * dst, const AVPicture * src, int width,
int height)
{
@@ -3125,6 +3195,7 @@ static ConvertEntry convert_table[] = {
{PIX_FMT_NV12, PIX_FMT_ABGR32, nv12_to_abgr32},
{PIX_FMT_NV12, PIX_FMT_NV21, nv12_to_nv21},
{PIX_FMT_NV12, PIX_FMT_YUV444P, nv12_to_yuv444p},
+ {PIX_FMT_NV12, PIX_FMT_YUV420P, nv12_to_yuv420p},
{PIX_FMT_NV21, PIX_FMT_RGB555, nv21_to_rgb555},
{PIX_FMT_NV21, PIX_FMT_RGB565, nv21_to_rgb565},
@@ -3140,6 +3211,7 @@ static ConvertEntry convert_table[] = {
{PIX_FMT_NV21, PIX_FMT_ABGR32, nv21_to_abgr32},
{PIX_FMT_NV21, PIX_FMT_YUV444P, nv21_to_yuv444p},
{PIX_FMT_NV21, PIX_FMT_NV12, nv21_to_nv12},
+ {PIX_FMT_NV21, PIX_FMT_YUV420P, nv21_to_yuv420p},
{PIX_FMT_YUV422P, PIX_FMT_YUV422, yuv422p_to_yuv422},
{PIX_FMT_YUV422P, PIX_FMT_UYVY422, yuv422p_to_uyvy422},