xref: /reactos/sdk/lib/3rdparty/strmbase/video.c (revision 4561998a)
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 static HRESULT BaseControlVideoImpl_CheckSourceRect(BaseControlVideo *This, RECT *pSourceRect)
57 {
58     LONG VideoWidth, VideoHeight;
59     HRESULT hr;
60 
61     if (IsRectEmpty(pSourceRect))
62         return E_INVALIDARG;
63 
64     hr = BaseControlVideoImpl_GetVideoSize((IBasicVideo *)This, &VideoWidth, &VideoHeight);
65     if (FAILED(hr))
66         return hr;
67 
68     if (pSourceRect->top < 0 || pSourceRect->left < 0 ||
69         pSourceRect->bottom > VideoHeight || pSourceRect->right > VideoWidth)
70         return E_INVALIDARG;
71 
72     return S_OK;
73 }
74 
75 static HRESULT BaseControlVideoImpl_CheckTargetRect(BaseControlVideo *This, RECT *pTargetRect)
76 {
77     if (IsRectEmpty(pTargetRect))
78         return E_INVALIDARG;
79 
80     return S_OK;
81 }
82 
83 HRESULT WINAPI BaseControlVideoImpl_GetTypeInfoCount(IBasicVideo *iface, UINT *pctinfo)
84 {
85     BaseControlVideo *This = impl_from_IBasicVideo(iface);
86 
87     return BaseDispatchImpl_GetTypeInfoCount(&This->baseDispatch, pctinfo);
88 }
89 
90 HRESULT WINAPI BaseControlVideoImpl_GetTypeInfo(IBasicVideo *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
91 {
92     BaseControlVideo *This = impl_from_IBasicVideo(iface);
93 
94     return BaseDispatchImpl_GetTypeInfo(&This->baseDispatch, &IID_NULL, iTInfo, lcid, ppTInfo);
95 }
96 
97 HRESULT WINAPI BaseControlVideoImpl_GetIDsOfNames(IBasicVideo *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
98 {
99     BaseControlVideo *This = impl_from_IBasicVideo(iface);
100 
101     return BaseDispatchImpl_GetIDsOfNames(&This->baseDispatch, riid, rgszNames, cNames, lcid, rgDispId);
102 }
103 
104 HRESULT WINAPI BaseControlVideoImpl_Invoke(IBasicVideo *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExepInfo, UINT *puArgErr)
105 {
106     BaseControlVideo *This = impl_from_IBasicVideo(iface);
107     ITypeInfo *pTypeInfo;
108     HRESULT hr;
109 
110     hr = BaseDispatchImpl_GetTypeInfo(&This->baseDispatch, riid, 1, lcid, &pTypeInfo);
111     if (SUCCEEDED(hr))
112     {
113         hr = ITypeInfo_Invoke(pTypeInfo, &This->IBasicVideo_iface, dispIdMember, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
114         ITypeInfo_Release(pTypeInfo);
115     }
116 
117     return hr;
118 }
119 
120 HRESULT WINAPI BaseControlVideoImpl_get_AvgTimePerFrame(IBasicVideo *iface, REFTIME *pAvgTimePerFrame)
121 {
122     VIDEOINFOHEADER *vih;
123     BaseControlVideo *This = impl_from_IBasicVideo(iface);
124 
125     if (!pAvgTimePerFrame)
126         return E_POINTER;
127     if (!This->pPin->pConnectedTo)
128         return VFW_E_NOT_CONNECTED;
129 
130     TRACE("(%p/%p)->(%p)\n", This, iface, pAvgTimePerFrame);
131 
132     vih = This->pFuncsTable->pfnGetVideoFormat(This);
133     *pAvgTimePerFrame = vih->AvgTimePerFrame;
134     return S_OK;
135 }
136 
137 HRESULT WINAPI BaseControlVideoImpl_get_BitRate(IBasicVideo *iface, LONG *pBitRate)
138 {
139     VIDEOINFOHEADER *vih;
140     BaseControlVideo *This = impl_from_IBasicVideo(iface);
141 
142     TRACE("(%p/%p)->(%p)\n", This, iface, pBitRate);
143 
144     if (!pBitRate)
145         return E_POINTER;
146     if (!This->pPin->pConnectedTo)
147         return VFW_E_NOT_CONNECTED;
148 
149     vih = This->pFuncsTable->pfnGetVideoFormat(This);
150     *pBitRate = vih->dwBitRate;
151     return S_OK;
152 }
153 
154 HRESULT WINAPI BaseControlVideoImpl_get_BitErrorRate(IBasicVideo *iface, LONG *pBitErrorRate)
155 {
156     VIDEOINFOHEADER *vih;
157     BaseControlVideo *This = impl_from_IBasicVideo(iface);
158 
159     TRACE("(%p/%p)->(%p)\n", This, iface, pBitErrorRate);
160 
161     if (!pBitErrorRate)
162         return E_POINTER;
163     if (!This->pPin->pConnectedTo)
164         return VFW_E_NOT_CONNECTED;
165 
166     vih = This->pFuncsTable->pfnGetVideoFormat(This);
167     *pBitErrorRate = vih->dwBitErrorRate;
168     return S_OK;
169 }
170 
171 HRESULT WINAPI BaseControlVideoImpl_get_VideoWidth(IBasicVideo *iface, LONG *pVideoWidth)
172 {
173     VIDEOINFOHEADER *vih;
174     BaseControlVideo *This = impl_from_IBasicVideo(iface);
175 
176     TRACE("(%p/%p)->(%p)\n", This, iface, pVideoWidth);
177     if (!pVideoWidth)
178         return E_POINTER;
179 
180     vih = This->pFuncsTable->pfnGetVideoFormat(This);
181     *pVideoWidth = vih->bmiHeader.biWidth;
182 
183     return S_OK;
184 }
185 
186 HRESULT WINAPI BaseControlVideoImpl_get_VideoHeight(IBasicVideo *iface, LONG *pVideoHeight)
187 {
188     VIDEOINFOHEADER *vih;
189     BaseControlVideo *This = impl_from_IBasicVideo(iface);
190 
191     TRACE("(%p/%p)->(%p)\n", This, iface, pVideoHeight);
192     if (!pVideoHeight)
193         return E_POINTER;
194 
195     vih = This->pFuncsTable->pfnGetVideoFormat(This);
196     *pVideoHeight = abs(vih->bmiHeader.biHeight);
197 
198     return S_OK;
199 }
200 
201 HRESULT WINAPI BaseControlVideoImpl_put_SourceLeft(IBasicVideo *iface, LONG SourceLeft)
202 {
203     RECT SourceRect;
204     BaseControlVideo *This = impl_from_IBasicVideo(iface);
205     HRESULT hr;
206 
207     TRACE("(%p/%p)->(%d)\n", This, iface, SourceLeft);
208     hr = This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
209     if (SUCCEEDED(hr))
210     {
211         SourceRect.right = (SourceRect.right - SourceRect.left) + SourceLeft;
212         SourceRect.left = SourceLeft;
213         hr = BaseControlVideoImpl_CheckSourceRect(This, &SourceRect);
214     }
215     if (SUCCEEDED(hr))
216         hr = This->pFuncsTable->pfnSetSourceRect(This, &SourceRect);
217 
218     return hr;
219 }
220 
221 HRESULT WINAPI BaseControlVideoImpl_get_SourceLeft(IBasicVideo *iface, LONG *pSourceLeft)
222 {
223     RECT SourceRect;
224     BaseControlVideo *This = impl_from_IBasicVideo(iface);
225 
226     TRACE("(%p/%p)->(%p)\n", This, iface, pSourceLeft);
227     if (!pSourceLeft)
228         return E_POINTER;
229     This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
230     *pSourceLeft = SourceRect.left;
231 
232     return S_OK;
233 }
234 
235 HRESULT WINAPI BaseControlVideoImpl_put_SourceWidth(IBasicVideo *iface, LONG SourceWidth)
236 {
237     RECT SourceRect;
238     BaseControlVideo *This = impl_from_IBasicVideo(iface);
239     HRESULT hr;
240 
241     TRACE("(%p/%p)->(%d)\n", This, iface, SourceWidth);
242     hr = This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
243     if (SUCCEEDED(hr))
244     {
245         SourceRect.right = SourceRect.left + SourceWidth;
246         hr = BaseControlVideoImpl_CheckSourceRect(This, &SourceRect);
247     }
248     if (SUCCEEDED(hr))
249         hr = This->pFuncsTable->pfnSetSourceRect(This, &SourceRect);
250 
251     return hr;
252 }
253 
254 HRESULT WINAPI BaseControlVideoImpl_get_SourceWidth(IBasicVideo *iface, LONG *pSourceWidth)
255 {
256     RECT SourceRect;
257     BaseControlVideo *This = impl_from_IBasicVideo(iface);
258 
259     TRACE("(%p/%p)->(%p)\n", This, iface, pSourceWidth);
260     if (!pSourceWidth)
261         return E_POINTER;
262     This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
263     *pSourceWidth = SourceRect.right - SourceRect.left;
264 
265     return S_OK;
266 }
267 
268 HRESULT WINAPI BaseControlVideoImpl_put_SourceTop(IBasicVideo *iface, LONG SourceTop)
269 {
270     RECT SourceRect;
271     BaseControlVideo *This = impl_from_IBasicVideo(iface);
272     HRESULT hr;
273 
274     TRACE("(%p/%p)->(%d)\n", This, iface, SourceTop);
275     hr = This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
276     if (SUCCEEDED(hr))
277     {
278         SourceRect.bottom = (SourceRect.bottom - SourceRect.top) + SourceTop;
279         SourceRect.top = SourceTop;
280         hr = BaseControlVideoImpl_CheckSourceRect(This, &SourceRect);
281     }
282     if (SUCCEEDED(hr))
283         hr = This->pFuncsTable->pfnSetSourceRect(This, &SourceRect);
284 
285     return hr;
286 }
287 
288 HRESULT WINAPI BaseControlVideoImpl_get_SourceTop(IBasicVideo *iface, LONG *pSourceTop)
289 {
290     RECT SourceRect;
291     BaseControlVideo *This = impl_from_IBasicVideo(iface);
292 
293     TRACE("(%p/%p)->(%p)\n", This, iface, pSourceTop);
294     if (!pSourceTop)
295         return E_POINTER;
296     This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
297     *pSourceTop = SourceRect.top;
298 
299     return S_OK;
300 }
301 
302 HRESULT WINAPI BaseControlVideoImpl_put_SourceHeight(IBasicVideo *iface, LONG SourceHeight)
303 {
304     RECT SourceRect;
305     BaseControlVideo *This = impl_from_IBasicVideo(iface);
306     HRESULT hr;
307 
308     TRACE("(%p/%p)->(%d)\n", This, iface, SourceHeight);
309     hr = This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
310     if (SUCCEEDED(hr))
311     {
312         SourceRect.bottom = SourceRect.top + SourceHeight;
313         hr = BaseControlVideoImpl_CheckSourceRect(This, &SourceRect);
314     }
315     if (SUCCEEDED(hr))
316         hr = This->pFuncsTable->pfnSetSourceRect(This, &SourceRect);
317 
318     return hr;
319 }
320 
321 HRESULT WINAPI BaseControlVideoImpl_get_SourceHeight(IBasicVideo *iface, LONG *pSourceHeight)
322 {
323     RECT SourceRect;
324     BaseControlVideo *This = impl_from_IBasicVideo(iface);
325 
326     TRACE("(%p/%p)->(%p)\n", This, iface, pSourceHeight);
327     if (!pSourceHeight)
328         return E_POINTER;
329     This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
330 
331     *pSourceHeight = SourceRect.bottom - SourceRect.top;
332 
333     return S_OK;
334 }
335 
336 HRESULT WINAPI BaseControlVideoImpl_put_DestinationLeft(IBasicVideo *iface, LONG DestinationLeft)
337 {
338     RECT DestRect;
339     BaseControlVideo *This = impl_from_IBasicVideo(iface);
340     HRESULT hr;
341 
342     TRACE("(%p/%p)->(%d)\n", This, iface, DestinationLeft);
343     hr = This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
344     if (SUCCEEDED(hr))
345     {
346         DestRect.right = (DestRect.right - DestRect.left) + DestinationLeft;
347         DestRect.left = DestinationLeft;
348         hr = BaseControlVideoImpl_CheckTargetRect(This, &DestRect);
349     }
350     if (SUCCEEDED(hr))
351         hr = This->pFuncsTable->pfnSetTargetRect(This, &DestRect);
352 
353     return hr;
354 }
355 
356 HRESULT WINAPI BaseControlVideoImpl_get_DestinationLeft(IBasicVideo *iface, LONG *pDestinationLeft)
357 {
358     RECT DestRect;
359     BaseControlVideo *This = impl_from_IBasicVideo(iface);
360 
361     TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationLeft);
362     if (!pDestinationLeft)
363         return E_POINTER;
364     This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
365     *pDestinationLeft = DestRect.left;
366 
367     return S_OK;
368 }
369 
370 HRESULT WINAPI BaseControlVideoImpl_put_DestinationWidth(IBasicVideo *iface, LONG DestinationWidth)
371 {
372     RECT DestRect;
373     BaseControlVideo *This = impl_from_IBasicVideo(iface);
374     HRESULT hr;
375 
376     TRACE("(%p/%p)->(%d)\n", This, iface, DestinationWidth);
377     hr = This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
378     if (SUCCEEDED(hr))
379     {
380         DestRect.right = DestRect.left + DestinationWidth;
381         hr = BaseControlVideoImpl_CheckTargetRect(This, &DestRect);
382     }
383     if (SUCCEEDED(hr))
384         hr = This->pFuncsTable->pfnSetTargetRect(This, &DestRect);
385 
386     return hr;
387 }
388 
389 HRESULT WINAPI BaseControlVideoImpl_get_DestinationWidth(IBasicVideo *iface, LONG *pDestinationWidth)
390 {
391     RECT DestRect;
392     BaseControlVideo *This = impl_from_IBasicVideo(iface);
393 
394     TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationWidth);
395     if (!pDestinationWidth)
396         return E_POINTER;
397     This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
398     *pDestinationWidth = DestRect.right - DestRect.left;
399 
400     return S_OK;
401 }
402 
403 HRESULT WINAPI BaseControlVideoImpl_put_DestinationTop(IBasicVideo *iface, LONG DestinationTop)
404 {
405     RECT DestRect;
406     BaseControlVideo *This = impl_from_IBasicVideo(iface);
407     HRESULT hr;
408 
409     TRACE("(%p/%p)->(%d)\n", This, iface, DestinationTop);
410     hr = This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
411     if (SUCCEEDED(hr))
412     {
413         DestRect.bottom = (DestRect.bottom - DestRect.top) + DestinationTop;
414         DestRect.top = DestinationTop;
415         hr = BaseControlVideoImpl_CheckTargetRect(This, &DestRect);
416     }
417     if (SUCCEEDED(hr))
418         hr = This->pFuncsTable->pfnSetTargetRect(This, &DestRect);
419 
420     return hr;
421 }
422 
423 HRESULT WINAPI BaseControlVideoImpl_get_DestinationTop(IBasicVideo *iface, LONG *pDestinationTop)
424 {
425     RECT DestRect;
426     BaseControlVideo *This = impl_from_IBasicVideo(iface);
427 
428     TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationTop);
429     if (!pDestinationTop)
430         return E_POINTER;
431     This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
432     *pDestinationTop = DestRect.top;
433 
434     return S_OK;
435 }
436 
437 HRESULT WINAPI BaseControlVideoImpl_put_DestinationHeight(IBasicVideo *iface, LONG DestinationHeight)
438 {
439     RECT DestRect;
440     BaseControlVideo *This = impl_from_IBasicVideo(iface);
441     HRESULT hr;
442 
443     TRACE("(%p/%p)->(%d)\n", This, iface, DestinationHeight);
444     hr = This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
445     if (SUCCEEDED(hr))
446     {
447         DestRect.bottom = DestRect.top + DestinationHeight;
448         hr = BaseControlVideoImpl_CheckTargetRect(This, &DestRect);
449     }
450     if (SUCCEEDED(hr))
451         hr = This->pFuncsTable->pfnSetTargetRect(This, &DestRect);
452 
453     return hr;
454 }
455 
456 HRESULT WINAPI BaseControlVideoImpl_get_DestinationHeight(IBasicVideo *iface, LONG *pDestinationHeight)
457 {
458     RECT DestRect;
459     BaseControlVideo *This = impl_from_IBasicVideo(iface);
460 
461     TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationHeight);
462     if (!pDestinationHeight)
463         return E_POINTER;
464     This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
465     *pDestinationHeight = DestRect.bottom - DestRect.top;
466 
467     return S_OK;
468 }
469 
470 HRESULT WINAPI BaseControlVideoImpl_SetSourcePosition(IBasicVideo *iface, LONG Left, LONG Top, LONG Width, LONG Height)
471 {
472     RECT SourceRect;
473     BaseControlVideo *This = impl_from_IBasicVideo(iface);
474 
475     TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This, iface, Left, Top, Width, Height);
476 
477     SetRect(&SourceRect, Left, Top, Left + Width, Top + Height);
478     if (FAILED(BaseControlVideoImpl_CheckSourceRect(This, &SourceRect)))
479         return E_INVALIDARG;
480     return This->pFuncsTable->pfnSetSourceRect(This, &SourceRect);
481 }
482 
483 HRESULT WINAPI BaseControlVideoImpl_GetSourcePosition(IBasicVideo *iface, LONG *pLeft, LONG *pTop, LONG *pWidth, LONG *pHeight)
484 {
485     RECT SourceRect;
486     BaseControlVideo *This = impl_from_IBasicVideo(iface);
487 
488     TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
489     if (!pLeft || !pTop || !pWidth || !pHeight)
490         return E_POINTER;
491     This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
492 
493     *pLeft = SourceRect.left;
494     *pTop = SourceRect.top;
495     *pWidth = SourceRect.right - SourceRect.left;
496     *pHeight = SourceRect.bottom - SourceRect.top;
497 
498     return S_OK;
499 }
500 
501 HRESULT WINAPI BaseControlVideoImpl_SetDefaultSourcePosition(IBasicVideo *iface)
502 {
503     BaseControlVideo *This = impl_from_IBasicVideo(iface);
504 
505     TRACE("(%p/%p)->()\n", This, iface);
506     return This->pFuncsTable->pfnSetDefaultSourceRect(This);
507 }
508 
509 HRESULT WINAPI BaseControlVideoImpl_SetDestinationPosition(IBasicVideo *iface, LONG Left, LONG Top, LONG Width, LONG Height)
510 {
511     RECT DestRect;
512     BaseControlVideo *This = impl_from_IBasicVideo(iface);
513 
514     TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This, iface, Left, Top, Width, Height);
515 
516     SetRect(&DestRect, Left, Top, Left + Width, Top + Height);
517     if (FAILED(BaseControlVideoImpl_CheckTargetRect(This, &DestRect)))
518         return E_INVALIDARG;
519     return This->pFuncsTable->pfnSetTargetRect(This, &DestRect);
520 }
521 
522 HRESULT WINAPI BaseControlVideoImpl_GetDestinationPosition(IBasicVideo *iface, LONG *pLeft, LONG *pTop, LONG *pWidth, LONG *pHeight)
523 {
524     RECT DestRect;
525     BaseControlVideo *This = impl_from_IBasicVideo(iface);
526 
527     TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
528     if (!pLeft || !pTop || !pWidth || !pHeight)
529         return E_POINTER;
530     This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
531 
532     *pLeft = DestRect.left;
533     *pTop = DestRect.top;
534     *pWidth = DestRect.right - DestRect.left;
535     *pHeight = DestRect.bottom - DestRect.top;
536 
537     return S_OK;
538 }
539 
540 HRESULT WINAPI BaseControlVideoImpl_SetDefaultDestinationPosition(IBasicVideo *iface)
541 {
542     BaseControlVideo *This = impl_from_IBasicVideo(iface);
543 
544     TRACE("(%p/%p)->()\n", This, iface);
545     return This->pFuncsTable->pfnSetDefaultTargetRect(This);
546 }
547 
548 HRESULT WINAPI BaseControlVideoImpl_GetVideoSize(IBasicVideo *iface, LONG *pWidth, LONG *pHeight)
549 {
550     VIDEOINFOHEADER *vih;
551     BaseControlVideo *This = impl_from_IBasicVideo(iface);
552 
553     TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight);
554     if (!pWidth || !pHeight)
555         return E_POINTER;
556 
557     vih = This->pFuncsTable->pfnGetVideoFormat(This);
558     *pHeight = vih->bmiHeader.biHeight;
559     *pWidth = vih->bmiHeader.biWidth;
560 
561     return S_OK;
562 }
563 
564 HRESULT WINAPI BaseControlVideoImpl_GetVideoPaletteEntries(IBasicVideo *iface, LONG StartIndex, LONG Entries, LONG *pRetrieved, LONG *pPalette)
565 {
566     BaseControlVideo *This = impl_from_IBasicVideo(iface);
567 
568     TRACE("(%p/%p)->(%d, %d, %p, %p)\n", This, iface, StartIndex, Entries, pRetrieved, pPalette);
569     if (!pRetrieved || !pPalette)
570         return E_POINTER;
571 
572     *pRetrieved = 0;
573     return VFW_E_NO_PALETTE_AVAILABLE;
574 }
575 
576 HRESULT WINAPI BaseControlVideoImpl_GetCurrentImage(IBasicVideo *iface, LONG *pBufferSize, LONG *pDIBImage)
577 {
578     BaseControlVideo *This = impl_from_IBasicVideo(iface);
579     if (!pBufferSize || !pDIBImage)
580         return E_POINTER;
581 
582     return This->pFuncsTable->pfnGetStaticImage(This, pBufferSize, pDIBImage);
583 }
584 
585 HRESULT WINAPI BaseControlVideoImpl_IsUsingDefaultSource(IBasicVideo *iface)
586 {
587     BaseControlVideo *This = impl_from_IBasicVideo(iface);
588 
589     return This->pFuncsTable->pfnIsDefaultSourceRect(This);
590 }
591 
592 HRESULT WINAPI BaseControlVideoImpl_IsUsingDefaultDestination(IBasicVideo *iface)
593 {
594     BaseControlVideo *This = impl_from_IBasicVideo(iface);
595 
596     return This->pFuncsTable->pfnIsDefaultTargetRect(This);
597 }
598