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