diff -Naur a/opencv/modules/imgproc/include/opencv2/imgproc/imgproc.hpp b/opencv/modules/imgproc/include/opencv2/imgproc/imgproc.hpp
--- a/opencv/modules/imgproc/include/opencv2/imgproc/imgproc.hpp	2012-03-30 10:37:06 +0200
+++ b/opencv/modules/imgproc/include/opencv2/imgproc/imgproc.hpp	2012-03-30 10:19:33 +0200
@@ -929,7 +914,44 @@
     COLOR_YUV420sp2RGBA = COLOR_YUV2RGBA_NV21,
     COLOR_YUV420sp2BGRA = COLOR_YUV2BGRA_NV21,
     
-    COLOR_COLORCVT_MAX  =100
+
+    COLOR_YUV2RGB_YUYV  = 100,
+    COLOR_YUV2BGR_YUYV  = 101,
+    COLOR_YUV2RGB_UYVY  = 102,
+    COLOR_YUV2BGR_UYVY  = 103,
+    COLOR_YUV2RGB_YUY2  = COLOR_YUV2RGB_YUYV,
+    COLOR_YUV2BGR_YUY2  = COLOR_YUV2BGR_YUYV,
+    COLOR_YUV2RGB_VYUY  = 104,
+    COLOR_YUV2BGR_VYUY  = 105,
+    COLOR_YUV2RGB_YVYU  = 106,
+    COLOR_YUV2BGR_YVYU  = 107,
+
+    COLOR_YUV2RGBA_YUYV = 108,
+    COLOR_YUV2BGRA_YUYV = 109,
+    COLOR_YUV2RGBA_UYVY = 110,
+    COLOR_YUV2BGRA_UYVY = 111,
+    COLOR_YUV2RGBA_YUY2 = COLOR_YUV2RGBA_YUYV,
+    COLOR_YUV2BGRA_YUY2 = COLOR_YUV2BGRA_YUYV,
+    COLOR_YUV2RGBA_VYUY = 112,
+    COLOR_YUV2BGRA_VYUY = 113,
+    COLOR_YUV2RGBA_YVYU = 114,
+    COLOR_YUV2BGRA_YVYU = 115,
+
+    COLOR_YUV2RGB_YV12  = 116,
+    COLOR_YUV2BGR_YV12  = 117,
+    COLOR_YUV2RGB_IYUV  = 118,
+    COLOR_YUV2BGR_IYUV  = 119,
+    COLOR_YUV420p2RGB   = COLOR_YUV2RGB_YV12,
+    COLOR_YUV420p2BGR   = COLOR_YUV2BGR_YV12,
+
+    COLOR_YUV2RGBA_YV12 = 120,
+    COLOR_YUV2BGRA_YV12 = 121,
+    COLOR_YUV2RGBA_IYUV = 122,
+    COLOR_YUV2BGRA_IYUV = 123,
+    COLOR_YUV420p2RGBA  = COLOR_YUV2RGBA_YV12,
+    COLOR_YUV420p2BGRA  = COLOR_YUV2BGRA_YV12,
+
+    COLOR_COLORCVT_MAX  = 124
 };
     
     
diff -Naur a/opencv/modules/imgproc/include/opencv2/imgproc/types_c.h b/opencv/modules/imgproc/include/opencv2/imgproc/types_c.h
--- a/opencv/modules/imgproc/include/opencv2/imgproc/types_c.h	2012-03-30 10:37:03 +0200
+++ b/opencv/modules/imgproc/include/opencv2/imgproc/types_c.h	2012-03-30 10:16:03 +0200
@@ -232,7 +240,43 @@
     CV_YUV420sp2RGBA = CV_YUV2RGBA_NV21,
     CV_YUV420sp2BGRA = CV_YUV2BGRA_NV21,
     
-    CV_COLORCVT_MAX  =100
+    CV_YUV2RGB_YUYV  = 100,
+    CV_YUV2BGR_YUYV  = 101,
+    CV_YUV2RGB_UYVY  = 102,
+    CV_YUV2BGR_UYVY  = 103,
+    CV_YUV2RGB_YUY2  = CV_YUV2RGB_YUYV,
+    CV_YUV2BGR_YUY2  = CV_YUV2BGR_YUYV,
+    CV_YUV2RGB_VYUY  = 104,
+    CV_YUV2BGR_VYUY  = 105,
+    CV_YUV2RGB_YVYU  = 106,
+    CV_YUV2BGR_YVYU  = 107,
+
+    CV_YUV2RGBA_YUYV = 108,
+    CV_YUV2BGRA_YUYV = 109,
+    CV_YUV2RGBA_UYVY = 110,
+    CV_YUV2BGRA_UYVY = 111,
+    CV_YUV2RGBA_YUY2 = CV_YUV2RGBA_YUYV,
+    CV_YUV2BGRA_YUY2 = CV_YUV2BGRA_YUYV,
+    CV_YUV2RGBA_VYUY = 112,
+    CV_YUV2BGRA_VYUY = 113,
+    CV_YUV2RGBA_YVYU = 114,
+    CV_YUV2BGRA_YVYU = 115,
+
+    CV_YUV2RGB_YV12  = 116,
+    CV_YUV2BGR_YV12  = 117,
+    CV_YUV2RGB_IYUV  = 118,
+    CV_YUV2BGR_IYUV  = 119,
+    CV_YUV420p2RGB   = CV_YUV2RGB_YV12,
+    CV_YUV420p2BGR   = CV_YUV2BGR_YV12,
+
+    CV_YUV2RGBA_YV12 = 120,
+    CV_YUV2BGRA_YV12 = 121,
+    CV_YUV2RGBA_IYUV = 122,
+    CV_YUV2BGRA_IYUV = 123,
+    CV_YUV420p2RGBA  = CV_YUV2RGBA_YV12,
+    CV_YUV420p2BGRA  = CV_YUV2BGRA_YV12,
+
+    CV_COLORCVT_MAX  = 124
 };
 
 
diff -Naur a/opencv/modules/imgproc/src/color.cpp b/opencv/modules/imgproc/src/color.cpp
--- a/opencv/modules/imgproc/src/color.cpp	2012-03-30 10:36:51 +0200
+++ b/opencv/modules/imgproc/src/color.cpp	2012-03-30 10:11:48 +0200
@@ -2665,16 +2665,168 @@
     }
 }
 
+///////////////////////////////////// YUV422 -> RGB /////////////////////////////////////
+
+template<int bIdx, int uIdx, int yIdx>
+struct YUV422i2RGB888Invoker
+{
+    Mat* dst;
+    const uchar* my1;
+    int width, stride;
+
+    YUV422i2RGB888Invoker(Mat* _dst, int _stride, const uchar* _y1)
+        : dst(_dst), my1(_y1), width(_dst->cols), stride(_stride) {}
+
+    void operator()(const BlockedRange& range) const
+    {
+        int rangeBegin = range.begin();
+        int rangeEnd = range.end();
+
+        //R = 1.164(Y - 16) + 1.596(V - 128)
+        //G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)
+        //B = 1.164(Y - 16)                  + 2.018(U - 128)
+
+        //R = (1220542(Y - 16) + 1673527(V - 128)                  + (1 << 19)) >> 20
+        //G = (1220542(Y - 16) - 852492(V - 128) - 409993(U - 128) + (1 << 19)) >> 20
+        //B = (1220542(Y - 16)                  + 2116026(U - 128) + (1 << 19)) >> 20
+
+        const int cY = 1220542;
+        const int cUB = 2116026;
+        const int cUG = -409993;
+        const int cVG = -852492;
+        const int cVR = 1673527;
+        const int YUV422_SHIFT = 20;
+        const int vIdx = (2 + uIdx) % 4;
+
+        const uchar* yuv_src = my1 + rangeBegin * stride;
+
+        for (int j = rangeBegin; j < rangeEnd; j ++, yuv_src += stride)
+        {
+            uchar* row = dst->ptr<uchar>(j);
+
+            for (int i = 0; i < 2 * width; i += 4, row += 6)
+            {
+                int u = int(yuv_src[i + uIdx]) - 128;
+                int v = int(yuv_src[i + vIdx]) - 128;
+
+                int ruv = (1 << (YUV422_SHIFT - 1)) + cVR * v;
+                int guv = (1 << (YUV422_SHIFT - 1)) + cVG * v + cUG * u;
+                int buv = (1 << (YUV422_SHIFT - 1)) + cUB * u;
+
+                int y00 = std::max(0, int(yuv_src[i + yIdx]) - 16) * cY;
+                row[2-bIdx] = saturate_cast<uchar>((y00 + ruv) >> YUV422_SHIFT);
+                row[1]      = saturate_cast<uchar>((y00 + guv) >> YUV422_SHIFT);
+                row[bIdx]   = saturate_cast<uchar>((y00 + buv) >> YUV422_SHIFT);
+
+                int y01 = std::max(0, int(yuv_src[i + yIdx + 2]) - 16) * cY;
+                row[5-bIdx] = saturate_cast<uchar>((y01 + ruv) >> YUV422_SHIFT);
+                row[4]      = saturate_cast<uchar>((y01 + guv) >> YUV422_SHIFT);
+                row[3+bIdx] = saturate_cast<uchar>((y01 + buv) >> YUV422_SHIFT);
+
+            }
+        }
+    }
+};
+
+template<int bIdx, int uIdx, int yIdx>
+struct YUV422i2RGBA888Invoker
+{
+    Mat* dst;
+    const uchar* my1;
+    int width, stride;
+
+    YUV422i2RGBA888Invoker(Mat* _dst, int _stride, const uchar* _y1)
+        : dst(_dst), my1(_y1), width(_dst->cols), stride(_stride) {}
+
+    void operator()(const BlockedRange& range) const
+    {
+        int rangeBegin = range.begin();
+        int rangeEnd = range.end();
+
+        //R = 1.164(Y - 16) + 1.596(V - 128)
+        //G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)
+        //B = 1.164(Y - 16)                  + 2.018(U - 128)
+
+        //R = (1220542(Y - 16) + 1673527(V - 128)                  + (1 << 19)) >> 20
+        //G = (1220542(Y - 16) - 852492(V - 128) - 409993(U - 128) + (1 << 19)) >> 20
+        //B = (1220542(Y - 16)                  + 2116026(U - 128) + (1 << 19)) >> 20
+
+        const int cY = 1220542;
+        const int cUB = 2116026;
+        const int cUG = -409993;
+        const int cVG = -852492;
+        const int cVR = 1673527;
+        const int YUV422_SHIFT = 20;
+        const int vIdx = (2 + uIdx) % 4;
+
+        const uchar* yuv_src = my1 + rangeBegin * stride;
+
+        for (int j = rangeBegin; j < rangeEnd; j ++, yuv_src += stride)
+        {
+            uchar* row = dst->ptr<uchar>(j);
+
+            for (int i = 0; i < 2 * width; i += 4, row += 8)
+            {
+                int u = int(yuv_src[i + uIdx]) - 128;
+                int v = int(yuv_src[i + vIdx]) - 128;
+
+                int ruv = (1 << (YUV422_SHIFT - 1)) + cVR * v;
+                int guv = (1 << (YUV422_SHIFT - 1)) + cVG * v + cUG * u;
+                int buv = (1 << (YUV422_SHIFT - 1)) + cUB * u;
+
+                int y00 = std::max(0, int(yuv_src[i + yIdx]) - 16) * cY;
+                row[2-bIdx] = saturate_cast<uchar>((y00 + ruv) >> YUV422_SHIFT);
+                row[1]      = saturate_cast<uchar>((y00 + guv) >> YUV422_SHIFT);
+                row[bIdx]   = saturate_cast<uchar>((y00 + buv) >> YUV422_SHIFT);
+                row[3]      = uchar(0xff);
+
+                int y01 = std::max(0, int(yuv_src[i + yIdx + 2]) - 16) * cY;
+                row[6-bIdx] = saturate_cast<uchar>((y01 + ruv) >> YUV422_SHIFT);
+                row[5]      = saturate_cast<uchar>((y01 + guv) >> YUV422_SHIFT);
+                row[4+bIdx] = saturate_cast<uchar>((y01 + buv) >> YUV422_SHIFT);
+                row[7]      = uchar(0xff);
+
+            }
+        }
+    }
+};
+
+
+#define MIN_SIZE_FOR_PARALLEL_YUV422_CONVERSION (320*240)
+template<int bIdx, int uIdx, int yIdx>
+inline void cvtYUV422i2RGB(Mat& _dst, int _stride, const uchar* _yuv)
+{
+    YUV422i2RGB888Invoker<bIdx, uIdx, yIdx> converter(&_dst, _stride, _yuv);
+#ifdef HAVE_TBB
+    if (_dst.total() >= MIN_SIZE_FOR_PARALLEL_YUV422_CONVERSION)
+        parallel_for(BlockedRange(0, _dst.rows), converter);
+    else
+#endif
+        converter(BlockedRange(0, _dst.rows));
+}
+
+template<int bIdx, int uIdx, int yIdx>
+inline void cvtYUV422i2RGBA(Mat& _dst, int _stride, const uchar* _yuv)
+{
+    YUV422i2RGBA888Invoker<bIdx, uIdx, yIdx> converter(&_dst, _stride, _yuv);
+#ifdef HAVE_TBB
+    if (_dst.total() >= MIN_SIZE_FOR_PARALLEL_YUV422_CONVERSION)
+        parallel_for(BlockedRange(0, _dst.rows), converter);
+    else
+#endif
+        converter(BlockedRange(0, _dst.rows));
+}
+
 ///////////////////////////////////// YUV420 -> RGB /////////////////////////////////////
 
 template<int bIdx, int uIdx>
-struct YUV4202RGB888Invoker
+struct YUV420sp2RGB888Invoker
 {
     Mat* dst;
     const uchar* my1, *muv;
     int width, stride;
 
-    YUV4202RGB888Invoker(Mat* _dst, int _stride, const uchar* _y1, const uchar* _uv)
+    YUV420sp2RGB888Invoker(Mat* _dst, int _stride, const uchar* _y1, const uchar* _uv)
         : dst(_dst), my1(_y1), muv(_uv), width(_dst->cols), stride(_stride) {}
 
     void operator()(const BlockedRange& range) const
@@ -2744,13 +2896,13 @@
 };
 
 template<int bIdx, int uIdx>
-struct YUV4202RGBA8888Invoker
+struct YUV420sp2RGBA8888Invoker
 {
     Mat* dst;
     const uchar* my1, *muv;
     int width, stride;
 
-    YUV4202RGBA8888Invoker(Mat* _dst, int _stride, const uchar* _y1, const uchar* _uv)
+    YUV420sp2RGBA8888Invoker(Mat* _dst, int _stride, const uchar* _y1, const uchar* _uv)
         : dst(_dst), my1(_y1), muv(_uv), width(_dst->cols), stride(_stride) {}
 
     void operator()(const BlockedRange& range) const
@@ -2823,11 +2975,158 @@
     }
 };
 
+template<int bIdx>
+struct YUV420p2RGB888Invoker
+{
+    Mat* dst;
+    const uchar* my1, *mu, *mv;
+    int width, stride;
+
+    YUV420p2RGB888Invoker(Mat* _dst, int _stride, const uchar* _y1, const uchar* _u, const uchar* _v)
+        : dst(_dst), my1(_y1), mu(_u), mv(_v), width(_dst->cols), stride(_stride) {}
+
+    void operator()(const BlockedRange& range) const
+    {
+        int rangeBegin = range.begin() * 2;
+        int rangeEnd = range.end() * 2;
+
+        //R = 1.164(Y - 16) + 1.596(V - 128)
+        //G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)
+        //B = 1.164(Y - 16)                  + 2.018(U - 128)
+
+        //R = (1220542(Y - 16) + 1673527(V - 128)                  + (1 << 19)) >> 20
+        //G = (1220542(Y - 16) - 852492(V - 128) - 409993(U - 128) + (1 << 19)) >> 20
+        //B = (1220542(Y - 16)                  + 2116026(U - 128) + (1 << 19)) >> 20
+
+        const int cY = 1220542;
+        const int cUB = 2116026;
+        const int cUG = -409993;
+        const int cVG = -852492;
+        const int cVR = 1673527;
+        const int YUV420_SHIFT = 20;
+
+        const uchar* y1 = my1 + rangeBegin * stride, *u1 = mu + rangeBegin * stride / 4, *v1 = mv + rangeBegin * stride / 4;
+
+        for (int j = rangeBegin; j < rangeEnd; j += 2, y1 += stride * 2, u1 += stride / 2, v1 += stride / 2)
+        {
+            uchar* row1 = dst->ptr<uchar>(j);
+            uchar* row2 = dst->ptr<uchar>(j + 1);
+            const uchar* y2 = y1 + stride;
+
+            for (int i = 0; i < width / 2; i += 1, row1 += 6, row2 += 6)
+            {
+                int u = int(u1[i]) - 128;
+                int v = int(v1[i]) - 128;
+
+                int ruv = (1 << (YUV420_SHIFT - 1)) + cVR * v;
+                int guv = (1 << (YUV420_SHIFT - 1)) + cVG * v + cUG * u;
+                int buv = (1 << (YUV420_SHIFT - 1)) + cUB * u;
+
+                int y00 = std::max(0, int(y1[2 * i]) - 16) * cY;
+                row1[2-bIdx] = saturate_cast<uchar>((y00 + ruv) >> YUV420_SHIFT);
+                row1[1]      = saturate_cast<uchar>((y00 + guv) >> YUV420_SHIFT);
+                row1[bIdx]   = saturate_cast<uchar>((y00 + buv) >> YUV420_SHIFT);
+
+                int y01 = std::max(0, int(y1[2 * i + 1]) - 16) * cY;
+                row1[5-bIdx] = saturate_cast<uchar>((y01 + ruv) >> YUV420_SHIFT);
+                row1[4]      = saturate_cast<uchar>((y01 + guv) >> YUV420_SHIFT);
+                row1[3+bIdx] = saturate_cast<uchar>((y01 + buv) >> YUV420_SHIFT);
+
+                int y10 = std::max(0, int(y2[2 * i]) - 16) * cY;
+                row2[2-bIdx] = saturate_cast<uchar>((y10 + ruv) >> YUV420_SHIFT);
+                row2[1]      = saturate_cast<uchar>((y10 + guv) >> YUV420_SHIFT);
+                row2[bIdx]   = saturate_cast<uchar>((y10 + buv) >> YUV420_SHIFT);
+
+                int y11 = std::max(0, int(y2[2 * i + 1]) - 16) * cY;
+                row2[5-bIdx] = saturate_cast<uchar>((y11 + ruv) >> YUV420_SHIFT);
+                row2[4]      = saturate_cast<uchar>((y11 + guv) >> YUV420_SHIFT);
+                row2[3+bIdx] = saturate_cast<uchar>((y11 + buv) >> YUV420_SHIFT);
+            }
+
+        }
+    }
+};
+
+template<int bIdx>
+struct YUV420p2RGBA8888Invoker
+{
+    Mat* dst;
+    const uchar* my1, *mu, *mv;
+    int width, stride;
+
+    YUV420p2RGBA8888Invoker(Mat* _dst, int _stride, const uchar* _y1, const uchar* _u, const uchar* _v)
+        : dst(_dst), my1(_y1), mu(_u), mv(_v), width(_dst->cols), stride(_stride) {}
+
+    void operator()(const BlockedRange& range) const
+    {
+        int rangeBegin = range.begin() * 2;
+        int rangeEnd = range.end() * 2;
+
+        //R = 1.164(Y - 16) + 1.596(V - 128)
+        //G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)
+        //B = 1.164(Y - 16)                  + 2.018(U - 128)
+
+        //R = (1220542(Y - 16) + 1673527(V - 128)                  + (1 << 19)) >> 20
+        //G = (1220542(Y - 16) - 852492(V - 128) - 409993(U - 128) + (1 << 19)) >> 20
+        //B = (1220542(Y - 16)                  + 2116026(U - 128) + (1 << 19)) >> 20
+
+        const int cY = 1220542;
+        const int cUB = 2116026;
+        const int cUG = -409993;
+        const int cVG = -852492;
+        const int cVR = 1673527;
+        const int YUV420_SHIFT = 20;
+
+        const uchar* y1 = my1 + rangeBegin * stride, *u1 = mu + rangeBegin * stride / 4, *v1 = mv + rangeBegin * stride / 4;
+
+        for (int j = rangeBegin; j < rangeEnd; j += 2, y1 += stride * 2, u1 += stride / 2, v1 += stride / 2)
+        {
+            uchar* row1 = dst->ptr<uchar>(j);
+            uchar* row2 = dst->ptr<uchar>(j + 1);
+            const uchar* y2 = y1 + stride;
+
+            for (int i = 0; i < width / 2; i += 1, row1 += 8, row2 += 8)
+            {
+                int u = int(u1[i]) - 128;
+                int v = int(v1[i]) - 128;
+
+                int ruv = (1 << (YUV420_SHIFT - 1)) + cVR * v;
+                int guv = (1 << (YUV420_SHIFT - 1)) + cVG * v + cUG * u;
+                int buv = (1 << (YUV420_SHIFT - 1)) + cUB * u;
+
+                int y00 = std::max(0, int(y1[2 * i]) - 16) * cY;
+                row1[2-bIdx] = saturate_cast<uchar>((y00 + ruv) >> YUV420_SHIFT);
+                row1[1]      = saturate_cast<uchar>((y00 + guv) >> YUV420_SHIFT);
+                row1[bIdx]   = saturate_cast<uchar>((y00 + buv) >> YUV420_SHIFT);
+                row1[3]      = uchar(0xff);
+
+                int y01 = std::max(0, int(y1[2 * i + 1]) - 16) * cY;
+                row1[6-bIdx] = saturate_cast<uchar>((y01 + ruv) >> YUV420_SHIFT);
+                row1[5]      = saturate_cast<uchar>((y01 + guv) >> YUV420_SHIFT);
+                row1[4+bIdx] = saturate_cast<uchar>((y01 + buv) >> YUV420_SHIFT);
+                row1[7]      = uchar(0xff);
+
+                int y10 = std::max(0, int(y2[2 * i]) - 16) * cY;
+                row2[2-bIdx] = saturate_cast<uchar>((y10 + ruv) >> YUV420_SHIFT);
+                row2[1]      = saturate_cast<uchar>((y10 + guv) >> YUV420_SHIFT);
+                row2[bIdx]   = saturate_cast<uchar>((y10 + buv) >> YUV420_SHIFT);
+                row2[3]      = uchar(0xff);
+
+                int y11 = std::max(0, int(y2[2 * i + 1]) - 16) * cY;
+                row2[6-bIdx] = saturate_cast<uchar>((y11 + ruv) >> YUV420_SHIFT);
+                row2[5]      = saturate_cast<uchar>((y11 + guv) >> YUV420_SHIFT);
+                row2[4+bIdx] = saturate_cast<uchar>((y11 + buv) >> YUV420_SHIFT);
+                row2[7]      = uchar(0xff);
+            }
+        }
+    }
+};
+
 #define MIN_SIZE_FOR_PARALLEL_YUV420_CONVERSION (320*240)
 template<int bIdx, int uIdx>
-inline void cvtYUV4202RGB(Mat& _dst, int _stride, const uchar* _y1, const uchar* _uv)
+inline void cvtYUV420sp2RGB(Mat& _dst, int _stride, const uchar* _y1, const uchar* _uv)
 {
-    YUV4202RGB888Invoker<bIdx, uIdx> converter(&_dst, _stride, _y1,  _uv);
+    YUV420sp2RGB888Invoker<bIdx, uIdx> converter(&_dst, _stride, _y1,  _uv);
 #ifdef HAVE_TBB
     if (_dst.total() >= MIN_SIZE_FOR_PARALLEL_YUV420_CONVERSION)
         parallel_for(BlockedRange(0, _dst.rows/2), converter);
@@ -2837,9 +3136,33 @@
 }
 
 template<int bIdx, int uIdx>
-inline void cvtYUV4202RGBA(Mat& _dst, int _stride, const uchar* _y1, const uchar* _uv)
+inline void cvtYUV420sp2RGBA(Mat& _dst, int _stride, const uchar* _y1, const uchar* _uv)
+{
+    YUV420sp2RGBA8888Invoker<bIdx, uIdx> converter(&_dst, _stride, _y1,  _uv);
+#ifdef HAVE_TBB
+    if (_dst.total() >= MIN_SIZE_FOR_PARALLEL_YUV420_CONVERSION)
+        parallel_for(BlockedRange(0, _dst.rows/2), converter);
+    else
+#endif
+        converter(BlockedRange(0, _dst.rows/2));
+}
+
+template<int bIdx>
+inline void cvtYUV420p2RGB(Mat& _dst, int _stride, const uchar* _y1, const uchar* _u, const uchar* _v)
 {
-    YUV4202RGBA8888Invoker<bIdx, uIdx> converter(&_dst, _stride, _y1,  _uv);
+    YUV420p2RGB888Invoker<bIdx> converter(&_dst, _stride, _y1,  _u, _v);
+#ifdef HAVE_TBB
+    if (_dst.total() >= MIN_SIZE_FOR_PARALLEL_YUV420_CONVERSION)
+        parallel_for(BlockedRange(0, _dst.rows/2), converter);
+    else
+#endif
+        converter(BlockedRange(0, _dst.rows/2));
+}
+
+template<int bIdx>
+inline void cvtYUV420p2RGBA(Mat& _dst, int _stride, const uchar* _y1, const uchar* _u, const uchar* _v)
+{
+    YUV420p2RGBA8888Invoker<bIdx> converter(&_dst, _stride, _y1,  _u, _v);
 #ifdef HAVE_TBB
     if (_dst.total() >= MIN_SIZE_FOR_PARALLEL_YUV420_CONVERSION)
         parallel_for(BlockedRange(0, _dst.rows/2), converter);
@@ -3239,30 +3562,160 @@
                 if (CV_YUV420sp2RGB == code || COLOR_YUV420sp2RGBA == code)
                 {
                     if (dcn == 3)
-                        cvtYUV4202RGB<2, 1>(dst, srcstep, y, uv);
+                        cvtYUV420sp2RGB<2, 1>(dst, srcstep, y, uv);
                     else
-                        cvtYUV4202RGBA<2, 1>(dst, srcstep, y, uv);
+                        cvtYUV420sp2RGBA<2, 1>(dst, srcstep, y, uv);
                 }
                 else if (CV_YUV420sp2BGR == code || CV_YUV420sp2BGRA == code)
                 {
                     if (dcn == 3)
-                        cvtYUV4202RGB<0, 1>(dst, srcstep, y, uv);
+                        cvtYUV420sp2RGB<0, 1>(dst, srcstep, y, uv);
                     else
-                        cvtYUV4202RGBA<0, 1>(dst, srcstep, y, uv);
+                        cvtYUV420sp2RGBA<0, 1>(dst, srcstep, y, uv);
                 }
                 else if (CV_YUV2RGB_NV12 == code || CV_YUV2RGBA_NV12 == code)
                 {
                     if (dcn == 3)
-                        cvtYUV4202RGB<2, 0>(dst, srcstep, y, uv);
+                        cvtYUV420sp2RGB<2, 0>(dst, srcstep, y, uv);
                     else
-                        cvtYUV4202RGBA<2, 0>(dst, srcstep, y, uv);
+                        cvtYUV420sp2RGBA<2, 0>(dst, srcstep, y, uv);
                 }
                 else //if (CV_YUV2BGR_NV12 == code || CV_YUV2BGRA_NV12 == code)
                 {
                     if (dcn == 3)
-                        cvtYUV4202RGB<0, 0>(dst, srcstep, y, uv);
+                        cvtYUV420sp2RGB<0, 0>(dst, srcstep, y, uv);
+                    else
+                        cvtYUV420sp2RGBA<0, 0>(dst, srcstep, y, uv);
+                }
+            }
+            break;
+        case CV_YUV2BGR_YV12: case CV_YUV2RGB_YV12: case CV_YUV2BGRA_YV12: case CV_YUV2RGBA_YV12:
+        case CV_YUV2RGB_IYUV: case CV_YUV2BGR_IYUV: case CV_YUV2RGBA_IYUV: case CV_YUV2BGRA_IYUV:
+            {
+                if (dcn <= 0) dcn = (code==CV_YUV2BGRA_YV12 || code==CV_YUV2RGBA_YV12 || code==CV_YUV2RGBA_IYUV || code==CV_YUV2BGRA_IYUV) ? 4 : 3;
+                CV_Assert( dcn == 3 || dcn == 4 );
+                CV_Assert( sz.width % 2 == 0 && sz.height % 3 == 0 && depth == CV_8U );
+
+                Size dstSz(sz.width, sz.height * 2 / 3);
+                _dst.create(dstSz, CV_MAKETYPE(depth, dcn));
+                dst = _dst.getMat();
+                int srcstep = (int)src.step;
+
+                const uchar* y = src.ptr();
+                const uchar* u = y + srcstep * dstSz.height;
+                const uchar* v = u + (srcstep * dstSz.height / 4);
+
+                if (CV_YUV2BGR_YV12 == code || CV_YUV2BGRA_YV12 == code )
+                {
+                    if (dcn == 3)
+                        cvtYUV420p2RGB<0>(dst, srcstep, y, v, u);
+                    else
+                        cvtYUV420p2RGBA<0>(dst,srcstep, y, v, u);
+                }
+                else if (CV_YUV2RGB_YV12 == code || CV_YUV2RGBA_YV12 == code)
+                {
+                    if (dcn == 3)
+                        cvtYUV420p2RGB<2>(dst, srcstep, y, v, u);
+                    else
+                        cvtYUV420p2RGBA<2>(dst, srcstep, y, v, u);
+                }
+                else if (CV_YUV2RGB_IYUV == code || CV_YUV2RGBA_IYUV == code)
+                {
+                    if (dcn == 3)
+                        cvtYUV420p2RGB<2>(dst, srcstep, y, u, v);
+                    else
+                        cvtYUV420p2RGBA<2>(dst, srcstep, y, u, v);
+                }
+                else // if (CV_YUV2BGR_IYUV == code || CV_YUV2BGRA_IYUV == code)
+                {
+                    if (dcn == 3)
+                        cvtYUV420p2RGB<0>(dst, srcstep, y, u, v);
+                    else
+                        cvtYUV420p2RGBA<0>(dst, srcstep, y, u, v);
+                }
+            }
+            break;
+        case CV_YUV2RGB_YUYV:   case CV_YUV2RGB_UYVY:  case CV_YUV2RGB_YVYU:  case CV_YUV2RGB_VYUY:
+        case CV_YUV2BGR_YUYV:   case CV_YUV2BGR_UYVY:  case CV_YUV2BGR_YVYU:  case CV_YUV2BGR_VYUY:
+        case CV_YUV2RGBA_YUYV:  case CV_YUV2RGBA_UYVY: case CV_YUV2RGBA_YVYU: case CV_YUV2RGBA_VYUY:
+        case CV_YUV2BGRA_YUYV:  case CV_YUV2BGRA_UYVY: case CV_YUV2BGRA_YVYU: case CV_YUV2BGRA_VYUY:
+            {
+                if (dcn <= 0) dcn = (
+                        CV_YUV2RGBA_YUYV==code || CV_YUV2RGBA_UYVY==code || CV_YUV2RGBA_YVYU==code || CV_YUV2RGBA_VYUY==code ||
+                        CV_YUV2BGRA_YUYV==code || CV_YUV2BGRA_UYVY==code || CV_YUV2BGRA_YVYU==code || CV_YUV2BGRA_VYUY==code) ? 4 : 3;
+                CV_Assert( dcn == 3 || dcn == 4 );
+                CV_Assert( sz.width % 4 == 0 && depth == CV_8U );
+
+                Size dstSz(sz.width / 2, sz.height);
+                _dst.create(dstSz, CV_MAKETYPE(depth, dcn));
+                dst = _dst.getMat();
+                int srcstep = (int)src.step;
+                
+                const uchar* yuv = src.ptr();
+                
+                // http://www.fourcc.org/yuv.php#YUY2 ->
+                if (CV_YUV2RGB_YUYV == code || CV_YUV2RGBA_YUYV == code)
+                {
+                    if (dcn == 3)
+                        cvtYUV422i2RGB<2, 1, 0>(dst, srcstep, yuv);
+                    else
+                        cvtYUV422i2RGBA<2, 1, 0>(dst, srcstep, yuv);
+                }
+                // http://www.fourcc.org/yuv.php#YUY2 ->
+                else if (CV_YUV2RGB_YVYU == code || CV_YUV2RGBA_YVYU == code)
+                {
+                    if (dcn == 3)
+                        cvtYUV422i2RGB<2, 3, 0>(dst, srcstep, yuv);
+                    else
+                        cvtYUV422i2RGBA<2, 3, 0>(dst, srcstep, yuv);
+                }
+                // http://www.fourcc.org/yuv.php VYUY ->
+                else if (CV_YUV2RGB_VYUY == code || CV_YUV2RGBA_VYUY == code)
+                {
+                    if (dcn == 3)
+                        cvtYUV422i2RGB<2, 2, 1>(dst, srcstep, yuv);
+                    else
+                        cvtYUV422i2RGBA<2, 2, 1>(dst, srcstep, yuv);
+                }
+                // http://www.fourcc.org/yuv.php#Y422 ->
+                else if (CV_YUV2RGB_UYVY == code || CV_YUV2RGBA_UYVY == code)
+                {
+                    if (dcn == 3)
+                        cvtYUV422i2RGB<2, 0, 1>(dst, srcstep, yuv);
+                    else
+                        cvtYUV422i2RGBA<2, 0, 1>(dst, srcstep, yuv);
+                }
+                // http://www.fourcc.org/yuv.php#YUY2 ->
+                else if (CV_YUV2BGR_YUYV == code || CV_YUV2BGRA_YUYV == code)
+                {
+                    if (dcn == 3)
+                        cvtYUV422i2RGB<0, 1, 0>(dst, srcstep, yuv);
+                    else
+                        cvtYUV422i2RGBA<0, 1, 0>(dst, srcstep, yuv);
+                }
+                // http://www.fourcc.org/yuv.php#YUY2 ->
+                else if (CV_YUV2BGR_YVYU == code || CV_YUV2BGRA_YVYU == code)
+                {
+                    if (dcn == 3)
+                        cvtYUV422i2RGB<0, 3, 0>(dst, srcstep, yuv);
+                    else
+                        cvtYUV422i2RGBA<0, 3, 0>(dst, srcstep, yuv);
+                }
+                // http://www.fourcc.org/yuv.php VYUY ->
+                else if (CV_YUV2BGR_VYUY == code || CV_YUV2BGRA_VYUY == code)
+                {
+                    if (dcn == 3)
+                        cvtYUV422i2RGB<0, 2, 1>(dst, srcstep, yuv);
+                    else
+                        cvtYUV422i2RGBA<0, 2, 1>(dst, srcstep, yuv);
+                }
+                // http://www.fourcc.org/yuv.php#Y422 ->
+                else // if (CV_YUV2BGR_UYVY == code || CV_YUV2BGRA_UYVY == code)
+                {
+                    if (dcn == 3)
+                        cvtYUV422i2RGB<0, 0, 1>(dst, srcstep, yuv);
                     else
-                        cvtYUV4202RGBA<0, 0>(dst, srcstep, y, uv);
+                        cvtYUV422i2RGBA<0, 0, 1>(dst, srcstep, yuv);
                 }
             }
             break;
