2 * Implementation of MediaStream Filter
4 * Copyright 2008, 2012 Christian Costa
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.
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.
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
22 #include "amstream_private.h"
23 #include "wine/debug.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(amstream
);
29 IEnumPins IEnumPins_iface
;
33 unsigned int count
, index
;
36 static const IEnumPinsVtbl enum_pins_vtbl
;
38 static struct enum_pins
*impl_from_IEnumPins(IEnumPins
*iface
)
40 return CONTAINING_RECORD(iface
, struct enum_pins
, IEnumPins_iface
);
43 static HRESULT WINAPI
enum_pins_QueryInterface(IEnumPins
*iface
, REFIID iid
, void **out
)
45 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
47 if (IsEqualGUID(iid
, &IID_IUnknown
) || IsEqualGUID(iid
, &IID_IEnumPins
))
49 IEnumPins_AddRef(iface
);
54 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
59 static ULONG WINAPI
enum_pins_AddRef(IEnumPins
*iface
)
61 struct enum_pins
*enum_pins
= impl_from_IEnumPins(iface
);
62 ULONG refcount
= InterlockedIncrement(&enum_pins
->refcount
);
63 TRACE("%p increasing refcount to %u.\n", enum_pins
, refcount
);
67 static ULONG WINAPI
enum_pins_Release(IEnumPins
*iface
)
69 struct enum_pins
*enum_pins
= impl_from_IEnumPins(iface
);
70 ULONG refcount
= InterlockedDecrement(&enum_pins
->refcount
);
73 TRACE("%p decreasing refcount to %u.\n", enum_pins
, refcount
);
76 for (i
= 0; i
< enum_pins
->count
; ++i
)
77 IPin_Release(enum_pins
->pins
[i
]);
78 heap_free(enum_pins
->pins
);
84 static HRESULT WINAPI
enum_pins_Next(IEnumPins
*iface
, ULONG count
, IPin
**pins
, ULONG
*ret_count
)
86 struct enum_pins
*enum_pins
= impl_from_IEnumPins(iface
);
89 TRACE("iface %p, count %u, pins %p, ret_count %p.\n", iface
, count
, pins
, ret_count
);
91 if (!pins
|| (count
> 1 && !ret_count
))
94 for (i
= 0; i
< count
&& enum_pins
->index
< enum_pins
->count
; ++i
)
96 IPin_AddRef(pins
[i
] = enum_pins
->pins
[i
]);
100 if (ret_count
) *ret_count
= i
;
101 return i
== count
? S_OK
: S_FALSE
;
104 static HRESULT WINAPI
enum_pins_Skip(IEnumPins
*iface
, ULONG count
)
106 struct enum_pins
*enum_pins
= impl_from_IEnumPins(iface
);
108 TRACE("iface %p, count %u.\n", iface
, count
);
110 enum_pins
->index
+= count
;
112 return enum_pins
->index
>= enum_pins
->count
? S_FALSE
: S_OK
;
115 static HRESULT WINAPI
enum_pins_Reset(IEnumPins
*iface
)
117 struct enum_pins
*enum_pins
= impl_from_IEnumPins(iface
);
119 TRACE("iface %p.\n", iface
);
121 enum_pins
->index
= 0;
125 static HRESULT WINAPI
enum_pins_Clone(IEnumPins
*iface
, IEnumPins
**out
)
127 struct enum_pins
*enum_pins
= impl_from_IEnumPins(iface
);
128 struct enum_pins
*object
;
131 TRACE("iface %p, out %p.\n", iface
, out
);
133 if (!(object
= heap_alloc(sizeof(*object
))))
134 return E_OUTOFMEMORY
;
136 object
->IEnumPins_iface
.lpVtbl
= &enum_pins_vtbl
;
137 object
->refcount
= 1;
138 object
->count
= enum_pins
->count
;
139 object
->index
= enum_pins
->index
;
140 if (!(object
->pins
= heap_alloc(enum_pins
->count
* sizeof(*object
->pins
))))
143 return E_OUTOFMEMORY
;
145 for (i
= 0; i
< enum_pins
->count
; ++i
)
146 IPin_AddRef(object
->pins
[i
] = enum_pins
->pins
[i
]);
148 *out
= &object
->IEnumPins_iface
;
152 static const IEnumPinsVtbl enum_pins_vtbl
=
154 enum_pins_QueryInterface
,
165 IMediaStreamFilter IMediaStreamFilter_iface
;
166 IMediaSeeking IMediaSeeking_iface
;
170 IReferenceClock
*clock
;
174 IAMMediaStream
**streams
;
175 IAMMediaStream
*seekable_stream
;
177 REFERENCE_TIME start_time
;
180 static inline struct filter
*impl_from_IMediaStreamFilter(IMediaStreamFilter
*iface
)
182 return CONTAINING_RECORD(iface
, struct filter
, IMediaStreamFilter_iface
);
185 static HRESULT WINAPI
filter_QueryInterface(IMediaStreamFilter
*iface
, REFIID iid
, void **out
)
187 struct filter
*filter
= impl_from_IMediaStreamFilter(iface
);
189 TRACE("filter %p, iid %s, out %p.\n", filter
, debugstr_guid(iid
), out
);
193 if (IsEqualGUID(iid
, &IID_IUnknown
)
194 || IsEqualGUID(iid
, &IID_IPersist
)
195 || IsEqualGUID(iid
, &IID_IMediaFilter
)
196 || IsEqualGUID(iid
, &IID_IBaseFilter
)
197 || IsEqualGUID(iid
, &IID_IMediaStreamFilter
))
199 else if (IsEqualGUID(iid
, &IID_IMediaSeeking
) && filter
->seekable_stream
)
200 *out
= &filter
->IMediaSeeking_iface
;
202 return E_NOINTERFACE
;
204 IUnknown_AddRef((IUnknown
*)*out
);
208 static ULONG WINAPI
filter_AddRef(IMediaStreamFilter
*iface
)
210 struct filter
*filter
= impl_from_IMediaStreamFilter(iface
);
211 ULONG refcount
= InterlockedIncrement(&filter
->refcount
);
213 TRACE("%p increasing refcount to %u.\n", iface
, refcount
);
218 static ULONG WINAPI
filter_Release(IMediaStreamFilter
*iface
)
220 struct filter
*filter
= impl_from_IMediaStreamFilter(iface
);
221 ULONG refcount
= InterlockedDecrement(&filter
->refcount
);
224 TRACE("%p decreasing refcount to %u.\n", iface
, refcount
);
228 for (i
= 0; i
< filter
->nb_streams
; ++i
)
230 IAMMediaStream_JoinFilter(filter
->streams
[i
], NULL
);
231 IAMMediaStream_Release(filter
->streams
[i
]);
233 heap_free(filter
->streams
);
235 IReferenceClock_Release(filter
->clock
);
236 DeleteCriticalSection(&filter
->cs
);
243 static HRESULT WINAPI
filter_GetClassID(IMediaStreamFilter
*iface
, CLSID
*clsid
)
245 *clsid
= CLSID_MediaStreamFilter
;
249 static void set_state(struct filter
*filter
, FILTER_STATE state
)
251 if (filter
->state
!= state
)
255 for (i
= 0; i
< filter
->nb_streams
; ++i
)
256 IAMMediaStream_SetState(filter
->streams
[i
], state
);
257 filter
->state
= state
;
261 static HRESULT WINAPI
filter_Stop(IMediaStreamFilter
*iface
)
263 struct filter
*filter
= impl_from_IMediaStreamFilter(iface
);
265 TRACE("iface %p.\n", iface
);
267 EnterCriticalSection(&filter
->cs
);
269 set_state(filter
, State_Stopped
);
271 LeaveCriticalSection(&filter
->cs
);
276 static HRESULT WINAPI
filter_Pause(IMediaStreamFilter
*iface
)
278 struct filter
*filter
= impl_from_IMediaStreamFilter(iface
);
280 TRACE("iface %p.\n", iface
);
282 EnterCriticalSection(&filter
->cs
);
284 set_state(filter
, State_Paused
);
286 LeaveCriticalSection(&filter
->cs
);
291 static HRESULT WINAPI
filter_Run(IMediaStreamFilter
*iface
, REFERENCE_TIME start
)
293 struct filter
*filter
= impl_from_IMediaStreamFilter(iface
);
295 TRACE("iface %p, start %s.\n", iface
, wine_dbgstr_longlong(start
));
297 EnterCriticalSection(&filter
->cs
);
299 filter
->start_time
= start
;
300 set_state(filter
, State_Running
);
302 LeaveCriticalSection(&filter
->cs
);
307 static HRESULT WINAPI
filter_GetState(IMediaStreamFilter
*iface
, DWORD timeout
, FILTER_STATE
*state
)
309 struct filter
*filter
= impl_from_IMediaStreamFilter(iface
);
311 TRACE("iface %p, timeout %u, state %p.\n", iface
, timeout
, state
);
316 EnterCriticalSection(&filter
->cs
);
318 *state
= filter
->state
;
320 LeaveCriticalSection(&filter
->cs
);
325 static HRESULT WINAPI
filter_SetSyncSource(IMediaStreamFilter
*iface
, IReferenceClock
*clock
)
327 struct filter
*filter
= impl_from_IMediaStreamFilter(iface
);
329 TRACE("iface %p, clock %p.\n", iface
, clock
);
331 EnterCriticalSection(&filter
->cs
);
334 IReferenceClock_AddRef(clock
);
336 IReferenceClock_Release(filter
->clock
);
337 filter
->clock
= clock
;
339 LeaveCriticalSection(&filter
->cs
);
344 static HRESULT WINAPI
filter_GetSyncSource(IMediaStreamFilter
*iface
, IReferenceClock
**clock
)
346 struct filter
*filter
= impl_from_IMediaStreamFilter(iface
);
348 TRACE("iface %p, clock %p.\n", iface
, clock
);
350 EnterCriticalSection(&filter
->cs
);
353 IReferenceClock_AddRef(filter
->clock
);
354 *clock
= filter
->clock
;
356 LeaveCriticalSection(&filter
->cs
);
361 static HRESULT WINAPI
filter_EnumPins(IMediaStreamFilter
*iface
, IEnumPins
**enum_pins
)
363 struct filter
*filter
= impl_from_IMediaStreamFilter(iface
);
364 struct enum_pins
*object
;
367 TRACE("iface %p, enum_pins %p.\n", iface
, enum_pins
);
372 if (!(object
= heap_alloc(sizeof(*object
))))
373 return E_OUTOFMEMORY
;
375 EnterCriticalSection(&filter
->cs
);
377 object
->IEnumPins_iface
.lpVtbl
= &enum_pins_vtbl
;
378 object
->refcount
= 1;
379 object
->count
= filter
->nb_streams
;
381 if (!(object
->pins
= heap_alloc(filter
->nb_streams
* sizeof(*object
->pins
))))
384 LeaveCriticalSection(&filter
->cs
);
385 return E_OUTOFMEMORY
;
387 for (i
= 0; i
< filter
->nb_streams
; ++i
)
389 if (FAILED(IAMMediaStream_QueryInterface(filter
->streams
[i
], &IID_IPin
, (void **)&object
->pins
[i
])))
390 WARN("Stream %p does not support IPin.\n", filter
->streams
[i
]);
393 LeaveCriticalSection(&filter
->cs
);
395 *enum_pins
= &object
->IEnumPins_iface
;
399 static HRESULT WINAPI
filter_FindPin(IMediaStreamFilter
*iface
, const WCHAR
*id
, IPin
**out
)
401 struct filter
*filter
= impl_from_IMediaStreamFilter(iface
);
406 TRACE("iface %p, id %s, out %p.\n", iface
, debugstr_w(id
), out
);
408 EnterCriticalSection(&filter
->cs
);
410 for (i
= 0; i
< filter
->nb_streams
; ++i
)
412 if (FAILED(IAMMediaStream_QueryInterface(filter
->streams
[i
], &IID_IPin
, (void **)&pin
)))
414 WARN("Stream %p does not support IPin.\n", filter
->streams
[i
]);
418 if (SUCCEEDED(IPin_QueryId(pin
, &ret_id
)))
420 if (!wcscmp(id
, ret_id
))
422 CoTaskMemFree(ret_id
);
424 LeaveCriticalSection(&filter
->cs
);
427 CoTaskMemFree(ret_id
);
432 LeaveCriticalSection(&filter
->cs
);
434 return VFW_E_NOT_FOUND
;
437 static HRESULT WINAPI
filter_QueryFilterInfo(IMediaStreamFilter
*iface
, FILTER_INFO
*info
)
439 struct filter
*filter
= impl_from_IMediaStreamFilter(iface
);
441 TRACE("iface %p, info %p.\n", iface
, info
);
443 EnterCriticalSection(&filter
->cs
);
445 wcscpy(info
->achName
, filter
->name
);
447 IFilterGraph_AddRef(filter
->graph
);
448 info
->pGraph
= filter
->graph
;
450 LeaveCriticalSection(&filter
->cs
);
455 static HRESULT WINAPI
filter_JoinFilterGraph(IMediaStreamFilter
*iface
,
456 IFilterGraph
*graph
, const WCHAR
*name
)
458 struct filter
*filter
= impl_from_IMediaStreamFilter(iface
);
460 TRACE("iface %p, graph %p, name.%s.\n", iface
, graph
, debugstr_w(name
));
462 EnterCriticalSection(&filter
->cs
);
465 wcsncpy(filter
->name
, name
, ARRAY_SIZE(filter
->name
));
468 filter
->graph
= graph
;
470 LeaveCriticalSection(&filter
->cs
);
475 static HRESULT WINAPI
filter_QueryVendorInfo(IMediaStreamFilter
*iface
, LPWSTR
*vendor_info
)
477 WARN("iface %p, vendor_info %p, stub!\n", iface
, vendor_info
);
481 /*** IMediaStreamFilter methods ***/
483 static HRESULT WINAPI
filter_AddMediaStream(IMediaStreamFilter
*iface
, IAMMediaStream
*pAMMediaStream
)
485 struct filter
*This
= impl_from_IMediaStreamFilter(iface
);
486 IAMMediaStream
** streams
;
489 TRACE("(%p)->(%p)\n", iface
, pAMMediaStream
);
491 streams
= CoTaskMemRealloc(This
->streams
, (This
->nb_streams
+ 1) * sizeof(IAMMediaStream
*));
493 return E_OUTOFMEMORY
;
494 This
->streams
= streams
;
496 hr
= IAMMediaStream_JoinFilter(pAMMediaStream
, iface
);
500 hr
= IAMMediaStream_JoinFilterGraph(pAMMediaStream
, This
->graph
);
504 This
->streams
[This
->nb_streams
] = pAMMediaStream
;
507 IAMMediaStream_AddRef(pAMMediaStream
);
512 static HRESULT WINAPI
filter_GetMediaStream(IMediaStreamFilter
*iface
, REFMSPID idPurpose
, IMediaStream
**ppMediaStream
)
514 struct filter
*This
= impl_from_IMediaStreamFilter(iface
);
518 TRACE("(%p)->(%s,%p)\n", iface
, debugstr_guid(idPurpose
), ppMediaStream
);
523 for (i
= 0; i
< This
->nb_streams
; i
++)
525 IAMMediaStream_GetInformation(This
->streams
[i
], &purpose_id
, NULL
);
526 if (IsEqualIID(&purpose_id
, idPurpose
))
528 *ppMediaStream
= (IMediaStream
*)This
->streams
[i
];
529 IMediaStream_AddRef(*ppMediaStream
);
534 return MS_E_NOSTREAM
;
537 static HRESULT WINAPI
filter_EnumMediaStreams(IMediaStreamFilter
*iface
, LONG index
, IMediaStream
**stream
)
539 struct filter
*filter
= impl_from_IMediaStreamFilter(iface
);
541 TRACE("filter %p, index %d, stream %p.\n", filter
, index
, stream
);
543 if (index
>= filter
->nb_streams
)
549 IMediaStream_AddRef(*stream
= (IMediaStream
*)filter
->streams
[index
]);
553 static IMediaSeeking
*get_seeking(IAMMediaStream
*stream
)
555 IMediaSeeking
*seeking
;
559 if (FAILED(IAMMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
)))
561 WARN("Stream %p does not support IPin.\n", stream
);
565 hr
= IPin_ConnectedTo(pin
, &peer
);
570 hr
= IPin_QueryInterface(peer
, &IID_IMediaSeeking
, (void **)&seeking
);
578 static HRESULT WINAPI
filter_SupportSeeking(IMediaStreamFilter
*iface
, BOOL renderer
)
580 struct filter
*filter
= impl_from_IMediaStreamFilter(iface
);
583 TRACE("filter %p, renderer %d\n", iface
, renderer
);
586 FIXME("Non-renderer filter support is not yet implemented.\n");
588 EnterCriticalSection(&filter
->cs
);
590 if (filter
->seekable_stream
)
592 LeaveCriticalSection(&filter
->cs
);
593 return HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED
);
596 for (i
= 0; i
< filter
->nb_streams
; ++i
)
598 IMediaSeeking
*seeking
= get_seeking(filter
->streams
[i
]);
604 if (SUCCEEDED(IMediaSeeking_GetDuration(seeking
, &duration
)))
606 filter
->seekable_stream
= filter
->streams
[i
];
607 IMediaSeeking_Release(seeking
);
608 LeaveCriticalSection(&filter
->cs
);
612 IMediaSeeking_Release(seeking
);
615 LeaveCriticalSection(&filter
->cs
);
616 return E_NOINTERFACE
;
619 static HRESULT WINAPI
filter_ReferenceTimeToStreamTime(IMediaStreamFilter
*iface
, REFERENCE_TIME
*pTime
)
621 FIXME("(%p)->(%p): Stub!\n", iface
, pTime
);
626 static HRESULT WINAPI
filter_GetCurrentStreamTime(IMediaStreamFilter
*iface
, REFERENCE_TIME
*time
)
628 struct filter
*filter
= impl_from_IMediaStreamFilter(iface
);
630 TRACE("filter %p, time %p.\n", filter
, time
);
635 EnterCriticalSection(&filter
->cs
);
637 if (filter
->state
!= State_Running
|| !filter
->clock
)
640 LeaveCriticalSection(&filter
->cs
);
644 IReferenceClock_GetTime(filter
->clock
, time
);
646 *time
-= filter
->start_time
;
648 LeaveCriticalSection(&filter
->cs
);
653 static HRESULT WINAPI
filter_WaitUntil(IMediaStreamFilter
*iface
, REFERENCE_TIME WaitStreamTime
)
655 FIXME("(%p)->(%s): Stub!\n", iface
, wine_dbgstr_longlong(WaitStreamTime
));
660 static HRESULT WINAPI
filter_Flush(IMediaStreamFilter
*iface
, BOOL bCancelEOS
)
662 FIXME("(%p)->(%d): Stub!\n", iface
, bCancelEOS
);
667 static HRESULT WINAPI
filter_EndOfStream(IMediaStreamFilter
*iface
)
669 FIXME("(%p)->(): Stub!\n", iface
);
674 static const IMediaStreamFilterVtbl filter_vtbl
=
676 filter_QueryInterface
,
684 filter_SetSyncSource
,
685 filter_GetSyncSource
,
688 filter_QueryFilterInfo
,
689 filter_JoinFilterGraph
,
690 filter_QueryVendorInfo
,
691 filter_AddMediaStream
,
692 filter_GetMediaStream
,
693 filter_EnumMediaStreams
,
694 filter_SupportSeeking
,
695 filter_ReferenceTimeToStreamTime
,
696 filter_GetCurrentStreamTime
,
702 static inline struct filter
*impl_from_IMediaSeeking(IMediaSeeking
*iface
)
704 return CONTAINING_RECORD(iface
, struct filter
, IMediaSeeking_iface
);
707 static HRESULT WINAPI
filter_seeking_QueryInterface(IMediaSeeking
*iface
, REFIID iid
, void **out
)
709 struct filter
*filter
= impl_from_IMediaSeeking(iface
);
710 return IMediaStreamFilter_QueryInterface(&filter
->IMediaStreamFilter_iface
, iid
, out
);
713 static ULONG WINAPI
filter_seeking_AddRef(IMediaSeeking
*iface
)
715 struct filter
*filter
= impl_from_IMediaSeeking(iface
);
716 return IMediaStreamFilter_AddRef(&filter
->IMediaStreamFilter_iface
);
719 static ULONG WINAPI
filter_seeking_Release(IMediaSeeking
*iface
)
721 struct filter
*filter
= impl_from_IMediaSeeking(iface
);
722 return IMediaStreamFilter_Release(&filter
->IMediaStreamFilter_iface
);
725 static HRESULT WINAPI
filter_seeking_GetCapabilities(IMediaSeeking
*iface
, DWORD
*capabilities
)
727 FIXME("iface %p, capabilities %p, stub!\n", iface
, capabilities
);
732 static HRESULT WINAPI
filter_seeking_CheckCapabilities(IMediaSeeking
*iface
, DWORD
*capabilities
)
734 FIXME("iface %p, capabilities %p, stub!\n", iface
, capabilities
);
739 static HRESULT WINAPI
filter_seeking_IsFormatSupported(IMediaSeeking
*iface
, const GUID
*format
)
741 FIXME("iface %p, format %s, stub!\n", iface
, debugstr_guid(format
));
746 static HRESULT WINAPI
filter_seeking_QueryPreferredFormat(IMediaSeeking
*iface
, GUID
*format
)
748 FIXME("iface %p, format %p, stub!\n", iface
, format
);
753 static HRESULT WINAPI
filter_seeking_GetTimeFormat(IMediaSeeking
*iface
, GUID
*format
)
755 FIXME("iface %p, format %p, stub!\n", iface
, format
);
760 static HRESULT WINAPI
filter_seeking_IsUsingTimeFormat(IMediaSeeking
*iface
, const GUID
*format
)
762 FIXME("iface %p, format %s, stub!\n", iface
, debugstr_guid(format
));
767 static HRESULT WINAPI
filter_seeking_SetTimeFormat(IMediaSeeking
*iface
, const GUID
*format
)
769 FIXME("iface %p, format %s, stub!\n", iface
, debugstr_guid(format
));
774 static HRESULT WINAPI
filter_seeking_GetDuration(IMediaSeeking
*iface
, LONGLONG
*duration
)
776 struct filter
*filter
= impl_from_IMediaSeeking(iface
);
777 IMediaSeeking
*seeking
;
780 TRACE("filter %p, duration %p.\n", filter
, duration
);
782 EnterCriticalSection(&filter
->cs
);
784 if (!(seeking
= get_seeking(filter
->seekable_stream
)))
786 LeaveCriticalSection(&filter
->cs
);
789 hr
= IMediaSeeking_GetDuration(seeking
, duration
);
790 IMediaSeeking_Release(seeking
);
792 LeaveCriticalSection(&filter
->cs
);
796 static HRESULT WINAPI
filter_seeking_GetStopPosition(IMediaSeeking
*iface
, LONGLONG
*stop
)
798 struct filter
*filter
= impl_from_IMediaSeeking(iface
);
799 IMediaSeeking
*seeking
;
802 TRACE("filter %p, stop %p.\n", filter
, stop
);
804 EnterCriticalSection(&filter
->cs
);
806 if (!(seeking
= get_seeking(filter
->seekable_stream
)))
808 LeaveCriticalSection(&filter
->cs
);
811 hr
= IMediaSeeking_GetStopPosition(seeking
, stop
);
812 IMediaSeeking_Release(seeking
);
814 LeaveCriticalSection(&filter
->cs
);
818 static HRESULT WINAPI
filter_seeking_GetCurrentPosition(IMediaSeeking
*iface
, LONGLONG
*current
)
820 FIXME("iface %p, current %p, stub!\n", iface
, current
);
825 static HRESULT WINAPI
filter_seeking_ConvertTimeFormat(IMediaSeeking
*iface
, LONGLONG
*target
,
826 const GUID
*target_format
, LONGLONG source
, const GUID
*source_format
)
828 FIXME("iface %p, target %p, target_format %s, source 0x%s, source_format %s, stub!\n", iface
, target
, debugstr_guid(target_format
),
829 wine_dbgstr_longlong(source
), debugstr_guid(source_format
));
834 static HRESULT WINAPI
filter_seeking_SetPositions(IMediaSeeking
*iface
, LONGLONG
*current_ptr
, DWORD current_flags
,
835 LONGLONG
*stop_ptr
, DWORD stop_flags
)
837 struct filter
*filter
= impl_from_IMediaSeeking(iface
);
838 IMediaSeeking
*seeking
;
841 TRACE("iface %p, current %s, current_flags %#x, stop %s, stop_flags %#x.\n", iface
,
842 current_ptr
? wine_dbgstr_longlong(*current_ptr
) : "<null>", current_flags
,
843 stop_ptr
? wine_dbgstr_longlong(*stop_ptr
): "<null>", stop_flags
);
845 EnterCriticalSection(&filter
->cs
);
847 seeking
= get_seeking(filter
->seekable_stream
);
851 LeaveCriticalSection(&filter
->cs
);
855 hr
= IMediaSeeking_SetPositions(seeking
, current_ptr
, current_flags
, stop_ptr
, stop_flags
);
857 IMediaSeeking_Release(seeking
);
859 LeaveCriticalSection(&filter
->cs
);
864 static HRESULT WINAPI
filter_seeking_GetPositions(IMediaSeeking
*iface
, LONGLONG
*current
, LONGLONG
*stop
)
866 FIXME("iface %p, current %p, stop %p, stub!\n", iface
, current
, stop
);
871 static HRESULT WINAPI
filter_seeking_GetAvailable(IMediaSeeking
*iface
, LONGLONG
*earliest
, LONGLONG
*latest
)
873 FIXME("iface %p, earliest %p, latest %p, stub!\n", iface
, earliest
, latest
);
878 static HRESULT WINAPI
filter_seeking_SetRate(IMediaSeeking
*iface
, double rate
)
880 FIXME("iface %p, rate %f, stub!\n", iface
, rate
);
885 static HRESULT WINAPI
filter_seeking_GetRate(IMediaSeeking
*iface
, double *rate
)
887 FIXME("iface %p, rate %p, stub!\n", iface
, rate
);
892 static HRESULT WINAPI
filter_seeking_GetPreroll(IMediaSeeking
*iface
, LONGLONG
*preroll
)
894 FIXME("iface %p, preroll %p, stub!\n", iface
, preroll
);
899 static const IMediaSeekingVtbl filter_seeking_vtbl
=
901 filter_seeking_QueryInterface
,
902 filter_seeking_AddRef
,
903 filter_seeking_Release
,
904 filter_seeking_GetCapabilities
,
905 filter_seeking_CheckCapabilities
,
906 filter_seeking_IsFormatSupported
,
907 filter_seeking_QueryPreferredFormat
,
908 filter_seeking_GetTimeFormat
,
909 filter_seeking_IsUsingTimeFormat
,
910 filter_seeking_SetTimeFormat
,
911 filter_seeking_GetDuration
,
912 filter_seeking_GetStopPosition
,
913 filter_seeking_GetCurrentPosition
,
914 filter_seeking_ConvertTimeFormat
,
915 filter_seeking_SetPositions
,
916 filter_seeking_GetPositions
,
917 filter_seeking_GetAvailable
,
918 filter_seeking_SetRate
,
919 filter_seeking_GetRate
,
920 filter_seeking_GetPreroll
,
923 HRESULT
filter_create(IUnknown
*outer
, void **out
)
925 struct filter
*object
;
927 TRACE("outer %p, out %p.\n", outer
, out
);
930 return CLASS_E_NOAGGREGATION
;
932 if (!(object
= heap_alloc_zero(sizeof(*object
))))
933 return E_OUTOFMEMORY
;
935 object
->IMediaStreamFilter_iface
.lpVtbl
= &filter_vtbl
;
936 object
->IMediaSeeking_iface
.lpVtbl
= &filter_seeking_vtbl
;
937 object
->refcount
= 1;
938 InitializeCriticalSection(&object
->cs
);
939 object
->cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": MediaStreamFilter.cs");
941 TRACE("Created media stream filter %p.\n", object
);
942 *out
= &object
->IMediaStreamFilter_iface
;