Index: libs/libmythtv/util-vdpau.cpp
===================================================================
--- libs/libmythtv/util-vdpau.cpp	(revision 19891)
+++ libs/libmythtv/util-vdpau.cpp	(working copy)
@@ -60,9 +60,8 @@
 VDPAUContext::VDPAUContext()
   : nextframedelay(0),      lastframetime(0),
     pix_fmt(-1),            maxVideoWidth(0),  maxVideoHeight(0),
-    videoSurfaces(0),       surface_render(0), checkVideoSurfaces(8),
-    numSurfaces(0),
-    videoSurface(0),        outputSurface(0),  checkOutputSurfaces(false),
+    checkVideoSurfaces(8),
+    outputSurface(0),       checkOutputSurfaces(false),
     outputSize(QSize(0,0)), decoder(0),        maxReferences(2),
     videoMixer(0),          surfaceNum(0),     osdVideoSurface(0),
     osdOutputSurface(0),    osdVideoMixer(0),  osdAlpha(0),
@@ -526,6 +525,44 @@
     }
 }
 
+int VDPAUContext::AddBuffer(int width, int height)
+{
+    VdpStatus vdp_st;
+    bool ok = true;
+
+    video_surface tmp;
+    tmp.surface = 0;
+
+    vdp_st = vdp_video_surface_create(
+        vdp_device,
+        vdp_chroma_type,
+        width,
+        height,
+        &(tmp.surface)
+    );
+    CHECK_ST
+
+    if (!ok || !tmp.surface)
+    {
+        VERBOSE(VB_PLAYBACK, LOC_ERR +
+            QString("Failed to create video surface."));
+        return -1;
+    }
+
+    if (vdpauDecode)
+    {
+        vdpau_render_state_t new_rend;
+        memset(&new_rend, 0, sizeof(vdpau_render_state_t));
+        new_rend.magic = MP_VDPAU_RENDER_MAGIC;
+        new_rend.state = 0;
+        new_rend.surface = tmp.surface;
+        tmp.render = new_rend;
+    }
+
+    videoSurfaces.push_back(tmp);
+    return GetNumBufs() - 1;
+}
+
 bool VDPAUContext::InitBuffers(int width, int height, int numbufs)
 {
     int num_bufs = numbufs;
@@ -566,39 +603,16 @@
         return false;
     }
 
-    videoSurfaces = (VdpVideoSurface *)malloc(sizeof(VdpVideoSurface) * num_bufs);
-    if (vdpauDecode)
-    {
-        surface_render = (vdpau_render_state_t*)malloc(sizeof(vdpau_render_state_t) * num_bufs);
-        memset(surface_render, 0, sizeof(vdpau_render_state_t) * num_bufs);
-    }
-
-    numSurfaces = num_bufs;
-
     for (i = 0; i < num_bufs; i++)
     {
-        vdp_st = vdp_video_surface_create(
-            vdp_device,
-            vdp_chroma_type,
-            width,
-            height,
-            &(videoSurfaces[i])
-        );
-        CHECK_ST
-
-        if (!ok)
+        int tmp = AddBuffer(width, height);
+        if (tmp != i)
         {
-            VERBOSE(VB_PLAYBACK, LOC_ERR +
-                QString("Failed to create video surface."));
+            VERBOSE(VB_IMPORTANT, LOC +
+                QString("Failed to add buffer %1 of %2")
+                .arg(i+1).arg(num_bufs));
             return false;
         }
-
-        if (vdpauDecode)
-        {
-            surface_render[i].magic = MP_VDPAU_RENDER_MAGIC;
-            surface_render[i].state = 0;
-            surface_render[i].surface = videoSurfaces[i];
-        }
     }
 
     // clear video surfaces to black
@@ -622,7 +636,7 @@
             for (i = 0; i < num_bufs; i++)
             {
                 vdp_video_surface_put_bits_y_cb_cr(
-                    videoSurfaces[i],
+                    videoSurfaces[i].surface,
                     VDP_YCBCR_FORMAT_YV12,
                     planes,
                     pitches
@@ -712,24 +726,20 @@
         CHECK_ST
     }
 
-    if (videoSurfaces)
+    if (videoSurfaces.size())
     {
-        for (i = 0; i < numSurfaces; i++)
+        for (i = 0; i < GetNumBufs(); i++)
         {
-            if (videoSurfaces[i])
+            if (videoSurfaces[i].surface)
             {
                 vdp_st = vdp_video_surface_destroy(
-                    videoSurfaces[i]);
+                    videoSurfaces[i].surface);
                 CHECK_ST
             }
         }
-        free(videoSurfaces);
-        videoSurfaces = NULL;
+        videoSurfaces.clear();
     }
-
-    if (surface_render)
-        free(surface_render);
-    surface_render = NULL;
+    checkVideoSurfaces = 8;
 }
 
 bool VDPAUContext::InitOutput(QSize size)
@@ -904,11 +914,15 @@
     CHECK_ST
 }
 
-void VDPAUContext::PrepareVideo(VideoFrame *frame, QRect video_rect,
+int VDPAUContext::PrepareVideo(VideoFrame *frame, QRect video_rect,
                                 QRect display_video_rect,
                                 QSize screen_size, FrameScanType scan,
                                 bool pause_frame)
 {
+    int ret = (maxReferences + (deinterlacing ? 5 : 3)) - GetNumBufs();
+    if (ret < 0 || !vdpauDecode || (checkVideoSurfaces != 1))
+        ret = 0;
+
     if (checkVideoSurfaces == 1)
         checkOutputSurfaces = true;
 
@@ -919,6 +933,7 @@
     bool ok = true;
     VdpTime dummy;
     vdpau_render_state_t *render;
+    VdpVideoSurface video_surface = 0;
 
     bool new_frame = true;
     bool deint = (deinterlacing && needDeintRefs && !pause_frame);
@@ -933,9 +948,9 @@
     {
         render = (vdpau_render_state_t *)frame->buf;
         if (!render)
-            return;
+            return ret;
 
-        videoSurface = render->surface;
+        video_surface = render->surface;
     }
     else if (new_frame && frame)
     {
@@ -943,7 +958,7 @@
         if (deint)
             surf = (currentFrameNum + 1) % NUM_REFERENCE_FRAMES;
 
-        videoSurface = videoSurfaces[surf];
+        video_surface = videoSurfaces[surf].surface;
 
         uint32_t pitches[3] = {
             frame->pitches[0],
@@ -956,19 +971,19 @@
             frame->buf + frame->offsets[1]
         };
         vdp_st = vdp_video_surface_put_bits_y_cb_cr(
-            videoSurface,
+            video_surface,
             VDP_YCBCR_FORMAT_YV12,
             planes,
             pitches);
         CHECK_ST;
         if (!ok)
-            return;
+            return ret;
     }
     else if (!frame)
     {
         deint = false;
-        if (!videoSurface)
-            videoSurface = videoSurfaces[0];
+        if (!video_surface)
+            video_surface = videoSurfaces[0].surface;
     }
 
     if (outRect.x1 != (uint)screen_size.width() ||
@@ -1052,11 +1067,11 @@
                 int ref = (currentFrameNum + i - 1) % NUM_REFERENCE_FRAMES;
                 if (ref < 0)
                     ref = 0;
-                refs[i] = videoSurfaces[ref];
+                refs[i] = videoSurfaces[ref].surface;
             }
         }
 
-        videoSurface = refs[1];
+        video_surface = refs[1];
  
         if (scan == kScan_Interlaced)
         {
@@ -1104,7 +1119,7 @@
         field,
         deint ? ARSIZE(past_surfaces) : 0,
         deint ? past_surfaces : NULL,
-        videoSurface,
+        video_surface,
         deint ? ARSIZE(future_surfaces) : 0,
         deint ? future_surfaces : NULL,
         &srcRect,
@@ -1119,6 +1134,8 @@
     if (pipReady)
         pipReady--;
     pipNeedsClear = true;
+
+    return ret;
 }
 
 void VDPAUContext::DisplayNextFrame(void)
@@ -1830,7 +1847,7 @@
         VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME,
         0,
         NULL,
-        videoSurfaces[0],
+        videoSurfaces[0].surface,
         0,
         NULL,
         &srcRect,
Index: libs/libmythtv/util-vdpau.h
===================================================================
--- libs/libmythtv/util-vdpau.h	(revision 19891)
+++ libs/libmythtv/util-vdpau.h	(working copy)
@@ -13,6 +13,13 @@
     VdpVideoSurface videoSurface;
     VdpVideoMixer   videoMixer;
 };
+
+struct video_surface
+{
+    VdpVideoSurface      surface;
+    vdpau_render_state_t render;
+};
+
 class NuppelVideoPlayer;
 
 class VDPAUContext
@@ -28,19 +35,20 @@
     bool IsErrored(void) { return errored; }
 
     bool InitBuffers(int width, int height, int numbufs);
+    int  AddBuffer(int width, int height);
     void FreeBuffers(void);
-    void *GetRenderData(int i) 
-    { if (i < numSurfaces && i >= 0) return (void*)&(surface_render[i]); 
+    void *GetRenderData(int i)
+    { if (i < GetNumBufs() && i >= 0) return (void*)&(videoSurfaces[i].render);
       return NULL;
     }
-    int GetNumBufs(void) { return numSurfaces; }
+    int GetNumBufs(void) { return videoSurfaces.size(); }
 
     bool InitOutput(QSize size);
     void FreeOutput(void);
 
     void Decode(VideoFrame *frame);
 
-    void PrepareVideo(VideoFrame *frame, QRect video_rect,
+    int PrepareVideo(VideoFrame *frame, QRect video_rect,
                       QRect display_video_rect,
                       QSize screen_size, FrameScanType scan,
                       bool pause_frame);
@@ -93,13 +101,10 @@
 
     uint maxVideoWidth;
     uint maxVideoHeight;
-    VdpVideoSurface *videoSurfaces;
-    vdpau_render_state_t *surface_render;
+    vector<video_surface> videoSurfaces;
     int checkVideoSurfaces;
-    int numSurfaces;
 
     vector<VdpOutputSurface> outputSurfaces;
-    VdpVideoSurface  videoSurface;
     VdpOutputSurface outputSurface;
     bool             checkOutputSurfaces;
     QSize            outputSize;
Index: libs/libmythtv/videoout_xv.cpp
===================================================================
--- libs/libmythtv/videoout_xv.cpp	(revision 19891)
+++ libs/libmythtv/videoout_xv.cpp	(working copy)
@@ -84,7 +84,7 @@
 #define XVMC_CHROMA_FORMAT_420 0x00000001
 #endif
 
-#define NUM_VDPAU_BUFFERS 17
+#define NUM_VDPAU_BUFFERS 6
 
 static QStringList allowed_video_renderers(
     MythCodecID codec_id, Display *display, int screen, Window curwin);
@@ -3127,10 +3127,18 @@
     if (!vdpau)
         return;
 
-    vdpau->PrepareVideo(
+    int extra_bufs = vdpau->PrepareVideo(
         frame, windows[0].GetVideoRect(), windows[0].GetDisplayVideoRect(),
     	windows[0].GetDisplayVisibleRect().size(), scan, pause);
 
+    if (extra_bufs)
+    {
+        vbuffers.begin_lock(kVideoBuffer_avail);
+        QSize vid_dim = windows[0].GetVideoDim();
+        vbuffers.Add(vid_dim.width(), vid_dim.height(), vdpau, extra_bufs);
+        vbuffers.end_lock();
+    }
+
 #endif
 
     if (pause)
Index: libs/libmythtv/videobuffers.h
===================================================================
--- libs/libmythtv/videobuffers.h	(revision 19891)
+++ libs/libmythtv/videobuffers.h	(working copy)
@@ -165,6 +165,7 @@
 
 #ifdef USING_VDPAU
     bool CreateBuffers(int width, int height, VDPAUContext *ctx);
+    void Add(int width, int height, VDPAUContext *ctx, int num);
 #endif
 
     QString GetStatus(int n=-1) const; // debugging method
Index: libs/libmythtv/videobuffers.cpp
===================================================================
--- libs/libmythtv/videobuffers.cpp	(revision 19891)
+++ libs/libmythtv/videobuffers.cpp	(working copy)
@@ -1164,11 +1164,11 @@
 }
 
 #ifdef USING_VDPAU
+static unsigned char *ffmpeg_vdpau_hack = (unsigned char*)
+    "avlib should not use this private data in VDPAU mode.";
+
 bool VideoBuffers::CreateBuffers(int width, int height, VDPAUContext *ctx)
 {
-    static unsigned char *ffmpeg_vdpau_hack = (unsigned char*)
-        "avlib should not use this private data in VDPAU mode.";
-
     if (!ctx)
         return false;
 
@@ -1191,6 +1191,48 @@
     }
     return true;
 }
+
+void VideoBuffers::Add(int width, int height, VDPAUContext *ctx, int num)
+{
+    if (!ctx)
+        return;
+
+    int cnt = 0;
+    QMutexLocker locker(&global_lock);
+
+    for (int i =0; i < num; i++)
+    {
+        int new_surf = ctx->AddBuffer(width, height);
+        if (new_surf > 0)
+        {
+            int ref = allocSize();
+            if (ref != new_surf)
+            {
+                VERBOSE(VB_PLAYBACK, QString("VideoBuffers::Add - ") +
+                    QString("mis-match between VideoBuffers and VDPAU."));
+                continue;
+            }
+            VideoFrame tmp;
+            memset(&tmp, 0, sizeof(VideoFrame));
+            buffers.push_back(tmp);
+            init(&buffers[ref], FMT_VDPAU, (unsigned char*)ctx->GetRenderData(new_surf), width, height, -1, 0);
+            vbufferMap[at(ref)] = ref;
+            numbuffers = allocSize();
+            buffers[ref].priv[0]      = ffmpeg_vdpau_hack;
+            buffers[ref].priv[1]      = ffmpeg_vdpau_hack;
+            enqueue(kVideoBuffer_avail, at(ref));
+            cnt++;
+        }
+        else
+        {
+            continue;
+        }
+    }
+    VERBOSE(VB_PLAYBACK,
+        QString("Added %1 VDPAU video buffer(s) (%2 requested).")
+            .arg(cnt).arg(num));
+    return;
+}
 #endif
 
 #ifdef USING_XVMC
