mirror of https://github.com/odrling/Aegisub
406 lines
12 KiB
C++
406 lines
12 KiB
C++
/*
|
|
* Copyright (C) 2003-2006 Gabest
|
|
* http://www.gabest.org
|
|
*
|
|
* This Program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This Program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with GNU Make; see the file COPYING. If not, write to
|
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
* http://www.gnu.org/copyleft/gpl.html
|
|
*
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <atlbase.h>
|
|
#include <atlcoll.h>
|
|
#include "CoordGeom.h"
|
|
|
|
#pragma pack(push, 1)
|
|
struct SubPicDesc
|
|
{
|
|
int type;
|
|
int w, h, bpp, pitch, pitchUV;
|
|
void* bits;
|
|
BYTE* bitsU;
|
|
BYTE* bitsV;
|
|
RECT vidrect; // video rectangle
|
|
|
|
struct SubPicDesc() {type = 0; w = h = bpp = pitch = pitchUV = 0; bits = NULL; bitsU = bitsV = NULL;}
|
|
};
|
|
#pragma pack(pop)
|
|
|
|
//
|
|
// ISubPic
|
|
//
|
|
|
|
[uuid("449E11F3-52D1-4a27-AA61-E2733AC92CC0")]
|
|
interface ISubPic : public IUnknown
|
|
{
|
|
STDMETHOD_(void*, GetObject) () PURE;
|
|
|
|
STDMETHOD_(REFERENCE_TIME, GetStart) () PURE;
|
|
STDMETHOD_(REFERENCE_TIME, GetStop) () PURE;
|
|
STDMETHOD_(void, SetStart) (REFERENCE_TIME rtStart) PURE;
|
|
STDMETHOD_(void, SetStop) (REFERENCE_TIME rtStop) PURE;
|
|
|
|
STDMETHOD (GetDesc) (SubPicDesc& spd /*[out]*/) PURE;
|
|
STDMETHOD (CopyTo) (ISubPic* pSubPic /*[in]*/) PURE;
|
|
|
|
STDMETHOD (ClearDirtyRect) (DWORD color /*[in]*/) PURE;
|
|
STDMETHOD (GetDirtyRect) (RECT* pDirtyRect /*[out]*/) PURE;
|
|
STDMETHOD (SetDirtyRect) (RECT* pDirtyRect /*[in]*/) PURE;
|
|
|
|
STDMETHOD (GetMaxSize) (SIZE* pMaxSize /*[out]*/) PURE;
|
|
STDMETHOD (SetSize) (SIZE pSize /*[in]*/, RECT vidrect /*[in]*/) PURE;
|
|
|
|
STDMETHOD (Lock) (SubPicDesc& spd /*[out]*/) PURE;
|
|
STDMETHOD (Unlock) (RECT* pDirtyRect /*[in]*/) PURE;
|
|
|
|
STDMETHOD (AlphaBlt) (RECT* pSrc, RECT* pDst, SubPicDesc* pTarget = NULL /*[in]*/) PURE;
|
|
};
|
|
|
|
class ISubPicImpl : public CUnknown, public ISubPic
|
|
{
|
|
protected:
|
|
REFERENCE_TIME m_rtStart, m_rtStop;
|
|
CRect m_rcDirty;
|
|
CSize m_maxsize, m_size;
|
|
CRect m_vidrect;
|
|
|
|
public:
|
|
ISubPicImpl();
|
|
|
|
DECLARE_IUNKNOWN;
|
|
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
|
|
|
|
// ISubPic
|
|
|
|
STDMETHODIMP_(REFERENCE_TIME) GetStart();
|
|
STDMETHODIMP_(REFERENCE_TIME) GetStop();
|
|
STDMETHODIMP_(void) SetStart(REFERENCE_TIME rtStart);
|
|
STDMETHODIMP_(void) SetStop(REFERENCE_TIME rtStop);
|
|
|
|
STDMETHODIMP GetDesc(SubPicDesc& spd) = 0;
|
|
STDMETHODIMP CopyTo(ISubPic* pSubPic);
|
|
|
|
STDMETHODIMP ClearDirtyRect(DWORD color) = 0;
|
|
STDMETHODIMP GetDirtyRect(RECT* pDirtyRect);
|
|
STDMETHODIMP SetDirtyRect(RECT* pDirtyRect);
|
|
|
|
STDMETHODIMP GetMaxSize(SIZE* pMaxSize);
|
|
STDMETHODIMP SetSize(SIZE size, RECT vidrect);
|
|
|
|
STDMETHODIMP Lock(SubPicDesc& spd) = 0;
|
|
STDMETHODIMP Unlock(RECT* pDirtyRect) = 0;
|
|
|
|
STDMETHODIMP AlphaBlt(RECT* pSrc, RECT* pDst, SubPicDesc* pTarget) = 0;
|
|
};
|
|
|
|
//
|
|
// ISubPicAllocator
|
|
//
|
|
|
|
[uuid("CF7C3C23-6392-4a42-9E72-0736CFF793CB")]
|
|
interface ISubPicAllocator : public IUnknown
|
|
{
|
|
STDMETHOD (SetCurSize) (SIZE size /*[in]*/) PURE;
|
|
STDMETHOD (SetCurVidRect) (RECT curvidrect) PURE;
|
|
|
|
STDMETHOD (GetStatic) (ISubPic** ppSubPic /*[out]*/) PURE;
|
|
STDMETHOD (AllocDynamic) (ISubPic** ppSubPic /*[out]*/) PURE;
|
|
|
|
STDMETHOD_(bool, IsDynamicWriteOnly) () PURE;
|
|
|
|
STDMETHOD (ChangeDevice) (IUnknown* pDev) PURE;
|
|
};
|
|
|
|
|
|
class ISubPicAllocatorImpl : public CUnknown, public ISubPicAllocator
|
|
{
|
|
CComPtr<ISubPic> m_pStatic;
|
|
|
|
private:
|
|
CSize m_cursize;
|
|
CRect m_curvidrect;
|
|
bool m_fDynamicWriteOnly;
|
|
|
|
virtual bool Alloc(bool fStatic, ISubPic** ppSubPic) = 0;
|
|
|
|
protected:
|
|
bool m_fPow2Textures;
|
|
|
|
public:
|
|
ISubPicAllocatorImpl(SIZE cursize, bool fDynamicWriteOnly, bool fPow2Textures);
|
|
|
|
DECLARE_IUNKNOWN;
|
|
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
|
|
|
|
// ISubPicAllocator
|
|
|
|
STDMETHODIMP SetCurSize(SIZE cursize);
|
|
STDMETHODIMP SetCurVidRect(RECT curvidrect);
|
|
STDMETHODIMP GetStatic(ISubPic** ppSubPic);
|
|
STDMETHODIMP AllocDynamic(ISubPic** ppSubPic);
|
|
STDMETHODIMP_(bool) IsDynamicWriteOnly();
|
|
STDMETHODIMP ChangeDevice(IUnknown* pDev);
|
|
};
|
|
|
|
//
|
|
// ISubPicProvider
|
|
//
|
|
|
|
[uuid("D62B9A1A-879A-42db-AB04-88AA8F243CFD")]
|
|
interface ISubPicProvider : public IUnknown
|
|
{
|
|
STDMETHOD (Lock) () PURE;
|
|
STDMETHOD (Unlock) () PURE;
|
|
|
|
STDMETHOD_(POSITION, GetStartPosition) (REFERENCE_TIME rt, double fps) PURE;
|
|
STDMETHOD_(POSITION, GetNext) (POSITION pos) PURE;
|
|
|
|
STDMETHOD_(REFERENCE_TIME, GetStart) (POSITION pos, double fps) PURE;
|
|
STDMETHOD_(REFERENCE_TIME, GetStop) (POSITION pos, double fps) PURE;
|
|
|
|
STDMETHOD_(bool, IsAnimated) (POSITION pos) PURE;
|
|
|
|
STDMETHOD (Render) (SubPicDesc& spd, REFERENCE_TIME rt, double fps, RECT& bbox) PURE;
|
|
};
|
|
|
|
class ISubPicProviderImpl : public CUnknown, public ISubPicProvider
|
|
{
|
|
protected:
|
|
CCritSec* m_pLock;
|
|
|
|
public:
|
|
ISubPicProviderImpl(CCritSec* pLock);
|
|
virtual ~ISubPicProviderImpl();
|
|
|
|
DECLARE_IUNKNOWN;
|
|
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
|
|
|
|
// ISubPicProvider
|
|
|
|
STDMETHODIMP Lock();
|
|
STDMETHODIMP Unlock();
|
|
|
|
STDMETHODIMP_(POSITION) GetStartPosition(REFERENCE_TIME rt, double fps) = 0;
|
|
STDMETHODIMP_(POSITION) GetNext(POSITION pos) = 0;
|
|
|
|
STDMETHODIMP_(REFERENCE_TIME) GetStart(POSITION pos, double fps) = 0;
|
|
STDMETHODIMP_(REFERENCE_TIME) GetStop(POSITION pos, double fps) = 0;
|
|
|
|
STDMETHODIMP Render(SubPicDesc& spd, REFERENCE_TIME rt, double fps, RECT& bbox) = 0;
|
|
};
|
|
|
|
//
|
|
// ISubPicQueue
|
|
//
|
|
|
|
[uuid("C8334466-CD1E-4ad1-9D2D-8EE8519BD180")]
|
|
interface ISubPicQueue : public IUnknown
|
|
{
|
|
STDMETHOD (SetSubPicProvider) (ISubPicProvider* pSubPicProvider /*[in]*/) PURE;
|
|
STDMETHOD (GetSubPicProvider) (ISubPicProvider** pSubPicProvider /*[out]*/) PURE;
|
|
|
|
STDMETHOD (SetFPS) (double fps /*[in]*/) PURE;
|
|
STDMETHOD (SetTime) (REFERENCE_TIME rtNow /*[in]*/) PURE;
|
|
|
|
STDMETHOD (Invalidate) (REFERENCE_TIME rtInvalidate = -1) PURE;
|
|
STDMETHOD_(bool, LookupSubPic) (REFERENCE_TIME rtNow /*[in]*/, ISubPic** ppSubPic /*[out]*/) PURE;
|
|
|
|
STDMETHOD (GetStats) (int& nSubPics, REFERENCE_TIME& rtNow, REFERENCE_TIME& rtStart, REFERENCE_TIME& rtStop /*[out]*/) PURE;
|
|
STDMETHOD (GetStats) (int nSubPic /*[in]*/, REFERENCE_TIME& rtStart, REFERENCE_TIME& rtStop /*[out]*/) PURE;
|
|
};
|
|
|
|
class ISubPicQueueImpl : public CUnknown, public ISubPicQueue
|
|
{
|
|
CCritSec m_csSubPicProvider;
|
|
CComPtr<ISubPicProvider> m_pSubPicProvider;
|
|
|
|
protected:
|
|
double m_fps;
|
|
REFERENCE_TIME m_rtNow;
|
|
|
|
CComPtr<ISubPicAllocator> m_pAllocator;
|
|
|
|
HRESULT RenderTo(ISubPic* pSubPic, REFERENCE_TIME rtStart, REFERENCE_TIME rtStop, double fps);
|
|
|
|
public:
|
|
ISubPicQueueImpl(ISubPicAllocator* pAllocator, HRESULT* phr);
|
|
virtual ~ISubPicQueueImpl();
|
|
|
|
DECLARE_IUNKNOWN;
|
|
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
|
|
|
|
// ISubPicQueue
|
|
|
|
STDMETHODIMP SetSubPicProvider(ISubPicProvider* pSubPicProvider);
|
|
STDMETHODIMP GetSubPicProvider(ISubPicProvider** pSubPicProvider);
|
|
|
|
STDMETHODIMP SetFPS(double fps);
|
|
STDMETHODIMP SetTime(REFERENCE_TIME rtNow);
|
|
/*
|
|
STDMETHODIMP Invalidate(REFERENCE_TIME rtInvalidate = -1) = 0;
|
|
STDMETHODIMP_(bool) LookupSubPic(REFERENCE_TIME rtNow, ISubPic** ppSubPic) = 0;
|
|
|
|
STDMETHODIMP GetStats(int& nSubPics, REFERENCE_TIME& rtNow, REFERENCE_TIME& rtStart, REFERENCE_TIME& rtStop) = 0;
|
|
STDMETHODIMP GetStats(int nSubPics, REFERENCE_TIME& rtStart, REFERENCE_TIME& rtStop) = 0;
|
|
*/
|
|
};
|
|
|
|
class CSubPicQueue : public ISubPicQueueImpl, private CInterfaceList<ISubPic>, private CAMThread
|
|
{
|
|
int m_nMaxSubPic;
|
|
|
|
CCritSec m_csQueueLock; // for protecting CInterfaceList<ISubPic>
|
|
REFERENCE_TIME UpdateQueue();
|
|
void AppendQueue(ISubPic* pSubPic);
|
|
|
|
REFERENCE_TIME m_rtQueueStart, m_rtInvalidate;
|
|
|
|
// CAMThread
|
|
|
|
bool m_fBreakBuffering;
|
|
enum {EVENT_EXIT, EVENT_TIME, EVENT_COUNT}; // IMPORTANT: _EXIT must come before _TIME if we want to exit fast from the destructor
|
|
HANDLE m_ThreadEvents[EVENT_COUNT];
|
|
DWORD ThreadProc();
|
|
|
|
public:
|
|
CSubPicQueue(int nMaxSubPic, ISubPicAllocator* pAllocator, HRESULT* phr);
|
|
virtual ~CSubPicQueue();
|
|
|
|
// ISubPicQueue
|
|
|
|
STDMETHODIMP SetFPS(double fps);
|
|
STDMETHODIMP SetTime(REFERENCE_TIME rtNow);
|
|
|
|
STDMETHODIMP Invalidate(REFERENCE_TIME rtInvalidate = -1);
|
|
STDMETHODIMP_(bool) LookupSubPic(REFERENCE_TIME rtNow, ISubPic** ppSubPic);
|
|
|
|
STDMETHODIMP GetStats(int& nSubPics, REFERENCE_TIME& rtNow, REFERENCE_TIME& rtStart, REFERENCE_TIME& rtStop);
|
|
STDMETHODIMP GetStats(int nSubPic, REFERENCE_TIME& rtStart, REFERENCE_TIME& rtStop);
|
|
};
|
|
|
|
class CSubPicQueueNoThread : public ISubPicQueueImpl
|
|
{
|
|
CCritSec m_csLock;
|
|
CComPtr<ISubPic> m_pSubPic;
|
|
|
|
public:
|
|
CSubPicQueueNoThread(ISubPicAllocator* pAllocator, HRESULT* phr);
|
|
virtual ~CSubPicQueueNoThread();
|
|
|
|
// ISubPicQueue
|
|
|
|
STDMETHODIMP Invalidate(REFERENCE_TIME rtInvalidate = -1);
|
|
STDMETHODIMP_(bool) LookupSubPic(REFERENCE_TIME rtNow, ISubPic** ppSubPic);
|
|
|
|
STDMETHODIMP GetStats(int& nSubPics, REFERENCE_TIME& rtNow, REFERENCE_TIME& rtStart, REFERENCE_TIME& rtStop);
|
|
STDMETHODIMP GetStats(int nSubPic, REFERENCE_TIME& rtStart, REFERENCE_TIME& rtStop);
|
|
};
|
|
|
|
//
|
|
// ISubPicAllocatorPresenter
|
|
//
|
|
|
|
[uuid("CF75B1F0-535C-4074-8869-B15F177F944E")]
|
|
interface ISubPicAllocatorPresenter : public IUnknown
|
|
{
|
|
STDMETHOD (CreateRenderer) (IUnknown** ppRenderer) PURE;
|
|
|
|
STDMETHOD_(SIZE, GetVideoSize) (bool fCorrectAR = true) PURE;
|
|
STDMETHOD_(void, SetPosition) (RECT w, RECT v) PURE;
|
|
STDMETHOD_(bool, Paint) (bool fAll) PURE;
|
|
|
|
STDMETHOD_(void, SetTime) (REFERENCE_TIME rtNow) PURE;
|
|
STDMETHOD_(double, GetFPS) () PURE;
|
|
|
|
STDMETHOD_(void, SetSubPicProvider) (ISubPicProvider* pSubPicProvider) PURE;
|
|
STDMETHOD_(void, Invalidate) (REFERENCE_TIME rtInvalidate = -1) PURE;
|
|
|
|
STDMETHOD (GetDIB) (BYTE* lpDib, DWORD* size) PURE;
|
|
|
|
STDMETHOD (SetVideoAngle) (Vector v, bool fRepaint = true) PURE;
|
|
STDMETHOD (SetPixelShader) (LPCSTR pSrcData, LPCSTR pTarget) PURE;
|
|
};
|
|
|
|
class ISubPicAllocatorPresenterImpl
|
|
: public CUnknown
|
|
, public CCritSec
|
|
, public ISubPicAllocatorPresenter
|
|
{
|
|
protected:
|
|
HWND m_hWnd;
|
|
CSize m_spMaxSize; // TODO:
|
|
int m_spMaxQueued; // TODO:
|
|
|
|
CSize m_NativeVideoSize, m_AspectRatio;
|
|
CRect m_VideoRect, m_WindowRect;
|
|
|
|
REFERENCE_TIME m_rtNow;
|
|
double m_fps;
|
|
|
|
CComPtr<ISubPicProvider> m_SubPicProvider;
|
|
CComPtr<ISubPicAllocator> m_pAllocator;
|
|
CComPtr<ISubPicQueue> m_pSubPicQueue;
|
|
|
|
void AlphaBltSubPic(CSize size, SubPicDesc* pTarget = NULL);
|
|
|
|
XForm m_xform;
|
|
void Transform(CRect r, Vector v[4]);
|
|
|
|
public:
|
|
ISubPicAllocatorPresenterImpl(HWND hWnd, HRESULT& hr);
|
|
virtual ~ISubPicAllocatorPresenterImpl();
|
|
|
|
DECLARE_IUNKNOWN;
|
|
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
|
|
|
|
// ISubPicAllocatorPresenter
|
|
|
|
STDMETHODIMP CreateRenderer(IUnknown** ppRenderer) = 0;
|
|
|
|
STDMETHODIMP_(SIZE) GetVideoSize(bool fCorrectAR = true);
|
|
STDMETHODIMP_(void) SetPosition(RECT w, RECT v);
|
|
STDMETHODIMP_(bool) Paint(bool fAll) = 0;
|
|
|
|
STDMETHODIMP_(void) SetTime(REFERENCE_TIME rtNow);
|
|
STDMETHODIMP_(double) GetFPS();
|
|
|
|
STDMETHODIMP_(void) SetSubPicProvider(ISubPicProvider* pSubPicProvider);
|
|
STDMETHODIMP_(void) Invalidate(REFERENCE_TIME rtInvalidate = -1);
|
|
|
|
STDMETHODIMP GetDIB(BYTE* lpDib, DWORD* size) {return E_NOTIMPL;}
|
|
|
|
STDMETHODIMP SetVideoAngle(Vector v, bool fRepaint = true);
|
|
STDMETHODIMP SetPixelShader(LPCSTR pSrcData, LPCSTR pTarget) {return E_NOTIMPL;}
|
|
};
|
|
|
|
//
|
|
// ISubStream
|
|
//
|
|
|
|
[uuid("DE11E2FB-02D3-45e4-A174-6B7CE2783BDB")]
|
|
interface ISubStream : public IPersist
|
|
{
|
|
STDMETHOD_(int, GetStreamCount) () PURE;
|
|
STDMETHOD (GetStreamInfo) (int i, WCHAR** ppName, LCID* pLCID) PURE;
|
|
STDMETHOD_(int, GetStream) () PURE;
|
|
STDMETHOD (SetStream) (int iStream) PURE;
|
|
STDMETHOD (Reload) () PURE;
|
|
|
|
// TODO: get rid of IPersist to identify type and use only
|
|
// interface functions to modify the settings of the substream
|
|
};
|
|
|