Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/strmbase/pospass.c
8723 views
1
/*
2
* Filter Seeking and Control Interfaces
3
*
4
* Copyright 2003 Robert Shearman
5
* Copyright 2012 Aric Stewart, CodeWeavers
6
*
7
* This library is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
11
*
12
* This library is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
16
*
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this library; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20
*/
21
/* FIXME: critical sections */
22
23
#define COBJMACROS
24
#include "wine/strmbase.h"
25
#include "wine/debug.h"
26
27
WINE_DEFAULT_DEBUG_CHANNEL(quartz);
28
29
static struct strmbase_passthrough *impl_from_ISeekingPassThru(ISeekingPassThru *iface)
30
{
31
return CONTAINING_RECORD(iface, struct strmbase_passthrough, ISeekingPassThru_iface);
32
}
33
34
static struct strmbase_passthrough *impl_from_IMediaSeeking(IMediaSeeking *iface)
35
{
36
return CONTAINING_RECORD(iface, struct strmbase_passthrough, IMediaSeeking_iface);
37
}
38
39
static struct strmbase_passthrough *impl_from_IMediaPosition(IMediaPosition *iface)
40
{
41
return CONTAINING_RECORD(iface, struct strmbase_passthrough, IMediaPosition_iface);
42
}
43
44
static HRESULT WINAPI SeekingPassThru_QueryInterface(ISeekingPassThru *iface, REFIID iid, void **out)
45
{
46
struct strmbase_passthrough *passthrough = impl_from_ISeekingPassThru(iface);
47
48
return IUnknown_QueryInterface(passthrough->outer_unk, iid, out);
49
}
50
51
static ULONG WINAPI SeekingPassThru_AddRef(ISeekingPassThru *iface)
52
{
53
struct strmbase_passthrough *passthrough = impl_from_ISeekingPassThru(iface);
54
55
return IUnknown_AddRef(passthrough->outer_unk);
56
}
57
58
static ULONG WINAPI SeekingPassThru_Release(ISeekingPassThru *iface)
59
{
60
struct strmbase_passthrough *passthrough = impl_from_ISeekingPassThru(iface);
61
62
return IUnknown_Release(passthrough->outer_unk);
63
}
64
65
static HRESULT WINAPI SeekingPassThru_Init(ISeekingPassThru *iface, BOOL renderer, IPin *pin)
66
{
67
struct strmbase_passthrough *This = impl_from_ISeekingPassThru(iface);
68
69
TRACE("(%p/%p)->(%d, %p)\n", This, iface, renderer, pin);
70
71
if (This->pin)
72
FIXME("Re-initializing?\n");
73
74
This->renderer = renderer;
75
This->pin = pin;
76
77
return S_OK;
78
}
79
80
static const ISeekingPassThruVtbl ISeekingPassThru_Vtbl =
81
{
82
SeekingPassThru_QueryInterface,
83
SeekingPassThru_AddRef,
84
SeekingPassThru_Release,
85
SeekingPassThru_Init
86
};
87
88
static HRESULT WINAPI MediaSeekingPassThru_QueryInterface(IMediaSeeking *iface, REFIID iid, void **out)
89
{
90
struct strmbase_passthrough *passthrough = impl_from_IMediaSeeking(iface);
91
92
return IUnknown_QueryInterface(passthrough->outer_unk, iid, out);
93
}
94
95
static ULONG WINAPI MediaSeekingPassThru_AddRef(IMediaSeeking *iface)
96
{
97
struct strmbase_passthrough *passthrough = impl_from_IMediaSeeking(iface);
98
99
return IUnknown_AddRef(passthrough->outer_unk);
100
}
101
102
static ULONG WINAPI MediaSeekingPassThru_Release(IMediaSeeking *iface)
103
{
104
struct strmbase_passthrough *passthrough = impl_from_IMediaSeeking(iface);
105
106
return IUnknown_Release(passthrough->outer_unk);
107
}
108
109
static HRESULT get_connected(struct strmbase_passthrough *This, REFIID riid, void **ppvObj)
110
{
111
HRESULT hr;
112
IPin *pin;
113
*ppvObj = NULL;
114
hr = IPin_ConnectedTo(This->pin, &pin);
115
if (FAILED(hr))
116
return VFW_E_NOT_CONNECTED;
117
hr = IPin_QueryInterface(pin, riid, ppvObj);
118
IPin_Release(pin);
119
if (FAILED(hr))
120
hr = E_NOTIMPL;
121
return hr;
122
}
123
124
static HRESULT WINAPI MediaSeekingPassThru_GetCapabilities(IMediaSeeking * iface, DWORD * pCapabilities)
125
{
126
struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
127
IMediaSeeking *seek;
128
HRESULT hr;
129
TRACE("(%p/%p)->(%p)\n", iface, This, pCapabilities);
130
hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
131
if (SUCCEEDED(hr)) {
132
hr = IMediaSeeking_GetCapabilities(seek, pCapabilities);
133
IMediaSeeking_Release(seek);
134
}
135
else
136
return E_NOTIMPL;
137
return hr;
138
}
139
140
static HRESULT WINAPI MediaSeekingPassThru_CheckCapabilities(IMediaSeeking * iface, DWORD * pCapabilities)
141
{
142
struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
143
IMediaSeeking *seek;
144
HRESULT hr;
145
TRACE("(%p/%p)->(%p)\n", iface, This, pCapabilities);
146
hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
147
if (SUCCEEDED(hr)) {
148
hr = IMediaSeeking_CheckCapabilities(seek, pCapabilities);
149
IMediaSeeking_Release(seek);
150
}
151
else
152
return E_NOTIMPL;
153
return hr;
154
}
155
156
static HRESULT WINAPI MediaSeekingPassThru_IsFormatSupported(IMediaSeeking * iface, const GUID * pFormat)
157
{
158
struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
159
IMediaSeeking *seek;
160
HRESULT hr;
161
TRACE("(%p/%p)->(%s)\n", iface, This, debugstr_guid(pFormat));
162
hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
163
if (SUCCEEDED(hr)) {
164
hr = IMediaSeeking_IsFormatSupported(seek, pFormat);
165
IMediaSeeking_Release(seek);
166
}
167
else
168
return E_NOTIMPL;
169
return hr;
170
}
171
172
static HRESULT WINAPI MediaSeekingPassThru_QueryPreferredFormat(IMediaSeeking * iface, GUID * pFormat)
173
{
174
struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
175
IMediaSeeking *seek;
176
HRESULT hr;
177
TRACE("(%p/%p)->(%p)\n", iface, This, pFormat);
178
hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
179
if (SUCCEEDED(hr)) {
180
hr = IMediaSeeking_QueryPreferredFormat(seek, pFormat);
181
IMediaSeeking_Release(seek);
182
}
183
else
184
return E_NOTIMPL;
185
return hr;
186
}
187
188
static HRESULT WINAPI MediaSeekingPassThru_GetTimeFormat(IMediaSeeking * iface, GUID * pFormat)
189
{
190
struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
191
IMediaSeeking *seek;
192
HRESULT hr;
193
TRACE("(%p/%p)->(%p)\n", iface, This, pFormat);
194
hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
195
if (SUCCEEDED(hr)) {
196
hr = IMediaSeeking_GetTimeFormat(seek, pFormat);
197
IMediaSeeking_Release(seek);
198
}
199
else
200
return E_NOTIMPL;
201
return hr;
202
}
203
204
static HRESULT WINAPI MediaSeekingPassThru_IsUsingTimeFormat(IMediaSeeking * iface, const GUID * pFormat)
205
{
206
struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
207
IMediaSeeking *seek;
208
HRESULT hr;
209
TRACE("(%p/%p)->(%s)\n", iface, This, debugstr_guid(pFormat));
210
hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
211
if (SUCCEEDED(hr)) {
212
hr = IMediaSeeking_IsUsingTimeFormat(seek, pFormat);
213
IMediaSeeking_Release(seek);
214
}
215
else
216
return E_NOTIMPL;
217
return hr;
218
}
219
220
static HRESULT WINAPI MediaSeekingPassThru_SetTimeFormat(IMediaSeeking * iface, const GUID * pFormat)
221
{
222
struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
223
IMediaSeeking *seek;
224
HRESULT hr;
225
TRACE("(%p/%p)->(%s)\n", iface, This, debugstr_guid(pFormat));
226
hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
227
if (SUCCEEDED(hr)) {
228
hr = IMediaSeeking_SetTimeFormat(seek, pFormat);
229
IMediaSeeking_Release(seek);
230
}
231
else
232
return E_NOTIMPL;
233
return hr;
234
}
235
236
static HRESULT WINAPI MediaSeekingPassThru_GetDuration(IMediaSeeking * iface, LONGLONG * pDuration)
237
{
238
struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
239
IMediaSeeking *seek;
240
HRESULT hr;
241
TRACE("(%p/%p)->(%p)\n", iface, This, pDuration);
242
hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
243
if (SUCCEEDED(hr)) {
244
hr = IMediaSeeking_GetDuration(seek, pDuration);
245
IMediaSeeking_Release(seek);
246
}
247
else
248
return E_NOTIMPL;
249
return hr;
250
}
251
252
static HRESULT WINAPI MediaSeekingPassThru_GetStopPosition(IMediaSeeking * iface, LONGLONG * pStop)
253
{
254
struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
255
IMediaSeeking *seek;
256
HRESULT hr;
257
TRACE("(%p/%p)->(%p)\n", iface, This, pStop);
258
hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
259
if (SUCCEEDED(hr)) {
260
hr = IMediaSeeking_GetStopPosition(seek, pStop);
261
IMediaSeeking_Release(seek);
262
}
263
else
264
return E_NOTIMPL;
265
return hr;
266
}
267
268
static HRESULT WINAPI MediaSeekingPassThru_GetCurrentPosition(IMediaSeeking * iface, LONGLONG * pCurrent)
269
{
270
struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
271
IMediaSeeking *seek;
272
HRESULT hr = S_OK;
273
TRACE("(%p/%p)->(%p)\n", iface, This, pCurrent);
274
if (!pCurrent)
275
return E_POINTER;
276
EnterCriticalSection(&This->time_cs);
277
if (This->timevalid)
278
*pCurrent = This->time_earliest;
279
else
280
hr = E_FAIL;
281
LeaveCriticalSection(&This->time_cs);
282
if (SUCCEEDED(hr)) {
283
hr = IMediaSeeking_ConvertTimeFormat(iface, pCurrent, NULL, *pCurrent, &TIME_FORMAT_MEDIA_TIME);
284
return hr;
285
}
286
hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
287
if (SUCCEEDED(hr)) {
288
hr = IMediaSeeking_GetCurrentPosition(seek, pCurrent);
289
IMediaSeeking_Release(seek);
290
}
291
else
292
return E_NOTIMPL;
293
return hr;
294
}
295
296
static HRESULT WINAPI MediaSeekingPassThru_ConvertTimeFormat(IMediaSeeking * iface, LONGLONG * pTarget, const GUID * pTargetFormat, LONGLONG Source, const GUID * pSourceFormat)
297
{
298
struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
299
IMediaSeeking *seek;
300
HRESULT hr;
301
302
TRACE("iface %p, target %p, target_format %s, source %s, source_format %s.\n",
303
iface, pTarget, debugstr_guid(pTargetFormat),
304
wine_dbgstr_longlong(Source), debugstr_guid(pSourceFormat));
305
306
hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
307
if (SUCCEEDED(hr)) {
308
hr = IMediaSeeking_ConvertTimeFormat(seek, pTarget, pTargetFormat, Source, pSourceFormat);
309
IMediaSeeking_Release(seek);
310
}
311
else
312
return E_NOTIMPL;
313
return hr;
314
}
315
316
static HRESULT WINAPI MediaSeekingPassThru_SetPositions(IMediaSeeking * iface, LONGLONG * pCurrent, DWORD dwCurrentFlags, LONGLONG * pStop, DWORD dwStopFlags)
317
{
318
struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
319
IMediaSeeking *seek;
320
HRESULT hr;
321
322
TRACE("iface %p, current %p, current_flags %#lx, stop %p, stop_flags %#lx.\n",
323
iface, pCurrent, dwCurrentFlags, pStop, dwStopFlags);
324
325
hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
326
if (SUCCEEDED(hr)) {
327
hr = IMediaSeeking_SetPositions(seek, pCurrent, dwCurrentFlags, pStop, dwStopFlags);
328
IMediaSeeking_Release(seek);
329
} else if (hr == VFW_E_NOT_CONNECTED)
330
hr = S_OK;
331
return hr;
332
}
333
334
static HRESULT WINAPI MediaSeekingPassThru_GetPositions(IMediaSeeking * iface, LONGLONG * pCurrent, LONGLONG * pStop)
335
{
336
struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
337
IMediaSeeking *seek;
338
HRESULT hr;
339
TRACE("(%p/%p)->(%p, %p)\n", iface, This, pCurrent, pStop);
340
hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
341
if (SUCCEEDED(hr)) {
342
hr = IMediaSeeking_GetPositions(seek, pCurrent, pStop);
343
IMediaSeeking_Release(seek);
344
}
345
else
346
return E_NOTIMPL;
347
return hr;
348
}
349
350
static HRESULT WINAPI MediaSeekingPassThru_GetAvailable(IMediaSeeking * iface, LONGLONG * pEarliest, LONGLONG * pLatest)
351
{
352
struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
353
IMediaSeeking *seek;
354
HRESULT hr;
355
TRACE("(%p/%p)->(%p,%p)\n", iface, This, pEarliest, pLatest);
356
hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
357
if (SUCCEEDED(hr)) {
358
hr = IMediaSeeking_GetAvailable(seek, pEarliest, pLatest);
359
IMediaSeeking_Release(seek);
360
}
361
else
362
return E_NOTIMPL;
363
return hr;
364
}
365
366
static HRESULT WINAPI MediaSeekingPassThru_SetRate(IMediaSeeking * iface, double dRate)
367
{
368
struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
369
IMediaSeeking *seek;
370
HRESULT hr;
371
TRACE("(%p/%p)->(%e)\n", iface, This, dRate);
372
hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
373
if (SUCCEEDED(hr)) {
374
hr = IMediaSeeking_SetRate(seek, dRate);
375
IMediaSeeking_Release(seek);
376
}
377
else
378
return E_NOTIMPL;
379
return hr;
380
}
381
382
static HRESULT WINAPI MediaSeekingPassThru_GetRate(IMediaSeeking * iface, double * dRate)
383
{
384
struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
385
IMediaSeeking *seek;
386
HRESULT hr;
387
TRACE("(%p/%p)->(%p)\n", iface, This, dRate);
388
hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
389
if (SUCCEEDED(hr)) {
390
hr = IMediaSeeking_GetRate(seek, dRate);
391
IMediaSeeking_Release(seek);
392
}
393
else
394
return E_NOTIMPL;
395
return hr;
396
}
397
398
static HRESULT WINAPI MediaSeekingPassThru_GetPreroll(IMediaSeeking * iface, LONGLONG * pPreroll)
399
{
400
struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
401
IMediaSeeking *seek;
402
HRESULT hr;
403
TRACE("(%p)\n", pPreroll);
404
hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
405
if (SUCCEEDED(hr)) {
406
hr = IMediaSeeking_GetPreroll(seek, pPreroll);
407
IMediaSeeking_Release(seek);
408
}
409
else
410
return E_NOTIMPL;
411
return hr;
412
}
413
414
static const IMediaSeekingVtbl IMediaSeekingPassThru_Vtbl =
415
{
416
MediaSeekingPassThru_QueryInterface,
417
MediaSeekingPassThru_AddRef,
418
MediaSeekingPassThru_Release,
419
MediaSeekingPassThru_GetCapabilities,
420
MediaSeekingPassThru_CheckCapabilities,
421
MediaSeekingPassThru_IsFormatSupported,
422
MediaSeekingPassThru_QueryPreferredFormat,
423
MediaSeekingPassThru_GetTimeFormat,
424
MediaSeekingPassThru_IsUsingTimeFormat,
425
MediaSeekingPassThru_SetTimeFormat,
426
MediaSeekingPassThru_GetDuration,
427
MediaSeekingPassThru_GetStopPosition,
428
MediaSeekingPassThru_GetCurrentPosition,
429
MediaSeekingPassThru_ConvertTimeFormat,
430
MediaSeekingPassThru_SetPositions,
431
MediaSeekingPassThru_GetPositions,
432
MediaSeekingPassThru_GetAvailable,
433
MediaSeekingPassThru_SetRate,
434
MediaSeekingPassThru_GetRate,
435
MediaSeekingPassThru_GetPreroll
436
};
437
438
static HRESULT WINAPI MediaPositionPassThru_QueryInterface(IMediaPosition *iface, REFIID iid, void **out)
439
{
440
struct strmbase_passthrough *passthrough = impl_from_IMediaPosition(iface);
441
442
return IUnknown_QueryInterface(passthrough->outer_unk, iid, out);
443
}
444
445
static ULONG WINAPI MediaPositionPassThru_AddRef(IMediaPosition *iface)
446
{
447
struct strmbase_passthrough *passthrough = impl_from_IMediaPosition(iface);
448
449
return IUnknown_AddRef(passthrough->outer_unk);
450
}
451
452
static ULONG WINAPI MediaPositionPassThru_Release(IMediaPosition *iface)
453
{
454
struct strmbase_passthrough *passthrough = impl_from_IMediaPosition(iface);
455
456
return IUnknown_Release(passthrough->outer_unk);
457
}
458
459
static HRESULT WINAPI MediaPositionPassThru_GetTypeInfoCount(IMediaPosition *iface, UINT *count)
460
{
461
TRACE("iface %p, count %p.\n", iface, count);
462
*count = 1;
463
return S_OK;
464
}
465
466
static HRESULT WINAPI MediaPositionPassThru_GetTypeInfo(IMediaPosition *iface, UINT index,
467
LCID lcid, ITypeInfo **typeinfo)
468
{
469
TRACE("iface %p, index %u, lcid %#lx, typeinfo %p.\n", iface, index, lcid, typeinfo);
470
return strmbase_get_typeinfo(IMediaPosition_tid, typeinfo);
471
}
472
473
static HRESULT WINAPI MediaPositionPassThru_GetIDsOfNames(IMediaPosition *iface, REFIID iid,
474
LPOLESTR *names, UINT count, LCID lcid, DISPID *ids)
475
{
476
ITypeInfo *typeinfo;
477
HRESULT hr;
478
479
TRACE("iface %p, iid %s, names %p, count %u, lcid %#lx, ids %p.\n",
480
iface, debugstr_guid(iid), names, count, lcid, ids);
481
482
if (SUCCEEDED(hr = strmbase_get_typeinfo(IMediaPosition_tid, &typeinfo)))
483
{
484
hr = ITypeInfo_GetIDsOfNames(typeinfo, names, count, ids);
485
ITypeInfo_Release(typeinfo);
486
}
487
return hr;
488
}
489
490
static HRESULT WINAPI MediaPositionPassThru_Invoke(IMediaPosition *iface, DISPID id, REFIID iid, LCID lcid,
491
WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *error_arg)
492
{
493
ITypeInfo *typeinfo;
494
HRESULT hr;
495
496
TRACE("iface %p, id %ld, iid %s, lcid %#lx, flags %#x, params %p, result %p, excepinfo %p, error_arg %p.\n",
497
iface, id, debugstr_guid(iid), lcid, flags, params, result, excepinfo, error_arg);
498
499
if (SUCCEEDED(hr = strmbase_get_typeinfo(IMediaPosition_tid, &typeinfo)))
500
{
501
hr = ITypeInfo_Invoke(typeinfo, iface, id, flags, params, result, excepinfo, error_arg);
502
ITypeInfo_Release(typeinfo);
503
}
504
return hr;
505
}
506
507
static HRESULT WINAPI MediaPositionPassThru_get_Duration(IMediaPosition *iface, REFTIME *plength)
508
{
509
struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
510
IMediaPosition *pos;
511
HRESULT hr;
512
513
TRACE("(%p)\n", plength);
514
515
hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
516
if (SUCCEEDED(hr)) {
517
hr = IMediaPosition_get_Duration(pos, plength);
518
IMediaPosition_Release(pos);
519
}
520
else
521
return E_NOTIMPL;
522
return hr;
523
}
524
525
static HRESULT WINAPI MediaPositionPassThru_put_CurrentPosition(IMediaPosition *iface, REFTIME llTime)
526
{
527
struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
528
IMediaPosition *pos;
529
HRESULT hr;
530
531
TRACE("iface %p, time %.16e.\n", iface, llTime);
532
533
hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
534
if (SUCCEEDED(hr)) {
535
hr = IMediaPosition_put_CurrentPosition(pos, llTime);
536
IMediaPosition_Release(pos);
537
}
538
else
539
return E_NOTIMPL;
540
return hr;
541
}
542
543
static HRESULT WINAPI MediaPositionPassThru_get_CurrentPosition(IMediaPosition *iface, REFTIME *pllTime)
544
{
545
struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
546
IMediaPosition *pos;
547
HRESULT hr;
548
549
TRACE("(%p)\n", pllTime);
550
551
hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
552
if (SUCCEEDED(hr)) {
553
hr = IMediaPosition_get_CurrentPosition(pos, pllTime);
554
IMediaPosition_Release(pos);
555
}
556
else
557
return E_NOTIMPL;
558
return hr;
559
}
560
561
static HRESULT WINAPI MediaPositionPassThru_get_StopTime(IMediaPosition *iface, REFTIME *pllTime)
562
{
563
struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
564
IMediaPosition *pos;
565
HRESULT hr;
566
567
TRACE("(%p)\n", pllTime);
568
569
hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
570
if (SUCCEEDED(hr)) {
571
hr = IMediaPosition_get_StopTime(pos, pllTime);
572
IMediaPosition_Release(pos);
573
}
574
else
575
return E_NOTIMPL;
576
return hr;
577
}
578
579
static HRESULT WINAPI MediaPositionPassThru_put_StopTime(IMediaPosition *iface, REFTIME llTime)
580
{
581
struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
582
IMediaPosition *pos;
583
HRESULT hr;
584
585
TRACE("iface %p, time %.16e.\n", iface, llTime);
586
587
hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
588
if (SUCCEEDED(hr)) {
589
hr = IMediaPosition_put_StopTime(pos, llTime);
590
IMediaPosition_Release(pos);
591
}
592
else
593
return E_NOTIMPL;
594
return hr;
595
}
596
597
static HRESULT WINAPI MediaPositionPassThru_get_PrerollTime(IMediaPosition *iface, REFTIME *pllTime)
598
{
599
struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
600
IMediaPosition *pos;
601
HRESULT hr;
602
603
TRACE("(%p)\n", pllTime);
604
605
hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
606
if (SUCCEEDED(hr)) {
607
hr = IMediaPosition_get_PrerollTime(pos, pllTime);
608
IMediaPosition_Release(pos);
609
}
610
else
611
return E_NOTIMPL;
612
return hr;
613
}
614
615
static HRESULT WINAPI MediaPositionPassThru_put_PrerollTime(IMediaPosition *iface, REFTIME llTime)
616
{
617
struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
618
IMediaPosition *pos;
619
HRESULT hr;
620
621
TRACE("iface %p, time %.16e.\n", iface, llTime);
622
623
hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
624
if (SUCCEEDED(hr)) {
625
hr = IMediaPosition_put_PrerollTime(pos, llTime);
626
IMediaPosition_Release(pos);
627
}
628
else
629
return E_NOTIMPL;
630
return hr;
631
}
632
633
static HRESULT WINAPI MediaPositionPassThru_put_Rate(IMediaPosition *iface, double dRate)
634
{
635
struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
636
IMediaPosition *pos;
637
HRESULT hr;
638
639
TRACE("(%f)\n", dRate);
640
641
hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
642
if (SUCCEEDED(hr)) {
643
hr = IMediaPosition_put_Rate(pos, dRate);
644
IMediaPosition_Release(pos);
645
}
646
else
647
return E_NOTIMPL;
648
return hr;
649
}
650
651
static HRESULT WINAPI MediaPositionPassThru_get_Rate(IMediaPosition *iface, double *pdRate)
652
{
653
struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
654
IMediaPosition *pos;
655
HRESULT hr;
656
657
TRACE("(%p)\n", pdRate);
658
659
hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
660
if (SUCCEEDED(hr)) {
661
hr = IMediaPosition_get_Rate(pos, pdRate);
662
IMediaPosition_Release(pos);
663
}
664
else
665
return E_NOTIMPL;
666
return hr;
667
}
668
669
static HRESULT WINAPI MediaPositionPassThru_CanSeekForward(IMediaPosition *iface, LONG *pCanSeekForward)
670
{
671
struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
672
IMediaPosition *pos;
673
HRESULT hr;
674
675
TRACE("(%p)\n", pCanSeekForward);
676
677
hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
678
if (SUCCEEDED(hr)) {
679
hr = IMediaPosition_CanSeekForward(pos, pCanSeekForward);
680
IMediaPosition_Release(pos);
681
}
682
else
683
return E_NOTIMPL;
684
return hr;
685
}
686
687
static HRESULT WINAPI MediaPositionPassThru_CanSeekBackward(IMediaPosition *iface, LONG *pCanSeekBackward)
688
{
689
struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
690
IMediaPosition *pos;
691
HRESULT hr;
692
693
TRACE("(%p)\n", pCanSeekBackward);
694
695
hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
696
if (SUCCEEDED(hr)) {
697
hr = IMediaPosition_CanSeekBackward(pos, pCanSeekBackward);
698
IMediaPosition_Release(pos);
699
}
700
else
701
return E_NOTIMPL;
702
return hr;
703
}
704
705
static const IMediaPositionVtbl IMediaPositionPassThru_Vtbl =
706
{
707
MediaPositionPassThru_QueryInterface,
708
MediaPositionPassThru_AddRef,
709
MediaPositionPassThru_Release,
710
MediaPositionPassThru_GetTypeInfoCount,
711
MediaPositionPassThru_GetTypeInfo,
712
MediaPositionPassThru_GetIDsOfNames,
713
MediaPositionPassThru_Invoke,
714
MediaPositionPassThru_get_Duration,
715
MediaPositionPassThru_put_CurrentPosition,
716
MediaPositionPassThru_get_CurrentPosition,
717
MediaPositionPassThru_get_StopTime,
718
MediaPositionPassThru_put_StopTime,
719
MediaPositionPassThru_get_PrerollTime,
720
MediaPositionPassThru_put_PrerollTime,
721
MediaPositionPassThru_put_Rate,
722
MediaPositionPassThru_get_Rate,
723
MediaPositionPassThru_CanSeekForward,
724
MediaPositionPassThru_CanSeekBackward
725
};
726
727
void strmbase_passthrough_init(struct strmbase_passthrough *passthrough, IUnknown *outer)
728
{
729
memset(passthrough, 0, sizeof(*passthrough));
730
731
passthrough->outer_unk = outer;
732
passthrough->IMediaPosition_iface.lpVtbl = &IMediaPositionPassThru_Vtbl;
733
passthrough->IMediaSeeking_iface.lpVtbl = &IMediaSeekingPassThru_Vtbl;
734
passthrough->ISeekingPassThru_iface.lpVtbl = &ISeekingPassThru_Vtbl;
735
if (!InitializeCriticalSectionEx(&passthrough->time_cs, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO))
736
InitializeCriticalSection(&passthrough->time_cs);
737
passthrough->time_cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": strmbase_passthrough.time_cs" );
738
}
739
740
void strmbase_passthrough_cleanup(struct strmbase_passthrough *passthrough)
741
{
742
passthrough->time_cs.DebugInfo->Spare[0] = 0;
743
DeleteCriticalSection(&passthrough->time_cs);
744
}
745
746
void strmbase_passthrough_update_time(struct strmbase_passthrough *passthrough, REFERENCE_TIME time)
747
{
748
EnterCriticalSection(&passthrough->time_cs);
749
passthrough->time_earliest = time;
750
passthrough->timevalid = TRUE;
751
LeaveCriticalSection(&passthrough->time_cs);
752
}
753
754
void strmbase_passthrough_invalidate_time(struct strmbase_passthrough *passthrough)
755
{
756
EnterCriticalSection(&passthrough->time_cs);
757
passthrough->timevalid = FALSE;
758
LeaveCriticalSection(&passthrough->time_cs);
759
}
760
761
void strmbase_passthrough_eos(struct strmbase_passthrough *passthrough)
762
{
763
REFERENCE_TIME time;
764
HRESULT hr;
765
766
hr = IMediaSeeking_GetStopPosition(&passthrough->IMediaSeeking_iface, &time);
767
EnterCriticalSection(&passthrough->time_cs);
768
if (SUCCEEDED(hr))
769
{
770
passthrough->timevalid = TRUE;
771
passthrough->time_earliest = time;
772
}
773
else
774
passthrough->timevalid = FALSE;
775
LeaveCriticalSection(&passthrough->time_cs);
776
}
777
778