2 * Primary DirectDraw video stream
4 * Copyright 2005, 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 NONAMELESSUNION
23 #include "amstream_private.h"
24 #include "wine/debug.h"
25 #include "wine/strmbase.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(amstream
);
29 static const WCHAR sink_id
[] = L
"I{A35FF56A-9FDA-11D0-8FDF-00C04FD9189D}";
31 static HRESULT
ddrawstreamsample_create(IDirectDrawMediaStream
*parent
, IDirectDrawSurface
*surface
,
32 const RECT
*rect
, IDirectDrawStreamSample
**ddraw_stream_sample
);
36 IAMMediaStream IAMMediaStream_iface
;
37 IDirectDrawMediaStream IDirectDrawMediaStream_iface
;
38 IMemInputPin IMemInputPin_iface
;
42 IMultiMediaStream
* parent
;
44 STREAM_TYPE stream_type
;
47 IMediaStreamFilter
*filter
;
50 IMemAllocator
*allocator
;
54 static inline struct ddraw_stream
*impl_from_IAMMediaStream(IAMMediaStream
*iface
)
56 return CONTAINING_RECORD(iface
, struct ddraw_stream
, IAMMediaStream_iface
);
59 /*** IUnknown methods ***/
60 static HRESULT WINAPI
ddraw_IAMMediaStream_QueryInterface(IAMMediaStream
*iface
,
61 REFIID riid
, void **ret_iface
)
63 struct ddraw_stream
*This
= impl_from_IAMMediaStream(iface
);
65 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ret_iface
);
67 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
68 IsEqualGUID(riid
, &IID_IMediaStream
) ||
69 IsEqualGUID(riid
, &IID_IAMMediaStream
))
71 IAMMediaStream_AddRef(iface
);
75 else if (IsEqualGUID(riid
, &IID_IDirectDrawMediaStream
))
77 IAMMediaStream_AddRef(iface
);
78 *ret_iface
= &This
->IDirectDrawMediaStream_iface
;
81 else if (IsEqualGUID(riid
, &IID_IPin
))
83 IAMMediaStream_AddRef(iface
);
84 *ret_iface
= &This
->IPin_iface
;
87 else if (IsEqualGUID(riid
, &IID_IMemInputPin
))
89 IAMMediaStream_AddRef(iface
);
90 *ret_iface
= &This
->IMemInputPin_iface
;
94 ERR("(%p)->(%s,%p),not found\n", This
, debugstr_guid(riid
), ret_iface
);
98 static ULONG WINAPI
ddraw_IAMMediaStream_AddRef(IAMMediaStream
*iface
)
100 struct ddraw_stream
*This
= impl_from_IAMMediaStream(iface
);
101 ULONG ref
= InterlockedIncrement(&This
->ref
);
103 TRACE("(%p/%p)->(): new ref = %u\n", iface
, This
, ref
);
108 static ULONG WINAPI
ddraw_IAMMediaStream_Release(IAMMediaStream
*iface
)
110 struct ddraw_stream
*This
= impl_from_IAMMediaStream(iface
);
111 ULONG ref
= InterlockedDecrement(&This
->ref
);
113 TRACE("(%p/%p)->(): new ref = %u\n", iface
, This
, ref
);
117 DeleteCriticalSection(&This
->cs
);
119 IDirectDraw7_Release(This
->ddraw
);
120 HeapFree(GetProcessHeap(), 0, This
);
126 /*** IMediaStream methods ***/
127 static HRESULT WINAPI
ddraw_IAMMediaStream_GetMultiMediaStream(IAMMediaStream
*iface
,
128 IMultiMediaStream
** multi_media_stream
)
130 struct ddraw_stream
*This
= impl_from_IAMMediaStream(iface
);
132 TRACE("(%p/%p)->(%p)\n", This
, iface
, multi_media_stream
);
134 if (!multi_media_stream
)
137 IMultiMediaStream_AddRef(This
->parent
);
138 *multi_media_stream
= This
->parent
;
143 static HRESULT WINAPI
ddraw_IAMMediaStream_GetInformation(IAMMediaStream
*iface
,
144 MSPID
*purpose_id
, STREAM_TYPE
*type
)
146 struct ddraw_stream
*This
= impl_from_IAMMediaStream(iface
);
148 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, purpose_id
, type
);
151 *purpose_id
= This
->purpose_id
;
153 *type
= This
->stream_type
;
158 static HRESULT WINAPI
ddraw_IAMMediaStream_SetSameFormat(IAMMediaStream
*iface
,
159 IMediaStream
*pStreamThatHasDesiredFormat
, DWORD flags
)
161 struct ddraw_stream
*This
= impl_from_IAMMediaStream(iface
);
163 FIXME("(%p/%p)->(%p,%x) stub!\n", This
, iface
, pStreamThatHasDesiredFormat
, flags
);
168 static HRESULT WINAPI
ddraw_IAMMediaStream_AllocateSample(IAMMediaStream
*iface
,
169 DWORD flags
, IStreamSample
**sample
)
171 struct ddraw_stream
*This
= impl_from_IAMMediaStream(iface
);
173 FIXME("(%p/%p)->(%x,%p) stub!\n", This
, iface
, flags
, sample
);
178 static HRESULT WINAPI
ddraw_IAMMediaStream_CreateSharedSample(IAMMediaStream
*iface
,
179 IStreamSample
*existing_sample
, DWORD flags
, IStreamSample
**sample
)
181 struct ddraw_stream
*This
= impl_from_IAMMediaStream(iface
);
183 FIXME("(%p/%p)->(%p,%x,%p) stub!\n", This
, iface
, existing_sample
, flags
, sample
);
188 static HRESULT WINAPI
ddraw_IAMMediaStream_SendEndOfStream(IAMMediaStream
*iface
, DWORD flags
)
190 struct ddraw_stream
*This
= impl_from_IAMMediaStream(iface
);
192 FIXME("(%p/%p)->(%x) stub!\n", This
, iface
, flags
);
197 /*** IAMMediaStream methods ***/
198 static HRESULT WINAPI
ddraw_IAMMediaStream_Initialize(IAMMediaStream
*iface
, IUnknown
*source_object
, DWORD flags
,
199 REFMSPID purpose_id
, const STREAM_TYPE stream_type
)
201 struct ddraw_stream
*This
= impl_from_IAMMediaStream(iface
);
203 FIXME("(%p/%p)->(%p,%x,%p,%u) stub!\n", This
, iface
, source_object
, flags
, purpose_id
, stream_type
);
208 static HRESULT WINAPI
ddraw_IAMMediaStream_SetState(IAMMediaStream
*iface
, FILTER_STATE state
)
210 struct ddraw_stream
*This
= impl_from_IAMMediaStream(iface
);
212 FIXME("(%p/%p)->(%u) stub!\n", This
, iface
, state
);
217 static HRESULT WINAPI
ddraw_IAMMediaStream_JoinAMMultiMediaStream(IAMMediaStream
*iface
, IAMMultiMediaStream
*am_multi_media_stream
)
219 struct ddraw_stream
*This
= impl_from_IAMMediaStream(iface
);
221 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, am_multi_media_stream
);
226 static HRESULT WINAPI
ddraw_IAMMediaStream_JoinFilter(IAMMediaStream
*iface
, IMediaStreamFilter
*filter
)
228 struct ddraw_stream
*stream
= impl_from_IAMMediaStream(iface
);
230 TRACE("iface %p, filter %p.\n", iface
, filter
);
232 stream
->filter
= filter
;
237 static HRESULT WINAPI
ddraw_IAMMediaStream_JoinFilterGraph(IAMMediaStream
*iface
, IFilterGraph
*filtergraph
)
239 struct ddraw_stream
*This
= impl_from_IAMMediaStream(iface
);
241 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, filtergraph
);
246 static const struct IAMMediaStreamVtbl ddraw_IAMMediaStream_vtbl
=
248 /*** IUnknown methods ***/
249 ddraw_IAMMediaStream_QueryInterface
,
250 ddraw_IAMMediaStream_AddRef
,
251 ddraw_IAMMediaStream_Release
,
252 /*** IMediaStream methods ***/
253 ddraw_IAMMediaStream_GetMultiMediaStream
,
254 ddraw_IAMMediaStream_GetInformation
,
255 ddraw_IAMMediaStream_SetSameFormat
,
256 ddraw_IAMMediaStream_AllocateSample
,
257 ddraw_IAMMediaStream_CreateSharedSample
,
258 ddraw_IAMMediaStream_SendEndOfStream
,
259 /*** IAMMediaStream methods ***/
260 ddraw_IAMMediaStream_Initialize
,
261 ddraw_IAMMediaStream_SetState
,
262 ddraw_IAMMediaStream_JoinAMMultiMediaStream
,
263 ddraw_IAMMediaStream_JoinFilter
,
264 ddraw_IAMMediaStream_JoinFilterGraph
267 static inline struct ddraw_stream
*impl_from_IDirectDrawMediaStream(IDirectDrawMediaStream
*iface
)
269 return CONTAINING_RECORD(iface
, struct ddraw_stream
, IDirectDrawMediaStream_iface
);
272 /*** IUnknown methods ***/
273 static HRESULT WINAPI
ddraw_IDirectDrawMediaStream_QueryInterface(IDirectDrawMediaStream
*iface
,
274 REFIID riid
, void **ret_iface
)
276 struct ddraw_stream
*This
= impl_from_IDirectDrawMediaStream(iface
);
277 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ret_iface
);
278 return IAMMediaStream_QueryInterface(&This
->IAMMediaStream_iface
, riid
, ret_iface
);
281 static ULONG WINAPI
ddraw_IDirectDrawMediaStream_AddRef(IDirectDrawMediaStream
*iface
)
283 struct ddraw_stream
*This
= impl_from_IDirectDrawMediaStream(iface
);
284 TRACE("(%p/%p)\n", iface
, This
);
285 return IAMMediaStream_AddRef(&This
->IAMMediaStream_iface
);
288 static ULONG WINAPI
ddraw_IDirectDrawMediaStream_Release(IDirectDrawMediaStream
*iface
)
290 struct ddraw_stream
*This
= impl_from_IDirectDrawMediaStream(iface
);
291 TRACE("(%p/%p)\n", iface
, This
);
292 return IAMMediaStream_Release(&This
->IAMMediaStream_iface
);
295 /*** IMediaStream methods ***/
296 static HRESULT WINAPI
ddraw_IDirectDrawMediaStream_GetMultiMediaStream(IDirectDrawMediaStream
*iface
,
297 IMultiMediaStream
**multi_media_stream
)
299 struct ddraw_stream
*This
= impl_from_IDirectDrawMediaStream(iface
);
301 TRACE("(%p/%p)->(%p)\n", This
, iface
, multi_media_stream
);
303 if (!multi_media_stream
)
306 IMultiMediaStream_AddRef(This
->parent
);
307 *multi_media_stream
= This
->parent
;
312 static HRESULT WINAPI
ddraw_IDirectDrawMediaStream_GetInformation(IDirectDrawMediaStream
*iface
,
313 MSPID
*purpose_id
, STREAM_TYPE
*type
)
315 struct ddraw_stream
*This
= impl_from_IDirectDrawMediaStream(iface
);
317 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, purpose_id
, type
);
320 *purpose_id
= This
->purpose_id
;
322 *type
= This
->stream_type
;
327 static HRESULT WINAPI
ddraw_IDirectDrawMediaStream_SetSameFormat(IDirectDrawMediaStream
*iface
,
328 IMediaStream
*pStreamThatHasDesiredFormat
, DWORD dwFlags
)
330 struct ddraw_stream
*This
= impl_from_IDirectDrawMediaStream(iface
);
332 FIXME("(%p/%p)->(%p,%x) stub!\n", This
, iface
, pStreamThatHasDesiredFormat
, dwFlags
);
337 static HRESULT WINAPI
ddraw_IDirectDrawMediaStream_AllocateSample(IDirectDrawMediaStream
*iface
,
338 DWORD dwFlags
, IStreamSample
**ppSample
)
340 struct ddraw_stream
*This
= impl_from_IDirectDrawMediaStream(iface
);
342 FIXME("(%p/%p)->(%x,%p) stub!\n", This
, iface
, dwFlags
, ppSample
);
347 static HRESULT WINAPI
ddraw_IDirectDrawMediaStream_CreateSharedSample(IDirectDrawMediaStream
*iface
,
348 IStreamSample
*pExistingSample
, DWORD dwFlags
, IStreamSample
**ppSample
)
350 struct ddraw_stream
*This
= impl_from_IDirectDrawMediaStream(iface
);
352 FIXME("(%p/%p)->(%p,%x,%p) stub!\n", This
, iface
, pExistingSample
, dwFlags
, ppSample
);
357 static HRESULT WINAPI
ddraw_IDirectDrawMediaStream_SendEndOfStream(IDirectDrawMediaStream
*iface
,
360 struct ddraw_stream
*This
= impl_from_IDirectDrawMediaStream(iface
);
362 FIXME("(%p/%p)->(%x) stub!\n", This
, iface
, dwFlags
);
367 /*** IDirectDrawMediaStream methods ***/
368 static HRESULT WINAPI
ddraw_IDirectDrawMediaStream_GetFormat(IDirectDrawMediaStream
*iface
,
369 DDSURFACEDESC
*current_format
, IDirectDrawPalette
**palette
,
370 DDSURFACEDESC
*desired_format
, DWORD
*flags
)
372 FIXME("(%p)->(%p,%p,%p,%p) stub!\n", iface
, current_format
, palette
, desired_format
,
375 return MS_E_NOSTREAM
;
379 static HRESULT WINAPI
ddraw_IDirectDrawMediaStream_SetFormat(IDirectDrawMediaStream
*iface
,
380 const DDSURFACEDESC
*pDDSurfaceDesc
, IDirectDrawPalette
*pDirectDrawPalette
)
382 FIXME("(%p)->(%p,%p) stub!\n", iface
, pDDSurfaceDesc
, pDirectDrawPalette
);
387 static HRESULT WINAPI
ddraw_IDirectDrawMediaStream_GetDirectDraw(IDirectDrawMediaStream
*iface
,
390 struct ddraw_stream
*This
= impl_from_IDirectDrawMediaStream(iface
);
392 TRACE("(%p)->(%p)\n", iface
, ddraw
);
397 HRESULT hr
= DirectDrawCreateEx(NULL
, (void**)&This
->ddraw
, &IID_IDirectDraw7
, NULL
);
400 IDirectDraw7_SetCooperativeLevel(This
->ddraw
, NULL
, DDSCL_NORMAL
);
403 return IDirectDraw7_QueryInterface(This
->ddraw
, &IID_IDirectDraw
, (void**)ddraw
);
406 static HRESULT WINAPI
ddraw_IDirectDrawMediaStream_SetDirectDraw(IDirectDrawMediaStream
*iface
,
407 IDirectDraw
*pDirectDraw
)
409 FIXME("(%p)->(%p) stub!\n", iface
, pDirectDraw
);
414 static HRESULT WINAPI
ddraw_IDirectDrawMediaStream_CreateSample(IDirectDrawMediaStream
*iface
,
415 IDirectDrawSurface
*surface
, const RECT
*rect
, DWORD dwFlags
,
416 IDirectDrawStreamSample
**ppSample
)
418 TRACE("(%p)->(%p,%s,%x,%p)\n", iface
, surface
, wine_dbgstr_rect(rect
), dwFlags
, ppSample
);
420 return ddrawstreamsample_create(iface
, surface
, rect
, ppSample
);
423 static HRESULT WINAPI
ddraw_IDirectDrawMediaStream_GetTimePerFrame(IDirectDrawMediaStream
*iface
,
424 STREAM_TIME
*pFrameTime
)
426 FIXME("(%p)->(%p) stub!\n", iface
, pFrameTime
);
431 static const struct IDirectDrawMediaStreamVtbl ddraw_IDirectDrawMediaStream_Vtbl
=
433 /*** IUnknown methods ***/
434 ddraw_IDirectDrawMediaStream_QueryInterface
,
435 ddraw_IDirectDrawMediaStream_AddRef
,
436 ddraw_IDirectDrawMediaStream_Release
,
437 /*** IMediaStream methods ***/
438 ddraw_IDirectDrawMediaStream_GetMultiMediaStream
,
439 ddraw_IDirectDrawMediaStream_GetInformation
,
440 ddraw_IDirectDrawMediaStream_SetSameFormat
,
441 ddraw_IDirectDrawMediaStream_AllocateSample
,
442 ddraw_IDirectDrawMediaStream_CreateSharedSample
,
443 ddraw_IDirectDrawMediaStream_SendEndOfStream
,
444 /*** IDirectDrawMediaStream methods ***/
445 ddraw_IDirectDrawMediaStream_GetFormat
,
446 ddraw_IDirectDrawMediaStream_SetFormat
,
447 ddraw_IDirectDrawMediaStream_GetDirectDraw
,
448 ddraw_IDirectDrawMediaStream_SetDirectDraw
,
449 ddraw_IDirectDrawMediaStream_CreateSample
,
450 ddraw_IDirectDrawMediaStream_GetTimePerFrame
453 struct enum_media_types
455 IEnumMediaTypes IEnumMediaTypes_iface
;
460 static const IEnumMediaTypesVtbl enum_media_types_vtbl
;
462 static struct enum_media_types
*impl_from_IEnumMediaTypes(IEnumMediaTypes
*iface
)
464 return CONTAINING_RECORD(iface
, struct enum_media_types
, IEnumMediaTypes_iface
);
467 static HRESULT WINAPI
enum_media_types_QueryInterface(IEnumMediaTypes
*iface
, REFIID iid
, void **out
)
469 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
471 if (IsEqualGUID(iid
, &IID_IUnknown
) || IsEqualGUID(iid
, &IID_IEnumMediaTypes
))
473 IEnumMediaTypes_AddRef(iface
);
478 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
480 return E_NOINTERFACE
;
483 static ULONG WINAPI
enum_media_types_AddRef(IEnumMediaTypes
*iface
)
485 struct enum_media_types
*enum_media_types
= impl_from_IEnumMediaTypes(iface
);
486 ULONG refcount
= InterlockedIncrement(&enum_media_types
->refcount
);
487 TRACE("%p increasing refcount to %u.\n", enum_media_types
, refcount
);
491 static ULONG WINAPI
enum_media_types_Release(IEnumMediaTypes
*iface
)
493 struct enum_media_types
*enum_media_types
= impl_from_IEnumMediaTypes(iface
);
494 ULONG refcount
= InterlockedDecrement(&enum_media_types
->refcount
);
495 TRACE("%p decreasing refcount to %u.\n", enum_media_types
, refcount
);
497 heap_free(enum_media_types
);
501 static HRESULT WINAPI
enum_media_types_Next(IEnumMediaTypes
*iface
, ULONG count
, AM_MEDIA_TYPE
**mts
, ULONG
*ret_count
)
503 struct enum_media_types
*enum_media_types
= impl_from_IEnumMediaTypes(iface
);
505 TRACE("iface %p, count %u, mts %p, ret_count %p.\n", iface
, count
, mts
, ret_count
);
510 if (count
&& !enum_media_types
->index
)
512 mts
[0] = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE
));
513 memset(mts
[0], 0, sizeof(AM_MEDIA_TYPE
));
514 mts
[0]->majortype
= MEDIATYPE_Video
;
515 mts
[0]->subtype
= MEDIASUBTYPE_RGB8
;
516 mts
[0]->bFixedSizeSamples
= TRUE
;
517 mts
[0]->lSampleSize
= 10000;
518 ++enum_media_types
->index
;
520 return count
== 1 ? S_OK
: S_FALSE
;
524 return count
? S_FALSE
: S_OK
;
527 static HRESULT WINAPI
enum_media_types_Skip(IEnumMediaTypes
*iface
, ULONG count
)
529 struct enum_media_types
*enum_media_types
= impl_from_IEnumMediaTypes(iface
);
531 TRACE("iface %p, count %u.\n", iface
, count
);
533 enum_media_types
->index
+= count
;
538 static HRESULT WINAPI
enum_media_types_Reset(IEnumMediaTypes
*iface
)
540 struct enum_media_types
*enum_media_types
= impl_from_IEnumMediaTypes(iface
);
542 TRACE("iface %p.\n", iface
);
544 enum_media_types
->index
= 0;
548 static HRESULT WINAPI
enum_media_types_Clone(IEnumMediaTypes
*iface
, IEnumMediaTypes
**out
)
550 struct enum_media_types
*enum_media_types
= impl_from_IEnumMediaTypes(iface
);
551 struct enum_media_types
*object
;
553 TRACE("iface %p, out %p.\n", iface
, out
);
555 if (!(object
= heap_alloc(sizeof(*object
))))
556 return E_OUTOFMEMORY
;
558 object
->IEnumMediaTypes_iface
.lpVtbl
= &enum_media_types_vtbl
;
559 object
->refcount
= 1;
560 object
->index
= enum_media_types
->index
;
562 *out
= &object
->IEnumMediaTypes_iface
;
566 static const IEnumMediaTypesVtbl enum_media_types_vtbl
=
568 enum_media_types_QueryInterface
,
569 enum_media_types_AddRef
,
570 enum_media_types_Release
,
571 enum_media_types_Next
,
572 enum_media_types_Skip
,
573 enum_media_types_Reset
,
574 enum_media_types_Clone
,
577 static inline struct ddraw_stream
*impl_from_IPin(IPin
*iface
)
579 return CONTAINING_RECORD(iface
, struct ddraw_stream
, IPin_iface
);
582 static HRESULT WINAPI
ddraw_sink_QueryInterface(IPin
*iface
, REFIID iid
, void **out
)
584 struct ddraw_stream
*stream
= impl_from_IPin(iface
);
585 return IAMMediaStream_QueryInterface(&stream
->IAMMediaStream_iface
, iid
, out
);
588 static ULONG WINAPI
ddraw_sink_AddRef(IPin
*iface
)
590 struct ddraw_stream
*stream
= impl_from_IPin(iface
);
591 return IAMMediaStream_AddRef(&stream
->IAMMediaStream_iface
);
594 static ULONG WINAPI
ddraw_sink_Release(IPin
*iface
)
596 struct ddraw_stream
*stream
= impl_from_IPin(iface
);
597 return IAMMediaStream_Release(&stream
->IAMMediaStream_iface
);
600 static HRESULT WINAPI
ddraw_sink_Connect(IPin
*iface
, IPin
*peer
, const AM_MEDIA_TYPE
*mt
)
602 WARN("iface %p, peer %p, mt %p, unexpected call!\n", iface
, peer
, mt
);
606 static BOOL
check_media_type(const AM_MEDIA_TYPE
*media_type
)
608 if (IsEqualGUID(&media_type
->majortype
, &MEDIATYPE_Video
))
610 if (IsEqualGUID(&media_type
->subtype
, &MEDIASUBTYPE_RGB1
) ||
611 IsEqualGUID(&media_type
->subtype
, &MEDIASUBTYPE_RGB4
) ||
612 IsEqualGUID(&media_type
->subtype
, &MEDIASUBTYPE_RGB8
) ||
613 IsEqualGUID(&media_type
->subtype
, &MEDIASUBTYPE_RGB565
) ||
614 IsEqualGUID(&media_type
->subtype
, &MEDIASUBTYPE_RGB555
) ||
615 IsEqualGUID(&media_type
->subtype
, &MEDIASUBTYPE_RGB24
) ||
616 IsEqualGUID(&media_type
->subtype
, &MEDIASUBTYPE_RGB32
))
618 TRACE("Video sub-type %s matches\n", debugstr_guid(&media_type
->subtype
));
626 static HRESULT WINAPI
ddraw_sink_ReceiveConnection(IPin
*iface
, IPin
*peer
, const AM_MEDIA_TYPE
*mt
)
628 struct ddraw_stream
*stream
= impl_from_IPin(iface
);
631 TRACE("stream %p, peer %p, mt %p.\n", stream
, peer
, mt
);
633 EnterCriticalSection(&stream
->cs
);
637 LeaveCriticalSection(&stream
->cs
);
638 return VFW_E_ALREADY_CONNECTED
;
641 if (!check_media_type(mt
))
643 LeaveCriticalSection(&stream
->cs
);
644 return VFW_E_TYPE_NOT_ACCEPTED
;
647 IPin_QueryDirection(peer
, &dir
);
648 if (dir
!= PINDIR_OUTPUT
)
650 WARN("Rejecting connection from input pin.\n");
651 LeaveCriticalSection(&stream
->cs
);
652 return VFW_E_INVALID_DIRECTION
;
655 CopyMediaType(&stream
->mt
, mt
);
656 IPin_AddRef(stream
->peer
= peer
);
658 LeaveCriticalSection(&stream
->cs
);
663 static HRESULT WINAPI
ddraw_sink_Disconnect(IPin
*iface
)
665 struct ddraw_stream
*stream
= impl_from_IPin(iface
);
667 TRACE("stream %p.\n", stream
);
669 EnterCriticalSection(&stream
->cs
);
673 LeaveCriticalSection(&stream
->cs
);
677 IPin_Release(stream
->peer
);
679 FreeMediaType(&stream
->mt
);
680 memset(&stream
->mt
, 0, sizeof(AM_MEDIA_TYPE
));
682 LeaveCriticalSection(&stream
->cs
);
687 static HRESULT WINAPI
ddraw_sink_ConnectedTo(IPin
*iface
, IPin
**peer
)
689 struct ddraw_stream
*stream
= impl_from_IPin(iface
);
692 TRACE("stream %p, peer %p.\n", stream
, peer
);
694 EnterCriticalSection(&stream
->cs
);
698 IPin_AddRef(*peer
= stream
->peer
);
704 hr
= VFW_E_NOT_CONNECTED
;
707 LeaveCriticalSection(&stream
->cs
);
712 static HRESULT WINAPI
ddraw_sink_ConnectionMediaType(IPin
*iface
, AM_MEDIA_TYPE
*mt
)
714 struct ddraw_stream
*stream
= impl_from_IPin(iface
);
717 TRACE("stream %p, mt %p.\n", stream
, mt
);
719 EnterCriticalSection(&stream
->cs
);
723 CopyMediaType(mt
, &stream
->mt
);
728 memset(mt
, 0, sizeof(AM_MEDIA_TYPE
));
729 hr
= VFW_E_NOT_CONNECTED
;
732 LeaveCriticalSection(&stream
->cs
);
737 static HRESULT WINAPI
ddraw_sink_QueryPinInfo(IPin
*iface
, PIN_INFO
*info
)
739 struct ddraw_stream
*stream
= impl_from_IPin(iface
);
741 TRACE("stream %p, info %p.\n", stream
, info
);
743 IBaseFilter_AddRef(info
->pFilter
= (IBaseFilter
*)stream
->filter
);
744 info
->dir
= PINDIR_INPUT
;
745 wcscpy(info
->achName
, sink_id
);
750 static HRESULT WINAPI
ddraw_sink_QueryDirection(IPin
*iface
, PIN_DIRECTION
*dir
)
752 TRACE("iface %p, dir %p.\n", iface
, dir
);
757 static HRESULT WINAPI
ddraw_sink_QueryId(IPin
*iface
, WCHAR
**id
)
759 TRACE("iface %p, id %p.\n", iface
, id
);
761 if (!(*id
= CoTaskMemAlloc(sizeof(sink_id
))))
762 return E_OUTOFMEMORY
;
764 wcscpy(*id
, sink_id
);
769 static HRESULT WINAPI
ddraw_sink_QueryAccept(IPin
*iface
, const AM_MEDIA_TYPE
*mt
)
771 TRACE("iface %p, mt %p.\n", iface
, mt
);
772 return check_media_type(mt
) ? S_OK
: S_FALSE
;
775 static HRESULT WINAPI
ddraw_sink_EnumMediaTypes(IPin
*iface
, IEnumMediaTypes
**enum_media_types
)
777 struct enum_media_types
*object
;
779 TRACE("iface %p, enum_media_types %p.\n", iface
, enum_media_types
);
781 if (!enum_media_types
)
784 if (!(object
= heap_alloc(sizeof(*object
))))
785 return E_OUTOFMEMORY
;
787 object
->IEnumMediaTypes_iface
.lpVtbl
= &enum_media_types_vtbl
;
788 object
->refcount
= 1;
791 *enum_media_types
= &object
->IEnumMediaTypes_iface
;
795 static HRESULT WINAPI
ddraw_sink_QueryInternalConnections(IPin
*iface
, IPin
**pins
, ULONG
*count
)
797 TRACE("iface %p, pins %p, count %p.\n", iface
, pins
, count
);
801 static HRESULT WINAPI
ddraw_sink_EndOfStream(IPin
*iface
)
803 FIXME("iface %p, stub!\n", iface
);
807 static HRESULT WINAPI
ddraw_sink_BeginFlush(IPin
*iface
)
809 FIXME("iface %p, stub!\n", iface
);
813 static HRESULT WINAPI
ddraw_sink_EndFlush(IPin
*iface
)
815 FIXME("iface %p, stub!\n", iface
);
819 static HRESULT WINAPI
ddraw_sink_NewSegment(IPin
*iface
, REFERENCE_TIME start
, REFERENCE_TIME stop
, double rate
)
821 FIXME("iface %p, start %s, stop %s, rate %0.16e, stub!\n",
822 iface
, wine_dbgstr_longlong(start
), wine_dbgstr_longlong(stop
), rate
);
826 static const IPinVtbl ddraw_sink_vtbl
=
828 ddraw_sink_QueryInterface
,
832 ddraw_sink_ReceiveConnection
,
833 ddraw_sink_Disconnect
,
834 ddraw_sink_ConnectedTo
,
835 ddraw_sink_ConnectionMediaType
,
836 ddraw_sink_QueryPinInfo
,
837 ddraw_sink_QueryDirection
,
839 ddraw_sink_QueryAccept
,
840 ddraw_sink_EnumMediaTypes
,
841 ddraw_sink_QueryInternalConnections
,
842 ddraw_sink_EndOfStream
,
843 ddraw_sink_BeginFlush
,
845 ddraw_sink_NewSegment
,
848 static inline struct ddraw_stream
*impl_from_IMemInputPin(IMemInputPin
*iface
)
850 return CONTAINING_RECORD(iface
, struct ddraw_stream
, IMemInputPin_iface
);
853 static HRESULT WINAPI
ddraw_meminput_QueryInterface(IMemInputPin
*iface
, REFIID iid
, void **out
)
855 struct ddraw_stream
*stream
= impl_from_IMemInputPin(iface
);
856 return IAMMediaStream_QueryInterface(&stream
->IAMMediaStream_iface
, iid
, out
);
859 static ULONG WINAPI
ddraw_meminput_AddRef(IMemInputPin
*iface
)
861 struct ddraw_stream
*stream
= impl_from_IMemInputPin(iface
);
862 return IAMMediaStream_AddRef(&stream
->IAMMediaStream_iface
);
865 static ULONG WINAPI
ddraw_meminput_Release(IMemInputPin
*iface
)
867 struct ddraw_stream
*stream
= impl_from_IMemInputPin(iface
);
868 return IAMMediaStream_Release(&stream
->IAMMediaStream_iface
);
871 static HRESULT WINAPI
ddraw_meminput_GetAllocator(IMemInputPin
*iface
, IMemAllocator
**allocator
)
873 struct ddraw_stream
*stream
= impl_from_IMemInputPin(iface
);
875 TRACE("stream %p, allocator %p.\n", stream
, allocator
);
877 if (stream
->allocator
)
879 IMemAllocator_AddRef(*allocator
= stream
->allocator
);
884 return VFW_E_NO_ALLOCATOR
;
887 static HRESULT WINAPI
ddraw_meminput_NotifyAllocator(IMemInputPin
*iface
, IMemAllocator
*allocator
, BOOL readonly
)
889 struct ddraw_stream
*stream
= impl_from_IMemInputPin(iface
);
891 TRACE("stream %p, allocator %p, readonly %d.\n", stream
, allocator
, readonly
);
897 IMemAllocator_AddRef(allocator
);
898 if (stream
->allocator
)
899 IMemAllocator_Release(stream
->allocator
);
900 stream
->allocator
= allocator
;
905 static HRESULT WINAPI
ddraw_meminput_GetAllocatorRequirements(IMemInputPin
*iface
, ALLOCATOR_PROPERTIES
*props
)
907 TRACE("iface %p, props %p.\n", iface
, props
);
911 static HRESULT WINAPI
ddraw_meminput_Receive(IMemInputPin
*iface
, IMediaSample
*sample
)
913 FIXME("iface %p, sample %p, stub!\n", iface
, sample
);
917 static HRESULT WINAPI
ddraw_meminput_ReceiveMultiple(IMemInputPin
*iface
,
918 IMediaSample
**samples
, LONG count
, LONG
*processed
)
920 FIXME("iface %p, samples %p, count %u, processed %p, stub!\n", iface
, samples
, count
, processed
);
924 static HRESULT WINAPI
ddraw_meminput_ReceiveCanBlock(IMemInputPin
*iface
)
926 TRACE("iface %p.\n", iface
);
930 static const IMemInputPinVtbl ddraw_meminput_vtbl
=
932 ddraw_meminput_QueryInterface
,
933 ddraw_meminput_AddRef
,
934 ddraw_meminput_Release
,
935 ddraw_meminput_GetAllocator
,
936 ddraw_meminput_NotifyAllocator
,
937 ddraw_meminput_GetAllocatorRequirements
,
938 ddraw_meminput_Receive
,
939 ddraw_meminput_ReceiveMultiple
,
940 ddraw_meminput_ReceiveCanBlock
,
943 HRESULT
ddraw_stream_create(IMultiMediaStream
*parent
, const MSPID
*purpose_id
,
944 IUnknown
*stream_object
, STREAM_TYPE stream_type
, IAMMediaStream
**media_stream
)
946 struct ddraw_stream
*object
;
949 TRACE("(%p,%s,%p,%p)\n", parent
, debugstr_guid(purpose_id
), stream_object
, media_stream
);
951 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
953 return E_OUTOFMEMORY
;
955 object
->IAMMediaStream_iface
.lpVtbl
= &ddraw_IAMMediaStream_vtbl
;
956 object
->IDirectDrawMediaStream_iface
.lpVtbl
= &ddraw_IDirectDrawMediaStream_Vtbl
;
957 object
->IMemInputPin_iface
.lpVtbl
= &ddraw_meminput_vtbl
;
958 object
->IPin_iface
.lpVtbl
= &ddraw_sink_vtbl
;
961 InitializeCriticalSection(&object
->cs
);
963 object
->parent
= parent
;
964 object
->purpose_id
= *purpose_id
;
965 object
->stream_type
= stream_type
;
968 && FAILED(hr
= IUnknown_QueryInterface(stream_object
, &IID_IDirectDraw7
, (void **)&object
->ddraw
)))
969 FIXME("Stream object doesn't implement IDirectDraw7 interface, hr %#x.\n", hr
);
971 *media_stream
= &object
->IAMMediaStream_iface
;
977 IDirectDrawStreamSample IDirectDrawStreamSample_iface
;
979 IMediaStream
*parent
;
980 IDirectDrawSurface
*surface
;
982 } IDirectDrawStreamSampleImpl
;
984 static inline IDirectDrawStreamSampleImpl
*impl_from_IDirectDrawStreamSample(IDirectDrawStreamSample
*iface
)
986 return CONTAINING_RECORD(iface
, IDirectDrawStreamSampleImpl
, IDirectDrawStreamSample_iface
);
989 /*** IUnknown methods ***/
990 static HRESULT WINAPI
IDirectDrawStreamSampleImpl_QueryInterface(IDirectDrawStreamSample
*iface
,
991 REFIID riid
, void **ret_iface
)
993 TRACE("(%p)->(%s,%p)\n", iface
, debugstr_guid(riid
), ret_iface
);
995 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
996 IsEqualGUID(riid
, &IID_IStreamSample
) ||
997 IsEqualGUID(riid
, &IID_IDirectDrawStreamSample
))
999 IDirectDrawStreamSample_AddRef(iface
);
1006 ERR("(%p)->(%s,%p),not found\n", iface
, debugstr_guid(riid
), ret_iface
);
1007 return E_NOINTERFACE
;
1010 static ULONG WINAPI
IDirectDrawStreamSampleImpl_AddRef(IDirectDrawStreamSample
*iface
)
1012 IDirectDrawStreamSampleImpl
*This
= impl_from_IDirectDrawStreamSample(iface
);
1013 ULONG ref
= InterlockedIncrement(&This
->ref
);
1015 TRACE("(%p)->(): new ref = %u\n", iface
, ref
);
1020 static ULONG WINAPI
IDirectDrawStreamSampleImpl_Release(IDirectDrawStreamSample
*iface
)
1022 IDirectDrawStreamSampleImpl
*This
= impl_from_IDirectDrawStreamSample(iface
);
1023 ULONG ref
= InterlockedDecrement(&This
->ref
);
1025 TRACE("(%p)->(): new ref = %u\n", iface
, ref
);
1030 IDirectDrawSurface_Release(This
->surface
);
1031 IMediaStream_Release(This
->parent
);
1032 HeapFree(GetProcessHeap(), 0, This
);
1038 /*** IStreamSample methods ***/
1039 static HRESULT WINAPI
IDirectDrawStreamSampleImpl_GetMediaStream(IDirectDrawStreamSample
*iface
, IMediaStream
**media_stream
)
1041 FIXME("(%p)->(%p): stub\n", iface
, media_stream
);
1046 static HRESULT WINAPI
IDirectDrawStreamSampleImpl_GetSampleTimes(IDirectDrawStreamSample
*iface
, STREAM_TIME
*start_time
,
1047 STREAM_TIME
*end_time
, STREAM_TIME
*current_time
)
1049 FIXME("(%p)->(%p,%p,%p): stub\n", iface
, start_time
, end_time
, current_time
);
1054 static HRESULT WINAPI
IDirectDrawStreamSampleImpl_SetSampleTimes(IDirectDrawStreamSample
*iface
, const STREAM_TIME
*start_time
,
1055 const STREAM_TIME
*end_time
)
1057 FIXME("(%p)->(%p,%p): stub\n", iface
, start_time
, end_time
);
1062 static HRESULT WINAPI
IDirectDrawStreamSampleImpl_Update(IDirectDrawStreamSample
*iface
, DWORD flags
, HANDLE event
,
1063 PAPCFUNC func_APC
, DWORD APC_data
)
1065 FIXME("(%p)->(%x,%p,%p,%u): stub\n", iface
, flags
, event
, func_APC
, APC_data
);
1070 static HRESULT WINAPI
IDirectDrawStreamSampleImpl_CompletionStatus(IDirectDrawStreamSample
*iface
, DWORD flags
, DWORD milliseconds
)
1072 FIXME("(%p)->(%x,%u): stub\n", iface
, flags
, milliseconds
);
1077 /*** IDirectDrawStreamSample methods ***/
1078 static HRESULT WINAPI
IDirectDrawStreamSampleImpl_GetSurface(IDirectDrawStreamSample
*iface
, IDirectDrawSurface
**ddraw_surface
,
1081 IDirectDrawStreamSampleImpl
*This
= impl_from_IDirectDrawStreamSample(iface
);
1083 TRACE("(%p)->(%p,%p)\n", iface
, ddraw_surface
, rect
);
1087 *ddraw_surface
= This
->surface
;
1089 IDirectDrawSurface_AddRef(*ddraw_surface
);
1098 static HRESULT WINAPI
IDirectDrawStreamSampleImpl_SetRect(IDirectDrawStreamSample
*iface
, const RECT
*rect
)
1100 FIXME("(%p)->(%p): stub\n", iface
, rect
);
1105 static const struct IDirectDrawStreamSampleVtbl DirectDrawStreamSample_Vtbl
=
1107 /*** IUnknown methods ***/
1108 IDirectDrawStreamSampleImpl_QueryInterface
,
1109 IDirectDrawStreamSampleImpl_AddRef
,
1110 IDirectDrawStreamSampleImpl_Release
,
1111 /*** IStreamSample methods ***/
1112 IDirectDrawStreamSampleImpl_GetMediaStream
,
1113 IDirectDrawStreamSampleImpl_GetSampleTimes
,
1114 IDirectDrawStreamSampleImpl_SetSampleTimes
,
1115 IDirectDrawStreamSampleImpl_Update
,
1116 IDirectDrawStreamSampleImpl_CompletionStatus
,
1117 /*** IDirectDrawStreamSample methods ***/
1118 IDirectDrawStreamSampleImpl_GetSurface
,
1119 IDirectDrawStreamSampleImpl_SetRect
1122 static HRESULT
ddrawstreamsample_create(IDirectDrawMediaStream
*parent
, IDirectDrawSurface
*surface
,
1123 const RECT
*rect
, IDirectDrawStreamSample
**ddraw_stream_sample
)
1125 IDirectDrawStreamSampleImpl
*object
;
1128 TRACE("(%p)\n", ddraw_stream_sample
);
1130 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
1132 return E_OUTOFMEMORY
;
1134 object
->IDirectDrawStreamSample_iface
.lpVtbl
= &DirectDrawStreamSample_Vtbl
;
1136 object
->parent
= (IMediaStream
*)parent
;
1137 IMediaStream_AddRef(object
->parent
);
1141 object
->surface
= surface
;
1142 IDirectDrawSurface_AddRef(surface
);
1149 hr
= IDirectDrawMediaStream_GetDirectDraw(parent
, &ddraw
);
1152 IDirectDrawStreamSample_Release(&object
->IDirectDrawStreamSample_iface
);
1156 desc
.dwSize
= sizeof(desc
);
1157 desc
.dwFlags
= DDSD_CAPS
|DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_PIXELFORMAT
;
1158 desc
.dwHeight
= 100;
1160 desc
.ddpfPixelFormat
.dwSize
= sizeof(desc
.ddpfPixelFormat
);
1161 desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
1162 desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
= 32;
1163 desc
.ddpfPixelFormat
.u2
.dwRBitMask
= 0xff0000;
1164 desc
.ddpfPixelFormat
.u3
.dwGBitMask
= 0x00ff00;
1165 desc
.ddpfPixelFormat
.u4
.dwBBitMask
= 0x0000ff;
1166 desc
.ddpfPixelFormat
.u5
.dwRGBAlphaBitMask
= 0;
1167 desc
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
|DDSCAPS_OFFSCREENPLAIN
;
1168 desc
.lpSurface
= NULL
;
1170 hr
= IDirectDraw_CreateSurface(ddraw
, &desc
, &object
->surface
, NULL
);
1171 IDirectDraw_Release(ddraw
);
1174 ERR("failed to create surface, 0x%08x\n", hr
);
1175 IDirectDrawStreamSample_Release(&object
->IDirectDrawStreamSample_iface
);
1181 object
->rect
= *rect
;
1182 else if (object
->surface
)
1184 DDSURFACEDESC desc
= { sizeof(desc
) };
1185 hr
= IDirectDrawSurface_GetSurfaceDesc(object
->surface
, &desc
);
1187 SetRect(&object
->rect
, 0, 0, desc
.dwWidth
, desc
.dwHeight
);
1190 *ddraw_stream_sample
= &object
->IDirectDrawStreamSample_iface
;