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