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