xref: /reactos/dll/directx/wine/quartz/nullrenderer.c (revision c7bba39a)
1 /*
2  * Null Renderer (Promiscuous, not rendering anything at all!)
3  *
4  * Copyright 2004 Christian Costa
5  * Copyright 2008 Maarten Lankhorst
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 
22 #include "config.h"
23 
24 #include "quartz_private.h"
25 #include "pin.h"
26 
27 #include "uuids.h"
28 #include "vfwmsgs.h"
29 #include "amvideo.h"
30 #include "windef.h"
31 #include "winbase.h"
32 #include "dshow.h"
33 #include "evcode.h"
34 #include "strmif.h"
35 #include "ddraw.h"
36 
37 #include "wine/unicode.h"
38 #include "wine/debug.h"
39 
40 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
41 
42 typedef struct NullRendererImpl
43 {
44     BaseRenderer renderer;
45     IUnknown IUnknown_inner;
46     IAMFilterMiscFlags IAMFilterMiscFlags_iface;
47     IUnknown *outer_unk;
48 } NullRendererImpl;
49 
50 static HRESULT WINAPI NullRenderer_DoRenderSample(BaseRenderer *iface, IMediaSample *pMediaSample)
51 {
52     return S_OK;
53 }
54 
55 static HRESULT WINAPI NullRenderer_CheckMediaType(BaseRenderer *iface, const AM_MEDIA_TYPE * pmt)
56 {
57     TRACE("Not a stub!\n");
58     return S_OK;
59 }
60 
61 static const BaseRendererFuncTable RendererFuncTable = {
62     NullRenderer_CheckMediaType,
63     NullRenderer_DoRenderSample,
64     /**/
65     NULL,
66     NULL,
67     NULL,
68     NULL,
69     NULL,
70     NULL,
71     NULL,
72     NULL,
73     NULL,
74     NULL,
75     /**/
76     NULL,
77     NULL,
78     NULL,
79     NULL,
80     NULL,
81 };
82 
83 static inline NullRendererImpl *impl_from_IUnknown(IUnknown *iface)
84 {
85     return CONTAINING_RECORD(iface, NullRendererImpl, IUnknown_inner);
86 }
87 
88 static HRESULT WINAPI NullRendererInner_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
89 {
90     NullRendererImpl *This = impl_from_IUnknown(iface);
91 
92     TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
93 
94     *ppv = NULL;
95 
96     if (IsEqualIID(riid, &IID_IUnknown))
97         *ppv = &This->IUnknown_inner;
98     else if (IsEqualIID(riid, &IID_IAMFilterMiscFlags))
99         *ppv = &This->IAMFilterMiscFlags_iface;
100     else
101     {
102         HRESULT hr;
103         hr = BaseRendererImpl_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
104         if (SUCCEEDED(hr))
105             return hr;
106     }
107 
108     if (*ppv)
109     {
110         IUnknown_AddRef((IUnknown *)*ppv);
111         return S_OK;
112     }
113 
114     if (!IsEqualIID(riid, &IID_IPin) && !IsEqualIID(riid, &IID_IVideoWindow))
115         FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
116 
117     return E_NOINTERFACE;
118 }
119 
120 static ULONG WINAPI NullRendererInner_AddRef(IUnknown *iface)
121 {
122     NullRendererImpl *This = impl_from_IUnknown(iface);
123     return BaseFilterImpl_AddRef(&This->renderer.filter.IBaseFilter_iface);
124 }
125 
126 static ULONG WINAPI NullRendererInner_Release(IUnknown *iface)
127 {
128     NullRendererImpl *This = impl_from_IUnknown(iface);
129     ULONG refCount = BaseRendererImpl_Release(&This->renderer.filter.IBaseFilter_iface);
130 
131     if (!refCount)
132     {
133         TRACE("Destroying Null Renderer\n");
134         CoTaskMemFree(This);
135     }
136 
137     return refCount;
138 }
139 
140 static const IUnknownVtbl IInner_VTable =
141 {
142     NullRendererInner_QueryInterface,
143     NullRendererInner_AddRef,
144     NullRendererInner_Release
145 };
146 
147 static inline NullRendererImpl *impl_from_IBaseFilter(IBaseFilter *iface)
148 {
149     return CONTAINING_RECORD(iface, NullRendererImpl, renderer.filter.IBaseFilter_iface);
150 }
151 
152 static HRESULT WINAPI NullRenderer_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv)
153 {
154     NullRendererImpl *This = impl_from_IBaseFilter(iface);
155     return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
156 }
157 
158 static ULONG WINAPI NullRenderer_AddRef(IBaseFilter * iface)
159 {
160     NullRendererImpl *This = impl_from_IBaseFilter(iface);
161     return IUnknown_AddRef(This->outer_unk);
162 }
163 
164 static ULONG WINAPI NullRenderer_Release(IBaseFilter * iface)
165 {
166     NullRendererImpl *This = impl_from_IBaseFilter(iface);
167     return IUnknown_Release(This->outer_unk);
168 }
169 
170 static const IBaseFilterVtbl NullRenderer_Vtbl =
171 {
172     NullRenderer_QueryInterface,
173     NullRenderer_AddRef,
174     NullRenderer_Release,
175     BaseFilterImpl_GetClassID,
176     BaseRendererImpl_Stop,
177     BaseRendererImpl_Pause,
178     BaseRendererImpl_Run,
179     BaseRendererImpl_GetState,
180     BaseRendererImpl_SetSyncSource,
181     BaseFilterImpl_GetSyncSource,
182     BaseFilterImpl_EnumPins,
183     BaseRendererImpl_FindPin,
184     BaseFilterImpl_QueryFilterInfo,
185     BaseFilterImpl_JoinFilterGraph,
186     BaseFilterImpl_QueryVendorInfo
187 };
188 
189 static NullRendererImpl *impl_from_IAMFilterMiscFlags(IAMFilterMiscFlags *iface)
190 {
191     return CONTAINING_RECORD(iface, NullRendererImpl, IAMFilterMiscFlags_iface);
192 }
193 
194 static HRESULT WINAPI AMFilterMiscFlags_QueryInterface(IAMFilterMiscFlags *iface, REFIID riid,
195         void **ppv)
196 {
197     NullRendererImpl *This = impl_from_IAMFilterMiscFlags(iface);
198     return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
199 }
200 
201 static ULONG WINAPI AMFilterMiscFlags_AddRef(IAMFilterMiscFlags *iface)
202 {
203     NullRendererImpl *This = impl_from_IAMFilterMiscFlags(iface);
204     return IUnknown_AddRef(This->outer_unk);
205 }
206 
207 static ULONG WINAPI AMFilterMiscFlags_Release(IAMFilterMiscFlags *iface)
208 {
209     NullRendererImpl *This = impl_from_IAMFilterMiscFlags(iface);
210     return IUnknown_Release(This->outer_unk);
211 }
212 
213 static ULONG WINAPI AMFilterMiscFlags_GetMiscFlags(IAMFilterMiscFlags *iface)
214 {
215     return AM_FILTER_MISC_FLAGS_IS_RENDERER;
216 }
217 
218 static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl = {
219     AMFilterMiscFlags_QueryInterface,
220     AMFilterMiscFlags_AddRef,
221     AMFilterMiscFlags_Release,
222     AMFilterMiscFlags_GetMiscFlags
223 };
224 
225 HRESULT NullRenderer_create(IUnknown *pUnkOuter, void **ppv)
226 {
227     HRESULT hr;
228     NullRendererImpl *pNullRenderer;
229 
230     TRACE("(%p, %p)\n", pUnkOuter, ppv);
231 
232     *ppv = NULL;
233 
234     pNullRenderer = CoTaskMemAlloc(sizeof(NullRendererImpl));
235     pNullRenderer->IUnknown_inner.lpVtbl = &IInner_VTable;
236     pNullRenderer->IAMFilterMiscFlags_iface.lpVtbl = &IAMFilterMiscFlags_Vtbl;
237 
238     if (pUnkOuter)
239         pNullRenderer->outer_unk = pUnkOuter;
240     else
241         pNullRenderer->outer_unk = &pNullRenderer->IUnknown_inner;
242 
243     hr = BaseRenderer_Init(&pNullRenderer->renderer, &NullRenderer_Vtbl, pUnkOuter,
244             &CLSID_NullRenderer, (DWORD_PTR)(__FILE__ ": NullRendererImpl.csFilter"),
245             &RendererFuncTable);
246 
247     if (FAILED(hr))
248     {
249         BaseRendererImpl_Release(&pNullRenderer->renderer.filter.IBaseFilter_iface);
250         CoTaskMemFree(pNullRenderer);
251     }
252     else
253         *ppv = &pNullRenderer->IUnknown_inner;
254 
255     return S_OK;
256 }
257