| /* |
| * Copyright 2017 Fabian Maurer |
| * |
| * 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 |
| */ |
| |
| #define COBJMACROS |
| |
| #include "config.h" |
| #include "wine/debug.h" |
| |
| #include <stdio.h> |
| |
| #include "evr_private.h" |
| #include "d3d9.h" |
| #include "wine/strmbase.h" |
| |
| #include "initguid.h" |
| #include "dxva2api.h" |
| |
| WINE_DEFAULT_DEBUG_CHANNEL(evr); |
| |
| typedef struct |
| { |
| BaseFilter filter; |
| |
| IUnknown IUnknown_inner; |
| } evr_filter; |
| |
| static inline evr_filter *impl_from_inner_IUnknown(IUnknown *iface) |
| { |
| return CONTAINING_RECORD(iface, evr_filter, IUnknown_inner); |
| } |
| |
| static HRESULT WINAPI inner_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) |
| { |
| evr_filter *This = impl_from_inner_IUnknown(iface); |
| TRACE("(%p/%p)->(%s, %p)\n", This, iface, debugstr_guid(riid), ppv); |
| |
| *ppv = NULL; |
| |
| if (IsEqualIID(riid, &IID_IUnknown)) |
| *ppv = &This->IUnknown_inner; |
| |
| else if (IsEqualIID(riid, &IID_IAMCertifiedOutputProtection)) |
| FIXME("No interface for IID_IAMCertifiedOutputProtection\n"); |
| else if (IsEqualIID(riid, &IID_IAMFilterMiscFlags)) |
| FIXME("No interface for IID_IAMFilterMiscFlags\n"); |
| else if (IsEqualIID(riid, &IID_IBaseFilter)) |
| *ppv =&This->filter.IBaseFilter_iface; |
| else if (IsEqualIID(riid, &IID_IMediaFilter)) |
| *ppv =&This->filter.IBaseFilter_iface; |
| else if (IsEqualIID(riid, &IID_IPersist)) |
| *ppv =&This->filter.IBaseFilter_iface; |
| else if (IsEqualIID(riid, &IID_IKsPropertySet)) |
| FIXME("No interface for IID_IKsPropertySet\n"); |
| else if (IsEqualIID(riid, &IID_IMediaEventSink)) |
| FIXME("No interface for IID_IMediaEventSink\n"); |
| else if (IsEqualIID(riid, &IID_IMediaSeeking)) |
| FIXME("No interface for IID_IMediaSeeking\n"); |
| else if (IsEqualIID(riid, &IID_IQualityControl)) |
| FIXME("No interface for IID_IQualityControl\n"); |
| else if (IsEqualIID(riid, &IID_IQualProp)) |
| FIXME("No interface for IID_IQualProp\n"); |
| |
| else if (IsEqualIID(riid, &IID_IEVRFilterConfig)) |
| FIXME("No interface for IID_IEVRFilterConfig\n"); |
| else if (IsEqualIID(riid, &IID_IMFGetService)) |
| FIXME("No interface for IID_IMFGetService\n"); |
| else if (IsEqualIID(riid, &IID_IMFVideoPositionMapper)) |
| FIXME("No interface for IID_IMFVideoPositionMapper\n"); |
| else if (IsEqualIID(riid, &IID_IMFVideoRenderer)) |
| FIXME("No interface for IID_IMFVideoRenderer\n"); |
| |
| else if (IsEqualIID(riid, &IID_IMemInputPin)) |
| FIXME("No interface for IID_IMemInputPin\n"); |
| else if (IsEqualIID(riid, &IID_IPin)) |
| FIXME("No interface for IID_IPin\n"); |
| else if (IsEqualIID(riid, &IID_IQualityControl)) |
| FIXME("No interface for IID_IQualityControl\n"); |
| |
| else if (IsEqualIID(riid, &IID_IDirectXVideoMemoryConfiguration)) |
| FIXME("No interface for IID_IDirectXVideoMemoryConfiguration\n"); |
| |
| if (*ppv) |
| { |
| IUnknown_AddRef((IUnknown *)(*ppv)); |
| return S_OK; |
| } |
| |
| FIXME("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppv); |
| return E_NOINTERFACE; |
| } |
| |
| static ULONG WINAPI inner_AddRef(IUnknown *iface) |
| { |
| evr_filter *This = impl_from_inner_IUnknown(iface); |
| ULONG ref = BaseFilterImpl_AddRef(&This->filter.IBaseFilter_iface); |
| |
| TRACE("(%p, %p)->(): new ref %d\n", iface, This, ref); |
| |
| return ref; |
| } |
| |
| static ULONG WINAPI inner_Release(IUnknown *iface) |
| { |
| evr_filter *This = impl_from_inner_IUnknown(iface); |
| ULONG ref = BaseFilterImpl_Release(&This->filter.IBaseFilter_iface); |
| |
| TRACE("(%p, %p)->(): new ref %d\n", iface, This, ref); |
| |
| if (!ref) |
| CoTaskMemFree(This); |
| |
| return ref; |
| } |
| |
| static const IUnknownVtbl evr_inner_vtbl = |
| { |
| inner_QueryInterface, |
| inner_AddRef, |
| inner_Release |
| }; |
| |
| static inline evr_filter *impl_from_IBaseFilter(IBaseFilter *iface) |
| { |
| return CONTAINING_RECORD(iface, evr_filter, filter); |
| } |
| |
| static HRESULT WINAPI filter_QueryInterface(IBaseFilter *iface, REFIID riid, void **ppv) |
| { |
| evr_filter *This = impl_from_IBaseFilter(iface); |
| return IUnknown_QueryInterface(&This->IUnknown_inner, riid, ppv); |
| } |
| |
| static ULONG WINAPI filter_AddRef(IBaseFilter *iface) |
| { |
| evr_filter *This = impl_from_IBaseFilter(iface); |
| LONG ret; |
| |
| ret = IUnknown_AddRef(&This->IUnknown_inner); |
| |
| TRACE("(%p)->AddRef from %d\n", iface, ret - 1); |
| |
| return ret; |
| } |
| |
| static ULONG WINAPI filter_Release(IBaseFilter *iface) |
| { |
| evr_filter *This = impl_from_IBaseFilter(iface); |
| LONG ret; |
| |
| ret = IUnknown_Release(&This->IUnknown_inner); |
| |
| TRACE("(%p)->Release from %d\n", iface, ret + 1); |
| |
| return ret; |
| } |
| |
| static const IBaseFilterVtbl basefilter_vtbl = |
| { |
| filter_QueryInterface, |
| filter_AddRef, |
| filter_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 |
| }; |
| |
| static IPin* WINAPI filter_GetPin(BaseFilter *iface, int position) |
| { |
| FIXME("(%p, %d): stub!\n", iface, position); |
| return NULL; |
| } |
| |
| static LONG WINAPI filter_GetPinCount(BaseFilter *iface) |
| { |
| FIXME("(%p): stub!\n", iface); |
| return 0; |
| } |
| |
| static const BaseFilterFuncTable basefilter_functable = |
| { |
| filter_GetPin, |
| filter_GetPinCount, |
| }; |
| |
| HRESULT evr_filter_create(IUnknown *outer_unk, void **ppv) |
| { |
| evr_filter *object; |
| |
| TRACE("(%p, %p)\n", outer_unk, ppv); |
| |
| *ppv = NULL; |
| |
| if(outer_unk != NULL) |
| { |
| FIXME("Aggregation yet unsupported!\n"); |
| return E_NOINTERFACE; |
| } |
| |
| object = CoTaskMemAlloc(sizeof(evr_filter)); |
| if (!object) |
| return E_OUTOFMEMORY; |
| |
| BaseFilter_Init(&object->filter, &basefilter_vtbl, &CLSID_EnhancedVideoRenderer, |
| (DWORD_PTR)(__FILE__ ": EVR.csFilter"), &basefilter_functable); |
| |
| object->IUnknown_inner.lpVtbl = &evr_inner_vtbl; |
| |
| *ppv = &object->IUnknown_inner; |
| |
| return S_OK; |
| } |