qcap/tests: Add media tests for the SmartTee filter.
[wine/multimedia.git] / dlls / strmbase / video.c
blob1c4f3606f679c28cfd9546549c4fdb04597c25ac
1 /*
2 * Generic Implementation of strmbase video classes
4 * Copyright 2012 Aric Stewart, CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define COBJMACROS
23 #include <assert.h>
24 #include "dshow.h"
25 #include "uuids.h"
26 #include "vfwmsgs.h"
27 #include "wine/debug.h"
28 #include "wine/unicode.h"
29 #include "wine/strmbase.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(strmbase);
33 static inline BaseControlVideo *impl_from_IBasicVideo(IBasicVideo *iface)
35 return CONTAINING_RECORD(iface, BaseControlVideo, IBasicVideo_iface);
38 HRESULT WINAPI BaseControlVideo_Init(BaseControlVideo *pControlVideo, const IBasicVideoVtbl *lpVtbl, BaseFilter *owner, CRITICAL_SECTION *lock, BasePin* pPin, const BaseControlVideoFuncTable* pFuncsTable)
40 pControlVideo->IBasicVideo_iface.lpVtbl = lpVtbl;
41 pControlVideo->pFilter = owner;
42 pControlVideo->pInterfaceLock = lock;
43 pControlVideo->pPin = pPin;
44 pControlVideo->pFuncsTable = pFuncsTable;
46 BaseDispatch_Init(&pControlVideo->baseDispatch, &IID_IBasicVideo);
48 return S_OK;
51 HRESULT WINAPI BaseControlVideo_Destroy(BaseControlVideo *pControlVideo)
53 return BaseDispatch_Destroy(&pControlVideo->baseDispatch);
56 HRESULT WINAPI BaseControlVideoImpl_GetTypeInfoCount(IBasicVideo *iface, UINT *pctinfo)
58 BaseControlVideo *This = impl_from_IBasicVideo(iface);
60 return BaseDispatchImpl_GetTypeInfoCount(&This->baseDispatch, pctinfo);
63 HRESULT WINAPI BaseControlVideoImpl_GetTypeInfo(IBasicVideo *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
65 BaseControlVideo *This = impl_from_IBasicVideo(iface);
67 return BaseDispatchImpl_GetTypeInfo(&This->baseDispatch, &IID_NULL, iTInfo, lcid, ppTInfo);
70 HRESULT WINAPI BaseControlVideoImpl_GetIDsOfNames(IBasicVideo *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
72 BaseControlVideo *This = impl_from_IBasicVideo(iface);
74 return BaseDispatchImpl_GetIDsOfNames(&This->baseDispatch, riid, rgszNames, cNames, lcid, rgDispId);
77 HRESULT WINAPI BaseControlVideoImpl_Invoke(IBasicVideo *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExepInfo, UINT *puArgErr)
79 BaseControlVideo *This = impl_from_IBasicVideo(iface);
80 HRESULT hr = S_OK;
81 ITypeInfo *pTypeInfo;
83 hr = BaseDispatchImpl_GetTypeInfo(&This->baseDispatch, riid, 1, lcid, &pTypeInfo);
84 if (SUCCEEDED(hr))
86 hr = ITypeInfo_Invoke(pTypeInfo, &This->IBasicVideo_iface, dispIdMember, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
87 ITypeInfo_Release(pTypeInfo);
90 return hr;
93 HRESULT WINAPI BaseControlVideoImpl_get_AvgTimePerFrame(IBasicVideo *iface, REFTIME *pAvgTimePerFrame)
95 VIDEOINFOHEADER *vih;
96 BaseControlVideo *This = impl_from_IBasicVideo(iface);
98 if (!This->pPin->pConnectedTo)
99 return VFW_E_NOT_CONNECTED;
101 TRACE("(%p/%p)->(%p)\n", This, iface, pAvgTimePerFrame);
103 vih = This->pFuncsTable->pfnGetVideoFormat(This);
104 *pAvgTimePerFrame = vih->AvgTimePerFrame;
105 return S_OK;
108 HRESULT WINAPI BaseControlVideoImpl_get_BitRate(IBasicVideo *iface, LONG *pBitRate)
110 VIDEOINFOHEADER *vih;
111 BaseControlVideo *This = impl_from_IBasicVideo(iface);
113 TRACE("(%p/%p)->(%p)\n", This, iface, pBitRate);
115 if (!This->pPin->pConnectedTo)
116 return VFW_E_NOT_CONNECTED;
118 vih = This->pFuncsTable->pfnGetVideoFormat(This);
119 *pBitRate = vih->dwBitRate;
120 return S_OK;
123 HRESULT WINAPI BaseControlVideoImpl_get_BitErrorRate(IBasicVideo *iface, LONG *pBitErrorRate)
125 VIDEOINFOHEADER *vih;
126 BaseControlVideo *This = impl_from_IBasicVideo(iface);
128 TRACE("(%p/%p)->(%p)\n", This, iface, pBitErrorRate);
130 if (!This->pPin->pConnectedTo)
131 return VFW_E_NOT_CONNECTED;
133 vih = This->pFuncsTable->pfnGetVideoFormat(This);
134 *pBitErrorRate = vih->dwBitErrorRate;
135 return S_OK;
138 HRESULT WINAPI BaseControlVideoImpl_get_VideoWidth(IBasicVideo *iface, LONG *pVideoWidth)
140 VIDEOINFOHEADER *vih;
141 BaseControlVideo *This = impl_from_IBasicVideo(iface);
143 TRACE("(%p/%p)->(%p)\n", This, iface, pVideoWidth);
145 vih = This->pFuncsTable->pfnGetVideoFormat(This);
146 *pVideoWidth = vih->bmiHeader.biWidth;
148 return S_OK;
151 HRESULT WINAPI BaseControlVideoImpl_get_VideoHeight(IBasicVideo *iface, LONG *pVideoHeight)
153 VIDEOINFOHEADER *vih;
154 BaseControlVideo *This = impl_from_IBasicVideo(iface);
156 TRACE("(%p/%p)->(%p)\n", This, iface, pVideoHeight);
158 vih = This->pFuncsTable->pfnGetVideoFormat(This);
159 *pVideoHeight = abs(vih->bmiHeader.biHeight);
161 return S_OK;
164 HRESULT WINAPI BaseControlVideoImpl_put_SourceLeft(IBasicVideo *iface, LONG SourceLeft)
166 RECT SourceRect;
167 BaseControlVideo *This = impl_from_IBasicVideo(iface);
169 TRACE("(%p/%p)->(%d)\n", This, iface, SourceLeft);
170 This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
171 SourceRect.left = SourceLeft;
172 This->pFuncsTable->pfnSetSourceRect(This, &SourceRect);
174 return S_OK;
177 HRESULT WINAPI BaseControlVideoImpl_get_SourceLeft(IBasicVideo *iface, LONG *pSourceLeft)
179 RECT SourceRect;
180 BaseControlVideo *This = impl_from_IBasicVideo(iface);
182 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceLeft);
183 This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
184 *pSourceLeft = SourceRect.left;
186 return S_OK;
189 HRESULT WINAPI BaseControlVideoImpl_put_SourceWidth(IBasicVideo *iface, LONG SourceWidth)
191 RECT SourceRect;
192 BaseControlVideo *This = impl_from_IBasicVideo(iface);
194 TRACE("(%p/%p)->(%d)\n", This, iface, SourceWidth);
195 This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
196 SourceRect.right = SourceRect.left + SourceWidth;
197 This->pFuncsTable->pfnSetSourceRect(This, &SourceRect);
199 return S_OK;
202 HRESULT WINAPI BaseControlVideoImpl_get_SourceWidth(IBasicVideo *iface, LONG *pSourceWidth)
204 RECT SourceRect;
205 BaseControlVideo *This = impl_from_IBasicVideo(iface);
207 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceWidth);
208 This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
209 *pSourceWidth = SourceRect.right - SourceRect.left;
211 return S_OK;
214 HRESULT WINAPI BaseControlVideoImpl_put_SourceTop(IBasicVideo *iface, LONG SourceTop)
216 RECT SourceRect;
217 BaseControlVideo *This = impl_from_IBasicVideo(iface);
219 TRACE("(%p/%p)->(%d)\n", This, iface, SourceTop);
220 This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
221 SourceRect.top = SourceTop;
222 This->pFuncsTable->pfnSetSourceRect(This, &SourceRect);
224 return S_OK;
227 HRESULT WINAPI BaseControlVideoImpl_get_SourceTop(IBasicVideo *iface, LONG *pSourceTop)
229 RECT SourceRect;
230 BaseControlVideo *This = impl_from_IBasicVideo(iface);
232 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceTop);
233 This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
234 *pSourceTop = SourceRect.top;
236 return S_OK;
239 HRESULT WINAPI BaseControlVideoImpl_put_SourceHeight(IBasicVideo *iface, LONG SourceHeight)
241 RECT SourceRect;
242 BaseControlVideo *This = impl_from_IBasicVideo(iface);
244 TRACE("(%p/%p)->(%d)\n", This, iface, SourceHeight);
245 This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
246 SourceRect.bottom = SourceRect.top + SourceHeight;
247 This->pFuncsTable->pfnSetSourceRect(This, &SourceRect);
249 return S_OK;
252 HRESULT WINAPI BaseControlVideoImpl_get_SourceHeight(IBasicVideo *iface, LONG *pSourceHeight)
254 RECT SourceRect;
255 BaseControlVideo *This = impl_from_IBasicVideo(iface);
257 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceHeight);
258 This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
260 *pSourceHeight = SourceRect.bottom - SourceRect.top;
262 return S_OK;
265 HRESULT WINAPI BaseControlVideoImpl_put_DestinationLeft(IBasicVideo *iface, LONG DestinationLeft)
267 RECT DestRect;
268 BaseControlVideo *This = impl_from_IBasicVideo(iface);
270 TRACE("(%p/%p)->(%d)\n", This, iface, DestinationLeft);
271 This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
272 DestRect.left = DestinationLeft;
273 This->pFuncsTable->pfnSetTargetRect(This, &DestRect);
275 return S_OK;
278 HRESULT WINAPI BaseControlVideoImpl_get_DestinationLeft(IBasicVideo *iface, LONG *pDestinationLeft)
280 RECT DestRect;
281 BaseControlVideo *This = impl_from_IBasicVideo(iface);
283 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationLeft);
284 This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
285 *pDestinationLeft = DestRect.left;
287 return S_OK;
290 HRESULT WINAPI BaseControlVideoImpl_put_DestinationWidth(IBasicVideo *iface, LONG DestinationWidth)
292 RECT DestRect;
293 BaseControlVideo *This = impl_from_IBasicVideo(iface);
295 TRACE("(%p/%p)->(%d)\n", This, iface, DestinationWidth);
296 This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
297 DestRect.right = DestRect.left + DestinationWidth;
298 This->pFuncsTable->pfnSetTargetRect(This, &DestRect);
300 return S_OK;
303 HRESULT WINAPI BaseControlVideoImpl_get_DestinationWidth(IBasicVideo *iface, LONG *pDestinationWidth)
305 RECT DestRect;
306 BaseControlVideo *This = impl_from_IBasicVideo(iface);
308 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationWidth);
309 This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
310 *pDestinationWidth = DestRect.right - DestRect.left;
312 return S_OK;
315 HRESULT WINAPI BaseControlVideoImpl_put_DestinationTop(IBasicVideo *iface, LONG DestinationTop)
317 RECT DestRect;
318 BaseControlVideo *This = impl_from_IBasicVideo(iface);
320 TRACE("(%p/%p)->(%d)\n", This, iface, DestinationTop);
321 This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
322 DestRect.top = DestinationTop;
323 This->pFuncsTable->pfnSetTargetRect(This, &DestRect);
325 return S_OK;
328 HRESULT WINAPI BaseControlVideoImpl_get_DestinationTop(IBasicVideo *iface, LONG *pDestinationTop)
330 RECT DestRect;
331 BaseControlVideo *This = impl_from_IBasicVideo(iface);
333 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationTop);
334 This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
335 *pDestinationTop = DestRect.top;
337 return S_OK;
340 HRESULT WINAPI BaseControlVideoImpl_put_DestinationHeight(IBasicVideo *iface, LONG DestinationHeight)
342 RECT DestRect;
343 BaseControlVideo *This = impl_from_IBasicVideo(iface);
345 TRACE("(%p/%p)->(%d)\n", This, iface, DestinationHeight);
346 This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
347 DestRect.right = DestRect.left + DestinationHeight;
348 This->pFuncsTable->pfnSetTargetRect(This, &DestRect);
350 return S_OK;
353 HRESULT WINAPI BaseControlVideoImpl_get_DestinationHeight(IBasicVideo *iface, LONG *pDestinationHeight)
355 RECT DestRect;
356 BaseControlVideo *This = impl_from_IBasicVideo(iface);
358 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationHeight);
359 This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
360 *pDestinationHeight = DestRect.right - DestRect.left;
362 return S_OK;
365 HRESULT WINAPI BaseControlVideoImpl_SetSourcePosition(IBasicVideo *iface, LONG Left, LONG Top, LONG Width, LONG Height)
367 RECT SourceRect;
368 BaseControlVideo *This = impl_from_IBasicVideo(iface);
370 TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This, iface, Left, Top, Width, Height);
371 SourceRect.left = Left;
372 SourceRect.top = Top;
373 SourceRect.right = Left + Width;
374 SourceRect.bottom = Top + Height;
375 This->pFuncsTable->pfnSetSourceRect(This, &SourceRect);
377 return S_OK;
380 HRESULT WINAPI BaseControlVideoImpl_GetSourcePosition(IBasicVideo *iface, LONG *pLeft, LONG *pTop, LONG *pWidth, LONG *pHeight)
382 RECT SourceRect;
383 BaseControlVideo *This = impl_from_IBasicVideo(iface);
385 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
386 This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
388 *pLeft = SourceRect.left;
389 *pTop = SourceRect.top;
390 *pWidth = SourceRect.right - SourceRect.left;
391 *pHeight = SourceRect.bottom - SourceRect.top;
393 return S_OK;
396 HRESULT WINAPI BaseControlVideoImpl_SetDefaultSourcePosition(IBasicVideo *iface)
398 BaseControlVideo *This = impl_from_IBasicVideo(iface);
400 TRACE("(%p/%p)->()\n", This, iface);
401 return This->pFuncsTable->pfnSetDefaultSourceRect(This);
404 HRESULT WINAPI BaseControlVideoImpl_SetDestinationPosition(IBasicVideo *iface, LONG Left, LONG Top, LONG Width, LONG Height)
406 RECT DestRect;
407 BaseControlVideo *This = impl_from_IBasicVideo(iface);
409 TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This, iface, Left, Top, Width, Height);
411 DestRect.left = Left;
412 DestRect.top = Top;
413 DestRect.right = Left + Width;
414 DestRect.bottom = Top + Height;
415 This->pFuncsTable->pfnSetTargetRect(This, &DestRect);
417 return S_OK;
420 HRESULT WINAPI BaseControlVideoImpl_GetDestinationPosition(IBasicVideo *iface, LONG *pLeft, LONG *pTop, LONG *pWidth, LONG *pHeight)
422 RECT DestRect;
423 BaseControlVideo *This = impl_from_IBasicVideo(iface);
425 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
426 This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
428 *pLeft = DestRect.left;
429 *pTop = DestRect.top;
430 *pWidth = DestRect.right - DestRect.left;
431 *pHeight = DestRect.bottom - DestRect.top;
433 return S_OK;
436 HRESULT WINAPI BaseControlVideoImpl_SetDefaultDestinationPosition(IBasicVideo *iface)
438 BaseControlVideo *This = impl_from_IBasicVideo(iface);
440 TRACE("(%p/%p)->()\n", This, iface);
441 return This->pFuncsTable->pfnSetDefaultTargetRect(This);
444 HRESULT WINAPI BaseControlVideoImpl_GetVideoSize(IBasicVideo *iface, LONG *pWidth, LONG *pHeight)
446 VIDEOINFOHEADER *vih;
447 BaseControlVideo *This = impl_from_IBasicVideo(iface);
449 TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight);
451 vih = This->pFuncsTable->pfnGetVideoFormat(This);
452 *pHeight = vih->bmiHeader.biHeight;
453 *pWidth = vih->bmiHeader.biWidth;
455 return S_OK;
458 HRESULT WINAPI BaseControlVideoImpl_GetVideoPaletteEntries(IBasicVideo *iface, LONG StartIndex, LONG Entries, LONG *pRetrieved, LONG *pPalette)
460 BaseControlVideo *This = impl_from_IBasicVideo(iface);
462 TRACE("(%p/%p)->(%d, %d, %p, %p)\n", This, iface, StartIndex, Entries, pRetrieved, pPalette);
464 if (pRetrieved)
465 *pRetrieved = 0;
466 return VFW_E_NO_PALETTE_AVAILABLE;
469 HRESULT WINAPI BaseControlVideoImpl_GetCurrentImage(IBasicVideo *iface, LONG *pBufferSize, LONG *pDIBImage)
471 BaseControlVideo *This = impl_from_IBasicVideo(iface);
473 return This->pFuncsTable->pfnGetStaticImage(This, pBufferSize, pDIBImage);
476 HRESULT WINAPI BaseControlVideoImpl_IsUsingDefaultSource(IBasicVideo *iface)
478 BaseControlVideo *This = impl_from_IBasicVideo(iface);
480 return This->pFuncsTable->pfnIsDefaultSourceRect(This);
483 HRESULT WINAPI BaseControlVideoImpl_IsUsingDefaultDestination(IBasicVideo *iface)
485 BaseControlVideo *This = impl_from_IBasicVideo(iface);
487 return This->pFuncsTable->pfnIsDefaultTargetRect(This);