Index: libs/libmythtv/util-vdpau.cpp
===================================================================
--- libs/libmythtv/util-vdpau.cpp	(revision 19681)
+++ libs/libmythtv/util-vdpau.cpp	(working copy)
@@ -19,7 +19,8 @@
 #define LOC QString("VDPAU: ")
 #define LOC_ERR QString("VDPAU Error: ")
 
-#define NUM_OUTPUT_SURFACES 2
+#define MIN_OUTPUT_SURFACES 2
+#define MAX_OUTPUT_SURFACES 6
 #define NUM_REFERENCE_FRAMES 3
 
 #define ARSIZE(x) (sizeof(x) / sizeof((x)[0]))
@@ -59,19 +60,19 @@
 VDPAUContext::VDPAUContext()
   : nextframedelay(0),      lastframetime(0),
     pix_fmt(-1),            maxVideoWidth(0),  maxVideoHeight(0),
-    videoSurfaces(0),       surface_render(0), numSurfaces(0),
-    videoSurface(0),        outputSurface(0),  decoder(0),
+    maxReferences(2),       checkVideoSurfaces(10), 
+    outputSize(QSize(0,0)), videoSurface(0),        outputSurface(0),
+    checkOutputSurfaces(false), decoder(0),
     videoMixer(0),          surfaceNum(0),     osdVideoSurface(0),
     osdOutputSurface(0),    osdVideoMixer(0),  osdAlpha(0),
     osdSize(QSize(0,0)),    osdReady(false),   deintAvail(false),
     deinterlacer("notset"), deinterlacing(false), currentFrameNum(-1),
     needDeintRefs(false),   useColorControl(false),
     pipOutputSurface(0),    pipAlpha(0),       pipBorder(0),
-    pipClear(0),            pipReady(0),       pipLayerSize(QSize(0,0)),
+    pipClear(0),            pipReady(0),
     pipNeedsClear(false),   vdp_flip_target(NULL), vdp_flip_queue(NULL),
     vdpauDecode(false),     vdp_device(NULL),  errored(false)
 {
-    memset(outputSurfaces, 0, sizeof(outputSurfaces));
 }
 
 VDPAUContext::~VDPAUContext()
@@ -82,6 +83,8 @@
                         Window win, QSize screen_size,
                         bool color_control, MythCodecID mcodecid)
 {
+    outputSize = screen_size;
+
     if ((kCodec_VDPAU_BEGIN < mcodecid) && (mcodecid < kCodec_VDPAU_END))
         vdpauDecode = true;
 
@@ -95,7 +98,7 @@
     if (!ok)
         return ok;
 
-    ok = InitOutput(screen_size);
+    ok = InitOutput();
     if (!ok)
         return ok;
 
@@ -521,6 +524,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;
@@ -561,39 +602,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
@@ -617,7 +635,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
@@ -707,27 +725,23 @@
         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 = 10;
 }
 
-bool VDPAUContext::InitOutput(QSize size)
+bool VDPAUContext::InitOutput(void)
 {
     VdpStatus vdp_st;
     bool ok = true;
@@ -750,24 +764,25 @@
             QString("Output surface chroma format not supported."));
         return false;
     }
-    else if (max_width  < (uint)size.width() ||
-             max_height < (uint)size.height())
+    else if (max_width  < (uint)outputSize.width() ||
+             max_height < (uint)outputSize.height())
     {
         VERBOSE(VB_PLAYBACK, LOC_ERR +
             QString("Output surface - too large (%1x%2 > %3x%4).")
-            .arg(size.width()).arg(size.height())
+            .arg(outputSize.width()).arg(outputSize.height())
             .arg(max_width).arg(max_height));
         return false;
     }
     
-    for (i = 0; i < NUM_OUTPUT_SURFACES; i++)
+    for (i = 0; i < MIN_OUTPUT_SURFACES; i++)
     {
+        VdpOutputSurface tmp;
         vdp_st = vdp_output_surface_create(
             vdp_device,
             VDP_RGBA_FORMAT_B8G8R8A8,
-            size.width(),
-            size.height(),
-            &outputSurfaces[i]
+            outputSize.width(),
+            outputSize.height(),
+            &tmp
         );
         CHECK_ST
 
@@ -777,12 +792,13 @@
                 QString("Failed to create output surface."));
             return false;
         }
+        outputSurfaces.push_back(tmp);
     }
 
     outRect.x0 = 0;
     outRect.y0 = 0;
-    outRect.x1 = size.width();
-    outRect.y1 = size.height();
+    outRect.x1 = outputSize.width();
+    outRect.y1 = outputSize.height();
     surfaceNum = 0;
     return ok;
 }
@@ -794,9 +810,9 @@
 
     VdpStatus vdp_st;
     bool ok = true;
-    int i;
+    uint i;
 
-    for (i = 0; i < NUM_OUTPUT_SURFACES; i++)
+    for (i = 0; i < outputSurfaces.size(); i++)
     {
         if (outputSurfaces[i])
         {
@@ -805,6 +821,9 @@
             CHECK_ST
         }
     }
+    outputSurfaces.clear();
+    outputSize = QSize(0,0);
+    checkOutputSurfaces = false;
 }
 
 void VDPAUContext::Decode(VideoFrame *frame)
@@ -818,21 +837,25 @@
 
     VdpStatus vdp_st;
     bool ok = true;
-    vdpau_render_state_t *render;
+    vdpau_render_state_t *render = (vdpau_render_state_t *)frame->buf;
 
     if (frame->pix_fmt != pix_fmt)
     {
-        uint32_t max_references = 2;
-
         if (frame->pix_fmt == PIX_FMT_VDPAU_H264_MAIN ||
             frame->pix_fmt == PIX_FMT_VDPAU_H264_HIGH)
         {
-            uint32_t round_width = (frame->width + 15) & ~15;
-            uint32_t round_height = (frame->height + 15) & ~15;
-            uint32_t surf_size = (round_width * round_height * 3) / 2;
-            max_references = (12 * 1024 * 1024) / surf_size;
-            if (max_references > 16)
-                max_references = 16;
+            if (render)
+                maxReferences = render->info.h264.num_ref_frames;
+
+            if (maxReferences < 1 || maxReferences > 16)
+            {
+                uint32_t round_width = (frame->width + 15) & ~15;
+                uint32_t round_height = (frame->height + 15) & ~15;
+                uint32_t surf_size = (round_width * round_height * 3) / 2;
+                maxReferences = (12 * 1024 * 1024) / surf_size;
+            }
+            if (maxReferences > 16)
+                maxReferences = 16;
         }
 
         VdpDecoderProfile vdp_decoder_profile;
@@ -858,7 +881,7 @@
             vdp_decoder_profile,
             frame->width,
             frame->height,
-            max_references,
+            maxReferences,
             &decoder
         );
         CHECK_ST
@@ -868,7 +891,7 @@
             pix_fmt = frame->pix_fmt;
             VERBOSE(VB_PLAYBACK, LOC +
                 QString("Created VDPAU decoder (%1 ref frames)")
-                .arg(max_references));
+                .arg(maxReferences));
         }
         else
         {
@@ -877,7 +900,6 @@
         }
     }
 
-    render = (vdpau_render_state_t *)frame->buf;
     if (!render || !decoder)
         return;
 
@@ -891,11 +913,21 @@
     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)
+                                FrameScanType scan, bool pause_frame)
 {
+    int ret = (maxReferences + (deinterlacing ? 5 : 3)) - GetNumBufs();
+    if (ret < 0 || !vdpauDecode || (checkVideoSurfaces != 1))
+        ret = 0;
+    // once we've tried to add video surfaces, try to increase
+    // the number of output surfaces
+    if (checkVideoSurfaces == 1)
+        checkOutputSurfaces = true;
+
+    if (checkVideoSurfaces > 0)
+        checkVideoSurfaces--;
+
     VdpStatus vdp_st;
     bool ok = true;
     VdpTime dummy;
@@ -914,7 +946,7 @@
     {
         render = (vdpau_render_state_t *)frame->buf;
         if (!render)
-            return;
+            return ret;
 
         videoSurface = render->surface;
     }
@@ -924,7 +956,7 @@
         if (deint)
             surf = (currentFrameNum + 1) % NUM_REFERENCE_FRAMES;
 
-        videoSurface = videoSurfaces[surf];
+        videoSurface = videoSurfaces[surf].surface;
 
         uint32_t pitches[3] = {
             frame->pitches[0],
@@ -943,22 +975,15 @@
             pitches);
         CHECK_ST;
         if (!ok)
-            return;
+            return ret;
     }
     else if (!frame)
     {
         deint = false;
         if (!videoSurface)
-            videoSurface = videoSurfaces[0];
+            videoSurface = videoSurfaces[0].surface;
     }
 
-    if (outRect.x1 != (uint)screen_size.width() ||
-        outRect.y1 != (uint)screen_size.height())
-    {
-        FreeOutput();
-        InitOutput(screen_size);
-    }
-
     // fix broken/missing negative rect clipping in vdpau
     if (display_video_rect.top() < 0 && display_video_rect.height() > 0)
     {
@@ -980,11 +1005,6 @@
         display_video_rect.setLeft(0);
     }
 
-    outRect.x0 = 0;
-    outRect.y0 = 0;
-    outRect.x1 = screen_size.width();
-    outRect.y1 = screen_size.height();
-
     VdpRect srcRect;
     srcRect.x0 = video_rect.left();
     srcRect.y0 = video_rect.top();
@@ -1032,7 +1052,7 @@
                 int ref = (currentFrameNum + i - 1) % NUM_REFERENCE_FRAMES;
                 if (ref < 0)
                     ref = 0;
-                refs[i] = videoSurfaces[ref];
+                refs[i] = videoSurfaces[ref].surface;
             }
         }
 
@@ -1099,6 +1119,8 @@
     if (pipReady)
         pipReady--;
     pipNeedsClear = true;
+
+    return ret;
 }
 
 void VDPAUContext::DisplayNextFrame(void)
@@ -1133,15 +1155,54 @@
     );
     CHECK_ST
 
-    surfaceNum = surfaceNum ^ 1;
+    surfaceNum++;
+    if (surfaceNum >= (int)(outputSurfaces.size()))
+        surfaceNum = 0;
+
+    if (checkOutputSurfaces)
+        AddOutputSurfaces();
 }
 
+void VDPAUContext::AddOutputSurfaces(void)
+{
+    checkOutputSurfaces = false;
+    VdpStatus vdp_st;
+    bool ok = true;
+
+    int cnt = 0;
+    int extra = MAX_OUTPUT_SURFACES - outputSurfaces.size();
+    if (extra <= 0)
+        return;
+
+    for (int i = 0; i < extra; i++)
+    {
+        VdpOutputSurface tmp;
+        vdp_st = vdp_output_surface_create(
+            vdp_device,
+            VDP_RGBA_FORMAT_B8G8R8A8,
+            outputSize.width(),
+            outputSize.height(),
+            &tmp
+        );
+        // suppress non-fatal error messages
+        ok &= (vdp_st == VDP_STATUS_OK);
+
+        if (!ok)
+            break;
+
+        outputSurfaces.push_back(tmp);
+        cnt++;
+    }
+    VERBOSE(VB_PLAYBACK, LOC + QString("Using %1 output surfaces (max %2)")
+        .arg(outputSurfaces.size()).arg(MAX_OUTPUT_SURFACES));
+}
+
 void VDPAUContext::SetNextFrameDisplayTimeOffset(int delayus)
 {
     nextframedelay = delayus;
 }
 
-bool VDPAUContext::InitOSD(QSize osd_size)
+bool VDPAUContext::InitOSD(void)
 {
     if (!vdp_device)
         return false;
@@ -1149,8 +1210,8 @@
     VdpStatus vdp_st;
     bool ok = true;
 
-    uint width = osd_size.width();
-    uint height = osd_size.height();
+    uint width = outputSize.width();
+    uint height = outputSize.height();
     VdpBool supported = false;
 
     vdp_st = vdp_video_surface_query_get_put_bits_y_cb_cr_capabilities(
@@ -1282,7 +1343,6 @@
     }
     else
     {
-        osdSize = osd_size;
         osdRect.x0 = 0;
         osdRect.y0 = 0;
         osdRect.x1 = width;
@@ -1296,22 +1356,19 @@
         return ok;
     }
 
-    osdSize = QSize(0,0);
     return ok;
 }
 
 void VDPAUContext::UpdateOSD(void* const planes[3],
-                             QSize size,
                              void* const alpha[1])
 {
-    if (size != osdSize)
-        return;
-
     VdpStatus vdp_st;
     bool ok = true;
 
     // upload OSD YV12 data
-    uint32_t pitches[3] = {size.width(), size.width()>>1, size.width()>>1};
+    uint32_t pitches[3] = {outputSize.width(),
+                           outputSize.width()>>1,
+                           outputSize.width()>>1};
     void * const realplanes[3] = { planes[0], planes[2], planes[1] };
 
     vdp_st = vdp_video_surface_put_bits_y_cb_cr(osdVideoSurface,
@@ -1346,7 +1403,7 @@
     // upload OSD alpha data
     if (ok)
     {
-        uint32_t pitch[1] = {size.width()};
+        uint32_t pitch[1] = {outputSize.width()};
         vdp_st = vdp_bitmap_surface_put_bits_native(
             osdAlpha,
             alpha,
@@ -1765,7 +1822,7 @@
         VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME,
         0,
         NULL,
-        videoSurfaces[0],
+        videoSurfaces[0].surface,
         0,
         NULL,
         &srcRect,
@@ -1811,15 +1868,11 @@
         pipClear = 0;
     }
 
-    pipLayerSize = QSize(0, 0);
     pipReady     = 0;
 }
 
-bool VDPAUContext::InitPIPLayer(QSize screen_size)
+bool VDPAUContext::InitPIPLayer(void)
 {
-    if (pipLayerSize != screen_size)
-        DeinitPIPLayer();
-
     bool ok = true;
     VdpStatus vdp_st;
 
@@ -1828,8 +1881,8 @@
         vdp_st = vdp_output_surface_create(
             vdp_device,
             VDP_RGBA_FORMAT_B8G8R8A8,
-            screen_size.width(),
-            screen_size.height(),
+            outputSize.width(),
+            outputSize.height(),
             &pipOutputSurface
         );
         CHECK_ST
@@ -1922,7 +1975,6 @@
 
     if (ok && pipNeedsClear)
     {
-        pipLayerSize = screen_size;
         vdp_st = vdp_output_surface_render_bitmap_surface(
             pipOutputSurface,
             NULL,
Index: libs/libmythtv/util-vdpau.h
===================================================================
--- libs/libmythtv/util-vdpau.h	(revision 19681)
+++ 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
@@ -27,28 +34,27 @@
     void Deinit(void);
     bool IsErrored(void) { return errored; }
 
+    int  AddBuffer(int width, int height);
     bool InitBuffers(int width, int height, int numbufs);
     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);
+    bool InitOutput(void);
     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);
+                      FrameScanType scan, bool pause_frame);
     void DisplayNextFrame(void);
     void SetNextFrameDisplayTimeOffset(int delayus);
-    bool InitOSD(QSize osd_size);
-    void UpdateOSD(void* const planes[3], QSize size,
-                   void* const alpha[1]);
+    bool InitOSD(void);
+    void UpdateOSD(void* const planes[3], void* const alpha[1]);
     void DisableOSD(void) { osdReady = false; }
     void DeinitOSD(void);
 
@@ -63,7 +69,7 @@
     PictureAttributeSupported  GetSupportedPictureAttributes(void) const;
     int SetPictureAttribute(PictureAttribute attributeType, int newValue);
 
-    bool InitPIPLayer(QSize screen_size);
+    bool InitPIPLayer(void);
     bool ShowPIP(NuppelVideoPlayer *pipplayer,
                  VideoFrame * frame, QRect position,
                  bool pip_is_active);
@@ -76,11 +82,10 @@
 
     bool InitFlipQueue(Window win);
     void DeinitFlipQueue(void);
-
+    void AddOutputSurfaces(void);
     bool UpdateReferenceFrames(VideoFrame *frame);
     bool InitColorControl(void);
     bool SetPictureAttributes(void);
-
     
     void DeinitPIPLayer(void);
     bool InitPIP(NuppelVideoPlayer *pipplayer, QSize vid_size);
@@ -92,13 +97,15 @@
 
     uint maxVideoWidth;
     uint maxVideoHeight;
-    VdpVideoSurface *videoSurfaces;
-    vdpau_render_state_t *surface_render;
-    int numSurfaces;
+    vector<video_surface> videoSurfaces;
+    uint32_t maxReferences;
+    int checkVideoSurfaces;
 
-    VdpOutputSurface outputSurfaces[2];
+    QSize outputSize;
+    vector<VdpOutputSurface> outputSurfaces;
     VdpVideoSurface videoSurface;
     VdpOutputSurface outputSurface;
+    bool checkOutputSurfaces;
 
     VdpDecoder decoder;
     VdpVideoMixer videoMixer;
@@ -135,7 +142,6 @@
     VdpBitmapSurface  pipClear;
     QMap<NuppelVideoPlayer*,vdpauPIP> pips;
     int  pipReady;
-    QSize             pipLayerSize;
     bool              pipNeedsClear;
 
     VdpPresentationQueueTarget vdp_flip_target;
Index: libs/libmythtv/videoout_xv.cpp
===================================================================
--- libs/libmythtv/videoout_xv.cpp	(revision 19681)
+++ 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, Screen *screen, Window curwin);
@@ -1672,7 +1672,7 @@
     if (osd_renderer == "vdpau" && vdpau)
     {
         vdpau_use_osd = true;
-        if (!vdpau->InitOSD(GetTotalOSDBounds().size()))
+        if (!vdpau->InitOSD())
         {
             vdpau_use_osd = false;
             VERBOSE(VB_IMPORTANT, LOC + "Init VDPAU osd failed.");
@@ -3128,10 +3128,18 @@
     if (!vdpau)
         return;
 
-    vdpau->PrepareVideo(
+    int extra_bufs = vdpau->PrepareVideo(
         frame, windows[0].GetVideoRect(), windows[0].GetDisplayVideoRect(),
-    	windows[0].GetDisplayVisibleRect().size(), scan, pause);
+        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)
@@ -3704,7 +3712,7 @@
 #ifdef USING_VDPAU
     if (vdpau && vdpau_use_pip && VideoOutputSubType() == XVideoVDPAU)
     {
-        if (vdpau->InitPIPLayer(dvr.size()))
+        if (vdpau->InitPIPLayer())
             vdpau_use_pip = vdpau->ShowPIP(pipplayer, pipimage,
                                            position, pipActive);
         pipplayer->ReleaseCurrentFrame(pipimage);
@@ -4954,7 +4962,7 @@
             offsets[1] = surface->u;
             offsets[2] = surface->v;
             alpha[0] = surface->alpha;
-            vdpau->UpdateOSD(offsets, visible, alpha);
+            vdpau->UpdateOSD(offsets, alpha);
 #endif // USING_VDPAU
         }
         else if (gl_use_osd_opengl2)
Index: libs/libmythtv/videobuffers.h
===================================================================
--- libs/libmythtv/videobuffers.h	(revision 19681)
+++ 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 19681)
+++ 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
