Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/mpc-hc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/filters/renderer/VideoRenderers/EVRAllocatorPresenter.cpp')
-rw-r--r--src/filters/renderer/VideoRenderers/EVRAllocatorPresenter.cpp4120
1 files changed, 2060 insertions, 2060 deletions
diff --git a/src/filters/renderer/VideoRenderers/EVRAllocatorPresenter.cpp b/src/filters/renderer/VideoRenderers/EVRAllocatorPresenter.cpp
index 2764fcb81..04ffbb083 100644
--- a/src/filters/renderer/VideoRenderers/EVRAllocatorPresenter.cpp
+++ b/src/filters/renderer/VideoRenderers/EVRAllocatorPresenter.cpp
@@ -29,15 +29,15 @@
#include "../../transform/MPCVideoDec/MPCVideoDecFilter.h"
-#if (0) // Set to 1 to activate EVR traces
-#define TRACE_EVR TRACE
+#if (0) // Set to 1 to activate EVR traces
+#define TRACE_EVR TRACE
#else
-#define TRACE_EVR __noop
+#define TRACE_EVR __noop
#endif
typedef enum {
- MSG_MIXERIN,
- MSG_MIXEROUT
+ MSG_MIXERIN,
+ MSG_MIXEROUT
} EVR_STATS_MSG;
// Guid to tag IMFSample with DirectX surface index
@@ -49,2558 +49,2558 @@ static const GUID GUID_SURFACE_INDEX = { 0x30c8e9f6, 0x415, 0x4b81, { 0xa3, 0x15
MFOffset MakeOffset(float v)
{
- MFOffset offset;
- offset.value = short(v);
- offset.fract = WORD(65536 * (v-offset.value));
- return offset;
+ MFOffset offset;
+ offset.value = short(v);
+ offset.fract = WORD(65536 * (v - offset.value));
+ return offset;
}
MFVideoArea MakeArea(float x, float y, DWORD width, DWORD height)
{
- MFVideoArea area;
- area.OffsetX = MakeOffset(x);
- area.OffsetY = MakeOffset(y);
- area.Area.cx = width;
- area.Area.cy = height;
- return area;
+ MFVideoArea area;
+ area.OffsetX = MakeOffset(x);
+ area.OffsetY = MakeOffset(y);
+ area.Area.cx = width;
+ area.Area.cy = height;
+ return area;
}
using namespace DSObjects;
-CEVRAllocatorPresenter::CEVRAllocatorPresenter(HWND hWnd, bool bFullscreen, HRESULT& hr, CString &_Error)
- : CDX9AllocatorPresenter(hWnd, bFullscreen, hr, true, _Error)
-{
- HMODULE hLib;
- CRenderersSettings& s = GetRenderersSettings();
-
- m_nResetToken = 0;
- m_hThread = INVALID_HANDLE_VALUE;
- m_hGetMixerThread= INVALID_HANDLE_VALUE;
- m_hEvtFlush = INVALID_HANDLE_VALUE;
- m_hEvtQuit = INVALID_HANDLE_VALUE;
- m_bEvtQuit = 0;
- m_bEvtFlush = 0;
- m_ModeratedTime = 0;
- m_ModeratedTimeLast = -1;
- m_ModeratedClockLast = -1;
-
- if (FAILED (hr)) {
- _Error += L"DX9AllocatorPresenter failed\n";
- return;
- }
-
- // Load EVR specifics DLLs
- hLib = LoadLibrary (L"dxva2.dll");
- pfDXVA2CreateDirect3DDeviceManager9 = hLib ? (PTR_DXVA2CreateDirect3DDeviceManager9) GetProcAddress (hLib, "DXVA2CreateDirect3DDeviceManager9") : NULL;
-
- // Load EVR functions
- hLib = LoadLibrary (L"evr.dll");
- pfMFCreateDXSurfaceBuffer = hLib ? (PTR_MFCreateDXSurfaceBuffer) GetProcAddress (hLib, "MFCreateDXSurfaceBuffer") : NULL;
- pfMFCreateVideoSampleFromSurface = hLib ? (PTR_MFCreateVideoSampleFromSurface) GetProcAddress (hLib, "MFCreateVideoSampleFromSurface") : NULL;
- pfMFCreateVideoMediaType = hLib ? (PTR_MFCreateVideoMediaType) GetProcAddress (hLib, "MFCreateVideoMediaType") : NULL;
-
- if (!pfDXVA2CreateDirect3DDeviceManager9 || !pfMFCreateDXSurfaceBuffer || !pfMFCreateVideoSampleFromSurface || !pfMFCreateVideoMediaType) {
- if (!pfDXVA2CreateDirect3DDeviceManager9) {
- _Error += L"Could not find DXVA2CreateDirect3DDeviceManager9 (dxva2.dll)\n";
- }
- if (!pfMFCreateDXSurfaceBuffer) {
- _Error += L"Could not find MFCreateDXSurfaceBuffer (evr.dll)\n";
- }
- if (!pfMFCreateVideoSampleFromSurface) {
- _Error += L"Could not find MFCreateVideoSampleFromSurface (evr.dll)\n";
- }
- if (!pfMFCreateVideoMediaType) {
- _Error += L"Could not find MFCreateVideoMediaType (evr.dll)\n";
- }
- hr = E_FAIL;
- return;
- }
-
- // Load mfplat fuctions
+CEVRAllocatorPresenter::CEVRAllocatorPresenter(HWND hWnd, bool bFullscreen, HRESULT& hr, CString& _Error)
+ : CDX9AllocatorPresenter(hWnd, bFullscreen, hr, true, _Error)
+{
+ HMODULE hLib;
+ CRenderersSettings& s = GetRenderersSettings();
+
+ m_nResetToken = 0;
+ m_hThread = INVALID_HANDLE_VALUE;
+ m_hGetMixerThread = INVALID_HANDLE_VALUE;
+ m_hEvtFlush = INVALID_HANDLE_VALUE;
+ m_hEvtQuit = INVALID_HANDLE_VALUE;
+ m_bEvtQuit = 0;
+ m_bEvtFlush = 0;
+ m_ModeratedTime = 0;
+ m_ModeratedTimeLast = -1;
+ m_ModeratedClockLast = -1;
+
+ if (FAILED(hr)) {
+ _Error += L"DX9AllocatorPresenter failed\n";
+ return;
+ }
+
+ // Load EVR specifics DLLs
+ hLib = LoadLibrary(L"dxva2.dll");
+ pfDXVA2CreateDirect3DDeviceManager9 = hLib ? (PTR_DXVA2CreateDirect3DDeviceManager9) GetProcAddress(hLib, "DXVA2CreateDirect3DDeviceManager9") : NULL;
+
+ // Load EVR functions
+ hLib = LoadLibrary(L"evr.dll");
+ pfMFCreateDXSurfaceBuffer = hLib ? (PTR_MFCreateDXSurfaceBuffer) GetProcAddress(hLib, "MFCreateDXSurfaceBuffer") : NULL;
+ pfMFCreateVideoSampleFromSurface = hLib ? (PTR_MFCreateVideoSampleFromSurface) GetProcAddress(hLib, "MFCreateVideoSampleFromSurface") : NULL;
+ pfMFCreateVideoMediaType = hLib ? (PTR_MFCreateVideoMediaType) GetProcAddress(hLib, "MFCreateVideoMediaType") : NULL;
+
+ if (!pfDXVA2CreateDirect3DDeviceManager9 || !pfMFCreateDXSurfaceBuffer || !pfMFCreateVideoSampleFromSurface || !pfMFCreateVideoMediaType) {
+ if (!pfDXVA2CreateDirect3DDeviceManager9) {
+ _Error += L"Could not find DXVA2CreateDirect3DDeviceManager9 (dxva2.dll)\n";
+ }
+ if (!pfMFCreateDXSurfaceBuffer) {
+ _Error += L"Could not find MFCreateDXSurfaceBuffer (evr.dll)\n";
+ }
+ if (!pfMFCreateVideoSampleFromSurface) {
+ _Error += L"Could not find MFCreateVideoSampleFromSurface (evr.dll)\n";
+ }
+ if (!pfMFCreateVideoMediaType) {
+ _Error += L"Could not find MFCreateVideoMediaType (evr.dll)\n";
+ }
+ hr = E_FAIL;
+ return;
+ }
+
+ // Load mfplat fuctions
#if 0
- hLib = LoadLibrary (L"mfplat.dll");
- (FARPROC &)pMFCreateMediaType = GetProcAddress(hLib, "MFCreateMediaType");
- (FARPROC &)pMFInitMediaTypeFromAMMediaType = GetProcAddress(hLib, "MFInitMediaTypeFromAMMediaType");
- (FARPROC &)pMFInitAMMediaTypeFromMFMediaType = GetProcAddress(hLib, "MFInitAMMediaTypeFromMFMediaType");
-
- if (!pMFCreateMediaType || !pMFInitMediaTypeFromAMMediaType || !pMFInitAMMediaTypeFromMFMediaType) {
- hr = E_FAIL;
- return;
- }
+ hLib = LoadLibrary(L"mfplat.dll");
+ (FARPROC&)pMFCreateMediaType = GetProcAddress(hLib, "MFCreateMediaType");
+ (FARPROC&)pMFInitMediaTypeFromAMMediaType = GetProcAddress(hLib, "MFInitMediaTypeFromAMMediaType");
+ (FARPROC&)pMFInitAMMediaTypeFromMFMediaType = GetProcAddress(hLib, "MFInitAMMediaTypeFromMFMediaType");
+
+ if (!pMFCreateMediaType || !pMFInitMediaTypeFromAMMediaType || !pMFInitAMMediaTypeFromMFMediaType) {
+ hr = E_FAIL;
+ return;
+ }
#endif
- // Load Vista specifics DLLs
- hLib = LoadLibrary (L"avrt.dll");
- pfAvSetMmThreadCharacteristicsW = hLib ? (PTR_AvSetMmThreadCharacteristicsW) GetProcAddress (hLib, "AvSetMmThreadCharacteristicsW") : NULL;
- pfAvSetMmThreadPriority = hLib ? (PTR_AvSetMmThreadPriority) GetProcAddress (hLib, "AvSetMmThreadPriority") : NULL;
- pfAvRevertMmThreadCharacteristics = hLib ? (PTR_AvRevertMmThreadCharacteristics) GetProcAddress (hLib, "AvRevertMmThreadCharacteristics") : NULL;
-
- // Init DXVA manager
- hr = pfDXVA2CreateDirect3DDeviceManager9(&m_nResetToken, &m_pD3DManager);
- if (SUCCEEDED (hr)) {
- hr = m_pD3DManager->ResetDevice(m_pD3DDev, m_nResetToken);
- if (!SUCCEEDED (hr)) {
- _Error += L"m_pD3DManager->ResetDevice failed\n";
- }
- } else {
- _Error += L"DXVA2CreateDirect3DDeviceManager9 failed\n";
- }
-
- CComPtr<IDirectXVideoDecoderService> pDecoderService;
- HANDLE hDevice;
- if (SUCCEEDED (m_pD3DManager->OpenDeviceHandle(&hDevice)) &&
- SUCCEEDED (m_pD3DManager->GetVideoService (hDevice, __uuidof(IDirectXVideoDecoderService), (void**)&pDecoderService))) {
- TRACE_EVR ("EVR: DXVA2 : device handle = 0x%08x", hDevice);
- HookDirectXVideoDecoderService (pDecoderService);
-
- m_pD3DManager->CloseDeviceHandle (hDevice);
- }
-
-
- // Bufferize frame only with 3D texture!
- if (s.iAPSurfaceUsage == VIDRNDT_AP_TEXTURE3D) {
- m_nNbDXSurface = max (min (s.iEvrBuffers, MAX_VIDEO_SURFACES), 4);
- } else {
- m_nNbDXSurface = 1;
- }
-
- ResetStats();
- m_nRenderState = Shutdown;
- m_fUseInternalTimer = false;
- m_LastSetOutputRange = -1;
- m_bPendingRenegotiate = false;
- m_bPendingMediaFinished = false;
- m_bWaitingSample = false;
- m_pCurrentDisplaydSample = NULL;
- m_nStepCount = 0;
- m_dwVideoAspectRatioMode = MFVideoARMode_PreservePicture;
- m_dwVideoRenderPrefs = (MFVideoRenderPrefs)0;
- m_BorderColor = RGB (0,0,0);
- m_bSignaledStarvation = false;
- m_StarvationClock = 0;
- m_pOuterEVR = NULL;
- m_LastScheduledSampleTime = -1;
- m_LastScheduledUncorrectedSampleTime = -1;
- m_MaxSampleDuration = 0;
- m_LastSampleOffset = 0;
- ZeroMemory(m_VSyncOffsetHistory, sizeof(m_VSyncOffsetHistory));
- m_VSyncOffsetHistoryPos = 0;
- m_bLastSampleOffsetValid = false;
+ // Load Vista specifics DLLs
+ hLib = LoadLibrary(L"avrt.dll");
+ pfAvSetMmThreadCharacteristicsW = hLib ? (PTR_AvSetMmThreadCharacteristicsW) GetProcAddress(hLib, "AvSetMmThreadCharacteristicsW") : NULL;
+ pfAvSetMmThreadPriority = hLib ? (PTR_AvSetMmThreadPriority) GetProcAddress(hLib, "AvSetMmThreadPriority") : NULL;
+ pfAvRevertMmThreadCharacteristics = hLib ? (PTR_AvRevertMmThreadCharacteristics) GetProcAddress(hLib, "AvRevertMmThreadCharacteristics") : NULL;
+
+ // Init DXVA manager
+ hr = pfDXVA2CreateDirect3DDeviceManager9(&m_nResetToken, &m_pD3DManager);
+ if (SUCCEEDED(hr)) {
+ hr = m_pD3DManager->ResetDevice(m_pD3DDev, m_nResetToken);
+ if (!SUCCEEDED(hr)) {
+ _Error += L"m_pD3DManager->ResetDevice failed\n";
+ }
+ } else {
+ _Error += L"DXVA2CreateDirect3DDeviceManager9 failed\n";
+ }
+
+ CComPtr<IDirectXVideoDecoderService> pDecoderService;
+ HANDLE hDevice;
+ if (SUCCEEDED(m_pD3DManager->OpenDeviceHandle(&hDevice)) &&
+ SUCCEEDED(m_pD3DManager->GetVideoService(hDevice, __uuidof(IDirectXVideoDecoderService), (void**)&pDecoderService))) {
+ TRACE_EVR("EVR: DXVA2 : device handle = 0x%08x", hDevice);
+ HookDirectXVideoDecoderService(pDecoderService);
+
+ m_pD3DManager->CloseDeviceHandle(hDevice);
+ }
+
+
+ // Bufferize frame only with 3D texture!
+ if (s.iAPSurfaceUsage == VIDRNDT_AP_TEXTURE3D) {
+ m_nNbDXSurface = max(min(s.iEvrBuffers, MAX_VIDEO_SURFACES), 4);
+ } else {
+ m_nNbDXSurface = 1;
+ }
+
+ ResetStats();
+ m_nRenderState = Shutdown;
+ m_fUseInternalTimer = false;
+ m_LastSetOutputRange = -1;
+ m_bPendingRenegotiate = false;
+ m_bPendingMediaFinished = false;
+ m_bWaitingSample = false;
+ m_pCurrentDisplaydSample = NULL;
+ m_nStepCount = 0;
+ m_dwVideoAspectRatioMode = MFVideoARMode_PreservePicture;
+ m_dwVideoRenderPrefs = (MFVideoRenderPrefs)0;
+ m_BorderColor = RGB(0, 0, 0);
+ m_bSignaledStarvation = false;
+ m_StarvationClock = 0;
+ m_pOuterEVR = NULL;
+ m_LastScheduledSampleTime = -1;
+ m_LastScheduledUncorrectedSampleTime = -1;
+ m_MaxSampleDuration = 0;
+ m_LastSampleOffset = 0;
+ ZeroMemory(m_VSyncOffsetHistory, sizeof(m_VSyncOffsetHistory));
+ m_VSyncOffsetHistoryPos = 0;
+ m_bLastSampleOffsetValid = false;
}
CEVRAllocatorPresenter::~CEVRAllocatorPresenter(void)
{
- StopWorkerThreads(); // If not already done...
- m_pMediaType = NULL;
- m_pClock = NULL;
+ StopWorkerThreads(); // If not already done...
+ m_pMediaType = NULL;
+ m_pClock = NULL;
- m_pD3DManager = NULL;
+ m_pD3DManager = NULL;
}
void CEVRAllocatorPresenter::ResetStats()
{
- m_pcFrames = 0;
- m_nDroppedUpdate = 0;
- m_pcFramesDrawn = 0;
- m_piAvg = 0;
- m_piDev = 0;
+ m_pcFrames = 0;
+ m_nDroppedUpdate = 0;
+ m_pcFramesDrawn = 0;
+ m_piAvg = 0;
+ m_piDev = 0;
}
HRESULT CEVRAllocatorPresenter::CheckShutdown() const
{
- if (m_nRenderState == Shutdown) {
- return MF_E_SHUTDOWN;
- } else {
- return S_OK;
- }
+ if (m_nRenderState == Shutdown) {
+ return MF_E_SHUTDOWN;
+ } else {
+ return S_OK;
+ }
}
void CEVRAllocatorPresenter::StartWorkerThreads()
{
- DWORD dwThreadId;
+ DWORD dwThreadId;
- if (m_nRenderState == Shutdown) {
- m_hEvtQuit = CreateEvent (NULL, TRUE, FALSE, NULL);
- m_hEvtFlush = CreateEvent (NULL, TRUE, FALSE, NULL);
+ if (m_nRenderState == Shutdown) {
+ m_hEvtQuit = CreateEvent(NULL, TRUE, FALSE, NULL);
+ m_hEvtFlush = CreateEvent(NULL, TRUE, FALSE, NULL);
- m_hThread = ::CreateThread(NULL, 0, PresentThread, (LPVOID)this, 0, &dwThreadId);
- SetThreadPriority(m_hThread, THREAD_PRIORITY_TIME_CRITICAL);
- m_hGetMixerThread = ::CreateThread(NULL, 0, GetMixerThreadStatic, (LPVOID)this, 0, &dwThreadId);
- SetThreadPriority(m_hGetMixerThread, THREAD_PRIORITY_HIGHEST);
+ m_hThread = ::CreateThread(NULL, 0, PresentThread, (LPVOID)this, 0, &dwThreadId);
+ SetThreadPriority(m_hThread, THREAD_PRIORITY_TIME_CRITICAL);
+ m_hGetMixerThread = ::CreateThread(NULL, 0, GetMixerThreadStatic, (LPVOID)this, 0, &dwThreadId);
+ SetThreadPriority(m_hGetMixerThread, THREAD_PRIORITY_HIGHEST);
- m_nRenderState = Stopped;
- TRACE_EVR ("EVR: Worker threads started...\n");
- }
+ m_nRenderState = Stopped;
+ TRACE_EVR("EVR: Worker threads started...\n");
+ }
}
void CEVRAllocatorPresenter::StopWorkerThreads()
{
- if (m_nRenderState != Shutdown) {
- SetEvent (m_hEvtFlush);
- m_bEvtFlush = true;
- SetEvent (m_hEvtQuit);
- m_bEvtQuit = true;
- if ((m_hThread != INVALID_HANDLE_VALUE) && (WaitForSingleObject (m_hThread, 10000) == WAIT_TIMEOUT)) {
- ASSERT (FALSE);
- TerminateThread (m_hThread, 0xDEAD);
- }
- if ((m_hGetMixerThread != INVALID_HANDLE_VALUE) && (WaitForSingleObject (m_hGetMixerThread, 10000) == WAIT_TIMEOUT)) {
- ASSERT (FALSE);
- TerminateThread (m_hGetMixerThread, 0xDEAD);
- }
-
- if (m_hThread != INVALID_HANDLE_VALUE) {
- CloseHandle (m_hThread);
- }
- if (m_hGetMixerThread != INVALID_HANDLE_VALUE) {
- CloseHandle (m_hGetMixerThread);
- }
- if (m_hEvtFlush != INVALID_HANDLE_VALUE) {
- CloseHandle (m_hEvtFlush);
- }
- if (m_hEvtQuit != INVALID_HANDLE_VALUE) {
- CloseHandle (m_hEvtQuit);
- }
-
- m_bEvtFlush = false;
- m_bEvtQuit = false;
-
-
- TRACE_EVR ("EVR: Worker threads stopped...\n");
- }
- m_nRenderState = Shutdown;
+ if (m_nRenderState != Shutdown) {
+ SetEvent(m_hEvtFlush);
+ m_bEvtFlush = true;
+ SetEvent(m_hEvtQuit);
+ m_bEvtQuit = true;
+ if ((m_hThread != INVALID_HANDLE_VALUE) && (WaitForSingleObject(m_hThread, 10000) == WAIT_TIMEOUT)) {
+ ASSERT(FALSE);
+ TerminateThread(m_hThread, 0xDEAD);
+ }
+ if ((m_hGetMixerThread != INVALID_HANDLE_VALUE) && (WaitForSingleObject(m_hGetMixerThread, 10000) == WAIT_TIMEOUT)) {
+ ASSERT(FALSE);
+ TerminateThread(m_hGetMixerThread, 0xDEAD);
+ }
+
+ if (m_hThread != INVALID_HANDLE_VALUE) {
+ CloseHandle(m_hThread);
+ }
+ if (m_hGetMixerThread != INVALID_HANDLE_VALUE) {
+ CloseHandle(m_hGetMixerThread);
+ }
+ if (m_hEvtFlush != INVALID_HANDLE_VALUE) {
+ CloseHandle(m_hEvtFlush);
+ }
+ if (m_hEvtQuit != INVALID_HANDLE_VALUE) {
+ CloseHandle(m_hEvtQuit);
+ }
+
+ m_bEvtFlush = false;
+ m_bEvtQuit = false;
+
+
+ TRACE_EVR("EVR: Worker threads stopped...\n");
+ }
+ m_nRenderState = Shutdown;
}
STDMETHODIMP CEVRAllocatorPresenter::CreateRenderer(IUnknown** ppRenderer)
{
- CheckPointer(ppRenderer, E_POINTER);
+ CheckPointer(ppRenderer, E_POINTER);
- *ppRenderer = NULL;
+ *ppRenderer = NULL;
- HRESULT hr = E_FAIL;
+ HRESULT hr = E_FAIL;
- do {
- CMacrovisionKicker* pMK = DNew CMacrovisionKicker(NAME("CMacrovisionKicker"), NULL);
- CComPtr<IUnknown> pUnk = (IUnknown*)(INonDelegatingUnknown*)pMK;
+ do {
+ CMacrovisionKicker* pMK = DNew CMacrovisionKicker(NAME("CMacrovisionKicker"), NULL);
+ CComPtr<IUnknown> pUnk = (IUnknown*)(INonDelegatingUnknown*)pMK;
- COuterEVR *pOuterEVR = DNew COuterEVR(NAME("COuterEVR"), pUnk, hr, &m_VMR9AlphaBitmap, this);
- m_pOuterEVR = pOuterEVR;
+ COuterEVR* pOuterEVR = DNew COuterEVR(NAME("COuterEVR"), pUnk, hr, &m_VMR9AlphaBitmap, this);
+ m_pOuterEVR = pOuterEVR;
- pMK->SetInner((IUnknown*)(INonDelegatingUnknown*)pOuterEVR);
- CComQIPtr<IBaseFilter> pBF = pUnk;
+ pMK->SetInner((IUnknown*)(INonDelegatingUnknown*)pOuterEVR);
+ CComQIPtr<IBaseFilter> pBF = pUnk;
- if (FAILED (hr)) {
- break;
- }
+ if (FAILED(hr)) {
+ break;
+ }
- // Set EVR custom presenter
- CComPtr<IMFVideoPresenter> pVP;
- CComPtr<IMFVideoRenderer> pMFVR;
- CComQIPtr<IMFGetService, &__uuidof(IMFGetService)> pMFGS = pBF;
- CComQIPtr<IEVRFilterConfig> pConfig = pBF;
- if (SUCCEEDED(hr)) {
- if (FAILED(pConfig->SetNumberOfStreams(3))) { // TODO - maybe need other number of input stream ...
- break;
- }
- }
+ // Set EVR custom presenter
+ CComPtr<IMFVideoPresenter> pVP;
+ CComPtr<IMFVideoRenderer> pMFVR;
+ CComQIPtr<IMFGetService, &__uuidof(IMFGetService)> pMFGS = pBF;
+ CComQIPtr<IEVRFilterConfig> pConfig = pBF;
+ if (SUCCEEDED(hr)) {
+ if (FAILED(pConfig->SetNumberOfStreams(3))) { // TODO - maybe need other number of input stream ...
+ break;
+ }
+ }
- hr = pMFGS->GetService (MR_VIDEO_RENDER_SERVICE, IID_IMFVideoRenderer, (void**)&pMFVR);
+ hr = pMFGS->GetService(MR_VIDEO_RENDER_SERVICE, IID_IMFVideoRenderer, (void**)&pMFVR);
- if (SUCCEEDED(hr)) {
- hr = QueryInterface (__uuidof(IMFVideoPresenter), (void**)&pVP);
- }
- if (SUCCEEDED(hr)) {
- hr = pMFVR->InitializeRenderer (NULL, pVP);
- }
+ if (SUCCEEDED(hr)) {
+ hr = QueryInterface(__uuidof(IMFVideoPresenter), (void**)&pVP);
+ }
+ if (SUCCEEDED(hr)) {
+ hr = pMFVR->InitializeRenderer(NULL, pVP);
+ }
#if 1
- CComPtr<IPin> pPin = GetFirstPin(pBF);
- CComQIPtr<IMemInputPin> pMemInputPin = pPin;
+ CComPtr<IPin> pPin = GetFirstPin(pBF);
+ CComQIPtr<IMemInputPin> pMemInputPin = pPin;
- // No NewSegment : no chocolate :o)
- m_fUseInternalTimer = HookNewSegmentAndReceive((IPinC*)(IPin*)pPin, (IMemInputPinC*)(IMemInputPin*)pMemInputPin);
+ // No NewSegment : no chocolate :o)
+ m_fUseInternalTimer = HookNewSegmentAndReceive((IPinC*)(IPin*)pPin, (IMemInputPinC*)(IMemInputPin*)pMemInputPin);
#else
- m_fUseInternalTimer = false;
+ m_fUseInternalTimer = false;
#endif
- if (FAILED(hr)) {
- *ppRenderer = NULL;
- } else {
- *ppRenderer = pBF.Detach();
- }
+ if (FAILED(hr)) {
+ *ppRenderer = NULL;
+ } else {
+ *ppRenderer = pBF.Detach();
+ }
- } while (0);
+ } while (0);
- return hr;
+ return hr;
}
STDMETHODIMP_(bool) CEVRAllocatorPresenter::Paint(bool fAll)
{
- return __super::Paint (fAll);
+ return __super::Paint(fAll);
}
STDMETHODIMP CEVRAllocatorPresenter::NonDelegatingQueryInterface(REFIID riid, void** ppv)
{
- HRESULT hr;
- if (riid == __uuidof(IMFClockStateSink)) {
- hr = GetInterface((IMFClockStateSink*)this, ppv);
- } else if (riid == __uuidof(IMFVideoPresenter)) {
- hr = GetInterface((IMFVideoPresenter*)this, ppv);
- } else if (riid == __uuidof(IMFTopologyServiceLookupClient)) {
- hr = GetInterface((IMFTopologyServiceLookupClient*)this, ppv);
- } else if (riid == __uuidof(IMFVideoDeviceID)) {
- hr = GetInterface((IMFVideoDeviceID*)this, ppv);
- } else if (riid == __uuidof(IMFGetService)) {
- hr = GetInterface((IMFGetService*)this, ppv);
- } else if (riid == __uuidof(IMFAsyncCallback)) {
- hr = GetInterface((IMFAsyncCallback*)this, ppv);
- } else if (riid == __uuidof(IMFVideoDisplayControl)) {
- hr = GetInterface((IMFVideoDisplayControl*)this, ppv);
- } else if (riid == __uuidof(IEVRTrustedVideoPlugin)) {
- hr = GetInterface((IEVRTrustedVideoPlugin*)this, ppv);
- } else if (riid == IID_IQualProp) {
- hr = GetInterface((IQualProp*)this, ppv);
- } else if (riid == __uuidof(IMFRateSupport)) {
- hr = GetInterface((IMFRateSupport*)this, ppv);
- } else if (riid == __uuidof(IDirect3DDeviceManager9))
- // hr = GetInterface((IDirect3DDeviceManager9*)this, ppv);
- {
- hr = m_pD3DManager->QueryInterface (__uuidof(IDirect3DDeviceManager9), (void**) ppv);
- } else {
- hr = __super::NonDelegatingQueryInterface(riid, ppv);
- }
-
- return hr;
+ HRESULT hr;
+ if (riid == __uuidof(IMFClockStateSink)) {
+ hr = GetInterface((IMFClockStateSink*)this, ppv);
+ } else if (riid == __uuidof(IMFVideoPresenter)) {
+ hr = GetInterface((IMFVideoPresenter*)this, ppv);
+ } else if (riid == __uuidof(IMFTopologyServiceLookupClient)) {
+ hr = GetInterface((IMFTopologyServiceLookupClient*)this, ppv);
+ } else if (riid == __uuidof(IMFVideoDeviceID)) {
+ hr = GetInterface((IMFVideoDeviceID*)this, ppv);
+ } else if (riid == __uuidof(IMFGetService)) {
+ hr = GetInterface((IMFGetService*)this, ppv);
+ } else if (riid == __uuidof(IMFAsyncCallback)) {
+ hr = GetInterface((IMFAsyncCallback*)this, ppv);
+ } else if (riid == __uuidof(IMFVideoDisplayControl)) {
+ hr = GetInterface((IMFVideoDisplayControl*)this, ppv);
+ } else if (riid == __uuidof(IEVRTrustedVideoPlugin)) {
+ hr = GetInterface((IEVRTrustedVideoPlugin*)this, ppv);
+ } else if (riid == IID_IQualProp) {
+ hr = GetInterface((IQualProp*)this, ppv);
+ } else if (riid == __uuidof(IMFRateSupport)) {
+ hr = GetInterface((IMFRateSupport*)this, ppv);
+ } else if (riid == __uuidof(IDirect3DDeviceManager9))
+ // hr = GetInterface((IDirect3DDeviceManager9*)this, ppv);
+ {
+ hr = m_pD3DManager->QueryInterface(__uuidof(IDirect3DDeviceManager9), (void**) ppv);
+ } else {
+ hr = __super::NonDelegatingQueryInterface(riid, ppv);
+ }
+
+ return hr;
}
// IMFClockStateSink
STDMETHODIMP CEVRAllocatorPresenter::OnClockStart(MFTIME hnsSystemTime, LONGLONG llClockStartOffset)
{
- m_nRenderState = Started;
+ m_nRenderState = Started;
- TRACE_EVR ("EVR: OnClockStart hnsSystemTime = %I64d, llClockStartOffset = %I64d\n", hnsSystemTime, llClockStartOffset);
- m_ModeratedTimeLast = -1;
- m_ModeratedClockLast = -1;
+ TRACE_EVR("EVR: OnClockStart hnsSystemTime = %I64d, llClockStartOffset = %I64d\n", hnsSystemTime, llClockStartOffset);
+ m_ModeratedTimeLast = -1;
+ m_ModeratedClockLast = -1;
- return S_OK;
+ return S_OK;
}
STDMETHODIMP CEVRAllocatorPresenter::OnClockStop(MFTIME hnsSystemTime)
{
- TRACE_EVR ("EVR: OnClockStop hnsSystemTime = %I64d\n", hnsSystemTime);
- m_nRenderState = Stopped;
+ TRACE_EVR("EVR: OnClockStop hnsSystemTime = %I64d\n", hnsSystemTime);
+ m_nRenderState = Stopped;
- m_ModeratedClockLast = -1;
- m_ModeratedTimeLast = -1;
- return S_OK;
+ m_ModeratedClockLast = -1;
+ m_ModeratedTimeLast = -1;
+ return S_OK;
}
STDMETHODIMP CEVRAllocatorPresenter::OnClockPause(MFTIME hnsSystemTime)
{
- TRACE_EVR ("EVR: OnClockPause hnsSystemTime = %I64d\n", hnsSystemTime);
- if (!m_bSignaledStarvation) {
- m_nRenderState = Paused;
- }
- m_ModeratedTimeLast = -1;
- m_ModeratedClockLast = -1;
- return S_OK;
+ TRACE_EVR("EVR: OnClockPause hnsSystemTime = %I64d\n", hnsSystemTime);
+ if (!m_bSignaledStarvation) {
+ m_nRenderState = Paused;
+ }
+ m_ModeratedTimeLast = -1;
+ m_ModeratedClockLast = -1;
+ return S_OK;
}
STDMETHODIMP CEVRAllocatorPresenter::OnClockRestart(MFTIME hnsSystemTime)
{
- m_nRenderState = Started;
+ m_nRenderState = Started;
- m_ModeratedTimeLast = -1;
- m_ModeratedClockLast = -1;
- TRACE_EVR ("EVR: OnClockRestart hnsSystemTime = %I64d\n", hnsSystemTime);
+ m_ModeratedTimeLast = -1;
+ m_ModeratedClockLast = -1;
+ TRACE_EVR("EVR: OnClockRestart hnsSystemTime = %I64d\n", hnsSystemTime);
- return S_OK;
+ return S_OK;
}
STDMETHODIMP CEVRAllocatorPresenter::OnClockSetRate(MFTIME hnsSystemTime, float flRate)
{
- ASSERT (FALSE);
- return E_NOTIMPL;
+ ASSERT(FALSE);
+ return E_NOTIMPL;
}
// IBaseFilter delegate
-bool CEVRAllocatorPresenter::GetState( DWORD dwMilliSecsTimeout, FILTER_STATE *State, HRESULT &_ReturnValue)
+bool CEVRAllocatorPresenter::GetState(DWORD dwMilliSecsTimeout, FILTER_STATE* State, HRESULT& _ReturnValue)
{
- CAutoLock lock(&m_SampleQueueLock);
+ CAutoLock lock(&m_SampleQueueLock);
- if (m_bSignaledStarvation) {
- size_t nSamples = max(m_nNbDXSurface / 2, 1);
- if ((m_ScheduledSamples.GetCount() < nSamples || m_LastSampleOffset < -m_rtTimePerFrame*2) && !g_bNoDuration) {
- *State = (FILTER_STATE)Paused;
- _ReturnValue = VFW_S_STATE_INTERMEDIATE;
- return true;
- }
- m_bSignaledStarvation = false;
- }
- return false;
+ if (m_bSignaledStarvation) {
+ size_t nSamples = max(m_nNbDXSurface / 2, 1);
+ if ((m_ScheduledSamples.GetCount() < nSamples || m_LastSampleOffset < -m_rtTimePerFrame * 2) && !g_bNoDuration) {
+ *State = (FILTER_STATE)Paused;
+ _ReturnValue = VFW_S_STATE_INTERMEDIATE;
+ return true;
+ }
+ m_bSignaledStarvation = false;
+ }
+ return false;
}
// IQualProp
-STDMETHODIMP CEVRAllocatorPresenter::get_FramesDroppedInRenderer(int *pcFrames)
+STDMETHODIMP CEVRAllocatorPresenter::get_FramesDroppedInRenderer(int* pcFrames)
{
- *pcFrames = m_pcFrames;
- return S_OK;
+ *pcFrames = m_pcFrames;
+ return S_OK;
}
-STDMETHODIMP CEVRAllocatorPresenter::get_FramesDrawn(int *pcFramesDrawn)
+STDMETHODIMP CEVRAllocatorPresenter::get_FramesDrawn(int* pcFramesDrawn)
{
- *pcFramesDrawn = m_pcFramesDrawn;
- return S_OK;
+ *pcFramesDrawn = m_pcFramesDrawn;
+ return S_OK;
}
-STDMETHODIMP CEVRAllocatorPresenter::get_AvgFrameRate(int *piAvgFrameRate)
+STDMETHODIMP CEVRAllocatorPresenter::get_AvgFrameRate(int* piAvgFrameRate)
{
- *piAvgFrameRate = (int)(m_fAvrFps * 100);
- return S_OK;
+ *piAvgFrameRate = (int)(m_fAvrFps * 100);
+ return S_OK;
}
-STDMETHODIMP CEVRAllocatorPresenter::get_Jitter(int *iJitter)
+STDMETHODIMP CEVRAllocatorPresenter::get_Jitter(int* iJitter)
{
- *iJitter = (int)((m_fJitterStdDev/10000.0) + 0.5);
- return S_OK;
+ *iJitter = (int)((m_fJitterStdDev / 10000.0) + 0.5);
+ return S_OK;
}
-STDMETHODIMP CEVRAllocatorPresenter::get_AvgSyncOffset(int *piAvg)
+STDMETHODIMP CEVRAllocatorPresenter::get_AvgSyncOffset(int* piAvg)
{
- *piAvg = (int)((m_fSyncOffsetAvr/10000.0) + 0.5);
- return S_OK;
+ *piAvg = (int)((m_fSyncOffsetAvr / 10000.0) + 0.5);
+ return S_OK;
}
-STDMETHODIMP CEVRAllocatorPresenter::get_DevSyncOffset(int *piDev)
+STDMETHODIMP CEVRAllocatorPresenter::get_DevSyncOffset(int* piDev)
{
- *piDev = (int)((m_fSyncOffsetStdDev/10000.0) + 0.5);
- return S_OK;
+ *piDev = (int)((m_fSyncOffsetStdDev / 10000.0) + 0.5);
+ return S_OK;
}
// IMFRateSupport
-STDMETHODIMP CEVRAllocatorPresenter::GetSlowestRate(MFRATE_DIRECTION eDirection, BOOL fThin, float *pflRate)
+STDMETHODIMP CEVRAllocatorPresenter::GetSlowestRate(MFRATE_DIRECTION eDirection, BOOL fThin, float* pflRate)
{
- // TODO : not finished...
- *pflRate = 0;
- return S_OK;
+ // TODO : not finished...
+ *pflRate = 0;
+ return S_OK;
}
-STDMETHODIMP CEVRAllocatorPresenter::GetFastestRate(MFRATE_DIRECTION eDirection, BOOL fThin, float *pflRate)
+STDMETHODIMP CEVRAllocatorPresenter::GetFastestRate(MFRATE_DIRECTION eDirection, BOOL fThin, float* pflRate)
{
- HRESULT hr = S_OK;
- float fMaxRate = 0.0f;
+ HRESULT hr = S_OK;
+ float fMaxRate = 0.0f;
- CAutoLock lock(this);
+ CAutoLock lock(this);
- CheckPointer(pflRate, E_POINTER);
- CheckHR(CheckShutdown());
+ CheckPointer(pflRate, E_POINTER);
+ CheckHR(CheckShutdown());
- // Get the maximum forward rate.
- fMaxRate = GetMaxRate(fThin);
+ // Get the maximum forward rate.
+ fMaxRate = GetMaxRate(fThin);
- // For reverse playback, swap the sign.
- if (eDirection == MFRATE_REVERSE) {
- fMaxRate = -fMaxRate;
- }
+ // For reverse playback, swap the sign.
+ if (eDirection == MFRATE_REVERSE) {
+ fMaxRate = -fMaxRate;
+ }
- *pflRate = fMaxRate;
+ *pflRate = fMaxRate;
- return hr;
+ return hr;
}
-STDMETHODIMP CEVRAllocatorPresenter::IsRateSupported(BOOL fThin, float flRate, float *pflNearestSupportedRate)
+STDMETHODIMP CEVRAllocatorPresenter::IsRateSupported(BOOL fThin, float flRate, float* pflNearestSupportedRate)
{
- // fRate can be negative for reverse playback.
- // pfNearestSupportedRate can be NULL.
+ // fRate can be negative for reverse playback.
+ // pfNearestSupportedRate can be NULL.
- CAutoLock lock(this);
+ CAutoLock lock(this);
- HRESULT hr = S_OK;
- float fMaxRate = 0.0f;
- float fNearestRate = flRate; // Default.
+ HRESULT hr = S_OK;
+ float fMaxRate = 0.0f;
+ float fNearestRate = flRate; // Default.
- CheckPointer (pflNearestSupportedRate, E_POINTER);
- CheckHR(hr = CheckShutdown());
+ CheckPointer(pflNearestSupportedRate, E_POINTER);
+ CheckHR(hr = CheckShutdown());
- // Find the maximum forward rate.
- fMaxRate = GetMaxRate(fThin);
+ // Find the maximum forward rate.
+ fMaxRate = GetMaxRate(fThin);
- if (fabsf(flRate) > fMaxRate) {
- // The (absolute) requested rate exceeds the maximum rate.
- hr = MF_E_UNSUPPORTED_RATE;
+ if (fabsf(flRate) > fMaxRate) {
+ // The (absolute) requested rate exceeds the maximum rate.
+ hr = MF_E_UNSUPPORTED_RATE;
- // The nearest supported rate is fMaxRate.
- fNearestRate = fMaxRate;
- if (flRate < 0) {
- // For reverse playback, swap the sign.
- fNearestRate = -fNearestRate;
- }
- }
+ // The nearest supported rate is fMaxRate.
+ fNearestRate = fMaxRate;
+ if (flRate < 0) {
+ // For reverse playback, swap the sign.
+ fNearestRate = -fNearestRate;
+ }
+ }
- // Return the nearest supported rate if the caller requested it.
- if (pflNearestSupportedRate != NULL) {
- *pflNearestSupportedRate = fNearestRate;
- }
+ // Return the nearest supported rate if the caller requested it.
+ if (pflNearestSupportedRate != NULL) {
+ *pflNearestSupportedRate = fNearestRate;
+ }
- return hr;
+ return hr;
}
float CEVRAllocatorPresenter::GetMaxRate(BOOL bThin)
{
- float fMaxRate = FLT_MAX; // Default.
- UINT32 fpsNumerator = 0, fpsDenominator = 0;
+ float fMaxRate = FLT_MAX; // Default.
+ UINT32 fpsNumerator = 0, fpsDenominator = 0;
- if (!bThin && (m_pMediaType != NULL)) {
- // Non-thinned: Use the frame rate and monitor refresh rate.
+ if (!bThin && (m_pMediaType != NULL)) {
+ // Non-thinned: Use the frame rate and monitor refresh rate.
- // Frame rate:
- MFGetAttributeRatio(m_pMediaType, MF_MT_FRAME_RATE,
- &fpsNumerator, &fpsDenominator);
+ // Frame rate:
+ MFGetAttributeRatio(m_pMediaType, MF_MT_FRAME_RATE,
+ &fpsNumerator, &fpsDenominator);
- // Monitor refresh rate:
- UINT MonitorRateHz = m_RefreshRate; // D3DDISPLAYMODE
+ // Monitor refresh rate:
+ UINT MonitorRateHz = m_RefreshRate; // D3DDISPLAYMODE
- if (fpsDenominator && fpsNumerator && MonitorRateHz) {
- // Max Rate = Refresh Rate / Frame Rate
- fMaxRate = (float)MulDiv(MonitorRateHz, fpsDenominator, fpsNumerator);
- }
- }
- return fMaxRate;
+ if (fpsDenominator && fpsNumerator && MonitorRateHz) {
+ // Max Rate = Refresh Rate / Frame Rate
+ fMaxRate = (float)MulDiv(MonitorRateHz, fpsDenominator, fpsNumerator);
+ }
+ }
+ return fMaxRate;
}
void CEVRAllocatorPresenter::CompleteFrameStep(bool bCancel)
{
- if (m_nStepCount > 0) {
- if (bCancel || (m_nStepCount == 1)) {
- m_pSink->Notify(EC_STEP_COMPLETE, bCancel ? TRUE : FALSE, 0);
- m_nStepCount = 0;
- } else {
- m_nStepCount--;
- }
- }
+ if (m_nStepCount > 0) {
+ if (bCancel || (m_nStepCount == 1)) {
+ m_pSink->Notify(EC_STEP_COMPLETE, bCancel ? TRUE : FALSE, 0);
+ m_nStepCount = 0;
+ } else {
+ m_nStepCount--;
+ }
+ }
}
// IMFVideoPresenter
STDMETHODIMP CEVRAllocatorPresenter::ProcessMessage(MFVP_MESSAGE_TYPE eMessage, ULONG_PTR ulParam)
{
- HRESULT hr = S_OK;
-
- switch (eMessage) {
- case MFVP_MESSAGE_BEGINSTREAMING : // The EVR switched from stopped to paused. The presenter should allocate resources
- ResetStats();
- TRACE_EVR ("EVR: MFVP_MESSAGE_BEGINSTREAMING\n");
- break;
-
- case MFVP_MESSAGE_CANCELSTEP : // Cancels a frame step
- TRACE_EVR ("EVR: MFVP_MESSAGE_CANCELSTEP\n");
- CompleteFrameStep (true);
- break;
-
- case MFVP_MESSAGE_ENDOFSTREAM : // All input streams have ended.
- TRACE_EVR ("EVR: MFVP_MESSAGE_ENDOFSTREAM\n");
- m_bPendingMediaFinished = true;
- break;
-
- case MFVP_MESSAGE_ENDSTREAMING : // The EVR switched from running or paused to stopped. The presenter should free resources
- TRACE_EVR ("EVR: MFVP_MESSAGE_ENDSTREAMING\n");
- break;
-
- case MFVP_MESSAGE_FLUSH : // The presenter should discard any pending samples
- SetEvent(m_hEvtFlush);
- m_bEvtFlush = true;
- TRACE_EVR ("EVR: MFVP_MESSAGE_FLUSH\n");
- while (WaitForSingleObject(m_hEvtFlush, 1) == WAIT_OBJECT_0) {
- ;
- }
- break;
-
- case MFVP_MESSAGE_INVALIDATEMEDIATYPE : // The mixer's output format has changed. The EVR will initiate format negotiation, as described previously
- /*
- 1) The EVR sets the media type on the reference stream.
- 2) The EVR calls IMFVideoPresenter::ProcessMessage on the presenter with the MFVP_MESSAGE_INVALIDATEMEDIATYPE message.
- 3) The presenter sets the media type on the mixer's output stream.
- 4) The EVR sets the media type on the substreams.
- */
- m_bPendingRenegotiate = true;
- while (*((volatile bool *)&m_bPendingRenegotiate)) {
- Sleep(1);
- }
- break;
-
- case MFVP_MESSAGE_PROCESSINPUTNOTIFY : // One input stream on the mixer has received a new sample
- // GetImageFromMixer();
- break;
-
- case MFVP_MESSAGE_STEP : // Requests a frame step.
- TRACE_EVR ("EVR: MFVP_MESSAGE_STEP\n");
- m_nStepCount = (int)ulParam;
- hr = S_OK;
- break;
-
- default :
- ASSERT (FALSE);
- break;
- }
- return hr;
+ HRESULT hr = S_OK;
+
+ switch (eMessage) {
+ case MFVP_MESSAGE_BEGINSTREAMING : // The EVR switched from stopped to paused. The presenter should allocate resources
+ ResetStats();
+ TRACE_EVR("EVR: MFVP_MESSAGE_BEGINSTREAMING\n");
+ break;
+
+ case MFVP_MESSAGE_CANCELSTEP : // Cancels a frame step
+ TRACE_EVR("EVR: MFVP_MESSAGE_CANCELSTEP\n");
+ CompleteFrameStep(true);
+ break;
+
+ case MFVP_MESSAGE_ENDOFSTREAM : // All input streams have ended.
+ TRACE_EVR("EVR: MFVP_MESSAGE_ENDOFSTREAM\n");
+ m_bPendingMediaFinished = true;
+ break;
+
+ case MFVP_MESSAGE_ENDSTREAMING : // The EVR switched from running or paused to stopped. The presenter should free resources
+ TRACE_EVR("EVR: MFVP_MESSAGE_ENDSTREAMING\n");
+ break;
+
+ case MFVP_MESSAGE_FLUSH : // The presenter should discard any pending samples
+ SetEvent(m_hEvtFlush);
+ m_bEvtFlush = true;
+ TRACE_EVR("EVR: MFVP_MESSAGE_FLUSH\n");
+ while (WaitForSingleObject(m_hEvtFlush, 1) == WAIT_OBJECT_0) {
+ ;
+ }
+ break;
+
+ case MFVP_MESSAGE_INVALIDATEMEDIATYPE : // The mixer's output format has changed. The EVR will initiate format negotiation, as described previously
+ /*
+ 1) The EVR sets the media type on the reference stream.
+ 2) The EVR calls IMFVideoPresenter::ProcessMessage on the presenter with the MFVP_MESSAGE_INVALIDATEMEDIATYPE message.
+ 3) The presenter sets the media type on the mixer's output stream.
+ 4) The EVR sets the media type on the substreams.
+ */
+ m_bPendingRenegotiate = true;
+ while (*((volatile bool*)&m_bPendingRenegotiate)) {
+ Sleep(1);
+ }
+ break;
+
+ case MFVP_MESSAGE_PROCESSINPUTNOTIFY : // One input stream on the mixer has received a new sample
+ // GetImageFromMixer();
+ break;
+
+ case MFVP_MESSAGE_STEP : // Requests a frame step.
+ TRACE_EVR("EVR: MFVP_MESSAGE_STEP\n");
+ m_nStepCount = (int)ulParam;
+ hr = S_OK;
+ break;
+
+ default :
+ ASSERT(FALSE);
+ break;
+ }
+ return hr;
}
HRESULT CEVRAllocatorPresenter::IsMediaTypeSupported(IMFMediaType* pMixerType)
{
- HRESULT hr;
+ HRESULT hr;
- // We support only video types
- GUID MajorType;
- hr = pMixerType->GetMajorType(&MajorType);
+ // We support only video types
+ GUID MajorType;
+ hr = pMixerType->GetMajorType(&MajorType);
- if (SUCCEEDED(hr)) {
- if (MajorType != MFMediaType_Video) {
- hr = MF_E_INVALIDMEDIATYPE;
- }
- }
+ if (SUCCEEDED(hr)) {
+ if (MajorType != MFMediaType_Video) {
+ hr = MF_E_INVALIDMEDIATYPE;
+ }
+ }
- // We support only progressive formats
- MFVideoInterlaceMode InterlaceMode;
+ // We support only progressive formats
+ MFVideoInterlaceMode InterlaceMode;
- if (SUCCEEDED(hr)) {
- hr = pMixerType->GetUINT32(MF_MT_INTERLACE_MODE, (UINT32*)&InterlaceMode);
- }
+ if (SUCCEEDED(hr)) {
+ hr = pMixerType->GetUINT32(MF_MT_INTERLACE_MODE, (UINT32*)&InterlaceMode);
+ }
- if (SUCCEEDED(hr)) {
- if (InterlaceMode != MFVideoInterlace_Progressive) {
- hr = MF_E_INVALIDMEDIATYPE;
- }
- }
+ if (SUCCEEDED(hr)) {
+ if (InterlaceMode != MFVideoInterlace_Progressive) {
+ hr = MF_E_INVALIDMEDIATYPE;
+ }
+ }
- // Check whether we support the surface format
- int Merit = 0;
+ // Check whether we support the surface format
+ int Merit = 0;
- if (SUCCEEDED(hr)) {
- hr = GetMediaTypeMerit(pMixerType, &Merit);
- }
+ if (SUCCEEDED(hr)) {
+ hr = GetMediaTypeMerit(pMixerType, &Merit);
+ }
- if (SUCCEEDED(hr)) {
- if (Merit == 0) {
- hr = MF_E_INVALIDMEDIATYPE;
- }
- }
+ if (SUCCEEDED(hr)) {
+ if (Merit == 0) {
+ hr = MF_E_INVALIDMEDIATYPE;
+ }
+ }
- return hr;
+ return hr;
}
HRESULT CEVRAllocatorPresenter::CreateProposedOutputType(IMFMediaType* pMixerType, IMFMediaType** pType)
{
- HRESULT hr;
- AM_MEDIA_TYPE* pAMMedia = NULL;
- LARGE_INTEGER i64Size;
- MFVIDEOFORMAT* VideoFormat;
-
- CheckHR (pMixerType->GetRepresentation (FORMAT_MFVideoFormat, (void**)&pAMMedia));
-
- VideoFormat = (MFVIDEOFORMAT*)pAMMedia->pbFormat;
- hr = pfMFCreateVideoMediaType (VideoFormat, &m_pMediaType);
-
- if (0) {
- // This code doesn't work, use same method as VMR9 instead
- if (VideoFormat->videoInfo.FramesPerSecond.Numerator != 0) {
- switch (VideoFormat->videoInfo.InterlaceMode) {
- case MFVideoInterlace_Progressive:
- case MFVideoInterlace_MixedInterlaceOrProgressive:
- default: {
- m_rtTimePerFrame = (10000000I64*VideoFormat->videoInfo.FramesPerSecond.Denominator)/VideoFormat->videoInfo.FramesPerSecond.Numerator;
- m_bInterlaced = false;
- }
- break;
- case MFVideoInterlace_FieldSingleUpper:
- case MFVideoInterlace_FieldSingleLower:
- case MFVideoInterlace_FieldInterleavedUpperFirst:
- case MFVideoInterlace_FieldInterleavedLowerFirst: {
- m_rtTimePerFrame = (20000000I64*VideoFormat->videoInfo.FramesPerSecond.Denominator)/VideoFormat->videoInfo.FramesPerSecond.Numerator;
- m_bInterlaced = true;
- }
- break;
- }
- }
- }
-
- m_AspectRatio.cx = VideoFormat->videoInfo.PixelAspectRatio.Numerator;
- m_AspectRatio.cy = VideoFormat->videoInfo.PixelAspectRatio.Denominator;
-
- if (SUCCEEDED (hr)) {
- i64Size.HighPart = VideoFormat->videoInfo.dwWidth;
- i64Size.LowPart = VideoFormat->videoInfo.dwHeight;
- m_pMediaType->SetUINT64 (MF_MT_FRAME_SIZE, i64Size.QuadPart);
-
- m_pMediaType->SetUINT32 (MF_MT_PAN_SCAN_ENABLED, 0);
-
- CRenderersSettings& s = GetRenderersSettings();
+ HRESULT hr;
+ AM_MEDIA_TYPE* pAMMedia = NULL;
+ LARGE_INTEGER i64Size;
+ MFVIDEOFORMAT* VideoFormat;
+
+ CheckHR(pMixerType->GetRepresentation(FORMAT_MFVideoFormat, (void**)&pAMMedia));
+
+ VideoFormat = (MFVIDEOFORMAT*)pAMMedia->pbFormat;
+ hr = pfMFCreateVideoMediaType(VideoFormat, &m_pMediaType);
+
+ if (0) {
+ // This code doesn't work, use same method as VMR9 instead
+ if (VideoFormat->videoInfo.FramesPerSecond.Numerator != 0) {
+ switch (VideoFormat->videoInfo.InterlaceMode) {
+ case MFVideoInterlace_Progressive:
+ case MFVideoInterlace_MixedInterlaceOrProgressive:
+ default: {
+ m_rtTimePerFrame = (10000000I64 * VideoFormat->videoInfo.FramesPerSecond.Denominator) / VideoFormat->videoInfo.FramesPerSecond.Numerator;
+ m_bInterlaced = false;
+ }
+ break;
+ case MFVideoInterlace_FieldSingleUpper:
+ case MFVideoInterlace_FieldSingleLower:
+ case MFVideoInterlace_FieldInterleavedUpperFirst:
+ case MFVideoInterlace_FieldInterleavedLowerFirst: {
+ m_rtTimePerFrame = (20000000I64 * VideoFormat->videoInfo.FramesPerSecond.Denominator) / VideoFormat->videoInfo.FramesPerSecond.Numerator;
+ m_bInterlaced = true;
+ }
+ break;
+ }
+ }
+ }
+
+ m_AspectRatio.cx = VideoFormat->videoInfo.PixelAspectRatio.Numerator;
+ m_AspectRatio.cy = VideoFormat->videoInfo.PixelAspectRatio.Denominator;
+
+ if (SUCCEEDED(hr)) {
+ i64Size.HighPart = VideoFormat->videoInfo.dwWidth;
+ i64Size.LowPart = VideoFormat->videoInfo.dwHeight;
+ m_pMediaType->SetUINT64(MF_MT_FRAME_SIZE, i64Size.QuadPart);
+
+ m_pMediaType->SetUINT32(MF_MT_PAN_SCAN_ENABLED, 0);
+
+ CRenderersSettings& s = GetRenderersSettings();
#if 1
- if (s.m_RenderSettings.iEVROutputRange == 1) {
- m_pMediaType->SetUINT32 (MF_MT_VIDEO_NOMINAL_RANGE, MFNominalRange_16_235);
- } else {
- m_pMediaType->SetUINT32 (MF_MT_VIDEO_NOMINAL_RANGE, MFNominalRange_0_255);
- }
+ if (s.m_RenderSettings.iEVROutputRange == 1) {
+ m_pMediaType->SetUINT32(MF_MT_VIDEO_NOMINAL_RANGE, MFNominalRange_16_235);
+ } else {
+ m_pMediaType->SetUINT32(MF_MT_VIDEO_NOMINAL_RANGE, MFNominalRange_0_255);
+ }
- // m_pMediaType->SetUINT32 (MF_MT_TRANSFER_FUNCTION, MFVideoTransFunc_10);
+ // m_pMediaType->SetUINT32 (MF_MT_TRANSFER_FUNCTION, MFVideoTransFunc_10);
#else
- m_pMediaType->SetUINT32 (MF_MT_VIDEO_NOMINAL_RANGE, MFNominalRange_0_255);
- if (s.iEVROutputRange == 1) {
- m_pMediaType->SetUINT32 (MF_MT_YUV_MATRIX, MFVideoTransferMatrix_BT601);
- } else {
- m_pMediaType->SetUINT32 (MF_MT_YUV_MATRIX, MFVideoTransferMatrix_BT709);
- }
+ m_pMediaType->SetUINT32(MF_MT_VIDEO_NOMINAL_RANGE, MFNominalRange_0_255);
+ if (s.iEVROutputRange == 1) {
+ m_pMediaType->SetUINT32(MF_MT_YUV_MATRIX, MFVideoTransferMatrix_BT601);
+ } else {
+ m_pMediaType->SetUINT32(MF_MT_YUV_MATRIX, MFVideoTransferMatrix_BT709);
+ }
#endif
- m_LastSetOutputRange = s.m_RenderSettings.iEVROutputRange;
+ m_LastSetOutputRange = s.m_RenderSettings.iEVROutputRange;
- i64Size.HighPart = m_AspectRatio.cx;
- i64Size.LowPart = m_AspectRatio.cy;
- m_pMediaType->SetUINT64 (MF_MT_PIXEL_ASPECT_RATIO, i64Size.QuadPart);
+ i64Size.HighPart = m_AspectRatio.cx;
+ i64Size.LowPart = m_AspectRatio.cy;
+ m_pMediaType->SetUINT64(MF_MT_PIXEL_ASPECT_RATIO, i64Size.QuadPart);
- MFVideoArea Area = MakeArea (0, 0, VideoFormat->videoInfo.dwWidth, VideoFormat->videoInfo.dwHeight);
- m_pMediaType->SetBlob(MF_MT_GEOMETRIC_APERTURE, (UINT8*)&Area, sizeof(MFVideoArea));
+ MFVideoArea Area = MakeArea(0, 0, VideoFormat->videoInfo.dwWidth, VideoFormat->videoInfo.dwHeight);
+ m_pMediaType->SetBlob(MF_MT_GEOMETRIC_APERTURE, (UINT8*)&Area, sizeof(MFVideoArea));
- }
+ }
- m_AspectRatio.cx *= VideoFormat->videoInfo.dwWidth;
- m_AspectRatio.cy *= VideoFormat->videoInfo.dwHeight;
+ m_AspectRatio.cx *= VideoFormat->videoInfo.dwWidth;
+ m_AspectRatio.cy *= VideoFormat->videoInfo.dwHeight;
- bool bDoneSomething = true;
+ bool bDoneSomething = true;
- if (m_AspectRatio.cx >= 1 && m_AspectRatio.cy >= 1) { //if any of these is 0, it will stuck into a infinite loop
- while (bDoneSomething) {
- bDoneSomething = false;
- INT MinNum = min(m_AspectRatio.cx, m_AspectRatio.cy);
- INT i;
- for (i = 2; i < MinNum+1; ++i) {
- if (m_AspectRatio.cx%i == 0 && m_AspectRatio.cy%i ==0) {
- break;
- }
- }
- if (i != MinNum + 1) {
- m_AspectRatio.cx = m_AspectRatio.cx / i;
- m_AspectRatio.cy = m_AspectRatio.cy / i;
- bDoneSomething = true;
- }
- }
- }
+ if (m_AspectRatio.cx >= 1 && m_AspectRatio.cy >= 1) { //if any of these is 0, it will stuck into a infinite loop
+ while (bDoneSomething) {
+ bDoneSomething = false;
+ INT MinNum = min(m_AspectRatio.cx, m_AspectRatio.cy);
+ INT i;
+ for (i = 2; i < MinNum + 1; ++i) {
+ if (m_AspectRatio.cx % i == 0 && m_AspectRatio.cy % i == 0) {
+ break;
+ }
+ }
+ if (i != MinNum + 1) {
+ m_AspectRatio.cx = m_AspectRatio.cx / i;
+ m_AspectRatio.cy = m_AspectRatio.cy / i;
+ bDoneSomething = true;
+ }
+ }
+ }
- pMixerType->FreeRepresentation (FORMAT_MFVideoFormat, (void*)pAMMedia);
- m_pMediaType->QueryInterface (__uuidof(IMFMediaType), (void**) pType);
+ pMixerType->FreeRepresentation(FORMAT_MFVideoFormat, (void*)pAMMedia);
+ m_pMediaType->QueryInterface(__uuidof(IMFMediaType), (void**) pType);
- return hr;
+ return hr;
}
HRESULT CEVRAllocatorPresenter::SetMediaType(IMFMediaType* pType)
{
- HRESULT hr;
- AM_MEDIA_TYPE* pAMMedia = NULL;
- CString strTemp, strTemp1;
+ HRESULT hr;
+ AM_MEDIA_TYPE* pAMMedia = NULL;
+ CString strTemp, strTemp1;
- CheckPointer (pType, E_POINTER);
- CheckHR (pType->GetRepresentation(FORMAT_VideoInfo2, (void**)&pAMMedia));
+ CheckPointer(pType, E_POINTER);
+ CheckHR(pType->GetRepresentation(FORMAT_VideoInfo2, (void**)&pAMMedia));
- hr = InitializeDevice (pType);
- if (SUCCEEDED(hr)) {
- strTemp = GetMediaTypeName (pAMMedia->subtype);
- strTemp.Replace (L"MEDIASUBTYPE_", L"");
- strTemp1 = GetMediaTypeFormatDesc(pType);
- strTemp1.Replace (L"D3DFMT_", L"");
- m_strStatsMsg[MSG_MIXEROUT].Format (L"Mixer output : %-10s Type %-10s", strTemp, strTemp1);
- }
+ hr = InitializeDevice(pType);
+ if (SUCCEEDED(hr)) {
+ strTemp = GetMediaTypeName(pAMMedia->subtype);
+ strTemp.Replace(L"MEDIASUBTYPE_", L"");
+ strTemp1 = GetMediaTypeFormatDesc(pType);
+ strTemp1.Replace(L"D3DFMT_", L"");
+ m_strStatsMsg[MSG_MIXEROUT].Format(L"Mixer output : %-10s Type %-10s", strTemp, strTemp1);
+ }
- pType->FreeRepresentation (FORMAT_VideoInfo2, (void*)pAMMedia);
+ pType->FreeRepresentation(FORMAT_VideoInfo2, (void*)pAMMedia);
- return hr;
+ return hr;
}
HRESULT CEVRAllocatorPresenter::GetMediaTypeFourCC(IMFMediaType* pType, DWORD* pFourCC)
{
- if (pFourCC == NULL) {
- return E_POINTER;
- }
+ if (pFourCC == NULL) {
+ return E_POINTER;
+ }
- HRESULT hr = S_OK;
- GUID guidSubType = GUID_NULL;
+ HRESULT hr = S_OK;
+ GUID guidSubType = GUID_NULL;
- if (SUCCEEDED(hr)) {
- hr = pType->GetGUID(MF_MT_SUBTYPE, &guidSubType);
- }
+ if (SUCCEEDED(hr)) {
+ hr = pType->GetGUID(MF_MT_SUBTYPE, &guidSubType);
+ }
- if (SUCCEEDED(hr)) {
- *pFourCC = guidSubType.Data1;
- }
+ if (SUCCEEDED(hr)) {
+ *pFourCC = guidSubType.Data1;
+ }
- return hr;
+ return hr;
}
HRESULT CEVRAllocatorPresenter::GetMediaTypeMerit(IMFMediaType* pType, int* pMerit)
{
- DWORD Format;
- HRESULT hr = GetMediaTypeFourCC(pType, &Format);
-
- if (SUCCEEDED(hr)) {
- switch (Format) {
- case FCC('AI44'):// Palettized, 4:4:4
- *pMerit = 31;
- break;
- case FCC('YVU9'):// 8-bit, 16:1:1
- *pMerit = 30;
- break;
- case FCC('NV11'):// 8-bit, 4:1:1
- *pMerit = 29;
- break;
- case FCC('Y41P'):
- *pMerit = 28;
- break;
- case FCC('Y41T'):
- *pMerit = 27;
- break;
- case FCC('P016'):// 4:2:0
- *pMerit = 26;
- break;
- case FCC('P010'):
- *pMerit = 25;
- break;
- case FCC('IMC1'):
- *pMerit = 24;
- break;
- case FCC('IMC3'):
- *pMerit = 23;
- break;
- case FCC('IMC2'):
- *pMerit = 22;
- break;
- case FCC('IMC4'):
- *pMerit = 21;
- break;
- case FCC('YV12'):
- *pMerit = 20;
- break;
- case FCC('NV12'):
- *pMerit = 19;
- break;
- case FCC('I420'):
- *pMerit = 18;
- break;
- case FCC('IYUV'):
- *pMerit = 17;
- break;
- case FCC('Y216'):// 4:2:2
- *pMerit = 16;
- break;
- case FCC('v216'):
- *pMerit = 15;
- break;
- case FCC('P216'):
- *pMerit = 14;
- break;
- case FCC('Y210'):
- *pMerit = 13;
- break;
- case FCC('v210'):
- *pMerit = 12;
- break;
- case FCC('P210'):
- *pMerit = 11;
- break;
- case FCC('YUY2'):
- *pMerit = 0;// bug: the internal software codecs will always select this, for safety this item is ranked below X8R8G8B8 until the problem is solved
- break;
- case FCC('UYVY'):
- *pMerit = 9;
- break;
- case FCC('Y42T'):
- *pMerit = 8;
- break;
- case FCC('YVYU'):
- *pMerit = 7;
- break;
- case FCC('Y416'):// 4:4:4
- *pMerit = 6;
- break;
- case FCC('Y410'):
- *pMerit = 5;
- break;
- case FCC('v410'):
- *pMerit = 4;
- break;
- case FCC('AYUV'):
- *pMerit = 3;
- break;
- case D3DFMT_X8R8G8B8:
- if (m_bForceInputHighColorResolution) {
- *pMerit = 63;
- } else {
- *pMerit = 1;
- }
- break;
- case D3DFMT_A8R8G8B8:// an accepted format, but fails on most surface types
- case D3DFMT_A8B8G8R8:
- case D3DFMT_X8B8G8R8:
- case D3DFMT_R8G8B8:
- case D3DFMT_R5G6B5:
- case D3DFMT_X1R5G5B5:
- case D3DFMT_A1R5G5B5:
- case D3DFMT_A4R4G4B4:
- case D3DFMT_R3G3B2:
- case D3DFMT_A8R3G3B2:
- case D3DFMT_X4R4G4B4:
- case D3DFMT_A8P8:
- case D3DFMT_P8:
- *pMerit = 0;
- break;
- default:
- *pMerit = 2;
- break;
- }
- }
-
- return hr;
+ DWORD Format;
+ HRESULT hr = GetMediaTypeFourCC(pType, &Format);
+
+ if (SUCCEEDED(hr)) {
+ switch (Format) {
+ case FCC('AI44'):// Palettized, 4:4:4
+ *pMerit = 31;
+ break;
+ case FCC('YVU9'):// 8-bit, 16:1:1
+ *pMerit = 30;
+ break;
+ case FCC('NV11'):// 8-bit, 4:1:1
+ *pMerit = 29;
+ break;
+ case FCC('Y41P'):
+ *pMerit = 28;
+ break;
+ case FCC('Y41T'):
+ *pMerit = 27;
+ break;
+ case FCC('P016'):// 4:2:0
+ *pMerit = 26;
+ break;
+ case FCC('P010'):
+ *pMerit = 25;
+ break;
+ case FCC('IMC1'):
+ *pMerit = 24;
+ break;
+ case FCC('IMC3'):
+ *pMerit = 23;
+ break;
+ case FCC('IMC2'):
+ *pMerit = 22;
+ break;
+ case FCC('IMC4'):
+ *pMerit = 21;
+ break;
+ case FCC('YV12'):
+ *pMerit = 20;
+ break;
+ case FCC('NV12'):
+ *pMerit = 19;
+ break;
+ case FCC('I420'):
+ *pMerit = 18;
+ break;
+ case FCC('IYUV'):
+ *pMerit = 17;
+ break;
+ case FCC('Y216'):// 4:2:2
+ *pMerit = 16;
+ break;
+ case FCC('v216'):
+ *pMerit = 15;
+ break;
+ case FCC('P216'):
+ *pMerit = 14;
+ break;
+ case FCC('Y210'):
+ *pMerit = 13;
+ break;
+ case FCC('v210'):
+ *pMerit = 12;
+ break;
+ case FCC('P210'):
+ *pMerit = 11;
+ break;
+ case FCC('YUY2'):
+ *pMerit = 0;// bug: the internal software codecs will always select this, for safety this item is ranked below X8R8G8B8 until the problem is solved
+ break;
+ case FCC('UYVY'):
+ *pMerit = 9;
+ break;
+ case FCC('Y42T'):
+ *pMerit = 8;
+ break;
+ case FCC('YVYU'):
+ *pMerit = 7;
+ break;
+ case FCC('Y416'):// 4:4:4
+ *pMerit = 6;
+ break;
+ case FCC('Y410'):
+ *pMerit = 5;
+ break;
+ case FCC('v410'):
+ *pMerit = 4;
+ break;
+ case FCC('AYUV'):
+ *pMerit = 3;
+ break;
+ case D3DFMT_X8R8G8B8:
+ if (m_bForceInputHighColorResolution) {
+ *pMerit = 63;
+ } else {
+ *pMerit = 1;
+ }
+ break;
+ case D3DFMT_A8R8G8B8:// an accepted format, but fails on most surface types
+ case D3DFMT_A8B8G8R8:
+ case D3DFMT_X8B8G8R8:
+ case D3DFMT_R8G8B8:
+ case D3DFMT_R5G6B5:
+ case D3DFMT_X1R5G5B5:
+ case D3DFMT_A1R5G5B5:
+ case D3DFMT_A4R4G4B4:
+ case D3DFMT_R3G3B2:
+ case D3DFMT_A8R3G3B2:
+ case D3DFMT_X4R4G4B4:
+ case D3DFMT_A8P8:
+ case D3DFMT_P8:
+ *pMerit = 0;
+ break;
+ default:
+ *pMerit = 2;
+ break;
+ }
+ }
+
+ return hr;
}
LPCTSTR FindD3DFormat(const D3DFORMAT Format);
LPCTSTR CEVRAllocatorPresenter::GetMediaTypeFormatDesc(IMFMediaType* pMediaType)
{
- D3DFORMAT Format = D3DFMT_UNKNOWN;
- GetMediaTypeFourCC(pMediaType, (DWORD*)&Format);
- return FindD3DFormat(Format);
+ D3DFORMAT Format = D3DFMT_UNKNOWN;
+ GetMediaTypeFourCC(pMediaType, (DWORD*)&Format);
+ return FindD3DFormat(Format);
}
HRESULT CEVRAllocatorPresenter::RenegotiateMediaType()
{
- HRESULT hr = S_OK;
-
- CComPtr<IMFMediaType> pMixerType;
- CComPtr<IMFMediaType> pType;
-
- if (!m_pMixer) {
- return MF_E_INVALIDREQUEST;
- }
-
- CInterfaceArray<IMFMediaType> ValidMixerTypes;
-
- // Loop through all of the mixer's proposed output types.
- DWORD iTypeIndex = 0;
- while ((hr != MF_E_NO_MORE_TYPES)) {
- pMixerType = NULL;
- pType = NULL;
- m_pMediaType = NULL;
-
- // Step 1. Get the next media type supported by mixer.
- hr = m_pMixer->GetOutputAvailableType(0, iTypeIndex++, &pMixerType);
- if (FAILED(hr)) {
- break;
- }
-
- // Step 2. Check if we support this media type.
- if (SUCCEEDED(hr)) {
- hr = IsMediaTypeSupported(pMixerType);
- }
-
- if (SUCCEEDED(hr)) {
- hr = CreateProposedOutputType(pMixerType, &pType);
- }
-
- // Step 4. Check if the mixer will accept this media type.
- if (SUCCEEDED(hr)) {
- hr = m_pMixer->SetOutputType(0, pType, MFT_SET_TYPE_TEST_ONLY);
- }
-
- int Merit;
- if (SUCCEEDED(hr)) {
- hr = GetMediaTypeMerit(pType, &Merit);
- }
-
- if (SUCCEEDED(hr)) {
- size_t nTypes = ValidMixerTypes.GetCount();
- size_t iInsertPos = 0;
- for (size_t i = 0; i < nTypes; ++i) {
- int ThisMerit;
- GetMediaTypeMerit(ValidMixerTypes[i], &ThisMerit);
-
- if (Merit > ThisMerit) {
- iInsertPos = i;
- break;
- } else {
- iInsertPos = i+1;
- }
- }
-
- ValidMixerTypes.InsertAt(iInsertPos, pType);
- }
- }
-
-
- size_t nValidTypes = ValidMixerTypes.GetCount();
+ HRESULT hr = S_OK;
+
+ CComPtr<IMFMediaType> pMixerType;
+ CComPtr<IMFMediaType> pType;
+
+ if (!m_pMixer) {
+ return MF_E_INVALIDREQUEST;
+ }
+
+ CInterfaceArray<IMFMediaType> ValidMixerTypes;
+
+ // Loop through all of the mixer's proposed output types.
+ DWORD iTypeIndex = 0;
+ while ((hr != MF_E_NO_MORE_TYPES)) {
+ pMixerType = NULL;
+ pType = NULL;
+ m_pMediaType = NULL;
+
+ // Step 1. Get the next media type supported by mixer.
+ hr = m_pMixer->GetOutputAvailableType(0, iTypeIndex++, &pMixerType);
+ if (FAILED(hr)) {
+ break;
+ }
+
+ // Step 2. Check if we support this media type.
+ if (SUCCEEDED(hr)) {
+ hr = IsMediaTypeSupported(pMixerType);
+ }
+
+ if (SUCCEEDED(hr)) {
+ hr = CreateProposedOutputType(pMixerType, &pType);
+ }
+
+ // Step 4. Check if the mixer will accept this media type.
+ if (SUCCEEDED(hr)) {
+ hr = m_pMixer->SetOutputType(0, pType, MFT_SET_TYPE_TEST_ONLY);
+ }
+
+ int Merit;
+ if (SUCCEEDED(hr)) {
+ hr = GetMediaTypeMerit(pType, &Merit);
+ }
+
+ if (SUCCEEDED(hr)) {
+ size_t nTypes = ValidMixerTypes.GetCount();
+ size_t iInsertPos = 0;
+ for (size_t i = 0; i < nTypes; ++i) {
+ int ThisMerit;
+ GetMediaTypeMerit(ValidMixerTypes[i], &ThisMerit);
+
+ if (Merit > ThisMerit) {
+ iInsertPos = i;
+ break;
+ } else {
+ iInsertPos = i + 1;
+ }
+ }
+
+ ValidMixerTypes.InsertAt(iInsertPos, pType);
+ }
+ }
+
+
+ size_t nValidTypes = ValidMixerTypes.GetCount();
#ifdef _DEBUG
- for (size_t i = 0; i < nValidTypes; ++i) {
- // Step 3. Adjust the mixer's type to match our requirements.
- pType = ValidMixerTypes[i];
- TRACE_EVR("EVR: Valid mixer output type: %ws\n", GetMediaTypeFormatDesc(pType));
- }
+ for (size_t i = 0; i < nValidTypes; ++i) {
+ // Step 3. Adjust the mixer's type to match our requirements.
+ pType = ValidMixerTypes[i];
+ TRACE_EVR("EVR: Valid mixer output type: %ws\n", GetMediaTypeFormatDesc(pType));
+ }
#endif
- for (size_t i = 0; i < nValidTypes; ++i) {
- // Step 3. Adjust the mixer's type to match our requirements.
- pType = ValidMixerTypes[i];
+ for (size_t i = 0; i < nValidTypes; ++i) {
+ // Step 3. Adjust the mixer's type to match our requirements.
+ pType = ValidMixerTypes[i];
- TRACE_EVR("EVR: Trying mixer output type: %ws\n", GetMediaTypeFormatDesc(pType));
+ TRACE_EVR("EVR: Trying mixer output type: %ws\n", GetMediaTypeFormatDesc(pType));
- // Step 5. Try to set the media type on ourselves.
- hr = SetMediaType(pType);
+ // Step 5. Try to set the media type on ourselves.
+ hr = SetMediaType(pType);
- // Step 6. Set output media type on mixer.
- if (SUCCEEDED(hr)) {
- hr = m_pMixer->SetOutputType(0, pType, 0);
+ // Step 6. Set output media type on mixer.
+ if (SUCCEEDED(hr)) {
+ hr = m_pMixer->SetOutputType(0, pType, 0);
- // If something went wrong, clear the media type.
- if (FAILED(hr)) {
- SetMediaType(NULL);
- } else {
- break;
- }
- }
- }
+ // If something went wrong, clear the media type.
+ if (FAILED(hr)) {
+ SetMediaType(NULL);
+ } else {
+ break;
+ }
+ }
+ }
- pMixerType = NULL;
- pType = NULL;
- return hr;
+ pMixerType = NULL;
+ pType = NULL;
+ return hr;
}
bool CEVRAllocatorPresenter::GetImageFromMixer()
{
- MFT_OUTPUT_DATA_BUFFER Buffer;
- HRESULT hr = S_OK;
- DWORD dwStatus;
- REFERENCE_TIME nsSampleTime;
- LONGLONG llClockBefore = 0;
- LONGLONG llClockAfter = 0;
- LONGLONG llMixerLatency;
- UINT dwSurface;
+ MFT_OUTPUT_DATA_BUFFER Buffer;
+ HRESULT hr = S_OK;
+ DWORD dwStatus;
+ REFERENCE_TIME nsSampleTime;
+ LONGLONG llClockBefore = 0;
+ LONGLONG llClockAfter = 0;
+ LONGLONG llMixerLatency;
+ UINT dwSurface;
- bool bDoneSomething = false;
+ bool bDoneSomething = false;
- while (SUCCEEDED(hr)) {
- CComPtr<IMFSample> pSample;
+ while (SUCCEEDED(hr)) {
+ CComPtr<IMFSample> pSample;
- if (FAILED (GetFreeSample (&pSample))) {
- m_bWaitingSample = true;
- break;
- }
+ if (FAILED(GetFreeSample(&pSample))) {
+ m_bWaitingSample = true;
+ break;
+ }
- memset (&Buffer, 0, sizeof(Buffer));
- Buffer.pSample = pSample;
- pSample->GetUINT32 (GUID_SURFACE_INDEX, &dwSurface);
+ memset(&Buffer, 0, sizeof(Buffer));
+ Buffer.pSample = pSample;
+ pSample->GetUINT32(GUID_SURFACE_INDEX, &dwSurface);
- {
- llClockBefore = GetRenderersData()->GetPerfCounter();
- hr = m_pMixer->ProcessOutput (0 , 1, &Buffer, &dwStatus);
- llClockAfter = GetRenderersData()->GetPerfCounter();
- }
+ {
+ llClockBefore = GetRenderersData()->GetPerfCounter();
+ hr = m_pMixer->ProcessOutput(0 , 1, &Buffer, &dwStatus);
+ llClockAfter = GetRenderersData()->GetPerfCounter();
+ }
- if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
- MoveToFreeList (pSample, false);
- break;
- }
+ if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
+ MoveToFreeList(pSample, false);
+ break;
+ }
- if (m_pSink) {
- //CAutoLock autolock(this); We shouldn't need to lock here, m_pSink is thread safe
- llMixerLatency = llClockAfter - llClockBefore;
- m_pSink->Notify (EC_PROCESSING_LATENCY, (LONG_PTR)&llMixerLatency, 0);
- }
+ if (m_pSink) {
+ //CAutoLock autolock(this); We shouldn't need to lock here, m_pSink is thread safe
+ llMixerLatency = llClockAfter - llClockBefore;
+ m_pSink->Notify(EC_PROCESSING_LATENCY, (LONG_PTR)&llMixerLatency, 0);
+ }
- pSample->GetSampleTime (&nsSampleTime);
- REFERENCE_TIME nsDuration;
- pSample->GetSampleDuration (&nsDuration);
+ pSample->GetSampleTime(&nsSampleTime);
+ REFERENCE_TIME nsDuration;
+ pSample->GetSampleDuration(&nsDuration);
- if (GetRenderersData()->m_fTearingTest) {
- RECT rcTearing;
+ if (GetRenderersData()->m_fTearingTest) {
+ RECT rcTearing;
- rcTearing.left = m_nTearingPos;
- rcTearing.top = 0;
- rcTearing.right = rcTearing.left + 4;
- rcTearing.bottom = m_NativeVideoSize.cy;
- m_pD3DDev->ColorFill (m_pVideoSurface[dwSurface], &rcTearing, D3DCOLOR_ARGB (255,255,0,0));
+ rcTearing.left = m_nTearingPos;
+ rcTearing.top = 0;
+ rcTearing.right = rcTearing.left + 4;
+ rcTearing.bottom = m_NativeVideoSize.cy;
+ m_pD3DDev->ColorFill(m_pVideoSurface[dwSurface], &rcTearing, D3DCOLOR_ARGB(255, 255, 0, 0));
- rcTearing.left = (rcTearing.right + 15) % m_NativeVideoSize.cx;
- rcTearing.right = rcTearing.left + 4;
- m_pD3DDev->ColorFill (m_pVideoSurface[dwSurface], &rcTearing, D3DCOLOR_ARGB (255,255,0,0));
- m_nTearingPos = (m_nTearingPos + 7) % m_NativeVideoSize.cx;
- }
+ rcTearing.left = (rcTearing.right + 15) % m_NativeVideoSize.cx;
+ rcTearing.right = rcTearing.left + 4;
+ m_pD3DDev->ColorFill(m_pVideoSurface[dwSurface], &rcTearing, D3DCOLOR_ARGB(255, 255, 0, 0));
+ m_nTearingPos = (m_nTearingPos + 7) % m_NativeVideoSize.cx;
+ }
- TRACE_EVR ("EVR: Get from Mixer : %d (%I64d) (%I64d)\n", dwSurface, nsSampleTime, m_rtTimePerFrame ? nsSampleTime/m_rtTimePerFrame : 0);
+ TRACE_EVR("EVR: Get from Mixer : %d (%I64d) (%I64d)\n", dwSurface, nsSampleTime, m_rtTimePerFrame ? nsSampleTime / m_rtTimePerFrame : 0);
- MoveToScheduledList (pSample, false);
- bDoneSomething = true;
- if (m_rtTimePerFrame == 0) {
- break;
- }
- }
+ MoveToScheduledList(pSample, false);
+ bDoneSomething = true;
+ if (m_rtTimePerFrame == 0) {
+ break;
+ }
+ }
- return bDoneSomething;
+ return bDoneSomething;
}
-STDMETHODIMP CEVRAllocatorPresenter::GetCurrentMediaType(__deref_out IMFVideoMediaType **ppMediaType)
+STDMETHODIMP CEVRAllocatorPresenter::GetCurrentMediaType(__deref_out IMFVideoMediaType** ppMediaType)
{
- HRESULT hr = S_OK;
- CAutoLock lock(this); // Hold the critical section.
+ HRESULT hr = S_OK;
+ CAutoLock lock(this); // Hold the critical section.
- CheckPointer (ppMediaType, E_POINTER);
- CheckHR (CheckShutdown());
+ CheckPointer(ppMediaType, E_POINTER);
+ CheckHR(CheckShutdown());
- if (m_pMediaType == NULL) {
- CheckHR(MF_E_NOT_INITIALIZED);
- }
+ if (m_pMediaType == NULL) {
+ CheckHR(MF_E_NOT_INITIALIZED);
+ }
- CheckHR(m_pMediaType->QueryInterface( __uuidof(IMFVideoMediaType), (void**)&ppMediaType));
+ CheckHR(m_pMediaType->QueryInterface(__uuidof(IMFVideoMediaType), (void**)&ppMediaType));
- return hr;
+ return hr;
}
// IMFTopologyServiceLookupClient
-STDMETHODIMP CEVRAllocatorPresenter::InitServicePointers(/* [in] */ __in IMFTopologyServiceLookup *pLookup)
+STDMETHODIMP CEVRAllocatorPresenter::InitServicePointers(/* [in] */ __in IMFTopologyServiceLookup* pLookup)
{
- HRESULT hr;
- DWORD dwObjects = 1;
+ HRESULT hr;
+ DWORD dwObjects = 1;
- TRACE_EVR ("EVR: CEVRAllocatorPresenter::InitServicePointers\n");
- hr = pLookup->LookupService (MF_SERVICE_LOOKUP_GLOBAL, 0, MR_VIDEO_MIXER_SERVICE,
- __uuidof (IMFTransform), (void**)&m_pMixer, &dwObjects);
+ TRACE_EVR("EVR: CEVRAllocatorPresenter::InitServicePointers\n");
+ hr = pLookup->LookupService(MF_SERVICE_LOOKUP_GLOBAL, 0, MR_VIDEO_MIXER_SERVICE,
+ __uuidof(IMFTransform), (void**)&m_pMixer, &dwObjects);
- hr = pLookup->LookupService (MF_SERVICE_LOOKUP_GLOBAL, 0, MR_VIDEO_RENDER_SERVICE,
- __uuidof (IMediaEventSink ), (void**)&m_pSink, &dwObjects);
+ hr = pLookup->LookupService(MF_SERVICE_LOOKUP_GLOBAL, 0, MR_VIDEO_RENDER_SERVICE,
+ __uuidof(IMediaEventSink), (void**)&m_pSink, &dwObjects);
- hr = pLookup->LookupService (MF_SERVICE_LOOKUP_GLOBAL, 0, MR_VIDEO_RENDER_SERVICE,
- __uuidof (IMFClock ), (void**)&m_pClock, &dwObjects);
+ hr = pLookup->LookupService(MF_SERVICE_LOOKUP_GLOBAL, 0, MR_VIDEO_RENDER_SERVICE,
+ __uuidof(IMFClock), (void**)&m_pClock, &dwObjects);
- StartWorkerThreads();
- return S_OK;
+ StartWorkerThreads();
+ return S_OK;
}
STDMETHODIMP CEVRAllocatorPresenter::ReleaseServicePointers()
{
- TRACE_EVR ("EVR: CEVRAllocatorPresenter::ReleaseServicePointers\n");
- StopWorkerThreads();
- m_pMixer = NULL;
- m_pSink = NULL;
- m_pClock = NULL;
- return S_OK;
+ TRACE_EVR("EVR: CEVRAllocatorPresenter::ReleaseServicePointers\n");
+ StopWorkerThreads();
+ m_pMixer = NULL;
+ m_pSink = NULL;
+ m_pClock = NULL;
+ return S_OK;
}
// IMFVideoDeviceID
-STDMETHODIMP CEVRAllocatorPresenter::GetDeviceID(/* [out] */ __out IID *pDeviceID)
+STDMETHODIMP CEVRAllocatorPresenter::GetDeviceID(/* [out] */ __out IID* pDeviceID)
{
- CheckPointer(pDeviceID, E_POINTER);
- *pDeviceID = IID_IDirect3DDevice9;
- return S_OK;
+ CheckPointer(pDeviceID, E_POINTER);
+ *pDeviceID = IID_IDirect3DDevice9;
+ return S_OK;
}
// IMFGetService
-STDMETHODIMP CEVRAllocatorPresenter::GetService (/* [in] */ __RPC__in REFGUID guidService,
- /* [in] */ __RPC__in REFIID riid,
- /* [iid_is][out] */ __RPC__deref_out_opt LPVOID *ppvObject)
+STDMETHODIMP CEVRAllocatorPresenter::GetService(/* [in] */ __RPC__in REFGUID guidService,
+ /* [in] */ __RPC__in REFIID riid,
+ /* [iid_is][out] */ __RPC__deref_out_opt LPVOID* ppvObject)
{
- if (guidService == MR_VIDEO_RENDER_SERVICE) {
- return NonDelegatingQueryInterface (riid, ppvObject);
- } else if (guidService == MR_VIDEO_ACCELERATION_SERVICE) {
- return m_pD3DManager->QueryInterface (__uuidof(IDirect3DDeviceManager9), (void**) ppvObject);
- }
+ if (guidService == MR_VIDEO_RENDER_SERVICE) {
+ return NonDelegatingQueryInterface(riid, ppvObject);
+ } else if (guidService == MR_VIDEO_ACCELERATION_SERVICE) {
+ return m_pD3DManager->QueryInterface(__uuidof(IDirect3DDeviceManager9), (void**) ppvObject);
+ }
- return E_NOINTERFACE;
+ return E_NOINTERFACE;
}
// IMFAsyncCallback
-STDMETHODIMP CEVRAllocatorPresenter::GetParameters( /* [out] */ __RPC__out DWORD *pdwFlags, /* [out] */ __RPC__out DWORD *pdwQueue)
+STDMETHODIMP CEVRAllocatorPresenter::GetParameters(/* [out] */ __RPC__out DWORD* pdwFlags, /* [out] */ __RPC__out DWORD* pdwQueue)
{
- return E_NOTIMPL;
+ return E_NOTIMPL;
}
-STDMETHODIMP CEVRAllocatorPresenter::Invoke ( /* [in] */ __RPC__in_opt IMFAsyncResult *pAsyncResult)
+STDMETHODIMP CEVRAllocatorPresenter::Invoke(/* [in] */ __RPC__in_opt IMFAsyncResult* pAsyncResult)
{
- return E_NOTIMPL;
+ return E_NOTIMPL;
}
// IMFVideoDisplayControl
-STDMETHODIMP CEVRAllocatorPresenter::GetNativeVideoSize(SIZE *pszVideo, SIZE *pszARVideo)
+STDMETHODIMP CEVRAllocatorPresenter::GetNativeVideoSize(SIZE* pszVideo, SIZE* pszARVideo)
{
- if (pszVideo) {
- pszVideo->cx = m_NativeVideoSize.cx;
- pszVideo->cy = m_NativeVideoSize.cy;
- }
- if (pszARVideo) {
- pszARVideo->cx = m_NativeVideoSize.cx * m_AspectRatio.cx;
- pszARVideo->cy = m_NativeVideoSize.cy * m_AspectRatio.cy;
- }
- return S_OK;
+ if (pszVideo) {
+ pszVideo->cx = m_NativeVideoSize.cx;
+ pszVideo->cy = m_NativeVideoSize.cy;
+ }
+ if (pszARVideo) {
+ pszARVideo->cx = m_NativeVideoSize.cx * m_AspectRatio.cx;
+ pszARVideo->cy = m_NativeVideoSize.cy * m_AspectRatio.cy;
+ }
+ return S_OK;
}
-STDMETHODIMP CEVRAllocatorPresenter::GetIdealVideoSize(SIZE *pszMin, SIZE *pszMax)
+STDMETHODIMP CEVRAllocatorPresenter::GetIdealVideoSize(SIZE* pszMin, SIZE* pszMax)
{
- if (pszMin) {
- pszMin->cx = 1;
- pszMin->cy = 1;
- }
+ if (pszMin) {
+ pszMin->cx = 1;
+ pszMin->cy = 1;
+ }
- if (pszMax) {
- D3DDISPLAYMODE d3ddm;
+ if (pszMax) {
+ D3DDISPLAYMODE d3ddm;
- ZeroMemory(&d3ddm, sizeof(d3ddm));
- if (SUCCEEDED(m_pD3D->GetAdapterDisplayMode(GetAdapter(m_pD3D), &d3ddm))) {
- pszMax->cx = d3ddm.Width;
- pszMax->cy = d3ddm.Height;
- }
- }
+ ZeroMemory(&d3ddm, sizeof(d3ddm));
+ if (SUCCEEDED(m_pD3D->GetAdapterDisplayMode(GetAdapter(m_pD3D), &d3ddm))) {
+ pszMax->cx = d3ddm.Width;
+ pszMax->cy = d3ddm.Height;
+ }
+ }
- return S_OK;
+ return S_OK;
}
-STDMETHODIMP CEVRAllocatorPresenter::SetVideoPosition(const MFVideoNormalizedRect *pnrcSource, const LPRECT prcDest)
+STDMETHODIMP CEVRAllocatorPresenter::SetVideoPosition(const MFVideoNormalizedRect* pnrcSource, const LPRECT prcDest)
{
- return S_OK;
+ return S_OK;
}
-STDMETHODIMP CEVRAllocatorPresenter::GetVideoPosition(MFVideoNormalizedRect *pnrcSource, LPRECT prcDest)
+STDMETHODIMP CEVRAllocatorPresenter::GetVideoPosition(MFVideoNormalizedRect* pnrcSource, LPRECT prcDest)
{
- // Always all source rectangle ?
- if (pnrcSource) {
- pnrcSource->left = 0.0;
- pnrcSource->top = 0.0;
- pnrcSource->right = 1.0;
- pnrcSource->bottom = 1.0;
- }
+ // Always all source rectangle ?
+ if (pnrcSource) {
+ pnrcSource->left = 0.0;
+ pnrcSource->top = 0.0;
+ pnrcSource->right = 1.0;
+ pnrcSource->bottom = 1.0;
+ }
- if (prcDest) {
- memcpy (prcDest, &m_VideoRect, sizeof(m_VideoRect)); //GetClientRect (m_hWnd, prcDest);
- }
+ if (prcDest) {
+ memcpy(prcDest, &m_VideoRect, sizeof(m_VideoRect)); //GetClientRect (m_hWnd, prcDest);
+ }
- return S_OK;
+ return S_OK;
}
STDMETHODIMP CEVRAllocatorPresenter::SetAspectRatioMode(DWORD dwAspectRatioMode)
{
- m_dwVideoAspectRatioMode = (MFVideoAspectRatioMode)dwAspectRatioMode;
- return S_OK;
+ m_dwVideoAspectRatioMode = (MFVideoAspectRatioMode)dwAspectRatioMode;
+ return S_OK;
}
-STDMETHODIMP CEVRAllocatorPresenter::GetAspectRatioMode(DWORD *pdwAspectRatioMode)
+STDMETHODIMP CEVRAllocatorPresenter::GetAspectRatioMode(DWORD* pdwAspectRatioMode)
{
- CheckPointer (pdwAspectRatioMode, E_POINTER);
- *pdwAspectRatioMode = m_dwVideoAspectRatioMode;
- return S_OK;
+ CheckPointer(pdwAspectRatioMode, E_POINTER);
+ *pdwAspectRatioMode = m_dwVideoAspectRatioMode;
+ return S_OK;
}
STDMETHODIMP CEVRAllocatorPresenter::SetVideoWindow(HWND hwndVideo)
{
- ASSERT (m_hWnd == hwndVideo); // What if not ??
- // m_hWnd = hwndVideo;
- return S_OK;
+ ASSERT(m_hWnd == hwndVideo); // What if not ??
+ // m_hWnd = hwndVideo;
+ return S_OK;
}
-STDMETHODIMP CEVRAllocatorPresenter::GetVideoWindow(HWND *phwndVideo)
+STDMETHODIMP CEVRAllocatorPresenter::GetVideoWindow(HWND* phwndVideo)
{
- CheckPointer (phwndVideo, E_POINTER);
- *phwndVideo = m_hWnd;
- return S_OK;
+ CheckPointer(phwndVideo, E_POINTER);
+ *phwndVideo = m_hWnd;
+ return S_OK;
}
STDMETHODIMP CEVRAllocatorPresenter::RepaintVideo()
{
- Paint (true);
- return S_OK;
+ Paint(true);
+ return S_OK;
}
-STDMETHODIMP CEVRAllocatorPresenter::GetCurrentImage(BITMAPINFOHEADER *pBih, BYTE **pDib, DWORD *pcbDib, LONGLONG *pTimeStamp)
+STDMETHODIMP CEVRAllocatorPresenter::GetCurrentImage(BITMAPINFOHEADER* pBih, BYTE** pDib, DWORD* pcbDib, LONGLONG* pTimeStamp)
{
- ASSERT (FALSE);
- return E_NOTIMPL;
+ ASSERT(FALSE);
+ return E_NOTIMPL;
}
STDMETHODIMP CEVRAllocatorPresenter::SetBorderColor(COLORREF Clr)
{
- m_BorderColor = Clr;
- return S_OK;
+ m_BorderColor = Clr;
+ return S_OK;
}
-STDMETHODIMP CEVRAllocatorPresenter::GetBorderColor(COLORREF *pClr)
+STDMETHODIMP CEVRAllocatorPresenter::GetBorderColor(COLORREF* pClr)
{
- CheckPointer (pClr, E_POINTER);
- *pClr = m_BorderColor;
- return S_OK;
+ CheckPointer(pClr, E_POINTER);
+ *pClr = m_BorderColor;
+ return S_OK;
}
STDMETHODIMP CEVRAllocatorPresenter::SetRenderingPrefs(DWORD dwRenderFlags)
{
- m_dwVideoRenderPrefs = (MFVideoRenderPrefs)dwRenderFlags;
- return S_OK;
+ m_dwVideoRenderPrefs = (MFVideoRenderPrefs)dwRenderFlags;
+ return S_OK;
}
-STDMETHODIMP CEVRAllocatorPresenter::GetRenderingPrefs(DWORD *pdwRenderFlags)
+STDMETHODIMP CEVRAllocatorPresenter::GetRenderingPrefs(DWORD* pdwRenderFlags)
{
- CheckPointer(pdwRenderFlags, E_POINTER);
- *pdwRenderFlags = m_dwVideoRenderPrefs;
- return S_OK;
+ CheckPointer(pdwRenderFlags, E_POINTER);
+ *pdwRenderFlags = m_dwVideoRenderPrefs;
+ return S_OK;
}
STDMETHODIMP CEVRAllocatorPresenter::SetFullscreen(BOOL fFullscreen)
{
- ASSERT (FALSE);
- return E_NOTIMPL;
+ ASSERT(FALSE);
+ return E_NOTIMPL;
}
-STDMETHODIMP CEVRAllocatorPresenter::GetFullscreen(BOOL *pfFullscreen)
+STDMETHODIMP CEVRAllocatorPresenter::GetFullscreen(BOOL* pfFullscreen)
{
- ASSERT (FALSE);
- return E_NOTIMPL;
+ ASSERT(FALSE);
+ return E_NOTIMPL;
}
// IEVRTrustedVideoPlugin
-STDMETHODIMP CEVRAllocatorPresenter::IsInTrustedVideoMode(BOOL *pYes)
+STDMETHODIMP CEVRAllocatorPresenter::IsInTrustedVideoMode(BOOL* pYes)
{
- CheckPointer(pYes, E_POINTER);
- *pYes = TRUE;
- return S_OK;
+ CheckPointer(pYes, E_POINTER);
+ *pYes = TRUE;
+ return S_OK;
}
-STDMETHODIMP CEVRAllocatorPresenter::CanConstrict(BOOL *pYes)
+STDMETHODIMP CEVRAllocatorPresenter::CanConstrict(BOOL* pYes)
{
- CheckPointer(pYes, E_POINTER);
- *pYes = TRUE;
- return S_OK;
+ CheckPointer(pYes, E_POINTER);
+ *pYes = TRUE;
+ return S_OK;
}
STDMETHODIMP CEVRAllocatorPresenter::SetConstriction(DWORD dwKPix)
{
- return S_OK;
+ return S_OK;
}
STDMETHODIMP CEVRAllocatorPresenter::DisableImageExport(BOOL bDisable)
{
- return S_OK;
+ return S_OK;
}
// IDirect3DDeviceManager9
-STDMETHODIMP CEVRAllocatorPresenter::ResetDevice(IDirect3DDevice9 *pDevice,UINT resetToken)
+STDMETHODIMP CEVRAllocatorPresenter::ResetDevice(IDirect3DDevice9* pDevice, UINT resetToken)
{
- HRESULT hr = m_pD3DManager->ResetDevice (pDevice, resetToken);
- return hr;
+ HRESULT hr = m_pD3DManager->ResetDevice(pDevice, resetToken);
+ return hr;
}
-STDMETHODIMP CEVRAllocatorPresenter::OpenDeviceHandle(HANDLE *phDevice)
+STDMETHODIMP CEVRAllocatorPresenter::OpenDeviceHandle(HANDLE* phDevice)
{
- HRESULT hr = m_pD3DManager->OpenDeviceHandle (phDevice);
- return hr;
+ HRESULT hr = m_pD3DManager->OpenDeviceHandle(phDevice);
+ return hr;
}
STDMETHODIMP CEVRAllocatorPresenter::CloseDeviceHandle(HANDLE hDevice)
{
- HRESULT hr = m_pD3DManager->CloseDeviceHandle(hDevice);
- return hr;
+ HRESULT hr = m_pD3DManager->CloseDeviceHandle(hDevice);
+ return hr;
}
STDMETHODIMP CEVRAllocatorPresenter::TestDevice(HANDLE hDevice)
{
- HRESULT hr = m_pD3DManager->TestDevice(hDevice);
- return hr;
+ HRESULT hr = m_pD3DManager->TestDevice(hDevice);
+ return hr;
}
-STDMETHODIMP CEVRAllocatorPresenter::LockDevice(HANDLE hDevice, IDirect3DDevice9 **ppDevice, BOOL fBlock)
+STDMETHODIMP CEVRAllocatorPresenter::LockDevice(HANDLE hDevice, IDirect3DDevice9** ppDevice, BOOL fBlock)
{
- HRESULT hr = m_pD3DManager->LockDevice(hDevice, ppDevice, fBlock);
- return hr;
+ HRESULT hr = m_pD3DManager->LockDevice(hDevice, ppDevice, fBlock);
+ return hr;
}
STDMETHODIMP CEVRAllocatorPresenter::UnlockDevice(HANDLE hDevice, BOOL fSaveState)
{
- HRESULT hr = m_pD3DManager->UnlockDevice(hDevice, fSaveState);
- return hr;
+ HRESULT hr = m_pD3DManager->UnlockDevice(hDevice, fSaveState);
+ return hr;
}
-STDMETHODIMP CEVRAllocatorPresenter::GetVideoService(HANDLE hDevice, REFIID riid, void **ppService)
+STDMETHODIMP CEVRAllocatorPresenter::GetVideoService(HANDLE hDevice, REFIID riid, void** ppService)
{
- HRESULT hr = m_pD3DManager->GetVideoService(hDevice, riid, ppService);
+ HRESULT hr = m_pD3DManager->GetVideoService(hDevice, riid, ppService);
- if (riid == __uuidof(IDirectXVideoDecoderService)) {
- UINT nNbDecoder = 5;
- GUID* pDecoderGuid;
- IDirectXVideoDecoderService* pDXVAVideoDecoder = (IDirectXVideoDecoderService*) *ppService;
- pDXVAVideoDecoder->GetDecoderDeviceGuids (&nNbDecoder, &pDecoderGuid);
- } else if (riid == __uuidof(IDirectXVideoProcessorService)) {
- IDirectXVideoProcessorService* pDXVAProcessor = (IDirectXVideoProcessorService*) *ppService;
- UNREFERENCED_PARAMETER(pDXVAProcessor);
- }
+ if (riid == __uuidof(IDirectXVideoDecoderService)) {
+ UINT nNbDecoder = 5;
+ GUID* pDecoderGuid;
+ IDirectXVideoDecoderService* pDXVAVideoDecoder = (IDirectXVideoDecoderService*) *ppService;
+ pDXVAVideoDecoder->GetDecoderDeviceGuids(&nNbDecoder, &pDecoderGuid);
+ } else if (riid == __uuidof(IDirectXVideoProcessorService)) {
+ IDirectXVideoProcessorService* pDXVAProcessor = (IDirectXVideoProcessorService*) *ppService;
+ UNREFERENCED_PARAMETER(pDXVAProcessor);
+ }
- return hr;
+ return hr;
}
STDMETHODIMP CEVRAllocatorPresenter::GetNativeVideoSize(LONG* lpWidth, LONG* lpHeight, LONG* lpARWidth, LONG* lpARHeight)
{
- // This function should be called...
- ASSERT (FALSE);
+ // This function should be called...
+ ASSERT(FALSE);
- if (lpWidth) {
- *lpWidth = m_NativeVideoSize.cx;
- }
- if (lpHeight) {
- *lpHeight = m_NativeVideoSize.cy;
- }
- if (lpARWidth) {
- *lpARWidth = m_AspectRatio.cx;
- }
- if (lpARHeight) {
- *lpARHeight = m_AspectRatio.cy;
- }
- return S_OK;
+ if (lpWidth) {
+ *lpWidth = m_NativeVideoSize.cx;
+ }
+ if (lpHeight) {
+ *lpHeight = m_NativeVideoSize.cy;
+ }
+ if (lpARWidth) {
+ *lpARWidth = m_AspectRatio.cx;
+ }
+ if (lpARHeight) {
+ *lpARHeight = m_AspectRatio.cy;
+ }
+ return S_OK;
}
STDMETHODIMP CEVRAllocatorPresenter::InitializeDevice(IMFMediaType* pMediaType)
{
- HRESULT hr;
- CAutoLock lock(this);
- CAutoLock lock2(&m_ImageProcessingLock);
- CAutoLock cRenderLock(&m_RenderLock);
+ HRESULT hr;
+ CAutoLock lock(this);
+ CAutoLock lock2(&m_ImageProcessingLock);
+ CAutoLock cRenderLock(&m_RenderLock);
- RemoveAllSamples();
- DeleteSurfaces();
+ RemoveAllSamples();
+ DeleteSurfaces();
- // Retrieve the surface size and format
- UINT32 Width;
- UINT32 Height;
- hr = MFGetAttributeSize(pMediaType, MF_MT_FRAME_SIZE, &Width, &Height);
+ // Retrieve the surface size and format
+ UINT32 Width;
+ UINT32 Height;
+ hr = MFGetAttributeSize(pMediaType, MF_MT_FRAME_SIZE, &Width, &Height);
- D3DFORMAT Format;
- if (SUCCEEDED(hr)) {
- m_NativeVideoSize = CSize(Width, Height);
- hr = GetMediaTypeFourCC(pMediaType, (DWORD*)&Format);
- }
+ D3DFORMAT Format;
+ if (SUCCEEDED(hr)) {
+ m_NativeVideoSize = CSize(Width, Height);
+ hr = GetMediaTypeFourCC(pMediaType, (DWORD*)&Format);
+ }
- if (SUCCEEDED(hr)) {
- hr = AllocSurfaces();
- }
+ if (SUCCEEDED(hr)) {
+ hr = AllocSurfaces();
+ }
- if (SUCCEEDED(hr)) {
- for (int i = 0; i < m_nNbDXSurface; i++) {
- CComPtr<IMFSample> pMFSample;
- hr = pfMFCreateVideoSampleFromSurface (m_pVideoSurface[i], &pMFSample);
+ if (SUCCEEDED(hr)) {
+ for (int i = 0; i < m_nNbDXSurface; i++) {
+ CComPtr<IMFSample> pMFSample;
+ hr = pfMFCreateVideoSampleFromSurface(m_pVideoSurface[i], &pMFSample);
- if (SUCCEEDED (hr)) {
- pMFSample->SetUINT32 (GUID_SURFACE_INDEX, i);
- m_FreeSamples.AddTail (pMFSample);
- }
- ASSERT (SUCCEEDED (hr));
- }
- }
+ if (SUCCEEDED(hr)) {
+ pMFSample->SetUINT32(GUID_SURFACE_INDEX, i);
+ m_FreeSamples.AddTail(pMFSample);
+ }
+ ASSERT(SUCCEEDED(hr));
+ }
+ }
- return hr;
+ return hr;
}
DWORD WINAPI CEVRAllocatorPresenter::GetMixerThreadStatic(LPVOID lpParam)
{
- SetThreadName((DWORD)-1, "CEVRPresenter::MixerThread");
- CEVRAllocatorPresenter* pThis = (CEVRAllocatorPresenter*) lpParam;
- pThis->GetMixerThread();
- return 0;
+ SetThreadName((DWORD) - 1, "CEVRPresenter::MixerThread");
+ CEVRAllocatorPresenter* pThis = (CEVRAllocatorPresenter*) lpParam;
+ pThis->GetMixerThread();
+ return 0;
}
DWORD WINAPI CEVRAllocatorPresenter::PresentThread(LPVOID lpParam)
{
- SetThreadName((DWORD)-1, "CEVRPresenter::PresentThread");
- CEVRAllocatorPresenter* pThis = (CEVRAllocatorPresenter*) lpParam;
- pThis->RenderThread();
- return 0;
+ SetThreadName((DWORD) - 1, "CEVRPresenter::PresentThread");
+ CEVRAllocatorPresenter* pThis = (CEVRAllocatorPresenter*) lpParam;
+ pThis->RenderThread();
+ return 0;
}
void CEVRAllocatorPresenter::CheckWaitingSampleFromMixer()
{
- if (m_bWaitingSample) {
- m_bWaitingSample = false;
- //GetImageFromMixer(); // Do this in processing thread instead
- }
+ if (m_bWaitingSample) {
+ m_bWaitingSample = false;
+ //GetImageFromMixer(); // Do this in processing thread instead
+ }
}
bool ExtractInterlaced(const AM_MEDIA_TYPE* pmt)
{
- if (pmt->formattype==FORMAT_VideoInfo) {
- return false;
- } else if (pmt->formattype==FORMAT_VideoInfo2) {
- return (((VIDEOINFOHEADER2*)pmt->pbFormat)->dwInterlaceFlags & AMINTERLACE_IsInterlaced) != 0;
- } else if (pmt->formattype==FORMAT_MPEGVideo) {
- return false;
- } else if (pmt->formattype==FORMAT_MPEG2Video) {
- return (((MPEG2VIDEOINFO*)pmt->pbFormat)->hdr.dwInterlaceFlags & AMINTERLACE_IsInterlaced) != 0;
- } else {
- return false;
- }
+ if (pmt->formattype == FORMAT_VideoInfo) {
+ return false;
+ } else if (pmt->formattype == FORMAT_VideoInfo2) {
+ return (((VIDEOINFOHEADER2*)pmt->pbFormat)->dwInterlaceFlags & AMINTERLACE_IsInterlaced) != 0;
+ } else if (pmt->formattype == FORMAT_MPEGVideo) {
+ return false;
+ } else if (pmt->formattype == FORMAT_MPEG2Video) {
+ return (((MPEG2VIDEOINFO*)pmt->pbFormat)->hdr.dwInterlaceFlags & AMINTERLACE_IsInterlaced) != 0;
+ } else {
+ return false;
+ }
}
void CEVRAllocatorPresenter::GetMixerThread()
{
- //HANDLE hAvrt;
- HANDLE hEvts[] = { m_hEvtQuit};
- bool bQuit = false;
- TIMECAPS tc;
- DWORD dwResolution;
- DWORD dwUser = 0;
- //DWORD dwTaskIndex = 0;
-
- // Tell Vista Multimedia Class Scheduler we are a playback thretad (increase priority)
- // if (pfAvSetMmThreadCharacteristicsW)
- // hAvrt = pfAvSetMmThreadCharacteristicsW (L"Playback", &dwTaskIndex);
- // if (pfAvSetMmThreadPriority)
- // pfAvSetMmThreadPriority (hAvrt, AVRT_PRIORITY_HIGH /*AVRT_PRIORITY_CRITICAL*/);
-
- timeGetDevCaps(&tc, sizeof(TIMECAPS));
- dwResolution = min(max(tc.wPeriodMin, 0), tc.wPeriodMax);
- dwUser = timeBeginPeriod(dwResolution);
-
- while (!bQuit) {
- DWORD dwObject = WaitForMultipleObjects (_countof(hEvts), hEvts, FALSE, 1);
- switch (dwObject) {
- case WAIT_OBJECT_0 :
- bQuit = true;
- break;
- case WAIT_TIMEOUT : {
- if (GetRenderersData()->m_fDisplayStats) {
- CComPtr<IPin> pPin;
- CComPtr<IPin> pPinTo;
- if (SUCCEEDED (m_pOuterEVR->FindPin(L"EVR Input0", &pPin)) &&
- SUCCEEDED(pPin->ConnectedTo(&pPinTo)) && pPinTo) {
- if (CComPtr<IBaseFilter> pFilter = GetFilterFromPin(pPinTo) ) {
- if (CComQIPtr<IMPCVideoDecFilter2> MPCVideoDecFilter = pFilter ) {
- m_nFrameType = (FF_FIELD_TYPE)MPCVideoDecFilter->GetFrameType();
- }
- }
- }
- }
-
- bool bDoneSomething = false;
- {
- CAutoLock AutoLock(&m_ImageProcessingLock);
- bDoneSomething = GetImageFromMixer();
- }
- if (m_rtTimePerFrame == 0 && bDoneSomething) {
- //CAutoLock lock(this);
- //CAutoLock lock2(&m_ImageProcessingLock);
- //CAutoLock cRenderLock(&m_RenderLock);
-
- // Use the code from VMR9 to get the movie fps, as this method is reliable.
- CComPtr<IPin> pPin;
- CMediaType mt;
- if (
- SUCCEEDED (m_pOuterEVR->FindPin(L"EVR Input0", &pPin)) &&
- SUCCEEDED (pPin->ConnectionMediaType(&mt)) ) {
-
- ExtractAvgTimePerFrame (&mt, m_rtTimePerFrame);
-
- m_bInterlaced = ExtractInterlaced(&mt);
-
- CComPtr<IPin> pPinTo;
- if (SUCCEEDED(pPin->ConnectedTo(&pPinTo)) && pPinTo) {
- m_Decoder = GetFilterName(GetFilterFromPin(pPinTo));
- }
- }
- // If framerate not set by Video Decoder choose 23.97...
- if (m_rtTimePerFrame == 0) {
- m_rtTimePerFrame = 417166;
- }
-
- // Update internal subtitle clock
- if (m_fUseInternalTimer && m_pSubPicQueue) {
- m_fps = (float)(10000000.0 / m_rtTimePerFrame);
- m_pSubPicQueue->SetFPS(m_fps);
- }
-
- }
-
- }
- break;
- }
- }
-
- timeEndPeriod (dwResolution);
- // if (pfAvRevertMmThreadCharacteristics) pfAvRevertMmThreadCharacteristics (hAvrt);
+ //HANDLE hAvrt;
+ HANDLE hEvts[] = { m_hEvtQuit};
+ bool bQuit = false;
+ TIMECAPS tc;
+ DWORD dwResolution;
+ DWORD dwUser = 0;
+ //DWORD dwTaskIndex = 0;
+
+ // Tell Vista Multimedia Class Scheduler we are a playback thretad (increase priority)
+ // if (pfAvSetMmThreadCharacteristicsW)
+ // hAvrt = pfAvSetMmThreadCharacteristicsW (L"Playback", &dwTaskIndex);
+ // if (pfAvSetMmThreadPriority)
+ // pfAvSetMmThreadPriority (hAvrt, AVRT_PRIORITY_HIGH /*AVRT_PRIORITY_CRITICAL*/);
+
+ timeGetDevCaps(&tc, sizeof(TIMECAPS));
+ dwResolution = min(max(tc.wPeriodMin, 0), tc.wPeriodMax);
+ dwUser = timeBeginPeriod(dwResolution);
+
+ while (!bQuit) {
+ DWORD dwObject = WaitForMultipleObjects(_countof(hEvts), hEvts, FALSE, 1);
+ switch (dwObject) {
+ case WAIT_OBJECT_0 :
+ bQuit = true;
+ break;
+ case WAIT_TIMEOUT : {
+ if (GetRenderersData()->m_fDisplayStats) {
+ CComPtr<IPin> pPin;
+ CComPtr<IPin> pPinTo;
+ if (SUCCEEDED(m_pOuterEVR->FindPin(L"EVR Input0", &pPin)) &&
+ SUCCEEDED(pPin->ConnectedTo(&pPinTo)) && pPinTo) {
+ if (CComPtr<IBaseFilter> pFilter = GetFilterFromPin(pPinTo)) {
+ if (CComQIPtr<IMPCVideoDecFilter2> MPCVideoDecFilter = pFilter) {
+ m_nFrameType = (FF_FIELD_TYPE)MPCVideoDecFilter->GetFrameType();
+ }
+ }
+ }
+ }
+
+ bool bDoneSomething = false;
+ {
+ CAutoLock AutoLock(&m_ImageProcessingLock);
+ bDoneSomething = GetImageFromMixer();
+ }
+ if (m_rtTimePerFrame == 0 && bDoneSomething) {
+ //CAutoLock lock(this);
+ //CAutoLock lock2(&m_ImageProcessingLock);
+ //CAutoLock cRenderLock(&m_RenderLock);
+
+ // Use the code from VMR9 to get the movie fps, as this method is reliable.
+ CComPtr<IPin> pPin;
+ CMediaType mt;
+ if (
+ SUCCEEDED(m_pOuterEVR->FindPin(L"EVR Input0", &pPin)) &&
+ SUCCEEDED(pPin->ConnectionMediaType(&mt))) {
+
+ ExtractAvgTimePerFrame(&mt, m_rtTimePerFrame);
+
+ m_bInterlaced = ExtractInterlaced(&mt);
+
+ CComPtr<IPin> pPinTo;
+ if (SUCCEEDED(pPin->ConnectedTo(&pPinTo)) && pPinTo) {
+ m_Decoder = GetFilterName(GetFilterFromPin(pPinTo));
+ }
+ }
+ // If framerate not set by Video Decoder choose 23.97...
+ if (m_rtTimePerFrame == 0) {
+ m_rtTimePerFrame = 417166;
+ }
+
+ // Update internal subtitle clock
+ if (m_fUseInternalTimer && m_pSubPicQueue) {
+ m_fps = (float)(10000000.0 / m_rtTimePerFrame);
+ m_pSubPicQueue->SetFPS(m_fps);
+ }
+
+ }
+
+ }
+ break;
+ }
+ }
+
+ timeEndPeriod(dwResolution);
+ // if (pfAvRevertMmThreadCharacteristics) pfAvRevertMmThreadCharacteristics (hAvrt);
}
void ModerateFloat(double& Value, double Target, double& ValuePrim, double ChangeSpeed)
{
- double xbiss = (-(ChangeSpeed)*(ValuePrim) - (Value-Target)*(ChangeSpeed*ChangeSpeed)*0.25f);
- ValuePrim += xbiss;
- Value += ValuePrim;
+ double xbiss = (-(ChangeSpeed) * (ValuePrim) - (Value - Target) * (ChangeSpeed * ChangeSpeed) * 0.25f);
+ ValuePrim += xbiss;
+ Value += ValuePrim;
}
LONGLONG CEVRAllocatorPresenter::GetClockTime(LONGLONG PerformanceCounter)
{
- LONGLONG llClockTime;
- MFTIME nsCurrentTime;
- m_pClock->GetCorrelatedTime(0, &llClockTime, &nsCurrentTime);
- DWORD Characteristics = 0;
- m_pClock->GetClockCharacteristics(&Characteristics);
- MFCLOCK_STATE State;
- m_pClock->GetState(0, &State);
-
- if (!(Characteristics & MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ)) {
- MFCLOCK_PROPERTIES Props;
- if (m_pClock->GetProperties(&Props) == S_OK) {
- llClockTime = (llClockTime * 10000000) / Props.qwClockFrequency; // Make 10 MHz
- }
-
- }
- LONGLONG llPerf = PerformanceCounter;
- // return llClockTime + (llPerf - nsCurrentTime);
- double Target = llClockTime + (llPerf - nsCurrentTime) * m_ModeratedTimeSpeed;
-
- bool bReset = false;
- if (m_ModeratedTimeLast < 0 || State != m_LastClockState || m_ModeratedClockLast < 0) {
- bReset = true;
- m_ModeratedTimeLast = llPerf;
- m_ModeratedClockLast = llClockTime;
- }
-
- m_LastClockState = State;
-
- LONGLONG TimeChangeM = llPerf - m_ModeratedTimeLast;
- LONGLONG ClockChangeM = llClockTime - m_ModeratedClockLast;
- UNREFERENCED_PARAMETER(ClockChangeM);
-
- m_ModeratedTimeLast = llPerf;
- m_ModeratedClockLast = llClockTime;
+ LONGLONG llClockTime;
+ MFTIME nsCurrentTime;
+ m_pClock->GetCorrelatedTime(0, &llClockTime, &nsCurrentTime);
+ DWORD Characteristics = 0;
+ m_pClock->GetClockCharacteristics(&Characteristics);
+ MFCLOCK_STATE State;
+ m_pClock->GetState(0, &State);
+
+ if (!(Characteristics & MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ)) {
+ MFCLOCK_PROPERTIES Props;
+ if (m_pClock->GetProperties(&Props) == S_OK) {
+ llClockTime = (llClockTime * 10000000) / Props.qwClockFrequency; // Make 10 MHz
+ }
+
+ }
+ LONGLONG llPerf = PerformanceCounter;
+ // return llClockTime + (llPerf - nsCurrentTime);
+ double Target = llClockTime + (llPerf - nsCurrentTime) * m_ModeratedTimeSpeed;
+
+ bool bReset = false;
+ if (m_ModeratedTimeLast < 0 || State != m_LastClockState || m_ModeratedClockLast < 0) {
+ bReset = true;
+ m_ModeratedTimeLast = llPerf;
+ m_ModeratedClockLast = llClockTime;
+ }
+
+ m_LastClockState = State;
+
+ LONGLONG TimeChangeM = llPerf - m_ModeratedTimeLast;
+ LONGLONG ClockChangeM = llClockTime - m_ModeratedClockLast;
+ UNREFERENCED_PARAMETER(ClockChangeM);
+
+ m_ModeratedTimeLast = llPerf;
+ m_ModeratedClockLast = llClockTime;
#if 1
- if (bReset) {
- m_ModeratedTimeSpeed = 1.0;
- m_ModeratedTimeSpeedPrim = 0.0;
- ZeroMemory(m_TimeChangeHistory, sizeof(m_TimeChangeHistory));
- ZeroMemory(m_ClockChangeHistory, sizeof(m_ClockChangeHistory));
- m_ClockTimeChangeHistoryPos = 0;
- }
- if (TimeChangeM) {
- int Pos = m_ClockTimeChangeHistoryPos % 100;
- int nHistory = min(m_ClockTimeChangeHistoryPos, 100);
- ++m_ClockTimeChangeHistoryPos;
- if (nHistory > 50) {
- int iLastPos = (Pos - (nHistory)) % 100;
- if (iLastPos < 0) {
- iLastPos += 100;
- }
-
- double TimeChange = llPerf - m_TimeChangeHistory[iLastPos];
- double ClockChange = llClockTime - m_ClockChangeHistory[iLastPos];
-
- double ClockSpeedTarget = ClockChange / TimeChange;
- double ChangeSpeed = 0.1;
- if (ClockSpeedTarget > m_ModeratedTimeSpeed) {
- if (ClockSpeedTarget / m_ModeratedTimeSpeed > 0.1) {
- ChangeSpeed = 0.1;
- } else {
- ChangeSpeed = 0.01;
- }
- } else {
- if (m_ModeratedTimeSpeed / ClockSpeedTarget > 0.1) {
- ChangeSpeed = 0.1;
- } else {
- ChangeSpeed = 0.01;
- }
- }
- ModerateFloat(m_ModeratedTimeSpeed, ClockSpeedTarget, m_ModeratedTimeSpeedPrim, ChangeSpeed);
- // m_ModeratedTimeSpeed = TimeChange / ClockChange;
- }
- m_TimeChangeHistory[Pos] = (double)llPerf;
- m_ClockChangeHistory[Pos] = (double)llClockTime;
- }
-
- return (LONGLONG)Target;
+ if (bReset) {
+ m_ModeratedTimeSpeed = 1.0;
+ m_ModeratedTimeSpeedPrim = 0.0;
+ ZeroMemory(m_TimeChangeHistory, sizeof(m_TimeChangeHistory));
+ ZeroMemory(m_ClockChangeHistory, sizeof(m_ClockChangeHistory));
+ m_ClockTimeChangeHistoryPos = 0;
+ }
+ if (TimeChangeM) {
+ int Pos = m_ClockTimeChangeHistoryPos % 100;
+ int nHistory = min(m_ClockTimeChangeHistoryPos, 100);
+ ++m_ClockTimeChangeHistoryPos;
+ if (nHistory > 50) {
+ int iLastPos = (Pos - (nHistory)) % 100;
+ if (iLastPos < 0) {
+ iLastPos += 100;
+ }
+
+ double TimeChange = llPerf - m_TimeChangeHistory[iLastPos];
+ double ClockChange = llClockTime - m_ClockChangeHistory[iLastPos];
+
+ double ClockSpeedTarget = ClockChange / TimeChange;
+ double ChangeSpeed = 0.1;
+ if (ClockSpeedTarget > m_ModeratedTimeSpeed) {
+ if (ClockSpeedTarget / m_ModeratedTimeSpeed > 0.1) {
+ ChangeSpeed = 0.1;
+ } else {
+ ChangeSpeed = 0.01;
+ }
+ } else {
+ if (m_ModeratedTimeSpeed / ClockSpeedTarget > 0.1) {
+ ChangeSpeed = 0.1;
+ } else {
+ ChangeSpeed = 0.01;
+ }
+ }
+ ModerateFloat(m_ModeratedTimeSpeed, ClockSpeedTarget, m_ModeratedTimeSpeedPrim, ChangeSpeed);
+ // m_ModeratedTimeSpeed = TimeChange / ClockChange;
+ }
+ m_TimeChangeHistory[Pos] = (double)llPerf;
+ m_ClockChangeHistory[Pos] = (double)llClockTime;
+ }
+
+ return (LONGLONG)Target;
#else
- double EstimateTime = m_ModeratedTime + TimeChange * m_ModeratedTimeSpeed + m_ClockDiffCalc;
- double Diff = Target - EstimateTime;
-
- // > 5 ms just set it
- if ((fabs(Diff) > 50000.0 || bReset)) {
-
- // TRACE_EVR("EVR: Reset clock at diff: %f ms\n", (m_ModeratedTime - Target) /10000.0);
- if (State == MFCLOCK_STATE_RUNNING) {
- if (bReset) {
- m_ModeratedTimeSpeed = 1.0;
- m_ModeratedTimeSpeedPrim = 0.0;
- m_ClockDiffCalc = 0;
- m_ClockDiffPrim = 0;
- m_ModeratedTime = Target;
- m_ModeratedTimer = llPerf;
- } else {
- EstimateTime = m_ModeratedTime + TimeChange * m_ModeratedTimeSpeed;
- Diff = Target - EstimateTime;
- m_ClockDiffCalc = Diff;
- m_ClockDiffPrim = 0;
- }
- } else {
- m_ModeratedTimeSpeed = 0.0;
- m_ModeratedTimeSpeedPrim = 0.0;
- m_ClockDiffCalc = 0;
- m_ClockDiffPrim = 0;
- m_ModeratedTime = Target;
- m_ModeratedTimer = llPerf;
- }
- }
-
- {
- LONGLONG ModerateTime = 10000;
- double ChangeSpeed = 1.00;
- /* if (m_ModeratedTimeSpeedPrim != 0.0)
- {
- if (m_ModeratedTimeSpeedPrim < 0.1)
- ChangeSpeed = 0.1;
- }*/
-
- int nModerate = 0;
- double Change = 0;
- while (m_ModeratedTimer < llPerf - ModerateTime) {
- m_ModeratedTimer += ModerateTime;
- m_ModeratedTime += double(ModerateTime) * m_ModeratedTimeSpeed;
-
- double TimerDiff = llPerf - m_ModeratedTimer;
-
- double Diff = (double)(m_ModeratedTime - (Target - TimerDiff));
-
- double TimeSpeedTarget;
- double AbsDiff = fabs(Diff);
- TimeSpeedTarget = 1.0 - (Diff / 1000000.0);
- // TimeSpeedTarget = m_ModeratedTimeSpeed - (Diff / 100000000000.0);
- //if (AbsDiff > 20000.0)
- // TimeSpeedTarget = 1.0 - (Diff / 1000000.0);
- /*else if (AbsDiff > 5000.0)
- TimeSpeedTarget = 1.0 - (Diff / 100000000.0);
- else
- TimeSpeedTarget = 1.0 - (Diff / 500000000.0);*/
- double StartMod = m_ModeratedTimeSpeed;
- ModerateFloat(m_ModeratedTimeSpeed, TimeSpeedTarget, m_ModeratedTimeSpeedPrim, ChangeSpeed);
- m_ModeratedTimeSpeed = TimeSpeedTarget;
- ++nModerate;
- Change += m_ModeratedTimeSpeed - StartMod;
- }
- if (nModerate) {
- m_ModeratedTimeSpeedDiff = Change / nModerate;
- }
-
- double Ret = m_ModeratedTime + double(llPerf - m_ModeratedTimer) * m_ModeratedTimeSpeed;
- double Diff = Target - Ret;
- ModerateFloat(m_ClockDiffCalc, Diff, m_ClockDiffPrim, ChangeSpeed*0.1);
-
- Ret += m_ClockDiffCalc;
- Diff = Target - Ret;
- m_ClockDiff = Diff;
- return LONGLONG(Ret + 0.5);
- }
-
- return Target;
- return LONGLONG(m_ModeratedTime + 0.5);
+ double EstimateTime = m_ModeratedTime + TimeChange * m_ModeratedTimeSpeed + m_ClockDiffCalc;
+ double Diff = Target - EstimateTime;
+
+ // > 5 ms just set it
+ if ((fabs(Diff) > 50000.0 || bReset)) {
+
+ // TRACE_EVR("EVR: Reset clock at diff: %f ms\n", (m_ModeratedTime - Target) /10000.0);
+ if (State == MFCLOCK_STATE_RUNNING) {
+ if (bReset) {
+ m_ModeratedTimeSpeed = 1.0;
+ m_ModeratedTimeSpeedPrim = 0.0;
+ m_ClockDiffCalc = 0;
+ m_ClockDiffPrim = 0;
+ m_ModeratedTime = Target;
+ m_ModeratedTimer = llPerf;
+ } else {
+ EstimateTime = m_ModeratedTime + TimeChange * m_ModeratedTimeSpeed;
+ Diff = Target - EstimateTime;
+ m_ClockDiffCalc = Diff;
+ m_ClockDiffPrim = 0;
+ }
+ } else {
+ m_ModeratedTimeSpeed = 0.0;
+ m_ModeratedTimeSpeedPrim = 0.0;
+ m_ClockDiffCalc = 0;
+ m_ClockDiffPrim = 0;
+ m_ModeratedTime = Target;
+ m_ModeratedTimer = llPerf;
+ }
+ }
+
+ {
+ LONGLONG ModerateTime = 10000;
+ double ChangeSpeed = 1.00;
+ /* if (m_ModeratedTimeSpeedPrim != 0.0)
+ {
+ if (m_ModeratedTimeSpeedPrim < 0.1)
+ ChangeSpeed = 0.1;
+ }*/
+
+ int nModerate = 0;
+ double Change = 0;
+ while (m_ModeratedTimer < llPerf - ModerateTime) {
+ m_ModeratedTimer += ModerateTime;
+ m_ModeratedTime += double(ModerateTime) * m_ModeratedTimeSpeed;
+
+ double TimerDiff = llPerf - m_ModeratedTimer;
+
+ double Diff = (double)(m_ModeratedTime - (Target - TimerDiff));
+
+ double TimeSpeedTarget;
+ double AbsDiff = fabs(Diff);
+ TimeSpeedTarget = 1.0 - (Diff / 1000000.0);
+ // TimeSpeedTarget = m_ModeratedTimeSpeed - (Diff / 100000000000.0);
+ //if (AbsDiff > 20000.0)
+ // TimeSpeedTarget = 1.0 - (Diff / 1000000.0);
+ /*else if (AbsDiff > 5000.0)
+ TimeSpeedTarget = 1.0 - (Diff / 100000000.0);
+ else
+ TimeSpeedTarget = 1.0 - (Diff / 500000000.0);*/
+ double StartMod = m_ModeratedTimeSpeed;
+ ModerateFloat(m_ModeratedTimeSpeed, TimeSpeedTarget, m_ModeratedTimeSpeedPrim, ChangeSpeed);
+ m_ModeratedTimeSpeed = TimeSpeedTarget;
+ ++nModerate;
+ Change += m_ModeratedTimeSpeed - StartMod;
+ }
+ if (nModerate) {
+ m_ModeratedTimeSpeedDiff = Change / nModerate;
+ }
+
+ double Ret = m_ModeratedTime + double(llPerf - m_ModeratedTimer) * m_ModeratedTimeSpeed;
+ double Diff = Target - Ret;
+ ModerateFloat(m_ClockDiffCalc, Diff, m_ClockDiffPrim, ChangeSpeed * 0.1);
+
+ Ret += m_ClockDiffCalc;
+ Diff = Target - Ret;
+ m_ClockDiff = Diff;
+ return LONGLONG(Ret + 0.5);
+ }
+
+ return Target;
+ return LONGLONG(m_ModeratedTime + 0.5);
#endif
}
void CEVRAllocatorPresenter::OnVBlankFinished(bool fAll, LONGLONG PerformanceCounter)
{
- if (!m_pCurrentDisplaydSample || !m_OrderedPaint || !fAll) {
- return;
- }
-
- LONGLONG llClockTime;
- LONGLONG nsSampleTime;
- LONGLONG SampleDuration = 0;
- if (!m_bSignaledStarvation) {
- llClockTime = GetClockTime(PerformanceCounter);
- m_StarvationClock = llClockTime;
- } else {
- llClockTime = m_StarvationClock;
- }
- if (FAILED(m_pCurrentDisplaydSample->GetSampleDuration(&SampleDuration))) {
- SampleDuration = 0;
- }
-
- if (FAILED(m_pCurrentDisplaydSample->GetSampleTime(&nsSampleTime))) {
- nsSampleTime = llClockTime;
- }
- LONGLONG TimePerFrame = m_rtTimePerFrame;
- if (!TimePerFrame) {
- return;
- }
- if (SampleDuration > 1) {
- TimePerFrame = SampleDuration;
- }
- {
- m_nNextSyncOffset = (m_nNextSyncOffset+1) % NB_JITTER;
- LONGLONG SyncOffset = nsSampleTime - llClockTime;
-
- m_pllSyncOffset[m_nNextSyncOffset] = SyncOffset;
- // TRACE_EVR("EVR: SyncOffset(%d, %d): %8I64d %8I64d %8I64d \n", m_nCurSurface, m_VSyncMode, m_LastPredictedSync, -SyncOffset, m_LastPredictedSync - (-SyncOffset));
-
- m_MaxSyncOffset = MINLONG64;
- m_MinSyncOffset = MAXLONG64;
-
- LONGLONG AvrageSum = 0;
- for (int i=0; i<NB_JITTER; i++) {
- LONGLONG Offset = m_pllSyncOffset[i];
- AvrageSum += Offset;
- m_MaxSyncOffset = max(m_MaxSyncOffset, Offset);
- m_MinSyncOffset = min(m_MinSyncOffset, Offset);
- }
- double MeanOffset = double(AvrageSum)/NB_JITTER;
- double DeviationSum = 0;
- for (int i=0; i<NB_JITTER; i++) {
- double Deviation = double(m_pllSyncOffset[i]) - MeanOffset;
- DeviationSum += Deviation*Deviation;
- }
- double StdDev = sqrt(DeviationSum/NB_JITTER);
-
- m_fSyncOffsetAvr = MeanOffset;
- m_bSyncStatsAvailable = true;
- m_fSyncOffsetStdDev = StdDev;
-
-
- }
+ if (!m_pCurrentDisplaydSample || !m_OrderedPaint || !fAll) {
+ return;
+ }
+
+ LONGLONG llClockTime;
+ LONGLONG nsSampleTime;
+ LONGLONG SampleDuration = 0;
+ if (!m_bSignaledStarvation) {
+ llClockTime = GetClockTime(PerformanceCounter);
+ m_StarvationClock = llClockTime;
+ } else {
+ llClockTime = m_StarvationClock;
+ }
+ if (FAILED(m_pCurrentDisplaydSample->GetSampleDuration(&SampleDuration))) {
+ SampleDuration = 0;
+ }
+
+ if (FAILED(m_pCurrentDisplaydSample->GetSampleTime(&nsSampleTime))) {
+ nsSampleTime = llClockTime;
+ }
+ LONGLONG TimePerFrame = m_rtTimePerFrame;
+ if (!TimePerFrame) {
+ return;
+ }
+ if (SampleDuration > 1) {
+ TimePerFrame = SampleDuration;
+ }
+ {
+ m_nNextSyncOffset = (m_nNextSyncOffset + 1) % NB_JITTER;
+ LONGLONG SyncOffset = nsSampleTime - llClockTime;
+
+ m_pllSyncOffset[m_nNextSyncOffset] = SyncOffset;
+ // TRACE_EVR("EVR: SyncOffset(%d, %d): %8I64d %8I64d %8I64d \n", m_nCurSurface, m_VSyncMode, m_LastPredictedSync, -SyncOffset, m_LastPredictedSync - (-SyncOffset));
+
+ m_MaxSyncOffset = MINLONG64;
+ m_MinSyncOffset = MAXLONG64;
+
+ LONGLONG AvrageSum = 0;
+ for (int i = 0; i < NB_JITTER; i++) {
+ LONGLONG Offset = m_pllSyncOffset[i];
+ AvrageSum += Offset;
+ m_MaxSyncOffset = max(m_MaxSyncOffset, Offset);
+ m_MinSyncOffset = min(m_MinSyncOffset, Offset);
+ }
+ double MeanOffset = double(AvrageSum) / NB_JITTER;
+ double DeviationSum = 0;
+ for (int i = 0; i < NB_JITTER; i++) {
+ double Deviation = double(m_pllSyncOffset[i]) - MeanOffset;
+ DeviationSum += Deviation * Deviation;
+ }
+ double StdDev = sqrt(DeviationSum / NB_JITTER);
+
+ m_fSyncOffsetAvr = MeanOffset;
+ m_bSyncStatsAvailable = true;
+ m_fSyncOffsetStdDev = StdDev;
+
+
+ }
}
STDMETHODIMP_(bool) CEVRAllocatorPresenter::ResetDevice()
{
- CAutoLock lock(this);
- CAutoLock lock2(&m_ImageProcessingLock);
- CAutoLock cRenderLock(&m_RenderLock);
+ CAutoLock lock(this);
+ CAutoLock lock2(&m_ImageProcessingLock);
+ CAutoLock cRenderLock(&m_RenderLock);
- RemoveAllSamples();
+ RemoveAllSamples();
- bool bResult = __super::ResetDevice();
+ bool bResult = __super::ResetDevice();
- for (int i = 0; i < m_nNbDXSurface; i++) {
- CComPtr<IMFSample> pMFSample;
- HRESULT hr = pfMFCreateVideoSampleFromSurface (m_pVideoSurface[i], &pMFSample);
+ for (int i = 0; i < m_nNbDXSurface; i++) {
+ CComPtr<IMFSample> pMFSample;
+ HRESULT hr = pfMFCreateVideoSampleFromSurface(m_pVideoSurface[i], &pMFSample);
- if (SUCCEEDED (hr)) {
- pMFSample->SetUINT32 (GUID_SURFACE_INDEX, i);
- m_FreeSamples.AddTail (pMFSample);
- }
- ASSERT (SUCCEEDED (hr));
- }
- return bResult;
+ if (SUCCEEDED(hr)) {
+ pMFSample->SetUINT32(GUID_SURFACE_INDEX, i);
+ m_FreeSamples.AddTail(pMFSample);
+ }
+ ASSERT(SUCCEEDED(hr));
+ }
+ return bResult;
}
STDMETHODIMP_(bool) CEVRAllocatorPresenter::DisplayChange()
{
- CAutoLock lock(this);
- CAutoLock lock2(&m_ImageProcessingLock);
- CAutoLock cRenderLock(&m_RenderLock);
-
- m_DetectedFrameRate = 0.0;
- m_DetectedFrameTime = 0.0;
- m_DetectedFrameTimeStdDev = 0.0;
- m_DetectedLock = false;
- ZeroMemory(m_DetectedFrameTimeHistory, sizeof(m_DetectedFrameTimeHistory));
- ZeroMemory(m_DetectedFrameTimeHistoryHistory, sizeof(m_DetectedFrameTimeHistoryHistory));
- m_DetectedFrameTimePos = 0;
- ZeroMemory(&m_VMR9AlphaBitmap, sizeof(m_VMR9AlphaBitmap));
-
- ZeroMemory(m_ldDetectedRefreshRateList, sizeof(m_ldDetectedRefreshRateList));
- ZeroMemory(m_ldDetectedScanlineRateList, sizeof(m_ldDetectedScanlineRateList));
- m_DetectedRefreshRatePos = 0;
- m_DetectedRefreshTimePrim = 0;
- m_DetectedScanlineTime = 0;
- m_DetectedScanlineTimePrim = 0;
- m_DetectedRefreshRate = 0;
-
- memset (m_pllJitter, 0, sizeof(m_pllJitter));
- memset (m_pllSyncOffset, 0, sizeof(m_pllSyncOffset));
- m_nNextJitter = 0;
- m_nNextSyncOffset = 0;
- m_llLastPerf = 0;
- m_fAvrFps = 0.0;
- m_fJitterStdDev = 0.0;
- m_fSyncOffsetStdDev = 0.0;
- m_fSyncOffsetAvr = 0.0;
- m_bSyncStatsAvailable = false;
-
- bool bResult = __super::DisplayChange();
-
- return bResult;
+ CAutoLock lock(this);
+ CAutoLock lock2(&m_ImageProcessingLock);
+ CAutoLock cRenderLock(&m_RenderLock);
+
+ m_DetectedFrameRate = 0.0;
+ m_DetectedFrameTime = 0.0;
+ m_DetectedFrameTimeStdDev = 0.0;
+ m_DetectedLock = false;
+ ZeroMemory(m_DetectedFrameTimeHistory, sizeof(m_DetectedFrameTimeHistory));
+ ZeroMemory(m_DetectedFrameTimeHistoryHistory, sizeof(m_DetectedFrameTimeHistoryHistory));
+ m_DetectedFrameTimePos = 0;
+ ZeroMemory(&m_VMR9AlphaBitmap, sizeof(m_VMR9AlphaBitmap));
+
+ ZeroMemory(m_ldDetectedRefreshRateList, sizeof(m_ldDetectedRefreshRateList));
+ ZeroMemory(m_ldDetectedScanlineRateList, sizeof(m_ldDetectedScanlineRateList));
+ m_DetectedRefreshRatePos = 0;
+ m_DetectedRefreshTimePrim = 0;
+ m_DetectedScanlineTime = 0;
+ m_DetectedScanlineTimePrim = 0;
+ m_DetectedRefreshRate = 0;
+
+ memset(m_pllJitter, 0, sizeof(m_pllJitter));
+ memset(m_pllSyncOffset, 0, sizeof(m_pllSyncOffset));
+ m_nNextJitter = 0;
+ m_nNextSyncOffset = 0;
+ m_llLastPerf = 0;
+ m_fAvrFps = 0.0;
+ m_fJitterStdDev = 0.0;
+ m_fSyncOffsetStdDev = 0.0;
+ m_fSyncOffsetAvr = 0.0;
+ m_bSyncStatsAvailable = false;
+
+ bool bResult = __super::DisplayChange();
+
+ return bResult;
}
void CEVRAllocatorPresenter::RenderThread()
{
- HANDLE hEvts[] = { m_hEvtQuit, m_hEvtFlush};
- bool bQuit = false;
- TIMECAPS tc;
- DWORD dwResolution;
- MFTIME nsSampleTime;
- LONGLONG llClockTime;
- DWORD dwUser = 0;
- DWORD dwObject;
-
-
- // Tell Vista Multimedia Class Scheduler we are a playback thretad (increase priority)
- HANDLE hAvrt = 0;
- if (pfAvSetMmThreadCharacteristicsW) {
- DWORD dwTaskIndex = 0;
- hAvrt = pfAvSetMmThreadCharacteristicsW (L"Playback", &dwTaskIndex);
- if (pfAvSetMmThreadPriority) {
- pfAvSetMmThreadPriority (hAvrt, AVRT_PRIORITY_HIGH /*AVRT_PRIORITY_CRITICAL*/);
- }
- }
-
- timeGetDevCaps(&tc, sizeof(TIMECAPS));
- dwResolution = min(max(tc.wPeriodMin, 0), tc.wPeriodMax);
- dwUser = timeBeginPeriod(dwResolution);
- CRenderersSettings& s = GetRenderersSettings();
-
- int NextSleepTime = 1;
- while (!bQuit) {
- LONGLONG llPerf = GetRenderersData()->GetPerfCounter();
- UNREFERENCED_PARAMETER(llPerf);
- if (!s.m_RenderSettings.iVMR9VSyncAccurate && NextSleepTime == 0) {
- NextSleepTime = 1;
- }
- dwObject = WaitForMultipleObjects (_countof(hEvts), hEvts, FALSE, max(NextSleepTime < 0 ? 1 : NextSleepTime, 0));
- /* dwObject = WAIT_TIMEOUT;
- if (m_bEvtFlush)
- dwObject = WAIT_OBJECT_0 + 1;
- else if (m_bEvtQuit)
- dwObject = WAIT_OBJECT_0;*/
- // if (NextSleepTime)
- // TRACE_EVR("EVR: Sleep: %7.3f\n", double(GetRenderersData()->GetPerfCounter()-llPerf) / 10000.0);
- if (NextSleepTime > 1) {
- NextSleepTime = 0;
- } else if (NextSleepTime == 0) {
- NextSleepTime = -1;
- }
- switch (dwObject) {
- case WAIT_OBJECT_0 :
- bQuit = true;
- break;
- case WAIT_OBJECT_0 + 1 :
- // Flush pending samples!
- FlushSamples();
- m_bEvtFlush = false;
- ResetEvent(m_hEvtFlush);
- TRACE_EVR ("EVR: Flush done!\n");
- break;
-
- case WAIT_TIMEOUT :
-
- if (m_LastSetOutputRange != -1 && m_LastSetOutputRange != s.m_RenderSettings.iEVROutputRange || m_bPendingRenegotiate) {
- FlushSamples();
- RenegotiateMediaType();
- m_bPendingRenegotiate = false;
- }
- if (m_bPendingResetDevice) {
- SendResetRequest();
- }
-
- // Discard timer events if playback stop
- // if ((dwObject == WAIT_OBJECT_0 + 3) && (m_nRenderState != Started)) continue;
-
- // TRACE_EVR ("EVR: RenderThread ==>> Waiting buffer\n");
-
- // if (WaitForMultipleObjects (_countof(hEvtsBuff), hEvtsBuff, FALSE, INFINITE) == WAIT_OBJECT_0+2)
- {
- CComPtr<IMFSample> pMFSample;
- LONGLONG llPerf = GetRenderersData()->GetPerfCounter();
- UNREFERENCED_PARAMETER(llPerf);
- int nSamplesLeft = 0;
- if (SUCCEEDED (GetScheduledSample(&pMFSample, nSamplesLeft))) {
- // pMFSample->GetUINT32 (GUID_SURFACE_INDEX, (UINT32*)&m_nCurSurface);
- m_pCurrentDisplaydSample = pMFSample;
-
- bool bValidSampleTime = true;
- HRESULT hGetSampleTime = pMFSample->GetSampleTime (&nsSampleTime);
- if (hGetSampleTime != S_OK || nsSampleTime == 0) {
- bValidSampleTime = false;
- }
- // We assume that all samples have the same duration
- LONGLONG SampleDuration = 0;
- pMFSample->GetSampleDuration(&SampleDuration);
-
- // TRACE_EVR ("EVR: RenderThread ==>> Presenting surface %d (%I64d)\n", m_nCurSurface, nsSampleTime);
-
- bool bStepForward = false;
-
- if (m_nStepCount < 0) {
- // Drop frame
- TRACE_EVR ("EVR: Dropped frame\n");
- m_pcFrames++;
- bStepForward = true;
- m_nStepCount = 0;
- /*
- } else if (m_nStepCount > 0) {
- pMFSample->GetUINT32(GUID_SURFACE_INDEX, (UINT32 *)&m_nCurSurface);
- ++m_OrderedPaint;
- if (!g_bExternalSubtitleTime) {
- __super::SetTime (g_tSegmentStart + nsSampleTime);
- }
- Paint(true);
- m_nDroppedUpdate = 0;
- CompleteFrameStep (false);
- bStepForward = true;
- */
- } else if ((m_nRenderState == Started)) {
- LONGLONG CurrentCounter = GetRenderersData()->GetPerfCounter();
- // Calculate wake up timer
- if (!m_bSignaledStarvation) {
- llClockTime = GetClockTime(CurrentCounter);
- m_StarvationClock = llClockTime;
- } else {
- llClockTime = m_StarvationClock;
- }
-
- if (!bValidSampleTime) {
- // Just play as fast as possible
- bStepForward = true;
- pMFSample->GetUINT32(GUID_SURFACE_INDEX, (UINT32 *)&m_nCurSurface);
- ++m_OrderedPaint;
- if (!g_bExternalSubtitleTime) {
- __super::SetTime (g_tSegmentStart + nsSampleTime);
- }
- Paint(true);
- } else {
- LONGLONG TimePerFrame = (LONGLONG)(GetFrameTime() * 10000000.0);
- LONGLONG DrawTime = m_PaintTime * 9 / 10 - 20000; // 2 ms offset (= m_PaintTime * 0.9 - 20000)
- //if (!s.iVMR9VSync)
- DrawTime = 0;
-
- LONGLONG SyncOffset = 0;
- LONGLONG VSyncTime = 0;
- LONGLONG TimeToNextVSync = -1;
- bool bVSyncCorrection = false;
- double DetectedRefreshTime;
- double DetectedScanlinesPerFrame;
- double DetectedScanlineTime;
- int DetectedRefreshRatePos;
- {
- CAutoLock Lock(&m_RefreshRateLock);
- DetectedRefreshTime = m_DetectedRefreshTime;
- DetectedRefreshRatePos = m_DetectedRefreshRatePos;
- DetectedScanlinesPerFrame = m_DetectedScanlinesPerFrame;
- DetectedScanlineTime = m_DetectedScanlineTime;
- }
-
- if (DetectedRefreshRatePos < 20 || !DetectedRefreshTime || !DetectedScanlinesPerFrame) {
- DetectedRefreshTime = 1.0/m_RefreshRate;
- DetectedScanlinesPerFrame = m_ScreenSize.cy;
- DetectedScanlineTime = DetectedRefreshTime / double(m_ScreenSize.cy);
- }
-
- if (s.m_RenderSettings.iVMR9VSync) {
- bVSyncCorrection = true;
- double TargetVSyncPos = GetVBlackPos();
- double RefreshLines = DetectedScanlinesPerFrame;
- double ScanlinesPerSecond = 1.0/DetectedScanlineTime;
- double CurrentVSyncPos = fmod(double(m_VBlankStartMeasure) + ScanlinesPerSecond * ((CurrentCounter - m_VBlankStartMeasureTime) / 10000000.0), RefreshLines);
- double LinesUntilVSync = 0;
- //TargetVSyncPos -= ScanlinesPerSecond * (DrawTime/10000000.0);
- //TargetVSyncPos -= 10;
- TargetVSyncPos = fmod(TargetVSyncPos, RefreshLines);
- if (TargetVSyncPos < 0) {
- TargetVSyncPos += RefreshLines;
- }
- if (TargetVSyncPos > CurrentVSyncPos) {
- LinesUntilVSync = TargetVSyncPos - CurrentVSyncPos;
- } else {
- LinesUntilVSync = (RefreshLines - CurrentVSyncPos) + TargetVSyncPos;
- }
- double TimeUntilVSync = LinesUntilVSync * DetectedScanlineTime;
- TimeToNextVSync = (LONGLONG)(TimeUntilVSync * 10000000.0);
- VSyncTime = (LONGLONG)(DetectedRefreshTime * 10000000.0);
-
- LONGLONG ClockTimeAtNextVSync = llClockTime + (LONGLONG)(TimeUntilVSync * 10000000.0 * m_ModeratedTimeSpeed);
-
- SyncOffset = (nsSampleTime - ClockTimeAtNextVSync);
-
- // if (SyncOffset < 0)
- // TRACE_EVR("EVR: SyncOffset(%d): %I64d %I64d %I64d\n", m_nCurSurface, SyncOffset, TimePerFrame, VSyncTime);
- } else {
- SyncOffset = (nsSampleTime - llClockTime);
- }
-
- //LONGLONG SyncOffset = nsSampleTime - llClockTime;
- TRACE_EVR ("EVR: SyncOffset: %I64d SampleFrame: %I64d ClockFrame: %I64d\n", SyncOffset, TimePerFrame!=0 ? nsSampleTime/TimePerFrame : 0, TimePerFrame!=0 ? llClockTime /TimePerFrame : 0);
- if (SampleDuration > 1 && !m_DetectedLock) {
- TimePerFrame = SampleDuration;
- }
-
- LONGLONG MinMargin;
- if (m_FrameTimeCorrection && 0) {
- MinMargin = 15000;
- } else {
- MinMargin = 15000 + min(LONGLONG(m_DetectedFrameTimeStdDev), 20000);
- }
- LONGLONG TimePerFrameMargin = min(max(TimePerFrame*2/100, MinMargin), TimePerFrame*11/100); // (0.02..0.11)TimePerFrame
- LONGLONG TimePerFrameMargin0 = TimePerFrameMargin/2;
- LONGLONG TimePerFrameMargin1 = 0;
-
- if (m_DetectedLock && TimePerFrame < VSyncTime) {
- VSyncTime = TimePerFrame;
- }
-
- if (m_VSyncMode == 1) {
- TimePerFrameMargin1 = -TimePerFrameMargin;
- } else if (m_VSyncMode == 2) {
- TimePerFrameMargin1 = TimePerFrameMargin;
- }
-
- m_LastSampleOffset = SyncOffset;
- m_bLastSampleOffsetValid = true;
-
- LONGLONG VSyncOffset0 = 0;
- bool bDoVSyncCorrection = false;
- if ((SyncOffset < -(TimePerFrame + TimePerFrameMargin0 - TimePerFrameMargin1)) && nSamplesLeft > 0) { // Only drop if we have something else to display at once
- // Drop frame
- TRACE_EVR ("EVR: Dropped frame\n");
- m_pcFrames++;
- bStepForward = true;
- ++m_nDroppedUpdate;
- NextSleepTime = 0;
- // VSyncOffset0 = (-SyncOffset) - VSyncTime;
- //VSyncOffset0 = (-SyncOffset) - VSyncTime + TimePerFrameMargin1;
- //m_LastPredictedSync = VSyncOffset0;
- bDoVSyncCorrection = false;
- } else if (SyncOffset < TimePerFrameMargin1) {
-
- if (bVSyncCorrection) {
- VSyncOffset0 = -SyncOffset;
- bDoVSyncCorrection = true;
- }
-
- // Paint and prepare for next frame
- TRACE_EVR ("EVR: Normalframe\n");
- m_nDroppedUpdate = 0;
- bStepForward = true;
- pMFSample->GetUINT32(GUID_SURFACE_INDEX, (UINT32 *)&m_nCurSurface);
- m_LastFrameDuration = nsSampleTime - m_LastSampleTime;
- m_LastSampleTime = nsSampleTime;
- m_LastPredictedSync = VSyncOffset0;
-
- if (m_nStepCount > 0) {
- CompleteFrameStep (false);
- }
-
- ++m_OrderedPaint;
-
- if (!g_bExternalSubtitleTime) {
- __super::SetTime (g_tSegmentStart + nsSampleTime);
- }
- Paint(true);
-
- NextSleepTime = 0;
- m_pcFramesDrawn++;
- } else {
- if (TimeToNextVSync >= 0 && SyncOffset > 0) {
- NextSleepTime = (int)(TimeToNextVSync/10000 - 2);
- } else {
- NextSleepTime = (int)(SyncOffset/10000 - 2);
- }
-
- if (NextSleepTime > TimePerFrame) {
- NextSleepTime = 1;
- }
-
- if (NextSleepTime < 0) {
- NextSleepTime = 0;
- }
- NextSleepTime = 1;
- //TRACE_EVR ("EVR: Delay\n");
- }
-
- if (bDoVSyncCorrection) {
- //LONGLONG VSyncOffset0 = (((SyncOffset) % VSyncTime) + VSyncTime) % VSyncTime;
- LONGLONG Margin = TimePerFrameMargin;
-
- LONGLONG VSyncOffsetMin = 30000000000000;
- LONGLONG VSyncOffsetMax = -30000000000000;
- for (int i = 0; i < 5; ++i) {
- VSyncOffsetMin = min(m_VSyncOffsetHistory[i], VSyncOffsetMin);
- VSyncOffsetMax = max(m_VSyncOffsetHistory[i], VSyncOffsetMax);
- }
-
- m_VSyncOffsetHistory[m_VSyncOffsetHistoryPos] = VSyncOffset0;
- m_VSyncOffsetHistoryPos = (m_VSyncOffsetHistoryPos + 1) % 5;
-
- // LONGLONG VSyncTime2 = VSyncTime2 + (VSyncOffsetMax - VSyncOffsetMin);
- //VSyncOffsetMin; = (((VSyncOffsetMin) % VSyncTime) + VSyncTime) % VSyncTime;
- //VSyncOffsetMax = (((VSyncOffsetMax) % VSyncTime) + VSyncTime) % VSyncTime;
-
- // TRACE_EVR("EVR: SyncOffset(%d, %d): %8I64d %8I64d %8I64d %8I64d\n", m_nCurSurface, m_VSyncMode,VSyncOffset0, VSyncOffsetMin, VSyncOffsetMax, VSyncOffsetMax - VSyncOffsetMin);
-
- if (m_VSyncMode == 0) {
- // 23.976 in 60 Hz
- if (VSyncOffset0 < Margin && VSyncOffsetMax > (VSyncTime - Margin)) {
- m_VSyncMode = 2;
- } else if (VSyncOffset0 > (VSyncTime - Margin) && VSyncOffsetMin < Margin) {
- m_VSyncMode = 1;
- }
- } else if (m_VSyncMode == 2) {
- if (VSyncOffsetMin > (Margin)) {
- m_VSyncMode = 0;
- }
- } else if (m_VSyncMode == 1) {
- if (VSyncOffsetMax < (VSyncTime - Margin)) {
- m_VSyncMode = 0;
- }
- }
- }
-
- }
- }
-
- m_pCurrentDisplaydSample = NULL;
- if (bStepForward) {
- MoveToFreeList(pMFSample, true);
- CheckWaitingSampleFromMixer();
- m_MaxSampleDuration = max(SampleDuration, m_MaxSampleDuration);
- } else {
- MoveToScheduledList(pMFSample, true);
- }
- } else if (m_bLastSampleOffsetValid && m_LastSampleOffset < -10000000) { // Only starve if we are 1 seconds behind
- if (m_nRenderState == Started && !g_bNoDuration) {
- m_pSink->Notify(EC_STARVATION, 0, 0);
- m_bSignaledStarvation = true;
- }
- }
- //GetImageFromMixer();
- }
- // else
- // {
- // TRACE_EVR ("EVR: RenderThread ==>> Flush before rendering frame!\n");
- // }
-
- break;
- }
- }
-
- timeEndPeriod (dwResolution);
- if (pfAvRevertMmThreadCharacteristics) {
- pfAvRevertMmThreadCharacteristics (hAvrt);
- }
+ HANDLE hEvts[] = { m_hEvtQuit, m_hEvtFlush};
+ bool bQuit = false;
+ TIMECAPS tc;
+ DWORD dwResolution;
+ MFTIME nsSampleTime;
+ LONGLONG llClockTime;
+ DWORD dwUser = 0;
+ DWORD dwObject;
+
+
+ // Tell Vista Multimedia Class Scheduler we are a playback thretad (increase priority)
+ HANDLE hAvrt = 0;
+ if (pfAvSetMmThreadCharacteristicsW) {
+ DWORD dwTaskIndex = 0;
+ hAvrt = pfAvSetMmThreadCharacteristicsW(L"Playback", &dwTaskIndex);
+ if (pfAvSetMmThreadPriority) {
+ pfAvSetMmThreadPriority(hAvrt, AVRT_PRIORITY_HIGH /*AVRT_PRIORITY_CRITICAL*/);
+ }
+ }
+
+ timeGetDevCaps(&tc, sizeof(TIMECAPS));
+ dwResolution = min(max(tc.wPeriodMin, 0), tc.wPeriodMax);
+ dwUser = timeBeginPeriod(dwResolution);
+ CRenderersSettings& s = GetRenderersSettings();
+
+ int NextSleepTime = 1;
+ while (!bQuit) {
+ LONGLONG llPerf = GetRenderersData()->GetPerfCounter();
+ UNREFERENCED_PARAMETER(llPerf);
+ if (!s.m_RenderSettings.iVMR9VSyncAccurate && NextSleepTime == 0) {
+ NextSleepTime = 1;
+ }
+ dwObject = WaitForMultipleObjects(_countof(hEvts), hEvts, FALSE, max(NextSleepTime < 0 ? 1 : NextSleepTime, 0));
+ /* dwObject = WAIT_TIMEOUT;
+ if (m_bEvtFlush)
+ dwObject = WAIT_OBJECT_0 + 1;
+ else if (m_bEvtQuit)
+ dwObject = WAIT_OBJECT_0;*/
+ // if (NextSleepTime)
+ // TRACE_EVR("EVR: Sleep: %7.3f\n", double(GetRenderersData()->GetPerfCounter()-llPerf) / 10000.0);
+ if (NextSleepTime > 1) {
+ NextSleepTime = 0;
+ } else if (NextSleepTime == 0) {
+ NextSleepTime = -1;
+ }
+ switch (dwObject) {
+ case WAIT_OBJECT_0 :
+ bQuit = true;
+ break;
+ case WAIT_OBJECT_0 + 1 :
+ // Flush pending samples!
+ FlushSamples();
+ m_bEvtFlush = false;
+ ResetEvent(m_hEvtFlush);
+ TRACE_EVR("EVR: Flush done!\n");
+ break;
+
+ case WAIT_TIMEOUT :
+
+ if (m_LastSetOutputRange != -1 && m_LastSetOutputRange != s.m_RenderSettings.iEVROutputRange || m_bPendingRenegotiate) {
+ FlushSamples();
+ RenegotiateMediaType();
+ m_bPendingRenegotiate = false;
+ }
+ if (m_bPendingResetDevice) {
+ SendResetRequest();
+ }
+
+ // Discard timer events if playback stop
+ // if ((dwObject == WAIT_OBJECT_0 + 3) && (m_nRenderState != Started)) continue;
+
+ // TRACE_EVR ("EVR: RenderThread ==>> Waiting buffer\n");
+
+ // if (WaitForMultipleObjects (_countof(hEvtsBuff), hEvtsBuff, FALSE, INFINITE) == WAIT_OBJECT_0+2)
+ {
+ CComPtr<IMFSample> pMFSample;
+ LONGLONG llPerf = GetRenderersData()->GetPerfCounter();
+ UNREFERENCED_PARAMETER(llPerf);
+ int nSamplesLeft = 0;
+ if (SUCCEEDED(GetScheduledSample(&pMFSample, nSamplesLeft))) {
+ // pMFSample->GetUINT32 (GUID_SURFACE_INDEX, (UINT32*)&m_nCurSurface);
+ m_pCurrentDisplaydSample = pMFSample;
+
+ bool bValidSampleTime = true;
+ HRESULT hGetSampleTime = pMFSample->GetSampleTime(&nsSampleTime);
+ if (hGetSampleTime != S_OK || nsSampleTime == 0) {
+ bValidSampleTime = false;
+ }
+ // We assume that all samples have the same duration
+ LONGLONG SampleDuration = 0;
+ pMFSample->GetSampleDuration(&SampleDuration);
+
+ // TRACE_EVR ("EVR: RenderThread ==>> Presenting surface %d (%I64d)\n", m_nCurSurface, nsSampleTime);
+
+ bool bStepForward = false;
+
+ if (m_nStepCount < 0) {
+ // Drop frame
+ TRACE_EVR("EVR: Dropped frame\n");
+ m_pcFrames++;
+ bStepForward = true;
+ m_nStepCount = 0;
+ /*
+ } else if (m_nStepCount > 0) {
+ pMFSample->GetUINT32(GUID_SURFACE_INDEX, (UINT32 *)&m_nCurSurface);
+ ++m_OrderedPaint;
+ if (!g_bExternalSubtitleTime) {
+ __super::SetTime (g_tSegmentStart + nsSampleTime);
+ }
+ Paint(true);
+ m_nDroppedUpdate = 0;
+ CompleteFrameStep (false);
+ bStepForward = true;
+ */
+ } else if ((m_nRenderState == Started)) {
+ LONGLONG CurrentCounter = GetRenderersData()->GetPerfCounter();
+ // Calculate wake up timer
+ if (!m_bSignaledStarvation) {
+ llClockTime = GetClockTime(CurrentCounter);
+ m_StarvationClock = llClockTime;
+ } else {
+ llClockTime = m_StarvationClock;
+ }
+
+ if (!bValidSampleTime) {
+ // Just play as fast as possible
+ bStepForward = true;
+ pMFSample->GetUINT32(GUID_SURFACE_INDEX, (UINT32*)&m_nCurSurface);
+ ++m_OrderedPaint;
+ if (!g_bExternalSubtitleTime) {
+ __super::SetTime(g_tSegmentStart + nsSampleTime);
+ }
+ Paint(true);
+ } else {
+ LONGLONG TimePerFrame = (LONGLONG)(GetFrameTime() * 10000000.0);
+ LONGLONG DrawTime = m_PaintTime * 9 / 10 - 20000; // 2 ms offset (= m_PaintTime * 0.9 - 20000)
+ //if (!s.iVMR9VSync)
+ DrawTime = 0;
+
+ LONGLONG SyncOffset = 0;
+ LONGLONG VSyncTime = 0;
+ LONGLONG TimeToNextVSync = -1;
+ bool bVSyncCorrection = false;
+ double DetectedRefreshTime;
+ double DetectedScanlinesPerFrame;
+ double DetectedScanlineTime;
+ int DetectedRefreshRatePos;
+ {
+ CAutoLock Lock(&m_RefreshRateLock);
+ DetectedRefreshTime = m_DetectedRefreshTime;
+ DetectedRefreshRatePos = m_DetectedRefreshRatePos;
+ DetectedScanlinesPerFrame = m_DetectedScanlinesPerFrame;
+ DetectedScanlineTime = m_DetectedScanlineTime;
+ }
+
+ if (DetectedRefreshRatePos < 20 || !DetectedRefreshTime || !DetectedScanlinesPerFrame) {
+ DetectedRefreshTime = 1.0 / m_RefreshRate;
+ DetectedScanlinesPerFrame = m_ScreenSize.cy;
+ DetectedScanlineTime = DetectedRefreshTime / double(m_ScreenSize.cy);
+ }
+
+ if (s.m_RenderSettings.iVMR9VSync) {
+ bVSyncCorrection = true;
+ double TargetVSyncPos = GetVBlackPos();
+ double RefreshLines = DetectedScanlinesPerFrame;
+ double ScanlinesPerSecond = 1.0 / DetectedScanlineTime;
+ double CurrentVSyncPos = fmod(double(m_VBlankStartMeasure) + ScanlinesPerSecond * ((CurrentCounter - m_VBlankStartMeasureTime) / 10000000.0), RefreshLines);
+ double LinesUntilVSync = 0;
+ //TargetVSyncPos -= ScanlinesPerSecond * (DrawTime/10000000.0);
+ //TargetVSyncPos -= 10;
+ TargetVSyncPos = fmod(TargetVSyncPos, RefreshLines);
+ if (TargetVSyncPos < 0) {
+ TargetVSyncPos += RefreshLines;
+ }
+ if (TargetVSyncPos > CurrentVSyncPos) {
+ LinesUntilVSync = TargetVSyncPos - CurrentVSyncPos;
+ } else {
+ LinesUntilVSync = (RefreshLines - CurrentVSyncPos) + TargetVSyncPos;
+ }
+ double TimeUntilVSync = LinesUntilVSync * DetectedScanlineTime;
+ TimeToNextVSync = (LONGLONG)(TimeUntilVSync * 10000000.0);
+ VSyncTime = (LONGLONG)(DetectedRefreshTime * 10000000.0);
+
+ LONGLONG ClockTimeAtNextVSync = llClockTime + (LONGLONG)(TimeUntilVSync * 10000000.0 * m_ModeratedTimeSpeed);
+
+ SyncOffset = (nsSampleTime - ClockTimeAtNextVSync);
+
+ // if (SyncOffset < 0)
+ // TRACE_EVR("EVR: SyncOffset(%d): %I64d %I64d %I64d\n", m_nCurSurface, SyncOffset, TimePerFrame, VSyncTime);
+ } else {
+ SyncOffset = (nsSampleTime - llClockTime);
+ }
+
+ //LONGLONG SyncOffset = nsSampleTime - llClockTime;
+ TRACE_EVR("EVR: SyncOffset: %I64d SampleFrame: %I64d ClockFrame: %I64d\n", SyncOffset, TimePerFrame != 0 ? nsSampleTime / TimePerFrame : 0, TimePerFrame != 0 ? llClockTime / TimePerFrame : 0);
+ if (SampleDuration > 1 && !m_DetectedLock) {
+ TimePerFrame = SampleDuration;
+ }
+
+ LONGLONG MinMargin;
+ if (m_FrameTimeCorrection && 0) {
+ MinMargin = 15000;
+ } else {
+ MinMargin = 15000 + min(LONGLONG(m_DetectedFrameTimeStdDev), 20000);
+ }
+ LONGLONG TimePerFrameMargin = min(max(TimePerFrame * 2 / 100, MinMargin), TimePerFrame * 11 / 100); // (0.02..0.11)TimePerFrame
+ LONGLONG TimePerFrameMargin0 = TimePerFrameMargin / 2;
+ LONGLONG TimePerFrameMargin1 = 0;
+
+ if (m_DetectedLock && TimePerFrame < VSyncTime) {
+ VSyncTime = TimePerFrame;
+ }
+
+ if (m_VSyncMode == 1) {
+ TimePerFrameMargin1 = -TimePerFrameMargin;
+ } else if (m_VSyncMode == 2) {
+ TimePerFrameMargin1 = TimePerFrameMargin;
+ }
+
+ m_LastSampleOffset = SyncOffset;
+ m_bLastSampleOffsetValid = true;
+
+ LONGLONG VSyncOffset0 = 0;
+ bool bDoVSyncCorrection = false;
+ if ((SyncOffset < -(TimePerFrame + TimePerFrameMargin0 - TimePerFrameMargin1)) && nSamplesLeft > 0) { // Only drop if we have something else to display at once
+ // Drop frame
+ TRACE_EVR("EVR: Dropped frame\n");
+ m_pcFrames++;
+ bStepForward = true;
+ ++m_nDroppedUpdate;
+ NextSleepTime = 0;
+ // VSyncOffset0 = (-SyncOffset) - VSyncTime;
+ //VSyncOffset0 = (-SyncOffset) - VSyncTime + TimePerFrameMargin1;
+ //m_LastPredictedSync = VSyncOffset0;
+ bDoVSyncCorrection = false;
+ } else if (SyncOffset < TimePerFrameMargin1) {
+
+ if (bVSyncCorrection) {
+ VSyncOffset0 = -SyncOffset;
+ bDoVSyncCorrection = true;
+ }
+
+ // Paint and prepare for next frame
+ TRACE_EVR("EVR: Normalframe\n");
+ m_nDroppedUpdate = 0;
+ bStepForward = true;
+ pMFSample->GetUINT32(GUID_SURFACE_INDEX, (UINT32*)&m_nCurSurface);
+ m_LastFrameDuration = nsSampleTime - m_LastSampleTime;
+ m_LastSampleTime = nsSampleTime;
+ m_LastPredictedSync = VSyncOffset0;
+
+ if (m_nStepCount > 0) {
+ CompleteFrameStep(false);
+ }
+
+ ++m_OrderedPaint;
+
+ if (!g_bExternalSubtitleTime) {
+ __super::SetTime(g_tSegmentStart + nsSampleTime);
+ }
+ Paint(true);
+
+ NextSleepTime = 0;
+ m_pcFramesDrawn++;
+ } else {
+ if (TimeToNextVSync >= 0 && SyncOffset > 0) {
+ NextSleepTime = (int)(TimeToNextVSync / 10000 - 2);
+ } else {
+ NextSleepTime = (int)(SyncOffset / 10000 - 2);
+ }
+
+ if (NextSleepTime > TimePerFrame) {
+ NextSleepTime = 1;
+ }
+
+ if (NextSleepTime < 0) {
+ NextSleepTime = 0;
+ }
+ NextSleepTime = 1;
+ //TRACE_EVR ("EVR: Delay\n");
+ }
+
+ if (bDoVSyncCorrection) {
+ //LONGLONG VSyncOffset0 = (((SyncOffset) % VSyncTime) + VSyncTime) % VSyncTime;
+ LONGLONG Margin = TimePerFrameMargin;
+
+ LONGLONG VSyncOffsetMin = 30000000000000;
+ LONGLONG VSyncOffsetMax = -30000000000000;
+ for (int i = 0; i < 5; ++i) {
+ VSyncOffsetMin = min(m_VSyncOffsetHistory[i], VSyncOffsetMin);
+ VSyncOffsetMax = max(m_VSyncOffsetHistory[i], VSyncOffsetMax);
+ }
+
+ m_VSyncOffsetHistory[m_VSyncOffsetHistoryPos] = VSyncOffset0;
+ m_VSyncOffsetHistoryPos = (m_VSyncOffsetHistoryPos + 1) % 5;
+
+ // LONGLONG VSyncTime2 = VSyncTime2 + (VSyncOffsetMax - VSyncOffsetMin);
+ //VSyncOffsetMin; = (((VSyncOffsetMin) % VSyncTime) + VSyncTime) % VSyncTime;
+ //VSyncOffsetMax = (((VSyncOffsetMax) % VSyncTime) + VSyncTime) % VSyncTime;
+
+ // TRACE_EVR("EVR: SyncOffset(%d, %d): %8I64d %8I64d %8I64d %8I64d\n", m_nCurSurface, m_VSyncMode,VSyncOffset0, VSyncOffsetMin, VSyncOffsetMax, VSyncOffsetMax - VSyncOffsetMin);
+
+ if (m_VSyncMode == 0) {
+ // 23.976 in 60 Hz
+ if (VSyncOffset0 < Margin && VSyncOffsetMax > (VSyncTime - Margin)) {
+ m_VSyncMode = 2;
+ } else if (VSyncOffset0 > (VSyncTime - Margin) && VSyncOffsetMin < Margin) {
+ m_VSyncMode = 1;
+ }
+ } else if (m_VSyncMode == 2) {
+ if (VSyncOffsetMin > (Margin)) {
+ m_VSyncMode = 0;
+ }
+ } else if (m_VSyncMode == 1) {
+ if (VSyncOffsetMax < (VSyncTime - Margin)) {
+ m_VSyncMode = 0;
+ }
+ }
+ }
+
+ }
+ }
+
+ m_pCurrentDisplaydSample = NULL;
+ if (bStepForward) {
+ MoveToFreeList(pMFSample, true);
+ CheckWaitingSampleFromMixer();
+ m_MaxSampleDuration = max(SampleDuration, m_MaxSampleDuration);
+ } else {
+ MoveToScheduledList(pMFSample, true);
+ }
+ } else if (m_bLastSampleOffsetValid && m_LastSampleOffset < -10000000) { // Only starve if we are 1 seconds behind
+ if (m_nRenderState == Started && !g_bNoDuration) {
+ m_pSink->Notify(EC_STARVATION, 0, 0);
+ m_bSignaledStarvation = true;
+ }
+ }
+ //GetImageFromMixer();
+ }
+ // else
+ // {
+ // TRACE_EVR ("EVR: RenderThread ==>> Flush before rendering frame!\n");
+ // }
+
+ break;
+ }
+ }
+
+ timeEndPeriod(dwResolution);
+ if (pfAvRevertMmThreadCharacteristics) {
+ pfAvRevertMmThreadCharacteristics(hAvrt);
+ }
}
void CEVRAllocatorPresenter::OnResetDevice()
{
- HRESULT hr;
+ HRESULT hr;
- // Reset DXVA Manager, and get new buffers
- hr = m_pD3DManager->ResetDevice(m_pD3DDev, m_nResetToken);
+ // Reset DXVA Manager, and get new buffers
+ hr = m_pD3DManager->ResetDevice(m_pD3DDev, m_nResetToken);
- // Not necessary, but Microsoft documentation say Presenter should send this message...
- if (m_pSink) {
- m_pSink->Notify (EC_DISPLAY_CHANGED, 0, 0);
- }
+ // Not necessary, but Microsoft documentation say Presenter should send this message...
+ if (m_pSink) {
+ m_pSink->Notify(EC_DISPLAY_CHANGED, 0, 0);
+ }
}
void CEVRAllocatorPresenter::RemoveAllSamples()
{
- CAutoLock AutoLock(&m_ImageProcessingLock);
+ CAutoLock AutoLock(&m_ImageProcessingLock);
- FlushSamples();
- m_ScheduledSamples.RemoveAll();
- m_FreeSamples.RemoveAll();
- m_LastScheduledSampleTime = -1;
- m_LastScheduledUncorrectedSampleTime = -1;
- m_nUsedBuffer = 0;
+ FlushSamples();
+ m_ScheduledSamples.RemoveAll();
+ m_FreeSamples.RemoveAll();
+ m_LastScheduledSampleTime = -1;
+ m_LastScheduledUncorrectedSampleTime = -1;
+ m_nUsedBuffer = 0;
}
HRESULT CEVRAllocatorPresenter::GetFreeSample(IMFSample** ppSample)
{
- CAutoLock lock(&m_SampleQueueLock);
- HRESULT hr = S_OK;
+ CAutoLock lock(&m_SampleQueueLock);
+ HRESULT hr = S_OK;
- if (m_FreeSamples.GetCount() > 1) { // <= Cannot use first free buffer (can be currently displayed)
- InterlockedIncrement (&m_nUsedBuffer);
- *ppSample = m_FreeSamples.RemoveHead().Detach();
- } else {
- hr = MF_E_SAMPLEALLOCATOR_EMPTY;
- }
+ if (m_FreeSamples.GetCount() > 1) { // <= Cannot use first free buffer (can be currently displayed)
+ InterlockedIncrement(&m_nUsedBuffer);
+ *ppSample = m_FreeSamples.RemoveHead().Detach();
+ } else {
+ hr = MF_E_SAMPLEALLOCATOR_EMPTY;
+ }
- return hr;
+ return hr;
}
-HRESULT CEVRAllocatorPresenter::GetScheduledSample(IMFSample** ppSample, int &_Count)
+HRESULT CEVRAllocatorPresenter::GetScheduledSample(IMFSample** ppSample, int& _Count)
{
- CAutoLock lock(&m_SampleQueueLock);
- HRESULT hr = S_OK;
+ CAutoLock lock(&m_SampleQueueLock);
+ HRESULT hr = S_OK;
- _Count = (int)m_ScheduledSamples.GetCount();
- if (_Count > 0) {
- *ppSample = m_ScheduledSamples.RemoveHead().Detach();
- --_Count;
- } else {
- hr = MF_E_SAMPLEALLOCATOR_EMPTY;
- }
+ _Count = (int)m_ScheduledSamples.GetCount();
+ if (_Count > 0) {
+ *ppSample = m_ScheduledSamples.RemoveHead().Detach();
+ --_Count;
+ } else {
+ hr = MF_E_SAMPLEALLOCATOR_EMPTY;
+ }
- return hr;
+ return hr;
}
void CEVRAllocatorPresenter::MoveToFreeList(IMFSample* pSample, bool bTail)
{
- CAutoLock lock(&m_SampleQueueLock);
- InterlockedDecrement (&m_nUsedBuffer);
- if (m_bPendingMediaFinished && m_nUsedBuffer == 0) {
- m_bPendingMediaFinished = false;
- m_pSink->Notify (EC_COMPLETE, 0, 0);
- }
- if (bTail) {
- m_FreeSamples.AddTail (pSample);
- } else {
- m_FreeSamples.AddHead(pSample);
- }
+ CAutoLock lock(&m_SampleQueueLock);
+ InterlockedDecrement(&m_nUsedBuffer);
+ if (m_bPendingMediaFinished && m_nUsedBuffer == 0) {
+ m_bPendingMediaFinished = false;
+ m_pSink->Notify(EC_COMPLETE, 0, 0);
+ }
+ if (bTail) {
+ m_FreeSamples.AddTail(pSample);
+ } else {
+ m_FreeSamples.AddHead(pSample);
+ }
}
void CEVRAllocatorPresenter::MoveToScheduledList(IMFSample* pSample, bool _bSorted)
{
- if (_bSorted) {
- CAutoLock lock(&m_SampleQueueLock);
- // Insert sorted
- /* POSITION Iterator = m_ScheduledSamples.GetHeadPosition();
-
- LONGLONG NewSampleTime;
- pSample->GetSampleTime(&NewSampleTime);
-
- while (Iterator != NULL)
- {
- POSITION CurrentPos = Iterator;
- IMFSample *pIter = m_ScheduledSamples.GetNext(Iterator);
- LONGLONG SampleTime;
- pIter->GetSampleTime(&SampleTime);
- if (NewSampleTime < SampleTime)
- {
- m_ScheduledSamples.InsertBefore(CurrentPos, pSample);
- return;
- }
- }*/
-
- m_ScheduledSamples.AddHead(pSample);
- } else {
-
- CAutoLock lock(&m_SampleQueueLock);
-
- CRenderersSettings& s = GetRenderersSettings();
- double ForceFPS = 0.0;
- // double ForceFPS = 59.94;
- // double ForceFPS = 23.976;
- if (ForceFPS != 0.0) {
- m_rtTimePerFrame = (REFERENCE_TIME)(10000000.0 / ForceFPS);
- }
- LONGLONG Duration = m_rtTimePerFrame;
- UNREFERENCED_PARAMETER(Duration);
- LONGLONG PrevTime = m_LastScheduledUncorrectedSampleTime;
- LONGLONG Time;
- LONGLONG SetDuration;
- pSample->GetSampleDuration(&SetDuration);
- pSample->GetSampleTime(&Time);
- m_LastScheduledUncorrectedSampleTime = Time;
-
- m_bCorrectedFrameTime = false;
-
- LONGLONG Diff2 = PrevTime - (LONGLONG)(m_LastScheduledSampleTimeFP * 10000000.0);
- LONGLONG Diff = Time - PrevTime;
- if (PrevTime == -1) {
- Diff = 0;
- }
- if (Diff < 0) {
- Diff = -Diff;
- }
- if (Diff2 < 0) {
- Diff2 = -Diff2;
- }
- if (Diff < m_rtTimePerFrame*8 && m_rtTimePerFrame && Diff2 < m_rtTimePerFrame*8) { // Detect seeking
- int iPos = (m_DetectedFrameTimePos++) % 60;
- LONGLONG Diff = Time - PrevTime;
- if (PrevTime == -1) {
- Diff = 0;
- }
- m_DetectedFrameTimeHistory[iPos] = Diff;
-
- if (m_DetectedFrameTimePos >= 10) {
- int nFrames = min(m_DetectedFrameTimePos, 60);
- LONGLONG DectedSum = 0;
- for (int i = 0; i < nFrames; ++i) {
- DectedSum += m_DetectedFrameTimeHistory[i];
- }
-
- double Average = double(DectedSum) / double(nFrames);
- double DeviationSum = 0.0;
- for (int i = 0; i < nFrames; ++i) {
- double Deviation = m_DetectedFrameTimeHistory[i] - Average;
- DeviationSum += Deviation*Deviation;
- }
-
- double StdDev = sqrt(DeviationSum/double(nFrames));
-
- m_DetectedFrameTimeStdDev = StdDev;
-
- double DetectedRate = 1.0/ (double(DectedSum) / (nFrames * 10000000.0) );
-
- double AllowedError = 0.0003;
-
- static double AllowedValues[] = {60.0, 59.94, 50.0, 48.0, 47.952, 30.0, 29.97, 25.0, 24.0, 23.976};
-
- int nAllowed = _countof(AllowedValues);
- for (int i = 0; i < nAllowed; ++i) {
- if (fabs(1.0 - DetectedRate / AllowedValues[i]) < AllowedError) {
- DetectedRate = AllowedValues[i];
- break;
- }
- }
-
- m_DetectedFrameTimeHistoryHistory[m_DetectedFrameTimePos % 500] = DetectedRate;
-
- class CAutoInt
- {
- public:
-
- int m_Int;
-
- CAutoInt() {
- m_Int = 0;
- }
- CAutoInt(int _Other) {
- m_Int = _Other;
- }
-
- operator int () const {
- return m_Int;
- }
-
- CAutoInt &operator ++ () {
- ++m_Int;
- return *this;
- }
- };
-
-
- CMap<double, double, CAutoInt, CAutoInt> Map;
-
- for (int i = 0; i < 500; ++i) {
- ++Map[m_DetectedFrameTimeHistoryHistory[i]];
- }
-
- POSITION Pos = Map.GetStartPosition();
- double BestVal = 0.0;
- int BestNum = 5;
- while (Pos) {
- double Key;
- CAutoInt Value;
- Map.GetNextAssoc(Pos, Key, Value);
- if (Value.m_Int > BestNum && Key != 0.0) {
- BestNum = Value.m_Int;
- BestVal = Key;
- }
- }
-
- m_DetectedLock = false;
- for (int i = 0; i < nAllowed; ++i) {
- if (BestVal == AllowedValues[i]) {
- m_DetectedLock = true;
- break;
- }
- }
- if (BestVal != 0.0) {
- m_DetectedFrameRate = BestVal;
- m_DetectedFrameTime = 1.0 / BestVal;
- }
- }
-
- LONGLONG PredictedNext = PrevTime + m_rtTimePerFrame;
- LONGLONG PredictedDiff = PredictedNext - Time;
- if (PredictedDiff < 0) {
- PredictedDiff = -PredictedDiff;
- }
-
- if (m_DetectedFrameTime != 0.0
- //&& PredictedDiff > 15000
- && m_DetectedLock && s.m_RenderSettings.iEVREnableFrameTimeCorrection) {
- double CurrentTime = Time / 10000000.0;
- double LastTime = m_LastScheduledSampleTimeFP;
- double PredictedTime = LastTime + m_DetectedFrameTime;
- if (fabs(PredictedTime - CurrentTime) > 0.0015) { // 1.5 ms wrong, lets correct
- CurrentTime = PredictedTime;
- Time = (LONGLONG)(CurrentTime * 10000000.0);
- pSample->SetSampleTime(Time);
- pSample->SetSampleDuration(LONGLONG(m_DetectedFrameTime * 10000000.0));
- m_bCorrectedFrameTime = true;
- m_FrameTimeCorrection = 30;
- }
- m_LastScheduledSampleTimeFP = CurrentTime;
- } else {
- m_LastScheduledSampleTimeFP = Time / 10000000.0;
- }
- } else {
- m_LastScheduledSampleTimeFP = Time / 10000000.0;
- if (Diff > m_rtTimePerFrame*8) {
- // Seek
- m_bSignaledStarvation = false;
- m_DetectedFrameTimePos = 0;
- m_DetectedLock = false;
- }
- }
-
- // TRACE_EVR("EVR: Time: %f %f %f\n", Time / 10000000.0, SetDuration / 10000000.0, m_DetectedFrameRate);
- if (!m_bCorrectedFrameTime && m_FrameTimeCorrection) {
- --m_FrameTimeCorrection;
- }
+ if (_bSorted) {
+ CAutoLock lock(&m_SampleQueueLock);
+ // Insert sorted
+ /* POSITION Iterator = m_ScheduledSamples.GetHeadPosition();
+
+ LONGLONG NewSampleTime;
+ pSample->GetSampleTime(&NewSampleTime);
+
+ while (Iterator != NULL)
+ {
+ POSITION CurrentPos = Iterator;
+ IMFSample *pIter = m_ScheduledSamples.GetNext(Iterator);
+ LONGLONG SampleTime;
+ pIter->GetSampleTime(&SampleTime);
+ if (NewSampleTime < SampleTime)
+ {
+ m_ScheduledSamples.InsertBefore(CurrentPos, pSample);
+ return;
+ }
+ }*/
+
+ m_ScheduledSamples.AddHead(pSample);
+ } else {
+
+ CAutoLock lock(&m_SampleQueueLock);
+
+ CRenderersSettings& s = GetRenderersSettings();
+ double ForceFPS = 0.0;
+ // double ForceFPS = 59.94;
+ // double ForceFPS = 23.976;
+ if (ForceFPS != 0.0) {
+ m_rtTimePerFrame = (REFERENCE_TIME)(10000000.0 / ForceFPS);
+ }
+ LONGLONG Duration = m_rtTimePerFrame;
+ UNREFERENCED_PARAMETER(Duration);
+ LONGLONG PrevTime = m_LastScheduledUncorrectedSampleTime;
+ LONGLONG Time;
+ LONGLONG SetDuration;
+ pSample->GetSampleDuration(&SetDuration);
+ pSample->GetSampleTime(&Time);
+ m_LastScheduledUncorrectedSampleTime = Time;
+
+ m_bCorrectedFrameTime = false;
+
+ LONGLONG Diff2 = PrevTime - (LONGLONG)(m_LastScheduledSampleTimeFP * 10000000.0);
+ LONGLONG Diff = Time - PrevTime;
+ if (PrevTime == -1) {
+ Diff = 0;
+ }
+ if (Diff < 0) {
+ Diff = -Diff;
+ }
+ if (Diff2 < 0) {
+ Diff2 = -Diff2;
+ }
+ if (Diff < m_rtTimePerFrame * 8 && m_rtTimePerFrame && Diff2 < m_rtTimePerFrame * 8) { // Detect seeking
+ int iPos = (m_DetectedFrameTimePos++) % 60;
+ LONGLONG Diff = Time - PrevTime;
+ if (PrevTime == -1) {
+ Diff = 0;
+ }
+ m_DetectedFrameTimeHistory[iPos] = Diff;
+
+ if (m_DetectedFrameTimePos >= 10) {
+ int nFrames = min(m_DetectedFrameTimePos, 60);
+ LONGLONG DectedSum = 0;
+ for (int i = 0; i < nFrames; ++i) {
+ DectedSum += m_DetectedFrameTimeHistory[i];
+ }
+
+ double Average = double(DectedSum) / double(nFrames);
+ double DeviationSum = 0.0;
+ for (int i = 0; i < nFrames; ++i) {
+ double Deviation = m_DetectedFrameTimeHistory[i] - Average;
+ DeviationSum += Deviation * Deviation;
+ }
+
+ double StdDev = sqrt(DeviationSum / double(nFrames));
+
+ m_DetectedFrameTimeStdDev = StdDev;
+
+ double DetectedRate = 1.0 / (double(DectedSum) / (nFrames * 10000000.0));
+
+ double AllowedError = 0.0003;
+
+ static double AllowedValues[] = {60.0, 59.94, 50.0, 48.0, 47.952, 30.0, 29.97, 25.0, 24.0, 23.976};
+
+ int nAllowed = _countof(AllowedValues);
+ for (int i = 0; i < nAllowed; ++i) {
+ if (fabs(1.0 - DetectedRate / AllowedValues[i]) < AllowedError) {
+ DetectedRate = AllowedValues[i];
+ break;
+ }
+ }
+
+ m_DetectedFrameTimeHistoryHistory[m_DetectedFrameTimePos % 500] = DetectedRate;
+
+ class CAutoInt
+ {
+ public:
+
+ int m_Int;
+
+ CAutoInt() {
+ m_Int = 0;
+ }
+ CAutoInt(int _Other) {
+ m_Int = _Other;
+ }
+
+ operator int () const {
+ return m_Int;
+ }
+
+ CAutoInt& operator ++ () {
+ ++m_Int;
+ return *this;
+ }
+ };
+
+
+ CMap<double, double, CAutoInt, CAutoInt> Map;
+
+ for (int i = 0; i < 500; ++i) {
+ ++Map[m_DetectedFrameTimeHistoryHistory[i]];
+ }
+
+ POSITION Pos = Map.GetStartPosition();
+ double BestVal = 0.0;
+ int BestNum = 5;
+ while (Pos) {
+ double Key;
+ CAutoInt Value;
+ Map.GetNextAssoc(Pos, Key, Value);
+ if (Value.m_Int > BestNum && Key != 0.0) {
+ BestNum = Value.m_Int;
+ BestVal = Key;
+ }
+ }
+
+ m_DetectedLock = false;
+ for (int i = 0; i < nAllowed; ++i) {
+ if (BestVal == AllowedValues[i]) {
+ m_DetectedLock = true;
+ break;
+ }
+ }
+ if (BestVal != 0.0) {
+ m_DetectedFrameRate = BestVal;
+ m_DetectedFrameTime = 1.0 / BestVal;
+ }
+ }
+
+ LONGLONG PredictedNext = PrevTime + m_rtTimePerFrame;
+ LONGLONG PredictedDiff = PredictedNext - Time;
+ if (PredictedDiff < 0) {
+ PredictedDiff = -PredictedDiff;
+ }
+
+ if (m_DetectedFrameTime != 0.0
+ //&& PredictedDiff > 15000
+ && m_DetectedLock && s.m_RenderSettings.iEVREnableFrameTimeCorrection) {
+ double CurrentTime = Time / 10000000.0;
+ double LastTime = m_LastScheduledSampleTimeFP;
+ double PredictedTime = LastTime + m_DetectedFrameTime;
+ if (fabs(PredictedTime - CurrentTime) > 0.0015) { // 1.5 ms wrong, lets correct
+ CurrentTime = PredictedTime;
+ Time = (LONGLONG)(CurrentTime * 10000000.0);
+ pSample->SetSampleTime(Time);
+ pSample->SetSampleDuration(LONGLONG(m_DetectedFrameTime * 10000000.0));
+ m_bCorrectedFrameTime = true;
+ m_FrameTimeCorrection = 30;
+ }
+ m_LastScheduledSampleTimeFP = CurrentTime;
+ } else {
+ m_LastScheduledSampleTimeFP = Time / 10000000.0;
+ }
+ } else {
+ m_LastScheduledSampleTimeFP = Time / 10000000.0;
+ if (Diff > m_rtTimePerFrame * 8) {
+ // Seek
+ m_bSignaledStarvation = false;
+ m_DetectedFrameTimePos = 0;
+ m_DetectedLock = false;
+ }
+ }
+
+ // TRACE_EVR("EVR: Time: %f %f %f\n", Time / 10000000.0, SetDuration / 10000000.0, m_DetectedFrameRate);
+ if (!m_bCorrectedFrameTime && m_FrameTimeCorrection) {
+ --m_FrameTimeCorrection;
+ }
#if 0
- if (Time <= m_LastScheduledUncorrectedSampleTime && m_LastScheduledSampleTime >= 0) {
- PrevTime = m_LastScheduledSampleTime;
- }
-
- m_bCorrectedFrameTime = false;
- if (PrevTime != -1 && (Time >= PrevTime - ((Duration*20)/9) || Time == 0) || ForceFPS != 0.0) {
- if (Time - PrevTime > ((Duration*20)/9) && Time - PrevTime < Duration * 8 || Time == 0 || ((Time - PrevTime) < (Duration / 11)) || ForceFPS != 0.0) {
- // Error!!!!
- Time = PrevTime + Duration;
- pSample->SetSampleTime(Time);
- pSample->SetSampleDuration(Duration);
- m_bCorrectedFrameTime = true;
- TRACE_EVR("EVR: Corrected invalid sample time\n");
- }
- }
- if (Time+Duration*10 < m_LastScheduledSampleTime) {
- // Flush when repeating movie
- FlushSamplesInternal();
- }
+ if (Time <= m_LastScheduledUncorrectedSampleTime && m_LastScheduledSampleTime >= 0) {
+ PrevTime = m_LastScheduledSampleTime;
+ }
+
+ m_bCorrectedFrameTime = false;
+ if (PrevTime != -1 && (Time >= PrevTime - ((Duration * 20) / 9) || Time == 0) || ForceFPS != 0.0) {
+ if (Time - PrevTime > ((Duration * 20) / 9) && Time - PrevTime < Duration * 8 || Time == 0 || ((Time - PrevTime) < (Duration / 11)) || ForceFPS != 0.0) {
+ // Error!!!!
+ Time = PrevTime + Duration;
+ pSample->SetSampleTime(Time);
+ pSample->SetSampleDuration(Duration);
+ m_bCorrectedFrameTime = true;
+ TRACE_EVR("EVR: Corrected invalid sample time\n");
+ }
+ }
+ if (Time + Duration * 10 < m_LastScheduledSampleTime) {
+ // Flush when repeating movie
+ FlushSamplesInternal();
+ }
#endif
#if 0
- static LONGLONG LastDuration = 0;
- LONGLONG SetDuration = m_rtTimePerFrame;
- pSample->GetSampleDuration(&SetDuration);
- if (SetDuration != LastDuration) {
- TRACE_EVR("EVR: Old duration: %I64d New duration: %I64d\n", LastDuration, SetDuration);
- }
- LastDuration = SetDuration;
+ static LONGLONG LastDuration = 0;
+ LONGLONG SetDuration = m_rtTimePerFrame;
+ pSample->GetSampleDuration(&SetDuration);
+ if (SetDuration != LastDuration) {
+ TRACE_EVR("EVR: Old duration: %I64d New duration: %I64d\n", LastDuration, SetDuration);
+ }
+ LastDuration = SetDuration;
#endif
- m_LastScheduledSampleTime = Time;
+ m_LastScheduledSampleTime = Time;
- m_ScheduledSamples.AddTail(pSample);
+ m_ScheduledSamples.AddTail(pSample);
- }
+ }
}
void CEVRAllocatorPresenter::FlushSamples()
{
- CAutoLock lock(this);
- CAutoLock lock2(&m_SampleQueueLock);
+ CAutoLock lock(this);
+ CAutoLock lock2(&m_SampleQueueLock);
- FlushSamplesInternal();
- m_LastScheduledSampleTime = -1;
+ FlushSamplesInternal();
+ m_LastScheduledSampleTime = -1;
}
void CEVRAllocatorPresenter::FlushSamplesInternal()
{
- while (m_ScheduledSamples.GetCount() > 0) {
- CComPtr<IMFSample> pMFSample;
+ while (m_ScheduledSamples.GetCount() > 0) {
+ CComPtr<IMFSample> pMFSample;
- pMFSample = m_ScheduledSamples.RemoveHead();
- MoveToFreeList (pMFSample, true);
- }
+ pMFSample = m_ScheduledSamples.RemoveHead();
+ MoveToFreeList(pMFSample, true);
+ }
- m_LastSampleOffset = 0;
- m_bLastSampleOffsetValid = false;
- m_bSignaledStarvation = false;
+ m_LastSampleOffset = 0;
+ m_bLastSampleOffsetValid = false;
+ m_bSignaledStarvation = false;
}