Ticket #6130: vdpau_optimisations.diff

File vdpau_optimisations.diff, 23.4 KB (added by anonymous, 12 years ago)
  • libs/libmythtv/util-vdpau.cpp

     
    1919#define LOC QString("VDPAU: ")
    2020#define LOC_ERR QString("VDPAU Error: ")
    2121
    22 #define NUM_OUTPUT_SURFACES 2
     22#define MIN_OUTPUT_SURFACES 2
     23#define MAX_OUTPUT_SURFACES 6
    2324#define NUM_REFERENCE_FRAMES 3
    2425
    2526#define ARSIZE(x) (sizeof(x) / sizeof((x)[0]))
     
    5960VDPAUContext::VDPAUContext()
    6061  : nextframedelay(0),      lastframetime(0),
    6162    pix_fmt(-1),            maxVideoWidth(0),  maxVideoHeight(0),
    62     videoSurfaces(0),       surface_render(0), numSurfaces(0),
    63     videoSurface(0),        outputSurface(0),  decoder(0),
     63    maxReferences(2),       checkVideoSurfaces(10),
     64    outputSize(QSize(0,0)), videoSurface(0),        outputSurface(0),
     65    checkOutputSurfaces(false), decoder(0),
    6466    videoMixer(0),          surfaceNum(0),     osdVideoSurface(0),
    6567    osdOutputSurface(0),    osdVideoMixer(0),  osdAlpha(0),
    6668    osdSize(QSize(0,0)),    osdReady(false),   deintAvail(false),
    6769    deinterlacer("notset"), deinterlacing(false), currentFrameNum(-1),
    6870    needDeintRefs(false),   useColorControl(false),
    6971    pipOutputSurface(0),    pipAlpha(0),       pipBorder(0),
    70     pipClear(0),            pipReady(0),       pipLayerSize(QSize(0,0)),
     72    pipClear(0),            pipReady(0),
    7173    pipNeedsClear(false),   vdp_flip_target(NULL), vdp_flip_queue(NULL),
    7274    vdpauDecode(false),     vdp_device(NULL),  errored(false)
    7375{
    74     memset(outputSurfaces, 0, sizeof(outputSurfaces));
    7576}
    7677
    7778VDPAUContext::~VDPAUContext()
     
    8283                        Window win, QSize screen_size,
    8384                        bool color_control, MythCodecID mcodecid)
    8485{
     86    outputSize = screen_size;
     87
    8588    if ((kCodec_VDPAU_BEGIN < mcodecid) && (mcodecid < kCodec_VDPAU_END))
    8689        vdpauDecode = true;
    8790
     
    9598    if (!ok)
    9699        return ok;
    97100
    98     ok = InitOutput(screen_size);
     101    ok = InitOutput();
    99102    if (!ok)
    100103        return ok;
    101104
     
    521524    }
    522525}
    523526
     527int VDPAUContext::AddBuffer(int width, int height)
     528{
     529    VdpStatus vdp_st;
     530    bool ok = true;
     531
     532    video_surface tmp;
     533    tmp.surface = 0;
     534
     535    vdp_st = vdp_video_surface_create(
     536        vdp_device,
     537        vdp_chroma_type,
     538        width,
     539        height,
     540        &(tmp.surface)
     541    );
     542    CHECK_ST
     543
     544    if (!ok || !tmp.surface)
     545    {
     546        VERBOSE(VB_PLAYBACK, LOC_ERR +
     547            QString("Failed to create video surface."));
     548        return -1;
     549    }
     550
     551    if (vdpauDecode)
     552    {
     553        vdpau_render_state_t new_rend;
     554        memset(&new_rend, 0, sizeof(vdpau_render_state_t));
     555        new_rend.magic = MP_VDPAU_RENDER_MAGIC;
     556        new_rend.state = 0;
     557        new_rend.surface = tmp.surface;
     558        tmp.render = new_rend;
     559    }
     560
     561    videoSurfaces.push_back(tmp);
     562    return GetNumBufs() - 1;
     563}
     564
    524565bool VDPAUContext::InitBuffers(int width, int height, int numbufs)
    525566{
    526567    int num_bufs = numbufs;
     
    561602        return false;
    562603    }
    563604
    564     videoSurfaces = (VdpVideoSurface *)malloc(sizeof(VdpVideoSurface) * num_bufs);
    565     if (vdpauDecode)
    566     {
    567         surface_render = (vdpau_render_state_t*)malloc(sizeof(vdpau_render_state_t) * num_bufs);
    568         memset(surface_render, 0, sizeof(vdpau_render_state_t) * num_bufs);
    569     }
    570 
    571     numSurfaces = num_bufs;
    572 
    573605    for (i = 0; i < num_bufs; i++)
    574606    {
    575         vdp_st = vdp_video_surface_create(
    576             vdp_device,
    577             vdp_chroma_type,
    578             width,
    579             height,
    580             &(videoSurfaces[i])
    581         );
    582         CHECK_ST
    583 
    584         if (!ok)
     607        int tmp = AddBuffer(width, height);
     608        if (tmp != i)
    585609        {
    586             VERBOSE(VB_PLAYBACK, LOC_ERR +
    587                 QString("Failed to create video surface."));
     610            VERBOSE(VB_IMPORTANT, LOC +
     611                QString("Failed to add buffer %1 of %2")
     612                .arg(i+1).arg(num_bufs));
    588613            return false;
    589614        }
    590 
    591         if (vdpauDecode)
    592         {
    593             surface_render[i].magic = MP_VDPAU_RENDER_MAGIC;
    594             surface_render[i].state = 0;
    595             surface_render[i].surface = videoSurfaces[i];
    596         }
    597615    }
    598616
    599617    // clear video surfaces to black
     
    617635            for (i = 0; i < num_bufs; i++)
    618636            {
    619637                vdp_video_surface_put_bits_y_cb_cr(
    620                     videoSurfaces[i],
     638                    videoSurfaces[i].surface,
    621639                    VDP_YCBCR_FORMAT_YV12,
    622640                    planes,
    623641                    pitches
     
    707725        CHECK_ST
    708726    }
    709727
    710     if (videoSurfaces)
     728    if (videoSurfaces.size())
    711729    {
    712         for (i = 0; i < numSurfaces; i++)
     730        for (i = 0; i < GetNumBufs(); i++)
    713731        {
    714             if (videoSurfaces[i])
     732            if (videoSurfaces[i].surface)
    715733            {
    716734                vdp_st = vdp_video_surface_destroy(
    717                     videoSurfaces[i]);
     735                    videoSurfaces[i].surface);
    718736                CHECK_ST
    719737            }
    720738        }
    721         free(videoSurfaces);
    722         videoSurfaces = NULL;
     739        videoSurfaces.clear();
    723740    }
    724 
    725     if (surface_render)
    726         free(surface_render);
    727     surface_render = NULL;
     741    checkVideoSurfaces = 10;
    728742}
    729743
    730 bool VDPAUContext::InitOutput(QSize size)
     744bool VDPAUContext::InitOutput(void)
    731745{
    732746    VdpStatus vdp_st;
    733747    bool ok = true;
     
    750764            QString("Output surface chroma format not supported."));
    751765        return false;
    752766    }
    753     else if (max_width  < (uint)size.width() ||
    754              max_height < (uint)size.height())
     767    else if (max_width  < (uint)outputSize.width() ||
     768             max_height < (uint)outputSize.height())
    755769    {
    756770        VERBOSE(VB_PLAYBACK, LOC_ERR +
    757771            QString("Output surface - too large (%1x%2 > %3x%4).")
    758             .arg(size.width()).arg(size.height())
     772            .arg(outputSize.width()).arg(outputSize.height())
    759773            .arg(max_width).arg(max_height));
    760774        return false;
    761775    }
    762776   
    763     for (i = 0; i < NUM_OUTPUT_SURFACES; i++)
     777    for (i = 0; i < MIN_OUTPUT_SURFACES; i++)
    764778    {
     779        VdpOutputSurface tmp;
    765780        vdp_st = vdp_output_surface_create(
    766781            vdp_device,
    767782            VDP_RGBA_FORMAT_B8G8R8A8,
    768             size.width(),
    769             size.height(),
    770             &outputSurfaces[i]
     783            outputSize.width(),
     784            outputSize.height(),
     785            &tmp
    771786        );
    772787        CHECK_ST
    773788
     
    777792                QString("Failed to create output surface."));
    778793            return false;
    779794        }
     795        outputSurfaces.push_back(tmp);
    780796    }
    781797
    782798    outRect.x0 = 0;
    783799    outRect.y0 = 0;
    784     outRect.x1 = size.width();
    785     outRect.y1 = size.height();
     800    outRect.x1 = outputSize.width();
     801    outRect.y1 = outputSize.height();
    786802    surfaceNum = 0;
    787803    return ok;
    788804}
     
    794810
    795811    VdpStatus vdp_st;
    796812    bool ok = true;
    797     int i;
     813    uint i;
    798814
    799     for (i = 0; i < NUM_OUTPUT_SURFACES; i++)
     815    for (i = 0; i < outputSurfaces.size(); i++)
    800816    {
    801817        if (outputSurfaces[i])
    802818        {
     
    805821            CHECK_ST
    806822        }
    807823    }
     824    outputSurfaces.clear();
     825    outputSize = QSize(0,0);
     826    checkOutputSurfaces = false;
    808827}
    809828
    810829void VDPAUContext::Decode(VideoFrame *frame)
     
    818837
    819838    VdpStatus vdp_st;
    820839    bool ok = true;
    821     vdpau_render_state_t *render;
     840    vdpau_render_state_t *render = (vdpau_render_state_t *)frame->buf;
    822841
    823842    if (frame->pix_fmt != pix_fmt)
    824843    {
    825         uint32_t max_references = 2;
    826 
    827844        if (frame->pix_fmt == PIX_FMT_VDPAU_H264_MAIN ||
    828845            frame->pix_fmt == PIX_FMT_VDPAU_H264_HIGH)
    829846        {
    830             uint32_t round_width = (frame->width + 15) & ~15;
    831             uint32_t round_height = (frame->height + 15) & ~15;
    832             uint32_t surf_size = (round_width * round_height * 3) / 2;
    833             max_references = (12 * 1024 * 1024) / surf_size;
    834             if (max_references > 16)
    835                 max_references = 16;
     847            if (render)
     848                maxReferences = render->info.h264.num_ref_frames;
     849
     850            if (maxReferences < 1 || maxReferences > 16)
     851            {
     852                uint32_t round_width = (frame->width + 15) & ~15;
     853                uint32_t round_height = (frame->height + 15) & ~15;
     854                uint32_t surf_size = (round_width * round_height * 3) / 2;
     855                maxReferences = (12 * 1024 * 1024) / surf_size;
     856            }
     857            if (maxReferences > 16)
     858                maxReferences = 16;
    836859        }
    837860
    838861        VdpDecoderProfile vdp_decoder_profile;
     
    858881            vdp_decoder_profile,
    859882            frame->width,
    860883            frame->height,
    861             max_references,
     884            maxReferences,
    862885            &decoder
    863886        );
    864887        CHECK_ST
     
    868891            pix_fmt = frame->pix_fmt;
    869892            VERBOSE(VB_PLAYBACK, LOC +
    870893                QString("Created VDPAU decoder (%1 ref frames)")
    871                 .arg(max_references));
     894                .arg(maxReferences));
    872895        }
    873896        else
    874897        {
     
    877900        }
    878901    }
    879902
    880     render = (vdpau_render_state_t *)frame->buf;
    881903    if (!render || !decoder)
    882904        return;
    883905
     
    891913    CHECK_ST
    892914}
    893915
    894 void VDPAUContext::PrepareVideo(VideoFrame *frame, QRect video_rect,
     916int VDPAUContext::PrepareVideo(VideoFrame *frame, QRect video_rect,
    895917                                QRect display_video_rect,
    896                                 QSize screen_size, FrameScanType scan,
    897                                 bool pause_frame)
     918                                FrameScanType scan, bool pause_frame)
    898919{
     920    int ret = (maxReferences + (deinterlacing ? 5 : 3)) - GetNumBufs();
     921    if (ret < 0 || !vdpauDecode || (checkVideoSurfaces != 1))
     922        ret = 0;
     923    // once we've tried to add video surfaces, try to increase
     924    // the number of output surfaces
     925    if (checkVideoSurfaces == 1)
     926        checkOutputSurfaces = true;
     927
     928    if (checkVideoSurfaces > 0)
     929        checkVideoSurfaces--;
     930
    899931    VdpStatus vdp_st;
    900932    bool ok = true;
    901933    VdpTime dummy;
     
    914946    {
    915947        render = (vdpau_render_state_t *)frame->buf;
    916948        if (!render)
    917             return;
     949            return ret;
    918950
    919951        videoSurface = render->surface;
    920952    }
     
    924956        if (deint)
    925957            surf = (currentFrameNum + 1) % NUM_REFERENCE_FRAMES;
    926958
    927         videoSurface = videoSurfaces[surf];
     959        videoSurface = videoSurfaces[surf].surface;
    928960
    929961        uint32_t pitches[3] = {
    930962            frame->pitches[0],
     
    943975            pitches);
    944976        CHECK_ST;
    945977        if (!ok)
    946             return;
     978            return ret;
    947979    }
    948980    else if (!frame)
    949981    {
    950982        deint = false;
    951983        if (!videoSurface)
    952             videoSurface = videoSurfaces[0];
     984            videoSurface = videoSurfaces[0].surface;
    953985    }
    954986
    955     if (outRect.x1 != (uint)screen_size.width() ||
    956         outRect.y1 != (uint)screen_size.height())
    957     {
    958         FreeOutput();
    959         InitOutput(screen_size);
    960     }
    961 
    962987    // fix broken/missing negative rect clipping in vdpau
    963988    if (display_video_rect.top() < 0 && display_video_rect.height() > 0)
    964989    {
     
    9801005        display_video_rect.setLeft(0);
    9811006    }
    9821007
    983     outRect.x0 = 0;
    984     outRect.y0 = 0;
    985     outRect.x1 = screen_size.width();
    986     outRect.y1 = screen_size.height();
    987 
    9881008    VdpRect srcRect;
    9891009    srcRect.x0 = video_rect.left();
    9901010    srcRect.y0 = video_rect.top();
     
    10321052                int ref = (currentFrameNum + i - 1) % NUM_REFERENCE_FRAMES;
    10331053                if (ref < 0)
    10341054                    ref = 0;
    1035                 refs[i] = videoSurfaces[ref];
     1055                refs[i] = videoSurfaces[ref].surface;
    10361056            }
    10371057        }
    10381058
     
    10991119    if (pipReady)
    11001120        pipReady--;
    11011121    pipNeedsClear = true;
     1122
     1123    return ret;
    11021124}
    11031125
    11041126void VDPAUContext::DisplayNextFrame(void)
     
    11331155    );
    11341156    CHECK_ST
    11351157
    1136     surfaceNum = surfaceNum ^ 1;
     1158    surfaceNum++;
     1159    if (surfaceNum >= (int)(outputSurfaces.size()))
     1160        surfaceNum = 0;
     1161
     1162    if (checkOutputSurfaces)
     1163        AddOutputSurfaces();
    11371164}
    11381165
     1166void VDPAUContext::AddOutputSurfaces(void)
     1167{
     1168    checkOutputSurfaces = false;
     1169    VdpStatus vdp_st;
     1170    bool ok = true;
     1171
     1172    int cnt = 0;
     1173    int extra = MAX_OUTPUT_SURFACES - outputSurfaces.size();
     1174    if (extra <= 0)
     1175        return;
     1176
     1177    for (int i = 0; i < extra; i++)
     1178    {
     1179        VdpOutputSurface tmp;
     1180        vdp_st = vdp_output_surface_create(
     1181            vdp_device,
     1182            VDP_RGBA_FORMAT_B8G8R8A8,
     1183            outputSize.width(),
     1184            outputSize.height(),
     1185            &tmp
     1186        );
     1187        // suppress non-fatal error messages
     1188        ok &= (vdp_st == VDP_STATUS_OK);
     1189
     1190        if (!ok)
     1191            break;
     1192
     1193        outputSurfaces.push_back(tmp);
     1194        cnt++;
     1195    }
     1196    VERBOSE(VB_PLAYBACK, LOC + QString("Using %1 output surfaces (max %2)")
     1197        .arg(outputSurfaces.size()).arg(MAX_OUTPUT_SURFACES));
     1198}
     1199
    11391200void VDPAUContext::SetNextFrameDisplayTimeOffset(int delayus)
    11401201{
    11411202    nextframedelay = delayus;
    11421203}
    11431204
    1144 bool VDPAUContext::InitOSD(QSize osd_size)
     1205bool VDPAUContext::InitOSD(void)
    11451206{
    11461207    if (!vdp_device)
    11471208        return false;
     
    11491210    VdpStatus vdp_st;
    11501211    bool ok = true;
    11511212
    1152     uint width = osd_size.width();
    1153     uint height = osd_size.height();
     1213    uint width = outputSize.width();
     1214    uint height = outputSize.height();
    11541215    VdpBool supported = false;
    11551216
    11561217    vdp_st = vdp_video_surface_query_get_put_bits_y_cb_cr_capabilities(
     
    12821343    }
    12831344    else
    12841345    {
    1285         osdSize = osd_size;
    12861346        osdRect.x0 = 0;
    12871347        osdRect.y0 = 0;
    12881348        osdRect.x1 = width;
     
    12961356        return ok;
    12971357    }
    12981358
    1299     osdSize = QSize(0,0);
    13001359    return ok;
    13011360}
    13021361
    13031362void VDPAUContext::UpdateOSD(void* const planes[3],
    1304                              QSize size,
    13051363                             void* const alpha[1])
    13061364{
    1307     if (size != osdSize)
    1308         return;
    1309 
    13101365    VdpStatus vdp_st;
    13111366    bool ok = true;
    13121367
    13131368    // upload OSD YV12 data
    1314     uint32_t pitches[3] = {size.width(), size.width()>>1, size.width()>>1};
     1369    uint32_t pitches[3] = {outputSize.width(),
     1370                           outputSize.width()>>1,
     1371                           outputSize.width()>>1};
    13151372    void * const realplanes[3] = { planes[0], planes[2], planes[1] };
    13161373
    13171374    vdp_st = vdp_video_surface_put_bits_y_cb_cr(osdVideoSurface,
     
    13461403    // upload OSD alpha data
    13471404    if (ok)
    13481405    {
    1349         uint32_t pitch[1] = {size.width()};
     1406        uint32_t pitch[1] = {outputSize.width()};
    13501407        vdp_st = vdp_bitmap_surface_put_bits_native(
    13511408            osdAlpha,
    13521409            alpha,
     
    17651822        VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME,
    17661823        0,
    17671824        NULL,
    1768         videoSurfaces[0],
     1825        videoSurfaces[0].surface,
    17691826        0,
    17701827        NULL,
    17711828        &srcRect,
     
    18111868        pipClear = 0;
    18121869    }
    18131870
    1814     pipLayerSize = QSize(0, 0);
    18151871    pipReady     = 0;
    18161872}
    18171873
    1818 bool VDPAUContext::InitPIPLayer(QSize screen_size)
     1874bool VDPAUContext::InitPIPLayer(void)
    18191875{
    1820     if (pipLayerSize != screen_size)
    1821         DeinitPIPLayer();
    1822 
    18231876    bool ok = true;
    18241877    VdpStatus vdp_st;
    18251878
     
    18281881        vdp_st = vdp_output_surface_create(
    18291882            vdp_device,
    18301883            VDP_RGBA_FORMAT_B8G8R8A8,
    1831             screen_size.width(),
    1832             screen_size.height(),
     1884            outputSize.width(),
     1885            outputSize.height(),
    18331886            &pipOutputSurface
    18341887        );
    18351888        CHECK_ST
     
    19221975
    19231976    if (ok && pipNeedsClear)
    19241977    {
    1925         pipLayerSize = screen_size;
    19261978        vdp_st = vdp_output_surface_render_bitmap_surface(
    19271979            pipOutputSurface,
    19281980            NULL,
  • libs/libmythtv/util-vdpau.h

     
    1313    VdpVideoSurface videoSurface;
    1414    VdpVideoMixer   videoMixer;
    1515};
     16
     17struct video_surface
     18{
     19    VdpVideoSurface      surface;
     20    vdpau_render_state_t render;
     21};
     22
    1623class NuppelVideoPlayer;
    1724
    1825class VDPAUContext
     
    2734    void Deinit(void);
    2835    bool IsErrored(void) { return errored; }
    2936
     37    int  AddBuffer(int width, int height);
    3038    bool InitBuffers(int width, int height, int numbufs);
    3139    void FreeBuffers(void);
    32     void *GetRenderData(int i) 
    33     { if (i < numSurfaces && i >= 0) return (void*)&(surface_render[i]);
     40    void *GetRenderData(int i)
     41    { if (i < GetNumBufs() && i >= 0) return (void*)&(videoSurfaces[i].render);
    3442      return NULL;
    3543    }
    36     int GetNumBufs(void) { return numSurfaces; }
     44    int GetNumBufs(void) { return videoSurfaces.size(); }
    3745
    38     bool InitOutput(QSize size);
     46    bool InitOutput(void);
    3947    void FreeOutput(void);
    4048
    4149    void Decode(VideoFrame *frame);
    4250
    43     void PrepareVideo(VideoFrame *frame, QRect video_rect,
     51    int PrepareVideo(VideoFrame *frame, QRect video_rect,
    4452                      QRect display_video_rect,
    45                       QSize screen_size, FrameScanType scan,
    46                       bool pause_frame);
     53                      FrameScanType scan, bool pause_frame);
    4754    void DisplayNextFrame(void);
    4855    void SetNextFrameDisplayTimeOffset(int delayus);
    49     bool InitOSD(QSize osd_size);
    50     void UpdateOSD(void* const planes[3], QSize size,
    51                    void* const alpha[1]);
     56    bool InitOSD(void);
     57    void UpdateOSD(void* const planes[3], void* const alpha[1]);
    5258    void DisableOSD(void) { osdReady = false; }
    5359    void DeinitOSD(void);
    5460
     
    6369    PictureAttributeSupported  GetSupportedPictureAttributes(void) const;
    6470    int SetPictureAttribute(PictureAttribute attributeType, int newValue);
    6571
    66     bool InitPIPLayer(QSize screen_size);
     72    bool InitPIPLayer(void);
    6773    bool ShowPIP(NuppelVideoPlayer *pipplayer,
    6874                 VideoFrame * frame, QRect position,
    6975                 bool pip_is_active);
     
    7682
    7783    bool InitFlipQueue(Window win);
    7884    void DeinitFlipQueue(void);
    79 
     85    void AddOutputSurfaces(void);
    8086    bool UpdateReferenceFrames(VideoFrame *frame);
    8187    bool InitColorControl(void);
    8288    bool SetPictureAttributes(void);
    83 
    8489   
    8590    void DeinitPIPLayer(void);
    8691    bool InitPIP(NuppelVideoPlayer *pipplayer, QSize vid_size);
     
    9297
    9398    uint maxVideoWidth;
    9499    uint maxVideoHeight;
    95     VdpVideoSurface *videoSurfaces;
    96     vdpau_render_state_t *surface_render;
    97     int numSurfaces;
     100    vector<video_surface> videoSurfaces;
     101    uint32_t maxReferences;
     102    int checkVideoSurfaces;
    98103
    99     VdpOutputSurface outputSurfaces[2];
     104    QSize outputSize;
     105    vector<VdpOutputSurface> outputSurfaces;
    100106    VdpVideoSurface videoSurface;
    101107    VdpOutputSurface outputSurface;
     108    bool checkOutputSurfaces;
    102109
    103110    VdpDecoder decoder;
    104111    VdpVideoMixer videoMixer;
     
    135142    VdpBitmapSurface  pipClear;
    136143    QMap<NuppelVideoPlayer*,vdpauPIP> pips;
    137144    int  pipReady;
    138     QSize             pipLayerSize;
    139145    bool              pipNeedsClear;
    140146
    141147    VdpPresentationQueueTarget vdp_flip_target;
  • libs/libmythtv/videoout_xv.cpp

     
    8484#define XVMC_CHROMA_FORMAT_420 0x00000001
    8585#endif
    8686
    87 #define NUM_VDPAU_BUFFERS 17
     87#define NUM_VDPAU_BUFFERS 6
    8888
    8989static QStringList allowed_video_renderers(
    9090    MythCodecID codec_id, Display *display, Screen *screen, Window curwin);
     
    16721672    if (osd_renderer == "vdpau" && vdpau)
    16731673    {
    16741674        vdpau_use_osd = true;
    1675         if (!vdpau->InitOSD(GetTotalOSDBounds().size()))
     1675        if (!vdpau->InitOSD())
    16761676        {
    16771677            vdpau_use_osd = false;
    16781678            VERBOSE(VB_IMPORTANT, LOC + "Init VDPAU osd failed.");
     
    31283128    if (!vdpau)
    31293129        return;
    31303130
    3131     vdpau->PrepareVideo(
     3131    int extra_bufs = vdpau->PrepareVideo(
    31323132        frame, windows[0].GetVideoRect(), windows[0].GetDisplayVideoRect(),
    3133         windows[0].GetDisplayVisibleRect().size(), scan, pause);
     3133        scan, pause);
    31343134
     3135    if (extra_bufs)
     3136    {
     3137        vbuffers.begin_lock(kVideoBuffer_avail);
     3138        QSize vid_dim = windows[0].GetVideoDim();
     3139        vbuffers.Add(vid_dim.width(), vid_dim.height(), vdpau, extra_bufs);
     3140        vbuffers.end_lock();
     3141    }
     3142
    31353143#endif
    31363144
    31373145    if (pause)
     
    37043712#ifdef USING_VDPAU
    37053713    if (vdpau && vdpau_use_pip && VideoOutputSubType() == XVideoVDPAU)
    37063714    {
    3707         if (vdpau->InitPIPLayer(dvr.size()))
     3715        if (vdpau->InitPIPLayer())
    37083716            vdpau_use_pip = vdpau->ShowPIP(pipplayer, pipimage,
    37093717                                           position, pipActive);
    37103718        pipplayer->ReleaseCurrentFrame(pipimage);
     
    49544962            offsets[1] = surface->u;
    49554963            offsets[2] = surface->v;
    49564964            alpha[0] = surface->alpha;
    4957             vdpau->UpdateOSD(offsets, visible, alpha);
     4965            vdpau->UpdateOSD(offsets, alpha);
    49584966#endif // USING_VDPAU
    49594967        }
    49604968        else if (gl_use_osd_opengl2)
  • libs/libmythtv/videobuffers.h

     
    165165
    166166#ifdef USING_VDPAU
    167167    bool CreateBuffers(int width, int height, VDPAUContext *ctx);
     168    void Add(int width, int height, VDPAUContext *ctx, int num);
    168169#endif
    169170
    170171    QString GetStatus(int n=-1) const; // debugging method
  • libs/libmythtv/videobuffers.cpp

     
    11641164}
    11651165
    11661166#ifdef USING_VDPAU
     1167static unsigned char *ffmpeg_vdpau_hack = (unsigned char*)
     1168    "avlib should not use this private data in VDPAU mode.";
     1169
    11671170bool VideoBuffers::CreateBuffers(int width, int height, VDPAUContext *ctx)
    11681171{
    1169     static unsigned char *ffmpeg_vdpau_hack = (unsigned char*)
    1170         "avlib should not use this private data in VDPAU mode.";
    1171 
    11721172    if (!ctx)
    11731173        return false;
    11741174
     
    11911191    }
    11921192    return true;
    11931193}
     1194
     1195void VideoBuffers::Add(int width, int height, VDPAUContext *ctx, int num)
     1196{
     1197    if (!ctx)
     1198        return;
     1199
     1200    int cnt = 0;
     1201    QMutexLocker locker(&global_lock);
     1202
     1203    for (int i =0; i < num; i++)
     1204    {
     1205        int new_surf = ctx->AddBuffer(width, height);
     1206        if (new_surf > 0)
     1207        {
     1208            int ref = allocSize();
     1209            if (ref != new_surf)
     1210            {
     1211                VERBOSE(VB_PLAYBACK, QString("VideoBuffers::Add - ") +
     1212                    QString("mis-match between VideoBuffers and VDPAU."));
     1213                continue;
     1214            }
     1215            VideoFrame tmp;
     1216            memset(&tmp, 0, sizeof(VideoFrame));
     1217            buffers.push_back(tmp);
     1218            init(&buffers[ref], FMT_VDPAU, (unsigned char*)ctx->GetRenderData(new_surf), width, height, -1, 0);
     1219            vbufferMap[at(ref)] = ref;
     1220            numbuffers = allocSize();
     1221            buffers[ref].priv[0]      = ffmpeg_vdpau_hack;
     1222            buffers[ref].priv[1]      = ffmpeg_vdpau_hack;
     1223            enqueue(kVideoBuffer_avail, at(ref));
     1224            cnt++;
     1225        }
     1226        else
     1227        {
     1228            continue;
     1229        }
     1230    }
     1231    VERBOSE(VB_PLAYBACK,
     1232        QString("Added %1 VDPAU video buffer(s) (%2 requested).")
     1233            .arg(cnt).arg(num));
     1234    return;
     1235}
    11941236#endif
    11951237
    11961238#ifdef USING_XVMC