Ticket #6130: video_surfaces.diff

File video_surfaces.diff, 12.2 KB (added by markk, 12 years ago)

Updated patch for remaining decoder/video surfaces optimisation.

  • libs/libmythtv/util-vdpau.cpp

     
    6060VDPAUContext::VDPAUContext()
    6161  : nextframedelay(0),      lastframetime(0),
    6262    pix_fmt(-1),            maxVideoWidth(0),  maxVideoHeight(0),
    63     videoSurfaces(0),       surface_render(0), checkVideoSurfaces(8),
    64     numSurfaces(0),
    65     videoSurface(0),        outputSurface(0),  checkOutputSurfaces(false),
     63    checkVideoSurfaces(8),
     64    outputSurface(0),       checkOutputSurfaces(false),
    6665    outputSize(QSize(0,0)), decoder(0),        maxReferences(2),
    6766    videoMixer(0),          surfaceNum(0),     osdVideoSurface(0),
    6867    osdOutputSurface(0),    osdVideoMixer(0),  osdAlpha(0),
     
    526525    }
    527526}
    528527
     528int VDPAUContext::AddBuffer(int width, int height)
     529{
     530    VdpStatus vdp_st;
     531    bool ok = true;
     532
     533    video_surface tmp;
     534    tmp.surface = 0;
     535
     536    vdp_st = vdp_video_surface_create(
     537        vdp_device,
     538        vdp_chroma_type,
     539        width,
     540        height,
     541        &(tmp.surface)
     542    );
     543    CHECK_ST
     544
     545    if (!ok || !tmp.surface)
     546    {
     547        VERBOSE(VB_PLAYBACK, LOC_ERR +
     548            QString("Failed to create video surface."));
     549        return -1;
     550    }
     551
     552    if (vdpauDecode)
     553    {
     554        vdpau_render_state_t new_rend;
     555        memset(&new_rend, 0, sizeof(vdpau_render_state_t));
     556        new_rend.magic = MP_VDPAU_RENDER_MAGIC;
     557        new_rend.state = 0;
     558        new_rend.surface = tmp.surface;
     559        tmp.render = new_rend;
     560    }
     561
     562    videoSurfaces.push_back(tmp);
     563    return GetNumBufs() - 1;
     564}
     565
    529566bool VDPAUContext::InitBuffers(int width, int height, int numbufs)
    530567{
    531568    int num_bufs = numbufs;
     
    566603        return false;
    567604    }
    568605
    569     videoSurfaces = (VdpVideoSurface *)malloc(sizeof(VdpVideoSurface) * num_bufs);
    570     if (vdpauDecode)
    571     {
    572         surface_render = (vdpau_render_state_t*)malloc(sizeof(vdpau_render_state_t) * num_bufs);
    573         memset(surface_render, 0, sizeof(vdpau_render_state_t) * num_bufs);
    574     }
    575 
    576     numSurfaces = num_bufs;
    577 
    578606    for (i = 0; i < num_bufs; i++)
    579607    {
    580         vdp_st = vdp_video_surface_create(
    581             vdp_device,
    582             vdp_chroma_type,
    583             width,
    584             height,
    585             &(videoSurfaces[i])
    586         );
    587         CHECK_ST
    588 
    589         if (!ok)
     608        int tmp = AddBuffer(width, height);
     609        if (tmp != i)
    590610        {
    591             VERBOSE(VB_PLAYBACK, LOC_ERR +
    592                 QString("Failed to create video surface."));
     611            VERBOSE(VB_IMPORTANT, LOC +
     612                QString("Failed to add buffer %1 of %2")
     613                .arg(i+1).arg(num_bufs));
    593614            return false;
    594615        }
    595 
    596         if (vdpauDecode)
    597         {
    598             surface_render[i].magic = MP_VDPAU_RENDER_MAGIC;
    599             surface_render[i].state = 0;
    600             surface_render[i].surface = videoSurfaces[i];
    601         }
    602616    }
    603617
    604618    // clear video surfaces to black
     
    622636            for (i = 0; i < num_bufs; i++)
    623637            {
    624638                vdp_video_surface_put_bits_y_cb_cr(
    625                     videoSurfaces[i],
     639                    videoSurfaces[i].surface,
    626640                    VDP_YCBCR_FORMAT_YV12,
    627641                    planes,
    628642                    pitches
     
    712726        CHECK_ST
    713727    }
    714728
    715     if (videoSurfaces)
     729    if (videoSurfaces.size())
    716730    {
    717         for (i = 0; i < numSurfaces; i++)
     731        for (i = 0; i < GetNumBufs(); i++)
    718732        {
    719             if (videoSurfaces[i])
     733            if (videoSurfaces[i].surface)
    720734            {
    721735                vdp_st = vdp_video_surface_destroy(
    722                     videoSurfaces[i]);
     736                    videoSurfaces[i].surface);
    723737                CHECK_ST
    724738            }
    725739        }
    726         free(videoSurfaces);
    727         videoSurfaces = NULL;
     740        videoSurfaces.clear();
    728741    }
    729 
    730     if (surface_render)
    731         free(surface_render);
    732     surface_render = NULL;
     742    checkVideoSurfaces = 8;
    733743}
    734744
    735745bool VDPAUContext::InitOutput(QSize size)
     
    904914    CHECK_ST
    905915}
    906916
    907 void VDPAUContext::PrepareVideo(VideoFrame *frame, QRect video_rect,
     917int VDPAUContext::PrepareVideo(VideoFrame *frame, QRect video_rect,
    908918                                QRect display_video_rect,
    909919                                QSize screen_size, FrameScanType scan,
    910920                                bool pause_frame)
    911921{
     922    int ret = (maxReferences + (deinterlacing ? 5 : 3)) - GetNumBufs();
     923    if (ret < 0 || !vdpauDecode || (checkVideoSurfaces != 1))
     924        ret = 0;
     925
    912926    if (checkVideoSurfaces == 1)
    913927        checkOutputSurfaces = true;
    914928
     
    919933    bool ok = true;
    920934    VdpTime dummy;
    921935    vdpau_render_state_t *render;
     936    VdpVideoSurface video_surface = 0;
    922937
    923938    bool new_frame = true;
    924939    bool deint = (deinterlacing && needDeintRefs && !pause_frame);
     
    933948    {
    934949        render = (vdpau_render_state_t *)frame->buf;
    935950        if (!render)
    936             return;
     951            return ret;
    937952
    938         videoSurface = render->surface;
     953        video_surface = render->surface;
    939954    }
    940955    else if (new_frame && frame)
    941956    {
     
    943958        if (deint)
    944959            surf = (currentFrameNum + 1) % NUM_REFERENCE_FRAMES;
    945960
    946         videoSurface = videoSurfaces[surf];
     961        video_surface = videoSurfaces[surf].surface;
    947962
    948963        uint32_t pitches[3] = {
    949964            frame->pitches[0],
     
    956971            frame->buf + frame->offsets[1]
    957972        };
    958973        vdp_st = vdp_video_surface_put_bits_y_cb_cr(
    959             videoSurface,
     974            video_surface,
    960975            VDP_YCBCR_FORMAT_YV12,
    961976            planes,
    962977            pitches);
    963978        CHECK_ST;
    964979        if (!ok)
    965             return;
     980            return ret;
    966981    }
    967982    else if (!frame)
    968983    {
    969984        deint = false;
    970         if (!videoSurface)
    971             videoSurface = videoSurfaces[0];
     985        if (!video_surface)
     986            video_surface = videoSurfaces[0].surface;
    972987    }
    973988
    974989    if (outRect.x1 != (uint)screen_size.width() ||
     
    10521067                int ref = (currentFrameNum + i - 1) % NUM_REFERENCE_FRAMES;
    10531068                if (ref < 0)
    10541069                    ref = 0;
    1055                 refs[i] = videoSurfaces[ref];
     1070                refs[i] = videoSurfaces[ref].surface;
    10561071            }
    10571072        }
    10581073
    1059         videoSurface = refs[1];
     1074        video_surface = refs[1];
    10601075 
    10611076        if (scan == kScan_Interlaced)
    10621077        {
     
    11041119        field,
    11051120        deint ? ARSIZE(past_surfaces) : 0,
    11061121        deint ? past_surfaces : NULL,
    1107         videoSurface,
     1122        video_surface,
    11081123        deint ? ARSIZE(future_surfaces) : 0,
    11091124        deint ? future_surfaces : NULL,
    11101125        &srcRect,
     
    11191134    if (pipReady)
    11201135        pipReady--;
    11211136    pipNeedsClear = true;
     1137
     1138    return ret;
    11221139}
    11231140
    11241141void VDPAUContext::DisplayNextFrame(void)
     
    18301847        VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME,
    18311848        0,
    18321849        NULL,
    1833         videoSurfaces[0],
     1850        videoSurfaces[0].surface,
    18341851        0,
    18351852        NULL,
    18361853        &srcRect,
  • 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
     
    2835    bool IsErrored(void) { return errored; }
    2936
    3037    bool InitBuffers(int width, int height, int numbufs);
     38    int  AddBuffer(int width, int height);
    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
    3846    bool InitOutput(QSize size);
    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,
    4553                      QSize screen_size, FrameScanType scan,
    4654                      bool pause_frame);
     
    93101
    94102    uint maxVideoWidth;
    95103    uint maxVideoHeight;
    96     VdpVideoSurface *videoSurfaces;
    97     vdpau_render_state_t *surface_render;
     104    vector<video_surface> videoSurfaces;
    98105    int checkVideoSurfaces;
    99     int numSurfaces;
    100106
    101107    vector<VdpOutputSurface> outputSurfaces;
    102     VdpVideoSurface  videoSurface;
    103108    VdpOutputSurface outputSurface;
    104109    bool             checkOutputSurfaces;
    105110    QSize            outputSize;
  • 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, int screen, Window curwin);
     
    31273127    if (!vdpau)
    31283128        return;
    31293129
    3130     vdpau->PrepareVideo(
     3130    int extra_bufs = vdpau->PrepareVideo(
    31313131        frame, windows[0].GetVideoRect(), windows[0].GetDisplayVideoRect(),
    31323132        windows[0].GetDisplayVisibleRect().size(), scan, pause);
    31333133
     3134    if (extra_bufs)
     3135    {
     3136        vbuffers.begin_lock(kVideoBuffer_avail);
     3137        QSize vid_dim = windows[0].GetVideoDim();
     3138        vbuffers.Add(vid_dim.width(), vid_dim.height(), vdpau, extra_bufs);
     3139        vbuffers.end_lock();
     3140    }
     3141
    31343142#endif
    31353143
    31363144    if (pause)
  • 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