Ticket #8593: vaapi_v3.diff

File vaapi_v3.diff, 54.1 KB (added by markk, 10 years ago)
  • configure

     
    128128  --enable-xvmc-vld        enable XvMC VLD accel. for the Unichrome (Pro) chipset
    129129  --xvmc-lib=LIB           XvMC library override (for crosscompiling)
    130130  --enable-vdpau           enable NVidia VDPAU hardware acceleration.
     131  --enable-vaapi           enable VAAPI hardware acceleration
    131132  --disable-opengl-video   disable OpenGL based video display
    132133  --enable-mac-accel       enable Mac OS X MPEG acceleration
    133134  --disable-opengl-vsync   disable OpenGL vsync method
     
    13361337    dvdv
    13371338    opengl
    13381339    vdpau
     1340    vaapi
    13391341'
    13401342
    13411343CMDLINE_SELECT="
     
    16781680xvmc_deps="xv X11_extensions_XvMClib_h"
    16791681xvmc_vld_deps="xvmc X11_extensions_vldXvMC_h"
    16801682xvmcw_deps="xvmc"
     1683vaapi_deps="opengl_video"
    16811684
    16821685# default parameters
    16831686pre_logfile="config.ep"
     
    33943397check_header termios.h
    33953398check_header vdpau/vdpau.h
    33963399check_header vdpau/vdpau_x11.h
     3400check_header va/va.h
     3401check_header va/va_x11.h
    33973402check_header X11/extensions/XvMClib.h
    33983403
    33993404check_struct dxva2api.h DXVA_PictureParameters wDecodedPictureIndex
     
    36623667      disable vdpau; }
    36633668fi
    36643669
     3670if ! disabled vaapi && enabled va_va_h; then
     3671    enable vaapi
     3672fi
     3673
    36653674enabled debug && add_cflags -g"$debuglevel" && add_asflags -g"$debuglevel"
    36663675enabled debug && add_cxxflags -g"$debuglevel"
    36673676
     
    42194228  echo "XvMC libs                 $VENDOR_XVMC_LIBS"
    42204229fi
    42214230  echo "VDPAU support             ${vdpau-no}"
     4231  echo "VAAPI support             ${vaapi-no}"
    42224232fi
    42234233  echo "OpenGL video              ${opengl_video-no}"
    42244234  if test x"$target_os" = x"darwin" ; then
  • libs/libmythtv/videoout_openglvaapi.h

     
     1#ifndef VIDEOOUTPUTOPENGLVAAPI_H
     2#define VIDEOOUTPUTOPENGLVAAPI_H
     3
     4#include "videoout_opengl.h"
     5#include "vaapicontext.h"
     6
     7class VideoOutputOpenGLVAAPI : public VideoOutputOpenGL
     8{
     9  public:
     10    static void GetRenderOptions(render_opts &opts);
     11
     12    VideoOutputOpenGLVAAPI(MythCodecID codec_id);
     13   ~VideoOutputOpenGLVAAPI();
     14
     15    bool  Init(int width, int height, float aspect, WId winid,
     16               int winx, int winy, int winw, int winh, WId embedid = 0);
     17    bool  InitVAAPIContext(QSize size);
     18    bool  CreateBuffers(void);
     19    void* GetVAAPIContext(void);
     20    void  SetProfile(void);
     21    virtual void TearDown(void);
     22    virtual bool InputChanged(const QSize &input_size, float aspect,
     23                              MythCodecID  av_codec_id, void *codec_private,
     24                              bool &aspect_only);
     25    uint8_t* GetSurfaceIDPointer(void* buf);
     26    void ProcessFrame(VideoFrame *frame, OSD *osd,
     27                              FilterChain *filterList,
     28                              const PIPMap &pipPlayers,
     29                              FrameScanType scan);
     30    virtual bool ApproveDeintFilter(const QString& filtername) const;
     31    static QStringList GetAllowedRenderers(MythCodecID myth_codec_id,
     32                                           const QSize &video_dim);
     33    static MythCodecID GetBestSupportedCodec(uint width, uint height,
     34                                             uint stream_type,
     35                                             bool no_acceleration,
     36                                             PixelFormat &pix_fmt);
     37
     38  private:
     39    VAAPIContext *m_ctx;
     40};
     41
     42#endif // VIDEOOUTPUTOPENGLVAAPI_H
     43
  • libs/libmythtv/videoout_opengl.cpp

     
    88#include "NuppelVideoPlayer.h"
    99#include "mythuihelper.h"
    1010
    11 #define LOC      QString("VidOutOGL: ")
    12 #define LOC_ERR  QString("VidOutOGL: ")
     11#define LOC      QString("VidOutGL: ")
     12#define LOC_ERR  QString("VidOutGL Error: ")
    1313
    1414void VideoOutputOpenGL::GetRenderOptions(render_opts &opts,
    1515                                         QStringList &cpudeints)
     
    3737    opts.priorities->insert("opengl", 65);
    3838}
    3939
    40 VideoOutputOpenGL::VideoOutputOpenGL(void)
     40VideoOutputOpenGL::VideoOutputOpenGL(MythCodecID codec_id)
    4141    : VideoOutput(),
    42     gl_context_lock(QMutex::Recursive),
     42    gl_codec_id(codec_id), gl_context_lock(QMutex::Recursive),
    4343    gl_context(NULL), gl_videochain(NULL), gl_pipchain_active(NULL),
    4444    gl_parent_win(0), gl_embed_win(0), gl_painter(NULL)
    4545{
     
    123123                      winid, winx, winy, winw, winh,
    124124                      embedid);
    125125
    126     if (db_vdisp_profile)
    127         db_vdisp_profile->SetVideoRenderer("opengl");
     126    SetProfile();
    128127
    129128    success &= SetupContext();
    130129    InitDisplayMeasurements(width, height, false);
    131130    success &= CreateBuffers();
     131    success &= CreatePauseFrame();
    132132    success &= SetupOpenGL();
    133133
    134134    InitOSD();
     
    144144    return success;
    145145}
    146146
     147void VideoOutputOpenGL::SetProfile(void)
     148{
     149    if (db_vdisp_profile)
     150        db_vdisp_profile->SetVideoRenderer("opengl");
     151}
     152
    147153bool VideoOutputOpenGL::InputChanged(const QSize &input_size,
    148154                                     float        aspect,
    149155                                     MythCodecID  av_codec_id,
    150156                                     void        *codec_private,
    151157                                     bool        &aspect_only)
    152158{
    153     VERBOSE(VB_PLAYBACK, LOC + QString("InputChanged(%1,%2,%3) %4")
     159    VERBOSE(VB_PLAYBACK, LOC + QString("InputChanged(%1,%2,%3) %4->%5")
    154160            .arg(input_size.width()).arg(input_size.height()).arg(aspect)
    155             .arg(toString(av_codec_id)));
     161            .arg(toString(gl_codec_id)).arg(toString(av_codec_id)));
    156162
    157163    QMutexLocker locker(&gl_context_lock);
    158 
    159     if (!codec_is_std(av_codec_id))
     164    gl_codec_id = av_codec_id;
     165    if (!codec_is_std(gl_codec_id))
    160166    {
    161167        VERBOSE(VB_IMPORTANT, LOC_ERR +
    162168            QString("New video codec is not supported."));
     
    242248                                  windows[0].GetVideoDim(), dvr,
    243249                                  windows[0].GetDisplayVideoRect(),
    244250                                  windows[0].GetVideoRect(), true,
    245                                   GetFilters(), db_letterbox_colour);
     251                                  GetFilters(), !codec_is_std(gl_codec_id),
     252                                  db_letterbox_colour);
    246253    if (success)
    247254    {
    248255        bool temp_deinterlacing = m_deinterlacing;
     
    276283bool VideoOutputOpenGL::CreateBuffers(void)
    277284{
    278285    QMutexLocker locker(&gl_context_lock);
    279 
    280     bool success = true;
    281286    vbuffers.Init(31, true, 1, 12, 4, 2, false);
    282     success &= vbuffers.CreateBuffers(windows[0].GetVideoDim().width(),
    283                                       windows[0].GetVideoDim().height());
     287    return vbuffers.CreateBuffers(windows[0].GetVideoDim().width(),
     288                                  windows[0].GetVideoDim().height());
     289}
    284290
     291bool VideoOutputOpenGL::CreatePauseFrame(void)
     292{
    285293    av_pause_frame.height = vbuffers.GetScratchFrame()->height;
    286294    av_pause_frame.width  = vbuffers.GetScratchFrame()->width;
    287295    av_pause_frame.bpp    = vbuffers.GetScratchFrame()->bpp;
     
    290298    av_pause_frame.frameNumber = vbuffers.GetScratchFrame()->frameNumber;
    291299
    292300    if (!av_pause_frame.buf)
    293     {
    294         success = false;
    295     }
    296     else
    297     {
    298         int size = av_pause_frame.width * av_pause_frame.height;
    299         memset(av_pause_frame.buf, 0,   size);
    300         memset(av_pause_frame.buf + size, 127, size / 2);
    301     }
     301        return false;
    302302
    303     return success;
     303    int size = av_pause_frame.width * av_pause_frame.height;
     304    memset(av_pause_frame.buf, 0,   size);
     305    memset(av_pause_frame.buf + size, 127, size / 2);
     306    return true;
    304307}
    305308
    306309void VideoOutputOpenGL::ProcessFrame(VideoFrame *frame, OSD *osd,
     
    312315    if (!gl_videochain || !gl_context)
    313316        return;
    314317
     318    bool sw_frame = codec_is_std(gl_codec_id);
    315319    bool deint_proc = m_deinterlacing && (m_deintFilter != NULL);
    316320    OpenGLLocker ctx_lock(gl_context);
    317321
     
    323327        pauseframe = true;
    324328    }
    325329
    326     if (filterList)
     330    if (filterList && sw_frame)
    327331        filterList->ProcessFrame(frame);
    328332
    329333    bool safepauseframe = pauseframe && !IsBobDeint();
    330     if (deint_proc && m_deinterlaceBeforeOSD &&
     334    if (sw_frame && deint_proc && m_deinterlaceBeforeOSD &&
    331335       (!pauseframe || safepauseframe))
    332336    {
    333337        m_deintFilter->ProcessFrame(frame, scan);
     
    339343        ShowPIPs(frame, pipPlayers);
    340344    }
    341345
    342     if ((!pauseframe || safepauseframe) &&
     346    if (sw_frame && (!pauseframe || safepauseframe) &&
    343347        deint_proc && !m_deinterlaceBeforeOSD)
    344348    {
    345349        m_deintFilter->ProcessFrame(frame, scan);
     
    347351
    348352    bool soft_bob = m_deinterlacing && (m_deintfiltername == "bobdeint");
    349353
    350     if (gl_videochain)
     354    if (gl_videochain && sw_frame)
    351355        gl_videochain->UpdateInputFrame(frame, soft_bob);
    352356}
    353357
     
    371375    framesPlayed = buffer->frameNumber + 1;
    372376    gl_context_lock.unlock();
    373377
    374     if (buffer->codec != FMT_YV12)
    375         return;
     378    //if (buffer->codec != FMT_YV12)
     379    //    return;
    376380
    377381    gl_videochain->SetVideoRect(vsz_enabled ? vsz_desired_display_rect :
    378382                                              windows[0].GetDisplayVideoRect(),
     
    653657                     QSize(pipVideoWidth, pipVideoHeight),
    654658                     dvr, position,
    655659                     QRect(0, 0, pipVideoWidth, pipVideoHeight),
    656                      false, GetFilters());
     660                     false, GetFilters(), false);
    657661        gl_pipchain->SetMasterViewport(gl_videochain->GetViewPort());
    658662        if (!success)
    659663        {
     
    674678            QSize(pipVideoWidth, pipVideoHeight),
    675679            dvr, position,
    676680            QRect(0, 0, pipVideoWidth, pipVideoHeight),
    677             false, GetFilters());
     681            false, GetFilters(), false);
    678682
    679683        gl_pipchain->SetMasterViewport(gl_videochain->GetViewPort());
    680684        if (!success)
  • libs/libmythtv/avformatdecoder.cpp

     
    4949}
    5050#endif // USING_VDPAU
    5151
     52#ifdef USING_VAAPI
     53#include "videoout_openglvaapi.h"
     54#endif // USING_VAAPI
     55
    5256extern "C" {
    5357#include "avutil.h"
    5458#include "ac3_parser.h"
     
    9296void render_slice_vdpau(struct AVCodecContext *s, const AVFrame *src,
    9397                        int offset[4], int y, int type, int height);
    9498
     99int  get_avf_buffer_vaapi(struct AVCodecContext *c, AVFrame *pic);
     100
    95101static AVCodec *find_vdpau_decoder(AVCodec *c, enum CodecID id)
    96102{
    97103    AVCodec *codec = c;
     
    461467    opts.decoders->append("vdpau");
    462468    (*opts.equiv_decoders)["vdpau"].append("dummy");
    463469#endif
     470
     471#ifdef USING_VAAPI
     472    opts.decoders->append("vaapi");
     473    (*opts.equiv_decoders)["vaapi"].append("dummy");
     474#endif
    464475}
    465476
    466477AvFormatDecoder::AvFormatDecoder(NuppelVideoPlayer *parent,
     
    13681379    return fmt[i];
    13691380}
    13701381
     1382static bool IS_VAAPI_PIX_FMT(enum PixelFormat fmt)
     1383{
     1384    return fmt == PIX_FMT_VAAPI_MOCO ||
     1385           fmt == PIX_FMT_VAAPI_IDCT ||
     1386           fmt == PIX_FMT_VAAPI_VLD;
     1387}
     1388
     1389static enum PixelFormat get_format_vaapi(struct AVCodecContext *avctx,
     1390                                         const enum PixelFormat *fmt)
     1391{
     1392    if (!fmt)
     1393        return PIX_FMT_NONE;
     1394    int i = 0;
     1395    for (; fmt[i] != PIX_FMT_NONE ; i++)
     1396        if (IS_VAAPI_PIX_FMT(fmt[i]))
     1397            break;
     1398    return fmt[i];
     1399}
     1400
    13711401static bool IS_DR1_PIX_FMT(const enum PixelFormat fmt)
    13721402{
    13731403    switch (fmt)
     
    14721502        enc->draw_horiz_band = render_slice_vdpau;
    14731503        enc->slice_flags     = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD;
    14741504    }
     1505    else if (codec && IS_VAAPI_PIX_FMT(enc->pix_fmt))
     1506    {
     1507        enc->get_buffer      = get_avf_buffer_vaapi;
     1508        enc->get_format      = get_format_vaapi;
     1509        enc->release_buffer  = release_avf_buffer;
     1510        enc->slice_flags     = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD; // is this correct?
     1511    }
    14751512    else if (codec && codec->capabilities & CODEC_CAP_DR1)
    14761513    {
    14771514        enc->flags          |= CODEC_FLAG_EMU_EDGE;
     
    19541991                        handled = true;
    19551992                    }
    19561993#endif // USING_VDPAU
     1994#ifdef USING_VAAPI
     1995                    MythCodecID vaapi_mcid;
     1996                    PixelFormat pix_fmt = PIX_FMT_YUV420P;
     1997                    vaapi_mcid = VideoOutputOpenGLVAAPI::GetBestSupportedCodec(
     1998                        width, height, mpeg_version(enc->codec_id),
     1999                        no_hardware_decoders, pix_fmt);
     2000
     2001                    if (vaapi_mcid >= video_codec_id)
     2002                    {
     2003                        enc->codec_id = (CodecID)myth2av_codecid(vaapi_mcid);
     2004                        video_codec_id = vaapi_mcid;
     2005                        handled = true;
     2006                        if (!no_hardware_decoders &&
     2007                            codec_is_vaapi_hw(video_codec_id))
     2008                        {
     2009                            enc->pix_fmt = pix_fmt;
     2010                        }
     2011                    }
     2012#endif // USING_VAAPI
    19572013#ifdef USING_XVMC
    19582014
    19592015                    bool force_xv = no_hardware_decoders;
     
    26722728    }
    26732729}
    26742730
     2731int get_avf_buffer_vaapi(struct AVCodecContext *c, AVFrame *pic)
     2732{
     2733    AvFormatDecoder *nd = (AvFormatDecoder *)(c->opaque);
     2734    VideoFrame *frame = nd->GetNVP()->GetNextVideoFrame(false);
     2735
     2736    pic->data[0] = frame->buf;
     2737    pic->data[1] = frame->priv[0];
     2738    pic->data[2] = frame->priv[1];
     2739
     2740    pic->linesize[0] = 0;
     2741    pic->linesize[1] = 0;
     2742    pic->linesize[2] = 0;
     2743
     2744    pic->opaque = frame;
     2745    pic->type = FF_BUFFER_TYPE_USER;
     2746
     2747    pic->age = 256 * 256 * 256 * 64;
     2748
     2749    frame->pix_fmt = c->pix_fmt;
     2750
     2751#ifdef USING_VAAPI
     2752    if (nd->GetNVP()->getVideoOutput())
     2753    {
     2754        VideoOutputOpenGLVAAPI *vo =
     2755            dynamic_cast<VideoOutputOpenGLVAAPI*>(nd->GetNVP()->getVideoOutput());
     2756        c->hwaccel_context = (vaapi_context*)vo->GetVAAPIContext();
     2757        pic->data[3] = vo->GetSurfaceIDPointer(frame->buf);
     2758    }
     2759#endif
     2760
     2761    return 0;
     2762}
     2763
    26752764void AvFormatDecoder::DecodeDTVCC(const uint8_t *buf, uint len)
    26762765{
    26772766    if (!len)
  • libs/libmythtv/videoout_openglvaapi.cpp

     
     1#include "videoout_openglvaapi.h"
     2
     3#define LOC      QString("VidOutGLVAAPI: ")
     4#define LOC_ERR  QString("VidOutGLVAAPI Error: ")
     5
     6void VideoOutputOpenGLVAAPI::GetRenderOptions(render_opts &opts)
     7{
     8    opts.renderers->append("openglvaapi");
     9    (*opts.deints)["openglvaapi"].append("vaapionefield");
     10    (*opts.deints)["openglvaapi"].append("vaapibobdeint");
     11    (*opts.deints)["openglvaapi"].append("none");
     12    (*opts.osds)["openglvaapi"].append("opengl2");
     13
     14    if (opts.decoders->contains("vaapi"))
     15        (*opts.safe_renderers)["vaapi"].append("openglvaapi");
     16    if (opts.decoders->contains("ffmpeg"))
     17        (*opts.safe_renderers)["ffmpeg"].append("openglvaapi");
     18    if (opts.decoders->contains("libmpeg2"))
     19        (*opts.safe_renderers)["libmpeg2"].append("openglvaapi");
     20    (*opts.safe_renderers)["dummy"].append("openglvaapi");
     21    (*opts.safe_renderers)["nuppel"].append("openglvaapi");
     22
     23    opts.priorities->insert("openglvaapi", 110);
     24}
     25
     26VideoOutputOpenGLVAAPI::VideoOutputOpenGLVAAPI(MythCodecID codec_id)
     27  : VideoOutputOpenGL(codec_id), m_ctx(NULL)
     28{
     29    if (gCoreContext->GetNumSetting("UseVideoModes", 0))
     30        display_res = DisplayRes::GetDisplayRes(true);
     31}
     32
     33VideoOutputOpenGLVAAPI::~VideoOutputOpenGLVAAPI()
     34{
     35}
     36
     37void VideoOutputOpenGLVAAPI::TearDown(void)
     38{
     39    VideoOutputOpenGL::TearDown();
     40    delete m_ctx;
     41    m_ctx = NULL;
     42}
     43
     44bool VideoOutputOpenGLVAAPI::Init(int width, int height, float aspect,
     45                                  WId winid, int winx, int winy, int winw,
     46                                  int winh, WId embedid)
     47{
     48    VERBOSE(VB_PLAYBACK, LOC + "Init");
     49    if (codec_is_vaapi_hw(gl_codec_id))
     50        if (!InitVAAPIContext(QSize(width, height)))
     51            return false;
     52
     53    return VideoOutputOpenGL::Init(width, height, aspect, winid, winx, winy,
     54                                   winw, winh, embedid);
     55}
     56
     57bool VideoOutputOpenGLVAAPI::InputChanged(const QSize &input_size, float aspect,
     58                              MythCodecID  av_codec_id, void *codec_private,
     59                              bool &aspect_only)
     60{
     61    VERBOSE(VB_PLAYBACK, LOC + QString("InputChanged(%1,%2,%3) %4->%5")
     62            .arg(input_size.width()).arg(input_size.height()).arg(aspect)
     63            .arg(toString(gl_codec_id)).arg(toString(av_codec_id)));
     64
     65    if (!codec_is_vaapi_hw(av_codec_id))
     66        return VideoOutputOpenGL::InputChanged(input_size, aspect, av_codec_id,
     67                                               codec_private, aspect_only);
     68                                                   
     69    QMutexLocker locker(&gl_context_lock);
     70    bool cid_changed = (gl_codec_id != av_codec_id);
     71    bool res_changed = input_size  != windows[0].GetVideoDispDim();
     72    bool asp_changed = aspect      != windows[0].GetVideoAspect();
     73    gl_codec_id = av_codec_id;
     74   
     75    if (!res_changed && !cid_changed)
     76    {
     77        if (asp_changed)
     78        {
     79            aspect_only = true;
     80            VideoAspectRatioChanged(aspect);
     81            MoveResize();
     82        }
     83        return true;
     84    }
     85
     86    TearDown();
     87    QRect disp = windows[0].GetDisplayVisibleRect();
     88    if (Init(input_size.width(), input_size.height(),
     89             aspect, gl_parent_win, disp.left(),  disp.top(),
     90             disp.width(), disp.height(), gl_embed_win))
     91    {
     92        BestDeint();
     93        return true;
     94    }
     95
     96    VERBOSE(VB_IMPORTANT, LOC_ERR +
     97        QString("Failed to re-initialise video output."));
     98    errorState = kError_Unknown;
     99
     100    return false;
     101}
     102
     103bool VideoOutputOpenGLVAAPI::InitVAAPIContext(QSize size)
     104{
     105    if (m_ctx)
     106        delete m_ctx;
     107    m_ctx = new VAAPIContext(gl_codec_id);
     108    if (m_ctx && m_ctx->Create(size))
     109        return true;
     110    return false;
     111}
     112
     113bool VideoOutputOpenGLVAAPI::CreateBuffers(void)
     114{
     115    if (!codec_is_vaapi_hw(gl_codec_id) || !m_ctx)
     116        return VideoOutputOpenGL::CreateBuffers();
     117
     118    QMutexLocker locker(&gl_context_lock);
     119    int num_buffers = m_ctx->GetNumBuffers();
     120    const QSize video_dim = windows[0].GetVideoDim();
     121    vbuffers.Init(num_buffers, true, 2, 1, 4, 1, false); // shouldn't need pause frame
     122
     123    bool ok = true;
     124    for (int i = 0; i < num_buffers; i++)
     125    {
     126        ok &= vbuffers.CreateBuffer(video_dim.width(),
     127                                    video_dim.height(), i,
     128                                    m_ctx->GetVideoSurface(i));
     129    }
     130    return ok;
     131}
     132
     133void* VideoOutputOpenGLVAAPI::GetVAAPIContext(void)
     134{
     135    if (m_ctx)
     136        return &m_ctx->m_ctx;
     137    return NULL;
     138}
     139
     140void VideoOutputOpenGLVAAPI::SetProfile(void)
     141{
     142    if (db_vdisp_profile)
     143        db_vdisp_profile->SetVideoRenderer("openglvaapi");
     144}
     145
     146bool VideoOutputOpenGLVAAPI::ApproveDeintFilter(const QString &filtername) const
     147{
     148    return filtername.contains("vaapi");
     149}
     150
     151uint8_t* VideoOutputOpenGLVAAPI::GetSurfaceIDPointer(void* buf)
     152{
     153    if (m_ctx)
     154        return m_ctx->GetSurfaceIDPointer(buf);
     155    return NULL;
     156}
     157
     158void VideoOutputOpenGLVAAPI::ProcessFrame(VideoFrame *frame, OSD *osd,
     159                                          FilterChain *filterList,
     160                                          const PIPMap &pipPlayers,
     161                                          FrameScanType scan)
     162{
     163    VideoOutputOpenGL::ProcessFrame(frame, osd, filterList, pipPlayers, scan);
     164    if (codec_is_vaapi_hw(gl_codec_id) && m_ctx && gl_videochain && frame)
     165    {
     166        gl_context->makeCurrent();
     167        uint tex = gl_videochain->GetInputTexture();
     168        gl_context->EnableTextures(tex);
     169        if (m_ctx->CopySurfaceToTexture(frame->buf, tex,
     170                                        gl_videochain->GetTextureType()))
     171        {
     172            gl_videochain->SetInputUpdated();
     173        }
     174        gl_context->doneCurrent();
     175    }
     176}
     177
     178QStringList VideoOutputOpenGLVAAPI::GetAllowedRenderers(
     179    MythCodecID myth_codec_id, const QSize &video_dim)
     180{
     181    (void) video_dim;
     182    QStringList list;
     183    if ((codec_is_std(myth_codec_id) || codec_is_vaapi_hw(myth_codec_id)) &&
     184         !getenv("NO_VAAPI"))
     185    {
     186        list += "openglvaapi";
     187    }
     188    return list;
     189}
     190
     191MythCodecID VideoOutputOpenGLVAAPI::GetBestSupportedCodec(
     192    uint width,       uint height,
     193    uint stream_type, bool no_acceleration,
     194    PixelFormat &pix_fmt)
     195{
     196    QSize size(width, height);
     197    bool use_cpu = no_acceleration;
     198    VideoDisplayProfile vdp;
     199    vdp.SetInput(size);
     200    QString dec = vdp.GetDecoder();
     201
     202    MythCodecID test_cid = (MythCodecID)(kCodec_MPEG1_VAAPI + (stream_type-1));
     203    use_cpu |= !codec_is_vaapi_hw(test_cid);
     204    use_cpu |= !VAAPIContext::IsFormatAccelerated(size, test_cid, pix_fmt);
     205    if ((dec != "vaapi") || getenv("NO_VAAPI") || use_cpu)
     206        return (MythCodecID)(kCodec_MPEG1 + (stream_type-1));
     207
     208    return test_cid;
     209}
  • libs/libmythtv/libmythtv.pro

     
    344344
    345345    using_glx_proc_addr_arb:DEFINES += USING_GLX_PROC_ADDR_ARB
    346346
     347    using_vaapi: DEFINES += USING_VAAPI
     348    using_vaapi: DEFINES += videoout_openglvaapi.h   vaapicontext.h
     349    using_vaapi: SOURCES += videoout_openglvaapi.cpp vaapicontext.cpp
     350    using_vaapi: LIBS    += -lva -lva-glx
     351
    347352    # Misc. frontend
    348353    HEADERS += DetectLetterbox.h
    349354    SOURCES += DetectLetterbox.cpp
  • libs/libmythtv/vaapicontext.cpp

     
     1#include <QHash>
     2
     3#include "mythverbose.h"
     4#include "mythxdisplay.h"
     5#include "mythcodecid.h"
     6#include "vaapicontext.h"
     7
     8#define LOC     QString("VAAPI: ")
     9#define LOC_ERR QString("VAAPI Error: ")
     10#define NUM_VAAPI_BUFFERS 20
     11
     12#define INIT_ST \
     13  VAStatus va_status; \
     14  bool ok = true;
     15
     16#define CHECK_ST \
     17  ok &= (va_status == VA_STATUS_SUCCESS); \
     18  if (!ok) { \
     19      VERBOSE(VB_GENERAL, LOC_ERR + QString("Error at %1:%2 (#%3, %4)") \
     20              .arg(__FILE__).arg( __LINE__).arg(va_status) \
     21              .arg(vaErrorStr(va_status))); \
     22  }
     23
     24#define CREATE_CHECK(arg1, arg2) \
     25  if (ok) \
     26  { \
     27      ok = arg1; \
     28      if (!ok) \
     29          VERBOSE(VB_IMPORTANT, LOC_ERR + arg2); \
     30  }
     31
     32QString profileToString(VAProfile profile)
     33{
     34    if (VAProfileMPEG2Simple == profile)         return "MPEG2Simple";
     35    if (VAProfileMPEG2Main == profile)           return "MPEG2Main";
     36    if (VAProfileMPEG4Simple == profile)         return "MPEG4Simple";
     37    if (VAProfileMPEG4AdvancedSimple == profile) return "MPEG4AdvSimple";
     38    if (VAProfileMPEG4Main == profile)           return "MPEG4Main";
     39    if (VAProfileH264Baseline == profile)        return "H264Base";
     40    if (VAProfileH264Main == profile)            return "H264Main";
     41    if (VAProfileH264High == profile)            return "H264High";
     42    if (VAProfileVC1Simple == profile)           return "VC1Simple";
     43    if (VAProfileVC1Main == profile)             return "VC1Main";
     44    if (VAProfileVC1Advanced == profile)         return "VC1Advanced";
     45    if (VAProfileH263Baseline == profile)        return "H263Base";
     46    return "Unknown";
     47}
     48
     49QString entryToString(VAEntrypoint entry)
     50{
     51    if (VAEntrypointVLD == entry)        return "VLD ";
     52    if (VAEntrypointIZZ == entry)        return "IZZ ";
     53    if (VAEntrypointIDCT == entry)       return "IDCT ";
     54    if (VAEntrypointMoComp == entry)     return "MC ";
     55    if (VAEntrypointDeblocking == entry) return "Deblock (UNSUPPORTED) ";
     56    if (VAEntrypointEncSlice == entry)   return "EncSlice (UNSUPPORTED) ";
     57    return "Unknown";
     58}
     59
     60VAProfile preferredProfile(MythCodecID codec)
     61{
     62    // FIXME handle unsupported codecs properly
     63    if (kCodec_H263_VAAPI  == codec) return VAProfileH263Baseline;
     64    if (kCodec_MPEG4_VAAPI == codec) return VAProfileMPEG4AdvancedSimple;
     65    if (kCodec_H264_VAAPI  == codec) return VAProfileH264High;
     66    if (kCodec_VC1_VAAPI   == codec) return VAProfileVC1Advanced;
     67    if (kCodec_WMV3_VAAPI  == codec) return VAProfileVC1Main;
     68    return VAProfileMPEG2Main;
     69}
     70
     71bool VAAPIContext::IsFormatAccelerated(QSize size, MythCodecID codec,
     72                                       PixelFormat &pix_fmt)
     73{
     74    bool result = false;
     75    VAAPIContext *ctx = new VAAPIContext(codec);
     76    if (ctx)
     77    {
     78        result  = ctx->CreateDummy(size);
     79        pix_fmt = ctx->GetPixelFormat();
     80    }
     81    delete ctx;
     82    return result;
     83}
     84
     85VAAPIContext::VAAPIContext(MythCodecID codec)
     86  : m_codec(codec), m_display(NULL),
     87    m_vaProfile(VAProfileMPEG2Main)/* ?? */,
     88    m_vaEntrypoint(VAEntrypointEncSlice),
     89    m_pix_fmt(PIX_FMT_YUV420P), m_numSurfaces(NUM_VAAPI_BUFFERS),
     90    m_surfaces(NULL), m_surfaceData(NULL)
     91{
     92    memset(&m_ctx, 0, sizeof(vaapi_context));
     93}
     94
     95VAAPIContext::~VAAPIContext()
     96{
     97    INIT_ST
     98
     99    ClearGLXSurfaces();
     100    if (m_ctx.context_id)
     101    {
     102        va_status = vaDestroyContext(m_ctx.display, m_ctx.context_id);
     103        CHECK_ST
     104    }
     105    if (m_ctx.config_id)
     106    {
     107        va_status = vaDestroyConfig(m_ctx.display, m_ctx.config_id);
     108        CHECK_ST
     109    }
     110    if (m_surfaces)
     111    {
     112        va_status = vaDestroySurfaces(m_ctx.display, m_surfaces, m_numSurfaces);
     113        CHECK_ST
     114    }
     115
     116    if (m_ctx.display)
     117    {
     118        va_status = vaTerminate(m_ctx.display);
     119        CHECK_ST
     120    }
     121
     122    if (m_surfaces)
     123        delete [] m_surfaces;
     124    if (m_surfaceData)
     125        delete [] m_surfaceData;
     126
     127    delete m_display;
     128    VERBOSE(VB_PLAYBACK, LOC + "Deleted context");
     129}
     130
     131bool VAAPIContext::CreateDummy(QSize size)\
     132{
     133    m_size = size;
     134    bool ok = true;
     135    m_display = OpenMythXDisplay();
     136    CREATE_CHECK(!m_size.isEmpty(), "Invalid size")
     137    CREATE_CHECK(m_display != NULL, "Invalid display")
     138    CREATE_CHECK(InitDisplay(),     "Invalid VADisplay")
     139    CREATE_CHECK(InitProfiles(),    "No supported profiles")
     140    return ok;
     141}
     142
     143bool VAAPIContext::Create(QSize size)
     144{
     145    m_size = size;
     146    bool ok = true;
     147    m_display = OpenMythXDisplay();
     148    CREATE_CHECK(!m_size.isEmpty(), "Invalid size")
     149    CREATE_CHECK(m_display != NULL, "Invalid display")
     150    CREATE_CHECK(InitDisplay(),     "Invalid VADisplay")
     151    CREATE_CHECK(InitProfiles(),    "No supported profiles")
     152    CREATE_CHECK(InitBuffers(),     "Failed to create buffers.")
     153    CREATE_CHECK(InitContext(),     "Failed to create context")
     154    if (ok)
     155        VERBOSE(VB_PLAYBACK, LOC + "Created context");
     156    return ok;
     157}
     158
     159bool VAAPIContext::InitDisplay(void)
     160{
     161    int major_ver, minor_ver;
     162    m_ctx.display = vaGetDisplayGLX(m_display->GetDisplay());
     163    INIT_ST
     164    va_status = vaInitialize(m_ctx.display, &major_ver, &minor_ver);
     165    CHECK_ST
     166
     167    static bool debugged = false;
     168    if (ok && !debugged)
     169    {
     170        debugged = true;
     171        VERBOSE(VB_IMPORTANT, LOC + QString("Version: %1.%2")
     172                                    .arg(major_ver).arg(minor_ver));
     173        VERBOSE(VB_IMPORTANT, LOC + QString("Vendor : %1")
     174                                    .arg(vaQueryVendorString(m_ctx.display)));
     175    }
     176    return ok;
     177}
     178
     179bool VAAPIContext::InitProfiles(void)
     180{
     181    if (!codec_is_vaapi_hw(m_codec) || !m_ctx.display)
     182        return false;
     183
     184    int max_profiles, max_entrypoints;
     185    VAProfile profile_wanted = preferredProfile(m_codec);
     186    VAProfile profile_found  = VAProfileMPEG2Main;   // FIXME
     187    VAEntrypoint entry_found = VAEntrypointEncSlice; // unsupported value
     188
     189    max_profiles          = vaMaxNumProfiles(m_ctx.display);
     190    max_entrypoints       = vaMaxNumEntrypoints(m_ctx.display);
     191    VAProfile *profiles   = new VAProfile[max_profiles];
     192    VAEntrypoint *entries = new VAEntrypoint[max_entrypoints];
     193
     194    static bool debugged = false;
     195    if (profiles && entries)
     196    {
     197        INIT_ST
     198        int act_profiles, act_entries;
     199        va_status = vaQueryConfigProfiles(m_ctx.display,
     200                                          profiles,
     201                                         &act_profiles);
     202        CHECK_ST
     203        if (ok && act_profiles > 0)
     204        {
     205            for (int i = 0; i < act_profiles; i++)
     206            {
     207                va_status = vaQueryConfigEntrypoints(m_ctx.display,
     208                                                     profiles[i],
     209                                                     entries,
     210                                                    &act_entries);
     211                if (va_status == VA_STATUS_SUCCESS && act_entries > 0)
     212                {
     213                    if (profiles[i] == profile_wanted)
     214                    {
     215                        profile_found = profile_wanted;
     216                        for (int j = 0; j < act_entries; j++)
     217                            if (entries[j] < entry_found)
     218                                entry_found = entries[j];
     219                    }
     220
     221                    if (!debugged)
     222                    {
     223                        QString entrylist = "Entrypoints: ";
     224                        for (int j = 0; j < act_entries; j++)
     225                            entrylist += entryToString(entries[j]);
     226                        VERBOSE(VB_IMPORTANT, LOC + QString("Profile: %1 %2")
     227                            .arg(profileToString(profiles[i])).arg(entrylist));
     228                    }
     229                }
     230            }
     231        }
     232        debugged = true;
     233    }
     234    delete profiles;
     235    delete entries;
     236
     237    VERBOSE(VB_PLAYBACK, LOC + QString("Desired profile for '%1': %2")
     238        .arg(toString(m_codec)).arg(profileToString(profile_wanted)));
     239    VERBOSE(VB_PLAYBACK, LOC + QString("Found profile %1 with entry %2")
     240        .arg(profileToString(profile_found)).arg(entryToString(entry_found)));
     241
     242    if (profile_wanted != profile_found)
     243    {
     244        VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to find supported profile.");
     245        return false;
     246    }
     247
     248    if (entry_found > VAEntrypointMoComp)
     249    {
     250        VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to find suitable entry point.");
     251        return false;
     252    }
     253
     254    m_vaProfile = profile_wanted;
     255    m_vaEntrypoint = entry_found;
     256    if (VAEntrypointVLD == m_vaEntrypoint)
     257        m_pix_fmt = PIX_FMT_VAAPI_VLD;
     258    else if (VAEntrypointIDCT == m_vaEntrypoint)
     259        m_pix_fmt = PIX_FMT_VAAPI_IDCT;
     260    else if (VAEntrypointMoComp == m_vaEntrypoint)
     261        m_pix_fmt = PIX_FMT_VAAPI_MOCO;
     262    return true;
     263}
     264
     265bool VAAPIContext::InitBuffers(void)
     266{
     267    m_surfaces = new VASurfaceID[m_numSurfaces];
     268    m_surfaceData = new vaapi_surface[m_numSurfaces];
     269
     270    if (!m_surfaces || !m_surfaceData)
     271        return false;
     272
     273    INIT_ST
     274    va_status = vaCreateSurfaces(m_ctx.display, m_size.width(), m_size.height(),
     275                                 VA_RT_FORMAT_YUV420, m_numSurfaces,
     276                                 m_surfaces);
     277    CHECK_ST
     278
     279    for (int i =0; i < m_numSurfaces; i++)
     280        m_surfaceData[i].m_id = m_surfaces[i];
     281
     282    return ok;
     283}
     284
     285bool VAAPIContext::InitContext(void)
     286{
     287    if (!m_ctx.display || m_vaEntrypoint > VAEntrypointMoComp)
     288        return false;
     289
     290    VAConfigAttrib attrib;
     291    attrib.type = VAConfigAttribRTFormat;
     292    INIT_ST
     293    va_status = vaGetConfigAttributes(m_ctx.display, m_vaProfile,
     294                                      m_vaEntrypoint, &attrib, 1);
     295    CHECK_ST
     296
     297    if (!ok || !(attrib.value & VA_RT_FORMAT_YUV420))
     298    {
     299        VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to confirm YUV420 chroma");
     300        return false;
     301    }
     302
     303    va_status = vaCreateConfig(m_ctx.display, m_vaProfile, m_vaEntrypoint,
     304                               &attrib, 1, &m_ctx.config_id);
     305    CHECK_ST
     306    if (!ok)
     307    {
     308        VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to create decoder config.");
     309        return false;
     310    }
     311
     312    va_status = vaCreateContext(m_ctx.display, m_ctx.config_id,
     313                                m_size.width(), m_size.height(), VA_PROGRESSIVE,
     314                                m_surfaces, m_numSurfaces,
     315                                &m_ctx.context_id);
     316    CHECK_ST
     317    if (!ok)
     318    {
     319        VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to create decoder context.");
     320        return false;
     321    }
     322    return true;
     323}
     324
     325void* VAAPIContext::GetVideoSurface(int i)
     326{
     327    if (i < 0 || i >= m_numSurfaces)
     328        return NULL;
     329    return &m_surfaceData[i];
     330}
     331
     332uint8_t* VAAPIContext::GetSurfaceIDPointer(void* buf)
     333{
     334    if (!buf)
     335        return NULL;
     336    const vaapi_surface *surf = (vaapi_surface*)buf;
     337    return (uint8_t*)(uintptr_t)surf->m_id;
     338}
     339
     340bool VAAPIContext::CopySurfaceToTexture(void* buf, uint texture,
     341                                        uint texture_type)
     342{
     343    if (!buf || !texture)
     344        return false;
     345    void* glx_surface = GetGLXSurface(texture, texture_type);
     346    if (!glx_surface)
     347        return false;
     348    const vaapi_surface *surf = (vaapi_surface*)buf;
     349    INIT_ST
     350    va_status = vaCopySurfaceGLX(m_ctx.display, glx_surface, surf->m_id, 0);
     351    CHECK_ST
     352    return ok;
     353}
     354
     355void* VAAPIContext::GetGLXSurface(uint texture, uint texture_type)
     356{
     357    if (m_glxSurfaces.contains(texture))
     358        return m_glxSurfaces.value(texture);
     359
     360
     361    void *glx_surface = NULL;
     362    INIT_ST
     363    glBindTexture(texture_type, texture);
     364    va_status = vaCreateSurfaceGLX(m_ctx.display, texture_type, texture,
     365                                  &glx_surface);
     366    CHECK_ST
     367    if (glx_surface)
     368        m_glxSurfaces.insert(texture, glx_surface);
     369
     370    VERBOSE(VB_PLAYBACK, QString("Number of VAAPI GLX surfaces: %1")
     371        .arg(m_glxSurfaces.size()));
     372    return glx_surface;
     373}
     374
     375void VAAPIContext::ClearGLXSurfaces(void)
     376{
     377    INIT_ST
     378    for (int i = 0; i < m_glxSurfaces.size(); i++)
     379    {
     380        va_status = vaDestroySurfaceGLX(m_ctx.display, m_glxSurfaces.value(i));
     381        CHECK_ST
     382    }
     383    m_glxSurfaces.clear();
     384}
  • libs/libmythtv/videoout_opengl.h

     
    1010{
    1111  public:
    1212    static void GetRenderOptions(render_opts &opts, QStringList &cpudeints);
    13     VideoOutputOpenGL();
    14    ~VideoOutputOpenGL();
     13    VideoOutputOpenGL(MythCodecID codec_id);
     14    virtual ~VideoOutputOpenGL();
    1515
    16     bool Init(int width, int height, float aspect, WId winid,
    17               int winx, int winy, int winw, int winh, WId embedid = 0);
    18     void TearDown(void);
     16    virtual bool Init(int width, int height, float aspect, WId winid,
     17                      int winx, int winy, int winw, int winh, WId embedid = 0);
     18    virtual void SetProfile(void);
     19    virtual void TearDown(void);
    1920
    2021    void PrepareFrame(VideoFrame *buffer, FrameScanType, OSD *osd);
    21     void ProcessFrame(VideoFrame *frame, OSD *osd,
    22                       FilterChain *filterList,
    23                       const PIPMap &pipPlayers,
    24                       FrameScanType scan);
    25     void Show(FrameScanType );
    26     bool InputChanged(const QSize &input_size, float aspect,
    27                       MythCodecID  av_codec_id, void *codec_private,
    28                       bool &aspect_only);
     22    virtual void ProcessFrame(VideoFrame *frame, OSD *osd,
     23                              FilterChain *filterList,
     24                              const PIPMap &pipPlayers,
     25                              FrameScanType scan);
     26    virtual void Show(FrameScanType );
     27    virtual bool InputChanged(const QSize &input_size, float aspect,
     28                              MythCodecID  av_codec_id, void *codec_private,
     29                              bool &aspect_only);
    2930    DisplayInfo GetDisplayInfo(void);
    3031    void UpdatePauseFrame(void);
    3132    void DrawUnusedRects(bool) { }
     
    5152    virtual bool ApproveDeintFilter(const QString& filtername) const;
    5253    virtual MythPainter *GetOSDPainter(void)  { return (MythPainter*)gl_painter; }
    5354
    54   private:
    55     bool CreateBuffers(void);
     55  protected:
     56    virtual bool CreateBuffers(void);
     57    bool CreatePauseFrame(void);
    5658    bool SetupContext(void);
    5759    bool SetupOpenGL(void);
    5860    void InitOSD(void);
    5961
     62    MythCodecID       gl_codec_id;
    6063    QMutex            gl_context_lock;
    6164    MythRenderOpenGL *gl_context;
    6265    OpenGLVideo      *gl_videochain;
  • libs/libmythtv/openglvideo.h

     
    4444              QSize videoDim, QRect displayVisibleRect,
    4545              QRect displayVideoRect, QRect videoRect,
    4646              bool viewport_control,  QString options,
     47              bool hwaccel,
    4748              LetterBoxColour letterbox_colour = kLetterBoxColour_Black);
    4849
     50    uint GetInputTexture(void);
     51    uint GetTextureType(void);
     52    void SetInputUpdated(void);
    4953    void UpdateInputFrame(const VideoFrame *frame, bool soft_bob = false);
    5054
    5155    /// \brief Public interface to AddFilter(OpenGLFilterType filter)
     
    124128    OpenGLFilterType defaultUpsize;
    125129    uint           gl_features;
    126130    bool           using_ycbcrtex;
     131    bool           using_hardwaretex;
    127132    LetterBoxColour gl_letterbox_colour;
    128133};
    129134#endif // _OPENGL_VIDEO_H__
  • libs/libmythtv/openglvideo.cpp

     
    8484    textureRects(false),      textureType(GL_TEXTURE_2D),
    8585    helperTexture(0),         defaultUpsize(kGLFilterResize),
    8686    gl_features(0),           using_ycbcrtex(false),
     87    using_hardwaretex(false),
    8788    gl_letterbox_colour(kLetterBoxColour_Black)
    8889{
    8990}
     
    139140                       QSize videoDim, QRect displayVisibleRect,
    140141                       QRect displayVideoRect, QRect videoRect,
    141142                       bool viewport_control, QString options,
     143                       bool hw_accel,
    142144                       LetterBoxColour letterbox_colour)
    143145{
    144146    gl_context            = glcontext;
     
    175177
    176178    SetViewPort(display_visible_rect.size());
    177179
    178     bool use_pbo        = gl_features & kGLExtPBufObj;
     180    using_hardwaretex   = hw_accel;
     181    bool use_pbo        = !using_hardwaretex && (gl_features & kGLExtPBufObj);
    179182    bool basic_features = gl_features & kGLExtFragProg;
    180183    bool full_features  = basic_features && (gl_features & kGLExtFBufObj);
    181     using_ycbcrtex      = !full_features && (gl_features & kGLYCbCrTex);
     184    using_ycbcrtex      = !using_hardwaretex && !full_features && (gl_features & kGLYCbCrTex);
    182185
    183186    if (using_ycbcrtex)
    184187        basic_features = false;
     
    192195                QString("No OpenGL feature support for Bicubic filter."));
    193196    }
    194197
    195     if ((defaultUpsize != kGLFilterBicubic) && (gl_features & kGLExtRect))
     198    if (!using_hardwaretex &&
     199        (defaultUpsize != kGLFilterBicubic) && (gl_features & kGLExtRect))
    196200        textureType = gl_context->GetTextureType(textureRects);
    197201
    198202    GLuint tex = 0;
    199203    bool    ok = false;
    200204
    201     if (basic_features)
     205    if (basic_features && !using_hardwaretex)
    202206    {
    203207        tex = CreateVideoTexture(actual_video_dim, inputTextureSize, use_pbo);
    204208        ok = tex && AddFilter(kGLFilterYUV2RGB);
    205209    }
    206     else if (using_ycbcrtex)
     210    else if (using_ycbcrtex || using_hardwaretex)
    207211    {
    208212        tex = CreateVideoTexture(actual_video_dim,
    209213                                 inputTextureSize, use_pbo);
    210214        ok = tex && AddFilter(kGLFilterResize);
    211         if (ok)
     215        if (ok && using_ycbcrtex)
    212216            VERBOSE(VB_PLAYBACK, LOC + QString("Using GL_MESA_ycbcr_texture for"
    213217                                               " colorspace conversion."));
     218        else if (ok && using_hardwaretex)
     219            VERBOSE(VB_PLAYBACK, LOC + QString("Using plain RGBA tex for hw accel."));
    214220        else
     221        {
    215222            using_ycbcrtex = false;
     223            using_hardwaretex = false;
     224        }
    216225    }
    217226
    218227    if (ok)
     
    707716        tmp_tex = gl_context->CreateTexture(size, use_pbo, textureType,
    708717                                            GL_UNSIGNED_SHORT_8_8_MESA,
    709718                                            GL_YCBCR_MESA, GL_YCBCR_MESA);
     719    else if (using_hardwaretex)
     720        tmp_tex = gl_context->CreateTexture(size, use_pbo, textureType,
     721                                            GL_UNSIGNED_BYTE, GL_RGBA,
     722                                            GL_RGBA, GL_LINEAR,
     723                                            GL_CLAMP_TO_EDGE);
    710724    else
    711725        tmp_tex = gl_context->CreateTexture(size, use_pbo, textureType);
    712726    tex_size = gl_context->GetTextureSize(textureType, size);
     
    737751    return QSize(w, h);
    738752}
    739753
     754uint OpenGLVideo::GetInputTexture(void)
     755{
     756    return inputTextures[0];
     757}
     758
     759uint OpenGLVideo::GetTextureType(void)
     760{
     761    return textureType;
     762}
     763
     764void OpenGLVideo::SetInputUpdated(void)
     765{
     766    inputUpdated = true;
     767}
     768
    740769/**
    741770 * \fn OpenGLVideo::UpdateInputFrame(const VideoFrame *frame, bool soft_bob)
    742771 *  Update the current input texture using the data from the given YV12 video
     
    9971026            program = filter->fragmentPrograms[prog_ref];
    9981027        }
    9991028
    1000         gl_context->DrawBitmap(textures, texture_count, target, &trect, &vrect,
    1001                                program,
     1029        gl_context->DrawBitmap(textures, using_hardwaretex, texture_count,
     1030                               target, &trect, &vrect, program,
    10021031                              (useColourControl && type == kGLFilterYUV2RGB));
    10031032
    10041033        inputs = filter->frameBufferTextures;
  • libs/libmythtv/mythcodecid.h

     
    7676
    7777    kCodec_VDPAU_END,
    7878
     79    kCodec_VAAPI_BEGIN = kCodec_VDPAU_END,
     80
     81    kCodec_MPEG1_VAAPI,
     82    kCodec_MPEG2_VAAPI,
     83    kCodec_H263_VAAPI,
     84    kCodec_MPEG4_VAAPI,
     85    kCodec_H264_VAAPI,
     86    kCodec_VC1_VAAPI,
     87    kCodec_WMV3_VAAPI,
     88
     89    kCodec_VAAPI_END,
    7990} MythCodecID;
    8091
    8192// MythCodecID convenience functions
     
    93104                              (id < kCodec_VDPAU_END)
    94105#define codec_is_vdpau_hw(id) (codec_is_vdpau(id) &&\
    95106                              (id != kCodec_H263_VDPAU))
     107#define codec_is_vaapi(id)    (id > kCodec_VAAPI_BEGIN) &&\
     108                              (id < kCodec_VAAPI_END)
     109#define codec_is_vaapi_hw(id) (codec_is_vaapi(id) &&\
     110                              (id != kCodec_H263_VAAPI))
    96111
    97112QString get_encoding_type(MythCodecID codecid);
    98113QString get_decoder_name(MythCodecID codec_id, bool libmpeg2);
  • libs/libmythtv/mythcodecid.cpp

     
    9292        case kCodec_WMV3_VDPAU:
    9393            return "WMV3 VDPAU";
    9494
     95        case kCodec_MPEG1_VAAPI:
     96            return "MPEG1 VAAPI";
     97        case kCodec_MPEG2_VAAPI:
     98            return "MPEG2 VAAPI";
     99        case kCodec_H263_VAAPI:
     100            return "H.263 VAAPI";
     101        case kCodec_MPEG4_VAAPI:
     102            return "MPEG4 VAAPI";
     103        case kCodec_H264_VAAPI:
     104            return "H.264 VAAPI";
     105        case kCodec_VC1_VAAPI:
     106            return "VC1 VAAPI";
     107        case kCodec_WMV3_VAAPI:
     108            return "WMV3 VAAPI";
     109
    95110        default:
    96111            break;
    97112    }
     
    228243            vdpau = true;
    229244            break;
    230245
     246        case kCodec_MPEG1_VAAPI:
     247            ret = CODEC_ID_MPEG1VIDEO;
     248            vld = idct = mc = true;
     249            break;
     250        case kCodec_MPEG2_VAAPI:
     251            ret = CODEC_ID_MPEG2VIDEO;
     252            vld = idct = mc = true;
     253            break;
     254        case kCodec_H263_VAAPI:
     255            VERBOSE(VB_IMPORTANT, "Error: VAAPI H.263 not supported by ffmpeg");
     256            break;
     257        case kCodec_MPEG4_VAAPI:
     258            ret = CODEC_ID_MPEG4;
     259            vld = true;
     260            break;
     261        case kCodec_H264_VAAPI:
     262            ret = CODEC_ID_H264;
     263            vld = true;
     264            break;
     265        case kCodec_VC1_VAAPI:
     266            ret = CODEC_ID_VC1;
     267            vld = true;
     268            break;
     269        case kCodec_WMV3_VAAPI:
     270            ret = CODEC_ID_WMV3;
     271            vld = true;
     272            break;
     273
    231274        default:
    232275            VERBOSE(VB_IMPORTANT,
    233276                    QString("Error: MythCodecID %1 has not been "
     
    283326        case kCodec_MPEG2_VLD:
    284327        case kCodec_MPEG2_DVDV:
    285328        case kCodec_MPEG2_VDPAU:
     329        case kCodec_MPEG2_VAAPI:
    286330            return "MPEG-2";
    287331
    288332        case kCodec_H263:
     
    291335        case kCodec_H263_VLD:
    292336        case kCodec_H263_DVDV:
    293337        case kCodec_H263_VDPAU:
     338        case kCodec_H263_VAAPI:
    294339            return "H.263";
    295340
    296341        case kCodec_NUV_MPEG4:
     
    300345        case kCodec_MPEG4_VLD:
    301346        case kCodec_MPEG4_DVDV:
    302347        case kCodec_MPEG4_VDPAU:
     348        case kCodec_MPEG4_VAAPI:
    303349            return "MPEG-4";
    304350
    305351        case kCodec_H264:
     
    338384    if (codec_is_vdpau(codec_id))
    339385        return "vdpau";
    340386
     387    if (codec_is_vaapi(codec_id))
     388        return "vaapi";
     389
    341390    return "ffmpeg";
    342391}
  • libs/libmythtv/videooutbase.cpp

     
    4040#include "videoout_vdpau.h"
    4141#endif
    4242
     43#ifdef USING_VAAPI
     44#include "videoout_openglvaapi.h"
     45#endif
     46
    4347#include "videoout_null.h"
    4448#include "dithertable.h"
    4549
     
    96100#ifdef USING_VDPAU
    97101    VideoOutputVDPAU::GetRenderOptions(opts);
    98102#endif // USING_VDPAU
     103
     104#ifdef USING_VAAPI
     105    VideoOutputOpenGLVAAPI::GetRenderOptions(opts);
     106#endif // USING_VAAPI
    99107}
    100108
    101109/**
     
    143151    renderers += VideoOutputVDPAU::GetAllowedRenderers(codec_id, video_dim);
    144152#endif // USING_VDPAU
    145153
     154#ifdef USING_VAAPI
     155    renderers += VideoOutputOpenGLVAAPI::GetAllowedRenderers(codec_id, video_dim);
     156#endif // USING_VAAPI
     157
    146158    VERBOSE(VB_PLAYBACK, LOC + "Allowed renderers: " +
    147159            to_comma_list(renderers));
    148160
     
    197209
    198210#ifdef USING_OPENGL_VIDEO
    199211        if (renderer == "opengl")
    200             vo = new VideoOutputOpenGL();
     212            vo = new VideoOutputOpenGL(codec_id);
    201213#endif // USING_OPENGL_VIDEO
    202214
    203215#ifdef USING_VDPAU
     
    205217            vo = new VideoOutputVDPAU(codec_id);
    206218#endif // USING_VDPAU
    207219
     220#ifdef USING_VAAPI
     221        if (renderer == "openglvaapi")
     222            vo = new VideoOutputOpenGLVAAPI(codec_id);
     223#endif // USING_VAAPI
     224
    208225#ifdef USING_XV
    209226        if (xvlist.contains(renderer))
    210227            vo = new VideoOutputXv(codec_id);
  • libs/libmythtv/vaapicontext.h

     
     1#ifndef VAAPICONTEXT_H
     2#define VAAPICONTEXT_H
     3
     4extern "C" {
     5#include "libavcodec/vaapi.h"
     6}
     7
     8#include "va/va.h"
     9#include "va/va_glx.h"
     10
     11#include <QHash>
     12
     13struct vaapi_surface
     14{
     15    VASurfaceID m_id;
     16};
     17
     18class VAAPIContext
     19{
     20  public:
     21    static bool IsFormatAccelerated(QSize size, MythCodecID codec,
     22                                    PixelFormat &pix_fmt);
     23    VAAPIContext(MythCodecID codec);
     24   ~VAAPIContext();
     25
     26    bool  Create(QSize size);
     27    bool  CreateDummy(QSize size);
     28    void* GetVideoSurface(int i);
     29    uint8_t* GetSurfaceIDPointer(void* buf);
     30   
     31    int   GetNumBuffers(void)        { return m_numSurfaces; }
     32    PixelFormat GetPixelFormat(void) { return m_pix_fmt;     }
     33
     34
     35    // temp hack
     36    void  ShowSurface(int win, QRect &rect, void* buf);
     37   
     38    bool  CopySurfaceToTexture(void* buf, uint texture, uint texture_type);
     39    void* GetGLXSurface(uint texture, uint texture_type);
     40    void  ClearGLXSurfaces(void);
     41
     42    bool InitDisplay(void);
     43    bool InitProfiles(void);
     44    bool InitBuffers(void);
     45    bool InitContext(void);
     46
     47    vaapi_context  m_ctx;
     48    MythCodecID    m_codec;
     49    QSize          m_size;
     50    MythXDisplay  *m_display;
     51    VAProfile      m_vaProfile;
     52    VAEntrypoint   m_vaEntrypoint;
     53    PixelFormat    m_pix_fmt;
     54    int            m_numSurfaces;
     55    VASurfaceID   *m_surfaces;
     56    vaapi_surface *m_surfaceData;
     57    QHash<uint, void*> m_glxSurfaces;
     58
     59};
     60
     61#endif // VAAPICONTEXT_H
  • libs/libmythtv/videodisplayprofile.cpp

     
    642642        dec_name["xvmc-vld"] = QObject::tr("VIA XvMC");
    643643        dec_name["macaccel"] = QObject::tr("Mac hardware acceleration");
    644644        dec_name["vdpau"]    = QObject::tr("NVidia VDPAU acceleration");
     645        dec_name["vaapi"]    = QObject::tr("VA API");
    645646    }
    646647
    647648    QString ret = decoder;
     
    691692            "VDPAU will attempt to use the graphics hardware to "
    692693            "accelerate video decoding and playback.");
    693694
     695    if (decoder == "vaapi")
     696        msg += QObject::tr(
     697            "VAAPI will attempt to use the graphics hardware to "
     698            "accelerate video decoding and playback.");
     699
    694700    return msg;
    695701}
    696702
     
    736742        return QObject::tr("Yadif (2x, Hw)");
    737743    else if ("openglyadif" == short_name)
    738744        return QObject::tr("Yadif (Hw)");
    739     else if ("vdpauonefield" == short_name)
     745    else if ("vdpauonefield" == short_name || "vaapionefield" == short_name)
    740746        return QObject::tr("One Field (1x, Hw)");
    741     else if ("vdpaubobdeint" == short_name)
     747    else if ("vdpaubobdeint" == short_name || "vaapibobdeint" == short_name)
    742748        return QObject::tr("Bob (2x, Hw)");
    743749    else if ("vdpaubasic" == short_name)
    744750        return QObject::tr("Temporal (1x, Hw)");
     
    12371243            "This is the only video renderer for NVidia VDPAU decoding.");
    12381244    }
    12391245
     1246    if (renderer == "openglvaapi")
     1247    {
     1248        msg = QObject::tr(
     1249            "This is the only video renderer for VAAPI decoding.");
     1250    }
     1251
    12401252    return msg;
    12411253}
    12421254
     
    13581370        msg = kFieldOrderMsg + " " +  kDoubleRateMsg;
    13591371    else if (deint == "opengldoublerateyadif")
    13601372        msg = kYadifMsg + " " +  kDoubleRateMsg + " " +  kUsingGPU;
    1361     else if (deint == "vdpauonefield")
     1373    else if (deint == "vdpauonefield" || deint == "vaapionefield")
    13621374        msg = kOneFieldMsg + " " + kUsingGPU;
    1363     else if (deint == "vdpaubobdeint")
     1375    else if (deint == "vdpaubobdeint" || deint == "vaapibobdeint")
    13641376        msg = kBobMsg + " " + kUsingGPU;
    13651377    else if (deint == "vdpaubasic")
    13661378        msg = kBasicMsg + " " + kUsingGPU;
  • libs/libavutil/internal.h

     
    242242#define log2f(x) log2(x)
    243243#endif /* HAVE_LOG2F */
    244244
    245 #if !HAVE_LRINT
    246 static av_always_inline av_const long int lrint(double x)
    247 {
    248     return rint(x);
    249 }
    250 #endif /* HAVE_LRINT */
    251 
    252245#if !HAVE_LRINTF
    253246static av_always_inline av_const long int lrintf(float x)
    254247{
     
    256249}
    257250#endif /* HAVE_LRINTF */
    258251
    259 #if !HAVE_ROUND
    260 static av_always_inline av_const double round(double x)
    261 {
    262     return (x > 0) ? floor(x + 0.5) : ceil(x - 0.5);
    263 }
    264 #endif /* HAVE_ROUND */
    265 
    266252#if !HAVE_ROUNDF
    267253static av_always_inline av_const float roundf(float x)
    268254{
  • libs/libmythui/mythrender_opengl.h

     
    116116    void DrawBitmap(uint tex, uint target, const QRect *src, const QRect *dst,
    117117                    uint prog, int alpha = 255, int red = 255, int green = 255,
    118118                    int blue = 255);
    119     void DrawBitmap(uint *textures, uint texture_count, uint target,
    120                     const QRectF *src, const QRectF *dst, uint prog,
    121                     bool colour_control = false);
     119    void DrawBitmap(uint *textures, bool use_full_tex, uint texture_count,
     120                    uint target, const QRectF *src, const QRectF *dst,
     121                    uint prog, bool colour_control = false);
    122122    void DrawRect(const QRect &area, bool drawFill,
    123123                  const QColor &fillColor, bool drawLine,
    124124                  int lineWidth, const QColor &lineColor,
  • libs/libmythui/mythrender_opengl.cpp

     
    10751075    doneCurrent();
    10761076}
    10771077
    1078 void MythRenderOpenGL::DrawBitmap(uint *textures, uint texture_count,
     1078void MythRenderOpenGL::DrawBitmap(uint *textures, bool use_full_tex,
     1079                                  uint texture_count,
    10791080                                  uint target, const QRectF *src,
    10801081                                  const QRectF *dst, uint prog,
    10811082                                  bool colour_control)
     
    10941095    uint first = textures[0];
    10951096    if (!IsRectTexture(m_textures[first].m_type))
    10961097    {
    1097         srcx1 = src->x() / m_textures[first].m_size.width();
    1098         srcx2 = srcx1 + src->width() / m_textures[first].m_size.width();
    1099         srcy1 = src->y() / m_textures[first].m_size.height();
    1100         srcy2 = srcy1 + src->height() / m_textures[first].m_size.height();
     1098        int width  = use_full_tex ? m_textures[first].m_act_size.width() :
     1099                                    m_textures[first].m_size.width();
     1100        int height = use_full_tex ? m_textures[first].m_act_size.height() :
     1101                                    m_textures[first].m_size.height();
     1102        srcx1 = src->x() / width;
     1103        srcx2 = srcx1 + src->width() / width;
     1104        srcy1 = src->y() / height;
     1105        srcy2 = srcy1 + src->height() / height;
    11011106    }
    11021107    else
    11031108    {