quartz: Add initial VMR9 stub.

This commit is contained in:
Aric Stewart 2012-04-03 14:37:55 -05:00 committed by Alexandre Julliard
parent ee0bfd36ed
commit d969b80210
6 changed files with 392 additions and 1 deletions

View File

@ -1,6 +1,6 @@
MODULE = quartz.dll
IMPORTLIB = quartz
IMPORTS = strmiids strmbase uuid dsound msacm32 msvfw32 ole32 oleaut32 shlwapi rpcrt4 user32 gdi32 advapi32
IMPORTS = strmiids dxguid strmbase uuid dsound msacm32 msvfw32 ole32 oleaut32 shlwapi rpcrt4 user32 gdi32 advapi32
EXTRADEFS = -DENTRY_PREFIX=QUARTZ_ -DPROXY_DELEGATION -DWINE_REGISTER_DLL
C_SRCS = \
@ -24,6 +24,7 @@ C_SRCS = \
regsvr.c \
systemclock.c \
videorenderer.c \
vmr9.c \
waveparser.c
RC_SRCS = version.rc

View File

@ -71,6 +71,7 @@ static const struct object_creation_info object_creation[] =
{ &CLSID_MPEG1Splitter, MPEGSplitter_create },
{ &CLSID_VideoRenderer, VideoRenderer_create },
{ &CLSID_NullRenderer, NullRenderer_create },
{ &CLSID_VideoMixingRenderer9, VMR9Impl_create },
{ &CLSID_VideoRendererDefault, VideoRendererDefault_create },
{ &CLSID_DSoundRender, DSoundRender_create },
{ &CLSID_AudioRender, DSoundRender_create },

View File

@ -56,6 +56,7 @@ HRESULT VideoRendererDefault_create(IUnknown * pUnkOuter, LPVOID * ppv) DECLSPEC
HRESULT QUARTZ_CreateSystemClock(IUnknown * pUnkOuter, LPVOID * ppv) DECLSPEC_HIDDEN;
HRESULT ACMWrapper_create(IUnknown * pUnkOuter, LPVOID * ppv) DECLSPEC_HIDDEN;
HRESULT WAVEParser_create(IUnknown * pUnkOuter, LPVOID * ppv) DECLSPEC_HIDDEN;
HRESULT VMR9Impl_create(IUnknown *pUnkOuter, LPVOID *ppv) DECLSPEC_HIDDEN;
HRESULT EnumMonikerImpl_Create(IMoniker ** ppMoniker, ULONG nMonikerCount, IEnumMoniker ** ppEnum) DECLSPEC_HIDDEN;

View File

@ -150,3 +150,10 @@ coclass ACMWrapper { interface IBaseFilter; }
uuid(d51bd5a1-7548-11cf-a520-0080c77ef58a)
]
coclass WAVEParser { interface IBaseFilter; }
[
helpstring("Video Mixing Renderer 9"),
threading(both),
uuid(51b4abf3-748f-4e3b-a276-c828330e926a)
]
coclass VideoMixingRenderer9 { interface IBaseFilter; }

View File

@ -958,6 +958,18 @@ static struct regsvr_filter const filter_list[] = {
{ 0xFFFFFFFF },
}
},
{ &CLSID_VideoMixingRenderer9,
&CLSID_LegacyAmFilterCategory,
{'V','i','d','e','o',' ','M','i','x','i','n','g',' ','R','e','n','d','e','r','e','r',' ','9',0},
0x200000,
{ { REG_PINFLAG_B_RENDERER,
{ { &MEDIATYPE_Video, &GUID_NULL },
{ NULL }
},
},
{ 0xFFFFFFFF },
}
},
{ &CLSID_DSoundRender,
&CLSID_LegacyAmFilterCategory,
{'A','u','d','i','o',' ','R','e','n','d','e','r','e','r',0},

369
dlls/quartz/vmr9.c Normal file
View File

@ -0,0 +1,369 @@
/*
* Video Mixing Renderer for dx9
*
* Copyright 2004 Christian Costa
* Copyright 2008 Maarten Lankhorst
* Copyright 2012 Aric Stewart
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#define NONAMELESSSTRUCT
#define NONAMELESSUNION
#include "quartz_private.h"
#include "uuids.h"
#include "vfwmsgs.h"
#include "amvideo.h"
#include "windef.h"
#include "winbase.h"
#include "dshow.h"
#include "evcode.h"
#include "strmif.h"
#include "ddraw.h"
#include "dvdmedia.h"
#include "d3d9.h"
#include "vmr9.h"
#include "pin.h"
#include "wine/unicode.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(quartz);
typedef struct
{
BaseRenderer renderer;
IUnknown IUnknown_inner;
BITMAPINFOHEADER bmiheader;
IUnknown * outer_unk;
BOOL bUnkOuterValid;
BOOL bAggregatable;
} VMR9Impl;
static inline VMR9Impl *impl_from_inner_IUnknown(IUnknown *iface)
{
return CONTAINING_RECORD(iface, VMR9Impl, IUnknown_inner);
}
static HRESULT WINAPI VMR9_DoRenderSample(BaseRenderer *iface, IMediaSample * pSample)
{
VMR9Impl *This = (VMR9Impl *)iface;
LPBYTE pbSrcStream = NULL;
REFERENCE_TIME tStart, tStop;
VMR9PresentationInfo info;
HRESULT hr;
TRACE("%p %p\n", iface, pSample);
hr = IMediaSample_GetTime(pSample, &tStart, &tStop);
if (FAILED(hr))
info.dwFlags = VMR9Sample_SrcDstRectsValid;
else
info.dwFlags = VMR9Sample_SrcDstRectsValid | VMR9Sample_TimeValid;
if (IMediaSample_IsDiscontinuity(pSample) == S_OK)
info.dwFlags |= VMR9Sample_Discontinuity;
if (IMediaSample_IsPreroll(pSample) == S_OK)
info.dwFlags |= VMR9Sample_Preroll;
if (IMediaSample_IsSyncPoint(pSample) == S_OK)
info.dwFlags |= VMR9Sample_SyncPoint;
hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
if (FAILED(hr))
{
ERR("Cannot get pointer to sample data (%x)\n", hr);
return hr;
}
info.rtStart = tStart;
info.rtEnd = tStop;
info.szAspectRatio.cx = This->bmiheader.biWidth;
info.szAspectRatio.cy = This->bmiheader.biHeight;
return hr;
}
static HRESULT WINAPI VMR9_CheckMediaType(BaseRenderer *iface, const AM_MEDIA_TYPE * pmt)
{
VMR9Impl *This = (VMR9Impl*)iface;
if (!IsEqualIID(&pmt->majortype, &MEDIATYPE_Video) || !pmt->pbFormat)
return S_FALSE;
/* Ignore subtype, test for bicompression instead */
if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo))
{
VIDEOINFOHEADER *format = (VIDEOINFOHEADER *)pmt->pbFormat;
This->bmiheader = format->bmiHeader;
TRACE("Resolution: %dx%d\n", format->bmiHeader.biWidth, format->bmiHeader.biHeight);
}
else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2))
{
VIDEOINFOHEADER2 *format = (VIDEOINFOHEADER2 *)pmt->pbFormat;
This->bmiheader = format->bmiHeader;
TRACE("Resolution: %dx%d\n", format->bmiHeader.biWidth, format->bmiHeader.biHeight);
}
else
{
ERR("Format type %s not supported\n", debugstr_guid(&pmt->formattype));
return S_FALSE;
}
if (This->bmiheader.biCompression)
return S_FALSE;
return S_OK;
}
HRESULT WINAPI VMR9_ShouldDrawSampleNow(BaseRenderer *This, IMediaSample *pSample, REFERENCE_TIME *pStartTime, REFERENCE_TIME *pEndTime)
{
/* Preroll means the sample isn't shown, this is used for key frames and things like that */
if (IMediaSample_IsPreroll(pSample) == S_OK)
return E_FAIL;
return S_FALSE;
}
static const BaseRendererFuncTable BaseFuncTable = {
VMR9_CheckMediaType,
VMR9_DoRenderSample,
/**/
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
VMR9_ShouldDrawSampleNow,
NULL,
/**/
NULL,
NULL,
NULL,
NULL,
NULL,
};
static HRESULT WINAPI VMR9Inner_QueryInterface(IUnknown * iface, REFIID riid, LPVOID * ppv)
{
VMR9Impl *This = impl_from_inner_IUnknown(iface);
TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
if (This->bAggregatable)
This->bUnkOuterValid = TRUE;
*ppv = NULL;
if (IsEqualIID(riid, &IID_IUnknown))
*ppv = &This->IUnknown_inner;
else
{
HRESULT hr;
hr = BaseRendererImpl_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
if (SUCCEEDED(hr))
return hr;
}
if (*ppv)
{
IUnknown_AddRef((IUnknown *)(*ppv));
return S_OK;
}
else if (IsEqualIID(riid, &IID_IBasicVideo))
FIXME("No interface for IID_IBasicVideo\n");
else if (IsEqualIID(riid, &IID_IBasicVideo2))
FIXME("No interface for IID_IBasicVideo2\n");
else if (IsEqualIID(riid, &IID_IVideoWindow))
FIXME("No interface for IID_IVideoWindow\n");
else if (IsEqualIID(riid, &IID_IVMRWindowlessControl9))
;
else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorNotify9))
;
else if (IsEqualIID(riid, &IID_IAMFilterMiscFlags))
FIXME("No interface for IID_IAMFilterMiscFlags\n");
else if (IsEqualIID(riid, &IID_IMediaPosition))
FIXME("No interface for IID_IMediaPosition\n");
else if (IsEqualIID(riid, &IID_IQualProp))
FIXME("No interface for IID_IQualProp\n");
else if (IsEqualIID(riid, &IID_IVMRAspectRatioControl9))
FIXME("No interface for IID_IVMRAspectRatioControl9\n");
else if (IsEqualIID(riid, &IID_IVMRDeinterlaceControl9))
FIXME("No interface for IID_IVMRDeinterlaceControl9\n");
else if (IsEqualIID(riid, &IID_IVMRMixerBitmap9))
FIXME("No interface for IID_IVMRMixerBitmap9\n");
else if (IsEqualIID(riid, &IID_IVMRMonitorConfig9))
FIXME("No interface for IID_IVMRMonitorConfig9\n");
else if (IsEqualIID(riid, &IID_IVMRMixerControl9))
FIXME("No interface for IID_IVMRMixerControl9\n");
else
FIXME("No interface for %s\n", debugstr_guid(riid));
return E_NOINTERFACE;
}
static ULONG WINAPI VMR9Inner_AddRef(IUnknown * iface)
{
VMR9Impl *This = impl_from_inner_IUnknown(iface);
ULONG refCount = BaseFilterImpl_AddRef(&This->renderer.filter.IBaseFilter_iface);
TRACE("(%p/%p)->() AddRef from %d\n", This, iface, refCount - 1);
return refCount;
}
static ULONG WINAPI VMR9Inner_Release(IUnknown * iface)
{
VMR9Impl *This = impl_from_inner_IUnknown(iface);
ULONG refCount = BaseRendererImpl_Release(&This->renderer.filter.IBaseFilter_iface);
TRACE("(%p/%p)->() Release from %d\n", This, iface, refCount + 1);
if (!refCount)
{
TRACE("Destroying\n");
CoTaskMemFree(This);
}
return refCount;
}
static const IUnknownVtbl IInner_VTable =
{
VMR9Inner_QueryInterface,
VMR9Inner_AddRef,
VMR9Inner_Release
};
static HRESULT WINAPI VMR9_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv)
{
VMR9Impl *This = (VMR9Impl *)iface;
if (This->bAggregatable)
This->bUnkOuterValid = TRUE;
if (This->outer_unk)
{
if (This->bAggregatable)
return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
if (IsEqualIID(riid, &IID_IUnknown))
{
HRESULT hr;
IUnknown_AddRef(&This->IUnknown_inner);
hr = IUnknown_QueryInterface(&This->IUnknown_inner, riid, ppv);
IUnknown_Release(&This->IUnknown_inner);
This->bAggregatable = TRUE;
return hr;
}
*ppv = NULL;
return E_NOINTERFACE;
}
return IUnknown_QueryInterface(&This->IUnknown_inner, riid, ppv);
}
static ULONG WINAPI VMR9_AddRef(IBaseFilter * iface)
{
VMR9Impl *This = (VMR9Impl *)iface;
LONG ret;
if (This->outer_unk && This->bUnkOuterValid)
ret = IUnknown_AddRef(This->outer_unk);
else
ret = IUnknown_AddRef(&This->IUnknown_inner);
TRACE("(%p)->AddRef from %d\n", iface, ret - 1);
return ret;
}
static ULONG WINAPI VMR9_Release(IBaseFilter * iface)
{
VMR9Impl *This = (VMR9Impl *)iface;
LONG ret;
if (This->outer_unk && This->bUnkOuterValid)
ret = IUnknown_Release(This->outer_unk);
else
ret = IUnknown_Release(&This->IUnknown_inner);
TRACE("(%p)->Release from %d\n", iface, ret + 1);
if (ret)
return ret;
return 0;
}
static const IBaseFilterVtbl VMR9_Vtbl =
{
VMR9_QueryInterface,
VMR9_AddRef,
VMR9_Release,
BaseFilterImpl_GetClassID,
BaseRendererImpl_Stop,
BaseRendererImpl_Pause,
BaseRendererImpl_Run,
BaseRendererImpl_GetState,
BaseRendererImpl_SetSyncSource,
BaseFilterImpl_GetSyncSource,
BaseFilterImpl_EnumPins,
BaseRendererImpl_FindPin,
BaseFilterImpl_QueryFilterInfo,
BaseFilterImpl_JoinFilterGraph,
BaseFilterImpl_QueryVendorInfo
};
HRESULT VMR9Impl_create(IUnknown * outer_unk, LPVOID * ppv)
{
HRESULT hr;
VMR9Impl * pVMR9;
TRACE("(%p, %p)\n", outer_unk, ppv);
*ppv = NULL;
pVMR9 = CoTaskMemAlloc(sizeof(VMR9Impl));
pVMR9->outer_unk = outer_unk;
pVMR9->bUnkOuterValid = FALSE;
pVMR9->bAggregatable = FALSE;
pVMR9->IUnknown_inner.lpVtbl = &IInner_VTable;
hr = BaseRenderer_Init(&pVMR9->renderer, &VMR9_Vtbl, outer_unk, &CLSID_VideoMixingRenderer9, (DWORD_PTR)(__FILE__ ": VMR9Impl.csFilter"), &BaseFuncTable);
if (SUCCEEDED(hr))
{
*ppv = (LPVOID)pVMR9;
TRACE("Created at %p\n", pVMR9);
}
else
{
BaseRendererImpl_Release(&pVMR9->renderer.filter.IBaseFilter_iface);
CoTaskMemFree(pVMR9);
}
return hr;
}