diff options
author | Nicolas Dufresne <nicolas.dufresne@collabora.com> | 2012-11-01 12:05:25 +0100 |
---|---|---|
committer | Olivier CrĂȘte <olivier.crete@collabora.com> | 2012-11-02 14:14:40 +0100 |
commit | d263c3690d2cbc4d328dc4b9e81133608747ecb9 (patch) | |
tree | 0d8a0e712ad0fa3336a64e4c320a696ee8041380 | |
parent | 108da2311490531002915f71306b64426df31678 (diff) | |
download | gstreamer-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.c | 72 |
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}, |