1c4f3606f679c28cfd9546549c4fdb04597c25ac
[reactos.git] / reactos / lib / 3rdparty / 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 }