Ticket #8593: vaapi_v6.diff

File vaapi_v6.diff, 39.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  --disable-opengl-video   disable OpenGL based video display
    132133  --disable-quartz-video   disable Mac OS X CoreVideo based video display
    133134  --disable-opengl-vsync   disable OpenGL vsync method
     
    13411342    mythtranscode
    13421343    opengl
    13431344    vdpau
     1345    vaapi
    13441346'
    13451347
    13461348CMDLINE_SELECT="
     
    16831685xvmc_deps="xv X11_extensions_XvMClib_h"
    16841686xvmc_vld_deps="xvmc X11_extensions_vldXvMC_h"
    16851687xvmcw_deps="xvmc"
     1688vaapi_deps="x11 opengl_video"
    16861689
    16871690# default parameters
    16881691pre_logfile="config.ep"
     
    34013404check_header termios.h
    34023405check_header vdpau/vdpau.h
    34033406check_header vdpau/vdpau_x11.h
     3407check_header va/va.h
     3408check_header va/va_glx.h
    34043409check_header X11/extensions/XvMClib.h
    34053410
    34063411check_struct dxva2api.h DXVA_PictureParameters wDecodedPictureIndex
     
    36803685      disable vdpau; }
    36813686fi
    36823687
     3688if enabled vaapi; then
     3689    enabled va_va_h && enabled va_va_glx_h || disable vaapi
     3690    if enabled vaapi; then
     3691        # for XvBA/VDPAU backends we need splitted desktop 0.31.0 but
     3692        # for upstream GLX support we need 0.31.1 ???
     3693        check_cpp_condition va/va.h "VA_VERSION_HEX >= 0x001F0000" ||
     3694        { echolog "VAAPI requires libva >= 0.31.1" && disable vaapi; }
     3695    fi
     3696else
     3697    disable vaapi
     3698fi
     3699
    36833700enabled debug && add_cflags -g"$debuglevel" && add_asflags -g"$debuglevel"
    36843701enabled debug && add_cxxflags -g"$debuglevel"
    36853702
     
    42384255  echo "XvMC libs                 $VENDOR_XVMC_LIBS"
    42394256fi
    42404257  echo "VDPAU support             ${vdpau-no}"
     4258  echo "VAAPI support             ${vaapi-no}"
    42414259fi
    42424260  echo "OpenGL video              ${opengl_video-no}"
    42434261  if test x"$target_os" = x"darwin" ; then
  • 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)
     
    123123                      winid, winx, winy, winw, winh,
    124124                      codec_id, embedid);
    125125
    126     if (db_vdisp_profile)
    127         db_vdisp_profile->SetVideoRenderer("opengl");
     126    SetProfile();
    128127
    129128    success &= SetupContext();
    130129    InitDisplayMeasurements(width, height, false);
    131130    success &= CreateBuffers();
     131    success &= CreatePauseFrame();
    132132    success &= SetupOpenGL();
    133133
    134134    InitOSD();
     
    144144    return success;
    145145}
    146146
     147void VideoOutputOpenGL::SetProfile(void)
     148{
     149    if (db_vdisp_profile)
     150        db_vdisp_profile->SetVideoRenderer("opengl");
     151}
     152
    147153bool VideoOutputOpenGL::InputChanged(const QSize &input_size,
    148154                                     float        aspect,
    149155                                     MythCodecID  av_codec_id,
    150156                                     void        *codec_private,
    151157                                     bool        &aspect_only)
    152158{
    153     VERBOSE(VB_PLAYBACK, LOC + QString("InputChanged(%1,%2,%3) %4")
     159    VERBOSE(VB_PLAYBACK, LOC + QString("InputChanged(%1,%2,%3) %4->%5")
    154160            .arg(input_size.width()).arg(input_size.height()).arg(aspect)
    155             .arg(toString(av_codec_id)));
     161            .arg(toString(video_codec_id)).arg(toString(av_codec_id)));
    156162
    157163    QMutexLocker locker(&gl_context_lock);
    158 
    159164    if (!codec_is_std(av_codec_id))
    160165    {
    161166        VERBOSE(VB_IMPORTANT, LOC_ERR +
     
    242247                                  window.GetVideoDim(), dvr,
    243248                                  window.GetDisplayVideoRect(),
    244249                                  window.GetVideoRect(), true,
    245                                   GetFilters(), db_letterbox_colour);
     250                                  GetFilters(), !codec_is_std(video_codec_id),
     251                                  db_letterbox_colour);
    246252    if (success)
    247253    {
    248254        bool temp_deinterlacing = m_deinterlacing;
     
    276282bool VideoOutputOpenGL::CreateBuffers(void)
    277283{
    278284    QMutexLocker locker(&gl_context_lock);
    279 
    280     bool success = true;
    281285    vbuffers.Init(31, true, 1, 12, 4, 2, false);
    282     success &= vbuffers.CreateBuffers(window.GetVideoDim().width(),
    283                                       window.GetVideoDim().height());
     286    return vbuffers.CreateBuffers(window.GetVideoDim().width(),
     287                                  window.GetVideoDim().height());
     288}
    284289
     290bool VideoOutputOpenGL::CreatePauseFrame(void)
     291{
    285292    av_pause_frame.height = vbuffers.GetScratchFrame()->height;
    286293    av_pause_frame.width  = vbuffers.GetScratchFrame()->width;
    287294    av_pause_frame.bpp    = vbuffers.GetScratchFrame()->bpp;
     
    290297    av_pause_frame.frameNumber = vbuffers.GetScratchFrame()->frameNumber;
    291298
    292299    if (!av_pause_frame.buf)
    293         success = false;
    294     else
    295         clear(&av_pause_frame, GUID_YV12_PLANAR);
     300        return false;
    296301
    297     return success;
     302    clear(&av_pause_frame, GUID_YV12_PLANAR);
     303    return true;
    298304}
    299305
    300306void VideoOutputOpenGL::ProcessFrame(VideoFrame *frame, OSD *osd,
     
    306312    if (!gl_videochain || !gl_context)
    307313        return;
    308314
     315    bool sw_frame = codec_is_std(video_codec_id);
    309316    bool deint_proc = m_deinterlacing && (m_deintFilter != NULL);
    310317    OpenGLLocker ctx_lock(gl_context);
    311318
     
    317324        pauseframe = true;
    318325    }
    319326
    320     if (filterList)
     327    if (filterList && sw_frame)
    321328        filterList->ProcessFrame(frame);
    322329
    323330    bool safepauseframe = pauseframe && !IsBobDeint();
    324     if (deint_proc && m_deinterlaceBeforeOSD &&
     331    if (sw_frame && deint_proc && m_deinterlaceBeforeOSD &&
    325332       (!pauseframe || safepauseframe))
    326333    {
    327334        m_deintFilter->ProcessFrame(frame, scan);
     
    333340        ShowPIPs(frame, pipPlayers);
    334341    }
    335342
    336     if ((!pauseframe || safepauseframe) &&
     343    if (sw_frame && (!pauseframe || safepauseframe) &&
    337344        deint_proc && !m_deinterlaceBeforeOSD)
    338345    {
    339346        m_deintFilter->ProcessFrame(frame, scan);
     
    341348
    342349    bool soft_bob = m_deinterlacing && (m_deintfiltername == "bobdeint");
    343350
    344     if (gl_videochain)
     351    if (gl_videochain && sw_frame)
    345352        gl_videochain->UpdateInputFrame(frame, soft_bob);
    346353}
    347354
     
    630637                     QSize(pipVideoWidth, pipVideoHeight),
    631638                     dvr, position,
    632639                     QRect(0, 0, pipVideoWidth, pipVideoHeight),
    633                      false, GetFilters());
     640                     false, GetFilters(), false);
    634641        gl_pipchain->SetMasterViewport(gl_videochain->GetViewPort());
    635642        if (!success)
    636643        {
     
    651658            QSize(pipVideoWidth, pipVideoHeight),
    652659            dvr, position,
    653660            QRect(0, 0, pipVideoWidth, pipVideoHeight),
    654             false, GetFilters());
     661            false, GetFilters(), false);
    655662
    656663        gl_pipchain->SetMasterViewport(gl_videochain->GetViewPort());
    657664        if (!success)
  • home/mark/trunk/mythtv/libs/libmythtv/avformatdecoder.cpp

     
    5050}
    5151#endif // USING_VDPAU
    5252
     53#ifdef USING_VAAPI
     54#include "videoout_openglvaapi.h"
     55#endif // USING_VAAPI
     56
    5357extern "C" {
    5458#include "avutil.h"
    5559#include "ac3_parser.h"
     
    97101void render_slice_vdpau(struct AVCodecContext *s, const AVFrame *src,
    98102                        int offset[4], int y, int type, int height);
    99103
     104int  get_avf_buffer_vaapi(struct AVCodecContext *c, AVFrame *pic);
     105
    100106static AVCodec *find_vdpau_decoder(AVCodec *c, enum CodecID id)
    101107{
    102108    AVCodec *codec = c;
     
    209215    (*opts.equiv_decoders)["vdpau"].append("dummy");
    210216#endif
    211217
     218#ifdef USING_VAAPI
     219    opts.decoders->append("vaapi");
     220    (*opts.equiv_decoders)["vaapi"].append("dummy");
     221#endif
     222
    212223    PrivateDecoder::GetDecoders(opts);
    213224}
    214225
     
    11081119    return fmt[i];
    11091120}
    11101121
     1122static bool IS_VAAPI_PIX_FMT(enum PixelFormat fmt)
     1123{
     1124    return fmt == PIX_FMT_VAAPI_MOCO ||
     1125           fmt == PIX_FMT_VAAPI_IDCT ||
     1126           fmt == PIX_FMT_VAAPI_VLD;
     1127}
     1128
     1129static enum PixelFormat get_format_vaapi(struct AVCodecContext *avctx,
     1130                                         const enum PixelFormat *fmt)
     1131{
     1132    if (!fmt)
     1133        return PIX_FMT_NONE;
     1134    int i = 0;
     1135    for (; fmt[i] != PIX_FMT_NONE ; i++)
     1136        if (IS_VAAPI_PIX_FMT(fmt[i]))
     1137            break;
     1138    return fmt[i];
     1139}
     1140
    11111141static bool IS_DR1_PIX_FMT(const enum PixelFormat fmt)
    11121142{
    11131143    switch (fmt)
     
    11781208    {
    11791209        directrendering = true;
    11801210        if (!gCoreContext->GetNumSetting("DecodeExtraAudio", 0) &&
    1181             !CODEC_IS_HWACCEL(codec))
     1211            !CODEC_IS_HWACCEL(codec, enc))
    11821212        {
    11831213            SetLowBuffers(false);
    11841214        }
     
    12021232        enc->draw_horiz_band = render_slice_vdpau;
    12031233        enc->slice_flags     = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD;
    12041234    }
     1235    else if (CODEC_IS_VAAPI(codec, enc))
     1236    {
     1237        enc->get_buffer      = get_avf_buffer_vaapi;
     1238        enc->get_format      = get_format_vaapi;
     1239        enc->release_buffer  = release_avf_buffer;
     1240        enc->slice_flags     = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD;
     1241    }
    12051242    else if (codec && codec->capabilities & CODEC_CAP_DR1)
    12061243    {
    12071244        enc->flags          |= CODEC_FLAG_EMU_EDGE;
     
    16901727                        handled = true;
    16911728                    }
    16921729#endif // USING_VDPAU
     1730#ifdef USING_VAAPI
     1731                    MythCodecID vaapi_mcid;
     1732                    PixelFormat pix_fmt = PIX_FMT_YUV420P;
     1733                    vaapi_mcid = VideoOutputOpenGLVAAPI::GetBestSupportedCodec(
     1734                        width, height, mpeg_version(enc->codec_id),
     1735                        no_hardware_decoders, pix_fmt);
     1736
     1737                    if (vaapi_mcid >= video_codec_id)
     1738                    {
     1739                        enc->codec_id = (CodecID)myth2av_codecid(vaapi_mcid);
     1740                        video_codec_id = vaapi_mcid;
     1741                        handled = true;
     1742                        if (!no_hardware_decoders &&
     1743                            codec_is_vaapi(video_codec_id))
     1744                        {
     1745                            enc->pix_fmt = pix_fmt;
     1746                        }
     1747                    }
     1748#endif // USING_VAAPI
    16931749#ifdef USING_XVMC
    16941750
    16951751                    bool force_xv = no_hardware_decoders;
     
    23902446    }
    23912447}
    23922448
     2449int get_avf_buffer_vaapi(struct AVCodecContext *c, AVFrame *pic)
     2450{
     2451    AvFormatDecoder *nd = (AvFormatDecoder *)(c->opaque);
     2452    VideoFrame *frame = nd->GetPlayer()->GetNextVideoFrame(false);
     2453
     2454    pic->data[0]     = frame->buf;
     2455    pic->data[1]     = NULL;
     2456    pic->data[2]     = NULL;
     2457    pic->data[3]     = NULL;
     2458    pic->linesize[0] = 0;
     2459    pic->linesize[1] = 0;
     2460    pic->linesize[2] = 0;
     2461    pic->linesize[3] = 0;
     2462    pic->opaque      = frame;
     2463    pic->type        = FF_BUFFER_TYPE_USER;
     2464    pic->age         = 256 * 256 * 256 * 64;
     2465    frame->pix_fmt   = c->pix_fmt;
     2466
     2467#ifdef USING_VAAPI
     2468    if (nd->GetPlayer()->getVideoOutput())
     2469    {
     2470        VideoOutputOpenGLVAAPI *vo =
     2471            dynamic_cast<VideoOutputOpenGLVAAPI*>(nd->GetPlayer()->getVideoOutput());
     2472        c->hwaccel_context = (vaapi_context*)vo->GetVAAPIContext();
     2473        pic->data[3] = vo->GetSurfaceIDPointer(frame->buf);
     2474    }
     2475#endif
     2476
     2477    return 0;
     2478}
     2479
    23932480void AvFormatDecoder::DecodeDTVCC(const uint8_t *buf, uint len)
    23942481{
    23952482    if (!len)
  • home/mark/trunk/mythtv/libs/libmythtv/libmythtv.pro

     
    338338    using_opengl_video:HEADERS += openglvideo.h   videoout_opengl.h
    339339    using_opengl_video:SOURCES += openglvideo.cpp videoout_opengl.cpp
    340340
     341    using_vaapi: DEFINES += USING_VAAPI
     342    using_vaapi: DEFINES += videoout_openglvaapi.h   vaapicontext.h
     343    using_vaapi: SOURCES += videoout_openglvaapi.cpp vaapicontext.cpp
     344    using_vaapi: LIBS    += -lva -lva-glx
     345
    341346    # Misc. frontend
    342347    HEADERS += DetectLetterbox.h
    343348    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 & kGLYCbCrTex);
     184    using_ycbcrtex      = !using_hardwaretex && !full_features && (gl_features & kGLYCbCrTex);
    182185
    183186    if (using_ycbcrtex)
    184187        basic_features = false;
     
    192195                QString("No OpenGL feature support for Bicubic filter."));
    193196    }
    194197
    195     if ((defaultUpsize != kGLFilterBicubic) && (gl_features & kGLExtRect))
     198    if (!using_hardwaretex &&
     199        (defaultUpsize != kGLFilterBicubic) && (gl_features & kGLExtRect))
    196200        textureType = gl_context->GetTextureType(textureRects);
    197201
    198202    GLuint tex = 0;
    199203    bool    ok = false;
    200204
    201     if (basic_features)
     205    if (basic_features && !using_hardwaretex)
    202206    {
    203207        tex = CreateVideoTexture(actual_video_dim, inputTextureSize, use_pbo);
    204208        ok = tex && AddFilter(kGLFilterYUV2RGB);
    205209    }
    206     else if (using_ycbcrtex)
     210    else if (using_ycbcrtex || using_hardwaretex)
    207211    {
    208212        tex = CreateVideoTexture(actual_video_dim,
    209213                                 inputTextureSize, use_pbo);
    210214        ok = tex && AddFilter(kGLFilterResize);
    211         if (ok)
     215        if (ok && using_ycbcrtex)
    212216            VERBOSE(VB_PLAYBACK, LOC + QString("Using GL_MESA_ycbcr_texture for"
    213217                                               " colorspace conversion."));
     218        else if (ok && using_hardwaretex)
     219            VERBOSE(VB_PLAYBACK, LOC + QString("Using plain RGBA tex for hw accel."));
    214220        else
     221        {
    215222            using_ycbcrtex = false;
     223            using_hardwaretex = false;
     224        }
    216225    }
    217226
    218227    if (ok)
     
    707716        tmp_tex = gl_context->CreateTexture(size, use_pbo, textureType,
    708717                                            GL_UNSIGNED_SHORT_8_8_MESA,
    709718                                            GL_YCBCR_MESA, GL_YCBCR_MESA);
     719    else if (using_hardwaretex)
     720        tmp_tex = gl_context->CreateTexture(size, use_pbo, textureType,
     721                                            GL_UNSIGNED_BYTE, GL_RGBA,
     722                                            GL_RGBA, GL_LINEAR,
     723                                            GL_CLAMP_TO_EDGE);
    710724    else
    711725        tmp_tex = gl_context->CreateTexture(size, use_pbo, textureType);
    712726    tex_size = gl_context->GetTextureSize(textureType, size);
     
    737751    return QSize(w, h);
    738752}
    739753
     754uint OpenGLVideo::GetInputTexture(void)
     755{
     756    return inputTextures[0];
     757}
     758
     759uint OpenGLVideo::GetTextureType(void)
     760{
     761    return textureType;
     762}
     763
     764void OpenGLVideo::SetInputUpdated(void)
     765{
     766    inputUpdated = true;
     767}
     768
    740769/**
    741770 * \fn OpenGLVideo::UpdateInputFrame(const VideoFrame *frame, bool soft_bob)
    742771 *  Update the current input texture using the data from the given YV12 video
  • 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
  • home/mark/trunk/mythtv/libs/libavutil/internal.h

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