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')
-rw-r--r--src/filters/renderer/VideoRenderers/DX9AllocatorPresenter.cpp8
-rw-r--r--src/filters/renderer/VideoRenderers/DX9RenderingEngine.cpp21
-rw-r--r--src/filters/renderer/VideoRenderers/DXRAllocatorPresenter.cpp30
-rw-r--r--src/filters/renderer/VideoRenderers/EVRAllocatorPresenter.cpp403
-rw-r--r--src/filters/renderer/VideoRenderers/EVRAllocatorPresenter.h48
-rw-r--r--src/filters/renderer/VideoRenderers/IPinHook.cpp77
-rw-r--r--src/filters/renderer/VideoRenderers/IPinHook.h5
-rw-r--r--src/filters/renderer/VideoRenderers/RM7AllocatorPresenter.cpp7
-rw-r--r--src/filters/renderer/VideoRenderers/RenderersSettings.cpp14
-rw-r--r--src/filters/renderer/VideoRenderers/RenderersSettings.h7
-rw-r--r--src/filters/renderer/VideoRenderers/SyncRenderer.cpp258
-rw-r--r--src/filters/renderer/VideoRenderers/SyncRenderer.h39
-rw-r--r--src/filters/renderer/VideoRenderers/madVRAllocatorPresenter.cpp10
-rw-r--r--src/filters/renderer/VideoRenderers/madVRAllocatorPresenter.h11
14 files changed, 418 insertions, 520 deletions
diff --git a/src/filters/renderer/VideoRenderers/DX9AllocatorPresenter.cpp b/src/filters/renderer/VideoRenderers/DX9AllocatorPresenter.cpp
index 4a1bb1da5..46e650176 100644
--- a/src/filters/renderer/VideoRenderers/DX9AllocatorPresenter.cpp
+++ b/src/filters/renderer/VideoRenderers/DX9AllocatorPresenter.cpp
@@ -672,7 +672,7 @@ HRESULT CDX9AllocatorPresenter::CreateDevice(CString& _Error)
if (r.m_AdvRendSets.bVMR9FullscreenGUISupport && !m_bHighColorResolution) {
pp.Flags |= D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
}
- m_D3DDevExError = L"No m_pD3DEx";
+ m_D3DDevExError = _T("No m_pD3DEx");
if (!m_FocusThread) {
m_FocusThread = (CFocusThread*)AfxBeginThread(RUNTIME_CLASS(CFocusThread), 0, 0, 0);
@@ -701,7 +701,7 @@ HRESULT CDX9AllocatorPresenter::CreateDevice(CString& _Error)
&pp, &DisplayMode, &m_pD3DDevEx);
}
- m_D3DDevExError = GetWindowsErrorMessage(hr, m_hD3D9);
+ m_D3DDevExError = FAILED(hr) ? GetWindowsErrorMessage(hr, m_hD3D9) : _T("");
if (m_pD3DDevEx) {
m_pD3DDev = m_pD3DDevEx;
m_BackbufferType = pp.BackBufferFormat;
@@ -1904,7 +1904,9 @@ void CDX9AllocatorPresenter::DrawStats()
DrawText(rc, strText, 1);
OffsetRect(&rc, 0, TextHeight);
- strText.Format(L"Formats : Surface %s Backbuffer %s Display %s Device %s D3DExError: %s", GetD3DFormatStr(m_SurfaceType), GetD3DFormatStr(m_BackbufferType), GetD3DFormatStr(m_DisplayType), m_pD3DDevEx ? L"D3DDevEx" : L"D3DDev", m_D3DDevExError.GetString());
+ strText.Format(L"Formats : Surface %s Backbuffer %s Display %s Device %s %s",
+ GetD3DFormatStr(m_SurfaceType), GetD3DFormatStr(m_BackbufferType), GetD3DFormatStr(m_DisplayType),
+ m_pD3DDevEx ? L"D3DDevEx" : L"D3DDev", m_D3DDevExError.IsEmpty() ? _T("") : _T("D3DExError: ") + m_D3DDevExError);
DrawText(rc, strText, 1);
OffsetRect(&rc, 0, TextHeight);
diff --git a/src/filters/renderer/VideoRenderers/DX9RenderingEngine.cpp b/src/filters/renderer/VideoRenderers/DX9RenderingEngine.cpp
index 2890ac870..4f4704c6d 100644
--- a/src/filters/renderer/VideoRenderers/DX9RenderingEngine.cpp
+++ b/src/filters/renderer/VideoRenderers/DX9RenderingEngine.cpp
@@ -1,5 +1,5 @@
/*
- * (C) 2006-2014 see Authors.txt
+ * (C) 2006-2015 see Authors.txt
*
* This file is part of MPC-HC.
*
@@ -1365,22 +1365,22 @@ HRESULT CDX9RenderingEngine::CreateIccProfileLut(TCHAR* profilePath, float* lut3
return E_FAIL;
}
- unsigned short* lut3DOutput = nullptr;
- unsigned short* lut3DInput = nullptr;
+ uint16_t* lut3DOutput = nullptr;
+ uint16_t* lut3DInput = nullptr;
try {
// Create the 3D LUT input
- lut3DOutput = DEBUG_NEW unsigned short[m_Lut3DEntryCount * 3];
- lut3DInput = DEBUG_NEW unsigned short[m_Lut3DEntryCount * 3];
+ lut3DOutput = DEBUG_NEW uint16_t[m_Lut3DEntryCount * 3];
+ lut3DInput = DEBUG_NEW uint16_t[m_Lut3DEntryCount * 3];
- unsigned short* lut3DInputIterator = lut3DInput;
+ uint16_t* lut3DInputIterator = lut3DInput;
for (int b = 0; b < m_Lut3DSize; b++) {
for (int g = 0; g < m_Lut3DSize; g++) {
for (int r = 0; r < m_Lut3DSize; r++) {
- *lut3DInputIterator++ = r * 65535 / (m_Lut3DSize - 1);
- *lut3DInputIterator++ = g * 65535 / (m_Lut3DSize - 1);
- *lut3DInputIterator++ = b * 65535 / (m_Lut3DSize - 1);
+ *lut3DInputIterator++ = uint16_t(r * 65535 / (m_Lut3DSize - 1));
+ *lut3DInputIterator++ = uint16_t(g * 65535 / (m_Lut3DSize - 1));
+ *lut3DInputIterator++ = uint16_t(b * 65535 / (m_Lut3DSize - 1));
}
}
}
@@ -1397,9 +1397,6 @@ HRESULT CDX9RenderingEngine::CreateIccProfileLut(TCHAR* profilePath, float* lut3
delete [] lut3DOutput;
delete [] lut3DInput;
cmsDeleteTransform(hTransform);
-
- return S_OK;
-
} catch (...) {
// Cleanup
delete [] lut3DOutput;
diff --git a/src/filters/renderer/VideoRenderers/DXRAllocatorPresenter.cpp b/src/filters/renderer/VideoRenderers/DXRAllocatorPresenter.cpp
index 248e4f863..c25c3728b 100644
--- a/src/filters/renderer/VideoRenderers/DXRAllocatorPresenter.cpp
+++ b/src/filters/renderer/VideoRenderers/DXRAllocatorPresenter.cpp
@@ -1,5 +1,5 @@
/*
- * (C) 2006-2014 see Authors.txt
+ * (C) 2006-2015 see Authors.txt
*
* This file is part of MPC-HC.
*
@@ -82,26 +82,36 @@ STDMETHODIMP CDXRAllocatorPresenter::NonDelegatingQueryInterface(REFIID riid, vo
HRESULT CDXRAllocatorPresenter::SetDevice(IDirect3DDevice9* pD3DDev)
{
- CheckPointer(pD3DDev, E_POINTER);
+ HRESULT hr = S_OK;
- const CRenderersSettings& r = GetRenderersSettings();
+ if (!pD3DDev) {
+ // release all resources
+ m_pSubPicQueue = nullptr;
+ m_pAllocator = nullptr;
+ return hr;
+ }
+ const CRenderersSettings& r = GetRenderersSettings();
InitMaxSubtitleTextureSize(r.subPicQueueSettings.nMaxRes, m_ScreenSize);
if (m_pAllocator) {
m_pAllocator->ChangeDevice(pD3DDev);
} else {
m_pAllocator = DEBUG_NEW CDX9SubPicAllocator(pD3DDev, m_maxSubtitleTextureSize, true);
+ m_condAllocatorReady.notify_one();
}
- HRESULT hr = S_OK;
- if (!m_pSubPicQueue) {
+ {
+ // Lock before check because m_pSubPicQueue might be initialized in CSubPicAllocatorPresenterImpl::Connect
CAutoLock cAutoLock(this);
- m_pSubPicQueue = r.subPicQueueSettings.nSize > 0
- ? (ISubPicQueue*)DEBUG_NEW CSubPicQueue(r.subPicQueueSettings, m_pAllocator, &hr)
- : (ISubPicQueue*)DEBUG_NEW CSubPicQueueNoThread(r.subPicQueueSettings, m_pAllocator, &hr);
- } else {
- m_pSubPicQueue->Invalidate();
+ if (!m_pSubPicQueue) {
+ m_pSubPicQueue = r.subPicQueueSettings.nSize > 0
+ ? (ISubPicQueue*)DEBUG_NEW CSubPicQueue(r.subPicQueueSettings, m_pAllocator, &hr)
+ : (ISubPicQueue*)DEBUG_NEW CSubPicQueueNoThread(r.subPicQueueSettings, m_pAllocator, &hr);
+ } else {
+ this->Unlock();
+ m_pSubPicQueue->Invalidate();
+ }
}
if (SUCCEEDED(hr) && m_pSubPicProvider) {
diff --git a/src/filters/renderer/VideoRenderers/EVRAllocatorPresenter.cpp b/src/filters/renderer/VideoRenderers/EVRAllocatorPresenter.cpp
index cdc4e7749..b391bd4b3 100644
--- a/src/filters/renderer/VideoRenderers/EVRAllocatorPresenter.cpp
+++ b/src/filters/renderer/VideoRenderers/EVRAllocatorPresenter.cpp
@@ -1,5 +1,5 @@
/*
- * (C) 2006-2014 see Authors.txt
+ * (C) 2006-2015 see Authors.txt
*
* This file is part of MPC-HC.
*
@@ -26,6 +26,7 @@
#include "IPinHook.h"
#include "MacrovisionKicker.h"
#include "IMPCVideoDecFilter.h"
+#include "../../../DSUtil/ArrayUtils.h"
#if (0) // Set to 1 to activate EVR traces
#define TRACE_EVR TRACE
@@ -102,16 +103,13 @@ CEVRAllocatorPresenter::CEVRAllocatorPresenter(HWND hWnd, bool bFullscreen, HRES
, m_nStepCount(0)
, m_bSignaledStarvation(false)
, m_StarvationClock(0)
- , m_hDXVA2Lib(nullptr)
- , m_hEVRLib(nullptr)
- , m_hAVRTLib(nullptr)
- , pfDXVA2CreateDirect3DDeviceManager9(nullptr)
- , pfMFCreateDXSurfaceBuffer(nullptr)
- , pfMFCreateVideoSampleFromSurface(nullptr)
- , pfMFCreateVideoMediaType(nullptr)
- , pfAvSetMmThreadCharacteristicsW(nullptr)
- , pfAvSetMmThreadPriority(nullptr)
- , pfAvRevertMmThreadCharacteristics(nullptr)
+ , fnDXVA2CreateDirect3DDeviceManager9("dxva2.dll", "DXVA2CreateDirect3DDeviceManager9")
+ , fnMFCreateDXSurfaceBuffer("evr.dll", "MFCreateDXSurfaceBuffer")
+ , fnMFCreateVideoSampleFromSurface("evr.dll", "MFCreateVideoSampleFromSurface")
+ , fnMFCreateMediaType("mfplat.dll", "MFCreateMediaType")
+ , fnAvSetMmThreadCharacteristicsW("avrt.dll", "AvSetMmThreadCharacteristicsW")
+ , fnAvSetMmThreadPriority("avrt.dll", "AvSetMmThreadPriority")
+ , fnAvRevertMmThreadCharacteristics("avrt.dll", "AvRevertMmThreadCharacteristics")
{
const CRenderersSettings& r = GetRenderersSettings();
@@ -123,62 +121,25 @@ CEVRAllocatorPresenter::CEVRAllocatorPresenter(HWND hWnd, bool bFullscreen, HRES
return;
}
- // Load EVR specific DLLs
- m_hDXVA2Lib = LoadLibrary(L"dxva2.dll");
- if (m_hDXVA2Lib) {
- pfDXVA2CreateDirect3DDeviceManager9 = (PTR_DXVA2CreateDirect3DDeviceManager9) GetProcAddress(m_hDXVA2Lib, "DXVA2CreateDirect3DDeviceManager9");
- }
-
- // Load EVR functions
- m_hEVRLib = LoadLibrary(L"evr.dll");
- if (m_hEVRLib) {
- pfMFCreateDXSurfaceBuffer = (PTR_MFCreateDXSurfaceBuffer) GetProcAddress(m_hEVRLib, "MFCreateDXSurfaceBuffer");
- pfMFCreateVideoSampleFromSurface = (PTR_MFCreateVideoSampleFromSurface) GetProcAddress(m_hEVRLib, "MFCreateVideoSampleFromSurface");
- pfMFCreateVideoMediaType = (PTR_MFCreateVideoMediaType) GetProcAddress(m_hEVRLib, "MFCreateVideoMediaType");
- }
-
- if (!pfDXVA2CreateDirect3DDeviceManager9 || !pfMFCreateDXSurfaceBuffer || !pfMFCreateVideoSampleFromSurface || !pfMFCreateVideoMediaType) {
- if (!pfDXVA2CreateDirect3DDeviceManager9) {
+ if (!fnDXVA2CreateDirect3DDeviceManager9 || !fnMFCreateDXSurfaceBuffer || !fnMFCreateVideoSampleFromSurface || !fnMFCreateMediaType) {
+ if (!fnDXVA2CreateDirect3DDeviceManager9) {
_Error += L"Could not find DXVA2CreateDirect3DDeviceManager9 (dxva2.dll)\n";
}
- if (!pfMFCreateDXSurfaceBuffer) {
+ if (!fnMFCreateDXSurfaceBuffer) {
_Error += L"Could not find MFCreateDXSurfaceBuffer (evr.dll)\n";
}
- if (!pfMFCreateVideoSampleFromSurface) {
+ if (!fnMFCreateVideoSampleFromSurface) {
_Error += L"Could not find MFCreateVideoSampleFromSurface (evr.dll)\n";
}
- if (!pfMFCreateVideoMediaType) {
- _Error += L"Could not find MFCreateVideoMediaType (evr.dll)\n";
+ if (!fnMFCreateMediaType) {
+ _Error += L"Could not find MFCreateMediaType (mfplat.dll)\n";
}
hr = E_FAIL;
return;
}
- // Load mfplat fuctions
-#if 0
- m_hMFPlatLib = LoadLibrary(L"mfplat.dll");
- if (m_hMFPlatLib) {
- (FARPROC&)pMFCreateMediaType = GetProcAddress(m_hMFPlatLib, "MFCreateMediaType");
- (FARPROC&)pMFInitMediaTypeFromAMMediaType = GetProcAddress(m_hMFPlatLib, "MFInitMediaTypeFromAMMediaType");
- (FARPROC&)pMFInitAMMediaTypeFromMFMediaType = GetProcAddress(m_hMFPlatLib, "MFInitAMMediaTypeFromMFMediaType");
- }
-
- if (!pMFCreateMediaType || !pMFInitMediaTypeFromAMMediaType || !pMFInitAMMediaTypeFromMFMediaType) {
- hr = E_FAIL;
- return;
- }
-#endif
-
- // Load Vista+ specific DLLs
- m_hAVRTLib = LoadLibrary(L"avrt.dll");
- if (m_hAVRTLib) {
- pfAvSetMmThreadCharacteristicsW = (PTR_AvSetMmThreadCharacteristicsW) GetProcAddress(m_hAVRTLib, "AvSetMmThreadCharacteristicsW");
- pfAvSetMmThreadPriority = (PTR_AvSetMmThreadPriority) GetProcAddress(m_hAVRTLib, "AvSetMmThreadPriority");
- pfAvRevertMmThreadCharacteristics = (PTR_AvRevertMmThreadCharacteristics) GetProcAddress(m_hAVRTLib, "AvRevertMmThreadCharacteristics");
- }
-
// Init DXVA manager
- hr = pfDXVA2CreateDirect3DDeviceManager9(&m_nResetToken, &m_pD3DManager);
+ hr = fnDXVA2CreateDirect3DDeviceManager9(&m_nResetToken, &m_pD3DManager);
if (SUCCEEDED(hr) && m_pD3DManager) {
hr = m_pD3DManager->ResetDevice(m_pD3DDev, m_nResetToken);
if (FAILED(hr)) {
@@ -189,7 +150,7 @@ CEVRAllocatorPresenter::CEVRAllocatorPresenter(HWND hWnd, bool bFullscreen, HRES
HANDLE hDevice;
if (SUCCEEDED(m_pD3DManager->OpenDeviceHandle(&hDevice)) &&
SUCCEEDED(m_pD3DManager->GetVideoService(hDevice, IID_PPV_ARGS(&pDecoderService)))) {
- TRACE_EVR("EVR: DXVA2 : device handle = 0x%08x", hDevice);
+ TRACE_EVR("EVR: DXVA2 : device handle = 0x%08x\n", hDevice);
HookDirectXVideoDecoderService(pDecoderService);
m_pD3DManager->CloseDeviceHandle(hDevice);
@@ -212,16 +173,6 @@ CEVRAllocatorPresenter::~CEVRAllocatorPresenter()
m_pMediaType = nullptr;
m_pClock = nullptr;
m_pD3DManager = nullptr;
-
- if (m_hDXVA2Lib) {
- FreeLibrary(m_hDXVA2Lib);
- }
- if (m_hEVRLib) {
- FreeLibrary(m_hEVRLib);
- }
- if (m_hAVRTLib) {
- FreeLibrary(m_hAVRTLib);
- }
}
void CEVRAllocatorPresenter::ResetStats()
@@ -713,95 +664,77 @@ HRESULT CEVRAllocatorPresenter::IsMediaTypeSupported(IMFMediaType* pMixerType)
return hr;
}
-HRESULT CEVRAllocatorPresenter::CreateProposedOutputType(IMFMediaType* pMixerType, IMFMediaType** ppType)
+HRESULT CEVRAllocatorPresenter::CreateOptimalOutputType(IMFMediaType* pMixerProposedType, IMFMediaType* pMixerInputType, IMFMediaType** ppType)
{
HRESULT hr;
- AM_MEDIA_TYPE* pAMMedia = nullptr;
- LARGE_INTEGER i64Size;
- MFVIDEOFORMAT* VideoFormat;
+ IMFMediaType* pOptimalMediaType;
- CHECK_HR(pMixerType->GetRepresentation(FORMAT_MFVideoFormat, (void**)&pAMMedia));
+ CHECK_HR(fnMFCreateMediaType(&pOptimalMediaType));
+ CHECK_HR(pMixerProposedType->CopyAllItems(pOptimalMediaType));
- VideoFormat = (MFVIDEOFORMAT*)pAMMedia->pbFormat;
+ auto colorAttributes = make_array(
+ MF_MT_VIDEO_LIGHTING,
+ MF_MT_VIDEO_PRIMARIES,
+ MF_MT_TRANSFER_FUNCTION,
+ MF_MT_YUV_MATRIX,
+ MF_MT_VIDEO_CHROMA_SITING
+ );
- IMFVideoMediaType* pMediaType;
- hr = pfMFCreateVideoMediaType(VideoFormat, &pMediaType);
+ auto copyAttribute = [](IMFAttributes * pFrom, IMFAttributes * pTo, REFGUID guidKey) {
+ PROPVARIANT val;
+ HRESULT hr = pFrom->GetItem(guidKey, &val);
-#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;
+ if (SUCCEEDED(hr)) {
+ hr = pTo->SetItem(guidKey, val);
+ PropVariantClear(&val);
+ } else if (hr == MF_E_ATTRIBUTENOTFOUND) {
+ hr = pTo->DeleteItem(guidKey);
}
- }
-#endif
+ return hr;
+ };
- CSize videoSize;
- videoSize.cx = VideoFormat->videoInfo.dwWidth;
- videoSize.cy = VideoFormat->videoInfo.dwHeight;
-
- if (SUCCEEDED(hr)) {
- i64Size.HighPart = videoSize.cx;
- i64Size.LowPart = videoSize.cy;
- pMediaType->SetUINT64(MF_MT_FRAME_SIZE, i64Size.QuadPart);
-
- pMediaType->SetUINT32(MF_MT_PAN_SCAN_ENABLED, 0);
-
- const CRenderersSettings& r = GetRenderersSettings();
-
-#if 1
- if (r.m_AdvRendSets.iEVROutputRange == 1) {
- pMediaType->SetUINT32(MF_MT_VIDEO_NOMINAL_RANGE, MFNominalRange_16_235);
- } else {
- pMediaType->SetUINT32(MF_MT_VIDEO_NOMINAL_RANGE, MFNominalRange_0_255);
+ for (REFGUID guidKey : colorAttributes) {
+ if (FAILED(hr = copyAttribute(pMixerInputType, pOptimalMediaType, guidKey))) {
+ TRACE_EVR(_T("Copying color attribute %s failed: 0x%08x\n"), CComBSTR(guidKey), hr);
}
+ }
- // m_pMediaType->SetUINT32 (MF_MT_TRANSFER_FUNCTION, MFVideoTransFunc_10);
-#else
-
- pMediaType->SetUINT32(MF_MT_VIDEO_NOMINAL_RANGE, MFNominalRange_0_255);
- if (r.iEVROutputRange == 1) {
- pMediaType->SetUINT32(MF_MT_YUV_MATRIX, MFVideoTransferMatrix_BT601);
- } else {
- pMediaType->SetUINT32(MF_MT_YUV_MATRIX, MFVideoTransferMatrix_BT709);
- }
-#endif
+ pOptimalMediaType->SetUINT32(MF_MT_PAN_SCAN_ENABLED, 0);
+ const CRenderersSettings& r = GetRenderersSettings();
+ UINT32 nominalRange;
+ if (SUCCEEDED(pMixerInputType->GetUINT32(MF_MT_VIDEO_NOMINAL_RANGE, &nominalRange))
+ && nominalRange == MFNominalRange_0_255) {
+ // EVR mixer always assume 16-235 input. To ensure that luminance range won't be expanded we requests 16-235 also on output.
+ // Request 16-235 to ensure untouched luminance range on output. It is the only way to pass 0-255 without changes.
+ nominalRange = MFNominalRange_16_235;
+ m_LastSetOutputRange = -1; // -1 to prevent renegotiations because of different value than this in settings.
+ } else {
+ nominalRange = (r.m_AdvRendSets.iEVROutputRange == 1) ? MFNominalRange_16_235 : MFNominalRange_0_255;
m_LastSetOutputRange = r.m_AdvRendSets.iEVROutputRange;
+ }
+ pOptimalMediaType->SetUINT32(MF_MT_VIDEO_NOMINAL_RANGE, nominalRange);
- i64Size.HighPart = VideoFormat->videoInfo.PixelAspectRatio.Numerator;
- i64Size.LowPart = VideoFormat->videoInfo.PixelAspectRatio.Denominator;
- pMediaType->SetUINT64(MF_MT_PIXEL_ASPECT_RATIO, i64Size.QuadPart);
+ ULARGE_INTEGER ui64Size;
+ pOptimalMediaType->GetUINT64(MF_MT_FRAME_SIZE, &ui64Size.QuadPart);
- MFVideoArea Area = MakeArea(0, 0, videoSize.cx, videoSize.cy);
- pMediaType->SetBlob(MF_MT_GEOMETRIC_APERTURE, (UINT8*)&Area, sizeof(MFVideoArea));
+ CSize videoSize((LONG)ui64Size.HighPart, (LONG)ui64Size.LowPart);
+ MFVideoArea Area = MakeArea(0, 0, videoSize.cx, videoSize.cy);
+ pOptimalMediaType->SetBlob(MF_MT_GEOMETRIC_APERTURE, (UINT8*)&Area, sizeof(MFVideoArea));
- }
+ ULARGE_INTEGER ui64AspectRatio;
+ pOptimalMediaType->GetUINT64(MF_MT_PIXEL_ASPECT_RATIO, &ui64AspectRatio.QuadPart);
- UINT64 dwARx = UINT64(VideoFormat->videoInfo.PixelAspectRatio.Numerator) * videoSize.cx;
- UINT64 dwARy = UINT64(VideoFormat->videoInfo.PixelAspectRatio.Denominator) * videoSize.cy;
- UINT64 gcd = GCD(dwARx, dwARy);
+ UINT64 ui64ARx = UINT64(ui64AspectRatio.HighPart) * ui64Size.HighPart;
+ UINT64 ui64ARy = UINT64(ui64AspectRatio.LowPart) * ui64Size.LowPart;
+ UINT64 gcd = GCD(ui64ARx, ui64ARy);
if (gcd > 1) {
- dwARx /= gcd;
- dwARy /= gcd;
+ ui64ARx /= gcd;
+ ui64ARy /= gcd;
}
- CSize aspectRatio((LONG)dwARx, (LONG)dwARy);
+ CSize aspectRatio((LONG)ui64ARx, (LONG)ui64ARy);
if (videoSize != m_nativeVideoSize || aspectRatio != m_aspectRatio) {
SetVideoSize(videoSize, aspectRatio);
@@ -811,8 +744,8 @@ HRESULT CEVRAllocatorPresenter::CreateProposedOutputType(IMFMediaType* pMixerTyp
}
}
- pMixerType->FreeRepresentation(FORMAT_MFVideoFormat, (void*)pAMMedia);
- pMediaType->QueryInterface(IID_PPV_ARGS(ppType));
+ *ppType = pOptimalMediaType;
+ (*ppType)->AddRef();
return hr;
}
@@ -1000,6 +933,7 @@ HRESULT CEVRAllocatorPresenter::RenegotiateMediaType()
HRESULT hr = S_OK;
CComPtr<IMFMediaType> pMixerType;
+ CComPtr<IMFMediaType> pMixerInputType;
CComPtr<IMFMediaType> pType;
if (!m_pMixer) {
@@ -1009,13 +943,13 @@ HRESULT CEVRAllocatorPresenter::RenegotiateMediaType()
CInterfaceArray<IMFMediaType> ValidMixerTypes;
// Get the mixer's input type
- hr = m_pMixer->GetInputCurrentType(0, &pType);
+ hr = m_pMixer->GetInputCurrentType(0, &pMixerInputType);
if (SUCCEEDED(hr)) {
AM_MEDIA_TYPE* pMT;
- hr = pType->GetRepresentation(FORMAT_VideoInfo2, (void**)&pMT);
+ hr = pMixerInputType->GetRepresentation(FORMAT_VideoInfo2, (void**)&pMT);
if (SUCCEEDED(hr)) {
m_inputMediaType = *pMT;
- pType->FreeRepresentation(FORMAT_VideoInfo2, pMT);
+ pMixerInputType->FreeRepresentation(FORMAT_VideoInfo2, pMT);
}
}
@@ -1037,7 +971,7 @@ HRESULT CEVRAllocatorPresenter::RenegotiateMediaType()
}
if (SUCCEEDED(hr)) {
- hr = CreateProposedOutputType(pMixerType, &pType);
+ hr = CreateOptimalOutputType(pMixerType, pMixerInputType, &pType);
}
// Step 4. Check if the mixer will accept this media type.
@@ -1108,7 +1042,7 @@ HRESULT CEVRAllocatorPresenter::RenegotiateMediaType()
bool CEVRAllocatorPresenter::GetImageFromMixer()
{
- MFT_OUTPUT_DATA_BUFFER Buffer;
+ MFT_OUTPUT_DATA_BUFFER dataBuffer;
HRESULT hr = S_OK;
DWORD dwStatus;
REFERENCE_TIME nsSampleTime;
@@ -1127,18 +1061,20 @@ bool CEVRAllocatorPresenter::GetImageFromMixer()
break;
}
- ZeroMemory(&Buffer, sizeof(Buffer));
- Buffer.pSample = pSample;
+ ZeroMemory(&dataBuffer, sizeof(dataBuffer));
+ dataBuffer.pSample = pSample;
pSample->GetUINT32(GUID_SURFACE_INDEX, &dwSurface);
{
llClockBefore = GetRenderersData()->GetPerfCounter();
- hr = m_pMixer->ProcessOutput(0, 1, &Buffer, &dwStatus);
+ hr = m_pMixer->ProcessOutput(0, 1, &dataBuffer, &dwStatus);
llClockAfter = GetRenderersData()->GetPerfCounter();
}
if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
MoveToFreeList(pSample, false);
+ // Important: Release any events returned from the ProcessOutput method.
+ SAFE_RELEASE(dataBuffer.pEvents);
break;
}
@@ -1171,6 +1107,10 @@ bool CEVRAllocatorPresenter::GetImageFromMixer()
MoveToScheduledList(pSample, false);
bDoneSomething = true;
+
+ // Important: Release any events returned from the ProcessOutput method.
+ SAFE_RELEASE(dataBuffer.pEvents);
+
if (m_rtTimePerFrame == 0) {
break;
}
@@ -1529,10 +1469,11 @@ STDMETHODIMP CEVRAllocatorPresenter::InitializeDevice(IMFMediaType* pMediaType)
if (SUCCEEDED(hr)) {
for (int i = 0; i < m_nNbDXSurface; i++) {
CComPtr<IMFSample> pMFSample;
- hr = pfMFCreateVideoSampleFromSurface(m_pVideoSurface[i], &pMFSample);
+ hr = fnMFCreateVideoSampleFromSurface(m_pVideoSurface[i], &pMFSample);
if (SUCCEEDED(hr)) {
pMFSample->SetUINT32(GUID_SURFACE_INDEX, i);
+ CAutoLock sampleQueueLock(&m_SampleQueueLock);
m_FreeSamples.AddTail(pMFSample);
}
ASSERT(SUCCEEDED(hr));
@@ -1922,10 +1863,11 @@ STDMETHODIMP_(bool) CEVRAllocatorPresenter::ResetDevice()
for (int i = 0; i < m_nNbDXSurface; i++) {
CComPtr<IMFSample> pMFSample;
- HRESULT hr = pfMFCreateVideoSampleFromSurface(m_pVideoSurface[i], &pMFSample);
+ HRESULT hr = fnMFCreateVideoSampleFromSurface(m_pVideoSurface[i], &pMFSample);
if (SUCCEEDED(hr)) {
pMFSample->SetUINT32(GUID_SURFACE_INDEX, i);
+ CAutoLock sampleQueueLock(&m_SampleQueueLock);
m_FreeSamples.AddTail(pMFSample);
}
ASSERT(SUCCEEDED(hr));
@@ -1986,17 +1928,17 @@ void CEVRAllocatorPresenter::RenderThread()
// Tell Multimedia Class Scheduler we are a playback thread (increase priority)
HANDLE hAvrt = 0;
- if (pfAvSetMmThreadCharacteristicsW) {
+ if (fnAvSetMmThreadCharacteristicsW) {
DWORD dwTaskIndex = 0;
- hAvrt = pfAvSetMmThreadCharacteristicsW(L"Playback", &dwTaskIndex);
- if (pfAvSetMmThreadPriority) {
- pfAvSetMmThreadPriority(hAvrt, AVRT_PRIORITY_HIGH /*AVRT_PRIORITY_CRITICAL*/);
+ hAvrt = fnAvSetMmThreadCharacteristicsW(L"Playback", &dwTaskIndex);
+ if (fnAvSetMmThreadPriority) {
+ fnAvSetMmThreadPriority(hAvrt, AVRT_PRIORITY_HIGH /*AVRT_PRIORITY_CRITICAL*/);
}
}
timeGetDevCaps(&tc, sizeof(TIMECAPS));
DWORD dwResolution = std::min(std::max(tc.wPeriodMin, 0u), tc.wPeriodMax);
- DWORD dwUser = timeBeginPeriod(dwResolution);
+ VERIFY(timeBeginPeriod(dwResolution) == 0);
const CRenderersSettings& r = GetRenderersSettings();
int NextSleepTime = 1;
@@ -2059,17 +2001,16 @@ void CEVRAllocatorPresenter::RenderThread()
m_pCurrentDisplaydSample = pMFSample;
bool bValidSampleTime = true;
- HRESULT hGetSampleTime = pMFSample->GetSampleTime(&nsSampleTime);
- if (hGetSampleTime != S_OK || nsSampleTime == 0) {
+ HRESULT hrGetSampleTime = pMFSample->GetSampleTime(&nsSampleTime);
+ if (hrGetSampleTime != S_OK || nsSampleTime == 0) {
bValidSampleTime = false;
}
// We assume that all samples have the same duration
LONGLONG SampleDuration = 0;
bool bValidSampleDuration = true;
- HRESULT hGetSampleDuration = pMFSample->GetSampleDuration(&SampleDuration);
-
+ HRESULT hrGetSampleDuration = pMFSample->GetSampleDuration(&SampleDuration);
// Some filters return invalid values, ignore them
- if (hGetSampleTime != S_OK || SampleDuration <= MIN_FRAME_TIME) {
+ if (hrGetSampleDuration != S_OK || SampleDuration <= MIN_FRAME_TIME) {
bValidSampleDuration = false;
}
@@ -2341,8 +2282,8 @@ void CEVRAllocatorPresenter::RenderThread()
}
timeEndPeriod(dwResolution);
- if (pfAvRevertMmThreadCharacteristics) {
- pfAvRevertMmThreadCharacteristics(hAvrt);
+ if (fnAvRevertMmThreadCharacteristics) {
+ fnAvRevertMmThreadCharacteristics(hAvrt);
}
}
@@ -2418,86 +2359,87 @@ void CEVRAllocatorPresenter::VSyncThread()
WaitForVBlankRange(ScanlineEnd, 5, true, true, false, bTakenLock);
LONGLONG TimeEnd = rd->GetPerfCounter();
- double nSeconds = double(TimeEnd - TimeStart) / 10000000.0;
- LONGLONG DiffMiddle = TimeMiddle - TimeStart;
- LONGLONG DiffEnd = TimeEnd - TimeMiddle;
- double DiffDiff;
- if (DiffEnd > DiffMiddle) {
- DiffDiff = double(DiffEnd) / double(DiffMiddle);
- } else {
- DiffDiff = double(DiffMiddle) / double(DiffEnd);
- }
- if (nSeconds > 0.003 && DiffDiff < 1.3) {
- double ScanLineSeconds;
- double nScanLines;
- if (ScanLineMiddle > ScanlineEnd) {
- ScanLineSeconds = double(TimeMiddle - TimeStart) / 10000000.0;
- nScanLines = ScanLineMiddle - ScanlineStart;
- } else {
- ScanLineSeconds = double(TimeEnd - TimeMiddle) / 10000000.0;
- nScanLines = ScanlineEnd - ScanLineMiddle;
- }
-
- double ScanLineTime = ScanLineSeconds / nScanLines;
-
- int iPos = m_DetectedRefreshRatePos % 100;
- m_ldDetectedScanlineRateList[iPos] = ScanLineTime;
- if (m_DetectedScanlineTime && ScanlineStart != ScanlineEnd) {
- int Diff = ScanlineEnd - ScanlineStart;
- nSeconds -= double(Diff) * m_DetectedScanlineTime;
- }
- m_ldDetectedRefreshRateList[iPos] = nSeconds;
- double Average = 0;
- double AverageScanline = 0;
- int nPos = std::min(iPos + 1, 100);
- for (int i = 0; i < nPos; ++i) {
- Average += m_ldDetectedRefreshRateList[i];
- AverageScanline += m_ldDetectedScanlineRateList[i];
- }
-
- if (nPos) {
- Average /= double(nPos);
- AverageScanline /= double(nPos);
- } else {
- Average = 0;
- AverageScanline = 0;
- }
+ double nSeconds = (TimeEnd - TimeStart) / 10000000.0;
+ LONGLONG llDiffMiddle = TimeMiddle - TimeStart;
+ ASSERT(llDiffMiddle > 0);
+
+ if (nSeconds > 0.003 && llDiffMiddle > 0) {
+ double dDiffMiddle = double(llDiffMiddle);
+ double dDiffEnd = double(TimeEnd - TimeMiddle);
+
+ double dDiffDiff = dDiffEnd / dDiffMiddle;
+ if (dDiffDiff < 1.3 && dDiffDiff > (1 / 1.3)) {
+ double ScanLineSeconds;
+ double nScanLines;
+ if (ScanLineMiddle > ScanlineEnd) {
+ ScanLineSeconds = dDiffMiddle / 10000000.0;
+ nScanLines = ScanLineMiddle - ScanlineStart;
+ } else {
+ ScanLineSeconds = dDiffEnd / 10000000.0;
+ nScanLines = ScanlineEnd - ScanLineMiddle;
+ }
- double ThisValue = Average;
+ double ScanLineTime = ScanLineSeconds / nScanLines;
- if (Average > 0.0 && AverageScanline > 0.0) {
- CAutoLock Lock(&m_refreshRateLock);
- ++m_DetectedRefreshRatePos;
- if (m_DetectedRefreshTime == 0 || m_DetectedRefreshTime / ThisValue > 1.01 || m_DetectedRefreshTime / ThisValue < 0.99) {
- m_DetectedRefreshTime = ThisValue;
- m_DetectedRefreshTimePrim = 0;
- }
- if (_isnan(m_DetectedRefreshTime)) {
- m_DetectedRefreshTime = 0.0;
+ int iPos = m_DetectedRefreshRatePos % 100;
+ m_ldDetectedScanlineRateList[iPos] = ScanLineTime;
+ if (m_DetectedScanlineTime && ScanlineStart != ScanlineEnd) {
+ int Diff = ScanlineEnd - ScanlineStart;
+ nSeconds -= double(Diff) * m_DetectedScanlineTime;
}
- if (_isnan(m_DetectedRefreshTimePrim)) {
- m_DetectedRefreshTimePrim = 0.0;
+ m_ldDetectedRefreshRateList[iPos] = nSeconds;
+ double Average = 0;
+ double AverageScanline = 0;
+ int nPos = std::min(iPos + 1, 100);
+ for (int i = 0; i < nPos; ++i) {
+ Average += m_ldDetectedRefreshRateList[i];
+ AverageScanline += m_ldDetectedScanlineRateList[i];
}
- ModerateFloat(m_DetectedRefreshTime, ThisValue, m_DetectedRefreshTimePrim, 1.5);
- if (m_DetectedRefreshTime > 0.0) {
- m_DetectedRefreshRate = 1.0 / m_DetectedRefreshTime;
+ if (nPos) {
+ Average /= double(nPos);
+ AverageScanline /= double(nPos);
} else {
- m_DetectedRefreshRate = 0.0;
+ Average = 0;
+ AverageScanline = 0;
}
- if (m_DetectedScanlineTime == 0 || m_DetectedScanlineTime / AverageScanline > 1.01 || m_DetectedScanlineTime / AverageScanline < 0.99) {
- m_DetectedScanlineTime = AverageScanline;
- m_DetectedScanlineTimePrim = 0;
- }
- ModerateFloat(m_DetectedScanlineTime, AverageScanline, m_DetectedScanlineTimePrim, 1.5);
- if (m_DetectedScanlineTime > 0.0) {
- m_DetectedScanlinesPerFrame = m_DetectedRefreshTime / m_DetectedScanlineTime;
- } else {
- m_DetectedScanlinesPerFrame = 0;
+ double ThisValue = Average;
+
+ if (Average > 0.0 && AverageScanline > 0.0) {
+ CAutoLock Lock(&m_refreshRateLock);
+ ++m_DetectedRefreshRatePos;
+ if (m_DetectedRefreshTime == 0 || m_DetectedRefreshTime / ThisValue > 1.01 || m_DetectedRefreshTime / ThisValue < 0.99) {
+ m_DetectedRefreshTime = ThisValue;
+ m_DetectedRefreshTimePrim = 0;
+ }
+ if (_isnan(m_DetectedRefreshTime)) {
+ m_DetectedRefreshTime = 0.0;
+ }
+ if (_isnan(m_DetectedRefreshTimePrim)) {
+ m_DetectedRefreshTimePrim = 0.0;
+ }
+
+ ModerateFloat(m_DetectedRefreshTime, ThisValue, m_DetectedRefreshTimePrim, 1.5);
+ if (m_DetectedRefreshTime > 0.0) {
+ m_DetectedRefreshRate = 1.0 / m_DetectedRefreshTime;
+ } else {
+ m_DetectedRefreshRate = 0.0;
+ }
+
+ if (m_DetectedScanlineTime == 0 || m_DetectedScanlineTime / AverageScanline > 1.01 || m_DetectedScanlineTime / AverageScanline < 0.99) {
+ m_DetectedScanlineTime = AverageScanline;
+ m_DetectedScanlineTimePrim = 0;
+ }
+ ModerateFloat(m_DetectedScanlineTime, AverageScanline, m_DetectedScanlineTimePrim, 1.5);
+ if (m_DetectedScanlineTime > 0.0) {
+ m_DetectedScanlinesPerFrame = m_DetectedRefreshTime / m_DetectedScanlineTime;
+ } else {
+ m_DetectedScanlinesPerFrame = 0;
+ }
}
+ //TRACE(_T("Refresh: %f\n"), RefreshRate);
}
- //TRACE(_T("Refresh: %f\n"), RefreshRate);
}
}
} else {
@@ -2534,7 +2476,8 @@ void CEVRAllocatorPresenter::OnResetDevice()
void CEVRAllocatorPresenter::RemoveAllSamples()
{
- CAutoLock AutoLock(&m_ImageProcessingLock);
+ CAutoLock imageProcesssingLock(&m_ImageProcessingLock);
+ CAutoLock sampleQueueLock(&m_SampleQueueLock);
FlushSamples();
m_ScheduledSamples.RemoveAll();
diff --git a/src/filters/renderer/VideoRenderers/EVRAllocatorPresenter.h b/src/filters/renderer/VideoRenderers/EVRAllocatorPresenter.h
index eb70c61c5..292b7a4e1 100644
--- a/src/filters/renderer/VideoRenderers/EVRAllocatorPresenter.h
+++ b/src/filters/renderer/VideoRenderers/EVRAllocatorPresenter.h
@@ -1,5 +1,5 @@
/*
- * (C) 2006-2014 see Authors.txt
+ * (C) 2006-2015 see Authors.txt
*
* This file is part of MPC-HC.
*
@@ -23,25 +23,10 @@
#include "DX9AllocatorPresenter.h"
#include <mfapi.h> // API Media Foundation
#include <evr9.h>
+#include "../../../DSUtil/WinapiFunc.h"
namespace DSObjects
{
- // dxva.dll
- typedef HRESULT(__stdcall* PTR_DXVA2CreateDirect3DDeviceManager9)(UINT* pResetToken, IDirect3DDeviceManager9** ppDeviceManager);
-
- // mf.dll
- typedef HRESULT(__stdcall* PTR_MFCreatePresentationClock)(IMFPresentationClock** ppPresentationClock);
-
- // evr.dll
- typedef HRESULT(__stdcall* PTR_MFCreateDXSurfaceBuffer)(REFIID riid, IUnknown* punkSurface, BOOL fBottomUpWhenLinear, IMFMediaBuffer** ppBuffer);
- typedef HRESULT(__stdcall* PTR_MFCreateVideoSampleFromSurface)(IUnknown* pUnkSurface, IMFSample** ppSample);
- typedef HRESULT(__stdcall* PTR_MFCreateVideoMediaType)(const MFVIDEOFORMAT* pVideoFormat, IMFVideoMediaType** ppIVideoMediaType);
-
- // avrt.dll
- typedef HANDLE(__stdcall* PTR_AvSetMmThreadCharacteristicsW)(LPCWSTR TaskName, LPDWORD TaskIndex);
- typedef BOOL (__stdcall* PTR_AvSetMmThreadPriority)(HANDLE AvrtHandle, AVRT_PRIORITY Priority);
- typedef BOOL (__stdcall* PTR_AvRevertMmThreadCharacteristics)(HANDLE AvrtHandle);
-
class COuterEVR;
class CEVRAllocatorPresenter :
@@ -262,31 +247,20 @@ namespace DSObjects
// === Media type negotiation functions
HRESULT RenegotiateMediaType();
HRESULT IsMediaTypeSupported(IMFMediaType* pMixerType);
- HRESULT CreateProposedOutputType(IMFMediaType* pMixerType, IMFMediaType** pType);
+ HRESULT CreateOptimalOutputType(IMFMediaType* pMixerProposedType, IMFMediaType* pMixerInputType, IMFMediaType** pType);
HRESULT SetMediaType(IMFMediaType* pType);
HRESULT GetMediaTypeFourCC(IMFMediaType* pType, DWORD* pFourCC);
HRESULT GetMediaTypeMerit(IMFMediaType* pType, int* pMerit);
LPCTSTR GetMediaTypeFormatDesc(IMFMediaType* pMediaType);
- // === Functions pointers on Vista+ / .NET Framework 3.5 specific library
- HMODULE m_hDXVA2Lib;
- HMODULE m_hEVRLib;
- HMODULE m_hAVRTLib;
-
- PTR_DXVA2CreateDirect3DDeviceManager9 pfDXVA2CreateDirect3DDeviceManager9;
- PTR_MFCreateDXSurfaceBuffer pfMFCreateDXSurfaceBuffer;
- PTR_MFCreateVideoSampleFromSurface pfMFCreateVideoSampleFromSurface;
- PTR_MFCreateVideoMediaType pfMFCreateVideoMediaType;
-
-#if 0
- HRESULT(__stdcall* pMFCreateMediaType)(__deref_out IMFMediaType** ppMFType);
- HRESULT(__stdcall* pMFInitMediaTypeFromAMMediaType)(__in IMFMediaType* pMFType, __in const AM_MEDIA_TYPE* pAMType);
- HRESULT(__stdcall* pMFInitAMMediaTypeFromMFMediaType)(__in IMFMediaType* pMFType, __in GUID guidFormatBlockType, __inout AM_MEDIA_TYPE* pAMType);
-#endif
-
- PTR_AvSetMmThreadCharacteristicsW pfAvSetMmThreadCharacteristicsW;
- PTR_AvSetMmThreadPriority pfAvSetMmThreadPriority;
- PTR_AvRevertMmThreadCharacteristics pfAvRevertMmThreadCharacteristics;
+ const WinapiFunc<decltype(DXVA2CreateDirect3DDeviceManager9)> fnDXVA2CreateDirect3DDeviceManager9;
+ const WinapiFunc<decltype(MFCreateDXSurfaceBuffer)> fnMFCreateDXSurfaceBuffer;
+ const WinapiFunc<decltype(MFCreateVideoSampleFromSurface)> fnMFCreateVideoSampleFromSurface;
+ const WinapiFunc<decltype(MFCreateMediaType)> fnMFCreateMediaType;
+
+ const WinapiFunc<decltype(AvSetMmThreadCharacteristicsW)> fnAvSetMmThreadCharacteristicsW;
+ const WinapiFunc<decltype(AvSetMmThreadPriority)> fnAvSetMmThreadPriority;
+ const WinapiFunc<decltype(AvRevertMmThreadCharacteristics)> fnAvRevertMmThreadCharacteristics;
};
}
diff --git a/src/filters/renderer/VideoRenderers/IPinHook.cpp b/src/filters/renderer/VideoRenderers/IPinHook.cpp
index 3dc19a98e..e445a0e5b 100644
--- a/src/filters/renderer/VideoRenderers/IPinHook.cpp
+++ b/src/filters/renderer/VideoRenderers/IPinHook.cpp
@@ -1,6 +1,6 @@
/*
* (C) 2003-2006 Gabest
- * (C) 2006-2014 see Authors.txt
+ * (C) 2006-2015 see Authors.txt
*
* This file is part of MPC-HC.
*
@@ -47,6 +47,7 @@ GUID g_guidDXVADecoder = GUID_NULL;
int g_nDXVAVersion = 0;
IPinCVtbl* g_pPinCVtbl = nullptr;
+IPinCVtbl* g_pPinCVtblVideoDriverWorkAround = nullptr;
IMemInputPinCVtbl* g_pMemInputPinCVtbl = nullptr;
struct D3DFORMAT_TYPE {
@@ -152,8 +153,8 @@ static HRESULT(STDMETHODCALLTYPE* ReceiveConnectionOrg)(IPinC* This, /* [in] */
static HRESULT STDMETHODCALLTYPE ReceiveConnectionMine(IPinC* This, /* [in] */ IPinC* pConnector, /* [in] */ const AM_MEDIA_TYPE* pmt)
{
- // Force the renderer to always reject the P010 pixel format
- if (pmt && pmt->subtype == MEDIASUBTYPE_P010) {
+ // Force the renderer to always reject the P010 and P016 pixel formats
+ if (pmt && (pmt->subtype == MEDIASUBTYPE_P010 || pmt->subtype == MEDIASUBTYPE_P016)) {
return VFW_E_TYPE_NOT_ACCEPTED;
} else {
return ReceiveConnectionOrg(This, pConnector, pmt);
@@ -183,53 +184,47 @@ static HRESULT STDMETHODCALLTYPE ReceiveMine(IMemInputPinC* This, IMediaSample*
return ReceiveMineI(This, pSample);
}
-void HookWorkAroundNVIDIADriverBug(IPinC* pPinC)
+void HookWorkAroundVideoDriversBug(IBaseFilter* pBF)
{
- // Work-around a bug in NVIDIA drivers v344.11: this driver mistakenly
- // accepts P010 pixel format as input for EVR so use the pin hook to
- // add our own level of verification
-#if MPC_VERSION_MAJOR > 1 || MPC_VERSION_MINOR > 7 || MPC_VERSION_PATCH > 6
-#pragma message("WARNING: Check if this bug is fixed in currently distributed driver")
+ // Work-around a bug in some video drivers: some drivers mistakenly
+ // accepts P010 and P016 pixel formats as input for VMR/EVR renderers
+ // so use the pin hook to add our own level of verification.
+#if MPC_VERSION_MAJOR > 1 || MPC_VERSION_MINOR > 7 || MPC_VERSION_PATCH > 9
+#pragma message("WARNING: Check if this bug is fixed in currently distributed drivers")
#endif
- if (ReceiveConnectionOrg == nullptr) {
- ReceiveConnectionOrg = pPinC->lpVtbl->ReceiveConnection;
- }
- pPinC->lpVtbl->ReceiveConnection = ReceiveConnectionMine;
-}
-void UnhookWorkAroundNVIDIADriverBug()
-{
- if (g_pPinCVtbl->ReceiveConnection == ReceiveConnectionMine) {
- g_pPinCVtbl->ReceiveConnection = ReceiveConnectionOrg;
- }
- ReceiveConnectionOrg = nullptr;
-}
-
-void HookWorkAroundNVIDIADriverBug(IBaseFilter* pBF)
-{
- DWORD flOldProtect = 0;
+ if (CComPtr<IPin> pPin = GetFirstPin(pBF)) {
+ IPinC* pPinC = (IPinC*)(IPin*)pPin;
- // Unhook previous VTable
- if (g_pPinCVtbl) {
- if (VirtualProtect(g_pPinCVtbl, sizeof(IPinCVtbl), PAGE_WRITECOPY, &flOldProtect)) {
- UnhookWorkAroundNVIDIADriverBug();
- VirtualProtect(g_pPinCVtbl, sizeof(IPinCVtbl), flOldProtect, &flOldProtect);
- g_pPinCVtbl = nullptr;
+ DWORD flOldProtect = 0;
+ if (VirtualProtect(pPinC->lpVtbl, sizeof(IPinCVtbl), PAGE_WRITECOPY, &flOldProtect)) {
+ if (ReceiveConnectionOrg == nullptr) {
+ ReceiveConnectionOrg = pPinC->lpVtbl->ReceiveConnection;
+ }
+ pPinC->lpVtbl->ReceiveConnection = ReceiveConnectionMine;
+ VirtualProtect(pPinC->lpVtbl, sizeof(IPinCVtbl), flOldProtect, &flOldProtect);
+ g_pPinCVtblVideoDriverWorkAround = pPinC->lpVtbl;
} else {
- TRACE(_T("HookWorkAroundNVIDIADriverBug: Could not unhook previous VTable"));
+ TRACE(_T("HookWorkAroundVideoDriversBug: Could not hook the VTable"));
ASSERT(FALSE);
}
}
+}
- if (CComPtr<IPin> pPin = GetFirstPin(pBF)) {
- IPinC* pPinC = (IPinC*)(IPin*)pPin;
-
- if (VirtualProtect(pPinC->lpVtbl, sizeof(IPinCVtbl), PAGE_WRITECOPY, &flOldProtect)) {
- HookWorkAroundNVIDIADriverBug(pPinC);
- VirtualProtect(pPinC->lpVtbl, sizeof(IPinCVtbl), flOldProtect, &flOldProtect);
- g_pPinCVtbl = pPinC->lpVtbl;
+void UnhookWorkAroundVideoDriversBug()
+{
+ // Unhook previous VTable
+ if (g_pPinCVtblVideoDriverWorkAround) {
+ DWORD flOldProtect = 0;
+ if (VirtualProtect(g_pPinCVtblVideoDriverWorkAround, sizeof(IPinCVtbl), PAGE_WRITECOPY, &flOldProtect)) {
+ if (g_pPinCVtblVideoDriverWorkAround->ReceiveConnection == ReceiveConnectionMine) {
+ g_pPinCVtblVideoDriverWorkAround->ReceiveConnection = ReceiveConnectionOrg;
+ }
+ ReceiveConnectionOrg = nullptr;
+ VirtualProtect(g_pPinCVtblVideoDriverWorkAround, sizeof(IPinCVtbl), flOldProtect, &flOldProtect);
+ g_pPinCVtblVideoDriverWorkAround = nullptr;
} else {
- TRACE(_T("HookWorkAroundNVIDIADriverBug: Could not hook the VTable"));
+ TRACE(_T("UnhookWorkAroundVideoDriversBug: Could not unhook previous VTable"));
ASSERT(FALSE);
}
}
@@ -245,7 +240,6 @@ void UnhookNewSegmentAndReceive()
if (g_pPinCVtbl->NewSegment == NewSegmentMine) {
g_pPinCVtbl->NewSegment = NewSegmentOrg;
}
- UnhookWorkAroundNVIDIADriverBug();
VirtualProtect(g_pPinCVtbl, sizeof(IPinCVtbl), flOldProtect, &flOldProtect);
g_pPinCVtbl = nullptr;
NewSegmentOrg = nullptr;
@@ -289,7 +283,6 @@ bool HookNewSegmentAndReceive(IPinC* pPinC, IMemInputPinC* pMemInputPinC)
NewSegmentOrg = pPinC->lpVtbl->NewSegment;
}
pPinC->lpVtbl->NewSegment = NewSegmentMine; // Function sets global variable(s)
- HookWorkAroundNVIDIADriverBug(pPinC);
VirtualProtect(pPinC->lpVtbl, sizeof(IPinCVtbl), flOldProtect, &flOldProtect);
g_pPinCVtbl = pPinC->lpVtbl;
} else {
diff --git a/src/filters/renderer/VideoRenderers/IPinHook.h b/src/filters/renderer/VideoRenderers/IPinHook.h
index 1712b3e34..adb5f8d83 100644
--- a/src/filters/renderer/VideoRenderers/IPinHook.h
+++ b/src/filters/renderer/VideoRenderers/IPinHook.h
@@ -1,6 +1,6 @@
/*
* (C) 2003-2006 Gabest
- * (C) 2006-2014 see Authors.txt
+ * (C) 2006-2015 see Authors.txt
*
* This file is part of MPC-HC.
*
@@ -76,7 +76,8 @@ extern bool HookNewSegmentAndReceive(IPinC* pPinC, IMemInputPinC* pMemInputPin);
extern void UnhookNewSegmentAndReceive();
extern REFERENCE_TIME g_tSegmentStart, g_tSampleStart, g_rtTimePerFrame;
-extern void HookWorkAroundNVIDIADriverBug(IBaseFilter* pBF);
+extern void HookWorkAroundVideoDriversBug(IBaseFilter* pBF);
+extern void UnhookWorkAroundVideoDriversBug();
//
diff --git a/src/filters/renderer/VideoRenderers/RM7AllocatorPresenter.cpp b/src/filters/renderer/VideoRenderers/RM7AllocatorPresenter.cpp
index 879103f88..98a943d5a 100644
--- a/src/filters/renderer/VideoRenderers/RM7AllocatorPresenter.cpp
+++ b/src/filters/renderer/VideoRenderers/RM7AllocatorPresenter.cpp
@@ -1,6 +1,6 @@
/*
* (C) 2003-2006 Gabest
- * (C) 2006-2014 see Authors.txt
+ * (C) 2006-2015 see Authors.txt
*
* This file is part of MPC-HC.
*
@@ -87,9 +87,8 @@ HRESULT CRM7AllocatorPresenter::AllocSurfaces()
ddsd.ddpfPixelFormat.dwYUVBitCount = 16;
ddsd.ddpfPixelFormat.dwFourCC = '2YUY';
- m_pDD->CreateSurface(&ddsd, &m_pVideoSurfaceYUY2, nullptr);
-
- if (FAILED(m_pVideoSurfaceOff->Blt(nullptr, m_pVideoSurfaceYUY2, nullptr, DDBLT_WAIT, nullptr))) {
+ if (FAILED(m_pDD->CreateSurface(&ddsd, &m_pVideoSurfaceYUY2, nullptr)) ||
+ FAILED(m_pVideoSurfaceOff->Blt(nullptr, m_pVideoSurfaceYUY2, nullptr, DDBLT_WAIT, nullptr))) {
m_pVideoSurfaceYUY2 = nullptr;
}
diff --git a/src/filters/renderer/VideoRenderers/RenderersSettings.cpp b/src/filters/renderer/VideoRenderers/RenderersSettings.cpp
index 89813297e..3f04ec596 100644
--- a/src/filters/renderer/VideoRenderers/RenderersSettings.cpp
+++ b/src/filters/renderer/VideoRenderers/RenderersSettings.cpp
@@ -1,6 +1,6 @@
/*
* (C) 2003-2006 Gabest
- * (C) 2006-2014 see Authors.txt
+ * (C) 2006-2015 see Authors.txt
*
* This file is part of MPC-HC.
*
@@ -108,21 +108,15 @@ CRenderersData::CRenderersData()
// Don't disable hardware features before initializing a renderer
m_bFP16Support = true;
m_b10bitSupport = true;
+ QueryPerformanceFrequency(&llPerfFrequency);
}
LONGLONG CRenderersData::GetPerfCounter() const
{
LARGE_INTEGER i64Ticks100ns;
- LARGE_INTEGER llPerfFrequency;
- QueryPerformanceFrequency(&llPerfFrequency);
- if (llPerfFrequency.QuadPart != 0) {
- QueryPerformanceCounter(&i64Ticks100ns);
- return llMulDiv(i64Ticks100ns.QuadPart, 10000000, llPerfFrequency.QuadPart, 0);
- } else {
- // ms to 100ns units
- return LONGLONG(timeGetTime()) * 10000;
- }
+ QueryPerformanceCounter(&i64Ticks100ns);
+ return llMulDiv(i64Ticks100ns.QuadPart, 10000000, llPerfFrequency.QuadPart, 0);
}
HINSTANCE CRenderersData::GetD3X9Dll()
diff --git a/src/filters/renderer/VideoRenderers/RenderersSettings.h b/src/filters/renderer/VideoRenderers/RenderersSettings.h
index c8c9e60cc..2e57c929a 100644
--- a/src/filters/renderer/VideoRenderers/RenderersSettings.h
+++ b/src/filters/renderer/VideoRenderers/RenderersSettings.h
@@ -1,6 +1,6 @@
/*
* (C) 2003-2006 Gabest
- * (C) 2006-2014 see Authors.txt
+ * (C) 2006-2015 see Authors.txt
*
* This file is part of MPC-HC.
*
@@ -131,8 +131,9 @@ public:
class CRenderersData
{
- HINSTANCE m_hD3DX9Dll;
- UINT m_nDXSdkRelease;
+ HINSTANCE m_hD3DX9Dll;
+ UINT m_nDXSdkRelease;
+ LARGE_INTEGER llPerfFrequency;
public:
CRenderersData();
diff --git a/src/filters/renderer/VideoRenderers/SyncRenderer.cpp b/src/filters/renderer/VideoRenderers/SyncRenderer.cpp
index cc25407b7..e4c13b406 100644
--- a/src/filters/renderer/VideoRenderers/SyncRenderer.cpp
+++ b/src/filters/renderer/VideoRenderers/SyncRenderer.cpp
@@ -1,5 +1,5 @@
/*
- * (C) 2010-2014 see Authors.txt
+ * (C) 2010-2015 see Authors.txt
*
* This file is part of MPC-HC.
*
@@ -45,6 +45,7 @@
#include "SyncRenderer.h"
#include "version.h"
#include "FocusThread.h"
+#include "../../../DSUtil/ArrayUtils.h"
// only for debugging
//#define DISABLE_USING_D3D9EX
@@ -79,7 +80,7 @@ CBaseAP::CBaseAP(HWND hWnd, bool bFullscreen, HRESULT& hr, CString& _Error)
, m_pAudioStats(nullptr)
, m_nNextJitter(0)
, m_nNextSyncOffset(0)
- , m_llLastSyncTime(0)
+ , m_llLastSyncTime(LONGLONG_ERROR)
, m_fAvrFps(0.0)
, m_fJitterStdDev(0.0)
, m_fSyncOffsetStdDev(0.0)
@@ -381,6 +382,7 @@ void CBaseAP::ResetStats()
m_MaxSyncOffset = MINLONG64;
m_uSyncGlitches = 0;
m_pcFramesDropped = 0;
+ m_llLastSyncTime = LONGLONG_ERROR;
}
bool CBaseAP::SettingsNeedResetDevice()
@@ -711,14 +713,13 @@ HRESULT CBaseAP::ResetDXDevice(CString& _Error)
CComPtr<IEnumPins> rendererInputEnum;
std::vector<CComPtr<IPin>> decoderOutput;
std::vector<CComPtr<IPin>> rendererInput;
- FILTER_INFO filterInfo;
- ZeroMemory(&filterInfo, sizeof(filterInfo));
+ CFilterInfo filterInfo;
- bool disconnected = FALSE;
+ bool disconnected = false;
// Disconnect all pins to release video memory resources
if (m_pD3DDev) {
- m_pOuterEVR->QueryFilterInfo(&filterInfo); // This addref's the pGraph member
+ m_pOuterEVR->QueryFilterInfo(&filterInfo);
if (SUCCEEDED(m_pOuterEVR->EnumPins(&rendererInputEnum))) {
CComPtr<IPin> input;
CComPtr<IPin> output;
@@ -735,13 +736,15 @@ HRESULT CBaseAP::ResetDXDevice(CString& _Error)
} else {
return hr;
}
- for (DWORD i = 0; i < decoderOutput.size(); i++) {
- TRACE(_T("Disconnecting pin\n"));
- filterInfo.pGraph->Disconnect(decoderOutput.at(i).p);
- filterInfo.pGraph->Disconnect(rendererInput.at(i).p);
- TRACE(_T("Pin disconnected\n"));
+ if (filterInfo.pGraph) {
+ for (size_t i = 0; i < decoderOutput.size(); i++) {
+ TRACE(_T("Disconnecting pin\n"));
+ filterInfo.pGraph->Disconnect(decoderOutput[i].p);
+ filterInfo.pGraph->Disconnect(rendererInput[i].p);
+ TRACE(_T("Pin disconnected\n"));
+ }
+ disconnected = true;
}
- disconnected = true;
}
// Release more resources
@@ -859,15 +862,11 @@ HRESULT CBaseAP::ResetDXDevice(CString& _Error)
}
if (disconnected) {
- for (DWORD i = 0; i < decoderOutput.size(); i++) {
- if (FAILED(filterInfo.pGraph->ConnectDirect(decoderOutput.at(i).p, rendererInput.at(i).p, nullptr))) {
+ for (size_t i = 0; i < decoderOutput.size(); i++) {
+ if (FAILED(filterInfo.pGraph->ConnectDirect(decoderOutput[i].p, rendererInput[i].p, nullptr))) {
return hr;
}
}
-
- if (filterInfo.pGraph != nullptr) {
- filterInfo.pGraph->Release();
- }
}
m_pPSC.Attach(DEBUG_NEW CPixelShaderCompiler(m_pD3DDev, true));
@@ -1461,6 +1460,10 @@ HRESULT CBaseAP::AlphaBlt(RECT* pSrc, const RECT* pDst, IDirect3DTexture9* pText
// Update the array m_pllJitter with a new vsync period. Calculate min, max and stddev.
void CBaseAP::SyncStats(LONGLONG syncTime)
{
+ if (m_llLastSyncTime == LONGLONG_ERROR) {
+ m_llLastSyncTime = syncTime;
+ }
+
m_nNextJitter = (m_nNextJitter + 1) % NB_JITTER;
LONGLONG jitter = syncTime - m_llLastSyncTime;
m_pllJitter[m_nNextJitter] = jitter;
@@ -2401,9 +2404,6 @@ STDMETHODIMP CBaseAP::SetPixelShader2(LPCSTR pSrcData, LPCSTR pTarget, bool bScr
CSyncAP::CSyncAP(HWND hWnd, bool bFullscreen, HRESULT& hr, CString& _Error)
: CBaseAP(hWnd, bFullscreen, hr, _Error)
- , m_hDXVA2Lib(nullptr)
- , m_hEVRLib(nullptr)
- , m_hAVRTLib(nullptr)
, m_nResetToken(0)
, m_hRenderThread(nullptr)
, m_hMixerThread(nullptr)
@@ -2426,13 +2426,13 @@ CSyncAP::CSyncAP(HWND hWnd, bool bFullscreen, HRESULT& hr, CString& _Error)
, m_bPrerolled(false)
, m_LastClockState(MFCLOCK_STATE_INVALID)
, m_bEvtSkip(false)
- , pfDXVA2CreateDirect3DDeviceManager9(nullptr)
- , pfMFCreateDXSurfaceBuffer(nullptr)
- , pfMFCreateVideoSampleFromSurface(nullptr)
- , pfMFCreateVideoMediaType(nullptr)
- , pfAvSetMmThreadCharacteristicsW(nullptr)
- , pfAvSetMmThreadPriority(nullptr)
- , pfAvRevertMmThreadCharacteristics(nullptr)
+ , fnDXVA2CreateDirect3DDeviceManager9("dxva2.dll", "DXVA2CreateDirect3DDeviceManager9")
+ , fnMFCreateDXSurfaceBuffer("evr.dll", "MFCreateDXSurfaceBuffer")
+ , fnMFCreateVideoSampleFromSurface("evr.dll", "MFCreateVideoSampleFromSurface")
+ , fnMFCreateMediaType("mfplat.dll", "MFCreateMediaType")
+ , fnAvSetMmThreadCharacteristicsW("avrt.dll", "AvSetMmThreadCharacteristicsW")
+ , fnAvSetMmThreadPriority("avrt.dll", "AvSetMmThreadPriority")
+ , fnAvRevertMmThreadCharacteristics("avrt.dll", "AvRevertMmThreadCharacteristics")
{
const CRenderersSettings& r = GetRenderersSettings();
@@ -2441,47 +2441,25 @@ CSyncAP::CSyncAP(HWND hWnd, bool bFullscreen, HRESULT& hr, CString& _Error)
return;
}
- // Load EVR specific DLLs
- m_hDXVA2Lib = LoadLibrary(L"dxva2.dll");
- if (m_hDXVA2Lib) {
- pfDXVA2CreateDirect3DDeviceManager9 = (PTR_DXVA2CreateDirect3DDeviceManager9) GetProcAddress(m_hDXVA2Lib, "DXVA2CreateDirect3DDeviceManager9");
- }
-
- // Load EVR functions
- m_hEVRLib = LoadLibrary(L"evr.dll");
- if (m_hEVRLib) {
- pfMFCreateDXSurfaceBuffer = (PTR_MFCreateDXSurfaceBuffer)GetProcAddress(m_hEVRLib, "MFCreateDXSurfaceBuffer");
- pfMFCreateVideoSampleFromSurface = (PTR_MFCreateVideoSampleFromSurface)GetProcAddress(m_hEVRLib, "MFCreateVideoSampleFromSurface");
- pfMFCreateVideoMediaType = (PTR_MFCreateVideoMediaType)GetProcAddress(m_hEVRLib, "MFCreateVideoMediaType");
- }
-
- if (!pfDXVA2CreateDirect3DDeviceManager9 || !pfMFCreateDXSurfaceBuffer || !pfMFCreateVideoSampleFromSurface || !pfMFCreateVideoMediaType) {
- if (!pfDXVA2CreateDirect3DDeviceManager9) {
+ if (!fnDXVA2CreateDirect3DDeviceManager9 || !fnMFCreateDXSurfaceBuffer || !fnMFCreateVideoSampleFromSurface || !fnMFCreateMediaType) {
+ if (!fnDXVA2CreateDirect3DDeviceManager9) {
_Error += L"Could not find DXVA2CreateDirect3DDeviceManager9 (dxva2.dll)\n";
}
- if (!pfMFCreateDXSurfaceBuffer) {
+ if (!fnMFCreateDXSurfaceBuffer) {
_Error += L"Could not find MFCreateDXSurfaceBuffer (evr.dll)\n";
}
- if (!pfMFCreateVideoSampleFromSurface) {
+ if (!fnMFCreateVideoSampleFromSurface) {
_Error += L"Could not find MFCreateVideoSampleFromSurface (evr.dll)\n";
}
- if (!pfMFCreateVideoMediaType) {
- _Error += L"Could not find MFCreateVideoMediaType (evr.dll)\n";
+ if (!fnMFCreateMediaType) {
+ _Error += L"Could not find MFCreateMediaType (mfplat.dll)\n";
}
hr = E_FAIL;
return;
}
- // Load Vista+ specific DLLs
- m_hAVRTLib = LoadLibrary(L"avrt.dll");
- if (m_hAVRTLib) {
- pfAvSetMmThreadCharacteristicsW = (PTR_AvSetMmThreadCharacteristicsW) GetProcAddress(m_hAVRTLib, "AvSetMmThreadCharacteristicsW");
- pfAvSetMmThreadPriority = (PTR_AvSetMmThreadPriority) GetProcAddress(m_hAVRTLib, "AvSetMmThreadPriority");
- pfAvRevertMmThreadCharacteristics = (PTR_AvRevertMmThreadCharacteristics) GetProcAddress(m_hAVRTLib, "AvRevertMmThreadCharacteristics");
- }
-
// Init DXVA manager
- hr = pfDXVA2CreateDirect3DDeviceManager9(&m_nResetToken, &m_pD3DManager);
+ hr = fnDXVA2CreateDirect3DDeviceManager9(&m_nResetToken, &m_pD3DManager);
if (SUCCEEDED(hr) && m_pD3DManager) {
hr = m_pD3DManager->ResetDevice(m_pD3DDev, m_nResetToken);
if (FAILED(hr)) {
@@ -2515,16 +2493,6 @@ CSyncAP::~CSyncAP()
m_pMediaType = nullptr;
m_pClock = nullptr;
m_pD3DManager = nullptr;
-
- if (m_hDXVA2Lib) {
- FreeLibrary(m_hDXVA2Lib);
- }
- if (m_hEVRLib) {
- FreeLibrary(m_hEVRLib);
- }
- if (m_hAVRTLib) {
- FreeLibrary(m_hAVRTLib);
- }
}
HRESULT CSyncAP::CheckShutdown() const
@@ -2940,52 +2908,78 @@ HRESULT CSyncAP::IsMediaTypeSupported(IMFMediaType* pMixerType)
return hr;
}
-HRESULT CSyncAP::CreateProposedOutputType(IMFMediaType* pMixerType, IMFMediaType** ppType)
+HRESULT CSyncAP::CreateOptimalOutputType(IMFMediaType* pMixerProposedType, IMFMediaType* pMixerInputType, IMFMediaType** ppType)
{
HRESULT hr;
- AM_MEDIA_TYPE* pAMMedia = nullptr;
- LARGE_INTEGER i64Size;
- MFVIDEOFORMAT* VideoFormat;
+ IMFMediaType* pOptimalMediaType;
- CHECK_HR(pMixerType->GetRepresentation(FORMAT_MFVideoFormat, (void**)&pAMMedia));
+ CHECK_HR(fnMFCreateMediaType(&pOptimalMediaType));
+ CHECK_HR(pMixerProposedType->CopyAllItems(pOptimalMediaType));
- VideoFormat = (MFVIDEOFORMAT*)pAMMedia->pbFormat;
- hr = pfMFCreateVideoMediaType(VideoFormat, &m_pMediaType);
+ auto colorAttributes = make_array(
+ MF_MT_VIDEO_LIGHTING,
+ MF_MT_VIDEO_PRIMARIES,
+ MF_MT_TRANSFER_FUNCTION,
+ MF_MT_YUV_MATRIX,
+ MF_MT_VIDEO_CHROMA_SITING
+ );
- CSize videoSize;
- videoSize.cx = VideoFormat->videoInfo.dwWidth;
- videoSize.cy = VideoFormat->videoInfo.dwHeight;
+ auto copyAttribute = [](IMFAttributes * pFrom, IMFAttributes * pTo, REFGUID guidKey) {
+ PROPVARIANT val;
+ HRESULT hr = pFrom->GetItem(guidKey, &val);
- if (SUCCEEDED(hr)) {
- i64Size.HighPart = videoSize.cx;
- i64Size.LowPart = videoSize.cy;
- m_pMediaType->SetUINT64(MF_MT_FRAME_SIZE, i64Size.QuadPart);
- m_pMediaType->SetUINT32(MF_MT_PAN_SCAN_ENABLED, 0);
- const CRenderersSettings& r = GetRenderersSettings();
+ if (SUCCEEDED(hr)) {
+ hr = pTo->SetItem(guidKey, val);
+ PropVariantClear(&val);
+ } else if (hr == MF_E_ATTRIBUTENOTFOUND) {
+ hr = pTo->DeleteItem(guidKey);
+ }
+ return hr;
+ };
- if (r.m_AdvRendSets.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);
+ for (REFGUID guidKey : colorAttributes) {
+ if (FAILED(hr = copyAttribute(pMixerInputType, pOptimalMediaType, guidKey))) {
+ TRACE(_T("Copying color attribute %s failed: 0x%08x\n"), CComBSTR(guidKey), hr);
}
+ }
- m_LastSetOutputRange = r.m_AdvRendSets.iEVROutputRange;
- i64Size.HighPart = VideoFormat->videoInfo.PixelAspectRatio.Numerator;
- i64Size.LowPart = VideoFormat->videoInfo.PixelAspectRatio.Denominator;
- m_pMediaType->SetUINT64(MF_MT_PIXEL_ASPECT_RATIO, i64Size.QuadPart);
+ pOptimalMediaType->SetUINT32(MF_MT_PAN_SCAN_ENABLED, 0);
- MFVideoArea Area = GetArea(0, 0, videoSize.cx, videoSize.cy);
- m_pMediaType->SetBlob(MF_MT_GEOMETRIC_APERTURE, (UINT8*)&Area, sizeof(MFVideoArea));
+ const CRenderersSettings& r = GetRenderersSettings();
+
+ UINT32 nominalRange;
+ if (SUCCEEDED(pMixerInputType->GetUINT32(MF_MT_VIDEO_NOMINAL_RANGE, &nominalRange))
+ && nominalRange == MFNominalRange_0_255) {
+ // EVR mixer always assume 16-235 input. To ensure that luminance range won't be expanded we requests 16-235 also on output.
+ // Request 16-235 to ensure untouched luminance range on output. It is the only way to pass 0-255 without changes.
+ nominalRange = MFNominalRange_16_235;
+ m_LastSetOutputRange = -1; // -1 to prevent renegotiations because of different value than this in settings.
+ } else {
+ nominalRange = (r.m_AdvRendSets.iEVROutputRange == 1) ? MFNominalRange_16_235 : MFNominalRange_0_255;
+ m_LastSetOutputRange = r.m_AdvRendSets.iEVROutputRange;
}
+ pOptimalMediaType->SetUINT32(MF_MT_VIDEO_NOMINAL_RANGE, nominalRange);
+
+ m_LastSetOutputRange = r.m_AdvRendSets.iEVROutputRange;
- UINT64 dwARx = UINT64(VideoFormat->videoInfo.PixelAspectRatio.Numerator) * videoSize.cx;
- UINT64 dwARy = UINT64(VideoFormat->videoInfo.PixelAspectRatio.Denominator) * videoSize.cy;
- UINT64 gcd = GCD(dwARx, dwARy);
+ ULARGE_INTEGER ui64Size;
+ pOptimalMediaType->GetUINT64(MF_MT_FRAME_SIZE, &ui64Size.QuadPart);
+
+ CSize videoSize((LONG)ui64Size.HighPart, (LONG)ui64Size.LowPart);
+ MFVideoArea Area = GetArea(0, 0, videoSize.cx, videoSize.cy);
+ pOptimalMediaType->SetBlob(MF_MT_GEOMETRIC_APERTURE, (UINT8*)&Area, sizeof(MFVideoArea));
+
+ ULARGE_INTEGER ui64AspectRatio;
+ pOptimalMediaType->GetUINT64(MF_MT_PIXEL_ASPECT_RATIO, &ui64AspectRatio.QuadPart);
+
+ UINT64 ui64ARx = UINT64(ui64AspectRatio.HighPart) * ui64Size.HighPart;
+ UINT64 ui64ARy = UINT64(ui64AspectRatio.LowPart) * ui64Size.LowPart;
+ UINT64 gcd = GCD(ui64ARx, ui64ARy);
if (gcd > 1) {
- dwARx /= gcd;
- dwARy /= gcd;
+ ui64ARx /= gcd;
+ ui64ARy /= gcd;
}
- CSize aspectRatio((LONG)dwARx, (LONG)dwARy);
+ CSize aspectRatio((LONG)ui64ARx, (LONG)ui64ARy);
if (videoSize != m_nativeVideoSize || aspectRatio != m_aspectRatio) {
SetVideoSize(videoSize, aspectRatio);
@@ -2996,8 +2990,8 @@ HRESULT CSyncAP::CreateProposedOutputType(IMFMediaType* pMixerType, IMFMediaType
}
}
- pMixerType->FreeRepresentation(FORMAT_MFVideoFormat, (void*)pAMMedia);
- m_pMediaType->QueryInterface(IID_PPV_ARGS(ppType));
+ *ppType = pOptimalMediaType;
+ (*ppType)->AddRef();
return hr;
}
@@ -3013,6 +3007,9 @@ HRESULT CSyncAP::SetMediaType(IMFMediaType* pType)
hr = InitializeDevice(pAMMedia);
if (SUCCEEDED(hr)) {
+ CAutoLock lock(this);
+ m_pMediaType = pType;
+
strTemp = GetMediaTypeName(pAMMedia->subtype);
strTemp.Replace(L"MEDIASUBTYPE_", L"");
m_strStatsMsg[MSG_MIXEROUT].Format(L"Mixer output : %s", strTemp);
@@ -3066,6 +3063,7 @@ HRESULT CSyncAP::RenegotiateMediaType()
HRESULT hr = S_OK;
CComPtr<IMFMediaType> pMixerType;
+ CComPtr<IMFMediaType> pMixerInputType;
CComPtr<IMFMediaType> pType;
if (!m_pMixer) {
@@ -3073,13 +3071,13 @@ HRESULT CSyncAP::RenegotiateMediaType()
}
// Get the mixer's input type
- hr = m_pMixer->GetInputCurrentType(0, &pType);
+ hr = m_pMixer->GetInputCurrentType(0, &pMixerInputType);
if (SUCCEEDED(hr)) {
AM_MEDIA_TYPE* pMT;
- hr = pType->GetRepresentation(FORMAT_VideoInfo2, (void**)&pMT);
+ hr = pMixerInputType->GetRepresentation(FORMAT_VideoInfo2, (void**)&pMT);
if (SUCCEEDED(hr)) {
m_inputMediaType = *pMT;
- pType->FreeRepresentation(FORMAT_VideoInfo2, pMT);
+ pMixerInputType->FreeRepresentation(FORMAT_VideoInfo2, pMT);
}
}
@@ -3089,7 +3087,6 @@ HRESULT CSyncAP::RenegotiateMediaType()
while ((hr != MF_E_NO_MORE_TYPES)) {
pMixerType = nullptr;
pType = nullptr;
- m_pMediaType = nullptr;
// Step 1. Get the next media type supported by mixer.
hr = m_pMixer->GetOutputAvailableType(0, iTypeIndex++, &pMixerType);
@@ -3101,7 +3098,7 @@ HRESULT CSyncAP::RenegotiateMediaType()
hr = IsMediaTypeSupported(pMixerType);
}
if (SUCCEEDED(hr)) {
- hr = CreateProposedOutputType(pMixerType, &pType);
+ hr = CreateOptimalOutputType(pMixerType, pMixerInputType, &pType);
}
// Step 4. Check if the mixer will accept this media type.
if (SUCCEEDED(hr)) {
@@ -3151,7 +3148,7 @@ HRESULT CSyncAP::RenegotiateMediaType()
bool CSyncAP::GetSampleFromMixer()
{
- MFT_OUTPUT_DATA_BUFFER Buffer;
+ MFT_OUTPUT_DATA_BUFFER dataBuffer;
HRESULT hr = S_OK;
DWORD dwStatus;
LONGLONG llClockBefore = 0;
@@ -3168,17 +3165,19 @@ bool CSyncAP::GetSampleFromMixer()
break;
}
- ZeroMemory(&Buffer, sizeof(Buffer));
- Buffer.pSample = pSample;
+ ZeroMemory(&dataBuffer, sizeof(dataBuffer));
+ dataBuffer.pSample = pSample;
pSample->GetUINT32(GUID_SURFACE_INDEX, &dwSurface);
{
llClockBefore = GetRenderersData()->GetPerfCounter();
- hr = m_pMixer->ProcessOutput(0 , 1, &Buffer, &dwStatus);
+ hr = m_pMixer->ProcessOutput(0 , 1, &dataBuffer, &dwStatus);
llClockAfter = GetRenderersData()->GetPerfCounter();
}
if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) { // There are no samples left in the mixer
MoveToFreeList(pSample, false);
+ // Important: Release any events returned from the ProcessOutput method.
+ SAFE_RELEASE(dataBuffer.pEvents);
break;
}
if (m_pSink) {
@@ -3203,6 +3202,8 @@ bool CSyncAP::GetSampleFromMixer()
m_nTearingPos = (m_nTearingPos + 7) % m_nativeVideoSize.cx;
}
MoveToScheduledList(pSample, false); // Schedule, then go back to see if there is more where that came from
+ // Important: Release any events returned from the ProcessOutput method.
+ SAFE_RELEASE(dataBuffer.pEvents);
}
return newSample;
}
@@ -3532,9 +3533,10 @@ STDMETHODIMP CSyncAP::InitializeDevice(AM_MEDIA_TYPE* pMediaType)
for (int i = 0; i < m_nDXSurface; i++) {
CComPtr<IMFSample> pMFSample;
- hr = pfMFCreateVideoSampleFromSurface(m_pVideoSurface[i], &pMFSample);
+ hr = fnMFCreateVideoSampleFromSurface(m_pVideoSurface[i], &pMFSample);
if (SUCCEEDED(hr)) {
pMFSample->SetUINT32(GUID_SURFACE_INDEX, i);
+ CAutoLock sampleQueueLock(&m_SampleQueueLock);
m_FreeSamples.AddTail(pMFSample);
}
ASSERT(SUCCEEDED(hr));
@@ -3617,18 +3619,18 @@ void CSyncAP::RenderThread()
// Tell Multimedia Class Scheduler we are doing threaded playback (increase priority)
HANDLE hAvrt = 0;
- if (pfAvSetMmThreadCharacteristicsW) {
+ if (fnAvSetMmThreadCharacteristicsW) {
DWORD dwTaskIndex = 0;
- hAvrt = pfAvSetMmThreadCharacteristicsW(L"Playback", &dwTaskIndex);
- if (pfAvSetMmThreadPriority) {
- pfAvSetMmThreadPriority(hAvrt, AVRT_PRIORITY_HIGH);
+ hAvrt = fnAvSetMmThreadCharacteristicsW(L"Playback", &dwTaskIndex);
+ if (fnAvSetMmThreadPriority) {
+ fnAvSetMmThreadPriority(hAvrt, AVRT_PRIORITY_HIGH);
}
}
// Set timer resolution
timeGetDevCaps(&tc, sizeof(TIMECAPS));
DWORD dwResolution = std::min(std::max(tc.wPeriodMin, 0u), tc.wPeriodMax);
- DWORD dwUser = timeBeginPeriod(dwResolution);
+ VERIFY(timeBeginPeriod(dwResolution) == 0);
pNewSample = nullptr;
while (!bQuit) {
@@ -3808,8 +3810,8 @@ void CSyncAP::RenderThread()
pNewSample = nullptr;
}
timeEndPeriod(dwResolution);
- if (pfAvRevertMmThreadCharacteristics) {
- pfAvRevertMmThreadCharacteristics(hAvrt);
+ if (fnAvRevertMmThreadCharacteristics) {
+ fnAvRevertMmThreadCharacteristics(hAvrt);
}
}
@@ -3818,15 +3820,17 @@ STDMETHODIMP_(bool) CSyncAP::ResetDevice()
CAutoLock lock(this);
CAutoLock lock2(&m_ImageProcessingLock);
CAutoLock cRenderLock(&m_allocatorLock);
+
RemoveAllSamples();
bool bResult = __super::ResetDevice();
for (int i = 0; i < m_nDXSurface; i++) {
CComPtr<IMFSample> pMFSample;
- HRESULT hr = pfMFCreateVideoSampleFromSurface(m_pVideoSurface[i], &pMFSample);
+ HRESULT hr = fnMFCreateVideoSampleFromSurface(m_pVideoSurface[i], &pMFSample);
if (SUCCEEDED(hr)) {
pMFSample->SetUINT32(GUID_SURFACE_INDEX, i);
+ CAutoLock sampleQueueLock(&m_SampleQueueLock);
m_FreeSamples.AddTail(pMFSample);
}
ASSERT(SUCCEEDED(hr));
@@ -3849,7 +3853,9 @@ void CSyncAP::OnResetDevice()
void CSyncAP::RemoveAllSamples()
{
- CAutoLock AutoLock(&m_ImageProcessingLock);
+ CAutoLock imageProcesssingLock(&m_ImageProcessingLock);
+ CAutoLock sampleQueueLock(&m_SampleQueueLock);
+
FlushSamples();
m_ScheduledSamples.RemoveAll();
m_FreeSamples.RemoveAll();
@@ -3905,11 +3911,11 @@ void CSyncAP::MoveToFreeList(IMFSample* pSample, bool bTail)
void CSyncAP::MoveToScheduledList(IMFSample* pSample, bool _bSorted)
{
+ CAutoLock lock(&m_SampleQueueLock);
+
if (_bSorted) {
- CAutoLock lock(&m_SampleQueueLock);
m_ScheduledSamples.AddHead(pSample);
} else {
- CAutoLock lock(&m_SampleQueueLock);
m_ScheduledSamples.AddTail(pSample);
}
}
@@ -3942,10 +3948,9 @@ HRESULT CSyncAP::BeginStreaming()
m_pcFramesDrawn = 0;
CComPtr<IBaseFilter> pEVR;
- FILTER_INFO filterInfo;
- ZeroMemory(&filterInfo, sizeof(filterInfo));
+ CFilterInfo filterInfo;
m_pOuterEVR->QueryInterface(IID_PPV_ARGS(&pEVR));
- pEVR->QueryFilterInfo(&filterInfo); // This addref's the pGraph member
+ pEVR->QueryFilterInfo(&filterInfo);
BeginEnumFilters(filterInfo.pGraph, pEF, pBF);
if (CComQIPtr<IAMAudioRendererStats> pAS = pBF) {
@@ -3954,9 +3959,6 @@ HRESULT CSyncAP::BeginStreaming()
EndEnumFilters;
pEVR->GetSyncSource(&m_pRefClock);
- if (filterInfo.pGraph) {
- filterInfo.pGraph->Release();
- }
m_pGenlock->SetMonitor(GetAdapter(m_pD3D, m_hWnd));
m_pGenlock->GetTiming();
diff --git a/src/filters/renderer/VideoRenderers/SyncRenderer.h b/src/filters/renderer/VideoRenderers/SyncRenderer.h
index fca1d67dd..7455e0e0c 100644
--- a/src/filters/renderer/VideoRenderers/SyncRenderer.h
+++ b/src/filters/renderer/VideoRenderers/SyncRenderer.h
@@ -1,5 +1,5 @@
/*
- * (C) 2010-2014 see Authors.txt
+ * (C) 2010-2015 see Authors.txt
*
* This file is part of MPC-HC.
*
@@ -25,6 +25,7 @@
#include "SyncAllocatorPresenter.h"
#include "AllocatorCommon.h"
#include <dxva2api.h>
+#include "../../../DSUtil/WinapiFunc.h"
#define VMRBITMAP_UPDATE 0x80000000
#define MAX_PICTURE_SLOTS (60 + 2) // Last 2 for pixels shader!
@@ -449,19 +450,6 @@ namespace GothSync
MFCLOCK_STATE m_LastClockState;
private:
- // dxva.dll
- typedef HRESULT(__stdcall* PTR_DXVA2CreateDirect3DDeviceManager9)(UINT* pResetToken, IDirect3DDeviceManager9** ppDeviceManager);
- // mf.dll
- typedef HRESULT(__stdcall* PTR_MFCreatePresentationClock)(IMFPresentationClock** ppPresentationClock);
- // evr.dll
- typedef HRESULT(__stdcall* PTR_MFCreateDXSurfaceBuffer)(REFIID riid, IUnknown* punkSurface, BOOL fBottomUpWhenLinear, IMFMediaBuffer** ppBuffer);
- typedef HRESULT(__stdcall* PTR_MFCreateVideoSampleFromSurface)(IUnknown* pUnkSurface, IMFSample** ppSample);
- typedef HRESULT(__stdcall* PTR_MFCreateVideoMediaType)(const MFVIDEOFORMAT* pVideoFormat, IMFVideoMediaType** ppIVideoMediaType);
- // avrt.dll
- typedef HANDLE(__stdcall* PTR_AvSetMmThreadCharacteristicsW)(LPCWSTR TaskName, LPDWORD TaskIndex);
- typedef BOOL (__stdcall* PTR_AvSetMmThreadPriority)(HANDLE AvrtHandle, AVRT_PRIORITY Priority);
- typedef BOOL (__stdcall* PTR_AvRevertMmThreadCharacteristics)(HANDLE AvrtHandle);
-
enum RENDER_STATE {
Started = State_Running,
Stopped = State_Stopped,
@@ -473,7 +461,7 @@ namespace GothSync
CComPtr<IDirect3DDeviceManager9> m_pD3DManager;
CComPtr<IMFTransform> m_pMixer;
CComPtr<IMediaEventSink> m_pSink;
- CComPtr<IMFVideoMediaType> m_pMediaType;
+ CComPtr<IMFMediaType> m_pMediaType;
MFVideoAspectRatioMode m_dwVideoAspectRatioMode;
MFVideoRenderPrefs m_dwVideoRenderPrefs;
COLORREF m_BorderColor;
@@ -529,22 +517,17 @@ namespace GothSync
LONGLONG GetMediaTypeMerit(IMFMediaType* pMediaType);
HRESULT RenegotiateMediaType();
HRESULT IsMediaTypeSupported(IMFMediaType* pMixerType);
- HRESULT CreateProposedOutputType(IMFMediaType* pMixerType, IMFMediaType** pType);
+ HRESULT CreateOptimalOutputType(IMFMediaType* pMixerProposedType, IMFMediaType* pMixerInputType, IMFMediaType** ppType);
HRESULT SetMediaType(IMFMediaType* pType);
- // Functions pointers for Vista+ / .NET Framework 3.5 specific library
- HMODULE m_hDXVA2Lib;
- HMODULE m_hEVRLib;
- HMODULE m_hAVRTLib;
-
- PTR_DXVA2CreateDirect3DDeviceManager9 pfDXVA2CreateDirect3DDeviceManager9;
- PTR_MFCreateDXSurfaceBuffer pfMFCreateDXSurfaceBuffer;
- PTR_MFCreateVideoSampleFromSurface pfMFCreateVideoSampleFromSurface;
- PTR_MFCreateVideoMediaType pfMFCreateVideoMediaType;
+ const WinapiFunc<decltype(DXVA2CreateDirect3DDeviceManager9)> fnDXVA2CreateDirect3DDeviceManager9;
+ const WinapiFunc<decltype(MFCreateDXSurfaceBuffer)> fnMFCreateDXSurfaceBuffer;
+ const WinapiFunc<decltype(MFCreateVideoSampleFromSurface)> fnMFCreateVideoSampleFromSurface;
+ const WinapiFunc<decltype(MFCreateMediaType)> fnMFCreateMediaType;
- PTR_AvSetMmThreadCharacteristicsW pfAvSetMmThreadCharacteristicsW;
- PTR_AvSetMmThreadPriority pfAvSetMmThreadPriority;
- PTR_AvRevertMmThreadCharacteristics pfAvRevertMmThreadCharacteristics;
+ const WinapiFunc<decltype(AvSetMmThreadCharacteristicsW)> fnAvSetMmThreadCharacteristicsW;
+ const WinapiFunc<decltype(AvSetMmThreadPriority)> fnAvSetMmThreadPriority;
+ const WinapiFunc<decltype(AvRevertMmThreadCharacteristics)> fnAvRevertMmThreadCharacteristics;
};
class CSyncRenderer:
diff --git a/src/filters/renderer/VideoRenderers/madVRAllocatorPresenter.cpp b/src/filters/renderer/VideoRenderers/madVRAllocatorPresenter.cpp
index 0124367e6..3faf3784d 100644
--- a/src/filters/renderer/VideoRenderers/madVRAllocatorPresenter.cpp
+++ b/src/filters/renderer/VideoRenderers/madVRAllocatorPresenter.cpp
@@ -1,5 +1,5 @@
/*
- * (C) 2006-2014 see Authors.txt
+ * (C) 2006-2015 see Authors.txt
*
* This file is part of MPC-HC.
*
@@ -23,7 +23,8 @@
#include "../../../SubPic/DX9SubPic.h"
#include "../../../SubPic/SubPicQueueImpl.h"
#include "RenderersSettings.h"
-#include "moreuuids.h"
+#include <mvrInterfaces.h>
+
using namespace DSObjects;
@@ -88,8 +89,6 @@ STDMETHODIMP CmadVRAllocatorPresenter::NonDelegatingQueryInterface(REFIID riid,
HRESULT CmadVRAllocatorPresenter::SetDevice(IDirect3DDevice9* pD3DDev)
{
- const CRenderersSettings& r = GetRenderersSettings();
-
if (!pD3DDev) {
// release all resources
m_pSubPicQueue = nullptr;
@@ -97,6 +96,7 @@ HRESULT CmadVRAllocatorPresenter::SetDevice(IDirect3DDevice9* pD3DDev)
return S_OK;
}
+ const CRenderersSettings& r = GetRenderersSettings();
InitMaxSubtitleTextureSize(r.subPicQueueSettings.nMaxRes, m_ScreenSize);
if (m_pAllocator) {
@@ -187,6 +187,8 @@ STDMETHODIMP_(void) CmadVRAllocatorPresenter::SetPosition(RECT w, RECT v)
if (CComQIPtr<IVideoWindow> pVW = m_pDXR) {
pVW->SetWindowPosition(w.left, w.top, w.right - w.left, w.bottom - w.top);
}
+
+ SetVideoSize(GetVideoSize(), GetVideoSize(true));
}
STDMETHODIMP_(SIZE) CmadVRAllocatorPresenter::GetVideoSize(bool bCorrectAR) const
diff --git a/src/filters/renderer/VideoRenderers/madVRAllocatorPresenter.h b/src/filters/renderer/VideoRenderers/madVRAllocatorPresenter.h
index b72901034..2bbf45e06 100644
--- a/src/filters/renderer/VideoRenderers/madVRAllocatorPresenter.h
+++ b/src/filters/renderer/VideoRenderers/madVRAllocatorPresenter.h
@@ -1,5 +1,5 @@
/*
- * (C) 2006-2014 see Authors.txt
+ * (C) 2006-2015 see Authors.txt
*
* This file is part of MPC-HC.
*
@@ -20,11 +20,8 @@
#pragma once
-#include "AllocatorCommon.h"
-#include "../../../SubPic/SubPicAllocatorPresenterImpl.h"
-#include "../../../SubPic/ISubRender.h"
-
-#include <mvrInterfaces.h>
+#include "../SubPic/SubPicAllocatorPresenterImpl.h"
+#include "../SubPic/ISubRender.h"
namespace DSObjects
{
@@ -94,7 +91,7 @@ namespace DSObjects
// ISubPicAllocatorPresenter
STDMETHODIMP CreateRenderer(IUnknown** ppRenderer);
STDMETHODIMP_(void) SetPosition(RECT w, RECT v);
- STDMETHODIMP_(SIZE) GetVideoSize(bool bCorrectAR) const;
+ STDMETHODIMP_(SIZE) GetVideoSize(bool bCorrectAR = true) const;
STDMETHODIMP_(bool) Paint(bool bAll);
STDMETHODIMP GetDIB(BYTE* lpDib, DWORD* size);
STDMETHODIMP SetPixelShader(LPCSTR pSrcData, LPCSTR pTarget);