Index: libs/libmythtv/util-opengl.h
===================================================================
--- libs/libmythtv/util-opengl.h	(revision 12809)
+++ libs/libmythtv/util-opengl.h	(working copy)
@@ -72,7 +72,6 @@
                          const QSize &window_size);
 
 void copy_pixels_to_texture(const unsigned char *buf,
-                            const int   *offsets,
                             int          buffer_format,
                             const QSize &buffer_size,
                             int          texture,
Index: libs/libmythtv/openglvideo.h
===================================================================
--- libs/libmythtv/openglvideo.h	(revision 12809)
+++ libs/libmythtv/openglvideo.h	(working copy)
@@ -95,7 +95,7 @@
     OpenGLFilterType GetDeintFilter(void) const;
     bool AddFrameBuffer(uint &framebuffer, uint &texture, QSize size);
     uint AddFragmentProgram(OpenGLFilterType name);
-    uint CreateVideoTexture(QSize size, QSize &tex_size, bool YUV12);
+    uint CreateVideoTexture(QSize size, QSize &tex_size);
     QString GetProgramString(OpenGLFilterType filter);
     void CalculateResize(float &left,  float &top,
                          float &right, float &bottom);
Index: libs/libmythtv/openglvideo.cpp
===================================================================
--- libs/libmythtv/openglvideo.cpp	(revision 12809)
+++ libs/libmythtv/openglvideo.cpp	(working copy)
@@ -134,26 +134,33 @@
     if (osd)
     {
         QSize osdsize = visibleRect.size();
+        QSize half_size(osdsize.width() >> 1, osdsize.height() >>1);
+        GLuint alphatex = CreateVideoTexture(osdsize, inputTextureSize);
+        GLuint utex = CreateVideoTexture(half_size, inputTextureSize);
+        GLuint vtex = CreateVideoTexture(half_size, inputTextureSize);
+        GLuint ytex = CreateVideoTexture(osdsize, inputTextureSize);
 
-        GLuint alphatex = CreateVideoTexture(
-            osdsize, inputTextureSize,
-            gl_context->IsFeatureSupported(kGLExtRect) ? false : true);
-
-        GLuint yuv12tex = CreateVideoTexture(osdsize, inputTextureSize, true);
-
-        if ((alphatex && yuv12tex) && AddFilter(kGLFilterYUV2RGBA))
+    if ((alphatex && ytex && utex && vtex) && AddFilter(kGLFilterYUV2RGBA))
         {
-            inputTextures.push_back(yuv12tex);
+            inputTextures.push_back(ytex);
+            inputTextures.push_back(utex);
+            inputTextures.push_back(vtex);
             inputTextures.push_back(alphatex);
         }
     }
     else
     {
-        GLuint yuv12tex = CreateVideoTexture(
-            videoSize, inputTextureSize, true);
+        QSize half_size(videoSize.width() >> 1, videoSize.height() >>1);
+        GLuint utex = CreateVideoTexture(half_size, inputTextureSize);
+        GLuint vtex = CreateVideoTexture(half_size, inputTextureSize);
+        GLuint ytex = CreateVideoTexture(videoSize, inputTextureSize);;
 
-        if (yuv12tex && AddFilter(kGLFilterYUV2RGB))
-            inputTextures.push_back(yuv12tex);
+        if ((ytex && utex && vtex) && AddFilter(kGLFilterYUV2RGB))
+        {
+            inputTextures.push_back(ytex);
+            inputTextures.push_back(utex);
+            inputTextures.push_back(vtex);
+        }
     }
 
     if (filters.empty())
@@ -169,12 +176,11 @@
                 "Falling back to software conversion.\n\t\t\t"
                 "Any opengl filters will also be disabled.");
 
-        GLuint yuv12tex = CreateVideoTexture(
-            videoSize, inputTextureSize, false);
+        GLuint rgb24tex = CreateVideoTexture(videoSize, inputTextureSize);
 
-        if (yuv12tex && AddFilter(kGLFilterResize))
+        if (rgb24tex && AddFilter(kGLFilterResize))
         {
-            inputTextures.push_back(yuv12tex);
+            inputTextures.push_back(rgb24tex);
         }
         else
         {
@@ -377,18 +383,22 @@
 
     temp->numInputs = 1;
 
-    if ((filter == kGLFilterYUV2RGBA) ||
-        (filter == kGLFilterLinearBlendDeint) ||
+    if ((filter == kGLFilterLinearBlendDeint) ||
         (filter == kGLFilterKernelDeint))
     {
         temp->numInputs = 2;
     }
-    else if ((filter == kGLFilterOneFieldDeintDFR) ||
+    else if ((filter == kGLFilterYUV2RGB) ||
+             (filter == kGLFilterOneFieldDeintDFR) ||
              (filter == kGLFilterKernelDeintDFR) ||
              (filter == kGLFilterLinearBlendDeintDFR))
     {
         temp->numInputs = 3;
     }
+    else if ((filter == kGLFilterYUV2RGBA))
+    {
+        temp->numInputs = 4;
+    }
 
     GLuint program = 0;
     if (filter != kGLFilterNone && filter != kGLFilterResize)
@@ -551,25 +561,12 @@
 }
 
 // locking ok
-uint OpenGLVideo::CreateVideoTexture(QSize size, QSize &tex_size, bool YUV12)
+uint OpenGLVideo::CreateVideoTexture(QSize size, QSize &tex_size)
 {
     uint tmp_tex = gl_context->CreateTexture();
 
     QSize temp = GetTextureSize(size);
 
-    if (YUV12)
-    {
-        if (gl_context->IsFeatureSupported(kGLExtRect))
-        {
-            temp.rheight() = size.height() * 3 / 2;
-        }
-        else
-        {
-            if ((size.height() * 1.5) > temp.height())
-                temp.rheight() *= 2;
-        }
-    }
-
     if ((temp.width()  > (int)gl_context->GetMaxTexSize()) ||
         (temp.height() > (int)gl_context->GetMaxTexSize()) ||
         !gl_context->SetupTexture(temp, tmp_tex, GL_LINEAR))
@@ -669,9 +666,22 @@
         return;
 
     copy_pixels_to_texture(
-        buf, offsets, format, size,
+        buf + offsets[0], format, size,
         inputTextures[texture_index], gl_context->GetTextureType());
 
+    if (FMT_YV12 == format)
+    {
+        QSize chroma_size(size.width() >> 1, size.height() >> 1);
+        copy_pixels_to_texture(
+            buf + offsets[1], format, chroma_size,
+            inputTextures[texture_index + 1],
+            gl_context->GetTextureType());
+        copy_pixels_to_texture(
+            buf + offsets[2], format, chroma_size,
+            inputTextures[texture_index + 2],
+            gl_context->GetTextureType());
+    }
+
     inputUpdated = true;
 }
 
@@ -826,7 +836,6 @@
             t_bottom /= inputsize.height();
         }
 
-        float full_height = t_bottom;
         float line_height = (t_bottom / (float)videoSize.height());
         float bob = line_height / 2.0f;
 
@@ -862,6 +871,10 @@
             }
         }
 
+        float t_right_uv = t_right / 2.0f;
+        float t_top_uv   = t_top / 2.0f;
+        float t_bottom_uv = t_bottom / 2.0f;
+
         // vertex coordinates
         QRect display = (filter->outputBuffer == kDefaultBuffer) ?
             videoRect : frameBufferRect;
@@ -931,9 +944,6 @@
             {
                 case kGLFilterYUV2RGB:
                 case kGLFilterYUV2RGBA:
-                    gl_context->InitFragmentParams(
-                        1, t_right / 2.0f, full_height, 0.0f, 0.0f);
-
                     if (useColourControl)
                     {
                         gl_context->InitFragmentParams(
@@ -973,10 +983,45 @@
 
         // draw quad
         glBegin(GL_QUADS);
-        glTexCoord2f(0.0f,    t_top);    glVertex2f(vleft,  vtop);
-        glTexCoord2f(t_right, t_top);    glVertex2f(vright, vtop);
-        glTexCoord2f(t_right, t_bottom); glVertex2f(vright, vbot);
-        glTexCoord2f(0.0f,    t_bottom); glVertex2f(vleft,  vbot);
+        glTexCoord2f(0.0f, t_top);
+        if (type == kGLFilterYUV2RGB || type == kGLFilterYUV2RGBA)
+        {
+            glMultiTexCoord2f(GL_TEXTURE1, 0.0f, t_top_uv);
+            glMultiTexCoord2f(GL_TEXTURE2, 0.0f, t_top_uv);
+            if (type == kGLFilterYUV2RGBA)
+                glMultiTexCoord2f(GL_TEXTURE3, 0.0f, t_top_uv);
+        }
+        glVertex2f(vleft,  vtop);
+
+        glTexCoord2f(t_right, t_top);
+        if (type == kGLFilterYUV2RGB || type == kGLFilterYUV2RGBA)
+        {
+            glMultiTexCoord2f(GL_TEXTURE1, t_right_uv, t_top_uv);
+            glMultiTexCoord2f(GL_TEXTURE2, t_right_uv, t_top_uv);
+            if (type == kGLFilterYUV2RGBA)
+                glMultiTexCoord2f(GL_TEXTURE3, t_right, t_top);
+        }
+        glVertex2f(vright, vtop);
+
+        glTexCoord2f(t_right, t_bottom);
+        if (type == kGLFilterYUV2RGB || type == kGLFilterYUV2RGBA)
+        {
+            glMultiTexCoord2f(GL_TEXTURE1, t_right_uv, t_bottom_uv);
+            glMultiTexCoord2f(GL_TEXTURE2, t_right_uv, t_bottom_uv);
+            if (type == kGLFilterYUV2RGBA)
+                glMultiTexCoord2f(GL_TEXTURE3, t_right, t_bottom);
+        }
+        glVertex2f(vright, vbot);
+
+        glTexCoord2f(0.0f, t_bottom);
+        if (type == kGLFilterYUV2RGB || type == kGLFilterYUV2RGBA)
+        {
+            glMultiTexCoord2f(GL_TEXTURE1, 0.0f, t_bottom_uv);
+            glMultiTexCoord2f(GL_TEXTURE2, 0.0f, t_bottom_uv);
+            if (type == kGLFilterYUV2RGBA)
+                glMultiTexCoord2f(GL_TEXTURE3, 0.0f, t_bottom);
+        }
+        glVertex2f(vleft,  vbot);
         glEnd();
 
         // disable blending
@@ -1092,20 +1137,18 @@
 }
 
 static const QString yuv2rgb1a =
-"ATTRIB ytex = fragment.texcoord[0];"
-"PARAM  off  = program.env[1];"
-"TEMP res, tmp, tmp2;";
+"ATTRIB ytex  = fragment.texcoord[0];"
+"ATTRIB uvtex = fragment.texcoord[1];"
+"TEMP res, tmp;";
 
 static const QString yuv2rgb1b =
 "TEMP alpha;"
-"TEX alpha, ytex, texture[1], %1;";
+"TEX alpha, ytex, texture[3], %1;";
 
 static const QString yuv2rgb1c =
-"TEX res, ytex, texture[0], %1;"
-"MAD tmp2, ytex, {0.5, 0.5}, off.wyww;"
-"TEX tmp.x, tmp2, texture[0], %1;"
-"ADD tmp2, tmp2, off.xwww;"
-"TEX tmp.y, tmp2, texture[0], %1;";
+"TEX res,   ytex,  texture[0], %1;"
+"TEX tmp.x, uvtex, texture[1], %1;"
+"TEX tmp.y, uvtex, texture[2], %1;";
 
 static const QString yuv2rgb2 =
 "PARAM  adj  = program.env[0];"
Index: libs/libmythtv/xvmctextures.cpp
===================================================================
--- libs/libmythtv/xvmctextures.cpp	(revision 12809)
+++ libs/libmythtv/xvmctextures.cpp	(working copy)
@@ -199,8 +199,7 @@
     glTexParameterf(rect_type, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     glTexParameterf(rect_type, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 
-    int offset = 0;
-    copy_pixels_to_texture(pixels, &offset, FMT_RGBA32, gl_video_size,
+    copy_pixels_to_texture(pixels, FMT_RGBA32, gl_video_size,
                            gl_osd_textures[gl_osd_tex_index], rect_type);
 
     glXMakeContextCurrent(XJ_disp, None, None, NULL);
Index: libs/libmythtv/util-opengl.cpp
===================================================================
--- libs/libmythtv/util-opengl.cpp	(revision 12809)
+++ libs/libmythtv/util-opengl.cpp	(working copy)
@@ -242,7 +242,6 @@
 }                       
 
 void copy_pixels_to_texture(const unsigned char *buf,
-                            const int           *offsets,
                             int                  buffer_format,
                             const QSize         &buffer_size,
                             int                  texture,
@@ -250,53 +249,30 @@
 {
     glBindTexture(texture_type, texture);
 
-    if (FMT_YV12 == buffer_format)
+    uint format;
+    switch (buffer_format)
     {
-        glTexSubImage2D(
-            texture_type,
-            0, 0, 0,
-            buffer_size.width(), buffer_size.height(),
-            GL_LUMINANCE, GL_UNSIGNED_BYTE,
-            buf + offsets[0]);
-
-        glTexSubImage2D(
-            texture_type,
-            0, 0, buffer_size.height(),
-            buffer_size.width()>>1, buffer_size.height()>>1,
-            GL_LUMINANCE, GL_UNSIGNED_BYTE,
-            buf + offsets[1]);
-
-        glTexSubImage2D(
-            texture_type,
-            0, buffer_size.width()>>1, buffer_size.height(),
-            buffer_size.width()>>1, buffer_size.height()>>1,
-            GL_LUMINANCE, GL_UNSIGNED_BYTE,
-            buf + offsets[2]);
+        case FMT_YV12:
+            format = GL_LUMINANCE;
+            break;
+        case FMT_RGB24:
+            format = GL_RGB;
+            break;
+        case FMT_RGBA32:
+            format = GL_RGBA;
+            break;
+        case FMT_ALPHA:
+            format = GL_ALPHA;
+            break;
+        default:
+            return;
     }
-    else if (FMT_RGB24 == buffer_format)
-    {
-        glTexSubImage2D(
-            texture_type, 0, 0, 0,
-            buffer_size.width(), buffer_size.height(),
-            GL_RGB, GL_UNSIGNED_BYTE,
-            buf + offsets[0]);
-    }
-    else if (FMT_RGBA32 == buffer_format)
-    {
-        glTexSubImage2D(
-            texture_type, 0, 0, 0,
-            buffer_size.width(), buffer_size.height(),
-            GL_RGBA, GL_UNSIGNED_BYTE,
-            buf + offsets[0]);
-    }
-    else if (FMT_ALPHA == buffer_format)
-    {
-        glTexSubImage2D(
-            texture_type, 0, 0, 0,
-            buffer_size.width(), buffer_size.height(),
-            GL_ALPHA, GL_UNSIGNED_BYTE,
-            buf + offsets[0]);
-    }
+    glTexSubImage2D(
+        texture_type,
+        0, 0, 0,
+        buffer_size.width(), buffer_size.height(),
+        format, GL_UNSIGNED_BYTE,
+        buf);
 }
 
 __GLXextFuncPtr get_gl_proc_address(const QString &procName)
Index: libs/libmythtv/videoout_xv.cpp
===================================================================
--- libs/libmythtv/videoout_xv.cpp	(revision 12809)
+++ libs/libmythtv/videoout_xv.cpp	(working copy)
@@ -3958,7 +3958,7 @@
         gl_osdchain->UpdateInput(surface->yuvbuffer, offsets,
                                  0, FMT_YV12, visible);
         gl_osdchain->UpdateInput(surface->alpha, offsets,
-                                 1, FMT_ALPHA, visible);
+                                 3, FMT_ALPHA, visible);
     }
     return changed;
 }
