From 2c0b294005a6627a4fad1b73aa2af4aff70c684c Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Thu, 24 Nov 2011 11:04:10 +0100 Subject: [PATCH] videoconvert: fix odd width and height handling in some fastpath cases --- gst/videoconvert/videoconvert.c | 105 ++++++++++++++++++++++++++------ 1 file changed, 88 insertions(+), 17 deletions(-) diff --git a/gst/videoconvert/videoconvert.c b/gst/videoconvert/videoconvert.c index 572c684da6..30e7b16fcc 100644 --- a/gst/videoconvert/videoconvert.c +++ b/gst/videoconvert/videoconvert.c @@ -1817,7 +1817,7 @@ convert_I420_YUY2 (VideoConvert * convert, GstVideoFrame * dest, { int i; - for (i = 0; i < convert->height; i += 2) { + for (i = 0; i < GST_ROUND_DOWN_2 (convert->height); i += 2) { cogorc_convert_I420_YUY2 (FRAME_GET_LINE (dest, 0, i), FRAME_GET_LINE (dest, 0, i + 1), FRAME_GET_LINE (src, 0, i), @@ -1825,6 +1825,12 @@ convert_I420_YUY2 (VideoConvert * convert, GstVideoFrame * dest, FRAME_GET_LINE (src, 1, i >> 1), FRAME_GET_LINE (src, 2, i >> 1), (convert->width + 1) / 2); } + + /* now handle last line */ + if (convert->height & 1) { + getline_I420 (convert, convert->tmpline, src, convert->height - 1); + putline_YUY2 (convert, dest, convert->tmpline, convert->height - 1); + } } static void @@ -1833,7 +1839,7 @@ convert_I420_UYVY (VideoConvert * convert, GstVideoFrame * dest, { int i; - for (i = 0; i < convert->height; i += 2) { + for (i = 0; i < GST_ROUND_DOWN_2 (convert->height); i += 2) { cogorc_convert_I420_UYVY (FRAME_GET_LINE (dest, 0, i), FRAME_GET_LINE (dest, 0, i + 1), FRAME_GET_LINE (src, 0, i), @@ -1841,6 +1847,12 @@ convert_I420_UYVY (VideoConvert * convert, GstVideoFrame * dest, FRAME_GET_LINE (src, 1, i >> 1), FRAME_GET_LINE (src, 2, i >> 1), (convert->width + 1) / 2); } + + /* now handle last line */ + if (convert->height & 1) { + getline_I420 (convert, convert->tmpline, src, convert->height - 1); + putline_UYVY (convert, dest, convert->tmpline, convert->height - 1); + } } static void @@ -1849,7 +1861,7 @@ convert_I420_AYUV (VideoConvert * convert, GstVideoFrame * dest, { int i; - for (i = 0; i < convert->height; i += 2) { + for (i = 0; i < GST_ROUND_DOWN_2 (convert->height); i += 2) { cogorc_convert_I420_AYUV (FRAME_GET_LINE (dest, 0, i), FRAME_GET_LINE (dest, 0, i + 1), FRAME_GET_LINE (src, 0, i), @@ -1857,6 +1869,12 @@ convert_I420_AYUV (VideoConvert * convert, GstVideoFrame * dest, FRAME_GET_LINE (src, 1, i >> 1), FRAME_GET_LINE (src, 2, i >> 1), convert->width); } + + /* now handle last line */ + if (convert->height & 1) { + getline_I420 (convert, convert->tmpline, src, convert->height - 1); + putline_AYUV (convert, dest, convert->tmpline, convert->height - 1); + } } static void @@ -1889,23 +1907,31 @@ convert_I420_Y444 (VideoConvert * convert, GstVideoFrame * dest, cogorc_planar_chroma_420_444 (FRAME_GET_LINE (dest, 1, 0), 2 * FRAME_GET_STRIDE (dest, 1), FRAME_GET_LINE (dest, 1, 1), 2 * FRAME_GET_STRIDE (dest, 1), FRAME_GET_LINE (src, 1, 0), - FRAME_GET_STRIDE (src, 1), (convert->width + 1) / 2, - (convert->height + 1) / 2); + FRAME_GET_STRIDE (src, 1), (convert->width + 1) / 2, convert->height / 2); cogorc_planar_chroma_420_444 (FRAME_GET_LINE (dest, 2, 0), 2 * FRAME_GET_STRIDE (dest, 2), FRAME_GET_LINE (dest, 2, 1), 2 * FRAME_GET_STRIDE (dest, 2), FRAME_GET_LINE (src, 2, 0), - FRAME_GET_STRIDE (src, 2), (convert->width + 1) / 2, - (convert->height + 1) / 2); + FRAME_GET_STRIDE (src, 2), (convert->width + 1) / 2, convert->height / 2); + + /* now handle last line */ + if (convert->height & 1) { + getline_I420 (convert, convert->tmpline, src, convert->height - 1); + putline_Y444 (convert, dest, convert->tmpline, convert->height - 1); + } } static void convert_YUY2_I420 (VideoConvert * convert, GstVideoFrame * dest, const GstVideoFrame * src) { - int i; + int i, h; - for (i = 0; i < convert->height; i += 2) { + h = convert->height; + if (convert->width & 1) + h--; + + for (i = 0; i < h; i += 2) { cogorc_convert_YUY2_I420 (FRAME_GET_LINE (dest, 0, i), FRAME_GET_LINE (dest, 0, i + 1), FRAME_GET_LINE (dest, 1, i >> 1), @@ -1913,6 +1939,12 @@ convert_YUY2_I420 (VideoConvert * convert, GstVideoFrame * dest, FRAME_GET_LINE (src, 0, i), FRAME_GET_LINE (src, 0, i + 1), (convert->width + 1) / 2); } + + /* now handle last line */ + if (convert->width & 1) { + getline_YUY2 (convert, convert->tmpline, src, convert->height - 1); + putline_I420 (convert, dest, convert->tmpline, convert->height - 1); + } } static void @@ -1921,7 +1953,14 @@ convert_YUY2_AYUV (VideoConvert * convert, GstVideoFrame * dest, { cogorc_convert_YUY2_AYUV (FRAME_GET_LINE (dest, 0, 0), FRAME_GET_STRIDE (dest, 0), FRAME_GET_LINE (src, 0, 0), - FRAME_GET_STRIDE (src, 0), (convert->width + 1) / 2, convert->height); + FRAME_GET_STRIDE (src, 0), (convert->width + 1) / 2, + convert->width & 1 ? convert->height - 1 : convert->height); + + /* now handle last line */ + if (convert->width & 1) { + getline_YUY2 (convert, convert->tmpline, src, convert->height - 1); + putline_AYUV (convert, dest, convert->tmpline, convert->height - 1); + } } static void @@ -1953,7 +1992,7 @@ convert_UYVY_I420 (VideoConvert * convert, GstVideoFrame * dest, { int i; - for (i = 0; i < convert->height; i += 2) { + for (i = 0; i < GST_ROUND_DOWN_2 (convert->height); i += 2) { cogorc_convert_UYVY_I420 (FRAME_GET_LINE (dest, 0, i), FRAME_GET_LINE (dest, 0, i + 1), FRAME_GET_LINE (dest, 1, i >> 1), @@ -1961,6 +2000,12 @@ convert_UYVY_I420 (VideoConvert * convert, GstVideoFrame * dest, FRAME_GET_LINE (src, 0, i), FRAME_GET_LINE (src, 0, i + 1), (convert->width + 1) / 2); } + + /* now handle last line */ + if (convert->height & 1) { + getline_UYVY (convert, convert->tmpline, src, convert->height - 1); + putline_I420 (convert, dest, convert->tmpline, convert->height - 1); + } } static void @@ -1969,7 +2014,14 @@ convert_UYVY_AYUV (VideoConvert * convert, GstVideoFrame * dest, { cogorc_convert_UYVY_AYUV (FRAME_GET_LINE (dest, 0, 0), FRAME_GET_STRIDE (dest, 0), FRAME_GET_LINE (src, 0, 0), - FRAME_GET_STRIDE (src, 0), (convert->width + 1) / 2, convert->height); + FRAME_GET_STRIDE (src, 0), (convert->width + 1) / 2, + convert->width & 1 ? convert->height - 1 : convert->height); + + /* now handle last line */ + if (convert->width & 1) { + getline_UYVY (convert, convert->tmpline, src, convert->height - 1); + putline_AYUV (convert, dest, convert->tmpline, convert->height - 1); + } } static void @@ -2042,7 +2094,14 @@ convert_AYUV_Y42B (VideoConvert * convert, GstVideoFrame * dest, FRAME_GET_STRIDE (dest, 0), FRAME_GET_LINE (dest, 1, 0), FRAME_GET_STRIDE (dest, 1), FRAME_GET_LINE (dest, 2, 0), FRAME_GET_STRIDE (dest, 2), FRAME_GET_LINE (src, 0, 0), - FRAME_GET_STRIDE (src, 0), (convert->width + 1) / 2, convert->height); + FRAME_GET_STRIDE (src, 0), (convert->width + 1) / 2, + convert->width & 1 ? convert->height - 1 : convert->height); + + /* now handle last line */ + if (convert->height & 1) { + getline_AYUV (convert, convert->tmpline, src, convert->height - 1); + putline_Y42B (convert, dest, convert->tmpline, convert->height - 1); + } } static void @@ -2068,13 +2127,19 @@ convert_Y42B_I420 (VideoConvert * convert, GstVideoFrame * dest, FRAME_GET_STRIDE (dest, 1), FRAME_GET_LINE (src, 1, 0), 2 * FRAME_GET_STRIDE (src, 1), FRAME_GET_LINE (src, 1, 1), 2 * FRAME_GET_STRIDE (src, 1), (convert->width + 1) / 2, - (convert->height + 1) / 2); + convert->height / 2); cogorc_planar_chroma_422_420 (FRAME_GET_LINE (dest, 2, 0), FRAME_GET_STRIDE (dest, 2), FRAME_GET_LINE (src, 2, 0), 2 * FRAME_GET_STRIDE (src, 2), FRAME_GET_LINE (src, 2, 1), 2 * FRAME_GET_STRIDE (src, 2), (convert->width + 1) / 2, - (convert->height + 1) / 2); + convert->height / 2); + + /* now handle last line */ + if (convert->height & 1) { + getline_Y42B (convert, convert->tmpline, src, convert->height - 1); + putline_I420 (convert, dest, convert->tmpline, convert->height - 1); + } } static void @@ -2139,13 +2204,19 @@ convert_Y444_I420 (VideoConvert * convert, GstVideoFrame * dest, FRAME_GET_STRIDE (dest, 1), FRAME_GET_LINE (src, 1, 0), 2 * FRAME_GET_STRIDE (src, 1), FRAME_GET_LINE (src, 1, 1), 2 * FRAME_GET_STRIDE (src, 1), (convert->width + 1) / 2, - (convert->height + 1) / 2); + convert->height / 2); cogorc_planar_chroma_444_420 (FRAME_GET_LINE (dest, 2, 0), FRAME_GET_STRIDE (dest, 2), FRAME_GET_LINE (src, 2, 0), 2 * FRAME_GET_STRIDE (src, 2), FRAME_GET_LINE (src, 2, 1), 2 * FRAME_GET_STRIDE (src, 2), (convert->width + 1) / 2, - (convert->height + 1) / 2); + convert->height / 2); + + /* now handle last line */ + if (convert->height & 1) { + getline_Y444 (convert, convert->tmpline, src, convert->height - 1); + putline_I420 (convert, dest, convert->tmpline, convert->height - 1); + } } static void