strmbase: Store and use the chosen IMemAllocator instead of getting it from the input...
[wine] / dlls / strmbase / video.c
1 /*
2  * Generic Implementation of strmbase video classes
3  *
4  * Copyright 2012 Aric Stewart, CodeWeavers
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #define COBJMACROS
22
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"
30
31 WINE_DEFAULT_DEBUG_CHANNEL(strmbase);
32
33 static inline BaseControlVideo *impl_from_IBasicVideo(IBasicVideo *iface)
34 {
35     return CONTAINING_RECORD(iface, BaseControlVideo, IBasicVideo_iface);
36 }
37
38 HRESULT WINAPI BaseControlVideo_Init(BaseControlVideo *pControlVideo, const IBasicVideoVtbl *lpVtbl, BaseFilter *owner, CRITICAL_SECTION *lock, BasePin* pPin, const BaseControlVideoFuncTable* pFuncsTable)
39 {
40     pControlVideo->IBasicVideo_iface.lpVtbl = lpVtbl;
41     pControlVideo->pFilter = owner;
42     pControlVideo->pInterfaceLock = lock;
43     pControlVideo->pPin = pPin;
44     pControlVideo->pFuncsTable = pFuncsTable;
45
46     BaseDispatch_Init(&pControlVideo->baseDispatch, &IID_IBasicVideo);
47
48     return S_OK;
49 }
50
51 HRESULT WINAPI BaseControlVideo_Destroy(BaseControlVideo *pControlVideo)
52 {
53     return BaseDispatch_Destroy(&pControlVideo->baseDispatch);
54 }
55
56 HRESULT WINAPI BaseControlVideoImpl_GetTypeInfoCount(IBasicVideo *iface, UINT *pctinfo)
57 {
58     BaseControlVideo *This = impl_from_IBasicVideo(iface);
59
60     return BaseDispatchImpl_GetTypeInfoCount(&This->baseDispatch, pctinfo);
61 }
62
63 HRESULT WINAPI BaseControlVideoImpl_GetTypeInfo(IBasicVideo *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
64 {
65     BaseControlVideo *This = impl_from_IBasicVideo(iface);
66
67     return BaseDispatchImpl_GetTypeInfo(&This->baseDispatch, &IID_NULL, iTInfo, lcid, ppTInfo);
68 }
69
70 HRESULT WINAPI BaseControlVideoImpl_GetIDsOfNames(IBasicVideo *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
71 {
72     BaseControlVideo *This = impl_from_IBasicVideo(iface);
73
74     return BaseDispatchImpl_GetIDsOfNames(&This->baseDispatch, riid, rgszNames, cNames, lcid, rgDispId);
75 }
76
77 HRESULT WINAPI BaseControlVideoImpl_Invoke(IBasicVideo *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExepInfo, UINT *puArgErr)
78 {
79     BaseControlVideo *This = impl_from_IBasicVideo(iface);
80     HRESULT hr = S_OK;
81     ITypeInfo *pTypeInfo;
82
83     hr = BaseDispatchImpl_GetTypeInfo(&This->baseDispatch, riid, 1, lcid, &pTypeInfo);
84     if (SUCCEEDED(hr))
85     {
86         hr = ITypeInfo_Invoke(pTypeInfo, &This->IBasicVideo_iface, dispIdMember, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
87         ITypeInfo_Release(pTypeInfo);
88     }
89
90     return hr;
91 }
92
93 HRESULT WINAPI BaseControlVideoImpl_get_AvgTimePerFrame(IBasicVideo *iface, REFTIME *pAvgTimePerFrame)
94 {
95     VIDEOINFOHEADER *vih;
96     BaseControlVideo *This = impl_from_IBasicVideo(iface);
97
98     if (!This->pPin->pConnectedTo)
99         return VFW_E_NOT_CONNECTED;
100
101     TRACE("(%p/%p)->(%p)\n", This, iface, pAvgTimePerFrame);
102
103     vih = This->pFuncsTable->pfnGetVideoFormat(This);
104     *pAvgTimePerFrame = vih->AvgTimePerFrame;
105     return S_OK;
106 }
107
108 HRESULT WINAPI BaseControlVideoImpl_get_BitRate(IBasicVideo *iface, LONG *pBitRate)
109 {
110     VIDEOINFOHEADER *vih;
111     BaseControlVideo *This = impl_from_IBasicVideo(iface);
112
113     TRACE("(%p/%p)->(%p)\n", This, iface, pBitRate);
114
115     if (!This->pPin->pConnectedTo)
116         return VFW_E_NOT_CONNECTED;
117
118     vih = This->pFuncsTable->pfnGetVideoFormat(This);
119     *pBitRate = vih->dwBitRate;
120     return S_OK;
121 }
122
123 HRESULT WINAPI BaseControlVideoImpl_get_BitErrorRate(IBasicVideo *iface, LONG *pBitErrorRate)
124 {
125     VIDEOINFOHEADER *vih;
126     BaseControlVideo *This = impl_from_IBasicVideo(iface);
127
128     TRACE("(%p/%p)->(%p)\n", This, iface, pBitErrorRate);
129
130     if (!This->pPin->pConnectedTo)
131         return VFW_E_NOT_CONNECTED;
132
133     vih = This->pFuncsTable->pfnGetVideoFormat(This);
134     *pBitErrorRate = vih->dwBitErrorRate;
135     return S_OK;
136 }
137
138 HRESULT WINAPI BaseControlVideoImpl_get_VideoWidth(IBasicVideo *iface, LONG *pVideoWidth)
139 {
140     VIDEOINFOHEADER *vih;
141     BaseControlVideo *This = impl_from_IBasicVideo(iface);
142
143     TRACE("(%p/%p)->(%p)\n", This, iface, pVideoWidth);
144
145     vih = This->pFuncsTable->pfnGetVideoFormat(This);
146     *pVideoWidth = vih->bmiHeader.biWidth;
147
148     return S_OK;
149 }
150
151 HRESULT WINAPI BaseControlVideoImpl_get_VideoHeight(IBasicVideo *iface, LONG *pVideoHeight)
152 {
153     VIDEOINFOHEADER *vih;
154     BaseControlVideo *This = impl_from_IBasicVideo(iface);
155
156     TRACE("(%p/%p)->(%p)\n", This, iface, pVideoHeight);
157
158     vih = This->pFuncsTable->pfnGetVideoFormat(This);
159     *pVideoHeight = abs(vih->bmiHeader.biHeight);
160
161     return S_OK;
162 }
163
164 HRESULT WINAPI BaseControlVideoImpl_put_SourceLeft(IBasicVideo *iface, LONG SourceLeft)
165 {
166     RECT SourceRect;
167     BaseControlVideo *This = impl_from_IBasicVideo(iface);
168
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);
173
174     return S_OK;
175 }
176
177 HRESULT WINAPI BaseControlVideoImpl_get_SourceLeft(IBasicVideo *iface, LONG *pSourceLeft)
178 {
179     RECT SourceRect;
180     BaseControlVideo *This = impl_from_IBasicVideo(iface);
181
182     TRACE("(%p/%p)->(%p)\n", This, iface, pSourceLeft);
183     This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
184     *pSourceLeft = SourceRect.left;
185
186     return S_OK;
187 }
188
189 HRESULT WINAPI BaseControlVideoImpl_put_SourceWidth(IBasicVideo *iface, LONG SourceWidth)
190 {
191     RECT SourceRect;
192     BaseControlVideo *This = impl_from_IBasicVideo(iface);
193
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);
198
199     return S_OK;
200 }
201
202 HRESULT WINAPI BaseControlVideoImpl_get_SourceWidth(IBasicVideo *iface, LONG *pSourceWidth)
203 {
204     RECT SourceRect;
205     BaseControlVideo *This = impl_from_IBasicVideo(iface);
206
207     TRACE("(%p/%p)->(%p)\n", This, iface, pSourceWidth);
208     This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
209     *pSourceWidth = SourceRect.right - SourceRect.left;
210
211     return S_OK;
212 }
213
214 HRESULT WINAPI BaseControlVideoImpl_put_SourceTop(IBasicVideo *iface, LONG SourceTop)
215 {
216     RECT SourceRect;
217     BaseControlVideo *This = impl_from_IBasicVideo(iface);
218
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);
223
224     return S_OK;
225 }
226
227 HRESULT WINAPI BaseControlVideoImpl_get_SourceTop(IBasicVideo *iface, LONG *pSourceTop)
228 {
229     RECT SourceRect;
230     BaseControlVideo *This = impl_from_IBasicVideo(iface);
231
232     TRACE("(%p/%p)->(%p)\n", This, iface, pSourceTop);
233     This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
234     *pSourceTop = SourceRect.top;
235
236     return S_OK;
237 }
238
239 HRESULT WINAPI BaseControlVideoImpl_put_SourceHeight(IBasicVideo *iface, LONG SourceHeight)
240 {
241     RECT SourceRect;
242     BaseControlVideo *This = impl_from_IBasicVideo(iface);
243
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);
248
249     return S_OK;
250 }
251
252 HRESULT WINAPI BaseControlVideoImpl_get_SourceHeight(IBasicVideo *iface, LONG *pSourceHeight)
253 {
254     RECT SourceRect;
255     BaseControlVideo *This = impl_from_IBasicVideo(iface);
256
257     TRACE("(%p/%p)->(%p)\n", This, iface, pSourceHeight);
258     This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
259
260     *pSourceHeight = SourceRect.bottom - SourceRect.top;
261
262     return S_OK;
263 }
264
265 HRESULT WINAPI BaseControlVideoImpl_put_DestinationLeft(IBasicVideo *iface, LONG DestinationLeft)
266 {
267     RECT DestRect;
268     BaseControlVideo *This = impl_from_IBasicVideo(iface);
269
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);
274
275     return S_OK;
276 }
277
278 HRESULT WINAPI BaseControlVideoImpl_get_DestinationLeft(IBasicVideo *iface, LONG *pDestinationLeft)
279 {
280     RECT DestRect;
281     BaseControlVideo *This = impl_from_IBasicVideo(iface);
282
283     TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationLeft);
284     This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
285     *pDestinationLeft = DestRect.left;
286
287     return S_OK;
288 }
289
290 HRESULT WINAPI BaseControlVideoImpl_put_DestinationWidth(IBasicVideo *iface, LONG DestinationWidth)
291 {
292     RECT DestRect;
293     BaseControlVideo *This = impl_from_IBasicVideo(iface);
294
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);
299
300     return S_OK;
301 }
302
303 HRESULT WINAPI BaseControlVideoImpl_get_DestinationWidth(IBasicVideo *iface, LONG *pDestinationWidth)
304 {
305     RECT DestRect;
306     BaseControlVideo *This = impl_from_IBasicVideo(iface);
307
308     TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationWidth);
309     This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
310     *pDestinationWidth = DestRect.right - DestRect.left;
311
312     return S_OK;
313 }
314
315 HRESULT WINAPI BaseControlVideoImpl_put_DestinationTop(IBasicVideo *iface, LONG DestinationTop)
316 {
317     RECT DestRect;
318     BaseControlVideo *This = impl_from_IBasicVideo(iface);
319
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);
324
325     return S_OK;
326 }
327
328 HRESULT WINAPI BaseControlVideoImpl_get_DestinationTop(IBasicVideo *iface, LONG *pDestinationTop)
329 {
330     RECT DestRect;
331     BaseControlVideo *This = impl_from_IBasicVideo(iface);
332
333     TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationTop);
334     This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
335     *pDestinationTop = DestRect.top;
336
337     return S_OK;
338 }
339
340 HRESULT WINAPI BaseControlVideoImpl_put_DestinationHeight(IBasicVideo *iface, LONG DestinationHeight)
341 {
342     RECT DestRect;
343     BaseControlVideo *This = impl_from_IBasicVideo(iface);
344
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);
349
350     return S_OK;
351 }
352
353 HRESULT WINAPI BaseControlVideoImpl_get_DestinationHeight(IBasicVideo *iface, LONG *pDestinationHeight)
354 {
355     RECT DestRect;
356     BaseControlVideo *This = impl_from_IBasicVideo(iface);
357
358     TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationHeight);
359     This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
360     *pDestinationHeight = DestRect.right - DestRect.left;
361
362     return S_OK;
363 }
364
365 HRESULT WINAPI BaseControlVideoImpl_SetSourcePosition(IBasicVideo *iface, LONG Left, LONG Top, LONG Width, LONG Height)
366 {
367     RECT SourceRect;
368     BaseControlVideo *This = impl_from_IBasicVideo(iface);
369
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);
376
377     return S_OK;
378 }
379
380 HRESULT WINAPI BaseControlVideoImpl_GetSourcePosition(IBasicVideo *iface, LONG *pLeft, LONG *pTop, LONG *pWidth, LONG *pHeight)
381 {
382     RECT SourceRect;
383     BaseControlVideo *This = impl_from_IBasicVideo(iface);
384
385     TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
386     This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
387
388     *pLeft = SourceRect.left;
389     *pTop = SourceRect.top;
390     *pWidth = SourceRect.right - SourceRect.left;
391     *pHeight = SourceRect.bottom - SourceRect.top;
392
393     return S_OK;
394 }
395
396 HRESULT WINAPI BaseControlVideoImpl_SetDefaultSourcePosition(IBasicVideo *iface)
397 {
398     BaseControlVideo *This = impl_from_IBasicVideo(iface);
399
400     TRACE("(%p/%p)->()\n", This, iface);
401     return This->pFuncsTable->pfnSetDefaultSourceRect(This);
402 }
403
404 HRESULT WINAPI BaseControlVideoImpl_SetDestinationPosition(IBasicVideo *iface, LONG Left, LONG Top, LONG Width, LONG Height)
405 {
406     RECT DestRect;
407     BaseControlVideo *This = impl_from_IBasicVideo(iface);
408
409     TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This, iface, Left, Top, Width, Height);
410
411     DestRect.left = Left;
412     DestRect.top = Top;
413     DestRect.right = Left + Width;
414     DestRect.bottom = Top + Height;
415     This->pFuncsTable->pfnSetTargetRect(This, &DestRect);
416
417     return S_OK;
418 }
419
420 HRESULT WINAPI BaseControlVideoImpl_GetDestinationPosition(IBasicVideo *iface, LONG *pLeft, LONG *pTop, LONG *pWidth, LONG *pHeight)
421 {
422     RECT DestRect;
423     BaseControlVideo *This = impl_from_IBasicVideo(iface);
424
425     TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
426     This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
427
428     *pLeft = DestRect.left;
429     *pTop = DestRect.top;
430     *pWidth = DestRect.right - DestRect.left;
431     *pHeight = DestRect.bottom - DestRect.top;
432
433     return S_OK;
434 }
435
436 HRESULT WINAPI BaseControlVideoImpl_SetDefaultDestinationPosition(IBasicVideo *iface)
437 {
438     BaseControlVideo *This = impl_from_IBasicVideo(iface);
439
440     TRACE("(%p/%p)->()\n", This, iface);
441     return This->pFuncsTable->pfnSetDefaultTargetRect(This);
442 }
443
444 HRESULT WINAPI BaseControlVideoImpl_GetVideoSize(IBasicVideo *iface, LONG *pWidth, LONG *pHeight)
445 {
446     VIDEOINFOHEADER *vih;
447     BaseControlVideo *This = impl_from_IBasicVideo(iface);
448
449     TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight);
450
451     vih = This->pFuncsTable->pfnGetVideoFormat(This);
452     *pHeight = vih->bmiHeader.biHeight;
453     *pWidth = vih->bmiHeader.biWidth;
454
455     return S_OK;
456 }
457
458 HRESULT WINAPI BaseControlVideoImpl_GetVideoPaletteEntries(IBasicVideo *iface, LONG StartIndex, LONG Entries, LONG *pRetrieved, LONG *pPalette)
459 {
460     BaseControlVideo *This = impl_from_IBasicVideo(iface);
461
462     TRACE("(%p/%p)->(%d, %d, %p, %p)\n", This, iface, StartIndex, Entries, pRetrieved, pPalette);
463
464     if (pRetrieved)
465         *pRetrieved = 0;
466     return VFW_E_NO_PALETTE_AVAILABLE;
467 }
468
469 HRESULT WINAPI BaseControlVideoImpl_GetCurrentImage(IBasicVideo *iface, LONG *pBufferSize, LONG *pDIBImage)
470 {
471     BaseControlVideo *This = impl_from_IBasicVideo(iface);
472
473     return This->pFuncsTable->pfnGetStaticImage(This, pBufferSize, pDIBImage);
474 }
475
476 HRESULT WINAPI BaseControlVideoImpl_IsUsingDefaultSource(IBasicVideo *iface)
477 {
478     BaseControlVideo *This = impl_from_IBasicVideo(iface);
479
480     return This->pFuncsTable->pfnIsDefaultSourceRect(This);
481 }
482
483 HRESULT WINAPI BaseControlVideoImpl_IsUsingDefaultDestination(IBasicVideo *iface)
484 {
485     BaseControlVideo *This = impl_from_IBasicVideo(iface);
486
487     return This->pFuncsTable->pfnIsDefaultTargetRect(This);
488 }