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}";
33 IAMMediaStream IAMMediaStream_iface
;
34 IDirectDrawMediaStream IDirectDrawMediaStream_iface
;
35 IMemInputPin IMemInputPin_iface
;
40 IMultiMediaStream
* parent
;
42 STREAM_TYPE stream_type
;
45 IMediaStreamFilter
*filter
;
48 IMemAllocator
*allocator
;
52 static HRESULT
ddrawstreamsample_create(struct ddraw_stream
*parent
, IDirectDrawSurface
*surface
,
53 const RECT
*rect
, IDirectDrawStreamSample
**ddraw_stream_sample
);
55 static inline struct ddraw_stream
*impl_from_IAMMediaStream(IAMMediaStream
*iface
)
57 return CONTAINING_RECORD(iface
, struct ddraw_stream
, IAMMediaStream_iface
);
60 /*** IUnknown methods ***/
61 static HRESULT WINAPI
ddraw_IAMMediaStream_QueryInterface(IAMMediaStream
*iface
,
62 REFIID riid
, void **ret_iface
)
64 struct ddraw_stream
*This
= impl_from_IAMMediaStream(iface
);
66 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ret_iface
);
68 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
69 IsEqualGUID(riid
, &IID_IMediaStream
) ||
70 IsEqualGUID(riid
, &IID_IAMMediaStream
))
72 IAMMediaStream_AddRef(iface
);
76 else if (IsEqualGUID(riid
, &IID_IDirectDrawMediaStream
))
78 IAMMediaStream_AddRef(iface
);
79 *ret_iface
= &This
->IDirectDrawMediaStream_iface
;
82 else if (IsEqualGUID(riid
, &IID_IPin
))
84 IAMMediaStream_AddRef(iface
);
85 *ret_iface
= &This
->IPin_iface
;
88 else if (IsEqualGUID(riid
, &IID_IMemInputPin
))
90 IAMMediaStream_AddRef(iface
);
91 *ret_iface
= &This
->IMemInputPin_iface
;
95 ERR("(%p)->(%s,%p),not found\n", This
, debugstr_guid(riid
), ret_iface
);
99 static ULONG WINAPI
ddraw_IAMMediaStream_AddRef(IAMMediaStream
*iface
)
101 struct ddraw_stream
*This
= impl_from_IAMMediaStream(iface
);
102 ULONG ref
= InterlockedIncrement(&This
->ref
);
104 TRACE("(%p/%p)->(): new ref = %u\n", iface
, This
, ref
);
109 static ULONG WINAPI
ddraw_IAMMediaStream_Release(IAMMediaStream
*iface
)
111 struct ddraw_stream
*stream
= impl_from_IAMMediaStream(iface
);
112 ULONG ref
= InterlockedDecrement(&stream
->ref
);
114 TRACE("%p decreasing refcount to %u.\n", stream
, ref
);
118 DeleteCriticalSection(&stream
->cs
);
120 IDirectDraw_Release(stream
->ddraw
);
121 HeapFree(GetProcessHeap(), 0, stream
);
127 /*** IMediaStream methods ***/
128 static HRESULT WINAPI
ddraw_IAMMediaStream_GetMultiMediaStream(IAMMediaStream
*iface
,
129 IMultiMediaStream
**mmstream
)
131 struct ddraw_stream
*stream
= impl_from_IAMMediaStream(iface
);
133 TRACE("stream %p, mmstream %p.\n", stream
, mmstream
);
139 IMultiMediaStream_AddRef(stream
->parent
);
140 *mmstream
= stream
->parent
;
144 static HRESULT WINAPI
ddraw_IAMMediaStream_GetInformation(IAMMediaStream
*iface
,
145 MSPID
*purpose_id
, STREAM_TYPE
*type
)
147 struct ddraw_stream
*This
= impl_from_IAMMediaStream(iface
);
149 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, purpose_id
, type
);
152 *purpose_id
= This
->purpose_id
;
154 *type
= This
->stream_type
;
159 static HRESULT WINAPI
ddraw_IAMMediaStream_SetSameFormat(IAMMediaStream
*iface
,
160 IMediaStream
*pStreamThatHasDesiredFormat
, DWORD flags
)
162 struct ddraw_stream
*This
= impl_from_IAMMediaStream(iface
);
164 FIXME("(%p/%p)->(%p,%x) stub!\n", This
, iface
, pStreamThatHasDesiredFormat
, flags
);
169 static HRESULT WINAPI
ddraw_IAMMediaStream_AllocateSample(IAMMediaStream
*iface
,
170 DWORD flags
, IStreamSample
**sample
)
172 struct ddraw_stream
*This
= impl_from_IAMMediaStream(iface
);
174 FIXME("(%p/%p)->(%x,%p) stub!\n", This
, iface
, flags
, sample
);
179 static HRESULT WINAPI
ddraw_IAMMediaStream_CreateSharedSample(IAMMediaStream
*iface
,
180 IStreamSample
*existing_sample
, DWORD flags
, IStreamSample
**sample
)
182 struct ddraw_stream
*This
= impl_from_IAMMediaStream(iface
);
184 FIXME("(%p/%p)->(%p,%x,%p) stub!\n", This
, iface
, existing_sample
, flags
, sample
);
189 static HRESULT WINAPI
ddraw_IAMMediaStream_SendEndOfStream(IAMMediaStream
*iface
, DWORD flags
)
191 struct ddraw_stream
*This
= impl_from_IAMMediaStream(iface
);
193 FIXME("(%p/%p)->(%x) stub!\n", This
, iface
, flags
);
198 /*** IAMMediaStream methods ***/
199 static HRESULT WINAPI
ddraw_IAMMediaStream_Initialize(IAMMediaStream
*iface
, IUnknown
*source_object
, DWORD flags
,
200 REFMSPID purpose_id
, const STREAM_TYPE stream_type
)
202 struct ddraw_stream
*stream
= impl_from_IAMMediaStream(iface
);
205 TRACE("stream %p, source_object %p, flags %x, purpose_id %s, stream_type %u.\n", stream
, source_object
, flags
,
206 debugstr_guid(purpose_id
), stream_type
);
211 if (flags
& AMMSF_CREATEPEER
)
212 FIXME("AMMSF_CREATEPEER is not yet supported.\n");
214 stream
->purpose_id
= *purpose_id
;
215 stream
->stream_type
= stream_type
;
218 && FAILED(hr
= IUnknown_QueryInterface(source_object
, &IID_IDirectDraw
, (void **)&stream
->ddraw
)))
219 FIXME("Stream object doesn't implement IDirectDraw interface, hr %#x.\n", hr
);
223 if (FAILED(hr
= DirectDrawCreate(NULL
, &stream
->ddraw
, NULL
)))
225 IDirectDraw_SetCooperativeLevel(stream
->ddraw
, NULL
, DDSCL_NORMAL
);
231 static HRESULT WINAPI
ddraw_IAMMediaStream_SetState(IAMMediaStream
*iface
, FILTER_STATE state
)
233 struct ddraw_stream
*This
= impl_from_IAMMediaStream(iface
);
235 FIXME("(%p/%p)->(%u) stub!\n", This
, iface
, state
);
240 static HRESULT WINAPI
ddraw_IAMMediaStream_JoinAMMultiMediaStream(IAMMediaStream
*iface
, IAMMultiMediaStream
*mmstream
)
242 struct ddraw_stream
*stream
= impl_from_IAMMediaStream(iface
);
244 TRACE("stream %p, mmstream %p.\n", stream
, mmstream
);
246 stream
->parent
= (IMultiMediaStream
*)mmstream
;
251 static HRESULT WINAPI
ddraw_IAMMediaStream_JoinFilter(IAMMediaStream
*iface
, IMediaStreamFilter
*filter
)
253 struct ddraw_stream
*stream
= impl_from_IAMMediaStream(iface
);
255 TRACE("iface %p, filter %p.\n", iface
, filter
);
257 stream
->filter
= filter
;
262 static HRESULT WINAPI
ddraw_IAMMediaStream_JoinFilterGraph(IAMMediaStream
*iface
, IFilterGraph
*filtergraph
)
264 struct ddraw_stream
*stream
= impl_from_IAMMediaStream(iface
);
266 TRACE("stream %p, filtergraph %p.\n", stream
, filtergraph
);
271 static const struct IAMMediaStreamVtbl ddraw_IAMMediaStream_vtbl
=
273 /*** IUnknown methods ***/
274 ddraw_IAMMediaStream_QueryInterface
,
275 ddraw_IAMMediaStream_AddRef
,
276 ddraw_IAMMediaStream_Release
,
277 /*** IMediaStream methods ***/
278 ddraw_IAMMediaStream_GetMultiMediaStream
,
279 ddraw_IAMMediaStream_GetInformation
,
280 ddraw_IAMMediaStream_SetSameFormat
,
281 ddraw_IAMMediaStream_AllocateSample
,
282 ddraw_IAMMediaStream_CreateSharedSample
,
283 ddraw_IAMMediaStream_SendEndOfStream
,
284 /*** IAMMediaStream methods ***/
285 ddraw_IAMMediaStream_Initialize
,
286 ddraw_IAMMediaStream_SetState
,
287 ddraw_IAMMediaStream_JoinAMMultiMediaStream
,
288 ddraw_IAMMediaStream_JoinFilter
,
289 ddraw_IAMMediaStream_JoinFilterGraph
292 static inline struct ddraw_stream
*impl_from_IDirectDrawMediaStream(IDirectDrawMediaStream
*iface
)
294 return CONTAINING_RECORD(iface
, struct ddraw_stream
, IDirectDrawMediaStream_iface
);
297 /*** IUnknown methods ***/
298 static HRESULT WINAPI
ddraw_IDirectDrawMediaStream_QueryInterface(IDirectDrawMediaStream
*iface
,
299 REFIID riid
, void **ret_iface
)
301 struct ddraw_stream
*This
= impl_from_IDirectDrawMediaStream(iface
);
302 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ret_iface
);
303 return IAMMediaStream_QueryInterface(&This
->IAMMediaStream_iface
, riid
, ret_iface
);
306 static ULONG WINAPI
ddraw_IDirectDrawMediaStream_AddRef(IDirectDrawMediaStream
*iface
)
308 struct ddraw_stream
*This
= impl_from_IDirectDrawMediaStream(iface
);
309 TRACE("(%p/%p)\n", iface
, This
);
310 return IAMMediaStream_AddRef(&This
->IAMMediaStream_iface
);
313 static ULONG WINAPI
ddraw_IDirectDrawMediaStream_Release(IDirectDrawMediaStream
*iface
)
315 struct ddraw_stream
*This
= impl_from_IDirectDrawMediaStream(iface
);
316 TRACE("(%p/%p)\n", iface
, This
);
317 return IAMMediaStream_Release(&This
->IAMMediaStream_iface
);
320 static HRESULT WINAPI
ddraw_IDirectDrawMediaStream_GetMultiMediaStream(IDirectDrawMediaStream
*iface
,
321 IMultiMediaStream
**mmstream
)
323 struct ddraw_stream
*stream
= impl_from_IDirectDrawMediaStream(iface
);
324 return IAMMediaStream_GetMultiMediaStream(&stream
->IAMMediaStream_iface
, mmstream
);
327 static HRESULT WINAPI
ddraw_IDirectDrawMediaStream_GetInformation(IDirectDrawMediaStream
*iface
,
328 MSPID
*purpose_id
, STREAM_TYPE
*type
)
330 struct ddraw_stream
*stream
= impl_from_IDirectDrawMediaStream(iface
);
331 return IAMMediaStream_GetInformation(&stream
->IAMMediaStream_iface
, purpose_id
, type
);
334 static HRESULT WINAPI
ddraw_IDirectDrawMediaStream_SetSameFormat(IDirectDrawMediaStream
*iface
,
335 IMediaStream
*other
, DWORD flags
)
337 struct ddraw_stream
*stream
= impl_from_IDirectDrawMediaStream(iface
);
338 return IAMMediaStream_SetSameFormat(&stream
->IAMMediaStream_iface
, other
, flags
);
341 static HRESULT WINAPI
ddraw_IDirectDrawMediaStream_AllocateSample(IDirectDrawMediaStream
*iface
,
342 DWORD flags
, IStreamSample
**sample
)
344 struct ddraw_stream
*stream
= impl_from_IDirectDrawMediaStream(iface
);
345 return IAMMediaStream_AllocateSample(&stream
->IAMMediaStream_iface
, flags
, sample
);
348 static HRESULT WINAPI
ddraw_IDirectDrawMediaStream_CreateSharedSample(IDirectDrawMediaStream
*iface
,
349 IStreamSample
*existing_sample
, DWORD flags
, IStreamSample
**sample
)
351 struct ddraw_stream
*stream
= impl_from_IDirectDrawMediaStream(iface
);
352 return IAMMediaStream_CreateSharedSample(&stream
->IAMMediaStream_iface
, existing_sample
, flags
, sample
);
355 static HRESULT WINAPI
ddraw_IDirectDrawMediaStream_SendEndOfStream(IDirectDrawMediaStream
*iface
, DWORD flags
)
357 struct ddraw_stream
*stream
= impl_from_IDirectDrawMediaStream(iface
);
358 return IAMMediaStream_SendEndOfStream(&stream
->IAMMediaStream_iface
, flags
);
361 /*** IDirectDrawMediaStream methods ***/
362 static HRESULT WINAPI
ddraw_IDirectDrawMediaStream_GetFormat(IDirectDrawMediaStream
*iface
,
363 DDSURFACEDESC
*current_format
, IDirectDrawPalette
**palette
,
364 DDSURFACEDESC
*desired_format
, DWORD
*flags
)
366 FIXME("(%p)->(%p,%p,%p,%p) stub!\n", iface
, current_format
, palette
, desired_format
,
369 return MS_E_NOSTREAM
;
373 static HRESULT WINAPI
ddraw_IDirectDrawMediaStream_SetFormat(IDirectDrawMediaStream
*iface
,
374 const DDSURFACEDESC
*pDDSurfaceDesc
, IDirectDrawPalette
*pDirectDrawPalette
)
376 FIXME("(%p)->(%p,%p) stub!\n", iface
, pDDSurfaceDesc
, pDirectDrawPalette
);
381 static HRESULT WINAPI
ddraw_IDirectDrawMediaStream_GetDirectDraw(IDirectDrawMediaStream
*iface
,
384 struct ddraw_stream
*stream
= impl_from_IDirectDrawMediaStream(iface
);
386 TRACE("stream %p, ddraw %p.\n", stream
, ddraw
);
397 IDirectDraw_AddRef(stream
->ddraw
);
398 *ddraw
= stream
->ddraw
;
403 static HRESULT WINAPI
ddraw_IDirectDrawMediaStream_SetDirectDraw(IDirectDrawMediaStream
*iface
,
406 struct ddraw_stream
*stream
= impl_from_IDirectDrawMediaStream(iface
);
408 TRACE("stream %p, ddraw %p.\n", stream
, ddraw
);
410 EnterCriticalSection(&stream
->cs
);
412 if (stream
->sample_refs
)
414 HRESULT hr
= (stream
->ddraw
== ddraw
) ? S_OK
: MS_E_SAMPLEALLOC
;
415 LeaveCriticalSection(&stream
->cs
);
420 IDirectDraw_Release(stream
->ddraw
);
424 IDirectDraw_AddRef(ddraw
);
425 stream
->ddraw
= ddraw
;
428 stream
->ddraw
= NULL
;
430 LeaveCriticalSection(&stream
->cs
);
435 static HRESULT WINAPI
ddraw_IDirectDrawMediaStream_CreateSample(IDirectDrawMediaStream
*iface
,
436 IDirectDrawSurface
*surface
, const RECT
*rect
, DWORD flags
,
437 IDirectDrawStreamSample
**sample
)
439 struct ddraw_stream
*stream
= impl_from_IDirectDrawMediaStream(iface
);
442 TRACE("stream %p, surface %p, rect %s, flags %#x, sample %p.\n",
443 stream
, surface
, wine_dbgstr_rect(rect
), flags
, sample
);
445 EnterCriticalSection(&stream
->cs
);
446 hr
= ddrawstreamsample_create(stream
, surface
, rect
, sample
);
447 LeaveCriticalSection(&stream
->cs
);
452 static HRESULT WINAPI
ddraw_IDirectDrawMediaStream_GetTimePerFrame(IDirectDrawMediaStream
*iface
,
453 STREAM_TIME
*pFrameTime
)
455 FIXME("(%p)->(%p) stub!\n", iface
, pFrameTime
);
460 static const struct IDirectDrawMediaStreamVtbl ddraw_IDirectDrawMediaStream_Vtbl
=
462 /*** IUnknown methods ***/
463 ddraw_IDirectDrawMediaStream_QueryInterface
,
464 ddraw_IDirectDrawMediaStream_AddRef
,
465 ddraw_IDirectDrawMediaStream_Release
,
466 /*** IMediaStream methods ***/
467 ddraw_IDirectDrawMediaStream_GetMultiMediaStream
,
468 ddraw_IDirectDrawMediaStream_GetInformation
,
469 ddraw_IDirectDrawMediaStream_SetSameFormat
,
470 ddraw_IDirectDrawMediaStream_AllocateSample
,
471 ddraw_IDirectDrawMediaStream_CreateSharedSample
,
472 ddraw_IDirectDrawMediaStream_SendEndOfStream
,
473 /*** IDirectDrawMediaStream methods ***/
474 ddraw_IDirectDrawMediaStream_GetFormat
,
475 ddraw_IDirectDrawMediaStream_SetFormat
,
476 ddraw_IDirectDrawMediaStream_GetDirectDraw
,
477 ddraw_IDirectDrawMediaStream_SetDirectDraw
,
478 ddraw_IDirectDrawMediaStream_CreateSample
,
479 ddraw_IDirectDrawMediaStream_GetTimePerFrame
482 struct enum_media_types
484 IEnumMediaTypes IEnumMediaTypes_iface
;
489 static const IEnumMediaTypesVtbl enum_media_types_vtbl
;
491 static struct enum_media_types
*impl_from_IEnumMediaTypes(IEnumMediaTypes
*iface
)
493 return CONTAINING_RECORD(iface
, struct enum_media_types
, IEnumMediaTypes_iface
);
496 static HRESULT WINAPI
enum_media_types_QueryInterface(IEnumMediaTypes
*iface
, REFIID iid
, void **out
)
498 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
500 if (IsEqualGUID(iid
, &IID_IUnknown
) || IsEqualGUID(iid
, &IID_IEnumMediaTypes
))
502 IEnumMediaTypes_AddRef(iface
);
507 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
509 return E_NOINTERFACE
;
512 static ULONG WINAPI
enum_media_types_AddRef(IEnumMediaTypes
*iface
)
514 struct enum_media_types
*enum_media_types
= impl_from_IEnumMediaTypes(iface
);
515 ULONG refcount
= InterlockedIncrement(&enum_media_types
->refcount
);
516 TRACE("%p increasing refcount to %u.\n", enum_media_types
, refcount
);
520 static ULONG WINAPI
enum_media_types_Release(IEnumMediaTypes
*iface
)
522 struct enum_media_types
*enum_media_types
= impl_from_IEnumMediaTypes(iface
);
523 ULONG refcount
= InterlockedDecrement(&enum_media_types
->refcount
);
524 TRACE("%p decreasing refcount to %u.\n", enum_media_types
, refcount
);
526 heap_free(enum_media_types
);
530 static HRESULT WINAPI
enum_media_types_Next(IEnumMediaTypes
*iface
, ULONG count
, AM_MEDIA_TYPE
**mts
, ULONG
*ret_count
)
532 struct enum_media_types
*enum_media_types
= impl_from_IEnumMediaTypes(iface
);
534 TRACE("iface %p, count %u, mts %p, ret_count %p.\n", iface
, count
, mts
, ret_count
);
539 if (count
&& !enum_media_types
->index
)
541 mts
[0] = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE
));
542 memset(mts
[0], 0, sizeof(AM_MEDIA_TYPE
));
543 mts
[0]->majortype
= MEDIATYPE_Video
;
544 mts
[0]->subtype
= MEDIASUBTYPE_RGB8
;
545 mts
[0]->bFixedSizeSamples
= TRUE
;
546 mts
[0]->lSampleSize
= 10000;
547 ++enum_media_types
->index
;
549 return count
== 1 ? S_OK
: S_FALSE
;
553 return count
? S_FALSE
: S_OK
;
556 static HRESULT WINAPI
enum_media_types_Skip(IEnumMediaTypes
*iface
, ULONG count
)
558 struct enum_media_types
*enum_media_types
= impl_from_IEnumMediaTypes(iface
);
560 TRACE("iface %p, count %u.\n", iface
, count
);
562 enum_media_types
->index
+= count
;
567 static HRESULT WINAPI
enum_media_types_Reset(IEnumMediaTypes
*iface
)
569 struct enum_media_types
*enum_media_types
= impl_from_IEnumMediaTypes(iface
);
571 TRACE("iface %p.\n", iface
);
573 enum_media_types
->index
= 0;
577 static HRESULT WINAPI
enum_media_types_Clone(IEnumMediaTypes
*iface
, IEnumMediaTypes
**out
)
579 struct enum_media_types
*enum_media_types
= impl_from_IEnumMediaTypes(iface
);
580 struct enum_media_types
*object
;
582 TRACE("iface %p, out %p.\n", iface
, out
);
584 if (!(object
= heap_alloc(sizeof(*object
))))
585 return E_OUTOFMEMORY
;
587 object
->IEnumMediaTypes_iface
.lpVtbl
= &enum_media_types_vtbl
;
588 object
->refcount
= 1;
589 object
->index
= enum_media_types
->index
;
591 *out
= &object
->IEnumMediaTypes_iface
;
595 static const IEnumMediaTypesVtbl enum_media_types_vtbl
=
597 enum_media_types_QueryInterface
,
598 enum_media_types_AddRef
,
599 enum_media_types_Release
,
600 enum_media_types_Next
,
601 enum_media_types_Skip
,
602 enum_media_types_Reset
,
603 enum_media_types_Clone
,
606 static inline struct ddraw_stream
*impl_from_IPin(IPin
*iface
)
608 return CONTAINING_RECORD(iface
, struct ddraw_stream
, IPin_iface
);
611 static HRESULT WINAPI
ddraw_sink_QueryInterface(IPin
*iface
, REFIID iid
, void **out
)
613 struct ddraw_stream
*stream
= impl_from_IPin(iface
);
614 return IAMMediaStream_QueryInterface(&stream
->IAMMediaStream_iface
, iid
, out
);
617 static ULONG WINAPI
ddraw_sink_AddRef(IPin
*iface
)
619 struct ddraw_stream
*stream
= impl_from_IPin(iface
);
620 return IAMMediaStream_AddRef(&stream
->IAMMediaStream_iface
);
623 static ULONG WINAPI
ddraw_sink_Release(IPin
*iface
)
625 struct ddraw_stream
*stream
= impl_from_IPin(iface
);
626 return IAMMediaStream_Release(&stream
->IAMMediaStream_iface
);
629 static HRESULT WINAPI
ddraw_sink_Connect(IPin
*iface
, IPin
*peer
, const AM_MEDIA_TYPE
*mt
)
631 WARN("iface %p, peer %p, mt %p, unexpected call!\n", iface
, peer
, mt
);
635 static HRESULT WINAPI
ddraw_sink_ReceiveConnection(IPin
*iface
, IPin
*peer
, const AM_MEDIA_TYPE
*mt
)
637 struct ddraw_stream
*stream
= impl_from_IPin(iface
);
640 TRACE("stream %p, peer %p, mt %p.\n", stream
, peer
, mt
);
642 EnterCriticalSection(&stream
->cs
);
646 LeaveCriticalSection(&stream
->cs
);
647 return VFW_E_ALREADY_CONNECTED
;
650 if (!IsEqualGUID(&mt
->majortype
, &MEDIATYPE_Video
)
651 || (!IsEqualGUID(&mt
->subtype
, &MEDIASUBTYPE_RGB8
)
652 && !IsEqualGUID(&mt
->subtype
, &MEDIASUBTYPE_RGB24
)
653 && !IsEqualGUID(&mt
->subtype
, &MEDIASUBTYPE_RGB32
)
654 && !IsEqualGUID(&mt
->subtype
, &MEDIASUBTYPE_RGB555
)
655 && !IsEqualGUID(&mt
->subtype
, &MEDIASUBTYPE_RGB565
))
656 || !IsEqualGUID(&mt
->formattype
, &FORMAT_VideoInfo
))
658 LeaveCriticalSection(&stream
->cs
);
659 return VFW_E_TYPE_NOT_ACCEPTED
;
662 IPin_QueryDirection(peer
, &dir
);
663 if (dir
!= PINDIR_OUTPUT
)
665 WARN("Rejecting connection from input pin.\n");
666 LeaveCriticalSection(&stream
->cs
);
667 return VFW_E_INVALID_DIRECTION
;
670 CopyMediaType(&stream
->mt
, mt
);
671 IPin_AddRef(stream
->peer
= peer
);
673 LeaveCriticalSection(&stream
->cs
);
678 static HRESULT WINAPI
ddraw_sink_Disconnect(IPin
*iface
)
680 struct ddraw_stream
*stream
= impl_from_IPin(iface
);
682 TRACE("stream %p.\n", stream
);
684 EnterCriticalSection(&stream
->cs
);
688 LeaveCriticalSection(&stream
->cs
);
692 IPin_Release(stream
->peer
);
694 FreeMediaType(&stream
->mt
);
695 memset(&stream
->mt
, 0, sizeof(AM_MEDIA_TYPE
));
697 LeaveCriticalSection(&stream
->cs
);
702 static HRESULT WINAPI
ddraw_sink_ConnectedTo(IPin
*iface
, IPin
**peer
)
704 struct ddraw_stream
*stream
= impl_from_IPin(iface
);
707 TRACE("stream %p, peer %p.\n", stream
, peer
);
709 EnterCriticalSection(&stream
->cs
);
713 IPin_AddRef(*peer
= stream
->peer
);
719 hr
= VFW_E_NOT_CONNECTED
;
722 LeaveCriticalSection(&stream
->cs
);
727 static HRESULT WINAPI
ddraw_sink_ConnectionMediaType(IPin
*iface
, AM_MEDIA_TYPE
*mt
)
729 struct ddraw_stream
*stream
= impl_from_IPin(iface
);
732 TRACE("stream %p, mt %p.\n", stream
, mt
);
734 EnterCriticalSection(&stream
->cs
);
738 CopyMediaType(mt
, &stream
->mt
);
743 memset(mt
, 0, sizeof(AM_MEDIA_TYPE
));
744 hr
= VFW_E_NOT_CONNECTED
;
747 LeaveCriticalSection(&stream
->cs
);
752 static HRESULT WINAPI
ddraw_sink_QueryPinInfo(IPin
*iface
, PIN_INFO
*info
)
754 struct ddraw_stream
*stream
= impl_from_IPin(iface
);
756 TRACE("stream %p, info %p.\n", stream
, info
);
758 IBaseFilter_AddRef(info
->pFilter
= (IBaseFilter
*)stream
->filter
);
759 info
->dir
= PINDIR_INPUT
;
760 wcscpy(info
->achName
, sink_id
);
765 static HRESULT WINAPI
ddraw_sink_QueryDirection(IPin
*iface
, PIN_DIRECTION
*dir
)
767 TRACE("iface %p, dir %p.\n", iface
, dir
);
772 static HRESULT WINAPI
ddraw_sink_QueryId(IPin
*iface
, WCHAR
**id
)
774 TRACE("iface %p, id %p.\n", iface
, id
);
776 if (!(*id
= CoTaskMemAlloc(sizeof(sink_id
))))
777 return E_OUTOFMEMORY
;
779 wcscpy(*id
, sink_id
);
784 static HRESULT WINAPI
ddraw_sink_QueryAccept(IPin
*iface
, const AM_MEDIA_TYPE
*mt
)
786 TRACE("iface %p, mt %p.\n", iface
, mt
);
788 if (IsEqualGUID(&mt
->majortype
, &MEDIATYPE_Video
)
789 && IsEqualGUID(&mt
->subtype
, &MEDIASUBTYPE_RGB8
)
790 && IsEqualGUID(&mt
->formattype
, &FORMAT_VideoInfo
))
793 return VFW_E_TYPE_NOT_ACCEPTED
;
796 static HRESULT WINAPI
ddraw_sink_EnumMediaTypes(IPin
*iface
, IEnumMediaTypes
**enum_media_types
)
798 struct enum_media_types
*object
;
800 TRACE("iface %p, enum_media_types %p.\n", iface
, enum_media_types
);
802 if (!enum_media_types
)
805 if (!(object
= heap_alloc(sizeof(*object
))))
806 return E_OUTOFMEMORY
;
808 object
->IEnumMediaTypes_iface
.lpVtbl
= &enum_media_types_vtbl
;
809 object
->refcount
= 1;
812 *enum_media_types
= &object
->IEnumMediaTypes_iface
;
816 static HRESULT WINAPI
ddraw_sink_QueryInternalConnections(IPin
*iface
, IPin
**pins
, ULONG
*count
)
818 TRACE("iface %p, pins %p, count %p.\n", iface
, pins
, count
);
822 static HRESULT WINAPI
ddraw_sink_EndOfStream(IPin
*iface
)
824 FIXME("iface %p, stub!\n", iface
);
828 static HRESULT WINAPI
ddraw_sink_BeginFlush(IPin
*iface
)
830 FIXME("iface %p, stub!\n", iface
);
834 static HRESULT WINAPI
ddraw_sink_EndFlush(IPin
*iface
)
836 FIXME("iface %p, stub!\n", iface
);
840 static HRESULT WINAPI
ddraw_sink_NewSegment(IPin
*iface
, REFERENCE_TIME start
, REFERENCE_TIME stop
, double rate
)
842 FIXME("iface %p, start %s, stop %s, rate %0.16e, stub!\n",
843 iface
, wine_dbgstr_longlong(start
), wine_dbgstr_longlong(stop
), rate
);
847 static const IPinVtbl ddraw_sink_vtbl
=
849 ddraw_sink_QueryInterface
,
853 ddraw_sink_ReceiveConnection
,
854 ddraw_sink_Disconnect
,
855 ddraw_sink_ConnectedTo
,
856 ddraw_sink_ConnectionMediaType
,
857 ddraw_sink_QueryPinInfo
,
858 ddraw_sink_QueryDirection
,
860 ddraw_sink_QueryAccept
,
861 ddraw_sink_EnumMediaTypes
,
862 ddraw_sink_QueryInternalConnections
,
863 ddraw_sink_EndOfStream
,
864 ddraw_sink_BeginFlush
,
866 ddraw_sink_NewSegment
,
869 static inline struct ddraw_stream
*impl_from_IMemInputPin(IMemInputPin
*iface
)
871 return CONTAINING_RECORD(iface
, struct ddraw_stream
, IMemInputPin_iface
);
874 static HRESULT WINAPI
ddraw_meminput_QueryInterface(IMemInputPin
*iface
, REFIID iid
, void **out
)
876 struct ddraw_stream
*stream
= impl_from_IMemInputPin(iface
);
877 return IAMMediaStream_QueryInterface(&stream
->IAMMediaStream_iface
, iid
, out
);
880 static ULONG WINAPI
ddraw_meminput_AddRef(IMemInputPin
*iface
)
882 struct ddraw_stream
*stream
= impl_from_IMemInputPin(iface
);
883 return IAMMediaStream_AddRef(&stream
->IAMMediaStream_iface
);
886 static ULONG WINAPI
ddraw_meminput_Release(IMemInputPin
*iface
)
888 struct ddraw_stream
*stream
= impl_from_IMemInputPin(iface
);
889 return IAMMediaStream_Release(&stream
->IAMMediaStream_iface
);
892 static HRESULT WINAPI
ddraw_meminput_GetAllocator(IMemInputPin
*iface
, IMemAllocator
**allocator
)
894 struct ddraw_stream
*stream
= impl_from_IMemInputPin(iface
);
896 TRACE("stream %p, allocator %p.\n", stream
, allocator
);
898 if (stream
->allocator
)
900 IMemAllocator_AddRef(*allocator
= stream
->allocator
);
905 return VFW_E_NO_ALLOCATOR
;
908 static HRESULT WINAPI
ddraw_meminput_NotifyAllocator(IMemInputPin
*iface
, IMemAllocator
*allocator
, BOOL readonly
)
910 struct ddraw_stream
*stream
= impl_from_IMemInputPin(iface
);
912 TRACE("stream %p, allocator %p, readonly %d.\n", stream
, allocator
, readonly
);
918 IMemAllocator_AddRef(allocator
);
919 if (stream
->allocator
)
920 IMemAllocator_Release(stream
->allocator
);
921 stream
->allocator
= allocator
;
926 static HRESULT WINAPI
ddraw_meminput_GetAllocatorRequirements(IMemInputPin
*iface
, ALLOCATOR_PROPERTIES
*props
)
928 TRACE("iface %p, props %p.\n", iface
, props
);
932 static HRESULT WINAPI
ddraw_meminput_Receive(IMemInputPin
*iface
, IMediaSample
*sample
)
934 FIXME("iface %p, sample %p, stub!\n", iface
, sample
);
938 static HRESULT WINAPI
ddraw_meminput_ReceiveMultiple(IMemInputPin
*iface
,
939 IMediaSample
**samples
, LONG count
, LONG
*processed
)
941 FIXME("iface %p, samples %p, count %u, processed %p, stub!\n", iface
, samples
, count
, processed
);
945 static HRESULT WINAPI
ddraw_meminput_ReceiveCanBlock(IMemInputPin
*iface
)
947 TRACE("iface %p.\n", iface
);
951 static const IMemInputPinVtbl ddraw_meminput_vtbl
=
953 ddraw_meminput_QueryInterface
,
954 ddraw_meminput_AddRef
,
955 ddraw_meminput_Release
,
956 ddraw_meminput_GetAllocator
,
957 ddraw_meminput_NotifyAllocator
,
958 ddraw_meminput_GetAllocatorRequirements
,
959 ddraw_meminput_Receive
,
960 ddraw_meminput_ReceiveMultiple
,
961 ddraw_meminput_ReceiveCanBlock
,
964 HRESULT
ddraw_stream_create(IUnknown
*outer
, void **out
)
966 struct ddraw_stream
*object
;
969 return CLASS_E_NOAGGREGATION
;
971 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
973 return E_OUTOFMEMORY
;
975 object
->IAMMediaStream_iface
.lpVtbl
= &ddraw_IAMMediaStream_vtbl
;
976 object
->IDirectDrawMediaStream_iface
.lpVtbl
= &ddraw_IDirectDrawMediaStream_Vtbl
;
977 object
->IMemInputPin_iface
.lpVtbl
= &ddraw_meminput_vtbl
;
978 object
->IPin_iface
.lpVtbl
= &ddraw_sink_vtbl
;
981 InitializeCriticalSection(&object
->cs
);
983 TRACE("Created ddraw stream %p.\n", object
);
985 *out
= &object
->IAMMediaStream_iface
;
992 IDirectDrawStreamSample IDirectDrawStreamSample_iface
;
994 struct ddraw_stream
*parent
;
995 IDirectDrawSurface
*surface
;
999 static inline struct ddraw_sample
*impl_from_IDirectDrawStreamSample(IDirectDrawStreamSample
*iface
)
1001 return CONTAINING_RECORD(iface
, struct ddraw_sample
, IDirectDrawStreamSample_iface
);
1004 /*** IUnknown methods ***/
1005 static HRESULT WINAPI
ddraw_sample_QueryInterface(IDirectDrawStreamSample
*iface
,
1006 REFIID riid
, void **ret_iface
)
1008 TRACE("(%p)->(%s,%p)\n", iface
, debugstr_guid(riid
), ret_iface
);
1010 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
1011 IsEqualGUID(riid
, &IID_IStreamSample
) ||
1012 IsEqualGUID(riid
, &IID_IDirectDrawStreamSample
))
1014 IDirectDrawStreamSample_AddRef(iface
);
1021 ERR("(%p)->(%s,%p),not found\n", iface
, debugstr_guid(riid
), ret_iface
);
1022 return E_NOINTERFACE
;
1025 static ULONG WINAPI
ddraw_sample_AddRef(IDirectDrawStreamSample
*iface
)
1027 struct ddraw_sample
*sample
= impl_from_IDirectDrawStreamSample(iface
);
1028 ULONG ref
= InterlockedIncrement(&sample
->ref
);
1030 TRACE("(%p)->(): new ref = %u\n", iface
, ref
);
1035 static ULONG WINAPI
ddraw_sample_Release(IDirectDrawStreamSample
*iface
)
1037 struct ddraw_sample
*sample
= impl_from_IDirectDrawStreamSample(iface
);
1038 ULONG ref
= InterlockedDecrement(&sample
->ref
);
1040 TRACE("(%p)->(): new ref = %u\n", iface
, ref
);
1044 EnterCriticalSection(&sample
->parent
->cs
);
1045 --sample
->parent
->sample_refs
;
1046 LeaveCriticalSection(&sample
->parent
->cs
);
1048 if (sample
->surface
)
1049 IDirectDrawSurface_Release(sample
->surface
);
1050 HeapFree(GetProcessHeap(), 0, sample
);
1056 /*** IStreamSample methods ***/
1057 static HRESULT WINAPI
ddraw_sample_GetMediaStream(IDirectDrawStreamSample
*iface
, IMediaStream
**media_stream
)
1059 struct ddraw_sample
*sample
= impl_from_IDirectDrawStreamSample(iface
);
1061 TRACE("sample %p, media_stream %p.\n", sample
, media_stream
);
1066 IAMMediaStream_AddRef(&sample
->parent
->IAMMediaStream_iface
);
1067 *media_stream
= (IMediaStream
*)&sample
->parent
->IAMMediaStream_iface
;
1072 static HRESULT WINAPI
ddraw_sample_GetSampleTimes(IDirectDrawStreamSample
*iface
, STREAM_TIME
*start_time
,
1073 STREAM_TIME
*end_time
, STREAM_TIME
*current_time
)
1075 FIXME("(%p)->(%p,%p,%p): stub\n", iface
, start_time
, end_time
, current_time
);
1080 static HRESULT WINAPI
ddraw_sample_SetSampleTimes(IDirectDrawStreamSample
*iface
, const STREAM_TIME
*start_time
,
1081 const STREAM_TIME
*end_time
)
1083 FIXME("(%p)->(%p,%p): stub\n", iface
, start_time
, end_time
);
1088 static HRESULT WINAPI
ddraw_sample_Update(IDirectDrawStreamSample
*iface
, DWORD flags
, HANDLE event
,
1089 PAPCFUNC func_APC
, DWORD APC_data
)
1091 FIXME("(%p)->(%x,%p,%p,%u): stub\n", iface
, flags
, event
, func_APC
, APC_data
);
1096 static HRESULT WINAPI
ddraw_sample_CompletionStatus(IDirectDrawStreamSample
*iface
, DWORD flags
, DWORD milliseconds
)
1098 FIXME("(%p)->(%x,%u): stub\n", iface
, flags
, milliseconds
);
1103 /*** IDirectDrawStreamSample methods ***/
1104 static HRESULT WINAPI
ddraw_sample_GetSurface(IDirectDrawStreamSample
*iface
, IDirectDrawSurface
**ddraw_surface
,
1107 struct ddraw_sample
*sample
= impl_from_IDirectDrawStreamSample(iface
);
1109 TRACE("(%p)->(%p,%p)\n", iface
, ddraw_surface
, rect
);
1113 *ddraw_surface
= sample
->surface
;
1115 IDirectDrawSurface_AddRef(*ddraw_surface
);
1119 *rect
= sample
->rect
;
1124 static HRESULT WINAPI
ddraw_sample_SetRect(IDirectDrawStreamSample
*iface
, const RECT
*rect
)
1126 FIXME("(%p)->(%p): stub\n", iface
, rect
);
1131 static const struct IDirectDrawStreamSampleVtbl DirectDrawStreamSample_Vtbl
=
1133 /*** IUnknown methods ***/
1134 ddraw_sample_QueryInterface
,
1135 ddraw_sample_AddRef
,
1136 ddraw_sample_Release
,
1137 /*** IStreamSample methods ***/
1138 ddraw_sample_GetMediaStream
,
1139 ddraw_sample_GetSampleTimes
,
1140 ddraw_sample_SetSampleTimes
,
1141 ddraw_sample_Update
,
1142 ddraw_sample_CompletionStatus
,
1143 /*** IDirectDrawStreamSample methods ***/
1144 ddraw_sample_GetSurface
,
1145 ddraw_sample_SetRect
1148 static HRESULT
ddrawstreamsample_create(struct ddraw_stream
*parent
, IDirectDrawSurface
*surface
,
1149 const RECT
*rect
, IDirectDrawStreamSample
**ddraw_stream_sample
)
1151 struct ddraw_sample
*object
;
1154 TRACE("(%p)\n", ddraw_stream_sample
);
1156 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
1158 return E_OUTOFMEMORY
;
1160 object
->IDirectDrawStreamSample_iface
.lpVtbl
= &DirectDrawStreamSample_Vtbl
;
1162 object
->parent
= parent
;
1163 ++parent
->sample_refs
;
1167 object
->surface
= surface
;
1168 IDirectDrawSurface_AddRef(surface
);
1175 hr
= IDirectDrawMediaStream_GetDirectDraw(&parent
->IDirectDrawMediaStream_iface
, &ddraw
);
1178 IDirectDrawStreamSample_Release(&object
->IDirectDrawStreamSample_iface
);
1182 desc
.dwSize
= sizeof(desc
);
1183 desc
.dwFlags
= DDSD_CAPS
|DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_PIXELFORMAT
;
1184 desc
.dwHeight
= 100;
1186 desc
.ddpfPixelFormat
.dwSize
= sizeof(desc
.ddpfPixelFormat
);
1187 desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
1188 desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
= 32;
1189 desc
.ddpfPixelFormat
.u2
.dwRBitMask
= 0xff0000;
1190 desc
.ddpfPixelFormat
.u3
.dwGBitMask
= 0x00ff00;
1191 desc
.ddpfPixelFormat
.u4
.dwBBitMask
= 0x0000ff;
1192 desc
.ddpfPixelFormat
.u5
.dwRGBAlphaBitMask
= 0;
1193 desc
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
|DDSCAPS_OFFSCREENPLAIN
;
1194 desc
.lpSurface
= NULL
;
1196 hr
= IDirectDraw_CreateSurface(ddraw
, &desc
, &object
->surface
, NULL
);
1197 IDirectDraw_Release(ddraw
);
1200 ERR("failed to create surface, 0x%08x\n", hr
);
1201 IDirectDrawStreamSample_Release(&object
->IDirectDrawStreamSample_iface
);
1207 object
->rect
= *rect
;
1208 else if (object
->surface
)
1210 DDSURFACEDESC desc
= { sizeof(desc
) };
1211 hr
= IDirectDrawSurface_GetSurfaceDesc(object
->surface
, &desc
);
1213 SetRect(&object
->rect
, 0, 0, desc
.dwWidth
, desc
.dwHeight
);
1216 *ddraw_stream_sample
= &object
->IDirectDrawStreamSample_iface
;