amstream: Implement MediaStreamFilter::SupportSeeking().
[wine.git] / dlls / amstream / filter.c
blobf1e0811d6790df7f76b30fdae47bfecf7ed92e95
1 /*
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
21 #define COBJMACROS
22 #include "amstream_private.h"
23 #include "wine/debug.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(amstream);
27 struct enum_pins
29 IEnumPins IEnumPins_iface;
30 LONG refcount;
32 IPin **pins;
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);
50 *out = iface;
51 return S_OK;
54 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
55 *out = NULL;
56 return E_NOINTERFACE;
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);
64 return 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);
71 unsigned int i;
73 TRACE("%p decreasing refcount to %u.\n", enum_pins, refcount);
74 if (!refcount)
76 for (i = 0; i < enum_pins->count; ++i)
77 IPin_Release(enum_pins->pins[i]);
78 heap_free(enum_pins->pins);
79 heap_free(enum_pins);
81 return refcount;
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);
87 unsigned int i;
89 TRACE("iface %p, count %u, pins %p, ret_count %p.\n", iface, count, pins, ret_count);
91 if (!pins || (count > 1 && !ret_count))
92 return E_POINTER;
94 for (i = 0; i < count && enum_pins->index < enum_pins->count; ++i)
96 IPin_AddRef(pins[i] = enum_pins->pins[i]);
97 enum_pins->index++;
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;
122 return S_OK;
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;
129 unsigned int i;
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))))
142 heap_free(object);
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;
149 return S_OK;
152 static const IEnumPinsVtbl enum_pins_vtbl =
154 enum_pins_QueryInterface,
155 enum_pins_AddRef,
156 enum_pins_Release,
157 enum_pins_Next,
158 enum_pins_Skip,
159 enum_pins_Reset,
160 enum_pins_Clone,
163 struct filter
165 IMediaStreamFilter IMediaStreamFilter_iface;
166 IMediaSeeking IMediaSeeking_iface;
167 LONG refcount;
168 CRITICAL_SECTION cs;
170 IReferenceClock *clock;
171 WCHAR name[128];
172 IFilterGraph *graph;
173 ULONG nb_streams;
174 IAMMediaStream **streams;
175 IAMMediaStream *seekable_stream;
176 FILTER_STATE state;
179 static inline struct filter *impl_from_IMediaStreamFilter(IMediaStreamFilter *iface)
181 return CONTAINING_RECORD(iface, struct filter, IMediaStreamFilter_iface);
184 static HRESULT WINAPI filter_QueryInterface(IMediaStreamFilter *iface, REFIID iid, void **out)
186 struct filter *filter = impl_from_IMediaStreamFilter(iface);
188 TRACE("filter %p, iid %s, out %p.\n", filter, debugstr_guid(iid), out);
190 *out = NULL;
192 if (IsEqualGUID(iid, &IID_IUnknown)
193 || IsEqualGUID(iid, &IID_IPersist)
194 || IsEqualGUID(iid, &IID_IMediaFilter)
195 || IsEqualGUID(iid, &IID_IBaseFilter)
196 || IsEqualGUID(iid, &IID_IMediaStreamFilter))
197 *out = iface;
198 else if (IsEqualGUID(iid, &IID_IMediaSeeking) && filter->seekable_stream)
199 *out = &filter->IMediaSeeking_iface;
200 else
201 return E_NOINTERFACE;
203 IUnknown_AddRef((IUnknown *)*out);
204 return S_OK;
207 static ULONG WINAPI filter_AddRef(IMediaStreamFilter *iface)
209 struct filter *filter = impl_from_IMediaStreamFilter(iface);
210 ULONG refcount = InterlockedIncrement(&filter->refcount);
212 TRACE("%p increasing refcount to %u.\n", iface, refcount);
214 return refcount;
217 static ULONG WINAPI filter_Release(IMediaStreamFilter *iface)
219 struct filter *filter = impl_from_IMediaStreamFilter(iface);
220 ULONG refcount = InterlockedDecrement(&filter->refcount);
221 unsigned int i;
223 TRACE("%p decreasing refcount to %u.\n", iface, refcount);
225 if (!refcount)
227 for (i = 0; i < filter->nb_streams; ++i)
229 IAMMediaStream_JoinFilter(filter->streams[i], NULL);
230 IAMMediaStream_Release(filter->streams[i]);
232 heap_free(filter->streams);
233 if (filter->clock)
234 IReferenceClock_Release(filter->clock);
235 DeleteCriticalSection(&filter->cs);
236 heap_free(filter);
239 return refcount;
242 static HRESULT WINAPI filter_GetClassID(IMediaStreamFilter *iface, CLSID *clsid)
244 *clsid = CLSID_MediaStreamFilter;
245 return S_OK;
248 static void set_state(struct filter *filter, FILTER_STATE state)
250 if (filter->state != state)
252 ULONG i;
254 for (i = 0; i < filter->nb_streams; ++i)
255 IAMMediaStream_SetState(filter->streams[i], state);
256 filter->state = state;
260 static HRESULT WINAPI filter_Stop(IMediaStreamFilter *iface)
262 struct filter *filter = impl_from_IMediaStreamFilter(iface);
264 TRACE("iface %p.\n", iface);
266 EnterCriticalSection(&filter->cs);
268 set_state(filter, State_Stopped);
270 LeaveCriticalSection(&filter->cs);
272 return S_OK;
275 static HRESULT WINAPI filter_Pause(IMediaStreamFilter *iface)
277 struct filter *filter = impl_from_IMediaStreamFilter(iface);
279 TRACE("iface %p.\n", iface);
281 EnterCriticalSection(&filter->cs);
283 set_state(filter, State_Paused);
285 LeaveCriticalSection(&filter->cs);
287 return S_OK;
290 static HRESULT WINAPI filter_Run(IMediaStreamFilter *iface, REFERENCE_TIME start)
292 struct filter *filter = impl_from_IMediaStreamFilter(iface);
294 TRACE("iface %p, start %s.\n", iface, wine_dbgstr_longlong(start));
296 EnterCriticalSection(&filter->cs);
298 set_state(filter, State_Running);
300 LeaveCriticalSection(&filter->cs);
302 return S_OK;
305 static HRESULT WINAPI filter_GetState(IMediaStreamFilter *iface, DWORD timeout, FILTER_STATE *state)
307 struct filter *filter = impl_from_IMediaStreamFilter(iface);
309 TRACE("iface %p, timeout %u, state %p.\n", iface, timeout, state);
311 if (!state)
312 return E_POINTER;
314 EnterCriticalSection(&filter->cs);
316 *state = filter->state;
318 LeaveCriticalSection(&filter->cs);
320 return S_OK;
323 static HRESULT WINAPI filter_SetSyncSource(IMediaStreamFilter *iface, IReferenceClock *clock)
325 struct filter *filter = impl_from_IMediaStreamFilter(iface);
327 TRACE("iface %p, clock %p.\n", iface, clock);
329 EnterCriticalSection(&filter->cs);
331 if (clock)
332 IReferenceClock_AddRef(clock);
333 if (filter->clock)
334 IReferenceClock_Release(filter->clock);
335 filter->clock = clock;
337 LeaveCriticalSection(&filter->cs);
339 return S_OK;
342 static HRESULT WINAPI filter_GetSyncSource(IMediaStreamFilter *iface, IReferenceClock **clock)
344 struct filter *filter = impl_from_IMediaStreamFilter(iface);
346 TRACE("iface %p, clock %p.\n", iface, clock);
348 EnterCriticalSection(&filter->cs);
350 if (filter->clock)
351 IReferenceClock_AddRef(filter->clock);
352 *clock = filter->clock;
354 LeaveCriticalSection(&filter->cs);
356 return S_OK;
359 static HRESULT WINAPI filter_EnumPins(IMediaStreamFilter *iface, IEnumPins **enum_pins)
361 struct filter *filter = impl_from_IMediaStreamFilter(iface);
362 struct enum_pins *object;
363 unsigned int i;
365 TRACE("iface %p, enum_pins %p.\n", iface, enum_pins);
367 if (!enum_pins)
368 return E_POINTER;
370 if (!(object = heap_alloc(sizeof(*object))))
371 return E_OUTOFMEMORY;
373 EnterCriticalSection(&filter->cs);
375 object->IEnumPins_iface.lpVtbl = &enum_pins_vtbl;
376 object->refcount = 1;
377 object->count = filter->nb_streams;
378 object->index = 0;
379 if (!(object->pins = heap_alloc(filter->nb_streams * sizeof(*object->pins))))
381 heap_free(object);
382 LeaveCriticalSection(&filter->cs);
383 return E_OUTOFMEMORY;
385 for (i = 0; i < filter->nb_streams; ++i)
387 if (FAILED(IAMMediaStream_QueryInterface(filter->streams[i], &IID_IPin, (void **)&object->pins[i])))
388 WARN("Stream %p does not support IPin.\n", filter->streams[i]);
391 LeaveCriticalSection(&filter->cs);
393 *enum_pins = &object->IEnumPins_iface;
394 return S_OK;
397 static HRESULT WINAPI filter_FindPin(IMediaStreamFilter *iface, const WCHAR *id, IPin **out)
399 struct filter *filter = impl_from_IMediaStreamFilter(iface);
400 unsigned int i;
401 WCHAR *ret_id;
402 IPin *pin;
404 TRACE("iface %p, id %s, out %p.\n", iface, debugstr_w(id), out);
406 EnterCriticalSection(&filter->cs);
408 for (i = 0; i < filter->nb_streams; ++i)
410 if (FAILED(IAMMediaStream_QueryInterface(filter->streams[i], &IID_IPin, (void **)&pin)))
412 WARN("Stream %p does not support IPin.\n", filter->streams[i]);
413 continue;
416 if (SUCCEEDED(IPin_QueryId(pin, &ret_id)))
418 if (!wcscmp(id, ret_id))
420 CoTaskMemFree(ret_id);
421 *out = pin;
422 LeaveCriticalSection(&filter->cs);
423 return S_OK;
425 CoTaskMemFree(ret_id);
427 IPin_Release(pin);
430 LeaveCriticalSection(&filter->cs);
432 return VFW_E_NOT_FOUND;
435 static HRESULT WINAPI filter_QueryFilterInfo(IMediaStreamFilter *iface, FILTER_INFO *info)
437 struct filter *filter = impl_from_IMediaStreamFilter(iface);
439 TRACE("iface %p, info %p.\n", iface, info);
441 EnterCriticalSection(&filter->cs);
443 wcscpy(info->achName, filter->name);
444 if (filter->graph)
445 IFilterGraph_AddRef(filter->graph);
446 info->pGraph = filter->graph;
448 LeaveCriticalSection(&filter->cs);
450 return S_OK;
453 static HRESULT WINAPI filter_JoinFilterGraph(IMediaStreamFilter *iface,
454 IFilterGraph *graph, const WCHAR *name)
456 struct filter *filter = impl_from_IMediaStreamFilter(iface);
458 TRACE("iface %p, graph %p, name.%s.\n", iface, graph, debugstr_w(name));
460 EnterCriticalSection(&filter->cs);
462 if (name)
463 wcsncpy(filter->name, name, ARRAY_SIZE(filter->name));
464 else
465 filter->name[0] = 0;
466 filter->graph = graph;
468 LeaveCriticalSection(&filter->cs);
470 return S_OK;
473 static HRESULT WINAPI filter_QueryVendorInfo(IMediaStreamFilter *iface, LPWSTR *vendor_info)
475 WARN("iface %p, vendor_info %p, stub!\n", iface, vendor_info);
476 return E_NOTIMPL;
479 /*** IMediaStreamFilter methods ***/
481 static HRESULT WINAPI filter_AddMediaStream(IMediaStreamFilter *iface, IAMMediaStream *pAMMediaStream)
483 struct filter *This = impl_from_IMediaStreamFilter(iface);
484 IAMMediaStream** streams;
485 HRESULT hr;
487 TRACE("(%p)->(%p)\n", iface, pAMMediaStream);
489 streams = CoTaskMemRealloc(This->streams, (This->nb_streams + 1) * sizeof(IAMMediaStream*));
490 if (!streams)
491 return E_OUTOFMEMORY;
492 This->streams = streams;
494 hr = IAMMediaStream_JoinFilter(pAMMediaStream, iface);
495 if (FAILED(hr))
496 return hr;
498 This->streams[This->nb_streams] = pAMMediaStream;
499 This->nb_streams++;
501 IAMMediaStream_AddRef(pAMMediaStream);
503 return S_OK;
506 static HRESULT WINAPI filter_GetMediaStream(IMediaStreamFilter *iface, REFMSPID idPurpose, IMediaStream **ppMediaStream)
508 struct filter *This = impl_from_IMediaStreamFilter(iface);
509 MSPID purpose_id;
510 unsigned int i;
512 TRACE("(%p)->(%s,%p)\n", iface, debugstr_guid(idPurpose), ppMediaStream);
514 for (i = 0; i < This->nb_streams; i++)
516 IAMMediaStream_GetInformation(This->streams[i], &purpose_id, NULL);
517 if (IsEqualIID(&purpose_id, idPurpose))
519 *ppMediaStream = (IMediaStream *)This->streams[i];
520 IMediaStream_AddRef(*ppMediaStream);
521 return S_OK;
525 return MS_E_NOSTREAM;
528 static HRESULT WINAPI filter_EnumMediaStreams(IMediaStreamFilter *iface, LONG index, IMediaStream **stream)
530 struct filter *filter = impl_from_IMediaStreamFilter(iface);
532 TRACE("filter %p, index %d, stream %p.\n", filter, index, stream);
534 if (index >= filter->nb_streams)
535 return S_FALSE;
537 if (!stream)
538 return E_POINTER;
540 IMediaStream_AddRef(*stream = (IMediaStream *)filter->streams[index]);
541 return S_OK;
544 static IMediaSeeking *get_seeking(IAMMediaStream *stream)
546 IMediaSeeking *seeking;
547 IPin *pin, *peer;
548 HRESULT hr;
550 if (FAILED(IAMMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin)))
552 WARN("Stream %p does not support IPin.\n", stream);
553 return NULL;
556 hr = IPin_ConnectedTo(pin, &peer);
557 IPin_Release(pin);
558 if (FAILED(hr))
559 return NULL;
561 hr = IPin_QueryInterface(peer, &IID_IMediaSeeking, (void **)&seeking);
562 IPin_Release(peer);
563 if (FAILED(hr))
564 return NULL;
566 return seeking;
569 static HRESULT WINAPI filter_SupportSeeking(IMediaStreamFilter *iface, BOOL renderer)
571 struct filter *filter = impl_from_IMediaStreamFilter(iface);
572 unsigned int i;
574 TRACE("filter %p, renderer %d\n", iface, renderer);
576 if (!renderer)
577 FIXME("Non-renderer filter support is not yet implemented.\n");
579 EnterCriticalSection(&filter->cs);
581 if (filter->seekable_stream)
583 LeaveCriticalSection(&filter->cs);
584 return HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED);
587 for (i = 0; i < filter->nb_streams; ++i)
589 IMediaSeeking *seeking = get_seeking(filter->streams[i]);
590 LONGLONG duration;
592 if (!seeking)
593 continue;
595 if (SUCCEEDED(IMediaSeeking_GetDuration(seeking, &duration)))
597 filter->seekable_stream = filter->streams[i];
598 IMediaSeeking_Release(seeking);
599 LeaveCriticalSection(&filter->cs);
600 return S_OK;
603 IMediaSeeking_Release(seeking);
606 LeaveCriticalSection(&filter->cs);
607 return E_NOINTERFACE;
610 static HRESULT WINAPI filter_ReferenceTimeToStreamTime(IMediaStreamFilter *iface, REFERENCE_TIME *pTime)
612 FIXME("(%p)->(%p): Stub!\n", iface, pTime);
614 return E_NOTIMPL;
617 static HRESULT WINAPI filter_GetCurrentStreamTime(IMediaStreamFilter *iface, REFERENCE_TIME *pCurrentStreamTime)
619 FIXME("(%p)->(%p): Stub!\n", iface, pCurrentStreamTime);
621 return E_NOTIMPL;
624 static HRESULT WINAPI filter_WaitUntil(IMediaStreamFilter *iface, REFERENCE_TIME WaitStreamTime)
626 FIXME("(%p)->(%s): Stub!\n", iface, wine_dbgstr_longlong(WaitStreamTime));
628 return E_NOTIMPL;
631 static HRESULT WINAPI filter_Flush(IMediaStreamFilter *iface, BOOL bCancelEOS)
633 FIXME("(%p)->(%d): Stub!\n", iface, bCancelEOS);
635 return E_NOTIMPL;
638 static HRESULT WINAPI filter_EndOfStream(IMediaStreamFilter *iface)
640 FIXME("(%p)->(): Stub!\n", iface);
642 return E_NOTIMPL;
645 static const IMediaStreamFilterVtbl filter_vtbl =
647 filter_QueryInterface,
648 filter_AddRef,
649 filter_Release,
650 filter_GetClassID,
651 filter_Stop,
652 filter_Pause,
653 filter_Run,
654 filter_GetState,
655 filter_SetSyncSource,
656 filter_GetSyncSource,
657 filter_EnumPins,
658 filter_FindPin,
659 filter_QueryFilterInfo,
660 filter_JoinFilterGraph,
661 filter_QueryVendorInfo,
662 filter_AddMediaStream,
663 filter_GetMediaStream,
664 filter_EnumMediaStreams,
665 filter_SupportSeeking,
666 filter_ReferenceTimeToStreamTime,
667 filter_GetCurrentStreamTime,
668 filter_WaitUntil,
669 filter_Flush,
670 filter_EndOfStream
673 static inline struct filter *impl_from_IMediaSeeking(IMediaSeeking *iface)
675 return CONTAINING_RECORD(iface, struct filter, IMediaSeeking_iface);
678 static HRESULT WINAPI filter_seeking_QueryInterface(IMediaSeeking *iface, REFIID iid, void **out)
680 struct filter *filter = impl_from_IMediaSeeking(iface);
681 return IMediaStreamFilter_QueryInterface(&filter->IMediaStreamFilter_iface, iid, out);
684 static ULONG WINAPI filter_seeking_AddRef(IMediaSeeking *iface)
686 struct filter *filter = impl_from_IMediaSeeking(iface);
687 return IMediaStreamFilter_AddRef(&filter->IMediaStreamFilter_iface);
690 static ULONG WINAPI filter_seeking_Release(IMediaSeeking *iface)
692 struct filter *filter = impl_from_IMediaSeeking(iface);
693 return IMediaStreamFilter_Release(&filter->IMediaStreamFilter_iface);
696 static HRESULT WINAPI filter_seeking_GetCapabilities(IMediaSeeking *iface, DWORD *capabilities)
698 FIXME("iface %p, capabilities %p, stub!\n", iface, capabilities);
700 return E_NOTIMPL;
703 static HRESULT WINAPI filter_seeking_CheckCapabilities(IMediaSeeking *iface, DWORD *capabilities)
705 FIXME("iface %p, capabilities %p, stub!\n", iface, capabilities);
707 return E_NOTIMPL;
710 static HRESULT WINAPI filter_seeking_IsFormatSupported(IMediaSeeking *iface, const GUID *format)
712 FIXME("iface %p, format %s, stub!\n", iface, debugstr_guid(format));
714 return E_NOTIMPL;
717 static HRESULT WINAPI filter_seeking_QueryPreferredFormat(IMediaSeeking *iface, GUID *format)
719 FIXME("iface %p, format %p, stub!\n", iface, format);
721 return E_NOTIMPL;
724 static HRESULT WINAPI filter_seeking_GetTimeFormat(IMediaSeeking *iface, GUID *format)
726 FIXME("iface %p, format %p, stub!\n", iface, format);
728 return E_NOTIMPL;
731 static HRESULT WINAPI filter_seeking_IsUsingTimeFormat(IMediaSeeking *iface, const GUID *format)
733 FIXME("iface %p, format %s, stub!\n", iface, debugstr_guid(format));
735 return E_NOTIMPL;
738 static HRESULT WINAPI filter_seeking_SetTimeFormat(IMediaSeeking *iface, const GUID *format)
740 FIXME("iface %p, format %s, stub!\n", iface, debugstr_guid(format));
742 return E_NOTIMPL;
745 static HRESULT WINAPI filter_seeking_GetDuration(IMediaSeeking *iface, LONGLONG *duration)
747 FIXME("iface %p, duration %p, stub!\n", iface, duration);
749 return E_NOTIMPL;
752 static HRESULT WINAPI filter_seeking_GetStopPosition(IMediaSeeking *iface, LONGLONG *stop)
754 FIXME("iface %p, stop %p, stub!\n", iface, stop);
756 return E_NOTIMPL;
759 static HRESULT WINAPI filter_seeking_GetCurrentPosition(IMediaSeeking *iface, LONGLONG *current)
761 FIXME("iface %p, current %p, stub!\n", iface, current);
763 return E_NOTIMPL;
766 static HRESULT WINAPI filter_seeking_ConvertTimeFormat(IMediaSeeking *iface, LONGLONG *target,
767 const GUID *target_format, LONGLONG source, const GUID *source_format)
769 FIXME("iface %p, target %p, target_format %s, source 0x%s, source_format %s, stub!\n", iface, target, debugstr_guid(target_format),
770 wine_dbgstr_longlong(source), debugstr_guid(source_format));
772 return E_NOTIMPL;
775 static HRESULT WINAPI filter_seeking_SetPositions(IMediaSeeking *iface, LONGLONG *current_ptr, DWORD current_flags,
776 LONGLONG *stop_ptr, DWORD stop_flags)
778 FIXME("iface %p, current %s, current_flags %#x, stop %s, stop_flags %#x, stub!\n", iface,
779 current_ptr ? wine_dbgstr_longlong(*current_ptr) : "<null>", current_flags,
780 stop_ptr ? wine_dbgstr_longlong(*stop_ptr): "<null>", stop_flags);
782 return E_NOTIMPL;
785 static HRESULT WINAPI filter_seeking_GetPositions(IMediaSeeking *iface, LONGLONG *current, LONGLONG *stop)
787 FIXME("iface %p, current %p, stop %p, stub!\n", iface, current, stop);
789 return E_NOTIMPL;
792 static HRESULT WINAPI filter_seeking_GetAvailable(IMediaSeeking *iface, LONGLONG *earliest, LONGLONG *latest)
794 FIXME("iface %p, earliest %p, latest %p, stub!\n", iface, earliest, latest);
796 return E_NOTIMPL;
799 static HRESULT WINAPI filter_seeking_SetRate(IMediaSeeking *iface, double rate)
801 FIXME("iface %p, rate %f, stub!\n", iface, rate);
803 return E_NOTIMPL;
806 static HRESULT WINAPI filter_seeking_GetRate(IMediaSeeking *iface, double *rate)
808 FIXME("iface %p, rate %p, stub!\n", iface, rate);
810 return E_NOTIMPL;
813 static HRESULT WINAPI filter_seeking_GetPreroll(IMediaSeeking *iface, LONGLONG *preroll)
815 FIXME("iface %p, preroll %p, stub!\n", iface, preroll);
817 return E_NOTIMPL;
820 static const IMediaSeekingVtbl filter_seeking_vtbl =
822 filter_seeking_QueryInterface,
823 filter_seeking_AddRef,
824 filter_seeking_Release,
825 filter_seeking_GetCapabilities,
826 filter_seeking_CheckCapabilities,
827 filter_seeking_IsFormatSupported,
828 filter_seeking_QueryPreferredFormat,
829 filter_seeking_GetTimeFormat,
830 filter_seeking_IsUsingTimeFormat,
831 filter_seeking_SetTimeFormat,
832 filter_seeking_GetDuration,
833 filter_seeking_GetStopPosition,
834 filter_seeking_GetCurrentPosition,
835 filter_seeking_ConvertTimeFormat,
836 filter_seeking_SetPositions,
837 filter_seeking_GetPositions,
838 filter_seeking_GetAvailable,
839 filter_seeking_SetRate,
840 filter_seeking_GetRate,
841 filter_seeking_GetPreroll,
844 HRESULT filter_create(IUnknown *outer, void **out)
846 struct filter *object;
848 TRACE("outer %p, out %p.\n", outer, out);
850 if (outer)
851 return CLASS_E_NOAGGREGATION;
853 if (!(object = heap_alloc_zero(sizeof(*object))))
854 return E_OUTOFMEMORY;
856 object->IMediaStreamFilter_iface.lpVtbl = &filter_vtbl;
857 object->IMediaSeeking_iface.lpVtbl = &filter_seeking_vtbl;
858 object->refcount = 1;
859 InitializeCriticalSection(&object->cs);
860 object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": MediaStreamFilter.cs");
862 TRACE("Created media stream filter %p.\n", object);
863 *out = &object->IMediaStreamFilter_iface;
864 return S_OK;