Ticket #8593: vaapi_v5.diff

File vaapi_v5.diff, 50.4 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="x11 opengl_video"
    16811684
    16821685# default parameters
    16831686pre_logfile="config.ep"
     
    33963399check_header termios.h
    33973400check_header vdpau/vdpau.h
    33983401check_header vdpau/vdpau_x11.h
     3402check_header va/va.h
     3403check_header va/va_glx.h
    33993404check_header X11/extensions/XvMClib.h
    34003405
    34013406check_struct dxva2api.h DXVA_PictureParameters wDecodedPictureIndex
     
    36643669      disable vdpau; }
    36653670fi
    36663671
     3672if enabled vaapi; then
     3673    enabled va_va_h && enabled va_va_glx_h || disable vaapi
     3674    if enabled vaapi; then
     3675        # for XvBA/VDPAU backends we need splitted desktop 0.31.0 but
     3676        # for upstream GLX support we need 0.31.1 ???
     3677        check_cpp_condition va/va.h "VA_VERSION_HEX >= 0x001F0000" ||
     3678        { echolog "VAAPI requires libva >= 0.31.1" && disable vaapi; }
     3679    fi
     3680else
     3681    disable vaapi
     3682fi
     3683
    36673684enabled debug && add_cflags -g"$debuglevel" && add_asflags -g"$debuglevel"
    36683685enabled debug && add_cxxflags -g"$debuglevel"
    36693686
     
    42214238  echo "XvMC libs                 $VENDOR_XVMC_LIBS"
    42224239fi
    42234240  echo "VDPAU support             ${vdpau-no}"
     4241  echo "VAAPI support             ${vaapi-no}"
    42244242fi
    42254243  echo "OpenGL video              ${opengl_video-no}"
    42264244  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  CreateVAAPIContext(QSize size);
     18    void  DeleteVAAPIContext(void);
     19    bool  CreateBuffers(void);
     20    void* GetVAAPIContext(void);
     21    uint8_t* GetSurfaceIDPointer(void* buf);
     22    void  SetProfile(void);
     23    void  TearDown(void);
     24    bool  InputChanged(const QSize &input_size, float aspect,
     25                       MythCodecID  av_codec_id, void *codec_private,
     26                       bool &aspect_only);
     27    void  ProcessFrame(VideoFrame *frame, OSD *osd,
     28                       FilterChain *filterList,
     29                       const PIPMap &pipPlayers,
     30                       FrameScanType scan);
     31    bool  ApproveDeintFilter(const QString& filtername) const;
     32    bool  SetDeinterlacingEnabled(bool);
     33    bool  SetupDeinterlace(bool i, const QString& ovrf="");
     34   
     35    static QStringList GetAllowedRenderers(MythCodecID myth_codec_id,
     36                                           const QSize &video_dim);
     37    static MythCodecID GetBestSupportedCodec(uint width, uint height,
     38                                             uint stream_type,
     39                                             bool no_acceleration,
     40                                             PixelFormat &pix_fmt);
     41
     42  private:
     43    VAAPIContext *m_ctx;
     44};
     45
     46#endif // VIDEOOUTPUTOPENGLVAAPI_H
     47
  • 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;
    376 
    377378    gl_videochain->SetVideoRect(vsz_enabled ? vsz_desired_display_rect :
    378379                                              windows[0].GetDisplayVideoRect(),
    379380                                windows[0].GetVideoRect());
     
    653654                     QSize(pipVideoWidth, pipVideoHeight),
    654655                     dvr, position,
    655656                     QRect(0, 0, pipVideoWidth, pipVideoHeight),
    656                      false, GetFilters());
     657                     false, GetFilters(), false);
    657658        gl_pipchain->SetMasterViewport(gl_videochain->GetViewPort());
    658659        if (!success)
    659660        {
     
    674675            QSize(pipVideoWidth, pipVideoHeight),
    675676            dvr, position,
    676677            QRect(0, 0, pipVideoWidth, pipVideoHeight),
    677             false, GetFilters());
     678            false, GetFilters(), false);
    678679
    679680        gl_pipchain->SetMasterViewport(gl_videochain->GetViewPort());
    680681        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,
     
    13561367    return fmt[i];
    13571368}
    13581369
     1370static bool IS_VAAPI_PIX_FMT(enum PixelFormat fmt)
     1371{
     1372    return fmt == PIX_FMT_VAAPI_MOCO ||
     1373           fmt == PIX_FMT_VAAPI_IDCT ||
     1374           fmt == PIX_FMT_VAAPI_VLD;
     1375}
     1376
     1377static enum PixelFormat get_format_vaapi(struct AVCodecContext *avctx,
     1378                                         const enum PixelFormat *fmt)
     1379{
     1380    if (!fmt)
     1381        return PIX_FMT_NONE;
     1382    int i = 0;
     1383    for (; fmt[i] != PIX_FMT_NONE ; i++)
     1384        if (IS_VAAPI_PIX_FMT(fmt[i]))
     1385            break;
     1386    return fmt[i];
     1387}
     1388
    13591389static bool IS_DR1_PIX_FMT(const enum PixelFormat fmt)
    13601390{
    13611391    switch (fmt)
     
    14261456    {
    14271457        directrendering = true;
    14281458        if (!gCoreContext->GetNumSetting("DecodeExtraAudio", 0) &&
    1429             !CODEC_IS_HWACCEL(codec))
     1459            !CODEC_IS_HWACCEL(codec, enc))
    14301460        {
    14311461            SetLowBuffers(false);
    14321462        }
     
    14601490        enc->draw_horiz_band = render_slice_vdpau;
    14611491        enc->slice_flags     = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD;
    14621492    }
     1493    else if (CODEC_IS_VAAPI(codec, enc))
     1494    {
     1495        enc->get_buffer      = get_avf_buffer_vaapi;
     1496        enc->get_format      = get_format_vaapi;
     1497        enc->release_buffer  = release_avf_buffer;
     1498        enc->slice_flags     = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD;
     1499    }
    14631500    else if (codec && codec->capabilities & CODEC_CAP_DR1)
    14641501    {
    14651502        enc->flags          |= CODEC_FLAG_EMU_EDGE;
     
    19421979                        handled = true;
    19431980                    }
    19441981#endif // USING_VDPAU
     1982#ifdef USING_VAAPI
     1983                    MythCodecID vaapi_mcid;
     1984                    PixelFormat pix_fmt = PIX_FMT_YUV420P;
     1985                    vaapi_mcid = VideoOutputOpenGLVAAPI::GetBestSupportedCodec(
     1986                        width, height, mpeg_version(enc->codec_id),
     1987                        no_hardware_decoders, pix_fmt);
     1988
     1989                    if (vaapi_mcid >= video_codec_id)
     1990                    {
     1991                        enc->codec_id = (CodecID)myth2av_codecid(vaapi_mcid);
     1992                        video_codec_id = vaapi_mcid;
     1993                        handled = true;
     1994                        if (!no_hardware_decoders &&
     1995                            codec_is_vaapi(video_codec_id))
     1996                        {
     1997                            enc->pix_fmt = pix_fmt;
     1998                        }
     1999                    }
     2000#endif // USING_VAAPI
    19452001#ifdef USING_XVMC
    19462002
    19472003                    bool force_xv = no_hardware_decoders;
     
    26602716    }
    26612717}
    26622718
     2719int get_avf_buffer_vaapi(struct AVCodecContext *c, AVFrame *pic)
     2720{
     2721    AvFormatDecoder *nd = (AvFormatDecoder *)(c->opaque);
     2722    VideoFrame *frame = nd->GetNVP()->GetNextVideoFrame(false);
     2723
     2724    pic->data[0]     = frame->buf;
     2725    pic->data[1]     = NULL;
     2726    pic->data[2]     = NULL;
     2727    pic->data[3]     = NULL;
     2728    pic->linesize[0] = 0;
     2729    pic->linesize[1] = 0;
     2730    pic->linesize[2] = 0;
     2731    pic->linesize[3] = 0;
     2732    pic->opaque      = frame;
     2733    pic->type        = FF_BUFFER_TYPE_USER;
     2734    pic->age         = 256 * 256 * 256 * 64;
     2735    frame->pix_fmt   = c->pix_fmt;
     2736
     2737#ifdef USING_VAAPI
     2738    if (nd->GetNVP()->getVideoOutput())
     2739    {
     2740        VideoOutputOpenGLVAAPI *vo =
     2741            dynamic_cast<VideoOutputOpenGLVAAPI*>(nd->GetNVP()->getVideoOutput());
     2742        c->hwaccel_context = (vaapi_context*)vo->GetVAAPIContext();
     2743        pic->data[3] = vo->GetSurfaceIDPointer(frame->buf);
     2744    }
     2745#endif
     2746
     2747    return 0;
     2748}
     2749
    26632750void AvFormatDecoder::DecodeDTVCC(const uint8_t *buf, uint len)
    26642751{
    26652752    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    TearDown();
     36}
     37
     38void VideoOutputOpenGLVAAPI::TearDown(void)
     39{
     40    DeleteVAAPIContext();
     41}
     42
     43bool VideoOutputOpenGLVAAPI::InputChanged(const QSize &input_size, float aspect,
     44                              MythCodecID  av_codec_id, void *codec_private,
     45                              bool &aspect_only)
     46{
     47    VERBOSE(VB_PLAYBACK, LOC + QString("InputChanged(%1,%2,%3) %4->%5")
     48            .arg(input_size.width()).arg(input_size.height()).arg(aspect)
     49            .arg(toString(gl_codec_id)).arg(toString(av_codec_id)));
     50
     51    if (!codec_is_vaapi(av_codec_id))
     52        return VideoOutputOpenGL::InputChanged(input_size, aspect, av_codec_id,
     53                                               codec_private, aspect_only);
     54                                                   
     55    QMutexLocker locker(&gl_context_lock);
     56    bool cid_changed = (gl_codec_id != av_codec_id);
     57    bool res_changed = input_size  != windows[0].GetVideoDim();
     58    bool asp_changed = aspect      != windows[0].GetVideoAspect();
     59    gl_codec_id = av_codec_id;
     60   
     61    if (!res_changed && !cid_changed)
     62    {
     63        if (asp_changed)
     64        {
     65            aspect_only = true;
     66            VideoAspectRatioChanged(aspect);
     67            MoveResize();
     68        }
     69        return true;
     70    }
     71
     72    TearDown();
     73    QRect disp = windows[0].GetDisplayVisibleRect();
     74    if (Init(input_size.width(), input_size.height(),
     75             aspect, gl_parent_win, disp.left(),  disp.top(),
     76             disp.width(), disp.height(), gl_embed_win))
     77    {
     78        BestDeint();
     79        return true;
     80    }
     81
     82    VERBOSE(VB_IMPORTANT, LOC_ERR +
     83        QString("Failed to re-initialise video output."));
     84    errorState = kError_Unknown;
     85
     86    return false;
     87}
     88
     89bool VideoOutputOpenGLVAAPI::Init(int width, int height, float aspect,
     90                                  WId winid, int winx, int winy, int winw,
     91                                  int winh, WId embedid)
     92{
     93    VERBOSE(VB_PLAYBACK, LOC + "Init");
     94    if (codec_is_vaapi(gl_codec_id))
     95        if (!CreateVAAPIContext(QSize(width, height)))
     96            return false;
     97
     98    return VideoOutputOpenGL::Init(width, height, aspect, winid, winx, winy,
     99                                winw, winh, embedid);
     100}
     101
     102bool VideoOutputOpenGLVAAPI::CreateVAAPIContext(QSize size)
     103{
     104    if (m_ctx)
     105        DeleteVAAPIContext();
     106    m_ctx = new VAAPIContext(gl_codec_id);
     107    if (m_ctx && m_ctx->CreateDisplay(size) && m_ctx->CreateBuffers())
     108        return true;
     109    VERBOSE(VB_IMPORTANT, LOC_ERR + QString("Failed to create VAAPI context."));
     110    errorState = kError_Unknown;
     111    return false;
     112}
     113
     114void VideoOutputOpenGLVAAPI::DeleteVAAPIContext(void)
     115{
     116    delete m_ctx;
     117    m_ctx = NULL;
     118}
     119
     120bool VideoOutputOpenGLVAAPI::CreateBuffers(void)
     121{
     122    if ((!codec_is_vaapi(gl_codec_id)) || !m_ctx)
     123        return VideoOutputOpenGL::CreateBuffers();
     124
     125    QMutexLocker locker(&gl_context_lock);
     126    int num_buffers = m_ctx->GetNumBuffers();
     127    const QSize video_dim = windows[0].GetVideoDim();
     128    vbuffers.Init(num_buffers, true, 2, 1, 4, 1, false); // shouldn't need pause frame
     129
     130    bool ok = true;
     131    for (int i = 0; i < num_buffers; i++)
     132    {
     133        ok &= vbuffers.CreateBuffer(video_dim.width(),
     134                                    video_dim.height(), i,
     135                                    m_ctx->GetVideoSurface(i), FMT_VAAPI);
     136    }
     137    return ok;
     138}
     139
     140void* VideoOutputOpenGLVAAPI::GetVAAPIContext(void)
     141{
     142    if (m_ctx)
     143        return &m_ctx->m_ctx;
     144    return NULL;
     145}
     146
     147uint8_t* VideoOutputOpenGLVAAPI::GetSurfaceIDPointer(void* buf)
     148{
     149    if (m_ctx)
     150        return m_ctx->GetSurfaceIDPointer(buf);
     151    return NULL;
     152}
     153
     154void VideoOutputOpenGLVAAPI::SetProfile(void)
     155{
     156    if (db_vdisp_profile)
     157        db_vdisp_profile->SetVideoRenderer("openglvaapi");
     158}
     159
     160bool VideoOutputOpenGLVAAPI::ApproveDeintFilter(const QString &filtername) const
     161{
     162    return filtername.contains("vaapi");
     163}
     164
     165bool VideoOutputOpenGLVAAPI::SetDeinterlacingEnabled(bool)
     166{
     167    return true;
     168}
     169
     170bool VideoOutputOpenGLVAAPI::SetupDeinterlace(bool i, const QString& ovrf)
     171{
     172    return true;
     173}
     174
     175void VideoOutputOpenGLVAAPI::ProcessFrame(VideoFrame *frame, OSD *osd,
     176                                          FilterChain *filterList,
     177                                          const PIPMap &pipPlayers,
     178                                          FrameScanType scan)
     179{
     180    VideoOutputOpenGL::ProcessFrame(frame, osd, filterList, pipPlayers, scan);
     181
     182    if (codec_is_vaapi(gl_codec_id) && m_ctx && gl_videochain && frame)
     183    {
     184        gl_context->makeCurrent();
     185        uint tex = gl_videochain->GetInputTexture();
     186        gl_context->EnableTextures(tex);
     187        if (m_ctx->CopySurfaceToTexture(frame->buf, tex,
     188                                        gl_videochain->GetTextureType()))
     189        {
     190            gl_videochain->SetInputUpdated();
     191        }
     192        gl_context->doneCurrent();
     193    }
     194}
     195
     196QStringList VideoOutputOpenGLVAAPI::GetAllowedRenderers(
     197    MythCodecID myth_codec_id, const QSize &video_dim)
     198{
     199    (void) video_dim;
     200    QStringList list;
     201    if ((codec_is_std(myth_codec_id) || (codec_is_vaapi(myth_codec_id))) &&
     202         !getenv("NO_VAAPI"))
     203    {
     204        list += "openglvaapi";
     205    }
     206    return list;
     207}
     208
     209MythCodecID VideoOutputOpenGLVAAPI::GetBestSupportedCodec(
     210    uint width,       uint height,
     211    uint stream_type, bool no_acceleration,
     212    PixelFormat &pix_fmt)
     213{
     214    QSize size(width, height);
     215    bool use_cpu = no_acceleration;
     216    VideoDisplayProfile vdp;
     217    vdp.SetInput(size);
     218    QString dec = vdp.GetDecoder();
     219
     220    MythCodecID test_cid = (MythCodecID)(kCodec_MPEG1_VAAPI + (stream_type-1));
     221    use_cpu |= !codec_is_vaapi(test_cid);
     222    use_cpu |= !VAAPIContext::IsFormatAccelerated(size, test_cid, pix_fmt);
     223    if ((dec != "vaapi") || getenv("NO_VAAPI") || use_cpu)
     224        return (MythCodecID)(kCodec_MPEG1 + (stream_type-1));
     225
     226    return test_cid;
     227}
  • 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 40
     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_IMPORTANT, 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 (UNSUPPORTED) ";
     53    if (VAEntrypointIDCT == entry)       return "IDCT (UNSUPPORTED) ";
     54    if (VAEntrypointMoComp == entry)     return "MC (UNSUPPORTED) ";
     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 VAProfileMPEG4AdvancedSimple;
     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
     71class VAAPIDisplay
     72{
     73  public:
     74    VAAPIDisplay() : m_va_disp(NULL), m_x_disp(NULL), m_ref_count(0) { }
     75   ~VAAPIDisplay()
     76    {
     77        if (m_va_disp)
     78        {
     79            INIT_ST
     80            XLOCK(m_x_disp, va_status = vaTerminate(m_va_disp));
     81            CHECK_ST
     82        }
     83        if (m_x_disp)
     84        {
     85            m_x_disp->Sync(true);
     86            delete m_x_disp;
     87        }
     88    }
     89
     90    bool Create(void)
     91    {
     92        m_x_disp = OpenMythXDisplay();
     93        if (!m_x_disp)
     94            return false;
     95
     96        MythXLocker locker(m_x_disp);
     97        int major_ver, minor_ver;
     98        m_va_disp = vaGetDisplayGLX(m_x_disp->GetDisplay());
     99        INIT_ST
     100        va_status = vaInitialize(m_va_disp, &major_ver, &minor_ver);
     101        CHECK_ST
     102
     103        static bool debugged = false;
     104        if (ok && !debugged)
     105        {
     106            debugged = true;
     107            VERBOSE(VB_IMPORTANT, LOC + QString("Version: %1.%2")
     108                                        .arg(major_ver).arg(minor_ver));
     109            VERBOSE(VB_IMPORTANT, LOC + QString("Vendor : %1")
     110                                        .arg(vaQueryVendorString(m_va_disp)));
     111        }
     112        if (ok)
     113            UpRef();
     114        return ok;
     115    }
     116
     117    void UpRef(void)
     118    {
     119        XLOCK(m_x_disp, m_ref_count++)
     120    }
     121
     122    void DownRef(void)
     123    {
     124        m_x_disp->Lock();
     125        m_ref_count--;
     126        if (m_ref_count <= 0)
     127        {
     128            if (gVAAPIDisplay == this)
     129                gVAAPIDisplay = NULL;
     130            m_x_disp->Unlock();
     131            delete this;
     132            return;
     133        }
     134        m_x_disp->Unlock();
     135    }
     136
     137    static VAAPIDisplay* GetDisplay(void)
     138    {
     139        if (gVAAPIDisplay)
     140        {
     141            gVAAPIDisplay->UpRef();
     142            return gVAAPIDisplay;
     143        }
     144
     145        gVAAPIDisplay = new VAAPIDisplay();
     146        if (gVAAPIDisplay && gVAAPIDisplay->Create())
     147            return gVAAPIDisplay;
     148
     149        delete gVAAPIDisplay;
     150        gVAAPIDisplay = NULL;
     151        return NULL;
     152    }
     153
     154    static VAAPIDisplay *gVAAPIDisplay;
     155    void                *m_va_disp;
     156    MythXDisplay        *m_x_disp;
     157    int                  m_ref_count;
     158};
     159
     160VAAPIDisplay* VAAPIDisplay::gVAAPIDisplay = NULL;
     161
     162bool VAAPIContext::IsFormatAccelerated(QSize size, MythCodecID codec,
     163                                       PixelFormat &pix_fmt)
     164{
     165    bool result = false;
     166    VAAPIContext *ctx = new VAAPIContext(codec);
     167    if (ctx)
     168    {
     169        result  = ctx->CreateDisplay(size);
     170        pix_fmt = ctx->GetPixelFormat();
     171    }
     172    delete ctx;
     173    return result;
     174}
     175
     176VAAPIContext::VAAPIContext(MythCodecID codec)
     177  : m_codec(codec),
     178    m_vaProfile(VAProfileMPEG2Main)/* ?? */,
     179    m_vaEntrypoint(VAEntrypointEncSlice),
     180    m_pix_fmt(PIX_FMT_YUV420P), m_numSurfaces(NUM_VAAPI_BUFFERS),
     181    m_surfaces(NULL), m_surfaceData(NULL)
     182{
     183    memset(&m_ctx, 0, sizeof(vaapi_context));
     184}
     185
     186VAAPIContext::~VAAPIContext()
     187{
     188    ClearGLXSurfaces();
     189   
     190    if (m_display)
     191        m_display->m_x_disp->Lock();
     192
     193    INIT_ST
     194    if (m_ctx.context_id)
     195    {
     196        va_status = vaDestroyContext(m_ctx.display, m_ctx.context_id);
     197        CHECK_ST
     198    }
     199    if (m_ctx.config_id)
     200    {
     201        va_status = vaDestroyConfig(m_ctx.display, m_ctx.config_id);
     202        CHECK_ST
     203    }
     204    if (m_surfaces)
     205    {
     206        va_status = vaDestroySurfaces(m_ctx.display, m_surfaces, m_numSurfaces);
     207        CHECK_ST
     208    }
     209
     210    if (m_surfaces)
     211        delete [] m_surfaces;
     212    if (m_surfaceData)
     213        delete [] m_surfaceData;
     214
     215    if (m_display)
     216    {
     217        m_display->m_x_disp->Unlock();
     218        m_display->DownRef();
     219    }
     220
     221    VERBOSE(VB_PLAYBACK, LOC + "Deleted context");
     222}
     223
     224bool VAAPIContext::CreateDisplay(QSize size)\
     225{
     226    m_size = size;
     227    bool ok = true;
     228    m_display = VAAPIDisplay::GetDisplay();
     229    CREATE_CHECK(!m_size.isEmpty(), "Invalid size")
     230    CREATE_CHECK(m_display != NULL, "Invalid display")
     231    CREATE_CHECK(InitDisplay(),     "Invalid VADisplay")
     232    CREATE_CHECK(InitProfiles(),    "No supported profiles")
     233    if (ok)
     234        VERBOSE(VB_PLAYBACK, LOC + QString("Created ctx display (%1x%2->%3x%4)")
     235            .arg(size.width()).arg(size.height())
     236            .arg(m_size.width()).arg(m_size.height()));
     237    return ok;
     238}
     239
     240bool VAAPIContext::CreateBuffers(void)
     241{
     242    bool ok = true;
     243    CREATE_CHECK(!m_size.isEmpty(), "Invalid size")
     244    CREATE_CHECK(InitBuffers(),     "Failed to create buffers.")
     245    CREATE_CHECK(InitContext(),     "Failed to create context")
     246    if (ok)
     247        VERBOSE(VB_PLAYBACK, LOC + "Created buffers");
     248    return ok;
     249}
     250
     251bool VAAPIContext::InitDisplay(void)
     252{
     253    if (!m_display)
     254        return false;
     255    m_ctx.display = m_display->m_va_disp;
     256    return m_ctx.display;
     257}
     258
     259bool VAAPIContext::InitProfiles(void)
     260{
     261    if (!(codec_is_vaapi(m_codec)) || !m_ctx.display)
     262        return false;
     263
     264    MythXLocker locker(m_display->m_x_disp);
     265    int max_profiles, max_entrypoints;
     266    VAProfile profile_wanted = preferredProfile(m_codec);
     267    VAProfile profile_found  = VAProfileMPEG2Main;   // FIXME
     268    VAEntrypoint entry_found = VAEntrypointEncSlice; // unsupported value
     269
     270    max_profiles          = vaMaxNumProfiles(m_ctx.display);
     271    max_entrypoints       = vaMaxNumEntrypoints(m_ctx.display);
     272    VAProfile *profiles   = new VAProfile[max_profiles];
     273    VAEntrypoint *entries = new VAEntrypoint[max_entrypoints];
     274
     275    static bool debugged = false;
     276    if (profiles && entries)
     277    {
     278        INIT_ST
     279        int act_profiles, act_entries;
     280        va_status = vaQueryConfigProfiles(m_ctx.display,
     281                                          profiles,
     282                                         &act_profiles);
     283        CHECK_ST
     284        if (ok && act_profiles > 0)
     285        {
     286            for (int i = 0; i < act_profiles; i++)
     287            {
     288                va_status = vaQueryConfigEntrypoints(m_ctx.display,
     289                                                     profiles[i],
     290                                                     entries,
     291                                                    &act_entries);
     292                if (va_status == VA_STATUS_SUCCESS && act_entries > 0)
     293                {
     294                    if (profiles[i] == profile_wanted)
     295                    {
     296                        profile_found = profile_wanted;
     297                        for (int j = 0; j < act_entries; j++)
     298                            if (entries[j] < entry_found)
     299                                entry_found = entries[j];
     300                    }
     301
     302                    if (!debugged)
     303                    {
     304                        QString entrylist = "Entrypoints: ";
     305                        for (int j = 0; j < act_entries; j++)
     306                            entrylist += entryToString(entries[j]);
     307                        VERBOSE(VB_IMPORTANT, LOC + QString("Profile: %1 %2")
     308                            .arg(profileToString(profiles[i])).arg(entrylist));
     309                    }
     310                }
     311            }
     312        }
     313        debugged = true;
     314    }
     315    delete profiles;
     316    delete entries;
     317
     318    VERBOSE(VB_PLAYBACK, LOC + QString("Desired profile for '%1': %2")
     319        .arg(toString(m_codec)).arg(profileToString(profile_wanted)));
     320    VERBOSE(VB_PLAYBACK, LOC + QString("Found profile %1 with entry %2")
     321        .arg(profileToString(profile_found)).arg(entryToString(entry_found)));
     322
     323    if (profile_wanted != profile_found)
     324    {
     325        VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to find supported profile.");
     326        return false;
     327    }
     328
     329    if (entry_found > VAEntrypointVLD)
     330    {
     331        VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to find suitable entry point.");
     332        return false;
     333    }
     334
     335    m_vaProfile = profile_wanted;
     336    m_vaEntrypoint = entry_found;
     337    if (VAEntrypointVLD == m_vaEntrypoint)
     338        m_pix_fmt = PIX_FMT_VAAPI_VLD;
     339    return true;
     340}
     341
     342bool VAAPIContext::InitBuffers(void)
     343{
     344    if (!m_ctx.display)
     345        return false;
     346       
     347    MythXLocker locker(m_display->m_x_disp);
     348    m_surfaces    = new VASurfaceID[m_numSurfaces];
     349    m_surfaceData = new vaapi_surface[m_numSurfaces];
     350
     351    if (!m_surfaces || !m_surfaceData)
     352        return false;
     353
     354    INIT_ST
     355    va_status = vaCreateSurfaces(m_ctx.display, m_size.width(), m_size.height(),
     356                                 VA_RT_FORMAT_YUV420, m_numSurfaces,
     357                                 m_surfaces);
     358    CHECK_ST
     359
     360    for (int i = 0; i < m_numSurfaces; i++)
     361        m_surfaceData[i].m_id = m_surfaces[i];
     362    return ok;
     363}
     364
     365bool VAAPIContext::InitContext(void)
     366{
     367    if (!m_ctx.display || m_vaEntrypoint > VAEntrypointVLD)
     368        return false;
     369
     370    MythXLocker locker(m_display->m_x_disp);
     371    VAConfigAttrib attrib;
     372    attrib.type = VAConfigAttribRTFormat;
     373    INIT_ST
     374    va_status = vaGetConfigAttributes(m_ctx.display, m_vaProfile,
     375                                      m_vaEntrypoint, &attrib, 1);
     376    CHECK_ST
     377
     378    if (!ok || !(attrib.value & VA_RT_FORMAT_YUV420))
     379    {
     380        VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to confirm YUV420 chroma");
     381        return false;
     382    }
     383
     384    va_status = vaCreateConfig(m_ctx.display, m_vaProfile, m_vaEntrypoint,
     385                               &attrib, 1, &m_ctx.config_id);
     386    CHECK_ST
     387    if (!ok)
     388    {
     389        VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to create decoder config.");
     390        return false;
     391    }
     392
     393    va_status = vaCreateContext(m_ctx.display, m_ctx.config_id,
     394                                m_size.width(), m_size.height(), VA_PROGRESSIVE,
     395                                m_surfaces, m_numSurfaces,
     396                                &m_ctx.context_id);
     397    CHECK_ST
     398    if (!ok)
     399    {
     400        VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to create decoder context.");
     401        return false;
     402    }
     403    return true;
     404}
     405
     406void* VAAPIContext::GetVideoSurface(int i)
     407{
     408    if (i < 0 || i >= m_numSurfaces)
     409        return NULL;
     410    return &m_surfaceData[i];
     411}
     412
     413uint8_t* VAAPIContext::GetSurfaceIDPointer(void* buf)
     414{
     415    if (!buf)
     416        return NULL;
     417    const vaapi_surface *surf = (vaapi_surface*)buf;
     418//    VASurfaceStatus status;
     419//    INIT_ST
     420//    va_status = vaQuerySurfaceStatus(m_ctx.display, surf->m_id, &status);
     421//    CHECK_ST
     422//    VERBOSE(VB_IMPORTANT, LOC + QString("Returning VASurfaceID: %1 status %2").arg(surf->m_id).arg(status));
     423//    va_status = vaSyncSurface(m_ctx.display, surf->m_id);
     424//    CHECK_ST
     425    return (uint8_t*)(uintptr_t)surf->m_id;
     426}
     427
     428bool VAAPIContext::CopySurfaceToTexture(const void* buf, uint texture,
     429                                        uint texture_type)
     430{
     431    if (!buf || !texture)
     432        return false;
     433    void* glx_surface = GetGLXSurface(texture, texture_type);
     434    if (!glx_surface)
     435        return false;
     436    const vaapi_surface *surf = (vaapi_surface*)buf;
     437    INIT_ST
     438    XLOCK(m_display->m_x_disp,
     439          va_status = vaCopySurfaceGLX(m_ctx.display, glx_surface,
     440                                       surf->m_id, 0));
     441    CHECK_ST
     442    return ok;
     443}
     444
     445void* VAAPIContext::GetGLXSurface(uint texture, uint texture_type)
     446{
     447    if (m_glxSurfaces.contains(texture))
     448        return m_glxSurfaces.value(texture);
     449
     450    void *glx_surface = NULL;
     451    INIT_ST
     452    XLOCK(m_display->m_x_disp,
     453          va_status = vaCreateSurfaceGLX(m_ctx.display, texture_type,
     454                                         texture, &glx_surface));
     455    CHECK_ST
     456    m_glxSurfaces.insert(texture, glx_surface);
     457
     458    VERBOSE(VB_PLAYBACK, QString("Number of VAAPI GLX surfaces: %1")
     459        .arg(m_glxSurfaces.size()));
     460    return glx_surface;
     461}
     462
     463void VAAPIContext::ClearGLXSurfaces(void)
     464{
     465    if (!m_display)
     466        return;
     467
     468    m_display->m_x_disp->Lock();
     469    INIT_ST
     470    foreach (void* surface, m_glxSurfaces)
     471    {
     472        va_status = vaDestroySurfaceGLX(m_ctx.display, surface);
     473        CHECK_ST
     474    }
     475    m_glxSurfaces.clear();
     476    m_display->m_x_disp->Unlock();
     477}
  • 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) { }
     
    3738                                           const QSize &video_dim);
    3839    void EmbedInWidget(int x, int y, int w, int h);
    3940    void StopEmbedding(void);
    40     bool SetDeinterlacingEnabled(bool);
    41     bool SetupDeinterlace(bool i, const QString& ovrf="");
     41    virtual bool SetDeinterlacingEnabled(bool);
     42    virtual bool SetupDeinterlace(bool i, const QString& ovrf="");
    4243    void ShowPIP(VideoFrame        *frame,
    4344                 NuppelVideoPlayer *pipplayer,
    4445                 PIPLocation        loc);
     
    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
  • libs/libmythtv/mythcodecid.h

     
    129129#define CODEC_IS_DVDV(codec) (codec && (codec->id == CODEC_ID_MPEG2VIDEO_DVDV))
    130130#define CODEC_IS_VDPAU(codec) (codec &&\
    131131                               codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
    132 #define CODEC_IS_HWACCEL(codec)  (CODEC_IS_XVMC(codec)  ||\
    133                                   CODEC_IS_VDPAU(codec) ||\
    134                                   CODEC_IS_DVDV(codec))
     132#define CODEC_IS_VAAPI(codec, enc) (codec && IS_VAAPI_PIX_FMT(enc->pix_fmt))
     133#define CODEC_IS_HWACCEL(codec, enc) (CODEC_IS_XVMC(codec)  ||\
     134                                      CODEC_IS_VDPAU(codec) ||\
     135                                      CODEC_IS_DVDV(codec)  ||\
     136                                      CODEC_IS_VAAPI(codec, enc))
    135137
    136138#endif // _MYTH_CODEC_ID_H_
  • 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);
     
    378395 */
    379396VideoOutput::~VideoOutput()
    380397{
     398    VERBOSE(VB_IMPORTANT, LOC + "dtor start");
    381399    if (osd_image)
    382400        osd_image->DownRef();
    383401    if (osd_painter)
     
    397415    ResizeForGui();
    398416    if (display_res)
    399417        display_res->Unlock();
     418    VERBOSE(VB_IMPORTANT, LOC + "dtor end");
    400419}
    401420
    402421/**
  • libs/libmythtv/vaapicontext.h

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