Index: libs/libmythtv/avformatdecoder.cpp
===================================================================
--- libs/libmythtv/avformatdecoder.cpp	(revision 10733)
+++ libs/libmythtv/avformatdecoder.cpp	(working copy)
@@ -1516,17 +1516,12 @@
 
     VideoFrame *frame = nd->GetNVP()->GetNextVideoFrame(true);
 
-    int width = frame->width;
-    int height = frame->height;
+    for (int i = 0; i < 3; i++)
+    {
+        pic->data[i]     = frame->buf + frame->offsets[i];
+        pic->linesize[i] = frame->pitches[i];
+    }
 
-    pic->data[0] = frame->buf;
-    pic->data[1] = pic->data[0] + width * height;
-    pic->data[2] = pic->data[1] + width * height / 4;
-
-    pic->linesize[0] = width;
-    pic->linesize[1] = width / 2;
-    pic->linesize[2] = width / 2;
-
     pic->opaque = frame;
     pic->type = FF_BUFFER_TYPE_USER;
 
Index: libs/libmythtv/frame.h
===================================================================
--- libs/libmythtv/frame.h	(revision 10733)
+++ libs/libmythtv/frame.h	(working copy)
@@ -37,6 +37,9 @@
     int top_field_first; // 1 if top field is first.
     int repeat_pict;
     int forcekey; // hardware encoded .nuv
+
+    int pitches[3]; // Y, U, & V pitches
+    int offsets[3]; // Y, U, & V offsets
 } VideoFrame;
 
 #endif
Index: libs/libmythtv/videoout_xv.h
===================================================================
--- libs/libmythtv/videoout_xv.h	(revision 10733)
+++ libs/libmythtv/videoout_xv.h	(working copy)
@@ -187,7 +187,8 @@
 
     // Used for all non-XvMC drawing
     VideoFrame           av_pause_frame;
-    vector<XShmSegmentInfo> XJ_shm_infos;
+    vector<XShmSegmentInfo*> XJ_shm_infos;
+    vector<YUVInfo>      XJ_yuv_infos;
 
     // Basic non-Xv drawing info
     XImage              *XJ_non_xv_image;
Index: libs/libmythtv/videoout_xv.cpp
===================================================================
--- libs/libmythtv/videoout_xv.cpp	(revision 10733)
+++ libs/libmythtv/videoout_xv.cpp	(working copy)
@@ -1500,13 +1500,9 @@
             .arg(num).arg(video_dim.width()).arg(video_dim.height()));
 
     vector<unsigned char*> bufs;
-    XShmSegmentInfo blank;
-    // for now make reserve big enough to avoid realloc.. 
-    // we should really have vector of pointers...
-    XJ_shm_infos.reserve(max(num + 32, (uint)128));
     for (uint i = 0; i < num; i++)
     {
-        XJ_shm_infos.push_back(blank);
+        XShmSegmentInfo *info = new XShmSegmentInfo;
         void *image = NULL;
         int size = 0;
         int desiredsize = 0;
@@ -1515,10 +1511,11 @@
 
         if (use_xv)
         {
-            image = XvShmCreateImage(XJ_disp, xv_port, xv_chroma, 0, 
-                                     video_dim.width(), video_dim.height(),
-                                     &XJ_shm_infos[i]);
-            size = ((XvImage*)image)->data_size + 64;
+            XvImage *img =
+                XvShmCreateImage(XJ_disp, xv_port, xv_chroma, 0, 
+                                 video_dim.width(), video_dim.height(), info);
+            size = img->data_size + 64;
+            image = img;
             desiredsize = video_dim.width() * video_dim.height() * 3 / 2;
 
             if (image && size < desiredsize)
@@ -1528,13 +1525,30 @@
                         "requested size.");
                 XFree(image);
                 image = NULL;
+                delete info;
             }
+
+            if (image && (3 == img->num_planes))
+            {
+                XJ_shm_infos.push_back(info);
+                YUVInfo tmp(img->width, img->height, img->pitches, img->offsets);
+                XJ_yuv_infos.push_back(tmp);
+            }
+            else if (image)
+            {
+                VERBOSE(VB_IMPORTANT, LOC_ERR + "CreateXvShmImages(): "
+                        "XvShmCreateImage() failed to create image "
+                        "with the correct number of pixel planes.");
+                XFree(image);
+                image = NULL;
+                delete info;
+            }
         }
         else
         {
             XImage *img =
                 XShmCreateImage(XJ_disp, DefaultVisual(XJ_disp, XJ_screen_num),
-                                XJ_depth, ZPixmap, 0, &XJ_shm_infos[i],
+                                XJ_depth, ZPixmap, 0, info,
                                 display_visible_rect.width(),
                                 display_visible_rect.height());
             size = img->bytes_per_line * img->height + 64;
@@ -1548,34 +1562,41 @@
                         "requested size.");
                 XDestroyImage((XImage *)image);
                 image = NULL;
+                delete info;
             }
+
+            if (image)
+            {
+                YUVInfo tmp(img->width, img->height, NULL, NULL);
+                XJ_yuv_infos.push_back(tmp);
+            }
         }
 
         X11U;
 
         if (image)
         {
-            XJ_shm_infos[i].shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777);
-            if (XJ_shm_infos[i].shmid >= 0)
+            XJ_shm_infos[i]->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777);
+            if (XJ_shm_infos[i]->shmid >= 0)
             {
-                XJ_shm_infos[i].shmaddr = (char*) shmat(XJ_shm_infos[i].shmid, 0, 0);
+                XJ_shm_infos[i]->shmaddr = (char*) shmat(XJ_shm_infos[i]->shmid, 0, 0);
                 if (use_xv)
-                    ((XvImage*)image)->data = XJ_shm_infos[i].shmaddr;
+                    ((XvImage*)image)->data = XJ_shm_infos[i]->shmaddr;
                 else
-                    ((XImage*)image)->data = XJ_shm_infos[i].shmaddr;
-                xv_buffers[(unsigned char*) XJ_shm_infos[i].shmaddr] = image;
-                XJ_shm_infos[i].readOnly = False;
+                    ((XImage*)image)->data = XJ_shm_infos[i]->shmaddr;
+                xv_buffers[(unsigned char*) XJ_shm_infos[i]->shmaddr] = image;
+                XJ_shm_infos[i]->readOnly = False;
 
                 X11L;
-                XShmAttach(XJ_disp, &XJ_shm_infos[i]);
+                XShmAttach(XJ_disp, XJ_shm_infos[i]);
                 XSync(XJ_disp, False); // needed for FreeBSD?
                 X11U;
 
                 // Mark for delete immediately.
                 // It won't actually be removed until after we detach it.
-                shmctl(XJ_shm_infos[i].shmid, IPC_RMID, 0);
+                shmctl(XJ_shm_infos[i]->shmid, IPC_RMID, 0);
 
-                bufs.push_back((unsigned char*) XJ_shm_infos[i].shmaddr);
+                bufs.push_back((unsigned char*) XJ_shm_infos[i]->shmaddr);
             }
             else
             { 
@@ -1605,7 +1626,7 @@
         vector<unsigned char*> bufs = 
             CreateShmImages(vbuffers.allocSize(), true);
         ok = vbuffers.CreateBuffers(
-            video_dim.width(), video_dim.height(), bufs);
+            video_dim.width(), video_dim.height(), bufs, XJ_yuv_infos);
 
         clear_xv_buffers(vbuffers, video_dim.width(), video_dim.height(),
                          xv_chroma);
@@ -1747,11 +1768,11 @@
         }
     }
 
-    for (uint i=0; i<XJ_shm_infos.size(); ++i)
+    for (uint i = 0; i < XJ_shm_infos.size(); i++)
     {
-        X11S(XShmDetach(XJ_disp, &(XJ_shm_infos[i])));
+        X11S(XShmDetach(XJ_disp, XJ_shm_infos[i]));
         XvImage *image = (XvImage*) 
-            xv_buffers[(unsigned char*)XJ_shm_infos[i].shmaddr];
+            xv_buffers[(unsigned char*) XJ_shm_infos[i]->shmaddr];
         if (image)
         {
             if ((XImage*)image == (XImage*)XJ_non_xv_image)
@@ -1759,10 +1780,11 @@
             else
                 X11S(XFree(image));
         }
-        if (XJ_shm_infos[i].shmaddr)
-            shmdt(XJ_shm_infos[i].shmaddr);
-        if (XJ_shm_infos[i].shmid > 0)
-            shmctl(XJ_shm_infos[0].shmid, IPC_RMID, 0);
+        if (XJ_shm_infos[i]->shmaddr)
+            shmdt(XJ_shm_infos[i]->shmaddr);
+        if (XJ_shm_infos[i]->shmid > 0)
+            shmctl(XJ_shm_infos[i]->shmid, IPC_RMID, 0);
+        delete XJ_shm_infos[i];
     }
     XJ_shm_infos.clear();
     xv_buffers.clear();
Index: libs/libmythtv/videobuffers.h
===================================================================
--- libs/libmythtv/videobuffers.h	(revision 10733)
+++ libs/libmythtv/videobuffers.h	(working copy)
@@ -44,6 +44,18 @@
     kVideoBuffer_all       = 0x0000001F,
 };
 
+class YUVInfo
+{
+  public:
+    YUVInfo(uint w, uint h, const int *p, const int *o);
+
+  public:
+    uint width;
+    uint height;
+    uint pitches[3];
+    uint offsets[3];
+};
+
 class VideoBuffers
 {
   public:
@@ -55,7 +67,9 @@
               uint needprebuffer_small, uint keepprebuffer,
               bool enable_frame_locking = false);
 
-    bool CreateBuffers(int width, int height, vector<unsigned char*> bufs);
+    bool CreateBuffers(int width, int height,
+                       vector<unsigned char*> bufs,
+                       vector<YUVInfo>        yuvinfo);
     bool CreateBuffers(int width, int height);
     void DeleteBuffers(void);
 
Index: libs/libmythtv/videobuffers.cpp
===================================================================
--- libs/libmythtv/videobuffers.cpp	(revision 10733)
+++ libs/libmythtv/videobuffers.cpp	(working copy)
@@ -18,6 +18,31 @@
 
 int next_dbg_str = 0;
 
+YUVInfo::YUVInfo(uint w, uint h, const int *p, const int *o)
+    : width(w), height(h)
+{
+    if (p)
+    {
+        memcpy(pitches, p, 3 * sizeof(int));
+    }
+    else
+    {
+        pitches[0] = width;
+        pitches[1] = pitches[2] = width >> 1;
+    }
+
+    if (o)
+    {
+        memcpy(offsets, o, 3 * sizeof(int));
+    }
+    else
+    {
+        offsets[0] = 0;
+        offsets[1] = width * height;
+        offsets[2] = offsets[1] + (offsets[1] >> 2);
+    }
+}
+
 /**
  * \class VideoBuffers
  *  This class creates tracks the state of the buffers used by 
@@ -1071,11 +1096,13 @@
 bool VideoBuffers::CreateBuffers(int width, int height)
 {
     vector<unsigned char*> bufs;
-    return CreateBuffers(width, height, bufs);
+    vector<YUVInfo>        yuvinfo;
+    return CreateBuffers(width, height, bufs, yuvinfo);
 }
 
 bool VideoBuffers::CreateBuffers(int width, int height,
-                                 vector<unsigned char*> bufs)
+                                 vector<unsigned char*> bufs,
+                                 vector<YUVInfo>        yuvinfo)
 {
     bool ok = true;
     uint bpp = 12 / 4; /* bits per pixel div common factor */
@@ -1087,6 +1114,7 @@
     uint adj_w = (width  + 15) & ~0xF;
     uint adj_h = (height + 15) & ~0xF;
     uint buf_size = (adj_w * adj_h * bpp + 4/* to round up */) / bpb;
+
     while (bufs.size() < allocSize())
     {
         unsigned char *data = (unsigned char*)av_malloc(buf_size + 64);
@@ -1097,6 +1125,8 @@
         memset(data + width * height, 127, width * height / 2);
 
         bufs.push_back(data);
+        yuvinfo.push_back(YUVInfo(width, height, NULL, NULL));
+
         if (bufs.back())
         {
             VERBOSE(VB_PLAYBACK, "Created data @"
@@ -1106,10 +1136,13 @@
         else
             ok = false;
     }
+
     for (uint i = 0; i < allocSize(); i++)
     {
-        buffers[i].width = width;
-        buffers[i].height = height;
+        buffers[i].width  = yuvinfo[i].width;
+        buffers[i].height = yuvinfo[i].height;
+        memcpy(buffers[i].pitches, yuvinfo[i].pitches, 3 * sizeof(int));
+        memcpy(buffers[i].offsets, yuvinfo[i].offsets, 3 * sizeof(int));
         buffers[i].bpp = 12;
         buffers[i].size = buf_size;
         buffers[i].codec = FMT_YV12;
