Ticket #8593: vaapi_v7.diff

File vaapi_v7.diff, 48.9 KB (added by markk, 10 years ago)
  • home/mark/trunk/mythtv/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  --enable-crystalhd       enable Broadcom CrystalHD hardware decoder support
    132133  --disable-opengl-video   disable OpenGL based video display
    133134  --disable-quartz-video   disable Mac OS X CoreVideo based video display
     
    13471348    mythtranscode
    13481349    opengl
    13491350    vdpau
     1351    vaapi
    13501352'
    13511353
    13521354CMDLINE_SELECT="
     
    17091711xvmc_deps="xv X11_extensions_XvMClib_h"
    17101712xvmc_vld_deps="xvmc X11_extensions_vldXvMC_h"
    17111713xvmcw_deps="xvmc"
     1714vaapi_deps="x11 opengl_video"
    17121715
    17131716<<BLOCKQUOTE
    17141717# tests
     
    35413544check_header termios.h
    35423545check_header vdpau/vdpau.h
    35433546check_header vdpau/vdpau_x11.h
     3547check_header va/va.h
     3548check_header va/va_glx.h
    35443549check_header X11/extensions/XvMClib.h
    35453550
    35463551check_struct dxva2api.h DXVA_PictureParameters wDecodedPictureIndex
     
    38193824        disable crystalhd;
    38203825fi
    38213826
     3827if enabled vaapi; then
     3828    enabled va_va_h && enabled va_va_glx_h || disable vaapi
     3829    if enabled vaapi; then
     3830        # for XvBA/VDPAU backends we need splitted desktop 0.31.0 but
     3831        # for upstream GLX support we need 0.31.1 ???
     3832        check_cpp_condition va/va.h "VA_VERSION_HEX >= 0x001F0000" ||
     3833        { echolog "VAAPI requires libva >= 0.31.1" && disable vaapi; }
     3834    fi
     3835else
     3836    disable vaapi
     3837fi
     3838
    38223839enabled debug && add_cflags -g"$debuglevel" && add_asflags -g"$debuglevel"
    38233840enabled debug && add_cxxflags -g"$debuglevel"
    38243841
     
    43764393  echo "XvMC libs                 $VENDOR_XVMC_LIBS"
    43774394fi
    43784395  echo "VDPAU support             ${vdpau-no}"
     4396  echo "VAAPI support             ${vaapi-no}"
    43794397  echo "CrystalHD support         ${crystalhd-no}"
    43804398fi
    43814399  echo "OpenGL video              ${opengl_video-no}"
  • home/mark/trunk/mythtv/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();
     13   ~VideoOutputOpenGLVAAPI();
     14
     15    bool  Init(int width, int height, float aspect, WId winid,
     16               int winx, int winy, int winw, int winh,
     17               MythCodecID codec_id, WId embedid = 0);
     18    bool  CreateVAAPIContext(QSize size);
     19    void  DeleteVAAPIContext(void);
     20    bool  CreateBuffers(void);
     21    void* GetVAAPIContext(void);
     22    uint8_t* GetSurfaceIDPointer(void* buf);
     23    void  SetProfile(void);
     24    void  TearDown(void);
     25    bool  InputChanged(const QSize &input_size, float aspect,
     26                       MythCodecID  av_codec_id, void *codec_private,
     27                       bool &aspect_only);
     28    void  ProcessFrame(VideoFrame *frame, OSD *osd,
     29                       FilterChain *filterList,
     30                       const PIPMap &pipPlayers,
     31                       FrameScanType scan);
     32    bool  ApproveDeintFilter(const QString& filtername) const;
     33    bool  SetDeinterlacingEnabled(bool);
     34    bool  SetupDeinterlace(bool i, const QString& ovrf="");
     35   
     36    static QStringList GetAllowedRenderers(MythCodecID myth_codec_id,
     37                                           const QSize &video_dim);
     38    static MythCodecID GetBestSupportedCodec(uint width, uint height,
     39                                             uint stream_type,
     40                                             bool no_acceleration,
     41                                             PixelFormat &pix_fmt);
     42
     43  private:
     44    VAAPIContext *m_ctx;
     45};
     46
     47#endif // VIDEOOUTPUTOPENGLVAAPI_H
     48
  • home/mark/trunk/mythtv/libs/libmythtv/videoout_opengl.cpp

     
    77#include "osd.h"
    88#include "mythuihelper.h"
    99
    10 #define LOC      QString("VidOutOGL: ")
    11 #define LOC_ERR  QString("VidOutOGL: ")
     10#define LOC      QString("VidOutGL: ")
     11#define LOC_ERR  QString("VidOutGL Error: ")
    1212
    1313void VideoOutputOpenGL::GetRenderOptions(render_opts &opts,
    1414                                         QStringList &cpudeints)
     
    125125                      winid, winx, winy, winw, winh,
    126126                      codec_id, embedid);
    127127
    128     if (db_vdisp_profile)
    129         db_vdisp_profile->SetVideoRenderer("opengl");
     128    SetProfile();
    130129
    131130    success &= SetupContext();
    132131    InitDisplayMeasurements(width, height, false);
    133132    success &= CreateBuffers();
     133    success &= CreatePauseFrame();
    134134    success &= SetupOpenGL();
    135135
    136136    InitOSD();
     
    146146    return success;
    147147}
    148148
     149void VideoOutputOpenGL::SetProfile(void)
     150{
     151    if (db_vdisp_profile)
     152        db_vdisp_profile->SetVideoRenderer("opengl");
     153}
     154
    149155bool VideoOutputOpenGL::InputChanged(const QSize &input_size,
    150156                                     float        aspect,
    151157                                     MythCodecID  av_codec_id,
    152158                                     void        *codec_private,
    153159                                     bool        &aspect_only)
    154160{
    155     VERBOSE(VB_PLAYBACK, LOC + QString("InputChanged(%1,%2,%3) %4")
     161    VERBOSE(VB_PLAYBACK, LOC + QString("InputChanged(%1,%2,%3) %4->%5")
    156162            .arg(input_size.width()).arg(input_size.height()).arg(aspect)
    157             .arg(toString(av_codec_id)));
     163            .arg(toString(video_codec_id)).arg(toString(av_codec_id)));
    158164
    159165    QMutexLocker locker(&gl_context_lock);
    160 
    161166    if (!codec_is_std(av_codec_id))
    162167    {
    163168        VERBOSE(VB_IMPORTANT, LOC_ERR +
     
    244249                                  window.GetVideoDim(), dvr,
    245250                                  window.GetDisplayVideoRect(),
    246251                                  window.GetVideoRect(), true,
    247                                   GetFilters(), db_letterbox_colour);
     252                                  GetFilters(), !codec_is_std(video_codec_id),
     253                                  db_letterbox_colour);
    248254    if (success)
    249255    {
    250256        bool temp_deinterlacing = m_deinterlacing;
     
    278284bool VideoOutputOpenGL::CreateBuffers(void)
    279285{
    280286    QMutexLocker locker(&gl_context_lock);
    281 
    282     bool success = true;
    283287    vbuffers.Init(31, true, 1, 12, 4, 2, false);
    284     success &= vbuffers.CreateBuffers(window.GetVideoDim().width(),
    285                                       window.GetVideoDim().height());
     288    return vbuffers.CreateBuffers(window.GetVideoDim().width(),
     289                                  window.GetVideoDim().height());
     290}
    286291
     292bool VideoOutputOpenGL::CreatePauseFrame(void)
     293{
    287294    av_pause_frame.height = vbuffers.GetScratchFrame()->height;
    288295    av_pause_frame.width  = vbuffers.GetScratchFrame()->width;
    289296    av_pause_frame.bpp    = vbuffers.GetScratchFrame()->bpp;
     
    292299    av_pause_frame.frameNumber = vbuffers.GetScratchFrame()->frameNumber;
    293300
    294301    if (!av_pause_frame.buf)
    295         success = false;
    296     else
    297         clear(&av_pause_frame, GUID_YV12_PLANAR);
     302        return false;
    298303
    299     return success;
     304    clear(&av_pause_frame, GUID_YV12_PLANAR);
     305    return true;
    300306}
    301307
    302308void VideoOutputOpenGL::ProcessFrame(VideoFrame *frame, OSD *osd,
     
    308314    if (!gl_videochain || !gl_context)
    309315        return;
    310316
     317    bool sw_frame = codec_is_std(video_codec_id);
    311318    bool deint_proc = m_deinterlacing && (m_deintFilter != NULL);
    312319    OpenGLLocker ctx_lock(gl_context);
    313320
     
    319326        pauseframe = true;
    320327    }
    321328
    322     if (filterList)
     329    if (filterList && sw_frame)
    323330        filterList->ProcessFrame(frame);
    324331
    325332    bool safepauseframe = pauseframe && !IsBobDeint();
    326     if (deint_proc && m_deinterlaceBeforeOSD &&
     333    if (sw_frame && deint_proc && m_deinterlaceBeforeOSD &&
    327334       (!pauseframe || safepauseframe))
    328335    {
    329336        m_deintFilter->ProcessFrame(frame, scan);
     
    335342        ShowPIPs(frame, pipPlayers);
    336343    }
    337344
    338     if ((!pauseframe || safepauseframe) &&
     345    if (sw_frame && (!pauseframe || safepauseframe) &&
    339346        deint_proc && !m_deinterlaceBeforeOSD)
    340347    {
    341348        m_deintFilter->ProcessFrame(frame, scan);
     
    343350
    344351    bool soft_bob = m_deinterlacing && (m_deintfiltername == "bobdeint");
    345352
    346     if (gl_videochain)
     353    if (gl_videochain && sw_frame)
    347354        gl_videochain->UpdateInputFrame(frame, soft_bob);
    348355}
    349356
     
    632639                     QSize(pipVideoWidth, pipVideoHeight),
    633640                     dvr, position,
    634641                     QRect(0, 0, pipVideoWidth, pipVideoHeight),
    635                      false, GetFilters());
     642                     false, GetFilters(), false);
    636643        gl_pipchain->SetMasterViewport(gl_videochain->GetViewPort());
    637644        if (!success)
    638645        {
     
    653660            QSize(pipVideoWidth, pipVideoHeight),
    654661            dvr, position,
    655662            QRect(0, 0, pipVideoWidth, pipVideoHeight),
    656             false, GetFilters());
     663            false, GetFilters(), false);
    657664
    658665        gl_pipchain->SetMasterViewport(gl_videochain->GetViewPort());
    659666        if (!success)
  • home/mark/trunk/mythtv/libs/libmythtv/avformatdecoder.cpp

     
    5252}
    5353#endif // USING_VDPAU
    5454
     55#ifdef USING_VAAPI
     56#include "videoout_openglvaapi.h"
     57#endif // USING_VAAPI
     58
    5559extern "C" {
    5660#include "libavutil/avutil.h"
    5761#include "libavcodec/ac3_parser.h"
     
    126130void render_slice_vdpau(struct AVCodecContext *s, const AVFrame *src,
    127131                        int offset[4], int y, int type, int height);
    128132
     133int  get_avf_buffer_vaapi(struct AVCodecContext *c, AVFrame *pic);
     134
    129135static AVCodec *find_vdpau_decoder(AVCodec *c, enum CodecID id)
    130136{
    131137    AVCodec *codec = c;
     
    238244    (*opts.equiv_decoders)["vdpau"].append("dummy");
    239245#endif
    240246
     247#ifdef USING_VAAPI
     248    opts.decoders->append("vaapi");
     249    (*opts.equiv_decoders)["vaapi"].append("dummy");
     250#endif
     251
    241252    PrivateDecoder::GetDecoders(opts);
    242253}
    243254
     
    11541165    return fmt[i];
    11551166}
    11561167
     1168static bool IS_VAAPI_PIX_FMT(enum PixelFormat fmt)
     1169{
     1170    return fmt == PIX_FMT_VAAPI_MOCO ||
     1171           fmt == PIX_FMT_VAAPI_IDCT ||
     1172           fmt == PIX_FMT_VAAPI_VLD;
     1173}
     1174
     1175static enum PixelFormat get_format_vaapi(struct AVCodecContext *avctx,
     1176                                         const enum PixelFormat *fmt)
     1177{
     1178    if (!fmt)
     1179        return PIX_FMT_NONE;
     1180    int i = 0;
     1181    for (; fmt[i] != PIX_FMT_NONE ; i++)
     1182        if (IS_VAAPI_PIX_FMT(fmt[i]))
     1183            break;
     1184    return fmt[i];
     1185}
     1186
    11571187static bool IS_DR1_PIX_FMT(const enum PixelFormat fmt)
    11581188{
    11591189    switch (fmt)
     
    12011231    {
    12021232        directrendering = true;
    12031233        if (!gCoreContext->GetNumSetting("DecodeExtraAudio", 0) &&
    1204             !CODEC_IS_HWACCEL(codec))
     1234            !CODEC_IS_HWACCEL(codec, enc))
    12051235        {
    12061236            SetLowBuffers(false);
    12071237        }
     
    12251255        enc->draw_horiz_band = render_slice_vdpau;
    12261256        enc->slice_flags     = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD;
    12271257    }
     1258    else if (CODEC_IS_VAAPI(codec, enc))
     1259    {
     1260        enc->get_buffer      = get_avf_buffer_vaapi;
     1261        enc->get_format      = get_format_vaapi;
     1262        enc->release_buffer  = release_avf_buffer;
     1263        enc->slice_flags     = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD;
     1264    }
    12281265    else if (codec && codec->capabilities & CODEC_CAP_DR1)
    12291266    {
    12301267        enc->flags          |= CODEC_FLAG_EMU_EDGE;
     
    17701807                        handled = true;
    17711808                    }
    17721809#endif // USING_VDPAU
     1810#ifdef USING_VAAPI
     1811                    MythCodecID vaapi_mcid;
     1812                    PixelFormat pix_fmt = PIX_FMT_YUV420P;
     1813                    vaapi_mcid = VideoOutputOpenGLVAAPI::GetBestSupportedCodec(
     1814                        width, height, mpeg_version(enc->codec_id),
     1815                        no_hardware_decoders, pix_fmt);
     1816
     1817                    if (vaapi_mcid >= video_codec_id)
     1818                    {
     1819                        enc->codec_id = (CodecID)myth2av_codecid(vaapi_mcid);
     1820                        video_codec_id = vaapi_mcid;
     1821                        handled = true;
     1822                        if (!no_hardware_decoders &&
     1823                            codec_is_vaapi(video_codec_id))
     1824                        {
     1825                            enc->pix_fmt = pix_fmt;
     1826                        }
     1827                    }
     1828#endif // USING_VAAPI
    17731829#ifdef USING_XVMC
    17741830
    17751831                    bool force_xv = no_hardware_decoders;
     
    24842540    }
    24852541}
    24862542
     2543int get_avf_buffer_vaapi(struct AVCodecContext *c, AVFrame *pic)
     2544{
     2545    AvFormatDecoder *nd = (AvFormatDecoder *)(c->opaque);
     2546    VideoFrame *frame = nd->GetPlayer()->GetNextVideoFrame(false);
     2547
     2548    pic->data[0]     = frame->buf;
     2549    pic->data[1]     = NULL;
     2550    pic->data[2]     = NULL;
     2551    pic->data[3]     = NULL;
     2552    pic->linesize[0] = 0;
     2553    pic->linesize[1] = 0;
     2554    pic->linesize[2] = 0;
     2555    pic->linesize[3] = 0;
     2556    pic->opaque      = frame;
     2557    pic->type        = FF_BUFFER_TYPE_USER;
     2558    pic->age         = 256 * 256 * 256 * 64;
     2559    frame->pix_fmt   = c->pix_fmt;
     2560
     2561#ifdef USING_VAAPI
     2562    if (nd->GetPlayer()->getVideoOutput())
     2563    {
     2564        VideoOutputOpenGLVAAPI *vo =
     2565            dynamic_cast<VideoOutputOpenGLVAAPI*>(nd->GetPlayer()->getVideoOutput());
     2566        c->hwaccel_context = (vaapi_context*)vo->GetVAAPIContext();
     2567        pic->data[3] = vo->GetSurfaceIDPointer(frame->buf);
     2568    }
     2569#endif
     2570
     2571    return 0;
     2572}
     2573
    24872574void AvFormatDecoder::DecodeDTVCC(const uint8_t *buf, uint len)
    24882575{
    24892576    if (!len)
     
    33623449    QStringList list  = text.split('\n', QString::SkipEmptyParts);
    33633450    delete dec;
    33643451    subReader->AddRawTextSubtitle(list, pkt->convergence_duration);
     3452    return true;
    33653453}
    33663454
    33673455bool AvFormatDecoder::ProcessDataPacket(AVStream *curstream, AVPacket *pkt,
  • home/mark/trunk/mythtv/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()
     27  : VideoOutputOpenGL(), 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(video_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 = (video_codec_id != av_codec_id);
     57    bool res_changed = input_size  != window.GetVideoDim();
     58    bool asp_changed = aspect      != window.GetVideoAspect();
     59   
     60    if (!res_changed && !cid_changed)
     61    {
     62        if (asp_changed)
     63        {
     64            aspect_only = true;
     65            VideoAspectRatioChanged(aspect);
     66            MoveResize();
     67        }
     68        return true;
     69    }
     70
     71    TearDown();
     72    QRect disp = window.GetDisplayVisibleRect();
     73    if (Init(input_size.width(), input_size.height(),
     74             aspect, gl_parent_win, disp.left(),  disp.top(),
     75             disp.width(), disp.height(), av_codec_id, gl_embed_win))
     76    {
     77        BestDeint();
     78        return true;
     79    }
     80
     81    VERBOSE(VB_IMPORTANT, LOC_ERR +
     82        QString("Failed to re-initialise video output."));
     83    errorState = kError_Unknown;
     84
     85    return false;
     86}
     87
     88bool VideoOutputOpenGLVAAPI::Init(int width, int height, float aspect,
     89                                  WId winid, int winx, int winy, int winw,
     90                                  int winh, MythCodecID codec_id, WId embedid)
     91{
     92    if (codec_is_vaapi(codec_id))
     93    {
     94        video_codec_id = codec_id;
     95        if (!CreateVAAPIContext(QSize(width, height)))
     96            return false;
     97    }
     98
     99    return VideoOutputOpenGL::Init(width, height, aspect, winid, winx, winy,
     100                                   winw, winh, video_codec_id, embedid);
     101}
     102
     103bool VideoOutputOpenGLVAAPI::CreateVAAPIContext(QSize size)
     104{
     105    if (m_ctx)
     106        DeleteVAAPIContext();
     107    m_ctx = new VAAPIContext(video_codec_id);
     108    if (m_ctx && m_ctx->CreateDisplay(size) && m_ctx->CreateBuffers())
     109        return true;
     110    VERBOSE(VB_IMPORTANT, LOC_ERR + QString("Failed to create VAAPI context."));
     111    errorState = kError_Unknown;
     112    return false;
     113}
     114
     115void VideoOutputOpenGLVAAPI::DeleteVAAPIContext(void)
     116{
     117    delete m_ctx;
     118    m_ctx = NULL;
     119}
     120
     121bool VideoOutputOpenGLVAAPI::CreateBuffers(void)
     122{
     123    if ((!codec_is_vaapi(video_codec_id)) || !m_ctx)
     124        return VideoOutputOpenGL::CreateBuffers();
     125
     126    QMutexLocker locker(&gl_context_lock);
     127    int num_buffers = m_ctx->GetNumBuffers();
     128    const QSize video_dim = window.GetVideoDim();
     129    vbuffers.Init(num_buffers, true, 2, 1, 4, 1, false); // shouldn't need pause frame
     130
     131    bool ok = true;
     132    for (int i = 0; i < num_buffers; i++)
     133    {
     134        ok &= vbuffers.CreateBuffer(video_dim.width(),
     135                                    video_dim.height(), i,
     136                                    m_ctx->GetVideoSurface(i), FMT_VAAPI);
     137    }
     138    return ok;
     139}
     140
     141void* VideoOutputOpenGLVAAPI::GetVAAPIContext(void)
     142{
     143    if (m_ctx)
     144        return &m_ctx->m_ctx;
     145    return NULL;
     146}
     147
     148uint8_t* VideoOutputOpenGLVAAPI::GetSurfaceIDPointer(void* buf)
     149{
     150    if (m_ctx)
     151        return m_ctx->GetSurfaceIDPointer(buf);
     152    return NULL;
     153}
     154
     155void VideoOutputOpenGLVAAPI::SetProfile(void)
     156{
     157    if (db_vdisp_profile)
     158        db_vdisp_profile->SetVideoRenderer("openglvaapi");
     159}
     160
     161bool VideoOutputOpenGLVAAPI::ApproveDeintFilter(const QString &filtername) const
     162{
     163    return filtername.contains("vaapi");
     164}
     165
     166bool VideoOutputOpenGLVAAPI::SetDeinterlacingEnabled(bool)
     167{
     168    return true;
     169}
     170
     171bool VideoOutputOpenGLVAAPI::SetupDeinterlace(bool i, const QString& ovrf)
     172{
     173    return true;
     174}
     175
     176void VideoOutputOpenGLVAAPI::ProcessFrame(VideoFrame *frame, OSD *osd,
     177                                          FilterChain *filterList,
     178                                          const PIPMap &pipPlayers,
     179                                          FrameScanType scan)
     180{
     181    VideoOutputOpenGL::ProcessFrame(frame, osd, filterList, pipPlayers, scan);
     182
     183    if (codec_is_vaapi(video_codec_id) && m_ctx && gl_videochain && frame)
     184    {
     185        gl_context->makeCurrent();
     186        uint tex = gl_videochain->GetInputTexture();
     187        gl_context->EnableTextures(tex);
     188        if (m_ctx->CopySurfaceToTexture(frame->buf, tex,
     189                                        gl_videochain->GetTextureType()))
     190        {
     191            gl_videochain->SetInputUpdated();
     192        }
     193        gl_context->doneCurrent();
     194    }
     195}
     196
     197QStringList VideoOutputOpenGLVAAPI::GetAllowedRenderers(
     198    MythCodecID myth_codec_id, const QSize &video_dim)
     199{
     200    (void) video_dim;
     201    QStringList list;
     202    if ((codec_is_std(myth_codec_id) || (codec_is_vaapi(myth_codec_id))) &&
     203         !getenv("NO_VAAPI"))
     204    {
     205        list += "openglvaapi";
     206    }
     207    return list;
     208}
     209
     210MythCodecID VideoOutputOpenGLVAAPI::GetBestSupportedCodec(
     211    uint width,       uint height,
     212    uint stream_type, bool no_acceleration,
     213    PixelFormat &pix_fmt)
     214{
     215    QSize size(width, height);
     216    bool use_cpu = no_acceleration;
     217    VideoDisplayProfile vdp;
     218    vdp.SetInput(size);
     219    QString dec = vdp.GetDecoder();
     220
     221    MythCodecID test_cid = (MythCodecID)(kCodec_MPEG1_VAAPI + (stream_type-1));
     222    use_cpu |= !codec_is_vaapi(test_cid);
     223    use_cpu |= !VAAPIContext::IsFormatAccelerated(size, test_cid, pix_fmt);
     224    if ((dec != "vaapi") || getenv("NO_VAAPI") || use_cpu)
     225        return (MythCodecID)(kCodec_MPEG1 + (stream_type-1));
     226
     227    return test_cid;
     228}
  • home/mark/trunk/mythtv/libs/libmythtv/libmythtv.pro

     
    352352    using_opengl_video:HEADERS += openglvideo.h   videoout_opengl.h
    353353    using_opengl_video:SOURCES += openglvideo.cpp videoout_opengl.cpp
    354354
     355    using_vaapi: DEFINES += USING_VAAPI
     356    using_vaapi: DEFINES += videoout_openglvaapi.h   vaapicontext.h
     357    using_vaapi: SOURCES += videoout_openglvaapi.cpp vaapicontext.cpp
     358    using_vaapi: LIBS    += -lva -lva-glx
     359
    355360    # Misc. frontend
    356361    HEADERS += DetectLetterbox.h
    357362    SOURCES += DetectLetterbox.cpp
  • home/mark/trunk/mythtv/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}
  • home/mark/trunk/mythtv/libs/libmythtv/videoout_opengl.h

     
    1111  public:
    1212    static void GetRenderOptions(render_opts &opts, QStringList &cpudeints);
    1313    VideoOutputOpenGL();
    14    ~VideoOutputOpenGL();
     14    virtual ~VideoOutputOpenGL();
    1515
    16     bool Init(int width, int height, float aspect, WId winid,
    17               int winx, int winy, int winw, int winh,
    18               MythCodecID codec_id, WId embedid = 0);
    19     void TearDown(void);
     16    virtual bool Init(int width, int height, float aspect, WId winid,
     17                      int winx, int winy, int winw, int winh,
     18                      MythCodecID codec_id, WId embedid = 0);
     19    virtual void SetProfile(void);
     20    virtual void TearDown(void);
    2021
    2122    void PrepareFrame(VideoFrame *buffer, FrameScanType, OSD *osd);
    22     void ProcessFrame(VideoFrame *frame, OSD *osd,
    23                       FilterChain *filterList,
    24                       const PIPMap &pipPlayers,
    25                       FrameScanType scan);
    26     void Show(FrameScanType );
    27     bool InputChanged(const QSize &input_size, float aspect,
    28                       MythCodecID  av_codec_id, void *codec_private,
    29                       bool &aspect_only);
     23    virtual void ProcessFrame(VideoFrame *frame, OSD *osd,
     24                              FilterChain *filterList,
     25                              const PIPMap &pipPlayers,
     26                              FrameScanType scan);
     27    virtual void Show(FrameScanType );
     28    virtual bool InputChanged(const QSize &input_size, float aspect,
     29                              MythCodecID  av_codec_id, void *codec_private,
     30                              bool &aspect_only);
    3031    void UpdatePauseFrame(void);
    3132    void DrawUnusedRects(bool) { }
    3233    void Zoom(ZoomDirection direction);
     
    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                 MythPlayer  *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);
  • home/mark/trunk/mythtv/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__
  • home/mark/trunk/mythtv/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 & kGLMesaYCbCr);
     184    using_ycbcrtex      = !using_hardwaretex && !full_features &&
     185                          (gl_features & kGLMesaYCbCr);
    182186
    183187    if (using_ycbcrtex)
    184188        basic_features = false;
     
    192196                QString("No OpenGL feature support for Bicubic filter."));
    193197    }
    194198
    195     if ((defaultUpsize != kGLFilterBicubic) && (gl_features & kGLExtRect))
     199    if (!using_hardwaretex &&
     200        (defaultUpsize != kGLFilterBicubic) && (gl_features & kGLExtRect))
    196201        textureType = gl_context->GetTextureType(textureRects);
    197202
    198203    GLuint tex = 0;
    199204    bool    ok = false;
    200205
    201     if (basic_features)
     206    if (basic_features && !using_hardwaretex)
    202207    {
    203208        tex = CreateVideoTexture(actual_video_dim, inputTextureSize, use_pbo);
    204209        ok = tex && AddFilter(kGLFilterYUV2RGB);
    205210    }
    206     else if (using_ycbcrtex)
     211    else if (using_ycbcrtex || using_hardwaretex)
    207212    {
    208213        tex = CreateVideoTexture(actual_video_dim,
    209214                                 inputTextureSize, use_pbo);
    210215        ok = tex && AddFilter(kGLFilterResize);
    211         if (ok)
     216        if (ok && using_ycbcrtex)
    212217            VERBOSE(VB_PLAYBACK, LOC + QString("Using GL_MESA_ycbcr_texture for"
    213218                                               " colorspace conversion."));
     219        else if (ok && using_hardwaretex)
     220            VERBOSE(VB_PLAYBACK, LOC + QString("Using plain RGBA tex for hw accel."));
    214221        else
     222        {
    215223            using_ycbcrtex = false;
     224            using_hardwaretex = false;
     225        }
    216226    }
    217227
    218228    if (ok)
     
    707717        tmp_tex = gl_context->CreateTexture(size, use_pbo, textureType,
    708718                                            GL_UNSIGNED_SHORT_8_8_MESA,
    709719                                            GL_YCBCR_MESA, GL_YCBCR_MESA);
     720    else if (using_hardwaretex)
     721        tmp_tex = gl_context->CreateTexture(size, use_pbo, textureType,
     722                                            GL_UNSIGNED_BYTE, GL_RGBA,
     723                                            GL_RGBA, GL_LINEAR,
     724                                            GL_CLAMP_TO_EDGE);
    710725    else
    711726        tmp_tex = gl_context->CreateTexture(size, use_pbo, textureType);
    712727    tex_size = gl_context->GetTextureSize(textureType, size);
     
    737752    return QSize(w, h);
    738753}
    739754
     755uint OpenGLVideo::GetInputTexture(void)
     756{
     757    return inputTextures[0];
     758}
     759
     760uint OpenGLVideo::GetTextureType(void)
     761{
     762    return textureType;
     763}
     764
     765void OpenGLVideo::SetInputUpdated(void)
     766{
     767    inputUpdated = true;
     768}
     769
    740770/**
    741771 * \fn OpenGLVideo::UpdateInputFrame(const VideoFrame *frame, bool soft_bob)
    742772 *  Update the current input texture using the data from the given YV12 video
  • home/mark/trunk/mythtv/libs/libmythtv/mythcodecid.h

     
    115115                              codec->id == CODEC_ID_MPEG2VIDEO_XVMC_VLD))
    116116#define CODEC_IS_VDPAU(codec) (codec &&\
    117117                               codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
    118 #define CODEC_IS_HWACCEL(codec)  (CODEC_IS_XVMC(codec)  ||\
    119                                   CODEC_IS_VDPAU(codec))
     118#define CODEC_IS_VAAPI(codec, enc) (codec && IS_VAAPI_PIX_FMT(enc->pix_fmt))
     119#define CODEC_IS_HWACCEL(codec, enc) (CODEC_IS_XVMC(codec)  ||\
     120                                      CODEC_IS_VDPAU(codec) ||\
     121                                      CODEC_IS_VAAPI(codec, enc))
    120122
    121123#endif // _MYTH_CODEC_ID_H_
  • home/mark/trunk/mythtv/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
     
    205217            vo = new VideoOutputVDPAU();
    206218#endif // USING_VDPAU
    207219
     220#ifdef USING_VAAPI
     221        if (renderer == "openglvaapi")
     222            vo = new VideoOutputOpenGLVAAPI();
     223#endif // USING_VAAPI
     224
    208225#ifdef USING_XV
    209226        if (xvlist.contains(renderer))
    210227            vo = new VideoOutputXv();
  • home/mark/trunk/mythtv/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