Ticket #8620: dxva2_v1.diff

File dxva2_v1.diff, 49.3 KB (added by markk, 10 years ago)
  • C:/mythtv/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-dxva2           enable video hardware acceleration on windows
    131132  --disable-opengl-video   disable OpenGL based video display
    132133  --enable-mac-accel       enable Mac OS X MPEG acceleration
    133134  --disable-opengl-vsync   disable OpenGL vsync method
     
    13341335    bindings_python
    13351336    darwin_da
    13361337    dvdv
     1338    dxva2
    13371339    opengl
    13381340    vdpau
    13391341'
     
    36643666      disable vdpau; }
    36653667fi
    36663668
     3669if enabled dxva2; then
     3670    enabled dxva2api_h && enabled windows || disable dxva2
     3671else
     3672    disable dxva2
     3673fi
     3674
    36673675enabled debug && add_cflags -g"$debuglevel" && add_asflags -g"$debuglevel"
    36683676enabled debug && add_cxxflags -g"$debuglevel"
    36693677
     
    42304238  echo "DirectFB                  ${directfb-no}"
    42314239  if test x"$target_os" = x"mingw32" ; then
    42324240    echo "Windows (Direct3D)        yes"
     4241    echo "DXVA2 support             ${dxva2-no}"
    42334242  fi
    42344243  echo "Fribidi formatting        ${fribidi}"
    42354244  echo "MHEG support              ${mheg}"
  • C:/mythtv/mythtv/libs/libmythtv/videoout_d3d.cpp

     
    5050    opts.priorities->insert("direct3d", 55);
    5151}
    5252
    53 VideoOutputD3D::VideoOutputD3D(void)
    54   : VideoOutput(),         m_lock(QMutex::Recursive),
    55     m_hWnd(NULL),          m_render(NULL),
    56     m_video(NULL),
     53VideoOutputD3D::VideoOutputD3D(MythCodecID codec_id)
     54  : VideoOutput(),         m_codec_id(codec_id),  m_lock(QMutex::Recursive),
     55    m_hWnd(NULL),          m_render(NULL),        m_video(NULL),
    5756    m_render_valid(false), m_render_reset(false), m_pip_active(NULL),
    5857    m_osd_painter(NULL)
    5958{
     
    133132            .arg(toString(av_codec_id)));
    134133
    135134    QMutexLocker locker(&m_lock);
    136 
    137     if (!codec_is_std(av_codec_id))
     135    m_codec_id = av_codec_id;
     136    if (!codec_is_std(m_codec_id))
    138137    {
    139138        VERBOSE(VB_IMPORTANT, LOC_ERR +
    140139            QString("New video codec is not supported."));
     
    220219    return ret;
    221220}
    222221
     222void VideoOutputD3D::SetProfile(void)
     223{
     224    if (db_vdisp_profile)
     225        db_vdisp_profile->SetVideoRenderer("direct3d");
     226}
     227
    223228bool VideoOutputD3D::Init(int width, int height, float aspect,
    224229                          WId winid, int winx, int winy, int winw,
    225230                          int winh, WId embedid)
     
    231236
    232237    VideoOutput::Init(width, height, aspect, winid,
    233238                      winx, winy, winw, winh, embedid);
     239    SetProfile();
    234240
    235     if (db_vdisp_profile)
    236         db_vdisp_profile->SetVideoRenderer("direct3d");
    237 
    238241    bool success = true;
    239242    success &= SetupContext();
    240243    InitDisplayMeasurements(width, height, false);
    241244
    242     vbuffers.Init(kNumBuffers, true, kNeedFreeFrames,
    243                   kPrebufferFramesNormal, kPrebufferFramesSmall,
    244                   kKeepPrebuffer);
    245     success &= vbuffers.CreateBuffers(windows[0].GetVideoDim().width(),
    246                                       windows[0].GetVideoDim().height());
    247     m_pauseFrame.height = vbuffers.GetScratchFrame()->height;
    248     m_pauseFrame.width  = vbuffers.GetScratchFrame()->width;
    249     m_pauseFrame.bpp    = vbuffers.GetScratchFrame()->bpp;
    250     m_pauseFrame.size   = vbuffers.GetScratchFrame()->size;
    251     m_pauseFrame.buf    = new unsigned char[m_pauseFrame.size + 128];
    252     m_pauseFrame.frameNumber = vbuffers.GetScratchFrame()->frameNumber;
    253245
     246    success &= CreateBuffers();
     247    success &= CreatePauseFrame();
    254248    MoveResize();
    255249
    256250    if (!success)
     
    269263    return success;
    270264}
    271265
     266bool VideoOutputD3D::CreateBuffers(void)
     267{
     268    vbuffers.Init(kNumBuffers, true, kNeedFreeFrames,
     269                  kPrebufferFramesNormal, kPrebufferFramesSmall,
     270                  kKeepPrebuffer);
     271    return vbuffers.CreateBuffers(windows[0].GetVideoDim().width(),
     272                                  windows[0].GetVideoDim().height());
     273}
     274
     275bool VideoOutputD3D::CreatePauseFrame(void)
     276{
     277    m_pauseFrame.height = vbuffers.GetScratchFrame()->height;
     278    m_pauseFrame.width  = vbuffers.GetScratchFrame()->width;
     279    m_pauseFrame.bpp    = vbuffers.GetScratchFrame()->bpp;
     280    m_pauseFrame.size   = vbuffers.GetScratchFrame()->size;
     281    m_pauseFrame.buf    = new unsigned char[m_pauseFrame.size + 128];
     282    m_pauseFrame.frameNumber = vbuffers.GetScratchFrame()->frameNumber;
     283    return true;
     284}
     285
    272286void VideoOutputD3D::PrepareFrame(VideoFrame *buffer, FrameScanType t,
    273287                                  OSD *osd)
    274288{
     
    440454                                  const PIPMap &pipPlayers,
    441455                                  FrameScanType scan)
    442456{
     457    bool sw_frame = (frame && (frame->codec == FMT_YV12));
     458
    443459    QMutexLocker locker(&m_lock);
    444460    if (IsErrored())
    445461    {
     
    458474        pauseframe = true;
    459475    }
    460476
    461     if (filterList)
     477    if (filterList && sw_frame)
    462478        filterList->ProcessFrame(frame);
    463479
    464     bool safepauseframe = pauseframe && !IsBobDeint();
     480    bool safepauseframe = pauseframe && !IsBobDeint() && sw_frame;
    465481    if (deint_proc && m_deinterlaceBeforeOSD &&
    466482       (!pauseframe || safepauseframe))
    467483    {
     
    472488        ShowPIPs(frame, pipPlayers);
    473489
    474490    if ((!pauseframe || safepauseframe) &&
    475         deint_proc && !m_deinterlaceBeforeOSD)
     491        deint_proc && !m_deinterlaceBeforeOSD && sw_frame)
    476492    {
    477493        m_deintFilter->ProcessFrame(frame, scan);
    478494    }
     
    482498        m_render_valid |= m_render->Test(m_render_reset);
    483499        if (m_render_reset)
    484500            SetupContext();
    485         if (m_render_valid && m_video)
     501        if (m_render_valid && m_video && sw_frame)
    486502            UpdateFrame(frame, m_video);
    487503    }
    488504}
  • C:/mythtv/mythtv/libs/libmythtv/videoout_d3ddxva2.h

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

     
    4949}
    5050#endif // USING_VDPAU
    5151
     52#ifdef USING_DXVA2
     53#include "videoout_d3ddxva2.h"
     54#endif
     55
    5256extern "C" {
    5357#include "avutil.h"
    5458#include "ac3_parser.h"
     
    9296void render_slice_vdpau(struct AVCodecContext *s, const AVFrame *src,
    9397                        int offset[4], int y, int type, int height);
    9498
     99int  get_avf_buffer_dxva2(struct AVCodecContext *c, AVFrame *pic);
     100
    95101static AVCodec *find_vdpau_decoder(AVCodec *c, enum CodecID id)
    96102{
    97103    AVCodec *codec = c;
     
    461467    opts.decoders->append("vdpau");
    462468    (*opts.equiv_decoders)["vdpau"].append("dummy");
    463469#endif
     470
     471#ifdef USING_DXVA2
     472    opts.decoders->append("dxva2");
     473    (*opts.equiv_decoders)["dxva2"].append("dummy");
     474#endif
    464475}
    465476
    466477AvFormatDecoder::AvFormatDecoder(NuppelVideoPlayer *parent,
     
    13681379    }
    13691380}
    13701381
     1382static enum PixelFormat get_format_dxva2(struct AVCodecContext *avctx,
     1383                                         const enum PixelFormat *fmt)
     1384{
     1385    if (!fmt)
     1386        return PIX_FMT_NONE;
     1387    int i = 0;
     1388    for (; fmt[i] != PIX_FMT_NONE ; i++)
     1389        if (PIX_FMT_DXVA2_VLD == fmt[i])
     1390            break;
     1391    return fmt[i];
     1392}
     1393
    13711394void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc,
    13721395                                     bool selectedStream)
    13731396{
     
    14261449    {
    14271450        directrendering = true;
    14281451        if (!gCoreContext->GetNumSetting("DecodeExtraAudio", 0) &&
    1429             !CODEC_IS_HWACCEL(codec))
     1452            !CODEC_IS_HWACCEL(codec, enc))
    14301453        {
    14311454            SetLowBuffers(false);
    14321455        }
     
    14601483        enc->draw_horiz_band = render_slice_vdpau;
    14611484        enc->slice_flags     = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD;
    14621485    }
     1486    else if (CODEC_IS_DXVA2(codec, enc))
     1487    {
     1488        enc->get_buffer      = get_avf_buffer_dxva2;
     1489        enc->get_format      = get_format_dxva2;
     1490        enc->release_buffer  = release_avf_buffer;
     1491    }
    14631492    else if (codec && codec->capabilities & CODEC_CAP_DR1)
    14641493    {
    14651494        enc->flags          |= CODEC_FLAG_EMU_EDGE;
     
    19421971                        handled = true;
    19431972                    }
    19441973#endif // USING_VDPAU
     1974#ifdef USING_DXVA2
     1975                    MythCodecID dxva2_mcid;
     1976                    PixelFormat pix_fmt = PIX_FMT_YUV420P;
     1977                    dxva2_mcid = VideoOutputD3DDXVA2::GetBestSupportedCodec(
     1978                        width, height, mpeg_version(enc->codec_id),
     1979                        no_hardware_decoders, pix_fmt);
     1980
     1981                    if (dxva2_mcid >= video_codec_id)
     1982                    {
     1983                        enc->codec_id = (CodecID)myth2av_codecid(dxva2_mcid);
     1984                        video_codec_id = dxva2_mcid;
     1985                        handled = true;
     1986                        if (!no_hardware_decoders &&
     1987                            codec_is_dxva2(video_codec_id))
     1988                        {
     1989                            enc->pix_fmt = pix_fmt;
     1990                        }
     1991                    }
     1992#endif // USING_DXVA2
    19451993#ifdef USING_XVMC
    19461994
    19471995                    bool force_xv = no_hardware_decoders;
     
    26602708    }
    26612709}
    26622710
     2711int get_avf_buffer_dxva2(struct AVCodecContext *c, AVFrame *pic)
     2712{
     2713    AvFormatDecoder *nd = (AvFormatDecoder *)(c->opaque);
     2714    VideoFrame *frame = nd->GetNVP()->GetNextVideoFrame(false);
     2715    for (int i =0; i < 4; i++)
     2716    {
     2717        pic->data[i]     = NULL;
     2718        pic->linesize[i] = 0;
     2719    }
     2720    pic->reordered_opaque = c->reordered_opaque;
     2721    pic->opaque      = frame;
     2722    pic->type        = FF_BUFFER_TYPE_USER;
     2723    pic->age         = 256 * 256 * 256 * 64;
     2724    frame->pix_fmt   = c->pix_fmt;
     2725
     2726#ifdef USING_DXVA2
     2727    if (nd->GetNVP()->getVideoOutput())
     2728    {
     2729        VideoOutputD3DDXVA2 *vo =
     2730            dynamic_cast<VideoOutputD3DDXVA2*>(nd->GetNVP()->getVideoOutput());
     2731        c->hwaccel_context = (dxva_context*)vo->GetDXVA2Context();
     2732        pic->data[0] = (uint8_t*)frame->buf;
     2733        pic->data[3] = (uint8_t*)frame->buf;
     2734    }
     2735#endif
     2736
     2737    return 0;
     2738}
     2739
    26632740void AvFormatDecoder::DecodeDTVCC(const uint8_t *buf, uint len)
    26642741{
    26652742    if (!len)
  • C:/mythtv/mythtv/libs/libmythtv/libmythtv.pro

     
    571571    SOURCES -= NuppelVideoRecorder.cpp
    572572    SOURCES += videoout_d3d.cpp
    573573
     574    using_dxva2: DEFINES += USING_DXVA2
     575    using_dxva2: HEADERS += videoout_d3ddxva2.h   dxva2context.h
     576    using_dxva2: SOURCES += videoout_d3ddxva2.cpp dxva2context.cpp
     577
    574578    LIBS += -lpthread
    575579    LIBS += -lws2_32
    576580}
  • C:/mythtv/mythtv/libs/libmythtv/dxva2context.cpp

     
     1#include <QString>
     2
     3#include "mythverbose.h"
     4#include "Initguid.h"
     5#include "dxva2context.h"
     6
     7static const GUID IID_IDirectXVideoDecoderService = {
     8    0xfc51a551, 0xd5e7, 0x11d9, {0xaf,0x55,0x00,0x05,0x4e,0x43,0xff,0x02}
     9};
     10
     11typedef HRESULT (__stdcall *DXVA2CreateVideoServicePtr)(IDirect3DDevice9* pDD,
     12                                                        REFIID riid,
     13                                                        void** ppService);
     14static DXVA2CreateVideoServicePtr gDXVA2CreateVideoService;
     15
     16static inline QString toString(const GUID& guid)
     17{
     18    return QString("%1-%2-%3-%4%5-%6%7%8%9%10%11")
     19            .arg(guid.Data1, 8, 16, QLatin1Char('0'))
     20            .arg(guid.Data2, 4, 16, QLatin1Char('0'))
     21            .arg(guid.Data3, 4, 16, QLatin1Char('0'))
     22            .arg(guid.Data4[0], 2, 16, QLatin1Char('0'))
     23            .arg(guid.Data4[1], 2, 16, QLatin1Char('0'))
     24            .arg(guid.Data4[2], 2, 16, QLatin1Char('0'))
     25            .arg(guid.Data4[3], 2, 16, QLatin1Char('0'))
     26            .arg(guid.Data4[4], 2, 16, QLatin1Char('0'))
     27            .arg(guid.Data4[5], 2, 16, QLatin1Char('0'))
     28            .arg(guid.Data4[6], 2, 16, QLatin1Char('0'))
     29            .arg(guid.Data4[7], 2, 16, QLatin1Char('0')).toUpper();
     30}
     31
     32#define LOC QString("DXVA2: ")
     33#define ERR QString("DXVA2 Error: ")
     34
     35DEFINE_GUID(DXVA2_ModeH264_A,       0x1b81be64, 0xa0c7, 0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
     36DEFINE_GUID(DXVA2_ModeH264_B,       0x1b81be65, 0xa0c7, 0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
     37DEFINE_GUID(DXVA2_ModeH264_C,       0x1b81be66, 0xa0c7, 0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
     38DEFINE_GUID(DXVA2_ModeH264_D,       0x1b81be67, 0xa0c7, 0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
     39DEFINE_GUID(DXVA2_ModeH264_E,       0x1b81be68, 0xa0c7, 0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
     40DEFINE_GUID(DXVA2_ModeH264_F,       0x1b81be69, 0xa0c7, 0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
     41
     42DEFINE_GUID(DXVA2_ModeWMV8_A,       0x1b81be80, 0xa0c7, 0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
     43DEFINE_GUID(DXVA2_ModeWMV8_B,       0x1b81be81, 0xa0c7, 0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
     44
     45DEFINE_GUID(DXVA2_ModeWMV9_A,       0x1b81be90, 0xa0c7, 0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
     46DEFINE_GUID(DXVA2_ModeWMV9_B,       0x1b81be91, 0xa0c7, 0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
     47DEFINE_GUID(DXVA2_ModeWMV9_C,       0x1b81be94, 0xa0c7, 0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
     48
     49DEFINE_GUID(DXVA2_ModeVC1_A,        0x1b81beA0, 0xa0c7, 0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
     50DEFINE_GUID(DXVA2_ModeVC1_B,        0x1b81beA1, 0xa0c7, 0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
     51DEFINE_GUID(DXVA2_ModeVC1_C,        0x1b81beA2, 0xa0c7, 0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
     52DEFINE_GUID(DXVA2_ModeVC1_D,        0x1b81beA3, 0xa0c7, 0x11d3, 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
     53
     54DEFINE_GUID(DXVA2_ModeMPEG2_MoComp, 0xe6a9f44b, 0x61b0, 0x4563, 0x9e,0xa4,0x63,0xd2,0xa3,0xc6,0xfe,0x66);
     55DEFINE_GUID(DXVA2_ModeMPEG2_IDCT,   0xbf22ad00, 0x03ea, 0x4690, 0x80,0x77,0x47,0x33,0x46,0x20,0x9b,0x7e);
     56DEFINE_GUID(DXVA2_ModeMPEG2_VLD,    0xee27417f, 0x5e28, 0x4e65, 0xbe,0xea,0x1d,0x26,0xb5,0x08,0xad,0xc9);
     57
     58#define DXVA2_ModeWMV8_PostProc     DXVA2_ModeWMV8_A
     59#define DXVA2_ModeWMV8_MoComp       DXVA2_ModeWMV8_B
     60
     61#define DXVA2_ModeWMV9_PostProc     DXVA2_ModeWMV9_A
     62#define DXVA2_ModeWMV9_MoComp       DXVA2_ModeWMV9_B
     63#define DXVA2_ModeWMV9_IDCT         DXVA2_ModeWMV9_C
     64
     65#define DXVA2_ModeVC1_PostProc      DXVA2_ModeVC1_A
     66#define DXVA2_ModeVC1_MoComp        DXVA2_ModeVC1_B
     67#define DXVA2_ModeVC1_IDCT          DXVA2_ModeVC1_C
     68#define DXVA2_ModeVC1_VLD           DXVA2_ModeVC1_D
     69
     70#define DXVA2_ModeH264_MoComp_NoFGT DXVA2_ModeH264_A
     71#define DXVA2_ModeH264_MoComp_FGT   DXVA2_ModeH264_B
     72#define DXVA2_ModeH264_IDCT_NoFGT   DXVA2_ModeH264_C
     73#define DXVA2_ModeH264_IDCT_FGT     DXVA2_ModeH264_D
     74#define DXVA2_ModeH264_VLD_NoFGT    DXVA2_ModeH264_E
     75#define DXVA2_ModeH264_VLD_FGT      DXVA2_ModeH264_F
     76
     77DEFINE_GUID(DXVA2_Intel_ModeH264_A, 0x604F8E64, 0x4951, 0x4c54, 0x88,0xFE,0xAB,0xD2,0x5C,0x15,0xB3,0xD6);
     78DEFINE_GUID(DXVA2_Intel_ModeH264_C, 0x604F8E66, 0x4951, 0x4c54, 0x88,0xFE,0xAB,0xD2,0x5C,0x15,0xB3,0xD6);
     79DEFINE_GUID(DXVA2_Intel_ModeH264_E, 0x604F8E68, 0x4951, 0x4c54, 0x88,0xFE,0xAB,0xD2,0x5C,0x15,0xB3,0xD6);
     80DEFINE_GUID(DXVA2_Intel_ModeVC1_E , 0xBCC5DB6D, 0xA2B6, 0x4AF0, 0xAC,0xE4,0xAD,0xB1,0xF7,0x87,0xBC,0x89);
     81
     82typedef struct {
     83    const QString name;
     84    const GUID   *guid;
     85    MythCodecID   codec;
     86} dxva2_mode;
     87
     88// Preferred modes must come first
     89static const dxva2_mode dxva2_modes[] =
     90{
     91    {"MPEG2 VLD",                  &DXVA2_ModeMPEG2_VLD,    kCodec_NONE/*kCodec_MPEG2_DXVA2*/},
     92    {"MPEG2 MoComp",               &DXVA2_ModeMPEG2_MoComp, kCodec_NONE},
     93    {"MPEG2 IDCT",                 &DXVA2_ModeMPEG2_IDCT,   kCodec_NONE},
     94
     95    {"H.264 VLD, FGT",             &DXVA2_ModeH264_F,       kCodec_H264_DXVA2},
     96    {"H.264 VLD, no FGT",          &DXVA2_ModeH264_E,       kCodec_H264_DXVA2},
     97    {"H.264 IDCT, FGT",            &DXVA2_ModeH264_D,       kCodec_NONE},
     98    {"H.264 IDCT, no FGT",         &DXVA2_ModeH264_C,       kCodec_NONE},
     99    {"H.264 MoComp, FGT",          &DXVA2_ModeH264_B,       kCodec_NONE},
     100    {"H.264 MoComp, no FGT",       &DXVA2_ModeH264_A,       kCodec_NONE},
     101
     102    {"WMV8 MoComp",                &DXVA2_ModeWMV8_B,       kCodec_NONE},
     103    {"WMV8 post processing",       &DXVA2_ModeWMV8_A,       kCodec_NONE},
     104
     105    {"WMV9 IDCT",                  &DXVA2_ModeWMV9_C,       kCodec_NONE},
     106    {"WMV9 MoComp",                &DXVA2_ModeWMV9_B,       kCodec_NONE},
     107    {"WMV9 post processing",       &DXVA2_ModeWMV9_A,       kCodec_NONE},
     108
     109    {"VC-1 VLD",                   &DXVA2_ModeVC1_D,        kCodec_VC1_DXVA2},
     110    {"VC-1 VLD",                   &DXVA2_ModeVC1_D,        kCodec_WMV3_DXVA2},
     111    {"VC-1 IDCT",                  &DXVA2_ModeVC1_C,        kCodec_NONE},
     112    {"VC-1 MoComp",                &DXVA2_ModeVC1_B,        kCodec_NONE},
     113    {"VC-1 post processing",       &DXVA2_ModeVC1_A,        kCodec_NONE},
     114
     115    {"Intel H.264 VLD, no FGT",    &DXVA2_Intel_ModeH264_E, kCodec_NONE},
     116    {"Intel H.264 IDCT, no FGT",   &DXVA2_Intel_ModeH264_C, kCodec_NONE},
     117    {"Intel H.264 MoComp, no FGT", &DXVA2_Intel_ModeH264_A, kCodec_NONE},
     118    {"Intel VC-1 VLD",             &DXVA2_Intel_ModeVC1_E,  kCodec_NONE},
     119
     120    {"", NULL, kCodec_NONE}
     121};
     122
     123#define CREATE_CHECK(arg1, arg2) \
     124  if (ok) \
     125  { \
     126      ok = arg1; \
     127      if (!ok) \
     128          VERBOSE(VB_IMPORTANT, ERR + arg2); \
     129  }
     130
     131DXVA2Context::DXVA2Context(IDirect3DDevice9 *device, uint num_bufs,
     132                           MythCodecID codec_id, uint width, uint height)
     133  : m_d3dDevice(device),  m_service(NULL),
     134    m_codec_id(codec_id), m_width(width),  m_height(height)
     135{
     136    memset(&m_format, 0, sizeof(DXVA2_VideoDesc));
     137    memset(&m_context, 0, sizeof(dxva_context));
     138    m_context.cfg = new DXVA2_ConfigPictureDecode();
     139    m_context.surface_count = num_bufs;
     140    m_context.surface = new IDirect3DSurface9*[num_bufs];
     141}
     142
     143DXVA2Context::~DXVA2Context(void)
     144{
     145    //for (uint i = 0; i < m_context.surface_count; i++)
     146    //    m_context.surface[i]->Release();
     147    if (m_context.decoder)
     148        m_context.decoder->Release();
     149    if (m_service)
     150        m_service->Release();
     151    delete m_context.cfg;
     152    delete [] m_context.surface;
     153}
     154
     155bool DXVA2Context::Init(void)
     156{
     157    bool ok = true;
     158    CREATE_CHECK(LoadDXVA2(),  "Failed to load DXVA2 library.")
     159    CREATE_CHECK(m_d3dDevice != NULL,  "No D3D9 device.")
     160    CREATE_CHECK(m_width > 0,  "Invalid width.")
     161    CREATE_CHECK(m_height > 0, "Invalid height.")
     162    gDXVA2CreateVideoService(m_d3dDevice,
     163                             IID_IDirectXVideoDecoderService,
     164                            (void**)&m_service);
     165    CREATE_CHECK(m_service != NULL, "Failed to create Video Service.")
     166    CREATE_CHECK(GetInputOutput(), "Failed to find input/output combination.")
     167    InitFormat();
     168    CREATE_CHECK(GetDecoderConfig(), "Failed to find a raw input bitstream.")
     169    CREATE_CHECK(CreateSurfaces(), "Failed to create surfaces.")
     170    CREATE_CHECK(CreateDecoder(), "Failed to create decoder.")
     171    return ok;
     172}
     173
     174bool DXVA2Context::LoadDXVA2()
     175{
     176    if (gDXVA2CreateVideoService)
     177        return true;
     178
     179    static QMutex  lock;
     180    static HMODULE handle;
     181
     182    QMutexLocker locker(&lock);
     183    if (handle == NULL)
     184        handle = LoadLibraryEx("dxva2.dll", NULL, 0);
     185    if (handle == NULL)
     186        return false;
     187    VERBOSE(VB_IMPORTANT, LOC + "Loaded DXVA2 library.");
     188    gDXVA2CreateVideoService = (DXVA2CreateVideoServicePtr)GetProcAddress(handle, "DXVA2CreateVideoService");
     189    if (gDXVA2CreateVideoService == NULL)
     190        return false;
     191    VERBOSE(VB_IMPORTANT, LOC + "Found DXVA2 library proc");
     192    return true;
     193}
     194
     195bool DXVA2Context::GetInputOutput(void)
     196{
     197    if (!m_service)
     198        return false;
     199    VERBOSE(VB_PLAYBACK, LOC + QString("Looking for support for %1")
     200                                        .arg(toString(m_codec_id)));
     201    uint input_count;
     202    GUID *input_list;
     203    m_format.Format = D3DFMT_UNKNOWN;
     204    m_service->GetDecoderDeviceGuids(&input_count, &input_list);
     205    for (const dxva2_mode* mode = dxva2_modes;
     206        !mode->name.isEmpty() && m_format.Format == D3DFMT_UNKNOWN;
     207         mode++)
     208    {
     209        if (mode->codec != m_codec_id)
     210            continue;
     211        for (uint j = 0; j < input_count; j++)
     212        {
     213            if (IsEqualGUID(input_list[j], *mode->guid))
     214            {
     215                VERBOSE(VB_PLAYBACK, LOC + QString("Testing %1")
     216                                           .arg(mode->name));
     217                if (TestTarget(input_list[j]))
     218                    break;
     219            }
     220        }
     221    }
     222
     223    return m_format.Format != D3DFMT_UNKNOWN;
     224}
     225
     226bool DXVA2Context::TestTarget(const GUID &guid)
     227{
     228    if (!m_service)
     229        return false;
     230    uint       output_count = 0;
     231    D3DFORMAT *output_list  = NULL;
     232    m_service->GetDecoderRenderTargets(guid, &output_count, &output_list);
     233    for(uint i = 0; i < output_count; i++)
     234    {
     235        if(output_list[i] == MAKEFOURCC('Y','V','1','2') ||
     236           output_list[i] == MAKEFOURCC('N','V','1','2'))
     237        {
     238            m_input         = guid;
     239            m_format.Format = output_list[i];
     240            return true;
     241        }
     242    }
     243    return false;
     244}
     245
     246void DXVA2Context::InitFormat(void)
     247{
     248    m_format.SampleWidth                         = m_width;
     249    m_format.SampleHeight                        = m_height;
     250    m_format.InputSampleFreq.Numerator           = 0;
     251    m_format.InputSampleFreq.Denominator         = 0;
     252    m_format.OutputFrameFreq                     = m_format.InputSampleFreq;
     253    m_format.UABProtectionLevel                  = FALSE;
     254    m_format.Reserved                            = 0;
     255}
     256
     257bool DXVA2Context::GetDecoderConfig(void)
     258{
     259    if (!m_service)
     260        return false;
     261
     262    uint                       cfg_count = 0;
     263    DXVA2_ConfigPictureDecode *cfg_list  = NULL;
     264    m_service->GetDecoderConfigurations(m_input, &m_format, NULL,
     265                                        &cfg_count, &cfg_list);
     266
     267    DXVA2_ConfigPictureDecode config = {};
     268    uint bitstream = 1;
     269    for (uint i = 0; i < cfg_count; i++)
     270    {
     271        // select first available
     272        if (config.ConfigBitstreamRaw == 0 &&
     273            cfg_list[i].ConfigBitstreamRaw != 0)
     274        {
     275            config = cfg_list[i];
     276        }
     277        // overide with preferred if found
     278        if (config.ConfigBitstreamRaw != bitstream &&
     279            cfg_list[i].ConfigBitstreamRaw == bitstream)
     280        {
     281            config = cfg_list[i];
     282        }
     283    }
     284    if(!config.ConfigBitstreamRaw)
     285        return false;
     286    *const_cast<DXVA2_ConfigPictureDecode*>(m_context.cfg) = config;
     287    VERBOSE(VB_PLAYBACK, LOC + QString("Found bitstream type %1")
     288        .arg(m_context.cfg->ConfigBitstreamRaw));
     289    return true;
     290}
     291
     292bool DXVA2Context::CreateSurfaces(void)
     293{
     294    if (!m_service || !m_context.surface)
     295        return false;
     296
     297    HRESULT hr = m_service->CreateSurface((m_width + 15) & ~15,
     298                                          (m_height + 15) & ~15,
     299                                           m_context.surface_count,
     300                                           m_format.Format,
     301                                           D3DPOOL_DEFAULT,
     302                                           0, DXVA2_VideoDecoderRenderTarget,
     303                                           m_context.surface, NULL);
     304    if (FAILED(hr))
     305        return false;
     306    VERBOSE(VB_PLAYBACK, LOC + QString("Created %1 decoder surfaces.")
     307                                           .arg(m_context.surface_count));
     308    for (uint i = 0; i < m_context.surface_count; i++)
     309        m_context.surface[i]->AddRef();
     310    return true;
     311}
     312
     313bool DXVA2Context::CreateDecoder(void)
     314{
     315    if (!m_service || !m_context.surface)
     316        return false;
     317
     318    HRESULT hr = m_service->CreateVideoDecoder(m_input,
     319                                              &m_format,
     320                                               const_cast<DXVA2_ConfigPictureDecode*>(m_context.cfg),
     321                                               m_context.surface,
     322                                               m_context.surface_count,
     323                                              &m_context.decoder);
     324    if (FAILED(hr))
     325        return false;
     326    VERBOSE(VB_PLAYBACK, LOC + QString("Created decoder: %1->%2x%3 (%4 surfaces)")
     327        .arg(toString(m_codec_id)).arg(m_width).arg(m_height)
     328        .arg(m_context.surface_count));
     329    return true;
     330}
     331
     332void* DXVA2Context::GetSurface(uint num)
     333{
     334    if (num < 0 || num >= m_context.surface_count)
     335        return NULL;
     336    return (void*)m_context.surface[num];
     337}
  • C:/mythtv/mythtv/libs/libmythtv/frame.h

     
    2424    FMT_BGRA,
    2525    FMT_VDPAU,
    2626    FMT_VAAPI,
     27    FMT_DXVA2,
    2728} VideoFrameType;
    2829
    2930typedef struct VideoFrame_
  • C:/mythtv/mythtv/libs/libmythtv/videoout_d3d.h

     
    1212{
    1313  public:
    1414    static void GetRenderOptions(render_opts &opts, QStringList &cpudeints);
    15     VideoOutputD3D();
    16    ~VideoOutputD3D();
     15    VideoOutputD3D(MythCodecID codec_id);
     16    virtual ~VideoOutputD3D();
    1717
    18     bool Init(int width, int height, float aspect, WId winid,
    19               int winx, int winy, int winw, int winh, WId embedid = 0);
     18    virtual bool Init(int width, int height, float aspect, WId winid,
     19                      int winx, int winy, int winw, int winh, WId embedid = 0);
     20    virtual bool CreateBuffers(void);
     21    bool CreatePauseFrame(void);
    2022    void PrepareFrame(VideoFrame *buffer, FrameScanType, OSD *osd);
    21     void ProcessFrame(VideoFrame *frame, OSD *osd,
    22                       FilterChain *filterList,
    23                       const PIPMap &pipPlayers,
    24                       FrameScanType scan);
     23    virtual void ProcessFrame(VideoFrame *frame, OSD *osd,
     24                              FilterChain *filterList,
     25                              const PIPMap &pipPlayers,
     26                              FrameScanType scan);
    2527    void Show(FrameScanType );
    2628    void WindowResized(const QSize &new_size);
    27     bool InputChanged(const QSize &input_size,
    28                       float        aspect,
    29                       MythCodecID  av_codec_id,
    30                       void        *codec_private,
    31                       bool        &aspect_only);
     29    virtual bool InputChanged(const QSize &input_size,
     30                              float        aspect,
     31                              MythCodecID  av_codec_id,
     32                              void        *codec_private,
     33                              bool        &aspect_only);
    3234    DisplayInfo GetDisplayInfo(void);
    3335    void MoveResizeWindow(QRect new_rect) {;}
    3436    void UpdatePauseFrame(void);
     
    4547    void RemovePIP(NuppelVideoPlayer *pipplayer);
    4648    bool IsPIPSupported(void) const { return true; }
    4749    virtual MythPainter *GetOSDPainter(void) { return (MythPainter*)m_osd_painter; }
     50    bool hasHWAcceleration(void) const { return !codec_is_std(m_codec_id); }
    4851
    49   private:
    50     void TearDown(void);
     52  protected:
     53    virtual void TearDown(void);
     54    virtual void SetProfile(void);
    5155    bool SetupContext(void);
    5256    void DestroyContext(void);
    5357    void UpdateFrame(VideoFrame *frame, D3D9Image *img);
    5458
    55   private:
     59    MythCodecID             m_codec_id;
    5660    VideoFrame              m_pauseFrame;
    5761    QMutex                  m_lock;
    5862    HWND                    m_hWnd;
  • C:/mythtv/mythtv/libs/libmythtv/videoout_d3ddxva2.cpp

     
     1#include "videoout_d3ddxva2.h"
     2
     3#define LOC QString("VidOutD3DDXVA2: ")
     4#define ERR QString("VidOutD3DDXVA2 Error: ")
     5#define NUM_DXVA2_BUFS 30
     6
     7void VideoOutputD3DDXVA2::GetRenderOptions(render_opts &opts)
     8{
     9    opts.renderers->append("direct3ddxva2");
     10    (*opts.deints)["direct3ddxva2"].append("none");
     11    (*opts.osds)["direct3ddxva2"].append("direct3d");
     12    (*opts.safe_renderers)["dummy"].append("direct3ddxva2");
     13    (*opts.safe_renderers)["nuppel"].append("direct3ddxva2");
     14    if (opts.decoders->contains("dxva2"))
     15        (*opts.safe_renderers)["dxva2"].append("direct3ddxva2");
     16    if (opts.decoders->contains("ffmpeg"))
     17        (*opts.safe_renderers)["ffmpeg"].append("direct3ddxva2");
     18    if (opts.decoders->contains("libmpeg2"))
     19        (*opts.safe_renderers)["libmpeg2"].append("direct3ddxva2");
     20    opts.priorities->insert("direct3ddxva2", 100);
     21}
     22
     23VideoOutputD3DDXVA2::VideoOutputD3DDXVA2(MythCodecID codec_id)
     24  : VideoOutputD3D(codec_id), m_ctx(NULL)
     25{
     26}
     27
     28VideoOutputD3DDXVA2::~VideoOutputD3DDXVA2()
     29{
     30    TearDown();
     31}
     32
     33void VideoOutputD3DDXVA2::TearDown(void)
     34{
     35    QMutexLocker locker(&m_lock);
     36    DeleteContext();
     37}
     38
     39void VideoOutputD3DDXVA2::SetProfile(void)
     40{
     41    if (db_vdisp_profile)
     42        db_vdisp_profile->SetVideoRenderer("direct3ddxva2");
     43}
     44
     45bool VideoOutputD3DDXVA2::Init(int width, int height, float aspect, WId winid,
     46                               int winx, int winy, int winw, int winh, WId embedid)
     47{
     48    VERBOSE(VB_PLAYBACK, LOC + QString("Init with codec: %1").arg(toString(m_codec_id)));
     49    if (VideoOutputD3D::Init(width, height, aspect, winid, winx, winy, winw,
     50                             winh, embedid))
     51    {
     52        // TODO if this fails, we need to recreate software buffers
     53        QMutexLocker locker(&m_lock);
     54        if (codec_is_dxva2(m_codec_id))
     55        {
     56            if (!CreateContext())
     57                return false;
     58            return InitBuffers();
     59        }
     60        return true;
     61    }
     62    return false;
     63}
     64
     65bool VideoOutputD3DDXVA2::InputChanged(const QSize &input_size,
     66                                       float        aspect,
     67                                       MythCodecID  av_codec_id,
     68                                       void        *codec_private,
     69                                       bool        &aspect_only)
     70{
     71    VERBOSE(VB_PLAYBACK, LOC + QString("InputChanged(%1,%2,%3) %4->%5")
     72            .arg(input_size.width()).arg(input_size.height()).arg(aspect)
     73            .arg(toString(m_codec_id)).arg(toString(av_codec_id)));
     74
     75    if (!codec_is_dxva2(av_codec_id))
     76        return VideoOutputD3D::InputChanged(input_size, aspect, av_codec_id,
     77                                            codec_private, aspect_only);
     78
     79    QMutexLocker locker(&m_lock);
     80    bool cid_changed = (m_codec_id != av_codec_id);
     81    bool res_changed = input_size  != windows[0].GetVideoDim();
     82    bool asp_changed = aspect      != windows[0].GetVideoAspect();
     83    m_codec_id = av_codec_id;
     84
     85    if (!res_changed && !cid_changed)
     86    {
     87        if (asp_changed)
     88        {
     89            aspect_only = true;
     90            VideoAspectRatioChanged(aspect);
     91            MoveResize();
     92        }
     93        return true;
     94    }
     95
     96    TearDown();
     97    QRect disp = windows[0].GetDisplayVisibleRect();
     98    if (Init(input_size.width(), input_size.height(),
     99             aspect, m_hWnd, disp.left(),  disp.top(),
     100             disp.width(), disp.height(), m_hEmbedWnd))
     101    {
     102        BestDeint();
     103        return true;
     104    }
     105
     106    VERBOSE(VB_IMPORTANT, ERR + QString("Failed to re-initialise video output."));
     107    errorState = kError_Unknown;
     108
     109    return false;
     110}
     111
     112bool VideoOutputD3DDXVA2::CreateBuffers(void)
     113{
     114    if ((!codec_is_dxva2(m_codec_id)))
     115        return VideoOutputD3D::CreateBuffers();
     116
     117    vbuffers.Init(NUM_DXVA2_BUFS, true, 2, 1, 4, 1, false);
     118    VERBOSE(VB_PLAYBACK, LOC + QString("Created %1 empty buffers.")
     119                                       .arg(NUM_DXVA2_BUFS));
     120    return true;
     121}
     122
     123bool VideoOutputD3DDXVA2::InitBuffers(void)
     124{
     125    if ((!codec_is_dxva2(m_codec_id)) || !m_ctx)
     126        return false;
     127
     128    QMutexLocker locker(&m_lock);
     129    const QSize video_dim = windows[0].GetVideoDim();
     130    bool ok = true;
     131    for (int i = 0; i < NUM_DXVA2_BUFS; i++)
     132    {
     133        ok &= vbuffers.CreateBuffer(video_dim.width(),
     134                                    video_dim.height(), i,
     135                                    m_ctx->GetSurface(i), FMT_DXVA2);
     136    }
     137    if (ok)
     138        VERBOSE(VB_PLAYBACK, LOC + "Initialised DXVA2 buffers.");
     139    return ok;
     140}
     141
     142bool VideoOutputD3DDXVA2::CreateContext(void)
     143{
     144    QMutexLocker locker(&m_lock);
     145    if (m_ctx)
     146        DeleteContext();
     147    QSize video_dim = windows[0].GetVideoDim();
     148    m_ctx = new DXVA2Context(m_render->GetDevice(), NUM_DXVA2_BUFS, m_codec_id,
     149                             video_dim.width(), video_dim.height());
     150    return (m_ctx && m_ctx->Init());
     151}
     152
     153void VideoOutputD3DDXVA2::DeleteContext(void)
     154{
     155    QMutexLocker locker(&m_lock);
     156    delete m_ctx;
     157    m_ctx = NULL;
     158}
     159
     160void VideoOutputD3DDXVA2::ProcessFrame(VideoFrame *frame, OSD *osd,
     161                                       FilterChain *filterList,
     162                                       const PIPMap &pipPlayers,
     163                                       FrameScanType scan)
     164{
     165    bool paused = !frame;
     166    VideoOutputD3D::ProcessFrame(frame, osd, filterList, pipPlayers, scan);
     167    if (!paused && frame->codec == FMT_DXVA2 && frame->buf && m_render)
     168    {
     169        m_render_valid |= m_render->Test(m_render_reset);
     170        if (m_render_reset)
     171            SetupContext();
     172        if (m_render_valid && m_video)
     173            m_render->CopyFrame(frame->buf, m_video);
     174    }
     175}
     176
     177void* VideoOutputD3DDXVA2::GetDXVA2Context(void)
     178{
     179    if (m_ctx)
     180        return (void*)&m_ctx->m_context;
     181    return NULL;
     182}
     183
     184QStringList VideoOutputD3DDXVA2::GetAllowedRenderers(
     185    MythCodecID myth_codec_id, const QSize &video_dim)
     186{
     187    (void) video_dim;
     188    QStringList list;
     189    if ((codec_is_std(myth_codec_id) || codec_is_dxva2(myth_codec_id)) &&
     190         !getenv("NO_DXVA2"))
     191    {
     192        list += "direct3ddxva2";
     193    }
     194
     195    return list;
     196}
     197
     198MythCodecID VideoOutputD3DDXVA2::GetBestSupportedCodec(
     199    uint width,       uint height,
     200    uint stream_type, bool no_acceleration,
     201    PixelFormat &pix_fmt)
     202{
     203    QSize size(width, height);
     204    bool use_cpu = no_acceleration;
     205    VideoDisplayProfile vdp;
     206    vdp.SetInput(size);
     207    QString dec = vdp.GetDecoder();
     208
     209    MythCodecID test_cid = (MythCodecID)(kCodec_MPEG1_DXVA2 + (stream_type-1));
     210    use_cpu |= !codec_is_dxva2(test_cid);
     211    use_cpu |= (test_cid != kCodec_H264_DXVA2); // FIXME
     212    pix_fmt = PIX_FMT_DXVA2_VLD;
     213    if ((dec != "dxva2") || getenv("NO_DXVA2") || use_cpu)
     214        return (MythCodecID)(kCodec_MPEG1 + (stream_type-1));
     215
     216    return test_cid;
     217}
  • C:/mythtv/mythtv/libs/libmythtv/mythcodecid.h

     
    8787    kCodec_WMV3_VAAPI,
    8888
    8989    kCodec_VAAPI_END,
     90
     91    kCodec_DXVA2_BEGIN = kCodec_VAAPI_END,
     92
     93    kCodec_MPEG1_DXVA2,
     94    kCodec_MPEG2_DXVA2,
     95    kCodec_H263_DXVA2,
     96    kCodec_MPEG4_DXVA2,
     97    kCodec_H264_DXVA2,
     98    kCodec_VC1_DXVA2,
     99    kCodec_WMV3_DXVA2,
     100
     101    kCodec_DXVA2_END,
    90102} MythCodecID;
    91103
    92104// MythCodecID convenience functions
     
    106118                              (id != kCodec_H263_VDPAU))
    107119#define codec_is_vaapi(id)    (id > kCodec_VAAPI_BEGIN) &&\
    108120                              (id < kCodec_VAAPI_END)
     121#define codec_is_dxva2(id)    (id > kCodec_DXVA2_BEGIN) &&\
     122                              (id < kCodec_DXVA2_END)
    109123
    110124QString get_encoding_type(MythCodecID codecid);
    111125QString get_decoder_name(MythCodecID codec_id, bool libmpeg2);
     
    129143#define CODEC_IS_DVDV(codec) (codec && (codec->id == CODEC_ID_MPEG2VIDEO_DVDV))
    130144#define CODEC_IS_VDPAU(codec) (codec &&\
    131145                               codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
    132 #define CODEC_IS_HWACCEL(codec)  (CODEC_IS_XVMC(codec)  ||\
    133                                   CODEC_IS_VDPAU(codec) ||\
    134                                   CODEC_IS_DVDV(codec))
     146#define CODEC_IS_DXVA2(codec, enc) (codec && enc->pix_fmt == PIX_FMT_DXVA2_VLD)
     147#define CODEC_IS_HWACCEL(codec, enc) (CODEC_IS_XVMC(codec)  ||\
     148                                      CODEC_IS_VDPAU(codec) ||\
     149                                      CODEC_IS_DVDV(codec)  ||\
     150                                      CODEC_IS_DXVA2(codec, enc))
    135151
    136152#endif // _MYTH_CODEC_ID_H_
  • C:/mythtv/mythtv/libs/libmythtv/dxva2context.h

     
     1#ifndef DXVA2CONTEXT_H
     2#define DXVA2CONTEXT_H
     3
     4#include <windows.h>
     5#include <d3d9.h>
     6
     7extern "C" {
     8#include "libavcodec/avcodec.h"
     9#include "libavcodec/dxva2.h"
     10}
     11
     12#include "mythcodecid.h"
     13#include "dxva2api.h"
     14
     15class DXVA2Context
     16{
     17  public:
     18    static bool LoadDXVA2(void);
     19    DXVA2Context(IDirect3DDevice9 *device, uint num_bufs, MythCodecID codec_id,
     20                 uint width, uint height);
     21   ~DXVA2Context(void);
     22    bool Init(void);
     23    bool GetInputOutput(void);
     24    void InitFormat(void);
     25    bool TestTarget(const GUID &guid);
     26    bool GetDecoderConfig(void);
     27    bool CreateSurfaces(void);
     28    bool CreateDecoder(void);
     29    void* GetSurface(uint num);
     30
     31    IDirect3DDevice9            *m_d3dDevice;
     32    IDirectXVideoDecoderService *m_service;
     33    struct dxva_context          m_context;
     34    MythCodecID                  m_codec_id;
     35    GUID                         m_input;
     36    DXVA2_VideoDesc              m_format;
     37    uint                         m_width;
     38    uint                         m_height;
     39};
     40
     41#endif // DXVA2CONTEXT_H
  • C:/mythtv/mythtv/libs/libmythtv/mythcodecid.cpp

     
    107107        case kCodec_WMV3_VAAPI:
    108108            return "WMV3 VAAPI";
    109109
     110        case kCodec_MPEG1_DXVA2:
     111            return "MPEG1 DXVA2";
     112        case kCodec_MPEG2_DXVA2:
     113            return "MPEG2 DXVA2";
     114        case kCodec_H263_DXVA2:
     115            return "H.263 DXVA2";
     116        case kCodec_MPEG4_DXVA2:
     117            return "MPEG4 DXVA2";
     118        case kCodec_H264_DXVA2:
     119            return "H.264 DXVA2";
     120        case kCodec_VC1_DXVA2:
     121            return "VC1 DXVA2";
     122        case kCodec_WMV3_DXVA2:
     123            return "WMV3 DXVA2";
     124
    110125        default:
    111126            break;
    112127    }
     
    265280            ret = CODEC_ID_WMV3;
    266281            break;
    267282
     283        case kCodec_MPEG1_DXVA2:
     284            ret = CODEC_ID_MPEG1VIDEO;
     285            break;
     286        case kCodec_MPEG2_DXVA2:
     287            ret = CODEC_ID_MPEG2VIDEO;
     288            break;
     289        case kCodec_H263_DXVA2:
     290            ret = CODEC_ID_H263;
     291            break;
     292        case kCodec_MPEG4_DXVA2:
     293            ret = CODEC_ID_MPEG4;
     294            break;
     295        case kCodec_H264_DXVA2:
     296            ret = CODEC_ID_H264;
     297            break;
     298        case kCodec_VC1_DXVA2:
     299            ret = CODEC_ID_VC1;
     300            break;
     301        case kCodec_WMV3_DXVA2:
     302            ret = CODEC_ID_WMV3;
     303            break;
     304
    268305        default:
    269306            VERBOSE(VB_IMPORTANT,
    270307                    QString("Error: MythCodecID %1 has not been "
     
    315352        case kCodec_MPEG1_DVDV:
    316353        case kCodec_MPEG1_VDPAU:
    317354        case kCodec_MPEG1_VAAPI:
     355        case kCodec_MPEG1_DXVA2:
    318356        case kCodec_MPEG2:
    319357        case kCodec_MPEG2_XVMC:
    320358        case kCodec_MPEG2_IDCT:
     
    322360        case kCodec_MPEG2_DVDV:
    323361        case kCodec_MPEG2_VDPAU:
    324362        case kCodec_MPEG2_VAAPI:
     363        case kCodec_MPEG2_DXVA2:
    325364            return "MPEG-2";
    326365
    327366        case kCodec_H263:
     
    331370        case kCodec_H263_DVDV:
    332371        case kCodec_H263_VDPAU:
    333372        case kCodec_H263_VAAPI:
     373        case kCodec_H263_DXVA2:
    334374            return "H.263";
    335375
    336376        case kCodec_NUV_MPEG4:
     
    341381        case kCodec_MPEG4_DVDV:
    342382        case kCodec_MPEG4_VDPAU:
    343383        case kCodec_MPEG4_VAAPI:
     384        case kCodec_MPEG4_DXVA2:
    344385            return "MPEG-4";
    345386
    346387        case kCodec_H264:
     
    350391        case kCodec_H264_DVDV:
    351392        case kCodec_H264_VDPAU:
    352393        case kCodec_H264_VAAPI:
     394        case kCodec_H264_DXVA2:
    353395            return "H.264";
    354396
    355397        case kCodec_NONE:
     
    359401        case kCodec_DVDV_END:
    360402        case kCodec_VDPAU_END:
    361403        case kCodec_VAAPI_END:
     404        case kCodec_DXVA2_END:
    362405            return QString::null;
    363406    }
    364407
     
    385428    if (codec_is_vaapi(codec_id))
    386429        return "vaapi";
    387430
     431    if (codec_is_dxva2(codec_id))
     432        return "dxva2";
     433
    388434    return "ffmpeg";
    389435}
  • C:/mythtv/mythtv/libs/libmythtv/videooutbase.cpp

     
    2626
    2727#ifdef USING_MINGW
    2828#include "videoout_d3d.h"
     29#ifdef USING_DXVA2
     30#include "videoout_d3ddxva2.h"
    2931#endif
     32#endif
    3033
    3134#ifdef Q_OS_MACX
    3235#include "videoout_quartz.h"
     
    7982
    8083#ifdef USING_MINGW
    8184    VideoOutputD3D::GetRenderOptions(opts, cpudeints);
     85#ifdef USING_DXVA2
     86    VideoOutputD3DDXVA2::GetRenderOptions(opts);
    8287#endif
     88#endif
    8389
    8490#ifdef USING_XV
    8591    VideoOutputXv::GetRenderOptions(opts, cpudeints);
     
    121127
    122128#ifdef USING_MINGW
    123129    renderers += VideoOutputD3D::GetAllowedRenderers(codec_id, video_dim);
     130#ifdef USING_DXVA2
     131    renderers += VideoOutputD3DDXVA2::GetAllowedRenderers(codec_id, video_dim);
    124132#endif
     133#endif
    125134
    126135#ifdef USING_XV
    127136    const QStringList xvlist =
     
    187196
    188197#ifdef USING_MINGW
    189198        if (renderer == "direct3d")
    190             vo = new VideoOutputD3D();
     199            vo = new VideoOutputD3D(codec_id);
     200#ifdef USING_DXVA2
     201        if (renderer == "direct3ddxva2")
     202            vo = new VideoOutputD3DDXVA2(codec_id);
     203#endif
    191204#endif // USING_MINGW
    192205
    193206#ifdef Q_OS_MACX
  • C:/mythtv/mythtv/libs/libavcodec/allcodecs.c

     
    5555
    5656    /* hardware accelerators */
    5757    REGISTER_HWACCEL (H263_VAAPI, h263_vaapi);
    58     REGISTER_HWACCEL (H264_DXVA2, h264_dxva2);
     58    //REGISTER_HWACCEL (H264_DXVA2, h264_dxva2);
     59    extern AVHWAccel h264_dxva2_hwaccel;
     60    av_register_hwaccel(&h264_dxva2_hwaccel);
    5961    REGISTER_HWACCEL (H264_VAAPI, h264_vaapi);
    6062    REGISTER_HWACCEL (MPEG2_VAAPI, mpeg2_vaapi);
    6163    REGISTER_HWACCEL (MPEG4_VAAPI, mpeg4_vaapi);
  • C:/mythtv/mythtv/libs/libmythui/mythrender_d3d9.cpp

     
    9090    return m_valid;
    9191}
    9292
     93bool D3D9Image::UpdateImage(IDirect3DSurface9 *surface)
     94{
     95    if (m_valid)
     96        return m_render->StretchRect(m_texture, surface, false);
     97    return false;
     98}
     99
    93100bool D3D9Image::UpdateImage(const MythImage *img)
    94101{
    95102    bool result = true;
     
    305312
    306313    if (D3D_OK != m_d3d->CreateDevice(D3DADAPTER_DEFAULT,
    307314                                      D3DDEVTYPE_HAL, d3dpp.hDeviceWindow,
    308                                       D3DCREATE_SOFTWARE_VERTEXPROCESSING,
     315                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING |
     316                                      D3DCREATE_MULTITHREADED,
    309317                                      &d3dpp, &m_d3dDevice))
    310318    {
    311319        VERBOSE(VB_IMPORTANT, D3DERR + "Could not create the D3D device.");
     
    414422    return true;
    415423}
    416424
     425void MythRenderD3D9::CopyFrame(void* surface, D3D9Image *img)
     426{
     427    if (surface && img)
     428        img->UpdateImage((IDirect3DSurface9*)surface);
     429}
     430
    417431bool MythRenderD3D9::StretchRect(IDirect3DTexture9 *texture,
    418                               IDirect3DSurface9 *surface)
     432                                 IDirect3DSurface9 *surface,
     433                                 bool known_surface)
    419434{
    420435    if (!m_textures.contains(texture) ||
    421         !m_surfaces.contains(surface))
     436       (!m_surfaces.contains(surface) && known_surface))
    422437        return false;
    423438
    424439    QMutexLocker locker(&m_lock);
  • C:/mythtv/mythtv/libs/libmythui/mythrender_d3d9.h

     
    1919    bool     IsValid(void) const { return m_valid; }
    2020    QSize    GetSize(void) const { return m_size;  }
    2121    bool     SetAsRenderTarget(void);
     22    bool     UpdateImage(IDirect3DSurface9 *surface);
    2223    bool     UpdateImage(const MythImage *img);
    2324    bool     UpdateVertices(const QRect &dvr, const QRect &vr, int alpha = 255,
    2425                            bool video = false);
     
    4546    bool Create(QSize size, HWND window);
    4647    bool Test(bool &reset);
    4748
     49    IDirect3DDevice9* GetDevice(void) { return m_d3dDevice; }
    4850    bool ClearBuffer(void);
    4951    bool Begin(void);
    5052    bool End(void);
    51     bool StretchRect(IDirect3DTexture9 *texture, IDirect3DSurface9 *surface);
     53    void CopyFrame(void* surface, D3D9Image *img);
     54    bool StretchRect(IDirect3DTexture9 *texture, IDirect3DSurface9 *surface,
     55                     bool known_surface = true);
    5256    bool DrawTexturedQuad(IDirect3DVertexBuffer9 *vertexbuffer);
    5357    void DrawRect(const QRect &rect,  const QColor &color);
    5458    bool Present(HWND win);