Ticket #8593: vaapi_v7.diff

File vaapi_v7.diff, 48.9 KB (added by markk, 21 months 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