/* * $Id$ * * (C) 2006-2010 see AUTHORS * * This file is part of mplayerc. * * Mplayerc 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 3 of the License, or * (at your option) any later version. * * Mplayerc 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 this program. If not, see . * */ #pragma once #include "DX9AllocatorPresenter.h" #include // API Media Foundation #include namespace DSObjects { // dxva.dll typedef HRESULT (__stdcall *PTR_DXVA2CreateDirect3DDeviceManager9)(UINT* pResetToken, IDirect3DDeviceManager9** ppDeviceManager); // mf.dll typedef HRESULT (__stdcall *PTR_MFCreatePresentationClock)(IMFPresentationClock** ppPresentationClock); // evr.dll typedef HRESULT (__stdcall *PTR_MFCreateDXSurfaceBuffer)(REFIID riid, IUnknown* punkSurface, BOOL fBottomUpWhenLinear, IMFMediaBuffer** ppBuffer); typedef HRESULT (__stdcall *PTR_MFCreateVideoSampleFromSurface)(IUnknown* pUnkSurface, IMFSample** ppSample); typedef HRESULT (__stdcall *PTR_MFCreateVideoMediaType)(const MFVIDEOFORMAT* pVideoFormat, IMFVideoMediaType** ppIVideoMediaType); // AVRT.dll typedef HANDLE (__stdcall *PTR_AvSetMmThreadCharacteristicsW)(LPCWSTR TaskName, LPDWORD TaskIndex); typedef BOOL (__stdcall *PTR_AvSetMmThreadPriority)(HANDLE AvrtHandle, AVRT_PRIORITY Priority); typedef BOOL (__stdcall *PTR_AvRevertMmThreadCharacteristics)(HANDLE AvrtHandle); class COuterEVR; class CEVRAllocatorPresenter : public CDX9AllocatorPresenter, public IMFGetService, public IMFTopologyServiceLookupClient, public IMFVideoDeviceID, public IMFVideoPresenter, public IDirect3DDeviceManager9, public IMFAsyncCallback, public IQualProp, public IMFRateSupport, public IMFVideoDisplayControl, public IEVRTrustedVideoPlugin /* public IMFVideoPositionMapper, // Non mandatory EVR Presenter Interfaces (see later...) */ { public: CEVRAllocatorPresenter(HWND hWnd, bool bFullscreen, HRESULT& hr, CString &_Error); ~CEVRAllocatorPresenter(void); DECLARE_IUNKNOWN; STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv); STDMETHODIMP CreateRenderer(IUnknown** ppRenderer); STDMETHODIMP_(bool) Paint(bool fAll); STDMETHODIMP GetNativeVideoSize(LONG* lpWidth, LONG* lpHeight, LONG* lpARWidth, LONG* lpARHeight); STDMETHODIMP InitializeDevice(IMFMediaType* pMediaType); STDMETHODIMP_(bool) ResetDevice(); // IMFClockStateSink STDMETHODIMP OnClockStart(/* [in] */ MFTIME hnsSystemTime, /* [in] */ LONGLONG llClockStartOffset); STDMETHODIMP STDMETHODCALLTYPE OnClockStop(/* [in] */ MFTIME hnsSystemTime); STDMETHODIMP STDMETHODCALLTYPE OnClockPause(/* [in] */ MFTIME hnsSystemTime); STDMETHODIMP STDMETHODCALLTYPE OnClockRestart(/* [in] */ MFTIME hnsSystemTime); STDMETHODIMP STDMETHODCALLTYPE OnClockSetRate(/* [in] */ MFTIME hnsSystemTime, /* [in] */ float flRate); // IBaseFilter delegate bool GetState( DWORD dwMilliSecsTimeout, FILTER_STATE *State, HRESULT &_ReturnValue); // IQualProp (EVR statistics window) STDMETHODIMP get_FramesDroppedInRenderer (int *pcFrames); STDMETHODIMP get_FramesDrawn (int *pcFramesDrawn); STDMETHODIMP get_AvgFrameRate (int *piAvgFrameRate); STDMETHODIMP get_Jitter (int *iJitter); STDMETHODIMP get_AvgSyncOffset (int *piAvg); STDMETHODIMP get_DevSyncOffset (int *piDev); // IMFRateSupport STDMETHODIMP GetSlowestRate(MFRATE_DIRECTION eDirection, BOOL fThin, float *pflRate); STDMETHODIMP GetFastestRate(MFRATE_DIRECTION eDirection, BOOL fThin, float *pflRate); STDMETHODIMP IsRateSupported(BOOL fThin, float flRate, float *pflNearestSupportedRate); float GetMaxRate(BOOL bThin); // IMFVideoPresenter STDMETHODIMP ProcessMessage(MFVP_MESSAGE_TYPE eMessage, ULONG_PTR ulParam); STDMETHODIMP GetCurrentMediaType(__deref_out IMFVideoMediaType **ppMediaType); // IMFTopologyServiceLookupClient STDMETHODIMP InitServicePointers(/* [in] */ __in IMFTopologyServiceLookup *pLookup); STDMETHODIMP ReleaseServicePointers(); // IMFVideoDeviceID STDMETHODIMP GetDeviceID(/* [out] */ __out IID *pDeviceID); // IMFGetService STDMETHODIMP GetService (/* [in] */ __RPC__in REFGUID guidService, /* [in] */ __RPC__in REFIID riid, /* [iid_is][out] */ __RPC__deref_out_opt LPVOID *ppvObject); // IMFAsyncCallback STDMETHODIMP GetParameters( /* [out] */ __RPC__out DWORD *pdwFlags, /* [out] */ __RPC__out DWORD *pdwQueue); STDMETHODIMP Invoke ( /* [in] */ __RPC__in_opt IMFAsyncResult *pAsyncResult); // IMFVideoDisplayControl STDMETHODIMP GetNativeVideoSize(SIZE *pszVideo, SIZE *pszARVideo); STDMETHODIMP GetIdealVideoSize(SIZE *pszMin, SIZE *pszMax); STDMETHODIMP SetVideoPosition(const MFVideoNormalizedRect *pnrcSource, const LPRECT prcDest); STDMETHODIMP GetVideoPosition(MFVideoNormalizedRect *pnrcSource, LPRECT prcDest); STDMETHODIMP SetAspectRatioMode(DWORD dwAspectRatioMode); STDMETHODIMP GetAspectRatioMode(DWORD *pdwAspectRatioMode); STDMETHODIMP SetVideoWindow(HWND hwndVideo); STDMETHODIMP GetVideoWindow(HWND *phwndVideo); STDMETHODIMP RepaintVideo( void); STDMETHODIMP GetCurrentImage(BITMAPINFOHEADER *pBih, BYTE **pDib, DWORD *pcbDib, LONGLONG *pTimeStamp); STDMETHODIMP SetBorderColor(COLORREF Clr); STDMETHODIMP GetBorderColor(COLORREF *pClr); STDMETHODIMP SetRenderingPrefs(DWORD dwRenderFlags); STDMETHODIMP GetRenderingPrefs(DWORD *pdwRenderFlags); STDMETHODIMP SetFullscreen(BOOL fFullscreen); STDMETHODIMP GetFullscreen(BOOL *pfFullscreen); // IEVRTrustedVideoPlugin STDMETHODIMP IsInTrustedVideoMode(BOOL *pYes); STDMETHODIMP CanConstrict(BOOL *pYes); STDMETHODIMP SetConstriction(DWORD dwKPix); STDMETHODIMP DisableImageExport(BOOL bDisable); // IDirect3DDeviceManager9 STDMETHODIMP ResetDevice(IDirect3DDevice9 *pDevice,UINT resetToken); STDMETHODIMP OpenDeviceHandle(HANDLE *phDevice); STDMETHODIMP CloseDeviceHandle(HANDLE hDevice); STDMETHODIMP TestDevice(HANDLE hDevice); STDMETHODIMP LockDevice(HANDLE hDevice, IDirect3DDevice9 **ppDevice, BOOL fBlock); STDMETHODIMP UnlockDevice(HANDLE hDevice, BOOL fSaveState); STDMETHODIMP GetVideoService(HANDLE hDevice, REFIID riid, void **ppService); protected : void OnResetDevice(); virtual void OnVBlankFinished(bool fAll, LONGLONG PerformanceCounter); double m_ModeratedTime; LONGLONG m_ModeratedTimeLast; LONGLONG m_ModeratedClockLast; LONGLONG m_ModeratedTimer; MFCLOCK_STATE m_LastClockState; LONGLONG GetClockTime(LONGLONG PerformanceCounter); private : typedef enum { Started = State_Running, Stopped = State_Stopped, Paused = State_Paused, Shutdown = State_Running + 1 } RENDER_STATE; COuterEVR* m_pOuterEVR; CComPtr m_pClock; CComPtr m_pD3DManager; CComPtr m_pMixer; CComPtr m_pSink; CComPtr m_pMediaType; MFVideoAspectRatioMode m_dwVideoAspectRatioMode; MFVideoRenderPrefs m_dwVideoRenderPrefs; COLORREF m_BorderColor; HANDLE m_hEvtQuit; // Stop rendering thread event bool m_bEvtQuit; HANDLE m_hEvtFlush; // Discard all buffers bool m_bEvtFlush; bool m_fUseInternalTimer; int32 m_LastSetOutputRange; bool m_bPendingRenegotiate; bool m_bPendingMediaFinished; HANDLE m_hThread; HANDLE m_hGetMixerThread; RENDER_STATE m_nRenderState; CCritSec m_SampleQueueLock; CCritSec m_ImageProcessingLock; CInterfaceList m_FreeSamples; CInterfaceList m_ScheduledSamples; IMFSample * m_pCurrentDisplaydSample; bool m_bWaitingSample; bool m_bLastSampleOffsetValid; LONGLONG m_LastScheduledSampleTime; double m_LastScheduledSampleTimeFP; LONGLONG m_LastScheduledUncorrectedSampleTime; LONGLONG m_MaxSampleDuration; LONGLONG m_LastSampleOffset; LONGLONG m_VSyncOffsetHistory[5]; LONGLONG m_LastPredictedSync; int m_VSyncOffsetHistoryPos; UINT m_nResetToken; int m_nStepCount; bool m_bSignaledStarvation; LONGLONG m_StarvationClock; // Stats variable for IQualProp UINT m_pcFrames; UINT m_nDroppedUpdate; UINT m_pcFramesDrawn; // Retrieves the number of frames drawn since streaming started UINT m_piAvg; UINT m_piDev; void GetMixerThread(); static DWORD WINAPI GetMixerThreadStatic(LPVOID lpParam); bool GetImageFromMixer(); void RenderThread(); static DWORD WINAPI PresentThread(LPVOID lpParam); void ResetStats(); void StartWorkerThreads(); void StopWorkerThreads(); HRESULT CheckShutdown() const; void CompleteFrameStep(bool bCancel); void CheckWaitingSampleFromMixer(); void RemoveAllSamples(); HRESULT GetFreeSample(IMFSample** ppSample); HRESULT GetScheduledSample(IMFSample** ppSample, int &_Count); void MoveToFreeList(IMFSample* pSample, bool bTail); void MoveToScheduledList(IMFSample* pSample, bool _bSorted); void FlushSamples(); void FlushSamplesInternal(); // === Media type negotiation functions HRESULT RenegotiateMediaType(); HRESULT IsMediaTypeSupported(IMFMediaType* pMixerType); HRESULT CreateProposedOutputType(IMFMediaType* pMixerType, IMFMediaType** pType); HRESULT SetMediaType(IMFMediaType* pType); HRESULT GetMediaTypeFourCC(IMFMediaType* pType, DWORD* pFourCC); HRESULT GetMediaTypeMerit(IMFMediaType* pType, int *pMerit); LPCTSTR GetMediaTypeFormatDesc(IMFMediaType* pMediaType); // === Functions pointers on Vista / .Net3 specifics library PTR_DXVA2CreateDirect3DDeviceManager9 pfDXVA2CreateDirect3DDeviceManager9; PTR_MFCreateDXSurfaceBuffer pfMFCreateDXSurfaceBuffer; PTR_MFCreateVideoSampleFromSurface pfMFCreateVideoSampleFromSurface; PTR_MFCreateVideoMediaType pfMFCreateVideoMediaType; #if 0 HRESULT (__stdcall *pMFCreateMediaType)(__deref_out IMFMediaType** ppMFType); HRESULT (__stdcall *pMFInitMediaTypeFromAMMediaType)(__in IMFMediaType *pMFType, __in const AM_MEDIA_TYPE *pAMType); HRESULT (__stdcall *pMFInitAMMediaTypeFromMFMediaType)(__in IMFMediaType *pMFType, __in GUID guidFormatBlockType, __inout AM_MEDIA_TYPE *pAMType); #endif PTR_AvSetMmThreadCharacteristicsW pfAvSetMmThreadCharacteristicsW; PTR_AvSetMmThreadPriority pfAvSetMmThreadPriority; PTR_AvRevertMmThreadCharacteristics pfAvRevertMmThreadCharacteristics; }; }