--- /dev/null
+# This file is used to ignore files which are generated
+# ----------------------------------------------------------------------------
+
+*~
+*.a
+*.core
+*.moc
+*.o
+*.obj
+*.orig
+*.rej
+*.so
+*_pch.h.cpp
+*_resource.rc
+*.qm
+.#*
+*.*#
+core
+.qmake.cache
+tags
+.DS_Store
+*.debug
+Makefile*
+*.prl
+*.app
+moc_*.cpp
+ui_*.h
+qrc_*.cpp
+
+# qtcreator generated files
+*.pro.user
+*.pro.user.*
+*.autosave
+
+# xemacs temporary files
+*.flc
+
+# Vim temporary files
+.*.swp
+
+# Visual Studio generated files
+*.ib_pdb_index
+*.idb
+*.ilk
+*.pdb
+*.sln
+*.suo
+*.vcproj
+*vcproj.*.*.user
+*.ncb
+*.exp
+
+# MinGW generated files
+*.Debug
+*.Release
+
+# Directories to ignore
+# ---------------------
+
+build
+debug
+release
+lib/qtsingleapplication/lib
+lib/qtsingleapplication/examples
+lib/qtsingleapplication/doc
+.tmp
+qtc-gdbmacros
+
+# Binaries
+# --------
+build/*.dll
+build/*.lib
+build/*.exe
+build/*.so*
+
+
--- /dev/null
+TEMPLATE = subdirs
+CONFIG += ordered
+
+include(config.pri)
+
+SUBDIRS += aniplayer2
+win32: SUBDIRS += aniplayer2_dshow
+SUBDIRS += player
--- /dev/null
+#include "aniplayer.h"
+
+
+AniPlayer::AniPlayer(QObject *parent) : QObject(parent), m_state(Stopped)
+{
+}
+
+AniPlayer::~AniPlayer()
+{
+}
+
+AniPlayer::State AniPlayer::state() const
+{
+ return m_state;
+}
+
+void AniPlayer::open(const QString &file)
+{
+ iopen(file);
+}
+
+void AniPlayer::play()
+{
+ iplay();
+}
+
+void AniPlayer::pause()
+{
+ ipause();
+}
+
+void AniPlayer::stop()
+{
+ istop();
+}
+
+void AniPlayer::togglePause()
+{
+ if (m_state == Paused)
+ play();
+ else
+ pause();
+}
--- /dev/null
+#ifndef ANIPLAYER_H
+#define ANIPLAYER_H
+
+#include "aniplayer2_global.h"
+
+#include <QObject>
+#include <QString>
+
+class VideoWidget;
+
+class ANIPLAYER2SHARED_EXPORT AniPlayer : public QObject
+{
+ Q_OBJECT
+public:
+ enum State
+ {
+ Stopped,
+ Playing,
+ Paused,
+ Error
+ };
+
+ AniPlayer(QObject *parent = 0);
+ virtual ~AniPlayer();
+
+ virtual VideoWidget *videoWidget() = 0;
+ virtual void widgetChanged() = 0;
+
+ State state() const;
+
+public slots:
+ void open(const QString &file);
+ void play();
+ void pause();
+ void stop();
+
+ void togglePause();
+
+
+protected:
+ virtual void iopen(const QString &file) = 0;
+ virtual void iplay() = 0;
+ virtual void ipause() = 0;
+ virtual void istop() = 0;
+
+ State m_state;
+};
+
+#endif // ANIPLAYER_H
--- /dev/null
+INCLUDEPATH += $$PWD
+INCLUDEPATH += $$PWD
+DEPENDPATH += $$PWD
+LIBS += -laniplayer2
+LIBS += -L$$PWD/../build
--- /dev/null
+QT += core gui
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+TARGET = aniplayer2
+DESTDIR = ../build
+
+TEMPLATE = lib
+
+DEFINES += ANIPLAYER2_LIBRARY
+
+SOURCES += aniplayer.cpp
+
+HEADERS += aniplayer2_global.h \
+ aniplayer.h\
+ videowidget.h
+
+
+HEADERS += \
+
+
+SOURCES += \
+ videowidget.cpp
+
+include(../config.pri)
--- /dev/null
+#ifndef ANIPLAYER2_GLOBAL_H
+#define ANIPLAYER2_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+
+#if defined(ANIPLAYER2_LIBRARY)
+# define ANIPLAYER2SHARED_EXPORT Q_DECL_EXPORT
+#else
+# define ANIPLAYER2SHARED_EXPORT Q_DECL_IMPORT
+#endif
+
+#endif // LIBANIPLAYER2_GLOBAL_H
--- /dev/null
+#include "videowidget.h"
+
+VideoWidget::VideoWidget(QWidget *parent) :
+ QWidget(parent)
+{
+}
--- /dev/null
+#ifndef VIDEOWIDGET_H
+#define VIDEOWIDGET_H
+
+#include "aniplayer2_global.h"
+#include <QWidget>
+
+class ANIPLAYER2SHARED_EXPORT VideoWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit VideoWidget(QWidget *parent = 0);
+
+signals:
+
+public slots:
+
+};
+
+#endif // VIDEOWIDGET_H
--- /dev/null
+INCLUDEPATH += $$PWD
+INCLUDEPATH += $$PWD
+DEPENDPATH += $$PWD
+LIBS += -laniplayer2_dshow
+LIBS += -L$$PWD/../build
--- /dev/null
+QT += core gui
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+TARGET = aniplayer2_dshow
+DESTDIR = ../build
+
+TEMPLATE = lib
+
+DEFINES += ANIPLAYER2_DSHOW_LIBRARY
+
+
+HEADERS += aniplayer2_dshow_global.h
+
+HEADERS += \
+ aniplayerdshow.h \
+ aniplayerdshowinternal.h \
+ videowidgetdshow.h
+
+
+SOURCES += \
+ aniplayerdshow.cpp \
+ aniplayerdshowinternal.cpp \
+ videowidgetdshow.cpp
+
+include(../config.pri)
+include(../aniplayer2/aniplayer2.pri)
+
+LIBS += -lstrmiids -lole32
--- /dev/null
+#ifndef ANIPLAYER2_DSHOW_GLOBAL_H
+#define ANIPLAYER2_DSHOW_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+
+#if defined(ANIPLAYER2_DSHOW_LIBRARY)
+# define ANIPLAYER2_DSHOWSHARED_EXPORT Q_DECL_EXPORT
+#else
+# define ANIPLAYER2_DSHOWSHARED_EXPORT Q_DECL_IMPORT
+#endif
+
+#endif // ANIPLAYER2_DSHOW_GLOBAL_H
--- /dev/null
+#include "aniplayerdshow.h"
+
+#include "aniplayerdshowinternal.h"
+#include "videowidgetdshow.h"
+
+#include <QDebug>
+
+AniPlayerDShow::AniPlayerDShow(QObject *parent) :
+ AniPlayer(parent)
+{
+ HRESULT hr;
+
+ hr = CoInitialize(NULL);
+ if (FAILED(hr))
+ qDebug() << "Failed to initialize COM";
+
+ m_videoWidget = new VideoWidgetDShow(this);
+ d = new AniPlayerDShowInternal(this);
+}
+
+AniPlayerDShow::~AniPlayerDShow()
+{
+ CoUninitialize();
+}
+
+VideoWidget *AniPlayerDShow::videoWidget()
+{
+ return m_videoWidget;
+}
+
+void AniPlayerDShow::widgetChanged()
+{
+ d->UpdateVideoWindow(0);
+ d->Repaint();
+}
+
+void AniPlayerDShow::iopen(const QString &file)
+{
+ d->OpenFile(reinterpret_cast<const wchar_t *>(file.utf16()));
+}
+
+void AniPlayerDShow::iplay()
+{
+ if (m_state == Paused || m_state == Stopped)
+ if (d->play())
+ m_state = Playing;
+}
+
+void AniPlayerDShow::ipause()
+{
+ if (m_state != Playing)
+ return;
+
+ if (d->pause())
+ m_state = Paused;
+}
+
+void AniPlayerDShow::istop()
+{
+ if (m_state == Playing || m_state == Paused)
+ if (d->stop())
+ m_state = Stopped;
+}
--- /dev/null
+#ifndef ANIPLAYERDSHOW_H
+#define ANIPLAYERDSHOW_H
+
+#include "aniplayer2_dshow_global.h"
+#include <aniplayer.h>
+
+class VideoWidgetDShow;
+
+struct AniPlayerDShowInternal;
+
+class ANIPLAYER2_DSHOWSHARED_EXPORT AniPlayerDShow : public AniPlayer
+{
+ Q_OBJECT
+public:
+ explicit AniPlayerDShow(QObject *parent = 0);
+ ~AniPlayerDShow();
+
+ VideoWidget *videoWidget();
+ void widgetChanged();
+
+
+signals:
+
+protected:
+ void iopen(const QString &file);
+ void iplay();
+ void ipause();
+ void istop();
+
+private:
+ AniPlayerDShowInternal *d;
+
+ VideoWidgetDShow *m_videoWidget;
+};
+
+#endif // ANIPLAYERDSHOW_H
--- /dev/null
+#include "aniplayerdshowinternal.h"
+
+#include "videowidgetdshow.h"
+#include "aniplayerdshow.h"
+
+#include <Dshow.h>
+#include <Evr.h>
+
+HRESULT IsPinConnected(IPin *pPin, BOOL *pResult);
+HRESULT IsPinDirection(IPin *pPin, PIN_DIRECTION dir, BOOL *pResult);
+HRESULT AddFilterByCLSID(IGraphBuilder *pGraph, REFGUID clsid, IBaseFilter **ppF, LPCWSTR wszName);
+HRESULT FindConnectedPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin);
+
+AniPlayerDShowInternal::AniPlayerDShowInternal(AniPlayerDShow *player_) : player(player_)
+{
+ pGraph = 0;
+ pControl = 0;
+ pEvent = 0;
+ pSeeking = 0;
+
+ pEVR = 0;
+ pVideoDisplay = 0;
+}
+
+AniPlayerDShowInternal::~AniPlayerDShowInternal()
+{
+ SafeRelease(&pControl);
+ SafeRelease(&pEvent);
+ SafeRelease(&pGraph);
+ SafeRelease(&pSeeking)
+}
+
+bool AniPlayerDShowInternal::play()
+{
+ HRESULT hr = pControl->Run();
+ return SUCCEEDED(hr);
+}
+
+bool AniPlayerDShowInternal::pause()
+{
+ HRESULT hr = pControl->Pause();
+ return SUCCEEDED(hr);
+}
+
+bool AniPlayerDShowInternal::stop()
+{
+ HRESULT hr = pControl->Stop();
+ return SUCCEEDED(hr);
+}
+
+QSize AniPlayerDShowInternal::videoSize() const
+{
+ if (!pVideoDisplay)
+ return QSize();
+
+ SIZE nativeSize;
+ SIZE aspectRatioSize;
+
+ pVideoDisplay->GetNativeVideoSize(&nativeSize, &aspectRatioSize);
+
+ return QSize(nativeSize.cx, nativeSize.cy);
+}
+
+HRESULT AniPlayerDShowInternal::InitializeGraph()
+{
+ TearDownGraph();
+
+ // Create the Filter Graph Manager.
+ HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL,
+ CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pGraph));
+ if (FAILED(hr))
+ {
+ goto done;
+ }
+
+ hr = pGraph->QueryInterface(IID_PPV_ARGS(&pControl));
+ if (FAILED(hr))
+ {
+ goto done;
+ }
+
+ hr = pGraph->QueryInterface(IID_PPV_ARGS(&pEvent));
+ if (FAILED(hr))
+ {
+ goto done;
+ }
+/*
+ // Set up event notification.
+ hr = pEvent->SetNotifyWindow((OAHWND)m_hwnd, WM_GRAPH_EVENT, NULL);
+ if (FAILED(hr))
+ {
+ goto done;
+ }
+*/
+// m_state = STATE_STOPPED;
+
+done:
+ return hr;
+}
+
+void AniPlayerDShowInternal::TearDownGraph()
+{
+/*
+ // Stop sending event messages
+ if (pEvent)
+ {
+ pEvent->SetNotifyWindow((OAHWND)NULL, NULL, NULL);
+ }
+*/
+ SafeRelease(&pGraph);
+ SafeRelease(&pControl);
+ SafeRelease(&pEvent);
+ SafeRelease(&pSeeking);
+
+// delete m_pVideo;
+// pVideo = NULL;
+
+// m_state = STATE_NO_GRAPH;
+}
+
+
+HRESULT AniPlayerDShowInternal::RenderStreams(IBaseFilter *pSource)
+{
+ BOOL bRenderedAnyPin = FALSE;
+
+ IFilterGraph2 *pGraph2 = NULL;
+ IEnumPins *pEnum = NULL;
+ IBaseFilter *pAudioRenderer = NULL;
+ HRESULT hr = pGraph->QueryInterface(IID_PPV_ARGS(&pGraph2));
+ if (FAILED(hr))
+ {
+ goto done;
+ }
+
+ // Add the video renderer to the graph
+ hr = CreateVideoRenderer();
+ if (FAILED(hr))
+ {
+ goto done;
+ }
+
+ // Add the DSound Renderer to the graph.
+ hr = AddFilterByCLSID(pGraph, CLSID_DSoundRender,
+ &pAudioRenderer, L"Audio Renderer");
+ if (FAILED(hr))
+ {
+ goto done;
+ }
+
+ // Enumerate the pins on the source filter.
+ hr = pSource->EnumPins(&pEnum);
+ if (FAILED(hr))
+ {
+ goto done;
+ }
+
+ // Loop through all the pins
+ IPin *pPin;
+ while (S_OK == pEnum->Next(1, &pPin, NULL))
+ {
+ // Try to render this pin.
+ // It's OK if we fail some pins, if at least one pin renders.
+ HRESULT hr2 = pGraph2->RenderEx(pPin, AM_RENDEREX_RENDERTOEXISTINGRENDERERS, NULL);
+
+ pPin->Release();
+ if (SUCCEEDED(hr2))
+ {
+ bRenderedAnyPin = TRUE;
+ }
+ }
+
+ hr = FinalizeGraph();
+ if (FAILED(hr))
+ {
+ goto done;
+ }
+
+ // Remove the audio renderer, if not used.
+ BOOL bRemoved;
+ hr = RemoveUnconnectedRenderer(pGraph, pAudioRenderer, &bRemoved);
+
+done:
+ SafeRelease(&pEnum);
+ SafeRelease(&pAudioRenderer);
+ SafeRelease(&pGraph2);
+
+ // If we succeeded to this point, make sure we rendered at least one
+ // stream.
+ if (SUCCEEDED(hr))
+ {
+ if (!bRenderedAnyPin)
+ {
+ hr = VFW_E_CANNOT_RENDER;
+ }
+ }
+ return hr;
+}
+
+HRESULT AniPlayerDShowInternal::RemoveUnconnectedRenderer(IGraphBuilder *pGraph, IBaseFilter *pRenderer, BOOL *pbRemoved)
+{
+ IPin *pPin = NULL;
+
+ *pbRemoved = FALSE;
+
+ // Look for a connected input pin on the renderer.
+
+ HRESULT hr = FindConnectedPin(pRenderer, PINDIR_INPUT, &pPin);
+ SafeRelease(&pPin);
+
+ // If this function succeeds, the renderer is connected, so we don't remove it.
+ // If it fails, it means the renderer is not connected to anything, so
+ // we remove it.
+
+ if (FAILED(hr))
+ {
+ hr = pGraph->RemoveFilter(pRenderer);
+ *pbRemoved = TRUE;
+ }
+
+ return hr;
+}
+
+HRESULT AniPlayerDShowInternal::AddVideoRenderer()
+{
+ IBaseFilter *npEVR = NULL;
+
+ HRESULT hr = AddFilterByCLSID(pGraph, CLSID_EnhancedVideoRenderer, &npEVR, L"EVR");
+
+ if (FAILED(hr))
+ {
+ goto done;
+ }
+
+ hr = InitializeEVR(npEVR, &pVideoDisplay);
+ if (FAILED(hr))
+ {
+ goto done;
+ }
+
+ // Note: Because IMFVideoDisplayControl is a service interface,
+ // you cannot QI the pointer to get back the IBaseFilter pointer.
+ // Therefore, we need to cache the IBaseFilter pointer.
+
+ pEVR = npEVR;
+ pEVR->AddRef();
+
+done:
+ SafeRelease(&npEVR);
+ return hr;
+}
+
+HRESULT AniPlayerDShowInternal::CreateVideoRenderer()
+{
+ HRESULT hr = AddVideoRenderer();
+
+ return hr;
+}
+
+HRESULT AniPlayerDShowInternal::OpenFile(PCWSTR pszFileName)
+{
+ IBaseFilter *pSource = NULL;
+
+ // Create a new filter graph. (This also closes the old one, if any.)
+ HRESULT hr = InitializeGraph();
+ if (FAILED(hr))
+ {
+ goto done;
+ }
+
+ // Add the source filter to the graph.
+ hr = pGraph->AddSourceFilter(pszFileName, NULL, &pSource);
+ if (FAILED(hr))
+ {
+ goto done;
+ }
+
+ // Try to render the streams.
+ hr = RenderStreams(pSource);
+
+done:
+ if (FAILED(hr))
+ {
+ TearDownGraph();
+ }
+ SafeRelease(&pSource);
+ return hr;
+}
+
+HRESULT AniPlayerDShowInternal::Repaint()
+{
+ if (pVideoDisplay)
+ {
+ return pVideoDisplay->RepaintVideo();
+ }
+ else
+ {
+ return S_OK;
+ }
+}
+
+HRESULT AniPlayerDShowInternal::UpdateVideoWindow(const LPRECT prc)
+{
+ if (pVideoDisplay == NULL)
+ {
+ return S_OK; // no-op
+ }
+
+ if (prc)
+ {
+ return pVideoDisplay->SetVideoPosition(NULL, prc);
+ }
+ else
+ {
+
+ RECT rc;
+ GetClientRect(hwnd(), &rc);
+ return pVideoDisplay->SetVideoPosition(NULL, &rc);
+ }
+}
+
+HRESULT AniPlayerDShowInternal::InitializeEVR(IBaseFilter *pEVR, IMFVideoDisplayControl **ppDisplayControl)
+{
+ IMFGetService *pGS = NULL;
+ IMFVideoDisplayControl *pDisplay = NULL;
+
+ HRESULT hr = pEVR->QueryInterface(IID_PPV_ARGS(&pGS));
+ if (FAILED(hr))
+ {
+ goto done;
+ }
+
+ hr = pGS->GetService(MR_VIDEO_RENDER_SERVICE, IID_PPV_ARGS(&pDisplay));
+ if (FAILED(hr))
+ {
+ goto done;
+ }
+
+ // Set the clipping window.
+ hr = pDisplay->SetVideoWindow(hwnd());
+ if (FAILED(hr))
+ {
+ goto done;
+ }
+
+ // Preserve aspect ratio by letter-boxing
+ hr = pDisplay->SetAspectRatioMode(MFVideoARMode_PreservePicture);
+ if (FAILED(hr))
+ {
+ goto done;
+ }
+
+ // Return the IMFVideoDisplayControl pointer to the caller.
+ *ppDisplayControl = pDisplay;
+ (*ppDisplayControl)->AddRef();
+
+done:
+ SafeRelease(&pGS);
+ SafeRelease(&pDisplay);
+ return hr;
+}
+
+HRESULT IsPinConnected(IPin *pPin, BOOL *pResult)
+{
+ IPin *pTmp = NULL;
+ HRESULT hr = pPin->ConnectedTo(&pTmp);
+ if (SUCCEEDED(hr))
+ {
+ *pResult = TRUE;
+ }
+ else if (hr == VFW_E_NOT_CONNECTED)
+ {
+ // The pin is not connected. This is not an error for our purposes.
+ *pResult = FALSE;
+ hr = S_OK;
+ }
+
+ SafeRelease(&pTmp);
+ return hr;
+}
+
+HRESULT IsPinDirection(IPin *pPin, PIN_DIRECTION dir, BOOL *pResult)
+{
+ PIN_DIRECTION pinDir;
+ HRESULT hr = pPin->QueryDirection(&pinDir);
+ if (SUCCEEDED(hr))
+ {
+ *pResult = (pinDir == dir);
+ }
+ return hr;
+}
+
+HRESULT AddFilterByCLSID(IGraphBuilder *pGraph, const GUID &clsid, IBaseFilter **ppF, LPCWSTR wszName)
+{
+ *ppF = 0;
+
+ IBaseFilter *pFilter = NULL;
+
+ HRESULT hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER,
+ IID_PPV_ARGS(&pFilter));
+ if (FAILED(hr))
+ {
+ goto done;
+ }
+
+ hr = pGraph->AddFilter(pFilter, wszName);
+ if (FAILED(hr))
+ {
+ goto done;
+ }
+
+ *ppF = pFilter;
+ (*ppF)->AddRef();
+
+done:
+ SafeRelease(&pFilter);
+ return hr;
+}
+
+HRESULT FindConnectedPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin)
+{
+ *ppPin = NULL;
+
+ IEnumPins *pEnum = NULL;
+ IPin *pPin = NULL;
+
+ HRESULT hr = pFilter->EnumPins(&pEnum);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+
+ BOOL bFound = FALSE;
+ while (S_OK == pEnum->Next(1, &pPin, NULL))
+ {
+ BOOL bIsConnected;
+ hr = IsPinConnected(pPin, &bIsConnected);
+ if (SUCCEEDED(hr))
+ {
+ if (bIsConnected)
+ {
+ hr = IsPinDirection(pPin, PinDir, &bFound);
+ }
+ }
+
+ if (FAILED(hr))
+ {
+ pPin->Release();
+ break;
+ }
+ if (bFound)
+ {
+ *ppPin = pPin;
+ break;
+ }
+ pPin->Release();
+ }
+
+ pEnum->Release();
+
+ if (!bFound)
+ {
+ hr = VFW_E_NOT_FOUND;
+ }
+ return hr;
+}
+
+HWND AniPlayerDShowInternal::hwnd() const
+{
+ return (HWND) player->videoWidget()->winId();
+}
+
+
+HRESULT AniPlayerDShowInternal::FinalizeGraph()
+{
+ if (pEVR == NULL)
+ {
+ return S_OK;
+ }
+
+ BOOL bRemoved;
+ HRESULT hr = RemoveUnconnectedRenderer(pGraph, pEVR, &bRemoved);
+ if (bRemoved)
+ {
+ SafeRelease(&pEVR);
+ SafeRelease(&pVideoDisplay);
+ }
+ return hr;
+}
--- /dev/null
+#ifndef ANIPLAYERDSHOWINTERNAL_H
+#define ANIPLAYERDSHOWINTERNAL_H
+
+#include <QSize>
+
+#include <windows.h>
+
+class AniPlayerDShow;
+
+struct IBaseFilter;
+struct IGraphBuilder;
+struct IMediaControl;
+struct IMediaEvent;
+struct IMediaSeeking;
+struct IMFVideoDisplayControl;
+
+struct AniPlayerDShowInternal
+{
+public:
+ AniPlayerDShowInternal(AniPlayerDShow *player_);
+ ~AniPlayerDShowInternal();
+
+ bool play();
+ bool pause();
+ bool stop();
+
+ QSize videoSize() const;
+
+ HRESULT InitializeGraph();
+ void TearDownGraph();
+ HRESULT CreateVideoRenderer();
+ HRESULT RenderStreams(IBaseFilter *pSource);
+ HRESULT RemoveUnconnectedRenderer(IGraphBuilder *pGraph, IBaseFilter *pRenderer, BOOL *pbRemoved);
+ HRESULT InitializeEVR(IBaseFilter *pEVR, IMFVideoDisplayControl** ppDisplayControl);
+
+
+ HRESULT AddVideoRenderer();
+ HRESULT FinalizeGraph();
+
+ HRESULT OpenFile(PCWSTR pszFileName);
+
+ IGraphBuilder *pGraph;
+ IMediaControl *pControl;
+ IMediaEvent *pEvent;
+ IMediaSeeking *pSeeking;
+
+ IBaseFilter *pEVR;
+ IMFVideoDisplayControl *pVideoDisplay;
+
+ HRESULT Repaint();
+ HRESULT UpdateVideoWindow(const LPRECT prc);
+
+
+ HWND hwnd() const;
+
+ AniPlayerDShow *player;
+};
+
+template <class T> void SafeRelease(T **ppT)
+{
+ if (*ppT)
+ {
+ (*ppT)->Release();
+ *ppT = NULL;
+ }
+}
+
+#endif // ANIPLAYERDSHOWINTERNAL_H
--- /dev/null
+#include "videowidgetdshow.h"
+
+#include "aniplayerdshow.h"
+
+VideoWidgetDShow::VideoWidgetDShow(AniPlayerDShow *player_, QWidget *parent) :
+ VideoWidget(parent), player(player_)
+{
+ setPalette(QPalette(Qt::black));
+ setAttribute(Qt::WA_OpaquePaintEvent, true);
+ setAttribute(Qt::WA_NoSystemBackground, true);
+ setAttribute(Qt::WA_PaintOnScreen, true);
+ setAutoFillBackground(false);
+}
+
+void VideoWidgetDShow::resizeEvent(QResizeEvent *e)
+{
+ player->widgetChanged();
+ VideoWidget::resizeEvent(e);
+}
--- /dev/null
+#ifndef VIDEOWIDGETDSHOW_H
+#define VIDEOWIDGETDSHOW_H
+
+#include "aniplayer2_dshow_global.h"
+#include <videowidget.h>
+
+class AniPlayerDShow;
+
+class ANIPLAYER2_DSHOWSHARED_EXPORT VideoWidgetDShow : public VideoWidget
+{
+ Q_OBJECT
+public:
+ explicit VideoWidgetDShow(AniPlayerDShow *player_, QWidget *parent = 0);
+
+ QPaintEngine* paintEngine() const
+ {
+ return 0;
+ }
+signals:
+
+public slots:
+
+protected:
+ void resizeEvent(QResizeEvent *e);
+
+private:
+ AniPlayerDShow *player;
+};
+
+#endif // VIDEOWIDGETDSHOW_H
--- /dev/null
+#include "mainwindow.h"
+#include <QApplication>
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ MainWindow w;
+ w.show();
+
+ return a.exec();
+}
--- /dev/null
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+
+#ifdef Q_OS_WIN
+# include <aniplayerdshow.h>
+#endif
+
+#include <videowidget.h>
+
+MainWindow::MainWindow(QWidget *parent) :
+ QMainWindow(parent),
+ ui(new Ui::MainWindow)
+{
+ player = new AniPlayerDShow(this);
+
+ player->open("E:/Anime/Accel World OVA/Accel World OVA - 01 - OVA - [UTW][3e56ee18].mkv");
+ player->play();
+
+ ui->setupUi(this);
+
+ QAction *a = new QAction("Pause", this);
+ a->setShortcut(QKeySequence("Space"));
+ connect(a, SIGNAL(triggered()), player, SLOT(togglePause()));
+ addAction(a);
+
+ setCentralWidget(player->videoWidget());
+}
+
+MainWindow::~MainWindow()
+{
+ delete ui;
+}
--- /dev/null
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+
+namespace Ui {
+class MainWindow;
+}
+
+class AniPlayer;
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ explicit MainWindow(QWidget *parent = 0);
+ ~MainWindow();
+
+private:
+ Ui::MainWindow *ui;
+
+ AniPlayer *player;
+};
+
+#endif // MAINWINDOW_H
--- /dev/null
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>MainWindow</string>
+ </property>
+ <widget class="QMenuBar" name="menuBar" />
+ <widget class="QToolBar" name="mainToolBar" />
+ <widget class="QWidget" name="centralWidget" />
+ <widget class="QStatusBar" name="statusBar" />
+ </widget>
+ <layoutDefault spacing="6" margin="11" />
+ <pixmapfunction></pixmapfunction>
+ <resources/>
+ <connections/>
+</ui>
--- /dev/null
+QT += core gui
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+TEMPLATE = app
+
+TARGET = player
+DESTDIR = ../build
+
+
+SOURCES += main.cpp\
+ mainwindow.cpp
+
+HEADERS += mainwindow.h
+
+FORMS += mainwindow.ui
+
+include(../config.pri)
+include(../aniplayer2/aniplayer2.pri)
+win32:include(../aniplayer2_dshow/aniplayer2_dshow.pri)