2 * Copyright 2020 Nikolay Sivov for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "mf_private.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(mfplat
);
31 enum video_renderer_flags
34 EVR_INIT_SERVICES
= 0x2, /* Currently in InitServices() call. */
35 EVR_MIXER_INITED_SERVICES
= 0x4,
36 EVR_PRESENTER_INITED_SERVICES
= 0x8,
39 enum video_renderer_state
41 EVR_STATE_STOPPED
= 0,
46 enum video_stream_flags
48 EVR_STREAM_PREROLLING
= 0x1,
49 EVR_STREAM_PREROLLED
= 0x2,
52 struct video_renderer
;
56 IMFStreamSink IMFStreamSink_iface
;
57 IMFMediaTypeHandler IMFMediaTypeHandler_iface
;
58 IMFGetService IMFGetService_iface
;
59 IMFAttributes IMFAttributes_iface
;
63 struct video_renderer
*parent
;
64 IMFMediaEventQueue
*event_queue
;
65 IMFVideoSampleAllocator
*allocator
;
66 IMFAttributes
*attributes
;
72 IMFMediaSink IMFMediaSink_iface
;
73 IMFMediaSinkPreroll IMFMediaSinkPreroll_iface
;
74 IMFVideoRenderer IMFVideoRenderer_iface
;
75 IMFClockStateSink IMFClockStateSink_iface
;
76 IMFMediaEventGenerator IMFMediaEventGenerator_iface
;
77 IMFGetService IMFGetService_iface
;
78 IMFTopologyServiceLookup IMFTopologyServiceLookup_iface
;
79 IMediaEventSink IMediaEventSink_iface
;
80 IMFAttributes IMFAttributes_iface
;
81 IMFQualityAdvise IMFQualityAdvise_iface
;
84 IMFMediaEventQueue
*event_queue
;
85 IMFAttributes
*attributes
;
86 IMFPresentationClock
*clock
;
89 IMFVideoPresenter
*presenter
;
91 IUnknown
*device_manager
;
95 struct video_stream
**streams
;
102 static struct video_renderer
*impl_from_IMFMediaSink(IMFMediaSink
*iface
)
104 return CONTAINING_RECORD(iface
, struct video_renderer
, IMFMediaSink_iface
);
107 static struct video_renderer
*impl_from_IMFMediaSinkPreroll(IMFMediaSinkPreroll
*iface
)
109 return CONTAINING_RECORD(iface
, struct video_renderer
, IMFMediaSinkPreroll_iface
);
112 static struct video_renderer
*impl_from_IMFVideoRenderer(IMFVideoRenderer
*iface
)
114 return CONTAINING_RECORD(iface
, struct video_renderer
, IMFVideoRenderer_iface
);
117 static struct video_renderer
*impl_from_IMFMediaEventGenerator(IMFMediaEventGenerator
*iface
)
119 return CONTAINING_RECORD(iface
, struct video_renderer
, IMFMediaEventGenerator_iface
);
122 static struct video_renderer
*impl_from_IMFClockStateSink(IMFClockStateSink
*iface
)
124 return CONTAINING_RECORD(iface
, struct video_renderer
, IMFClockStateSink_iface
);
127 static struct video_renderer
*impl_from_IMFGetService(IMFGetService
*iface
)
129 return CONTAINING_RECORD(iface
, struct video_renderer
, IMFGetService_iface
);
132 static struct video_renderer
*impl_from_IMFTopologyServiceLookup(IMFTopologyServiceLookup
*iface
)
134 return CONTAINING_RECORD(iface
, struct video_renderer
, IMFTopologyServiceLookup_iface
);
137 static struct video_renderer
*impl_from_IMediaEventSink(IMediaEventSink
*iface
)
139 return CONTAINING_RECORD(iface
, struct video_renderer
, IMediaEventSink_iface
);
142 static struct video_renderer
*impl_from_IMFAttributes(IMFAttributes
*iface
)
144 return CONTAINING_RECORD(iface
, struct video_renderer
, IMFAttributes_iface
);
147 static struct video_renderer
*impl_from_IMFQualityAdvise(IMFQualityAdvise
*iface
)
149 return CONTAINING_RECORD(iface
, struct video_renderer
, IMFQualityAdvise_iface
);
152 static struct video_stream
*impl_from_IMFStreamSink(IMFStreamSink
*iface
)
154 return CONTAINING_RECORD(iface
, struct video_stream
, IMFStreamSink_iface
);
157 static struct video_stream
*impl_from_IMFMediaTypeHandler(IMFMediaTypeHandler
*iface
)
159 return CONTAINING_RECORD(iface
, struct video_stream
, IMFMediaTypeHandler_iface
);
162 static struct video_stream
*impl_from_stream_IMFGetService(IMFGetService
*iface
)
164 return CONTAINING_RECORD(iface
, struct video_stream
, IMFGetService_iface
);
167 static struct video_stream
*impl_from_stream_IMFAttributes(IMFAttributes
*iface
)
169 return CONTAINING_RECORD(iface
, struct video_stream
, IMFAttributes_iface
);
172 static void video_renderer_release_services(struct video_renderer
*renderer
)
174 IMFTopologyServiceLookupClient
*lookup_client
;
176 if (renderer
->flags
& EVR_MIXER_INITED_SERVICES
&& SUCCEEDED(IMFTransform_QueryInterface(renderer
->mixer
,
177 &IID_IMFTopologyServiceLookupClient
, (void **)&lookup_client
)))
179 IMFTopologyServiceLookupClient_ReleaseServicePointers(lookup_client
);
180 IMFTopologyServiceLookupClient_Release(lookup_client
);
181 renderer
->flags
&= ~EVR_MIXER_INITED_SERVICES
;
184 if (renderer
->flags
& EVR_PRESENTER_INITED_SERVICES
&& SUCCEEDED(IMFVideoPresenter_QueryInterface(renderer
->presenter
,
185 &IID_IMFTopologyServiceLookupClient
, (void **)&lookup_client
)))
187 IMFTopologyServiceLookupClient_ReleaseServicePointers(lookup_client
);
188 IMFTopologyServiceLookupClient_Release(lookup_client
);
189 renderer
->flags
&= ~EVR_PRESENTER_INITED_SERVICES
;
193 static HRESULT WINAPI
video_stream_sink_QueryInterface(IMFStreamSink
*iface
, REFIID riid
, void **obj
)
195 struct video_stream
*stream
= impl_from_IMFStreamSink(iface
);
197 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
199 if (IsEqualIID(riid
, &IID_IMFStreamSink
) ||
200 IsEqualIID(riid
, &IID_IMFMediaEventGenerator
) ||
201 IsEqualIID(riid
, &IID_IUnknown
))
205 else if (IsEqualIID(riid
, &IID_IMFMediaTypeHandler
))
207 *obj
= &stream
->IMFMediaTypeHandler_iface
;
209 else if (IsEqualIID(riid
, &IID_IMFGetService
))
211 *obj
= &stream
->IMFGetService_iface
;
213 else if (IsEqualIID(riid
, &IID_IMFAttributes
))
215 *obj
= &stream
->IMFAttributes_iface
;
219 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
221 return E_NOINTERFACE
;
224 IUnknown_AddRef((IUnknown
*)*obj
);
229 static ULONG WINAPI
video_stream_sink_AddRef(IMFStreamSink
*iface
)
231 struct video_stream
*stream
= impl_from_IMFStreamSink(iface
);
232 ULONG refcount
= InterlockedIncrement(&stream
->refcount
);
234 TRACE("%p, refcount %u.\n", iface
, refcount
);
239 static ULONG WINAPI
video_stream_sink_Release(IMFStreamSink
*iface
)
241 struct video_stream
*stream
= impl_from_IMFStreamSink(iface
);
242 ULONG refcount
= InterlockedDecrement(&stream
->refcount
);
246 if (stream
->event_queue
)
247 IMFMediaEventQueue_Release(stream
->event_queue
);
248 if (stream
->attributes
)
249 IMFAttributes_Release(stream
->attributes
);
250 if (stream
->allocator
)
251 IMFVideoSampleAllocator_Release(stream
->allocator
);
252 DeleteCriticalSection(&stream
->cs
);
259 static HRESULT WINAPI
video_stream_sink_GetEvent(IMFStreamSink
*iface
, DWORD flags
, IMFMediaEvent
**event
)
261 struct video_stream
*stream
= impl_from_IMFStreamSink(iface
);
263 TRACE("%p, %#x, %p.\n", iface
, flags
, event
);
265 return IMFMediaEventQueue_GetEvent(stream
->event_queue
, flags
, event
);
268 static HRESULT WINAPI
video_stream_sink_BeginGetEvent(IMFStreamSink
*iface
, IMFAsyncCallback
*callback
, IUnknown
*state
)
270 struct video_stream
*stream
= impl_from_IMFStreamSink(iface
);
272 TRACE("%p, %p, %p.\n", iface
, callback
, state
);
274 return IMFMediaEventQueue_BeginGetEvent(stream
->event_queue
, callback
, state
);
277 static HRESULT WINAPI
video_stream_sink_EndGetEvent(IMFStreamSink
*iface
, IMFAsyncResult
*result
,
278 IMFMediaEvent
**event
)
280 struct video_stream
*stream
= impl_from_IMFStreamSink(iface
);
282 TRACE("%p, %p, %p.\n", iface
, result
, event
);
284 return IMFMediaEventQueue_EndGetEvent(stream
->event_queue
, result
, event
);
287 static HRESULT WINAPI
video_stream_sink_QueueEvent(IMFStreamSink
*iface
, MediaEventType event_type
,
288 REFGUID ext_type
, HRESULT hr
, const PROPVARIANT
*value
)
290 struct video_stream
*stream
= impl_from_IMFStreamSink(iface
);
292 TRACE("%p, %d, %s, %#x, %p.\n", iface
, event_type
, debugstr_guid(ext_type
), hr
, value
);
294 return IMFMediaEventQueue_QueueEventParamVar(stream
->event_queue
, event_type
, ext_type
, hr
, value
);
297 static HRESULT WINAPI
video_stream_sink_GetMediaSink(IMFStreamSink
*iface
, IMFMediaSink
**sink
)
299 struct video_stream
*stream
= impl_from_IMFStreamSink(iface
);
302 TRACE("%p, %p.\n", iface
, sink
);
304 EnterCriticalSection(&stream
->cs
);
306 hr
= MF_E_STREAMSINK_REMOVED
;
311 *sink
= &stream
->parent
->IMFMediaSink_iface
;
312 IMFMediaSink_AddRef(*sink
);
314 LeaveCriticalSection(&stream
->cs
);
319 static HRESULT WINAPI
video_stream_sink_GetIdentifier(IMFStreamSink
*iface
, DWORD
*id
)
321 struct video_stream
*stream
= impl_from_IMFStreamSink(iface
);
323 TRACE("%p, %p.\n", iface
, id
);
326 return MF_E_STREAMSINK_REMOVED
;
336 static HRESULT WINAPI
video_stream_sink_GetMediaTypeHandler(IMFStreamSink
*iface
, IMFMediaTypeHandler
**handler
)
338 struct video_stream
*stream
= impl_from_IMFStreamSink(iface
);
340 TRACE("%p, %p.\n", iface
, handler
);
346 return MF_E_STREAMSINK_REMOVED
;
348 *handler
= &stream
->IMFMediaTypeHandler_iface
;
349 IMFMediaTypeHandler_AddRef(*handler
);
354 static HRESULT WINAPI
video_stream_sink_ProcessSample(IMFStreamSink
*iface
, IMFSample
*sample
)
356 struct video_stream
*stream
= impl_from_IMFStreamSink(iface
);
360 TRACE("%p, %p.\n", iface
, sample
);
362 EnterCriticalSection(&stream
->cs
);
365 hr
= MF_E_STREAMSINK_REMOVED
;
366 else if (!stream
->parent
->clock
)
368 else if (FAILED(hr
= IMFSample_GetSampleTime(sample
, ×tamp
)))
370 WARN("No sample timestamp, hr %#x.\n", hr
);
372 else if (stream
->parent
->state
== EVR_STATE_RUNNING
|| stream
->flags
& EVR_STREAM_PREROLLING
)
374 if (SUCCEEDED(IMFTransform_ProcessInput(stream
->parent
->mixer
, stream
->id
, sample
, 0)))
375 IMFVideoPresenter_ProcessMessage(stream
->parent
->presenter
, MFVP_MESSAGE_PROCESSINPUTNOTIFY
, 0);
377 if (stream
->flags
& EVR_STREAM_PREROLLING
)
379 IMFMediaEventQueue_QueueEventParamVar(stream
->event_queue
, MEStreamSinkPrerolled
, &GUID_NULL
, S_OK
, NULL
);
380 stream
->flags
&= ~EVR_STREAM_PREROLLING
;
381 stream
->flags
|= EVR_STREAM_PREROLLED
;
385 LeaveCriticalSection(&stream
->cs
);
390 static HRESULT WINAPI
video_stream_sink_PlaceMarker(IMFStreamSink
*iface
, MFSTREAMSINK_MARKER_TYPE marker_type
,
391 const PROPVARIANT
*marker_value
, const PROPVARIANT
*context_value
)
393 FIXME("%p, %d, %p, %p.\n", iface
, marker_type
, marker_value
, context_value
);
398 static HRESULT WINAPI
video_stream_sink_Flush(IMFStreamSink
*iface
)
400 FIXME("%p.\n", iface
);
405 static const IMFStreamSinkVtbl video_stream_sink_vtbl
=
407 video_stream_sink_QueryInterface
,
408 video_stream_sink_AddRef
,
409 video_stream_sink_Release
,
410 video_stream_sink_GetEvent
,
411 video_stream_sink_BeginGetEvent
,
412 video_stream_sink_EndGetEvent
,
413 video_stream_sink_QueueEvent
,
414 video_stream_sink_GetMediaSink
,
415 video_stream_sink_GetIdentifier
,
416 video_stream_sink_GetMediaTypeHandler
,
417 video_stream_sink_ProcessSample
,
418 video_stream_sink_PlaceMarker
,
419 video_stream_sink_Flush
,
422 static HRESULT WINAPI
video_stream_typehandler_QueryInterface(IMFMediaTypeHandler
*iface
, REFIID riid
,
425 struct video_stream
*stream
= impl_from_IMFMediaTypeHandler(iface
);
426 return IMFStreamSink_QueryInterface(&stream
->IMFStreamSink_iface
, riid
, obj
);
429 static ULONG WINAPI
video_stream_typehandler_AddRef(IMFMediaTypeHandler
*iface
)
431 struct video_stream
*stream
= impl_from_IMFMediaTypeHandler(iface
);
432 return IMFStreamSink_AddRef(&stream
->IMFStreamSink_iface
);
435 static ULONG WINAPI
video_stream_typehandler_Release(IMFMediaTypeHandler
*iface
)
437 struct video_stream
*stream
= impl_from_IMFMediaTypeHandler(iface
);
438 return IMFStreamSink_Release(&stream
->IMFStreamSink_iface
);
441 static HRESULT WINAPI
video_stream_typehandler_IsMediaTypeSupported(IMFMediaTypeHandler
*iface
,
442 IMFMediaType
*in_type
, IMFMediaType
**out_type
)
444 struct video_stream
*stream
= impl_from_IMFMediaTypeHandler(iface
);
447 TRACE("%p, %p, %p.\n", iface
, in_type
, out_type
);
453 return MF_E_INVALIDMEDIATYPE
;
455 if (SUCCEEDED(hr
= IMFTransform_SetInputType(stream
->parent
->mixer
, stream
->id
, in_type
,
456 MFT_SET_TYPE_TEST_ONLY
)))
458 if (out_type
) *out_type
= NULL
;
464 static HRESULT WINAPI
video_stream_typehandler_GetMediaTypeCount(IMFMediaTypeHandler
*iface
, DWORD
*count
)
466 TRACE("%p, %p.\n", iface
, count
);
476 static HRESULT WINAPI
video_stream_typehandler_GetMediaTypeByIndex(IMFMediaTypeHandler
*iface
, DWORD index
,
479 TRACE("%p, %u, %p.\n", iface
, index
, type
);
481 return MF_E_NO_MORE_TYPES
;
484 static HRESULT WINAPI
video_stream_typehandler_SetCurrentMediaType(IMFMediaTypeHandler
*iface
, IMFMediaType
*type
)
486 struct video_stream
*stream
= impl_from_IMFMediaTypeHandler(iface
);
489 TRACE("%p, %p.\n", iface
, type
);
495 return MF_E_STREAMSINK_REMOVED
;
497 hr
= IMFTransform_SetInputType(stream
->parent
->mixer
, stream
->id
, type
, 0);
498 if (SUCCEEDED(hr
) && !stream
->id
)
499 hr
= IMFVideoPresenter_ProcessMessage(stream
->parent
->presenter
, MFVP_MESSAGE_INVALIDATEMEDIATYPE
, 0);
504 static HRESULT WINAPI
video_stream_typehandler_GetCurrentMediaType(IMFMediaTypeHandler
*iface
, IMFMediaType
**type
)
506 struct video_stream
*stream
= impl_from_IMFMediaTypeHandler(iface
);
508 TRACE("%p, %p.\n", iface
, type
);
514 return MF_E_STREAMSINK_REMOVED
;
516 return IMFTransform_GetInputCurrentType(stream
->parent
->mixer
, stream
->id
, type
);
519 static HRESULT WINAPI
video_stream_typehandler_GetMajorType(IMFMediaTypeHandler
*iface
, GUID
*type
)
521 struct video_stream
*stream
= impl_from_IMFMediaTypeHandler(iface
);
523 TRACE("%p, %p.\n", iface
, type
);
526 return MF_E_STREAMSINK_REMOVED
;
531 memcpy(type
, &MFMediaType_Video
, sizeof(*type
));
535 static const IMFMediaTypeHandlerVtbl video_stream_type_handler_vtbl
=
537 video_stream_typehandler_QueryInterface
,
538 video_stream_typehandler_AddRef
,
539 video_stream_typehandler_Release
,
540 video_stream_typehandler_IsMediaTypeSupported
,
541 video_stream_typehandler_GetMediaTypeCount
,
542 video_stream_typehandler_GetMediaTypeByIndex
,
543 video_stream_typehandler_SetCurrentMediaType
,
544 video_stream_typehandler_GetCurrentMediaType
,
545 video_stream_typehandler_GetMajorType
,
548 static HRESULT WINAPI
video_stream_get_service_QueryInterface(IMFGetService
*iface
, REFIID riid
, void **obj
)
550 struct video_stream
*stream
= impl_from_stream_IMFGetService(iface
);
551 return IMFStreamSink_QueryInterface(&stream
->IMFStreamSink_iface
, riid
, obj
);
554 static ULONG WINAPI
video_stream_get_service_AddRef(IMFGetService
*iface
)
556 struct video_stream
*stream
= impl_from_stream_IMFGetService(iface
);
557 return IMFStreamSink_AddRef(&stream
->IMFStreamSink_iface
);
560 static ULONG WINAPI
video_stream_get_service_Release(IMFGetService
*iface
)
562 struct video_stream
*stream
= impl_from_stream_IMFGetService(iface
);
563 return IMFStreamSink_Release(&stream
->IMFStreamSink_iface
);
566 static HRESULT WINAPI
video_stream_get_service_GetService(IMFGetService
*iface
, REFGUID service
, REFIID riid
, void **obj
)
568 struct video_stream
*stream
= impl_from_stream_IMFGetService(iface
);
571 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_guid(service
), debugstr_guid(riid
), obj
);
573 if (IsEqualGUID(service
, &MR_VIDEO_ACCELERATION_SERVICE
))
575 if (IsEqualIID(riid
, &IID_IMFVideoSampleAllocator
))
577 EnterCriticalSection(&stream
->cs
);
579 if (!stream
->allocator
)
581 hr
= MFCreateVideoSampleAllocator(&IID_IMFVideoSampleAllocator
, (void **)&stream
->allocator
);
583 hr
= IMFVideoSampleAllocator_SetDirectXManager(stream
->allocator
, stream
->parent
->device_manager
);
586 hr
= IMFVideoSampleAllocator_QueryInterface(stream
->allocator
, riid
, obj
);
588 LeaveCriticalSection(&stream
->cs
);
593 return E_NOINTERFACE
;
596 FIXME("Unsupported service %s.\n", debugstr_guid(service
));
601 static const IMFGetServiceVtbl video_stream_get_service_vtbl
=
603 video_stream_get_service_QueryInterface
,
604 video_stream_get_service_AddRef
,
605 video_stream_get_service_Release
,
606 video_stream_get_service_GetService
,
609 static HRESULT WINAPI
video_stream_attributes_QueryInterface(IMFAttributes
*iface
, REFIID riid
, void **obj
)
611 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
612 return IMFStreamSink_QueryInterface(&stream
->IMFStreamSink_iface
, riid
, obj
);
615 static ULONG WINAPI
video_stream_attributes_AddRef(IMFAttributes
*iface
)
617 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
618 return IMFStreamSink_AddRef(&stream
->IMFStreamSink_iface
);
621 static ULONG WINAPI
video_stream_attributes_Release(IMFAttributes
*iface
)
623 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
624 return IMFStreamSink_Release(&stream
->IMFStreamSink_iface
);
627 static HRESULT WINAPI
video_stream_attributes_GetItem(IMFAttributes
*iface
, REFGUID key
, PROPVARIANT
*value
)
629 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
631 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
633 return IMFAttributes_GetItem(stream
->attributes
, key
, value
);
636 static HRESULT WINAPI
video_stream_attributes_GetItemType(IMFAttributes
*iface
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
638 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
640 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), type
);
642 return IMFAttributes_GetItemType(stream
->attributes
, key
, type
);
645 static HRESULT WINAPI
video_stream_attributes_CompareItem(IMFAttributes
*iface
, REFGUID key
, REFPROPVARIANT value
,
648 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
650 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_guid(key
), value
, result
);
652 return IMFAttributes_CompareItem(stream
->attributes
, key
, value
, result
);
655 static HRESULT WINAPI
video_stream_attributes_Compare(IMFAttributes
*iface
, IMFAttributes
*theirs
,
656 MF_ATTRIBUTES_MATCH_TYPE type
, BOOL
*result
)
658 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
660 TRACE("%p, %p, %d, %p.\n", iface
, theirs
, type
, result
);
662 return IMFAttributes_Compare(stream
->attributes
, theirs
, type
, result
);
665 static HRESULT WINAPI
video_stream_attributes_GetUINT32(IMFAttributes
*iface
, REFGUID key
, UINT32
*value
)
667 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
669 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
671 return IMFAttributes_GetUINT32(stream
->attributes
, key
, value
);
674 static HRESULT WINAPI
video_stream_attributes_GetUINT64(IMFAttributes
*iface
, REFGUID key
, UINT64
*value
)
676 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
678 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
680 return IMFAttributes_GetUINT64(stream
->attributes
, key
, value
);
683 static HRESULT WINAPI
video_stream_attributes_GetDouble(IMFAttributes
*iface
, REFGUID key
, double *value
)
685 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
687 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
689 return IMFAttributes_GetDouble(stream
->attributes
, key
, value
);
692 static HRESULT WINAPI
video_stream_attributes_GetGUID(IMFAttributes
*iface
, REFGUID key
, GUID
*value
)
694 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
696 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
698 return IMFAttributes_GetGUID(stream
->attributes
, key
, value
);
701 static HRESULT WINAPI
video_stream_attributes_GetStringLength(IMFAttributes
*iface
, REFGUID key
,
704 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
706 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), length
);
708 return IMFAttributes_GetStringLength(stream
->attributes
, key
, length
);
711 static HRESULT WINAPI
video_stream_attributes_GetString(IMFAttributes
*iface
, REFGUID key
, WCHAR
*value
,
712 UINT32 size
, UINT32
*length
)
714 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
716 TRACE("%p, %s, %p, %u, %p.\n", iface
, debugstr_guid(key
), value
, size
, length
);
718 return IMFAttributes_GetString(stream
->attributes
, key
, value
, size
, length
);
721 static HRESULT WINAPI
video_stream_attributes_GetAllocatedString(IMFAttributes
*iface
, REFGUID key
,
722 WCHAR
**value
, UINT32
*length
)
724 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
726 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_guid(key
), value
, length
);
728 return IMFAttributes_GetAllocatedString(stream
->attributes
, key
, value
, length
);
731 static HRESULT WINAPI
video_stream_attributes_GetBlobSize(IMFAttributes
*iface
, REFGUID key
, UINT32
*size
)
733 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
735 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), size
);
737 return IMFAttributes_GetBlobSize(stream
->attributes
, key
, size
);
740 static HRESULT WINAPI
video_stream_attributes_GetBlob(IMFAttributes
*iface
, REFGUID key
, UINT8
*buf
,
741 UINT32 bufsize
, UINT32
*blobsize
)
743 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
745 TRACE("%p, %s, %p, %u, %p.\n", iface
, debugstr_guid(key
), buf
, bufsize
, blobsize
);
747 return IMFAttributes_GetBlob(stream
->attributes
, key
, buf
, bufsize
, blobsize
);
750 static HRESULT WINAPI
video_stream_attributes_GetAllocatedBlob(IMFAttributes
*iface
, REFGUID key
,
751 UINT8
**buf
, UINT32
*size
)
753 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
755 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_guid(key
), buf
, size
);
757 return IMFAttributes_GetAllocatedBlob(stream
->attributes
, key
, buf
, size
);
760 static HRESULT WINAPI
video_stream_attributes_GetUnknown(IMFAttributes
*iface
, REFGUID key
, REFIID riid
, void **out
)
762 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
764 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_guid(key
), debugstr_guid(riid
), out
);
766 return IMFAttributes_GetUnknown(stream
->attributes
, key
, riid
, out
);
769 static HRESULT WINAPI
video_stream_attributes_SetItem(IMFAttributes
*iface
, REFGUID key
, REFPROPVARIANT value
)
771 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
773 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
775 return IMFAttributes_SetItem(stream
->attributes
, key
, value
);
778 static HRESULT WINAPI
video_stream_attributes_DeleteItem(IMFAttributes
*iface
, REFGUID key
)
780 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
782 TRACE("%p, %s.\n", iface
, debugstr_guid(key
));
784 return IMFAttributes_DeleteItem(stream
->attributes
, key
);
787 static HRESULT WINAPI
video_stream_attributes_DeleteAllItems(IMFAttributes
*iface
)
789 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
791 TRACE("%p.\n", iface
);
793 return IMFAttributes_DeleteAllItems(stream
->attributes
);
796 static HRESULT WINAPI
video_stream_attributes_SetUINT32(IMFAttributes
*iface
, REFGUID key
, UINT32 value
)
798 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
800 TRACE("%p, %s, %u.\n", iface
, debugstr_guid(key
), value
);
802 return IMFAttributes_SetUINT32(stream
->attributes
, key
, value
);
805 static HRESULT WINAPI
video_stream_attributes_SetUINT64(IMFAttributes
*iface
, REFGUID key
, UINT64 value
)
807 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
809 TRACE("%p, %s, %s.\n", iface
, debugstr_guid(key
), wine_dbgstr_longlong(value
));
811 return IMFAttributes_SetUINT64(stream
->attributes
, key
, value
);
814 static HRESULT WINAPI
video_stream_attributes_SetDouble(IMFAttributes
*iface
, REFGUID key
, double value
)
816 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
818 TRACE("%p, %s, %f.\n", iface
, debugstr_guid(key
), value
);
820 return IMFAttributes_SetDouble(stream
->attributes
, key
, value
);
823 static HRESULT WINAPI
video_stream_attributes_SetGUID(IMFAttributes
*iface
, REFGUID key
, REFGUID value
)
825 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
827 TRACE("%p, %s, %s.\n", iface
, debugstr_guid(key
), debugstr_guid(value
));
829 return IMFAttributes_SetGUID(stream
->attributes
, key
, value
);
832 static HRESULT WINAPI
video_stream_attributes_SetString(IMFAttributes
*iface
, REFGUID key
,
835 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
837 TRACE("%p, %s, %s.\n", iface
, debugstr_guid(key
), debugstr_w(value
));
839 return IMFAttributes_SetString(stream
->attributes
, key
, value
);
842 static HRESULT WINAPI
video_stream_attributes_SetBlob(IMFAttributes
*iface
, REFGUID key
,
843 const UINT8
*buf
, UINT32 size
)
845 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
847 TRACE("%p, %s, %p, %u.\n", iface
, debugstr_guid(key
), buf
, size
);
849 return IMFAttributes_SetBlob(stream
->attributes
, key
, buf
, size
);
852 static HRESULT WINAPI
video_stream_attributes_SetUnknown(IMFAttributes
*iface
, REFGUID key
,
855 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
857 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), unknown
);
859 return IMFAttributes_SetUnknown(stream
->attributes
, key
, unknown
);
862 static HRESULT WINAPI
video_stream_attributes_LockStore(IMFAttributes
*iface
)
864 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
866 TRACE("%p.\n", iface
);
868 return IMFAttributes_LockStore(stream
->attributes
);
871 static HRESULT WINAPI
video_stream_attributes_UnlockStore(IMFAttributes
*iface
)
873 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
875 TRACE("%p.\n", iface
);
877 return IMFAttributes_UnlockStore(stream
->attributes
);
880 static HRESULT WINAPI
video_stream_attributes_GetCount(IMFAttributes
*iface
, UINT32
*count
)
882 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
884 TRACE("%p, %p.\n", iface
, count
);
886 return IMFAttributes_GetCount(stream
->attributes
, count
);
889 static HRESULT WINAPI
video_stream_attributes_GetItemByIndex(IMFAttributes
*iface
, UINT32 index
,
890 GUID
*key
, PROPVARIANT
*value
)
892 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
894 TRACE("%p, %u, %p, %p.\n", iface
, index
, key
, value
);
896 return IMFAttributes_GetItemByIndex(stream
->attributes
, index
, key
, value
);
899 static HRESULT WINAPI
video_stream_attributes_CopyAllItems(IMFAttributes
*iface
, IMFAttributes
*dest
)
901 struct video_stream
*stream
= impl_from_stream_IMFAttributes(iface
);
903 TRACE("%p, %p.\n", iface
, dest
);
905 return IMFAttributes_CopyAllItems(stream
->attributes
, dest
);
908 static const IMFAttributesVtbl video_stream_attributes_vtbl
=
910 video_stream_attributes_QueryInterface
,
911 video_stream_attributes_AddRef
,
912 video_stream_attributes_Release
,
913 video_stream_attributes_GetItem
,
914 video_stream_attributes_GetItemType
,
915 video_stream_attributes_CompareItem
,
916 video_stream_attributes_Compare
,
917 video_stream_attributes_GetUINT32
,
918 video_stream_attributes_GetUINT64
,
919 video_stream_attributes_GetDouble
,
920 video_stream_attributes_GetGUID
,
921 video_stream_attributes_GetStringLength
,
922 video_stream_attributes_GetString
,
923 video_stream_attributes_GetAllocatedString
,
924 video_stream_attributes_GetBlobSize
,
925 video_stream_attributes_GetBlob
,
926 video_stream_attributes_GetAllocatedBlob
,
927 video_stream_attributes_GetUnknown
,
928 video_stream_attributes_SetItem
,
929 video_stream_attributes_DeleteItem
,
930 video_stream_attributes_DeleteAllItems
,
931 video_stream_attributes_SetUINT32
,
932 video_stream_attributes_SetUINT64
,
933 video_stream_attributes_SetDouble
,
934 video_stream_attributes_SetGUID
,
935 video_stream_attributes_SetString
,
936 video_stream_attributes_SetBlob
,
937 video_stream_attributes_SetUnknown
,
938 video_stream_attributes_LockStore
,
939 video_stream_attributes_UnlockStore
,
940 video_stream_attributes_GetCount
,
941 video_stream_attributes_GetItemByIndex
,
942 video_stream_attributes_CopyAllItems
,
945 static BOOL
video_renderer_is_mixer_d3d_aware(const struct video_renderer
*renderer
)
947 IMFAttributes
*attributes
;
948 unsigned int value
= 0;
951 if (FAILED(IMFTransform_QueryInterface(renderer
->mixer
, &IID_IMFAttributes
, (void **)&attributes
)))
954 ret
= SUCCEEDED(IMFAttributes_GetUINT32(attributes
, &MF_SA_D3D_AWARE
, &value
)) && value
;
955 IMFAttributes_Release(attributes
);
959 static HRESULT
video_renderer_stream_create(struct video_renderer
*renderer
, unsigned int id
,
960 struct video_stream
**ret
)
962 struct video_stream
*stream
;
963 IMFAttributes
*attributes
;
967 if (!(stream
= heap_alloc_zero(sizeof(*stream
))))
968 return E_OUTOFMEMORY
;
970 stream
->IMFStreamSink_iface
.lpVtbl
= &video_stream_sink_vtbl
;
971 stream
->IMFMediaTypeHandler_iface
.lpVtbl
= &video_stream_type_handler_vtbl
;
972 stream
->IMFGetService_iface
.lpVtbl
= &video_stream_get_service_vtbl
;
973 stream
->IMFAttributes_iface
.lpVtbl
= &video_stream_attributes_vtbl
;
974 stream
->refcount
= 1;
975 InitializeCriticalSection(&stream
->cs
);
977 if (FAILED(hr
= MFCreateEventQueue(&stream
->event_queue
)))
980 if (FAILED(hr
= MFCreateAttributes(&stream
->attributes
, 0)))
983 stream
->parent
= renderer
;
984 IMFMediaSink_AddRef(&stream
->parent
->IMFMediaSink_iface
);
987 if (video_renderer_is_mixer_d3d_aware(renderer
))
988 IMFAttributes_SetUINT32(stream
->attributes
, &MF_SA_D3D_AWARE
, 1);
990 if (SUCCEEDED(IMFTransform_GetInputStreamAttributes(renderer
->mixer
, id
, &attributes
)))
992 if (SUCCEEDED(IMFAttributes_GetUINT32(attributes
, &MF_SA_REQUIRED_SAMPLE_COUNT
, &value
)))
993 IMFAttributes_SetUINT32(stream
->attributes
, &MF_SA_REQUIRED_SAMPLE_COUNT
, value
);
994 IMFAttributes_Release(attributes
);
1003 IMFStreamSink_Release(&stream
->IMFStreamSink_iface
);
1008 static HRESULT WINAPI
video_renderer_sink_QueryInterface(IMFMediaSink
*iface
, REFIID riid
, void **obj
)
1010 struct video_renderer
*renderer
= impl_from_IMFMediaSink(iface
);
1012 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
1014 if (IsEqualIID(riid
, &IID_IMFMediaSink
) ||
1015 IsEqualIID(riid
, &IID_IUnknown
))
1017 *obj
= &renderer
->IMFMediaSink_iface
;
1019 else if (IsEqualIID(riid
, &IID_IMFMediaSinkPreroll
))
1021 *obj
= &renderer
->IMFMediaSinkPreroll_iface
;
1023 else if (IsEqualIID(riid
, &IID_IMFVideoRenderer
))
1025 *obj
= &renderer
->IMFVideoRenderer_iface
;
1027 else if (IsEqualIID(riid
, &IID_IMFMediaEventGenerator
))
1029 *obj
= &renderer
->IMFMediaEventGenerator_iface
;
1031 else if (IsEqualIID(riid
, &IID_IMFClockStateSink
))
1033 *obj
= &renderer
->IMFClockStateSink_iface
;
1035 else if (IsEqualIID(riid
, &IID_IMFGetService
))
1037 *obj
= &renderer
->IMFGetService_iface
;
1039 else if (IsEqualIID(riid
, &IID_IMFAttributes
))
1041 *obj
= &renderer
->IMFAttributes_iface
;
1043 else if (IsEqualIID(riid
, &IID_IMFQualityAdvise
))
1045 *obj
= &renderer
->IMFQualityAdvise_iface
;
1049 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
1051 return E_NOINTERFACE
;
1054 IUnknown_AddRef((IUnknown
*)*obj
);
1059 static ULONG WINAPI
video_renderer_sink_AddRef(IMFMediaSink
*iface
)
1061 struct video_renderer
*renderer
= impl_from_IMFMediaSink(iface
);
1062 ULONG refcount
= InterlockedIncrement(&renderer
->refcount
);
1063 TRACE("%p, refcount %u.\n", iface
, refcount
);
1067 static ULONG WINAPI
video_renderer_sink_Release(IMFMediaSink
*iface
)
1069 struct video_renderer
*renderer
= impl_from_IMFMediaSink(iface
);
1070 ULONG refcount
= InterlockedDecrement(&renderer
->refcount
);
1072 TRACE("%p, refcount %u.\n", iface
, refcount
);
1076 if (renderer
->event_queue
)
1077 IMFMediaEventQueue_Release(renderer
->event_queue
);
1078 if (renderer
->mixer
)
1079 IMFTransform_Release(renderer
->mixer
);
1080 if (renderer
->presenter
)
1081 IMFVideoPresenter_Release(renderer
->presenter
);
1082 if (renderer
->device_manager
)
1083 IUnknown_Release(renderer
->device_manager
);
1084 if (renderer
->clock
)
1085 IMFPresentationClock_Release(renderer
->clock
);
1086 if (renderer
->attributes
)
1087 IMFAttributes_Release(renderer
->attributes
);
1088 DeleteCriticalSection(&renderer
->cs
);
1089 heap_free(renderer
);
1095 static HRESULT WINAPI
video_renderer_sink_GetCharacteristics(IMFMediaSink
*iface
, DWORD
*flags
)
1097 struct video_renderer
*renderer
= impl_from_IMFMediaSink(iface
);
1099 TRACE("%p, %p.\n", iface
, flags
);
1101 if (renderer
->flags
& EVR_SHUT_DOWN
)
1102 return MF_E_SHUTDOWN
;
1104 *flags
= MEDIASINK_CLOCK_REQUIRED
| MEDIASINK_CAN_PREROLL
;
1109 static HRESULT
video_renderer_add_stream(struct video_renderer
*renderer
, unsigned int id
,
1110 IMFStreamSink
**stream_sink
)
1112 struct video_stream
*stream
;
1115 if (!mf_array_reserve((void **)&renderer
->streams
, &renderer
->stream_size
, renderer
->stream_count
+ 1,
1116 sizeof(*renderer
->streams
)))
1118 return E_OUTOFMEMORY
;
1121 if (SUCCEEDED(hr
= video_renderer_stream_create(renderer
, id
, &stream
)))
1125 *stream_sink
= &stream
->IMFStreamSink_iface
;
1126 IMFStreamSink_AddRef(*stream_sink
);
1128 renderer
->streams
[renderer
->stream_count
++] = stream
;
1134 static HRESULT WINAPI
video_renderer_sink_AddStreamSink(IMFMediaSink
*iface
, DWORD id
,
1135 IMFMediaType
*media_type
, IMFStreamSink
**stream_sink
)
1137 struct video_renderer
*renderer
= impl_from_IMFMediaSink(iface
);
1140 TRACE("%p, %#x, %p, %p.\n", iface
, id
, media_type
, stream_sink
);
1142 /* Rely on mixer for stream id validation. */
1144 EnterCriticalSection(&renderer
->cs
);
1145 if (renderer
->flags
& EVR_SHUT_DOWN
)
1147 else if (SUCCEEDED(hr
= IMFTransform_AddInputStreams(renderer
->mixer
, 1, &id
)))
1149 if (FAILED(hr
= video_renderer_add_stream(renderer
, id
, stream_sink
)))
1150 IMFTransform_DeleteInputStream(renderer
->mixer
, id
);
1153 LeaveCriticalSection(&renderer
->cs
);
1158 static HRESULT WINAPI
video_renderer_sink_RemoveStreamSink(IMFMediaSink
*iface
, DWORD id
)
1160 struct video_renderer
*renderer
= impl_from_IMFMediaSink(iface
);
1164 TRACE("%p, %#x.\n", iface
, id
);
1166 /* Rely on mixer for stream id validation. */
1168 EnterCriticalSection(&renderer
->cs
);
1169 if (renderer
->flags
& EVR_SHUT_DOWN
)
1171 else if (SUCCEEDED(hr
= IMFTransform_DeleteInputStream(renderer
->mixer
, id
)))
1173 for (i
= 0; i
< renderer
->stream_count
; ++i
)
1175 if (renderer
->streams
[i
]->id
== id
)
1177 IMFStreamSink_Release(&renderer
->streams
[i
]->IMFStreamSink_iface
);
1178 renderer
->streams
[i
] = NULL
;
1179 if (i
< renderer
->stream_count
- 1)
1181 memmove(&renderer
->streams
[i
], &renderer
->streams
[i
+1],
1182 (renderer
->stream_count
- i
- 1) * sizeof(*renderer
->streams
));
1184 renderer
->stream_count
--;
1189 LeaveCriticalSection(&renderer
->cs
);
1194 static HRESULT WINAPI
video_renderer_sink_GetStreamSinkCount(IMFMediaSink
*iface
, DWORD
*count
)
1196 struct video_renderer
*renderer
= impl_from_IMFMediaSink(iface
);
1199 TRACE("%p, %p.\n", iface
, count
);
1204 EnterCriticalSection(&renderer
->cs
);
1205 if (renderer
->flags
& EVR_SHUT_DOWN
)
1210 *count
= renderer
->stream_count
;
1211 LeaveCriticalSection(&renderer
->cs
);
1216 static HRESULT WINAPI
video_renderer_sink_GetStreamSinkByIndex(IMFMediaSink
*iface
, DWORD index
,
1217 IMFStreamSink
**stream
)
1219 struct video_renderer
*renderer
= impl_from_IMFMediaSink(iface
);
1222 TRACE("%p, %u, %p.\n", iface
, index
, stream
);
1224 EnterCriticalSection(&renderer
->cs
);
1225 if (renderer
->flags
& EVR_SHUT_DOWN
)
1229 else if (index
>= renderer
->stream_count
)
1233 *stream
= &renderer
->streams
[index
]->IMFStreamSink_iface
;
1234 IMFStreamSink_AddRef(*stream
);
1236 LeaveCriticalSection(&renderer
->cs
);
1241 static HRESULT WINAPI
video_renderer_sink_GetStreamSinkById(IMFMediaSink
*iface
, DWORD id
,
1242 IMFStreamSink
**stream
)
1244 struct video_renderer
*renderer
= impl_from_IMFMediaSink(iface
);
1248 TRACE("%p, %#x, %p.\n", iface
, id
, stream
);
1250 EnterCriticalSection(&renderer
->cs
);
1251 if (renderer
->flags
& EVR_SHUT_DOWN
)
1257 for (i
= 0; i
< renderer
->stream_count
; ++i
)
1259 if (renderer
->streams
[i
]->id
== id
)
1263 if (i
== renderer
->stream_count
)
1264 hr
= MF_E_INVALIDSTREAMNUMBER
;
1267 *stream
= &renderer
->streams
[i
]->IMFStreamSink_iface
;
1268 IMFStreamSink_AddRef(*stream
);
1271 LeaveCriticalSection(&renderer
->cs
);
1276 static void video_renderer_set_presentation_clock(struct video_renderer
*renderer
, IMFPresentationClock
*clock
)
1278 if (renderer
->clock
)
1280 IMFPresentationClock_RemoveClockStateSink(renderer
->clock
, &renderer
->IMFClockStateSink_iface
);
1281 IMFPresentationClock_Release(renderer
->clock
);
1283 renderer
->clock
= clock
;
1284 if (renderer
->clock
)
1286 IMFPresentationClock_AddRef(renderer
->clock
);
1287 IMFPresentationClock_AddClockStateSink(renderer
->clock
, &renderer
->IMFClockStateSink_iface
);
1291 static HRESULT WINAPI
video_renderer_sink_SetPresentationClock(IMFMediaSink
*iface
, IMFPresentationClock
*clock
)
1293 struct video_renderer
*renderer
= impl_from_IMFMediaSink(iface
);
1296 TRACE("%p, %p.\n", iface
, clock
);
1298 EnterCriticalSection(&renderer
->cs
);
1300 if (renderer
->flags
& EVR_SHUT_DOWN
)
1303 video_renderer_set_presentation_clock(renderer
, clock
);
1305 LeaveCriticalSection(&renderer
->cs
);
1310 static HRESULT WINAPI
video_renderer_sink_GetPresentationClock(IMFMediaSink
*iface
, IMFPresentationClock
**clock
)
1312 struct video_renderer
*renderer
= impl_from_IMFMediaSink(iface
);
1315 TRACE("%p, %p.\n", iface
, clock
);
1320 EnterCriticalSection(&renderer
->cs
);
1322 if (renderer
->flags
& EVR_SHUT_DOWN
)
1324 else if (renderer
->clock
)
1326 *clock
= renderer
->clock
;
1327 IMFPresentationClock_AddRef(*clock
);
1332 LeaveCriticalSection(&renderer
->cs
);
1337 static HRESULT WINAPI
video_renderer_sink_Shutdown(IMFMediaSink
*iface
)
1339 struct video_renderer
*renderer
= impl_from_IMFMediaSink(iface
);
1342 TRACE("%p.\n", iface
);
1344 if (renderer
->flags
& EVR_SHUT_DOWN
)
1345 return MF_E_SHUTDOWN
;
1347 EnterCriticalSection(&renderer
->cs
);
1348 renderer
->flags
|= EVR_SHUT_DOWN
;
1349 /* Detach streams from the sink. */
1350 for (i
= 0; i
< renderer
->stream_count
; ++i
)
1352 struct video_stream
*stream
= renderer
->streams
[i
];
1354 EnterCriticalSection(&stream
->cs
);
1355 stream
->parent
= NULL
;
1356 LeaveCriticalSection(&stream
->cs
);
1358 IMFMediaEventQueue_Shutdown(stream
->event_queue
);
1359 IMFStreamSink_Release(&stream
->IMFStreamSink_iface
);
1360 IMFMediaSink_Release(iface
);
1361 renderer
->streams
[i
] = NULL
;
1363 heap_free(renderer
->streams
);
1364 renderer
->stream_count
= 0;
1365 renderer
->stream_size
= 0;
1366 IMFMediaEventQueue_Shutdown(renderer
->event_queue
);
1367 video_renderer_set_presentation_clock(renderer
, NULL
);
1368 video_renderer_release_services(renderer
);
1369 LeaveCriticalSection(&renderer
->cs
);
1374 static const IMFMediaSinkVtbl video_renderer_sink_vtbl
=
1376 video_renderer_sink_QueryInterface
,
1377 video_renderer_sink_AddRef
,
1378 video_renderer_sink_Release
,
1379 video_renderer_sink_GetCharacteristics
,
1380 video_renderer_sink_AddStreamSink
,
1381 video_renderer_sink_RemoveStreamSink
,
1382 video_renderer_sink_GetStreamSinkCount
,
1383 video_renderer_sink_GetStreamSinkByIndex
,
1384 video_renderer_sink_GetStreamSinkById
,
1385 video_renderer_sink_SetPresentationClock
,
1386 video_renderer_sink_GetPresentationClock
,
1387 video_renderer_sink_Shutdown
,
1390 static HRESULT WINAPI
video_renderer_preroll_QueryInterface(IMFMediaSinkPreroll
*iface
, REFIID riid
, void **obj
)
1392 struct video_renderer
*renderer
= impl_from_IMFMediaSinkPreroll(iface
);
1393 return IMFMediaSink_QueryInterface(&renderer
->IMFMediaSink_iface
, riid
, obj
);
1396 static ULONG WINAPI
video_renderer_preroll_AddRef(IMFMediaSinkPreroll
*iface
)
1398 struct video_renderer
*renderer
= impl_from_IMFMediaSinkPreroll(iface
);
1399 return IMFMediaSink_AddRef(&renderer
->IMFMediaSink_iface
);
1402 static ULONG WINAPI
video_renderer_preroll_Release(IMFMediaSinkPreroll
*iface
)
1404 struct video_renderer
*renderer
= impl_from_IMFMediaSinkPreroll(iface
);
1405 return IMFMediaSink_Release(&renderer
->IMFMediaSink_iface
);
1408 static HRESULT WINAPI
video_renderer_preroll_NotifyPreroll(IMFMediaSinkPreroll
*iface
, MFTIME start_time
)
1410 struct video_renderer
*renderer
= impl_from_IMFMediaSinkPreroll(iface
);
1414 TRACE("%p, %s.\n", iface
, debugstr_time(start_time
));
1416 EnterCriticalSection(&renderer
->cs
);
1417 if (renderer
->flags
& EVR_SHUT_DOWN
)
1421 for (i
= 0; i
< renderer
->stream_count
; ++i
)
1423 struct video_stream
*stream
= renderer
->streams
[i
];
1425 EnterCriticalSection(&stream
->cs
);
1426 if (!(stream
->flags
& (EVR_STREAM_PREROLLING
| EVR_STREAM_PREROLLED
)))
1428 IMFMediaEventQueue_QueueEventParamVar(stream
->event_queue
, MEStreamSinkRequestSample
,
1429 &GUID_NULL
, S_OK
, NULL
);
1430 stream
->flags
|= EVR_STREAM_PREROLLING
;
1432 LeaveCriticalSection(&stream
->cs
);
1435 LeaveCriticalSection(&renderer
->cs
);
1440 static const IMFMediaSinkPrerollVtbl video_renderer_preroll_vtbl
=
1442 video_renderer_preroll_QueryInterface
,
1443 video_renderer_preroll_AddRef
,
1444 video_renderer_preroll_Release
,
1445 video_renderer_preroll_NotifyPreroll
,
1448 static HRESULT WINAPI
video_renderer_QueryInterface(IMFVideoRenderer
*iface
, REFIID riid
, void **obj
)
1450 struct video_renderer
*renderer
= impl_from_IMFVideoRenderer(iface
);
1451 return IMFMediaSink_QueryInterface(&renderer
->IMFMediaSink_iface
, riid
, obj
);
1454 static ULONG WINAPI
video_renderer_AddRef(IMFVideoRenderer
*iface
)
1456 struct video_renderer
*renderer
= impl_from_IMFVideoRenderer(iface
);
1457 return IMFMediaSink_AddRef(&renderer
->IMFMediaSink_iface
);
1460 static ULONG WINAPI
video_renderer_Release(IMFVideoRenderer
*iface
)
1462 struct video_renderer
*renderer
= impl_from_IMFVideoRenderer(iface
);
1463 return IMFMediaSink_Release(&renderer
->IMFMediaSink_iface
);
1466 static HRESULT
video_renderer_create_mixer(IMFAttributes
*attributes
, IMFTransform
**out
)
1468 unsigned int flags
= 0;
1469 IMFActivate
*activate
;
1473 if (attributes
&& SUCCEEDED(hr
= IMFAttributes_GetUnknown(attributes
, &MF_ACTIVATE_CUSTOM_VIDEO_MIXER_ACTIVATE
,
1474 &IID_IMFActivate
, (void **)&activate
)))
1476 IMFAttributes_GetUINT32(attributes
, &MF_ACTIVATE_CUSTOM_VIDEO_MIXER_FLAGS
, &flags
);
1477 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFTransform
, (void **)out
);
1478 IMFActivate_Release(activate
);
1479 if (SUCCEEDED(hr
) || !(flags
& MF_ACTIVATE_CUSTOM_MIXER_ALLOWFAIL
))
1483 if (!attributes
|| FAILED(IMFAttributes_GetGUID(attributes
, &MF_ACTIVATE_CUSTOM_VIDEO_MIXER_CLSID
, &clsid
)))
1484 memcpy(&clsid
, &CLSID_MFVideoMixer9
, sizeof(clsid
));
1486 return CoCreateInstance(&clsid
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMFTransform
, (void **)out
);
1489 static HRESULT
video_renderer_create_presenter(struct video_renderer
*renderer
, IMFAttributes
*attributes
,
1490 IMFVideoPresenter
**out
)
1492 unsigned int flags
= 0;
1493 IMFActivate
*activate
;
1498 if (attributes
&& SUCCEEDED(IMFAttributes_GetUINT64(attributes
, &MF_ACTIVATE_VIDEO_WINDOW
, &value
)))
1499 renderer
->window
= UlongToHandle(value
);
1501 if (attributes
&& SUCCEEDED(IMFAttributes_GetUnknown(attributes
, &MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_ACTIVATE
,
1502 &IID_IMFActivate
, (void **)&activate
)))
1504 IMFAttributes_GetUINT32(attributes
, &MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_FLAGS
, &flags
);
1505 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFVideoPresenter
, (void **)out
);
1506 IMFActivate_Release(activate
);
1507 if (SUCCEEDED(hr
) || !(flags
& MF_ACTIVATE_CUSTOM_PRESENTER_ALLOWFAIL
))
1511 if (!attributes
|| FAILED(IMFAttributes_GetGUID(attributes
, &MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_CLSID
, &clsid
)))
1512 memcpy(&clsid
, &CLSID_MFVideoPresenter9
, sizeof(clsid
));
1514 return CoCreateInstance(&clsid
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMFVideoPresenter
, (void **)out
);
1517 static HRESULT
video_renderer_configure_mixer(struct video_renderer
*renderer
)
1519 IMFTopologyServiceLookupClient
*lookup_client
;
1522 if (SUCCEEDED(hr
= IMFTransform_QueryInterface(renderer
->mixer
, &IID_IMFTopologyServiceLookupClient
,
1523 (void **)&lookup_client
)))
1525 renderer
->flags
|= EVR_INIT_SERVICES
;
1526 if (SUCCEEDED(hr
= IMFTopologyServiceLookupClient_InitServicePointers(lookup_client
,
1527 &renderer
->IMFTopologyServiceLookup_iface
)))
1529 renderer
->flags
|= EVR_MIXER_INITED_SERVICES
;
1531 renderer
->flags
&= ~EVR_INIT_SERVICES
;
1532 IMFTopologyServiceLookupClient_Release(lookup_client
);
1537 unsigned int input_count
, output_count
;
1538 unsigned int *ids
, *oids
;
1541 /* Create stream sinks for inputs that mixer already has by default. */
1542 if (SUCCEEDED(IMFTransform_GetStreamCount(renderer
->mixer
, &input_count
, &output_count
)))
1544 ids
= heap_calloc(input_count
, sizeof(*ids
));
1545 oids
= heap_calloc(output_count
, sizeof(*oids
));
1549 if (SUCCEEDED(IMFTransform_GetStreamIDs(renderer
->mixer
, input_count
, ids
, output_count
, oids
)))
1551 for (i
= 0; i
< input_count
; ++i
)
1553 video_renderer_add_stream(renderer
, ids
[i
], NULL
);
1564 /* Set device manager that presenter should have created. */
1565 if (video_renderer_is_mixer_d3d_aware(renderer
))
1567 IDirect3DDeviceManager9
*device_manager
;
1569 if (SUCCEEDED(MFGetService((IUnknown
*)renderer
->presenter
, &MR_VIDEO_ACCELERATION_SERVICE
,
1570 &IID_IDirect3DDeviceManager9
, (void **)&device_manager
)))
1572 IMFTransform_ProcessMessage(renderer
->mixer
, MFT_MESSAGE_SET_D3D_MANAGER
, (ULONG_PTR
)device_manager
);
1573 IDirect3DDeviceManager9_Release(device_manager
);
1580 static HRESULT
video_renderer_configure_presenter(struct video_renderer
*renderer
)
1582 IMFTopologyServiceLookupClient
*lookup_client
;
1583 IMFVideoDisplayControl
*control
;
1586 if (SUCCEEDED(IMFVideoPresenter_QueryInterface(renderer
->presenter
, &IID_IMFVideoDisplayControl
, (void **)&control
)))
1588 IMFVideoDisplayControl_SetVideoWindow(control
, renderer
->window
);
1589 IMFVideoDisplayControl_Release(control
);
1592 if (SUCCEEDED(hr
= IMFVideoPresenter_QueryInterface(renderer
->presenter
, &IID_IMFTopologyServiceLookupClient
,
1593 (void **)&lookup_client
)))
1595 renderer
->flags
|= EVR_INIT_SERVICES
;
1596 if (SUCCEEDED(hr
= IMFTopologyServiceLookupClient_InitServicePointers(lookup_client
,
1597 &renderer
->IMFTopologyServiceLookup_iface
)))
1599 renderer
->flags
|= EVR_PRESENTER_INITED_SERVICES
;
1601 renderer
->flags
&= ~EVR_INIT_SERVICES
;
1602 IMFTopologyServiceLookupClient_Release(lookup_client
);
1605 if (FAILED(MFGetService((IUnknown
*)renderer
->presenter
, &MR_VIDEO_ACCELERATION_SERVICE
,
1606 &IID_IUnknown
, (void **)&renderer
->device_manager
)))
1608 WARN("Failed to get device manager from the presenter.\n");
1614 static HRESULT
video_renderer_initialize(struct video_renderer
*renderer
, IMFTransform
*mixer
,
1615 IMFVideoPresenter
*presenter
)
1619 if (renderer
->mixer
)
1621 IMFTransform_Release(renderer
->mixer
);
1622 renderer
->mixer
= NULL
;
1625 if (renderer
->presenter
)
1627 IMFVideoPresenter_Release(renderer
->presenter
);
1628 renderer
->presenter
= NULL
;
1631 if (renderer
->device_manager
)
1633 IUnknown_Release(renderer
->device_manager
);
1634 renderer
->device_manager
= NULL
;
1637 renderer
->mixer
= mixer
;
1638 IMFTransform_AddRef(renderer
->mixer
);
1640 renderer
->presenter
= presenter
;
1641 IMFVideoPresenter_AddRef(renderer
->presenter
);
1643 if (SUCCEEDED(hr
= video_renderer_configure_mixer(renderer
)))
1644 hr
= video_renderer_configure_presenter(renderer
);
1649 static HRESULT WINAPI
video_renderer_InitializeRenderer(IMFVideoRenderer
*iface
, IMFTransform
*mixer
,
1650 IMFVideoPresenter
*presenter
)
1652 struct video_renderer
*renderer
= impl_from_IMFVideoRenderer(iface
);
1655 TRACE("%p, %p, %p.\n", iface
, mixer
, presenter
);
1658 IMFTransform_AddRef(mixer
);
1659 else if (FAILED(hr
= video_renderer_create_mixer(NULL
, &mixer
)))
1661 WARN("Failed to create default mixer object, hr %#x.\n", hr
);
1666 IMFVideoPresenter_AddRef(presenter
);
1667 else if (FAILED(hr
= video_renderer_create_presenter(renderer
, NULL
, &presenter
)))
1669 WARN("Failed to create default presenter, hr %#x.\n", hr
);
1670 IMFTransform_Release(mixer
);
1674 EnterCriticalSection(&renderer
->cs
);
1676 if (renderer
->flags
& EVR_SHUT_DOWN
)
1680 /* FIXME: check clock state */
1681 /* FIXME: check that streams are not initialized */
1683 hr
= video_renderer_initialize(renderer
, mixer
, presenter
);
1686 LeaveCriticalSection(&renderer
->cs
);
1688 IMFTransform_Release(mixer
);
1689 IMFVideoPresenter_Release(presenter
);
1694 static const IMFVideoRendererVtbl video_renderer_vtbl
=
1696 video_renderer_QueryInterface
,
1697 video_renderer_AddRef
,
1698 video_renderer_Release
,
1699 video_renderer_InitializeRenderer
,
1702 static HRESULT WINAPI
video_renderer_events_QueryInterface(IMFMediaEventGenerator
*iface
, REFIID riid
, void **obj
)
1704 struct video_renderer
*renderer
= impl_from_IMFMediaEventGenerator(iface
);
1705 return IMFMediaSink_QueryInterface(&renderer
->IMFMediaSink_iface
, riid
, obj
);
1708 static ULONG WINAPI
video_renderer_events_AddRef(IMFMediaEventGenerator
*iface
)
1710 struct video_renderer
*renderer
= impl_from_IMFMediaEventGenerator(iface
);
1711 return IMFMediaSink_AddRef(&renderer
->IMFMediaSink_iface
);
1714 static ULONG WINAPI
video_renderer_events_Release(IMFMediaEventGenerator
*iface
)
1716 struct video_renderer
*renderer
= impl_from_IMFMediaEventGenerator(iface
);
1717 return IMFMediaSink_Release(&renderer
->IMFMediaSink_iface
);
1720 static HRESULT WINAPI
video_renderer_events_GetEvent(IMFMediaEventGenerator
*iface
, DWORD flags
, IMFMediaEvent
**event
)
1722 struct video_renderer
*renderer
= impl_from_IMFMediaEventGenerator(iface
);
1724 TRACE("%p, %#x, %p.\n", iface
, flags
, event
);
1726 return IMFMediaEventQueue_GetEvent(renderer
->event_queue
, flags
, event
);
1729 static HRESULT WINAPI
video_renderer_events_BeginGetEvent(IMFMediaEventGenerator
*iface
, IMFAsyncCallback
*callback
,
1732 struct video_renderer
*renderer
= impl_from_IMFMediaEventGenerator(iface
);
1734 TRACE("%p, %p, %p.\n", iface
, callback
, state
);
1736 return IMFMediaEventQueue_BeginGetEvent(renderer
->event_queue
, callback
, state
);
1739 static HRESULT WINAPI
video_renderer_events_EndGetEvent(IMFMediaEventGenerator
*iface
, IMFAsyncResult
*result
,
1740 IMFMediaEvent
**event
)
1742 struct video_renderer
*renderer
= impl_from_IMFMediaEventGenerator(iface
);
1744 TRACE("%p, %p, %p.\n", iface
, result
, event
);
1746 return IMFMediaEventQueue_EndGetEvent(renderer
->event_queue
, result
, event
);
1749 static HRESULT WINAPI
video_renderer_events_QueueEvent(IMFMediaEventGenerator
*iface
, MediaEventType event_type
,
1750 REFGUID ext_type
, HRESULT hr
, const PROPVARIANT
*value
)
1752 struct video_renderer
*renderer
= impl_from_IMFMediaEventGenerator(iface
);
1754 TRACE("%p, %u, %s, %#x, %p.\n", iface
, event_type
, debugstr_guid(ext_type
), hr
, value
);
1756 return IMFMediaEventQueue_QueueEventParamVar(renderer
->event_queue
, event_type
, ext_type
, hr
, value
);
1759 static const IMFMediaEventGeneratorVtbl video_renderer_events_vtbl
=
1761 video_renderer_events_QueryInterface
,
1762 video_renderer_events_AddRef
,
1763 video_renderer_events_Release
,
1764 video_renderer_events_GetEvent
,
1765 video_renderer_events_BeginGetEvent
,
1766 video_renderer_events_EndGetEvent
,
1767 video_renderer_events_QueueEvent
,
1770 static HRESULT WINAPI
video_renderer_clock_sink_QueryInterface(IMFClockStateSink
*iface
, REFIID riid
, void **obj
)
1772 struct video_renderer
*renderer
= impl_from_IMFClockStateSink(iface
);
1773 return IMFMediaSink_QueryInterface(&renderer
->IMFMediaSink_iface
, riid
, obj
);
1776 static ULONG WINAPI
video_renderer_clock_sink_AddRef(IMFClockStateSink
*iface
)
1778 struct video_renderer
*renderer
= impl_from_IMFClockStateSink(iface
);
1779 return IMFMediaSink_AddRef(&renderer
->IMFMediaSink_iface
);
1782 static ULONG WINAPI
video_renderer_clock_sink_Release(IMFClockStateSink
*iface
)
1784 struct video_renderer
*renderer
= impl_from_IMFClockStateSink(iface
);
1785 return IMFMediaSink_Release(&renderer
->IMFMediaSink_iface
);
1788 static HRESULT WINAPI
video_renderer_clock_sink_OnClockStart(IMFClockStateSink
*iface
, MFTIME systime
, LONGLONG offset
)
1790 struct video_renderer
*renderer
= impl_from_IMFClockStateSink(iface
);
1793 TRACE("%p, %s, %s.\n", iface
, debugstr_time(systime
), debugstr_time(offset
));
1795 EnterCriticalSection(&renderer
->cs
);
1797 if (renderer
->state
== EVR_STATE_STOPPED
)
1799 IMFTransform_ProcessMessage(renderer
->mixer
, MFT_MESSAGE_NOTIFY_BEGIN_STREAMING
, 0);
1800 IMFVideoPresenter_ProcessMessage(renderer
->presenter
, MFVP_MESSAGE_BEGINSTREAMING
, 0);
1802 for (i
= 0; i
< renderer
->stream_count
; ++i
)
1804 struct video_stream
*stream
= renderer
->streams
[i
];
1806 IMFMediaEventQueue_QueueEventParamVar(stream
->event_queue
, MEStreamSinkStarted
, &GUID_NULL
, S_OK
, NULL
);
1808 EnterCriticalSection(&stream
->cs
);
1809 if (!(stream
->flags
& EVR_STREAM_PREROLLED
))
1810 IMFMediaEventQueue_QueueEventParamVar(stream
->event_queue
, MEStreamSinkRequestSample
,
1811 &GUID_NULL
, S_OK
, NULL
);
1812 stream
->flags
|= EVR_STREAM_PREROLLED
;
1813 LeaveCriticalSection(&stream
->cs
);
1817 renderer
->state
= EVR_STATE_RUNNING
;
1819 IMFVideoPresenter_OnClockStart(renderer
->presenter
, systime
, offset
);
1821 LeaveCriticalSection(&renderer
->cs
);
1826 static HRESULT WINAPI
video_renderer_clock_sink_OnClockStop(IMFClockStateSink
*iface
, MFTIME systime
)
1828 struct video_renderer
*renderer
= impl_from_IMFClockStateSink(iface
);
1831 TRACE("%p, %s.\n", iface
, debugstr_time(systime
));
1833 EnterCriticalSection(&renderer
->cs
);
1835 IMFVideoPresenter_OnClockStop(renderer
->presenter
, systime
);
1837 IMFTransform_ProcessMessage(renderer
->mixer
, MFT_MESSAGE_COMMAND_FLUSH
, 0);
1838 IMFVideoPresenter_ProcessMessage(renderer
->presenter
, MFVP_MESSAGE_FLUSH
, 0);
1840 if (renderer
->state
== EVR_STATE_RUNNING
||
1841 renderer
->state
== EVR_STATE_PAUSED
)
1843 IMFTransform_ProcessMessage(renderer
->mixer
, MFT_MESSAGE_NOTIFY_END_STREAMING
, 0);
1844 IMFVideoPresenter_ProcessMessage(renderer
->presenter
, MFVP_MESSAGE_ENDSTREAMING
, 0);
1846 for (i
= 0; i
< renderer
->stream_count
; ++i
)
1848 struct video_stream
*stream
= renderer
->streams
[i
];
1849 IMFMediaEventQueue_QueueEventParamVar(stream
->event_queue
, MEStreamSinkStopped
, &GUID_NULL
, S_OK
, NULL
);
1851 EnterCriticalSection(&stream
->cs
);
1852 stream
->flags
&= ~EVR_STREAM_PREROLLED
;
1853 LeaveCriticalSection(&stream
->cs
);
1855 renderer
->state
= EVR_STATE_STOPPED
;
1858 LeaveCriticalSection(&renderer
->cs
);
1863 static HRESULT WINAPI
video_renderer_clock_sink_OnClockPause(IMFClockStateSink
*iface
, MFTIME systime
)
1865 struct video_renderer
*renderer
= impl_from_IMFClockStateSink(iface
);
1868 TRACE("%p, %s.\n", iface
, debugstr_time(systime
));
1870 EnterCriticalSection(&renderer
->cs
);
1872 IMFVideoPresenter_OnClockPause(renderer
->presenter
, systime
);
1874 if (renderer
->state
== EVR_STATE_RUNNING
)
1876 for (i
= 0; i
< renderer
->stream_count
; ++i
)
1878 struct video_stream
*stream
= renderer
->streams
[i
];
1879 IMFMediaEventQueue_QueueEventParamVar(stream
->event_queue
, MEStreamSinkPaused
, &GUID_NULL
, S_OK
, NULL
);
1883 renderer
->state
= EVR_STATE_PAUSED
;
1885 LeaveCriticalSection(&renderer
->cs
);
1890 static HRESULT WINAPI
video_renderer_clock_sink_OnClockRestart(IMFClockStateSink
*iface
, MFTIME systime
)
1892 struct video_renderer
*renderer
= impl_from_IMFClockStateSink(iface
);
1895 TRACE("%p, %s.\n", iface
, debugstr_time(systime
));
1897 EnterCriticalSection(&renderer
->cs
);
1899 IMFVideoPresenter_OnClockRestart(renderer
->presenter
, systime
);
1901 for (i
= 0; i
< renderer
->stream_count
; ++i
)
1903 struct video_stream
*stream
= renderer
->streams
[i
];
1904 IMFMediaEventQueue_QueueEventParamVar(stream
->event_queue
, MEStreamSinkStarted
, &GUID_NULL
, S_OK
, NULL
);
1906 renderer
->state
= EVR_STATE_RUNNING
;
1908 LeaveCriticalSection(&renderer
->cs
);
1913 static HRESULT WINAPI
video_renderer_clock_sink_OnClockSetRate(IMFClockStateSink
*iface
, MFTIME systime
, float rate
)
1915 struct video_renderer
*renderer
= impl_from_IMFClockStateSink(iface
);
1916 IMFClockStateSink
*sink
;
1918 TRACE("%p, %s, %f.\n", iface
, debugstr_time(systime
), rate
);
1920 EnterCriticalSection(&renderer
->cs
);
1922 IMFVideoPresenter_OnClockSetRate(renderer
->presenter
, systime
, rate
);
1923 if (SUCCEEDED(IMFTransform_QueryInterface(renderer
->mixer
, &IID_IMFClockStateSink
, (void **)&sink
)))
1925 IMFClockStateSink_OnClockSetRate(sink
, systime
, rate
);
1926 IMFClockStateSink_Release(sink
);
1929 LeaveCriticalSection(&renderer
->cs
);
1934 static const IMFClockStateSinkVtbl video_renderer_clock_sink_vtbl
=
1936 video_renderer_clock_sink_QueryInterface
,
1937 video_renderer_clock_sink_AddRef
,
1938 video_renderer_clock_sink_Release
,
1939 video_renderer_clock_sink_OnClockStart
,
1940 video_renderer_clock_sink_OnClockStop
,
1941 video_renderer_clock_sink_OnClockPause
,
1942 video_renderer_clock_sink_OnClockRestart
,
1943 video_renderer_clock_sink_OnClockSetRate
,
1946 static HRESULT WINAPI
video_renderer_get_service_QueryInterface(IMFGetService
*iface
, REFIID riid
, void **obj
)
1948 struct video_renderer
*renderer
= impl_from_IMFGetService(iface
);
1949 return IMFMediaSink_QueryInterface(&renderer
->IMFMediaSink_iface
, riid
, obj
);
1952 static ULONG WINAPI
video_renderer_get_service_AddRef(IMFGetService
*iface
)
1954 struct video_renderer
*renderer
= impl_from_IMFGetService(iface
);
1955 return IMFMediaSink_AddRef(&renderer
->IMFMediaSink_iface
);
1958 static ULONG WINAPI
video_renderer_get_service_Release(IMFGetService
*iface
)
1960 struct video_renderer
*renderer
= impl_from_IMFGetService(iface
);
1961 return IMFMediaSink_Release(&renderer
->IMFMediaSink_iface
);
1964 static HRESULT WINAPI
video_renderer_get_service_GetService(IMFGetService
*iface
, REFGUID service
, REFIID riid
, void **obj
)
1966 struct video_renderer
*renderer
= impl_from_IMFGetService(iface
);
1967 HRESULT hr
= E_NOINTERFACE
;
1968 IMFGetService
*gs
= NULL
;
1970 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_guid(service
), debugstr_guid(riid
), obj
);
1972 if (IsEqualGUID(service
, &MR_VIDEO_MIXER_SERVICE
))
1974 hr
= IMFTransform_QueryInterface(renderer
->mixer
, &IID_IMFGetService
, (void **)&gs
);
1976 else if (IsEqualGUID(service
, &MR_VIDEO_RENDER_SERVICE
))
1978 hr
= IMFVideoPresenter_QueryInterface(renderer
->presenter
, &IID_IMFGetService
, (void **)&gs
);
1982 FIXME("Unsupported service %s.\n", debugstr_guid(service
));
1987 hr
= IMFGetService_GetService(gs
, service
, riid
, obj
);
1988 IMFGetService_Release(gs
);
1994 static const IMFGetServiceVtbl video_renderer_get_service_vtbl
=
1996 video_renderer_get_service_QueryInterface
,
1997 video_renderer_get_service_AddRef
,
1998 video_renderer_get_service_Release
,
1999 video_renderer_get_service_GetService
,
2002 static HRESULT WINAPI
video_renderer_service_lookup_QueryInterface(IMFTopologyServiceLookup
*iface
, REFIID riid
, void **obj
)
2004 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
2006 if (IsEqualIID(riid
, &IID_IMFTopologyServiceLookup
) ||
2007 IsEqualIID(riid
, &IID_IUnknown
))
2010 IMFTopologyServiceLookup_AddRef(iface
);
2014 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
2016 return E_NOINTERFACE
;
2019 static ULONG WINAPI
video_renderer_service_lookup_AddRef(IMFTopologyServiceLookup
*iface
)
2021 struct video_renderer
*renderer
= impl_from_IMFTopologyServiceLookup(iface
);
2022 return IMFMediaSink_AddRef(&renderer
->IMFMediaSink_iface
);
2025 static ULONG WINAPI
video_renderer_service_lookup_Release(IMFTopologyServiceLookup
*iface
)
2027 struct video_renderer
*renderer
= impl_from_IMFTopologyServiceLookup(iface
);
2028 return IMFMediaSink_Release(&renderer
->IMFMediaSink_iface
);
2031 static HRESULT WINAPI
video_renderer_service_lookup_LookupService(IMFTopologyServiceLookup
*iface
,
2032 MF_SERVICE_LOOKUP_TYPE lookup_type
, DWORD index
, REFGUID service
, REFIID riid
,
2033 void **objects
, DWORD
*num_objects
)
2035 struct video_renderer
*renderer
= impl_from_IMFTopologyServiceLookup(iface
);
2038 TRACE("%p, %u, %u, %s, %s, %p, %p.\n", iface
, lookup_type
, index
, debugstr_guid(service
), debugstr_guid(riid
),
2039 objects
, num_objects
);
2041 EnterCriticalSection(&renderer
->cs
);
2043 if (!(renderer
->flags
& EVR_INIT_SERVICES
))
2044 hr
= MF_E_NOTACCEPTING
;
2045 else if (IsEqualGUID(service
, &MR_VIDEO_RENDER_SERVICE
))
2047 if (IsEqualIID(riid
, &IID_IMediaEventSink
))
2049 *objects
= &renderer
->IMediaEventSink_iface
;
2050 IUnknown_AddRef((IUnknown
*)*objects
);
2054 FIXME("Unsupported interface %s for render service.\n", debugstr_guid(riid
));
2058 else if (IsEqualGUID(service
, &MR_VIDEO_MIXER_SERVICE
))
2060 if (IsEqualIID(riid
, &IID_IMFTransform
))
2062 *objects
= renderer
->mixer
;
2063 IUnknown_AddRef((IUnknown
*)*objects
);
2067 FIXME("Unsupported interface %s for mixer service.\n", debugstr_guid(riid
));
2073 WARN("Unsupported service %s.\n", debugstr_guid(service
));
2074 hr
= MF_E_UNSUPPORTED_SERVICE
;
2077 LeaveCriticalSection(&renderer
->cs
);
2082 static const IMFTopologyServiceLookupVtbl video_renderer_service_lookup_vtbl
=
2084 video_renderer_service_lookup_QueryInterface
,
2085 video_renderer_service_lookup_AddRef
,
2086 video_renderer_service_lookup_Release
,
2087 video_renderer_service_lookup_LookupService
,
2090 static HRESULT WINAPI
video_renderer_event_sink_QueryInterface(IMediaEventSink
*iface
, REFIID riid
, void **obj
)
2092 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
2094 if (IsEqualIID(riid
, &IID_IMediaEventSink
) ||
2095 IsEqualIID(riid
, &IID_IUnknown
))
2098 IMediaEventSink_AddRef(iface
);
2102 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
2104 return E_NOINTERFACE
;
2107 static ULONG WINAPI
video_renderer_event_sink_AddRef(IMediaEventSink
*iface
)
2109 struct video_renderer
*renderer
= impl_from_IMediaEventSink(iface
);
2110 return IMFMediaSink_AddRef(&renderer
->IMFMediaSink_iface
);
2113 static ULONG WINAPI
video_renderer_event_sink_Release(IMediaEventSink
*iface
)
2115 struct video_renderer
*renderer
= impl_from_IMediaEventSink(iface
);
2116 return IMFMediaSink_Release(&renderer
->IMFMediaSink_iface
);
2119 static HRESULT WINAPI
video_renderer_event_sink_Notify(IMediaEventSink
*iface
, LONG event
, LONG_PTR param1
, LONG_PTR param2
)
2121 struct video_renderer
*renderer
= impl_from_IMediaEventSink(iface
);
2125 TRACE("%p, %d, %ld, %ld.\n", iface
, event
, param1
, param2
);
2127 EnterCriticalSection(&renderer
->cs
);
2129 if (event
== EC_SAMPLE_NEEDED
)
2132 if (idx
>= renderer
->stream_count
)
2133 hr
= MF_E_INVALIDSTREAMNUMBER
;
2136 hr
= IMFMediaEventQueue_QueueEventParamVar(renderer
->streams
[idx
]->event_queue
,
2137 MEStreamSinkRequestSample
, &GUID_NULL
, S_OK
, NULL
);
2140 else if (event
== EC_DISPLAY_CHANGED
)
2142 for (idx
= 0; idx
< renderer
->stream_count
; ++idx
)
2143 IMFMediaEventQueue_QueueEventParamVar(renderer
->streams
[idx
]->event_queue
,
2144 MEStreamSinkDeviceChanged
, &GUID_NULL
, S_OK
, NULL
);
2146 else if (event
>= EC_USER
)
2152 hr
= IMFMediaEventQueue_QueueEventParamVar(renderer
->event_queue
, MERendererEvent
,
2153 &GUID_NULL
, S_OK
, &code
);
2157 WARN("Unhandled event %d.\n", event
);
2158 hr
= MF_E_UNEXPECTED
;
2161 LeaveCriticalSection(&renderer
->cs
);
2166 static const IMediaEventSinkVtbl media_event_sink_vtbl
=
2168 video_renderer_event_sink_QueryInterface
,
2169 video_renderer_event_sink_AddRef
,
2170 video_renderer_event_sink_Release
,
2171 video_renderer_event_sink_Notify
,
2174 static HRESULT WINAPI
video_renderer_attributes_QueryInterface(IMFAttributes
*iface
, REFIID riid
, void **obj
)
2176 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2177 return IMFMediaSink_QueryInterface(&renderer
->IMFMediaSink_iface
, riid
, obj
);
2180 static ULONG WINAPI
video_renderer_attributes_AddRef(IMFAttributes
*iface
)
2182 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2183 return IMFMediaSink_AddRef(&renderer
->IMFMediaSink_iface
);
2186 static ULONG WINAPI
video_renderer_attributes_Release(IMFAttributes
*iface
)
2188 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2189 return IMFMediaSink_Release(&renderer
->IMFMediaSink_iface
);
2192 static HRESULT WINAPI
video_renderer_attributes_GetItem(IMFAttributes
*iface
, REFGUID key
, PROPVARIANT
*value
)
2194 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2196 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
2198 return IMFAttributes_GetItem(renderer
->attributes
, key
, value
);
2201 static HRESULT WINAPI
video_renderer_attributes_GetItemType(IMFAttributes
*iface
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
2203 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2205 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), type
);
2207 return IMFAttributes_GetItemType(renderer
->attributes
, key
, type
);
2210 static HRESULT WINAPI
video_renderer_attributes_CompareItem(IMFAttributes
*iface
, REFGUID key
, REFPROPVARIANT value
,
2213 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2215 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_guid(key
), value
, result
);
2217 return IMFAttributes_CompareItem(renderer
->attributes
, key
, value
, result
);
2220 static HRESULT WINAPI
video_renderer_attributes_Compare(IMFAttributes
*iface
, IMFAttributes
*theirs
,
2221 MF_ATTRIBUTES_MATCH_TYPE type
, BOOL
*result
)
2223 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2225 TRACE("%p, %p, %d, %p.\n", iface
, theirs
, type
, result
);
2227 return IMFAttributes_Compare(renderer
->attributes
, theirs
, type
, result
);
2230 static HRESULT WINAPI
video_renderer_attributes_GetUINT32(IMFAttributes
*iface
, REFGUID key
, UINT32
*value
)
2232 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2234 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
2236 return IMFAttributes_GetUINT32(renderer
->attributes
, key
, value
);
2239 static HRESULT WINAPI
video_renderer_attributes_GetUINT64(IMFAttributes
*iface
, REFGUID key
, UINT64
*value
)
2241 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2243 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
2245 return IMFAttributes_GetUINT64(renderer
->attributes
, key
, value
);
2248 static HRESULT WINAPI
video_renderer_attributes_GetDouble(IMFAttributes
*iface
, REFGUID key
, double *value
)
2250 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2252 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
2254 return IMFAttributes_GetDouble(renderer
->attributes
, key
, value
);
2257 static HRESULT WINAPI
video_renderer_attributes_GetGUID(IMFAttributes
*iface
, REFGUID key
, GUID
*value
)
2259 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2261 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
2263 return IMFAttributes_GetGUID(renderer
->attributes
, key
, value
);
2266 static HRESULT WINAPI
video_renderer_attributes_GetStringLength(IMFAttributes
*iface
, REFGUID key
,
2269 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2271 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), length
);
2273 return IMFAttributes_GetStringLength(renderer
->attributes
, key
, length
);
2276 static HRESULT WINAPI
video_renderer_attributes_GetString(IMFAttributes
*iface
, REFGUID key
, WCHAR
*value
,
2277 UINT32 size
, UINT32
*length
)
2279 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2281 TRACE("%p, %s, %p, %u, %p.\n", iface
, debugstr_guid(key
), value
, size
, length
);
2283 return IMFAttributes_GetString(renderer
->attributes
, key
, value
, size
, length
);
2286 static HRESULT WINAPI
video_renderer_attributes_GetAllocatedString(IMFAttributes
*iface
, REFGUID key
,
2287 WCHAR
**value
, UINT32
*length
)
2289 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2291 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_guid(key
), value
, length
);
2293 return IMFAttributes_GetAllocatedString(renderer
->attributes
, key
, value
, length
);
2296 static HRESULT WINAPI
video_renderer_attributes_GetBlobSize(IMFAttributes
*iface
, REFGUID key
, UINT32
*size
)
2298 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2300 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), size
);
2302 return IMFAttributes_GetBlobSize(renderer
->attributes
, key
, size
);
2305 static HRESULT WINAPI
video_renderer_attributes_GetBlob(IMFAttributes
*iface
, REFGUID key
, UINT8
*buf
,
2306 UINT32 bufsize
, UINT32
*blobsize
)
2308 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2310 TRACE("%p, %s, %p, %u, %p.\n", iface
, debugstr_guid(key
), buf
, bufsize
, blobsize
);
2312 return IMFAttributes_GetBlob(renderer
->attributes
, key
, buf
, bufsize
, blobsize
);
2315 static HRESULT WINAPI
video_renderer_attributes_GetAllocatedBlob(IMFAttributes
*iface
, REFGUID key
,
2316 UINT8
**buf
, UINT32
*size
)
2318 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2320 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_guid(key
), buf
, size
);
2322 return IMFAttributes_GetAllocatedBlob(renderer
->attributes
, key
, buf
, size
);
2325 static HRESULT WINAPI
video_renderer_attributes_GetUnknown(IMFAttributes
*iface
, REFGUID key
, REFIID riid
, void **out
)
2327 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2329 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_guid(key
), debugstr_guid(riid
), out
);
2331 return IMFAttributes_GetUnknown(renderer
->attributes
, key
, riid
, out
);
2334 static HRESULT WINAPI
video_renderer_attributes_SetItem(IMFAttributes
*iface
, REFGUID key
, REFPROPVARIANT value
)
2336 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2338 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
2340 return IMFAttributes_SetItem(renderer
->attributes
, key
, value
);
2343 static HRESULT WINAPI
video_renderer_attributes_DeleteItem(IMFAttributes
*iface
, REFGUID key
)
2345 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2347 TRACE("%p, %s.\n", iface
, debugstr_guid(key
));
2349 return IMFAttributes_DeleteItem(renderer
->attributes
, key
);
2352 static HRESULT WINAPI
video_renderer_attributes_DeleteAllItems(IMFAttributes
*iface
)
2354 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2356 TRACE("%p.\n", iface
);
2358 return IMFAttributes_DeleteAllItems(renderer
->attributes
);
2361 static HRESULT WINAPI
video_renderer_attributes_SetUINT32(IMFAttributes
*iface
, REFGUID key
, UINT32 value
)
2363 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2365 TRACE("%p, %s, %u.\n", iface
, debugstr_guid(key
), value
);
2367 return IMFAttributes_SetUINT32(renderer
->attributes
, key
, value
);
2370 static HRESULT WINAPI
video_renderer_attributes_SetUINT64(IMFAttributes
*iface
, REFGUID key
, UINT64 value
)
2372 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2374 TRACE("%p, %s, %s.\n", iface
, debugstr_guid(key
), wine_dbgstr_longlong(value
));
2376 return IMFAttributes_SetUINT64(renderer
->attributes
, key
, value
);
2379 static HRESULT WINAPI
video_renderer_attributes_SetDouble(IMFAttributes
*iface
, REFGUID key
, double value
)
2381 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2383 TRACE("%p, %s, %f.\n", iface
, debugstr_guid(key
), value
);
2385 return IMFAttributes_SetDouble(renderer
->attributes
, key
, value
);
2388 static HRESULT WINAPI
video_renderer_attributes_SetGUID(IMFAttributes
*iface
, REFGUID key
, REFGUID value
)
2390 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2392 TRACE("%p, %s, %s.\n", iface
, debugstr_guid(key
), debugstr_guid(value
));
2394 return IMFAttributes_SetGUID(renderer
->attributes
, key
, value
);
2397 static HRESULT WINAPI
video_renderer_attributes_SetString(IMFAttributes
*iface
, REFGUID key
,
2400 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2402 TRACE("%p, %s, %s.\n", iface
, debugstr_guid(key
), debugstr_w(value
));
2404 return IMFAttributes_SetString(renderer
->attributes
, key
, value
);
2407 static HRESULT WINAPI
video_renderer_attributes_SetBlob(IMFAttributes
*iface
, REFGUID key
,
2408 const UINT8
*buf
, UINT32 size
)
2410 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2412 TRACE("%p, %s, %p, %u.\n", iface
, debugstr_guid(key
), buf
, size
);
2414 return IMFAttributes_SetBlob(renderer
->attributes
, key
, buf
, size
);
2417 static HRESULT WINAPI
video_renderer_attributes_SetUnknown(IMFAttributes
*iface
, REFGUID key
,
2420 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2422 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), unknown
);
2424 return IMFAttributes_SetUnknown(renderer
->attributes
, key
, unknown
);
2427 static HRESULT WINAPI
video_renderer_attributes_LockStore(IMFAttributes
*iface
)
2429 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2431 TRACE("%p.\n", iface
);
2433 return IMFAttributes_LockStore(renderer
->attributes
);
2436 static HRESULT WINAPI
video_renderer_attributes_UnlockStore(IMFAttributes
*iface
)
2438 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2440 TRACE("%p.\n", iface
);
2442 return IMFAttributes_UnlockStore(renderer
->attributes
);
2445 static HRESULT WINAPI
video_renderer_attributes_GetCount(IMFAttributes
*iface
, UINT32
*count
)
2447 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2449 TRACE("%p, %p.\n", iface
, count
);
2451 return IMFAttributes_GetCount(renderer
->attributes
, count
);
2454 static HRESULT WINAPI
video_renderer_attributes_GetItemByIndex(IMFAttributes
*iface
, UINT32 index
,
2455 GUID
*key
, PROPVARIANT
*value
)
2457 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2459 TRACE("%p, %u, %p, %p.\n", iface
, index
, key
, value
);
2461 return IMFAttributes_GetItemByIndex(renderer
->attributes
, index
, key
, value
);
2464 static HRESULT WINAPI
video_renderer_attributes_CopyAllItems(IMFAttributes
*iface
, IMFAttributes
*dest
)
2466 struct video_renderer
*renderer
= impl_from_IMFAttributes(iface
);
2468 TRACE("%p, %p.\n", iface
, dest
);
2470 return IMFAttributes_CopyAllItems(renderer
->attributes
, dest
);
2473 static const IMFAttributesVtbl video_renderer_attributes_vtbl
=
2475 video_renderer_attributes_QueryInterface
,
2476 video_renderer_attributes_AddRef
,
2477 video_renderer_attributes_Release
,
2478 video_renderer_attributes_GetItem
,
2479 video_renderer_attributes_GetItemType
,
2480 video_renderer_attributes_CompareItem
,
2481 video_renderer_attributes_Compare
,
2482 video_renderer_attributes_GetUINT32
,
2483 video_renderer_attributes_GetUINT64
,
2484 video_renderer_attributes_GetDouble
,
2485 video_renderer_attributes_GetGUID
,
2486 video_renderer_attributes_GetStringLength
,
2487 video_renderer_attributes_GetString
,
2488 video_renderer_attributes_GetAllocatedString
,
2489 video_renderer_attributes_GetBlobSize
,
2490 video_renderer_attributes_GetBlob
,
2491 video_renderer_attributes_GetAllocatedBlob
,
2492 video_renderer_attributes_GetUnknown
,
2493 video_renderer_attributes_SetItem
,
2494 video_renderer_attributes_DeleteItem
,
2495 video_renderer_attributes_DeleteAllItems
,
2496 video_renderer_attributes_SetUINT32
,
2497 video_renderer_attributes_SetUINT64
,
2498 video_renderer_attributes_SetDouble
,
2499 video_renderer_attributes_SetGUID
,
2500 video_renderer_attributes_SetString
,
2501 video_renderer_attributes_SetBlob
,
2502 video_renderer_attributes_SetUnknown
,
2503 video_renderer_attributes_LockStore
,
2504 video_renderer_attributes_UnlockStore
,
2505 video_renderer_attributes_GetCount
,
2506 video_renderer_attributes_GetItemByIndex
,
2507 video_renderer_attributes_CopyAllItems
,
2510 static HRESULT WINAPI
video_renderer_quality_advise_QueryInterface(IMFQualityAdvise
*iface
, REFIID riid
, void **out
)
2512 struct video_renderer
*renderer
= impl_from_IMFQualityAdvise(iface
);
2513 return IMFMediaSink_QueryInterface(&renderer
->IMFMediaSink_iface
, riid
, out
);
2516 static ULONG WINAPI
video_renderer_quality_advise_AddRef(IMFQualityAdvise
*iface
)
2518 struct video_renderer
*renderer
= impl_from_IMFQualityAdvise(iface
);
2519 return IMFMediaSink_AddRef(&renderer
->IMFMediaSink_iface
);
2522 static ULONG WINAPI
video_renderer_quality_Release(IMFQualityAdvise
*iface
)
2524 struct video_renderer
*renderer
= impl_from_IMFQualityAdvise(iface
);
2525 return IMFMediaSink_Release(&renderer
->IMFMediaSink_iface
);
2528 static HRESULT WINAPI
video_renderer_quality_advise_SetDropMode(IMFQualityAdvise
*iface
,
2529 MF_QUALITY_DROP_MODE mode
)
2531 FIXME("%p, %u.\n", iface
, mode
);
2536 static HRESULT WINAPI
video_renderer_quality_advise_SetQualityLevel(IMFQualityAdvise
*iface
,
2537 MF_QUALITY_LEVEL level
)
2539 FIXME("%p, %u.\n", iface
, level
);
2544 static HRESULT WINAPI
video_renderer_quality_advise_GetDropMode(IMFQualityAdvise
*iface
,
2545 MF_QUALITY_DROP_MODE
*mode
)
2547 FIXME("%p, %p.\n", iface
, mode
);
2552 static HRESULT WINAPI
video_renderer_quality_advise_GetQualityLevel(IMFQualityAdvise
*iface
,
2553 MF_QUALITY_LEVEL
*level
)
2555 FIXME("%p, %p.\n", iface
, level
);
2560 static HRESULT WINAPI
video_renderer_quality_advise_DropTime(IMFQualityAdvise
*iface
, LONGLONG interval
)
2562 FIXME("%p, %s.\n", iface
, wine_dbgstr_longlong(interval
));
2567 static const IMFQualityAdviseVtbl video_renderer_quality_advise_vtbl
=
2569 video_renderer_quality_advise_QueryInterface
,
2570 video_renderer_quality_advise_AddRef
,
2571 video_renderer_quality_Release
,
2572 video_renderer_quality_advise_SetDropMode
,
2573 video_renderer_quality_advise_SetQualityLevel
,
2574 video_renderer_quality_advise_GetDropMode
,
2575 video_renderer_quality_advise_GetQualityLevel
,
2576 video_renderer_quality_advise_DropTime
,
2579 static HRESULT
evr_create_object(IMFAttributes
*attributes
, void *user_context
, IUnknown
**obj
)
2581 struct video_renderer
*object
;
2582 IMFVideoPresenter
*presenter
= NULL
;
2583 IMFTransform
*mixer
= NULL
;
2586 TRACE("%p, %p, %p.\n", attributes
, user_context
, obj
);
2588 if (!(object
= heap_alloc_zero(sizeof(*object
))))
2589 return E_OUTOFMEMORY
;
2591 object
->IMFMediaSink_iface
.lpVtbl
= &video_renderer_sink_vtbl
;
2592 object
->IMFMediaSinkPreroll_iface
.lpVtbl
= &video_renderer_preroll_vtbl
;
2593 object
->IMFVideoRenderer_iface
.lpVtbl
= &video_renderer_vtbl
;
2594 object
->IMFMediaEventGenerator_iface
.lpVtbl
= &video_renderer_events_vtbl
;
2595 object
->IMFClockStateSink_iface
.lpVtbl
= &video_renderer_clock_sink_vtbl
;
2596 object
->IMFGetService_iface
.lpVtbl
= &video_renderer_get_service_vtbl
;
2597 object
->IMFTopologyServiceLookup_iface
.lpVtbl
= &video_renderer_service_lookup_vtbl
;
2598 object
->IMediaEventSink_iface
.lpVtbl
= &media_event_sink_vtbl
;
2599 object
->IMFAttributes_iface
.lpVtbl
= &video_renderer_attributes_vtbl
;
2600 object
->IMFQualityAdvise_iface
.lpVtbl
= &video_renderer_quality_advise_vtbl
;
2601 object
->refcount
= 1;
2602 InitializeCriticalSection(&object
->cs
);
2604 if (FAILED(hr
= MFCreateEventQueue(&object
->event_queue
)))
2607 if (FAILED(hr
= MFCreateAttributes(&object
->attributes
, 0)))
2610 /* Create mixer and presenter. */
2611 if (FAILED(hr
= video_renderer_create_mixer(attributes
, &mixer
)))
2614 if (FAILED(hr
= video_renderer_create_presenter(object
, attributes
, &presenter
)))
2617 if (FAILED(hr
= video_renderer_initialize(object
, mixer
, presenter
)))
2620 IMFTransform_Release(mixer
);
2621 IMFVideoPresenter_Release(presenter
);
2623 /* Default attributes */
2624 IMFAttributes_SetUINT32(object
->attributes
, &EVRConfig_ForceBob
, 0);
2625 IMFAttributes_SetUINT32(object
->attributes
, &EVRConfig_AllowDropToBob
, 0);
2626 IMFAttributes_SetUINT32(object
->attributes
, &EVRConfig_ForceThrottle
, 0);
2627 IMFAttributes_SetUINT32(object
->attributes
, &EVRConfig_AllowDropToThrottle
, 0);
2628 IMFAttributes_SetUINT32(object
->attributes
, &EVRConfig_ForceHalfInterlace
, 0);
2629 IMFAttributes_SetUINT32(object
->attributes
, &EVRConfig_AllowDropToHalfInterlace
, 0);
2630 IMFAttributes_SetUINT32(object
->attributes
, &EVRConfig_ForceScaling
, 0);
2631 IMFAttributes_SetUINT32(object
->attributes
, &EVRConfig_AllowScaling
, 0);
2632 IMFAttributes_SetUINT32(object
->attributes
, &EVRConfig_ForceBatching
, 0);
2633 IMFAttributes_SetUINT32(object
->attributes
, &EVRConfig_AllowBatching
, 0);
2635 *obj
= (IUnknown
*)&object
->IMFMediaSink_iface
;
2642 IMFTransform_Release(mixer
);
2645 IMFVideoPresenter_Release(presenter
);
2647 video_renderer_release_services(object
);
2648 IMFMediaSink_Release(&object
->IMFMediaSink_iface
);
2653 static void evr_shutdown_object(void *user_context
, IUnknown
*obj
)
2657 if (SUCCEEDED(IUnknown_QueryInterface(obj
, &IID_IMFMediaSink
, (void **)&sink
)))
2659 IMFMediaSink_Shutdown(sink
);
2660 IMFMediaSink_Release(sink
);
2664 static const struct activate_funcs evr_activate_funcs
=
2666 .create_object
= evr_create_object
,
2667 .shutdown_object
= evr_shutdown_object
,
2670 /***********************************************************************
2671 * MFCreateVideoRendererActivate (mf.@)
2673 HRESULT WINAPI
MFCreateVideoRendererActivate(HWND hwnd
, IMFActivate
**activate
)
2677 TRACE("%p, %p.\n", hwnd
, activate
);
2682 hr
= create_activation_object(NULL
, &evr_activate_funcs
, activate
);
2684 IMFActivate_SetUINT64(*activate
, &MF_ACTIVATE_VIDEO_WINDOW
, (ULONG_PTR
)hwnd
);
2689 /***********************************************************************
2690 * MFCreateVideoRenderer (mf.@)
2692 HRESULT WINAPI
MFCreateVideoRenderer(REFIID riid
, void **renderer
)
2697 TRACE("%s, %p.\n", debugstr_guid(riid
), renderer
);
2701 if (SUCCEEDED(hr
= evr_create_object(NULL
, NULL
, &obj
)))
2703 hr
= IUnknown_QueryInterface(obj
, riid
, renderer
);
2704 IUnknown_Release(obj
);