2 * Copyright 2020 Nikolay Sivov
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
27 #include "evr_classes.h"
32 #include "wine/debug.h"
33 #include "wine/heap.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(evr
);
37 #define MAX_MIXER_INPUT_STREAMS 16
42 IMFAttributes
*attributes
;
43 IMFMediaType
*media_type
;
44 MFVideoNormalizedRect rect
;
53 IMFMediaType
*media_type
;
58 IMFMediaType
*media_type
;
59 struct rt_format
*rt_formats
;
60 unsigned int rt_formats_count
;
65 IMFTransform IMFTransform_iface
;
66 IMFVideoDeviceID IMFVideoDeviceID_iface
;
67 IMFTopologyServiceLookupClient IMFTopologyServiceLookupClient_iface
;
68 IMFVideoMixerControl2 IMFVideoMixerControl2_iface
;
69 IMFGetService IMFGetService_iface
;
70 IMFVideoMixerBitmap IMFVideoMixerBitmap_iface
;
71 IMFVideoPositionMapper IMFVideoPositionMapper_iface
;
72 IMFVideoProcessor IMFVideoProcessor_iface
;
73 IMFAttributes IMFAttributes_iface
;
74 IMFQualityAdvise IMFQualityAdvise_iface
;
75 IUnknown IUnknown_inner
;
79 struct input_stream inputs
[MAX_MIXER_INPUT_STREAMS
];
80 unsigned int input_ids
[MAX_MIXER_INPUT_STREAMS
];
81 unsigned int input_count
;
82 struct output_stream output
;
84 IDirect3DDeviceManager9
*device_manager
;
85 IDirectXVideoProcessor
*processor
;
88 IMediaEventSink
*event_sink
;
89 IMFAttributes
*attributes
;
90 IMFAttributes
*internal_attributes
;
91 unsigned int mixing_flags
;
92 unsigned int is_streaming
;
99 static struct video_mixer
*impl_from_IUnknown(IUnknown
*iface
)
101 return CONTAINING_RECORD(iface
, struct video_mixer
, IUnknown_inner
);
104 static struct video_mixer
*impl_from_IMFTransform(IMFTransform
*iface
)
106 return CONTAINING_RECORD(iface
, struct video_mixer
, IMFTransform_iface
);
109 static struct video_mixer
*impl_from_IMFVideoDeviceID(IMFVideoDeviceID
*iface
)
111 return CONTAINING_RECORD(iface
, struct video_mixer
, IMFVideoDeviceID_iface
);
114 static struct video_mixer
*impl_from_IMFTopologyServiceLookupClient(IMFTopologyServiceLookupClient
*iface
)
116 return CONTAINING_RECORD(iface
, struct video_mixer
, IMFTopologyServiceLookupClient_iface
);
119 static struct video_mixer
*impl_from_IMFVideoMixerControl2(IMFVideoMixerControl2
*iface
)
121 return CONTAINING_RECORD(iface
, struct video_mixer
, IMFVideoMixerControl2_iface
);
124 static struct video_mixer
*impl_from_IMFGetService(IMFGetService
*iface
)
126 return CONTAINING_RECORD(iface
, struct video_mixer
, IMFGetService_iface
);
129 static struct video_mixer
*impl_from_IMFVideoMixerBitmap(IMFVideoMixerBitmap
*iface
)
131 return CONTAINING_RECORD(iface
, struct video_mixer
, IMFVideoMixerBitmap_iface
);
134 static struct video_mixer
*impl_from_IMFVideoPositionMapper(IMFVideoPositionMapper
*iface
)
136 return CONTAINING_RECORD(iface
, struct video_mixer
, IMFVideoPositionMapper_iface
);
139 static struct video_mixer
*impl_from_IMFVideoProcessor(IMFVideoProcessor
*iface
)
141 return CONTAINING_RECORD(iface
, struct video_mixer
, IMFVideoProcessor_iface
);
144 static struct video_mixer
*impl_from_IMFAttributes(IMFAttributes
*iface
)
146 return CONTAINING_RECORD(iface
, struct video_mixer
, IMFAttributes_iface
);
149 static struct video_mixer
*impl_from_IMFQualityAdvise(IMFQualityAdvise
*iface
)
151 return CONTAINING_RECORD(iface
, struct video_mixer
, IMFQualityAdvise_iface
);
154 static int video_mixer_compare_input_id(const void *a
, const void *b
)
156 const unsigned int *key
= a
;
157 const struct input_stream
*input
= b
;
159 if (*key
> input
->id
) return 1;
160 if (*key
< input
->id
) return -1;
164 static HRESULT
video_mixer_get_input(const struct video_mixer
*mixer
, unsigned int id
, struct input_stream
**stream
)
166 *stream
= bsearch(&id
, mixer
->inputs
, mixer
->input_count
, sizeof(*mixer
->inputs
), video_mixer_compare_input_id
);
167 return *stream
? S_OK
: MF_E_INVALIDSTREAMNUMBER
;
170 static void video_mixer_init_input(struct input_stream
*stream
)
172 if (SUCCEEDED(MFCreateAttributes(&stream
->attributes
, 1)))
173 IMFAttributes_SetUINT32(stream
->attributes
, &MF_SA_REQUIRED_SAMPLE_COUNT
, 1);
174 stream
->rect
.left
= stream
->rect
.top
= 0.0f
;
175 stream
->rect
.right
= stream
->rect
.bottom
= 1.0f
;
178 static void video_mixer_clear_types(struct video_mixer
*mixer
)
182 for (i
= 0; i
< mixer
->input_count
; ++i
)
184 if (mixer
->inputs
[i
].media_type
)
185 IMFMediaType_Release(mixer
->inputs
[i
].media_type
);
186 mixer
->inputs
[i
].media_type
= NULL
;
187 if (mixer
->inputs
[i
].sample
)
188 IMFSample_Release(mixer
->inputs
[i
].sample
);
189 mixer
->inputs
[i
].sample
= NULL
;
191 for (i
= 0; i
< mixer
->output
.rt_formats_count
; ++i
)
193 IMFMediaType_Release(mixer
->output
.rt_formats
[i
].media_type
);
195 heap_free(mixer
->output
.rt_formats
);
196 if (mixer
->output
.media_type
)
197 IMFMediaType_Release(mixer
->output
.media_type
);
198 mixer
->output
.media_type
= NULL
;
201 static HRESULT WINAPI
video_mixer_inner_QueryInterface(IUnknown
*iface
, REFIID riid
, void **obj
)
203 struct video_mixer
*mixer
= impl_from_IUnknown(iface
);
205 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
207 if (IsEqualIID(riid
, &IID_IUnknown
))
211 else if (IsEqualIID(riid
, &IID_IMFTransform
))
213 *obj
= &mixer
->IMFTransform_iface
;
215 else if (IsEqualIID(riid
, &IID_IMFVideoDeviceID
))
217 *obj
= &mixer
->IMFVideoDeviceID_iface
;
219 else if (IsEqualIID(riid
, &IID_IMFTopologyServiceLookupClient
))
221 *obj
= &mixer
->IMFTopologyServiceLookupClient_iface
;
223 else if (IsEqualIID(riid
, &IID_IMFVideoMixerControl2
) ||
224 IsEqualIID(riid
, &IID_IMFVideoMixerControl
))
226 *obj
= &mixer
->IMFVideoMixerControl2_iface
;
228 else if (IsEqualIID(riid
, &IID_IMFGetService
))
230 *obj
= &mixer
->IMFGetService_iface
;
232 else if (IsEqualIID(riid
, &IID_IMFVideoMixerBitmap
))
234 *obj
= &mixer
->IMFVideoMixerBitmap_iface
;
236 else if (IsEqualIID(riid
, &IID_IMFVideoPositionMapper
))
238 *obj
= &mixer
->IMFVideoPositionMapper_iface
;
240 else if (IsEqualIID(riid
, &IID_IMFVideoProcessor
))
242 *obj
= &mixer
->IMFVideoProcessor_iface
;
244 else if (IsEqualIID(riid
, &IID_IMFAttributes
))
246 *obj
= &mixer
->IMFAttributes_iface
;
248 else if (IsEqualIID(riid
, &IID_IMFQualityAdvise
))
250 *obj
= &mixer
->IMFQualityAdvise_iface
;
254 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
256 return E_NOINTERFACE
;
259 IUnknown_AddRef((IUnknown
*)*obj
);
263 static ULONG WINAPI
video_mixer_inner_AddRef(IUnknown
*iface
)
265 struct video_mixer
*mixer
= impl_from_IUnknown(iface
);
266 ULONG refcount
= InterlockedIncrement(&mixer
->refcount
);
268 TRACE("%p, refcount %u.\n", iface
, refcount
);
273 static void video_mixer_release_device_manager(struct video_mixer
*mixer
)
275 if (mixer
->processor
)
276 IDirectXVideoProcessor_Release(mixer
->processor
);
277 if (mixer
->device_manager
)
279 IDirect3DDeviceManager9_CloseDeviceHandle(mixer
->device_manager
, mixer
->device_handle
);
280 IDirect3DDeviceManager9_Release(mixer
->device_manager
);
282 mixer
->device_handle
= NULL
;
283 mixer
->device_manager
= NULL
;
284 mixer
->processor
= NULL
;
287 static ULONG WINAPI
video_mixer_inner_Release(IUnknown
*iface
)
289 struct video_mixer
*mixer
= impl_from_IUnknown(iface
);
290 ULONG refcount
= InterlockedDecrement(&mixer
->refcount
);
293 TRACE("%p, refcount %u.\n", iface
, refcount
);
297 for (i
= 0; i
< mixer
->input_count
; ++i
)
299 if (mixer
->inputs
[i
].attributes
)
300 IMFAttributes_Release(mixer
->inputs
[i
].attributes
);
302 video_mixer_clear_types(mixer
);
303 video_mixer_release_device_manager(mixer
);
304 if (mixer
->attributes
)
305 IMFAttributes_Release(mixer
->attributes
);
306 if (mixer
->internal_attributes
)
307 IMFAttributes_Release(mixer
->internal_attributes
);
308 DeleteCriticalSection(&mixer
->cs
);
315 static const IUnknownVtbl video_mixer_inner_vtbl
=
317 video_mixer_inner_QueryInterface
,
318 video_mixer_inner_AddRef
,
319 video_mixer_inner_Release
,
322 static HRESULT WINAPI
video_mixer_transform_QueryInterface(IMFTransform
*iface
, REFIID riid
, void **obj
)
324 struct video_mixer
*mixer
= impl_from_IMFTransform(iface
);
325 return IUnknown_QueryInterface(mixer
->outer_unk
, riid
, obj
);
328 static ULONG WINAPI
video_mixer_transform_AddRef(IMFTransform
*iface
)
330 struct video_mixer
*mixer
= impl_from_IMFTransform(iface
);
331 return IUnknown_AddRef(mixer
->outer_unk
);
334 static ULONG WINAPI
video_mixer_transform_Release(IMFTransform
*iface
)
336 struct video_mixer
*mixer
= impl_from_IMFTransform(iface
);
337 return IUnknown_Release(mixer
->outer_unk
);
340 static HRESULT WINAPI
video_mixer_transform_GetStreamLimits(IMFTransform
*iface
, DWORD
*input_minimum
,
341 DWORD
*input_maximum
, DWORD
*output_minimum
, DWORD
*output_maximum
)
343 TRACE("%p, %p, %p, %p, %p.\n", iface
, input_minimum
, input_maximum
, output_minimum
, output_maximum
);
346 *input_maximum
= MAX_MIXER_INPUT_STREAMS
;
353 static HRESULT WINAPI
video_mixer_transform_GetStreamCount(IMFTransform
*iface
, DWORD
*inputs
, DWORD
*outputs
)
355 struct video_mixer
*mixer
= impl_from_IMFTransform(iface
);
357 TRACE("%p, %p, %p.\n", iface
, inputs
, outputs
);
359 EnterCriticalSection(&mixer
->cs
);
360 if (inputs
) *inputs
= mixer
->input_count
;
361 if (outputs
) *outputs
= 1;
362 LeaveCriticalSection(&mixer
->cs
);
367 static HRESULT WINAPI
video_mixer_transform_GetStreamIDs(IMFTransform
*iface
, DWORD input_size
, DWORD
*inputs
,
368 DWORD output_size
, DWORD
*outputs
)
370 struct video_mixer
*mixer
= impl_from_IMFTransform(iface
);
373 TRACE("%p, %u, %p, %u, %p.\n", iface
, input_size
, inputs
, output_size
, outputs
);
375 EnterCriticalSection(&mixer
->cs
);
376 if (mixer
->input_count
> input_size
|| !output_size
)
377 hr
= MF_E_BUFFERTOOSMALL
;
379 memcpy(inputs
, mixer
->input_ids
, mixer
->input_count
* sizeof(*inputs
));
380 if (outputs
) *outputs
= 0;
381 LeaveCriticalSection(&mixer
->cs
);
386 static HRESULT WINAPI
video_mixer_transform_GetInputStreamInfo(IMFTransform
*iface
, DWORD id
, MFT_INPUT_STREAM_INFO
*info
)
388 struct video_mixer
*mixer
= impl_from_IMFTransform(iface
);
389 struct input_stream
*input
;
392 TRACE("%p, %u, %p.\n", iface
, id
, info
);
394 EnterCriticalSection(&mixer
->cs
);
396 if (SUCCEEDED(hr
= video_mixer_get_input(mixer
, id
, &input
)))
398 memset(info
, 0, sizeof(*info
));
400 info
->dwFlags
|= MFT_INPUT_STREAM_REMOVABLE
| MFT_INPUT_STREAM_OPTIONAL
;
403 LeaveCriticalSection(&mixer
->cs
);
408 static HRESULT WINAPI
video_mixer_transform_GetOutputStreamInfo(IMFTransform
*iface
, DWORD id
, MFT_OUTPUT_STREAM_INFO
*info
)
410 TRACE("%p, %u, %p.\n", iface
, id
, info
);
413 return MF_E_INVALIDSTREAMNUMBER
;
415 memset(info
, 0, sizeof(*info
));
420 static HRESULT WINAPI
video_mixer_transform_GetAttributes(IMFTransform
*iface
, IMFAttributes
**attributes
)
422 struct video_mixer
*mixer
= impl_from_IMFTransform(iface
);
424 TRACE("%p, %p.\n", iface
, attributes
);
429 *attributes
= mixer
->attributes
;
430 IMFAttributes_AddRef(*attributes
);
435 static HRESULT WINAPI
video_mixer_transform_GetInputStreamAttributes(IMFTransform
*iface
, DWORD id
,
436 IMFAttributes
**attributes
)
438 struct video_mixer
*mixer
= impl_from_IMFTransform(iface
);
439 struct input_stream
*input
;
442 TRACE("%p, %u, %p.\n", iface
, id
, attributes
);
444 EnterCriticalSection(&mixer
->cs
);
446 if (SUCCEEDED(hr
= video_mixer_get_input(mixer
, id
, &input
)))
448 *attributes
= input
->attributes
;
450 IMFAttributes_AddRef(*attributes
);
453 LeaveCriticalSection(&mixer
->cs
);
458 static HRESULT WINAPI
video_mixer_transform_GetOutputStreamAttributes(IMFTransform
*iface
, DWORD id
,
459 IMFAttributes
**attributes
)
461 TRACE("%p, %u, %p.\n", iface
, id
, attributes
);
466 static HRESULT WINAPI
video_mixer_transform_DeleteInputStream(IMFTransform
*iface
, DWORD id
)
468 struct video_mixer
*mixer
= impl_from_IMFTransform(iface
);
469 struct input_stream
*input
;
473 TRACE("%p, %u.\n", iface
, id
);
476 return MF_E_INVALIDSTREAMNUMBER
;
478 EnterCriticalSection(&mixer
->cs
);
480 /* Can't delete reference stream. */
481 if (SUCCEEDED(hr
= video_mixer_get_input(mixer
, id
, &input
)))
483 mixer
->input_count
--;
484 idx
= input
- mixer
->inputs
;
485 if (idx
< mixer
->input_count
)
487 if (mixer
->inputs
[idx
].attributes
)
488 IMFAttributes_Release(mixer
->inputs
[idx
].attributes
);
489 memmove(&mixer
->inputs
[idx
], &mixer
->inputs
[idx
+ 1], (mixer
->input_count
- idx
) * sizeof(*mixer
->inputs
));
490 memmove(&mixer
->input_ids
[idx
], &mixer
->input_ids
[idx
+ 1], (mixer
->input_count
- idx
) *
491 sizeof(*mixer
->input_ids
));
495 LeaveCriticalSection(&mixer
->cs
);
500 static int video_mixer_add_input_sort_compare(const void *a
, const void *b
)
502 const struct input_stream
*left
= a
, *right
= b
;
503 return left
->id
!= right
->id
? (left
->id
< right
->id
? -1 : 1) : 0;
506 static HRESULT WINAPI
video_mixer_transform_AddInputStreams(IMFTransform
*iface
, DWORD count
, DWORD
*ids
)
508 struct video_mixer
*mixer
= impl_from_IMFTransform(iface
);
509 struct input_stream inputs
[MAX_MIXER_INPUT_STREAMS
] = { {0} };
510 struct input_stream
*input
;
514 TRACE("%p, %u, %p.\n", iface
, count
, ids
);
519 EnterCriticalSection(&mixer
->cs
);
520 if (count
> ARRAY_SIZE(mixer
->inputs
) - mixer
->input_count
)
524 /* Test for collisions. */
525 memcpy(inputs
, mixer
->inputs
, mixer
->input_count
* sizeof(*inputs
));
526 for (i
= 0; i
< count
; ++i
)
527 inputs
[i
+ mixer
->input_count
].id
= ids
[i
];
529 len
= mixer
->input_count
+ count
;
531 qsort(inputs
, len
, sizeof(*inputs
), video_mixer_add_input_sort_compare
);
533 for (i
= 1; i
< len
; ++i
)
535 if (inputs
[i
- 1].id
== inputs
[i
].id
)
544 unsigned int zorder
= mixer
->input_count
;
546 for (i
= 0; i
< count
; ++i
)
548 if ((input
= bsearch(&ids
[i
], inputs
, len
, sizeof(*inputs
), video_mixer_compare_input_id
)))
549 video_mixer_init_input(input
);
551 memcpy(&mixer
->input_ids
[mixer
->input_count
], ids
, count
* sizeof(*ids
));
552 memcpy(mixer
->inputs
, inputs
, len
* sizeof(*inputs
));
553 mixer
->input_count
+= count
;
555 for (i
= 0; i
< count
; ++i
)
557 if (SUCCEEDED(video_mixer_get_input(mixer
, ids
[i
], &input
)))
558 input
->zorder
= zorder
;
563 LeaveCriticalSection(&mixer
->cs
);
568 static HRESULT WINAPI
video_mixer_transform_GetInputAvailableType(IMFTransform
*iface
, DWORD id
, DWORD index
,
571 TRACE("%p, %u, %u, %p.\n", iface
, id
, index
, type
);
576 static HRESULT WINAPI
video_mixer_transform_GetOutputAvailableType(IMFTransform
*iface
, DWORD id
, DWORD index
,
579 struct video_mixer
*mixer
= impl_from_IMFTransform(iface
);
582 TRACE("%p, %u, %u, %p.\n", iface
, id
, index
, type
);
585 return MF_E_INVALIDSTREAMNUMBER
;
587 EnterCriticalSection(&mixer
->cs
);
589 if (!mixer
->inputs
[0].media_type
)
590 hr
= MF_E_TRANSFORM_TYPE_NOT_SET
;
591 else if (index
>= mixer
->output
.rt_formats_count
)
592 hr
= MF_E_NO_MORE_TYPES
;
595 *type
= mixer
->output
.rt_formats
[index
].media_type
;
596 IMFMediaType_AddRef(*type
);
599 LeaveCriticalSection(&mixer
->cs
);
604 static HRESULT
video_mixer_init_dxva_videodesc(IMFMediaType
*media_type
, DXVA2_VideoDesc
*video_desc
)
606 const MFVIDEOFORMAT
*video_format
;
607 IMFVideoMediaType
*video_type
;
608 BOOL is_compressed
= TRUE
;
611 if (FAILED(IMFMediaType_QueryInterface(media_type
, &IID_IMFVideoMediaType
, (void **)&video_type
)))
612 return MF_E_INVALIDMEDIATYPE
;
614 video_format
= IMFVideoMediaType_GetVideoFormat(video_type
);
615 IMFVideoMediaType_IsCompressedFormat(video_type
, &is_compressed
);
617 if (!video_format
|| !video_format
->videoInfo
.dwWidth
|| !video_format
->videoInfo
.dwHeight
|| is_compressed
)
619 hr
= MF_E_INVALIDMEDIATYPE
;
623 memset(video_desc
, 0, sizeof(*video_desc
));
624 video_desc
->SampleWidth
= video_format
->videoInfo
.dwWidth
;
625 video_desc
->SampleHeight
= video_format
->videoInfo
.dwHeight
;
626 video_desc
->Format
= video_format
->surfaceInfo
.Format
;
629 IMFVideoMediaType_Release(video_type
);
634 static int rt_formats_sort_compare(const void *left
, const void *right
)
636 const struct rt_format
*format1
= left
, *format2
= right
;
638 if (format1
->format
< format2
->format
) return -1;
639 if (format1
->format
> format2
->format
) return 1;
643 static HRESULT
video_mixer_collect_output_types(struct video_mixer
*mixer
, const DXVA2_VideoDesc
*video_desc
,
644 IDirectXVideoProcessorService
*service
, unsigned int device_count
, const GUID
*devices
, unsigned int flags
)
646 unsigned int i
, j
, format_count
, count
;
647 struct rt_format
*rt_formats
= NULL
, *ptr
;
648 HRESULT hr
= MF_E_INVALIDMEDIATYPE
;
653 for (i
= 0; i
< device_count
; ++i
)
655 if (SUCCEEDED(IDirectXVideoProcessorService_GetVideoProcessorRenderTargets(service
, &devices
[i
], video_desc
,
656 &format_count
, &formats
)))
658 if (!(ptr
= heap_realloc(rt_formats
, (count
+ format_count
) * sizeof(*rt_formats
))))
662 CoTaskMemFree(formats
);
667 for (j
= 0; j
< format_count
; ++j
)
669 rt_formats
[count
+ j
].format
= formats
[j
];
670 rt_formats
[count
+ j
].device
= devices
[i
];
672 count
+= format_count
;
674 CoTaskMemFree(formats
);
678 if (count
&& !(flags
& MFT_SET_TYPE_TEST_ONLY
))
680 qsort(rt_formats
, count
, sizeof(*rt_formats
), rt_formats_sort_compare
);
683 for (i
= j
+ 1; i
< count
; ++i
)
685 if (rt_formats
[i
].format
!= rt_formats
[j
].format
)
687 rt_formats
[++j
] = rt_formats
[i
];
692 memcpy(&subtype
, &MFVideoFormat_Base
, sizeof(subtype
));
693 if ((mixer
->output
.rt_formats
= heap_calloc(count
, sizeof(*mixer
->output
.rt_formats
))))
695 for (i
= 0; i
< count
; ++i
)
697 subtype
.Data1
= rt_formats
[i
].format
;
698 mixer
->output
.rt_formats
[i
] = rt_formats
[i
];
699 MFCreateVideoMediaTypeFromSubtype(&subtype
, (IMFVideoMediaType
**)&mixer
->output
.rt_formats
[i
].media_type
);
701 mixer
->output
.rt_formats_count
= count
;
710 heap_free(rt_formats
);
712 return count
? S_OK
: hr
;
715 static HRESULT
video_mixer_get_processor_service(struct video_mixer
*mixer
, IDirectXVideoProcessorService
**service
)
719 if (!mixer
->device_handle
)
721 if (FAILED(hr
= IDirect3DDeviceManager9_OpenDeviceHandle(mixer
->device_manager
, &mixer
->device_handle
)))
727 hr
= IDirect3DDeviceManager9_GetVideoService(mixer
->device_manager
, mixer
->device_handle
,
728 &IID_IDirectXVideoProcessorService
, (void **)service
);
729 if (hr
== DXVA2_E_NEW_VIDEO_DEVICE
)
731 IDirect3DDeviceManager9_CloseDeviceHandle(mixer
->device_manager
, mixer
->device_handle
);
732 mixer
->device_handle
= NULL
;
733 if (SUCCEEDED(hr
= IDirect3DDeviceManager9_OpenDeviceHandle(mixer
->device_manager
, &mixer
->device_handle
)))
742 static HRESULT WINAPI
video_mixer_transform_SetInputType(IMFTransform
*iface
, DWORD id
, IMFMediaType
*media_type
, DWORD flags
)
744 struct video_mixer
*mixer
= impl_from_IMFTransform(iface
);
745 IDirectXVideoProcessorService
*service
;
746 DXVA2_VideoDesc video_desc
;
747 HRESULT hr
= E_NOTIMPL
;
751 TRACE("%p, %u, %p, %#x.\n", iface
, id
, media_type
, flags
);
753 EnterCriticalSection(&mixer
->cs
);
755 if (!(flags
& MFT_SET_TYPE_TEST_ONLY
))
756 video_mixer_clear_types(mixer
);
758 if (!mixer
->device_manager
)
759 hr
= MF_E_NOT_INITIALIZED
;
762 if (SUCCEEDED(hr
= video_mixer_get_processor_service(mixer
, &service
)))
764 if (SUCCEEDED(hr
= video_mixer_init_dxva_videodesc(media_type
, &video_desc
)))
768 if (SUCCEEDED(hr
= IDirectXVideoProcessorService_GetVideoProcessorDeviceGuids(service
, &video_desc
,
771 if (SUCCEEDED(hr
= video_mixer_collect_output_types(mixer
, &video_desc
, service
, count
,
772 guids
, flags
)) && !(flags
& MFT_SET_TYPE_TEST_ONLY
))
774 if (mixer
->inputs
[0].media_type
)
775 IMFMediaType_Release(mixer
->inputs
[0].media_type
);
776 mixer
->inputs
[0].media_type
= media_type
;
777 IMFMediaType_AddRef(mixer
->inputs
[0].media_type
);
779 CoTaskMemFree(guids
);
784 FIXME("Unimplemented for substreams.\n");
788 IDirectXVideoProcessorService_Release(service
);
792 LeaveCriticalSection(&mixer
->cs
);
797 static HRESULT WINAPI
video_mixer_transform_SetOutputType(IMFTransform
*iface
, DWORD id
, IMFMediaType
*type
, DWORD flags
)
799 const unsigned int equality_flags
= MF_MEDIATYPE_EQUAL_MAJOR_TYPES
|
800 MF_MEDIATYPE_EQUAL_FORMAT_TYPES
| MF_MEDIATYPE_EQUAL_FORMAT_DATA
;
801 struct video_mixer
*mixer
= impl_from_IMFTransform(iface
);
802 HRESULT hr
= MF_E_INVALIDMEDIATYPE
;
803 unsigned int i
, compare_flags
;
805 TRACE("%p, %u, %p, %#x.\n", iface
, id
, type
, flags
);
808 return MF_E_INVALIDSTREAMNUMBER
;
810 EnterCriticalSection(&mixer
->cs
);
812 for (i
= 0; i
< mixer
->output
.rt_formats_count
; ++i
)
815 if (FAILED(IMFMediaType_IsEqual(type
, mixer
->output
.rt_formats
[i
].media_type
, &compare_flags
)))
818 if ((compare_flags
& equality_flags
) == equality_flags
)
825 if (SUCCEEDED(hr
) && !(flags
& MFT_SET_TYPE_TEST_ONLY
))
827 IDirectXVideoProcessorService
*service
;
829 if (SUCCEEDED(hr
= video_mixer_get_processor_service(mixer
, &service
)))
831 DXVA2_VideoDesc video_desc
;
832 GUID subtype
= { 0 };
835 if (mixer
->processor
)
836 IDirectXVideoProcessor_Release(mixer
->processor
);
837 mixer
->processor
= NULL
;
839 video_mixer_init_dxva_videodesc(mixer
->inputs
[0].media_type
, &video_desc
);
840 IMFMediaType_GetGUID(type
, &MF_MT_SUBTYPE
, &subtype
);
841 rt_format
= subtype
.Data1
;
843 if (SUCCEEDED(hr
= IDirectXVideoProcessorService_CreateVideoProcessor(service
, &mixer
->output
.rt_formats
[i
].device
,
844 &video_desc
, rt_format
, MAX_MIXER_INPUT_STREAMS
, &mixer
->processor
)))
846 if (mixer
->output
.media_type
)
847 IMFMediaType_Release(mixer
->output
.media_type
);
848 mixer
->output
.media_type
= type
;
849 IMFMediaType_AddRef(mixer
->output
.media_type
);
852 IDirectXVideoProcessorService_Release(service
);
856 LeaveCriticalSection(&mixer
->cs
);
861 static HRESULT WINAPI
video_mixer_transform_GetInputCurrentType(IMFTransform
*iface
, DWORD id
, IMFMediaType
**type
)
863 struct video_mixer
*mixer
= impl_from_IMFTransform(iface
);
864 struct input_stream
*stream
;
867 TRACE("%p, %u, %p.\n", iface
, id
, type
);
869 EnterCriticalSection(&mixer
->cs
);
871 if (SUCCEEDED(hr
= video_mixer_get_input(mixer
, id
, &stream
)))
873 if (!stream
->media_type
)
874 hr
= MF_E_TRANSFORM_TYPE_NOT_SET
;
877 *type
= (IMFMediaType
*)stream
->media_type
;
878 IMFMediaType_AddRef(*type
);
882 LeaveCriticalSection(&mixer
->cs
);
887 static HRESULT WINAPI
video_mixer_transform_GetOutputCurrentType(IMFTransform
*iface
, DWORD id
, IMFMediaType
**type
)
889 struct video_mixer
*mixer
= impl_from_IMFTransform(iface
);
892 TRACE("%p, %u, %p.\n", iface
, id
, type
);
895 return MF_E_INVALIDSTREAMNUMBER
;
897 EnterCriticalSection(&mixer
->cs
);
899 if (!mixer
->output
.media_type
)
900 hr
= MF_E_TRANSFORM_TYPE_NOT_SET
;
903 *type
= (IMFMediaType
*)mixer
->output
.media_type
;
904 IMFMediaType_AddRef(*type
);
907 LeaveCriticalSection(&mixer
->cs
);
912 static HRESULT WINAPI
video_mixer_transform_GetInputStatus(IMFTransform
*iface
, DWORD id
, DWORD
*flags
)
914 FIXME("%p, %u, %p.\n", iface
, id
, flags
);
919 static HRESULT WINAPI
video_mixer_transform_GetOutputStatus(IMFTransform
*iface
, DWORD
*flags
)
921 FIXME("%p, %p.\n", iface
, flags
);
926 static HRESULT WINAPI
video_mixer_transform_SetOutputBounds(IMFTransform
*iface
, LONGLONG lower
, LONGLONG upper
)
928 struct video_mixer
*mixer
= impl_from_IMFTransform(iface
);
930 TRACE("%p, %s, %s.\n", iface
, wine_dbgstr_longlong(lower
), wine_dbgstr_longlong(upper
));
932 EnterCriticalSection(&mixer
->cs
);
934 mixer
->lower_bound
= lower
;
935 mixer
->upper_bound
= upper
;
937 LeaveCriticalSection(&mixer
->cs
);
942 static HRESULT WINAPI
video_mixer_transform_ProcessEvent(IMFTransform
*iface
, DWORD id
, IMFMediaEvent
*event
)
944 FIXME("%p, %u, %p.\n", iface
, id
, event
);
949 static HRESULT WINAPI
video_mixer_transform_ProcessMessage(IMFTransform
*iface
, MFT_MESSAGE_TYPE message
, ULONG_PTR param
)
951 struct video_mixer
*mixer
= impl_from_IMFTransform(iface
);
955 TRACE("%p, %u, %#lx.\n", iface
, message
, param
);
959 case MFT_MESSAGE_SET_D3D_MANAGER
:
961 EnterCriticalSection(&mixer
->cs
);
963 video_mixer_release_device_manager(mixer
);
965 hr
= IUnknown_QueryInterface((IUnknown
*)param
, &IID_IDirect3DDeviceManager9
, (void **)&mixer
->device_manager
);
967 LeaveCriticalSection(&mixer
->cs
);
971 case MFT_MESSAGE_COMMAND_FLUSH
:
973 EnterCriticalSection(&mixer
->cs
);
975 for (i
= 0; i
< mixer
->input_count
; ++i
)
977 if (mixer
->inputs
[i
].sample
)
979 IMFSample_Release(mixer
->inputs
[i
].sample
);
980 mixer
->inputs
[i
].sample
= NULL
;
984 LeaveCriticalSection(&mixer
->cs
);
988 case MFT_MESSAGE_NOTIFY_BEGIN_STREAMING
:
989 case MFT_MESSAGE_NOTIFY_END_STREAMING
:
991 EnterCriticalSection(&mixer
->cs
);
993 mixer
->is_streaming
= message
== MFT_MESSAGE_NOTIFY_BEGIN_STREAMING
;
995 LeaveCriticalSection(&mixer
->cs
);
999 case MFT_MESSAGE_COMMAND_DRAIN
:
1003 WARN("Message not handled %d.\n", message
);
1010 static HRESULT WINAPI
video_mixer_transform_ProcessInput(IMFTransform
*iface
, DWORD id
, IMFSample
*sample
, DWORD flags
)
1012 struct video_mixer
*mixer
= impl_from_IMFTransform(iface
);
1013 struct input_stream
*input
;
1016 TRACE("%p, %u, %p, %#x.\n", iface
, id
, sample
, flags
);
1021 EnterCriticalSection(&mixer
->cs
);
1023 if (SUCCEEDED(hr
= video_mixer_get_input(mixer
, id
, &input
)))
1025 if (!input
->media_type
|| !mixer
->output
.media_type
)
1026 hr
= MF_E_TRANSFORM_TYPE_NOT_SET
;
1027 else if (input
->sample
)
1028 hr
= MF_E_NOTACCEPTING
;
1031 mixer
->is_streaming
= 1;
1032 input
->sample
= sample
;
1033 IMFSample_AddRef(input
->sample
);
1037 LeaveCriticalSection(&mixer
->cs
);
1042 static HRESULT WINAPI
video_mixer_transform_ProcessOutput(IMFTransform
*iface
, DWORD flags
, DWORD count
,
1043 MFT_OUTPUT_DATA_BUFFER
*samples
, DWORD
*status
)
1045 FIXME("%p, %#x, %u, %p, %p.\n", iface
, flags
, count
, samples
, status
);
1050 static const IMFTransformVtbl video_mixer_transform_vtbl
=
1052 video_mixer_transform_QueryInterface
,
1053 video_mixer_transform_AddRef
,
1054 video_mixer_transform_Release
,
1055 video_mixer_transform_GetStreamLimits
,
1056 video_mixer_transform_GetStreamCount
,
1057 video_mixer_transform_GetStreamIDs
,
1058 video_mixer_transform_GetInputStreamInfo
,
1059 video_mixer_transform_GetOutputStreamInfo
,
1060 video_mixer_transform_GetAttributes
,
1061 video_mixer_transform_GetInputStreamAttributes
,
1062 video_mixer_transform_GetOutputStreamAttributes
,
1063 video_mixer_transform_DeleteInputStream
,
1064 video_mixer_transform_AddInputStreams
,
1065 video_mixer_transform_GetInputAvailableType
,
1066 video_mixer_transform_GetOutputAvailableType
,
1067 video_mixer_transform_SetInputType
,
1068 video_mixer_transform_SetOutputType
,
1069 video_mixer_transform_GetInputCurrentType
,
1070 video_mixer_transform_GetOutputCurrentType
,
1071 video_mixer_transform_GetInputStatus
,
1072 video_mixer_transform_GetOutputStatus
,
1073 video_mixer_transform_SetOutputBounds
,
1074 video_mixer_transform_ProcessEvent
,
1075 video_mixer_transform_ProcessMessage
,
1076 video_mixer_transform_ProcessInput
,
1077 video_mixer_transform_ProcessOutput
,
1080 static HRESULT WINAPI
video_mixer_device_id_QueryInterface(IMFVideoDeviceID
*iface
, REFIID riid
, void **obj
)
1082 struct video_mixer
*mixer
= impl_from_IMFVideoDeviceID(iface
);
1083 return IMFTransform_QueryInterface(&mixer
->IMFTransform_iface
, riid
, obj
);
1086 static ULONG WINAPI
video_mixer_device_id_AddRef(IMFVideoDeviceID
*iface
)
1088 struct video_mixer
*mixer
= impl_from_IMFVideoDeviceID(iface
);
1089 return IMFTransform_AddRef(&mixer
->IMFTransform_iface
);
1092 static ULONG WINAPI
video_mixer_device_id_Release(IMFVideoDeviceID
*iface
)
1094 struct video_mixer
*mixer
= impl_from_IMFVideoDeviceID(iface
);
1095 return IMFTransform_Release(&mixer
->IMFTransform_iface
);
1098 static HRESULT WINAPI
video_mixer_device_id_GetDeviceID(IMFVideoDeviceID
*iface
, IID
*device_id
)
1100 TRACE("%p, %p.\n", iface
, device_id
);
1105 memcpy(device_id
, &IID_IDirect3DDevice9
, sizeof(*device_id
));
1110 static const IMFVideoDeviceIDVtbl video_mixer_device_id_vtbl
=
1112 video_mixer_device_id_QueryInterface
,
1113 video_mixer_device_id_AddRef
,
1114 video_mixer_device_id_Release
,
1115 video_mixer_device_id_GetDeviceID
,
1118 static HRESULT WINAPI
video_mixer_service_client_QueryInterface(IMFTopologyServiceLookupClient
*iface
,
1119 REFIID riid
, void **obj
)
1121 struct video_mixer
*mixer
= impl_from_IMFTopologyServiceLookupClient(iface
);
1122 return IMFTransform_QueryInterface(&mixer
->IMFTransform_iface
, riid
, obj
);
1125 static ULONG WINAPI
video_mixer_service_client_AddRef(IMFTopologyServiceLookupClient
*iface
)
1127 struct video_mixer
*mixer
= impl_from_IMFTopologyServiceLookupClient(iface
);
1128 return IMFTransform_AddRef(&mixer
->IMFTransform_iface
);
1131 static ULONG WINAPI
video_mixer_service_client_Release(IMFTopologyServiceLookupClient
*iface
)
1133 struct video_mixer
*mixer
= impl_from_IMFTopologyServiceLookupClient(iface
);
1134 return IMFTransform_Release(&mixer
->IMFTransform_iface
);
1137 static HRESULT WINAPI
video_mixer_service_client_InitServicePointers(IMFTopologyServiceLookupClient
*iface
,
1138 IMFTopologyServiceLookup
*service_lookup
)
1140 struct video_mixer
*mixer
= impl_from_IMFTopologyServiceLookupClient(iface
);
1144 TRACE("%p, %p.\n", iface
, service_lookup
);
1146 if (!service_lookup
)
1149 EnterCriticalSection(&mixer
->cs
);
1152 if (FAILED(hr
= IMFTopologyServiceLookup_LookupService(service_lookup
, MF_SERVICE_LOOKUP_GLOBAL
, 0,
1153 &MR_VIDEO_RENDER_SERVICE
, &IID_IMediaEventSink
, (void **)&mixer
->event_sink
, &count
)))
1155 WARN("Failed to get renderer event sink, hr %#x.\n", hr
);
1158 LeaveCriticalSection(&mixer
->cs
);
1163 static HRESULT WINAPI
video_mixer_service_client_ReleaseServicePointers(IMFTopologyServiceLookupClient
*iface
)
1165 struct video_mixer
*mixer
= impl_from_IMFTopologyServiceLookupClient(iface
);
1167 TRACE("%p.\n", iface
);
1169 EnterCriticalSection(&mixer
->cs
);
1171 if (mixer
->event_sink
)
1172 IMediaEventSink_Release(mixer
->event_sink
);
1173 mixer
->event_sink
= NULL
;
1175 LeaveCriticalSection(&mixer
->cs
);
1180 static const IMFTopologyServiceLookupClientVtbl video_mixer_service_client_vtbl
=
1182 video_mixer_service_client_QueryInterface
,
1183 video_mixer_service_client_AddRef
,
1184 video_mixer_service_client_Release
,
1185 video_mixer_service_client_InitServicePointers
,
1186 video_mixer_service_client_ReleaseServicePointers
,
1189 static HRESULT WINAPI
video_mixer_control_QueryInterface(IMFVideoMixerControl2
*iface
, REFIID riid
, void **obj
)
1191 struct video_mixer
*mixer
= impl_from_IMFVideoMixerControl2(iface
);
1192 return IMFTransform_QueryInterface(&mixer
->IMFTransform_iface
, riid
, obj
);
1195 static ULONG WINAPI
video_mixer_control_AddRef(IMFVideoMixerControl2
*iface
)
1197 struct video_mixer
*mixer
= impl_from_IMFVideoMixerControl2(iface
);
1198 return IMFTransform_AddRef(&mixer
->IMFTransform_iface
);
1201 static ULONG WINAPI
video_mixer_control_Release(IMFVideoMixerControl2
*iface
)
1203 struct video_mixer
*mixer
= impl_from_IMFVideoMixerControl2(iface
);
1204 return IMFTransform_Release(&mixer
->IMFTransform_iface
);
1207 static HRESULT WINAPI
video_mixer_control_SetStreamZOrder(IMFVideoMixerControl2
*iface
, DWORD id
, DWORD zorder
)
1209 struct video_mixer
*mixer
= impl_from_IMFVideoMixerControl2(iface
);
1210 struct input_stream
*stream
;
1213 TRACE("%p, %u, %u.\n", iface
, id
, zorder
);
1215 /* Can't change reference stream. */
1217 return E_INVALIDARG
;
1219 EnterCriticalSection(&mixer
->cs
);
1221 if (zorder
>= mixer
->input_count
)
1223 else if (SUCCEEDED(hr
= video_mixer_get_input(mixer
, id
, &stream
)))
1225 /* Lowest zorder only applies to reference stream. */
1227 hr
= MF_E_INVALIDREQUEST
;
1229 stream
->zorder
= zorder
;
1232 LeaveCriticalSection(&mixer
->cs
);
1237 static HRESULT WINAPI
video_mixer_control_GetStreamZOrder(IMFVideoMixerControl2
*iface
, DWORD id
, DWORD
*zorder
)
1239 struct video_mixer
*mixer
= impl_from_IMFVideoMixerControl2(iface
);
1240 struct input_stream
*stream
;
1243 TRACE("%p, %u, %p.\n", iface
, id
, zorder
);
1248 EnterCriticalSection(&mixer
->cs
);
1250 if (SUCCEEDED(hr
= video_mixer_get_input(mixer
, id
, &stream
)))
1251 *zorder
= stream
->zorder
;
1253 LeaveCriticalSection(&mixer
->cs
);
1258 static HRESULT WINAPI
video_mixer_control_SetStreamOutputRect(IMFVideoMixerControl2
*iface
, DWORD id
,
1259 const MFVideoNormalizedRect
*rect
)
1261 struct video_mixer
*mixer
= impl_from_IMFVideoMixerControl2(iface
);
1262 struct input_stream
*stream
;
1265 TRACE("%p, %u, %p.\n", iface
, id
, rect
);
1270 if (rect
->left
> rect
->right
|| rect
->top
> rect
->bottom
||
1271 rect
->left
< 0.0f
|| rect
->top
< 0.0f
|| rect
->right
> 1.0f
|| rect
->bottom
> 1.0f
)
1273 return E_INVALIDARG
;
1276 EnterCriticalSection(&mixer
->cs
);
1278 if (SUCCEEDED(hr
= video_mixer_get_input(mixer
, id
, &stream
)))
1279 stream
->rect
= *rect
;
1281 LeaveCriticalSection(&mixer
->cs
);
1286 static HRESULT WINAPI
video_mixer_control_GetStreamOutputRect(IMFVideoMixerControl2
*iface
, DWORD id
,
1287 MFVideoNormalizedRect
*rect
)
1289 struct video_mixer
*mixer
= impl_from_IMFVideoMixerControl2(iface
);
1290 struct input_stream
*stream
;
1293 TRACE("%p, %u, %p.\n", iface
, id
, rect
);
1298 EnterCriticalSection(&mixer
->cs
);
1300 if (SUCCEEDED(hr
= video_mixer_get_input(mixer
, id
, &stream
)))
1301 *rect
= stream
->rect
;
1303 LeaveCriticalSection(&mixer
->cs
);
1308 static HRESULT WINAPI
video_mixer_control_SetMixingPrefs(IMFVideoMixerControl2
*iface
, DWORD flags
)
1310 struct video_mixer
*mixer
= impl_from_IMFVideoMixerControl2(iface
);
1312 TRACE("%p, %#x.\n", iface
, flags
);
1314 EnterCriticalSection(&mixer
->cs
);
1315 mixer
->mixing_flags
= flags
;
1316 LeaveCriticalSection(&mixer
->cs
);
1321 static HRESULT WINAPI
video_mixer_control_GetMixingPrefs(IMFVideoMixerControl2
*iface
, DWORD
*flags
)
1323 struct video_mixer
*mixer
= impl_from_IMFVideoMixerControl2(iface
);
1325 TRACE("%p, %p.\n", iface
, flags
);
1330 EnterCriticalSection(&mixer
->cs
);
1331 *flags
= mixer
->mixing_flags
;
1332 LeaveCriticalSection(&mixer
->cs
);
1337 static const IMFVideoMixerControl2Vtbl video_mixer_control_vtbl
=
1339 video_mixer_control_QueryInterface
,
1340 video_mixer_control_AddRef
,
1341 video_mixer_control_Release
,
1342 video_mixer_control_SetStreamZOrder
,
1343 video_mixer_control_GetStreamZOrder
,
1344 video_mixer_control_SetStreamOutputRect
,
1345 video_mixer_control_GetStreamOutputRect
,
1346 video_mixer_control_SetMixingPrefs
,
1347 video_mixer_control_GetMixingPrefs
,
1350 static HRESULT WINAPI
video_mixer_getservice_QueryInterface(IMFGetService
*iface
, REFIID riid
, void **obj
)
1352 struct video_mixer
*mixer
= impl_from_IMFGetService(iface
);
1353 return IMFTransform_QueryInterface(&mixer
->IMFTransform_iface
, riid
, obj
);
1356 static ULONG WINAPI
video_mixer_getservice_AddRef(IMFGetService
*iface
)
1358 struct video_mixer
*mixer
= impl_from_IMFGetService(iface
);
1359 return IMFTransform_AddRef(&mixer
->IMFTransform_iface
);
1362 static ULONG WINAPI
video_mixer_getservice_Release(IMFGetService
*iface
)
1364 struct video_mixer
*mixer
= impl_from_IMFGetService(iface
);
1365 return IMFTransform_Release(&mixer
->IMFTransform_iface
);
1368 static HRESULT WINAPI
video_mixer_getservice_GetService(IMFGetService
*iface
, REFGUID service
, REFIID riid
, void **obj
)
1370 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_guid(service
), debugstr_guid(riid
), obj
);
1372 if (IsEqualGUID(service
, &MR_VIDEO_MIXER_SERVICE
))
1374 if (IsEqualIID(riid
, &IID_IMFVideoMixerBitmap
) ||
1375 IsEqualIID(riid
, &IID_IMFVideoProcessor
) ||
1376 IsEqualIID(riid
, &IID_IMFVideoPositionMapper
) ||
1377 IsEqualIID(riid
, &IID_IMFVideoMixerControl
) ||
1378 IsEqualIID(riid
, &IID_IMFVideoMixerControl2
))
1380 return IMFGetService_QueryInterface(iface
, riid
, obj
);
1384 FIXME("Unsupported service %s, riid %s.\n", debugstr_guid(service
), debugstr_guid(riid
));
1389 static const IMFGetServiceVtbl video_mixer_getservice_vtbl
=
1391 video_mixer_getservice_QueryInterface
,
1392 video_mixer_getservice_AddRef
,
1393 video_mixer_getservice_Release
,
1394 video_mixer_getservice_GetService
,
1397 static HRESULT WINAPI
video_mixer_bitmap_QueryInterface(IMFVideoMixerBitmap
*iface
, REFIID riid
, void **obj
)
1399 struct video_mixer
*mixer
= impl_from_IMFVideoMixerBitmap(iface
);
1400 return IMFTransform_QueryInterface(&mixer
->IMFTransform_iface
, riid
, obj
);
1403 static ULONG WINAPI
video_mixer_bitmap_AddRef(IMFVideoMixerBitmap
*iface
)
1405 struct video_mixer
*mixer
= impl_from_IMFVideoMixerBitmap(iface
);
1406 return IMFTransform_AddRef(&mixer
->IMFTransform_iface
);
1409 static ULONG WINAPI
video_mixer_bitmap_Release(IMFVideoMixerBitmap
*iface
)
1411 struct video_mixer
*mixer
= impl_from_IMFVideoMixerBitmap(iface
);
1412 return IMFTransform_Release(&mixer
->IMFTransform_iface
);
1415 static HRESULT WINAPI
video_mixer_bitmap_SetAlphaBitmap(IMFVideoMixerBitmap
*iface
, const MFVideoAlphaBitmap
*bitmap
)
1417 FIXME("%p, %p.\n", iface
, bitmap
);
1422 static HRESULT WINAPI
video_mixer_bitmap_ClearAlphaBitmap(IMFVideoMixerBitmap
*iface
)
1424 FIXME("%p.\n", iface
);
1429 static HRESULT WINAPI
video_mixer_bitmap_UpdateAlphaBitmapParameters(IMFVideoMixerBitmap
*iface
,
1430 const MFVideoAlphaBitmapParams
*params
)
1432 FIXME("%p, %p.\n", iface
, params
);
1437 static HRESULT WINAPI
video_mixer_bitmap_GetAlphaBitmapParameters(IMFVideoMixerBitmap
*iface
, MFVideoAlphaBitmapParams
*params
)
1439 FIXME("%p, %p.\n", iface
, params
);
1444 static const IMFVideoMixerBitmapVtbl video_mixer_bitmap_vtbl
=
1446 video_mixer_bitmap_QueryInterface
,
1447 video_mixer_bitmap_AddRef
,
1448 video_mixer_bitmap_Release
,
1449 video_mixer_bitmap_SetAlphaBitmap
,
1450 video_mixer_bitmap_ClearAlphaBitmap
,
1451 video_mixer_bitmap_UpdateAlphaBitmapParameters
,
1452 video_mixer_bitmap_GetAlphaBitmapParameters
,
1455 static HRESULT WINAPI
video_mixer_position_mapper_QueryInterface(IMFVideoPositionMapper
*iface
, REFIID riid
, void **obj
)
1457 struct video_mixer
*mixer
= impl_from_IMFVideoPositionMapper(iface
);
1458 return IMFTransform_QueryInterface(&mixer
->IMFTransform_iface
, riid
, obj
);
1461 static ULONG WINAPI
video_mixer_position_mapper_AddRef(IMFVideoPositionMapper
*iface
)
1463 struct video_mixer
*mixer
= impl_from_IMFVideoPositionMapper(iface
);
1464 return IMFTransform_AddRef(&mixer
->IMFTransform_iface
);
1467 static ULONG WINAPI
video_mixer_position_mapper_Release(IMFVideoPositionMapper
*iface
)
1469 struct video_mixer
*mixer
= impl_from_IMFVideoPositionMapper(iface
);
1470 return IMFTransform_Release(&mixer
->IMFTransform_iface
);
1473 static HRESULT WINAPI
video_mixer_position_mapper_MapOutputCoordinateToInputStream(IMFVideoPositionMapper
*iface
,
1474 float x_out
, float y_out
, DWORD output_stream
, DWORD input_stream
, float *x_in
, float *y_in
)
1476 FIXME("%p, %f, %f, %u, %u, %p, %p.\n", iface
, x_out
, y_out
, output_stream
, input_stream
, x_in
, y_in
);
1481 static const IMFVideoPositionMapperVtbl video_mixer_position_mapper_vtbl
=
1483 video_mixer_position_mapper_QueryInterface
,
1484 video_mixer_position_mapper_AddRef
,
1485 video_mixer_position_mapper_Release
,
1486 video_mixer_position_mapper_MapOutputCoordinateToInputStream
,
1489 static HRESULT WINAPI
video_mixer_processor_QueryInterface(IMFVideoProcessor
*iface
, REFIID riid
, void **obj
)
1491 struct video_mixer
*mixer
= impl_from_IMFVideoProcessor(iface
);
1492 return IMFTransform_QueryInterface(&mixer
->IMFTransform_iface
, riid
, obj
);
1495 static ULONG WINAPI
video_mixer_processor_AddRef(IMFVideoProcessor
*iface
)
1497 struct video_mixer
*mixer
= impl_from_IMFVideoProcessor(iface
);
1498 return IMFTransform_AddRef(&mixer
->IMFTransform_iface
);
1501 static ULONG WINAPI
video_mixer_processor_Release(IMFVideoProcessor
*iface
)
1503 struct video_mixer
*mixer
= impl_from_IMFVideoProcessor(iface
);
1504 return IMFTransform_Release(&mixer
->IMFTransform_iface
);
1507 static HRESULT WINAPI
video_mixer_processor_GetAvailableVideoProcessorModes(IMFVideoProcessor
*iface
, UINT
*count
,
1510 FIXME("%p, %p, %p.\n", iface
, count
, modes
);
1515 static HRESULT WINAPI
video_mixer_processor_GetVideoProcessorCaps(IMFVideoProcessor
*iface
, GUID
*mode
,
1516 DXVA2_VideoProcessorCaps
*caps
)
1518 FIXME("%p, %s, %p.\n", iface
, debugstr_guid(mode
), caps
);
1523 static HRESULT WINAPI
video_mixer_processor_GetVideoProcessorMode(IMFVideoProcessor
*iface
, GUID
*mode
)
1525 FIXME("%p, %p.\n", iface
, mode
);
1530 static HRESULT WINAPI
video_mixer_processor_SetVideoProcessorMode(IMFVideoProcessor
*iface
, GUID
*mode
)
1532 FIXME("%p, %s.\n", iface
, debugstr_guid(mode
));
1537 static HRESULT WINAPI
video_mixer_processor_GetProcAmpRange(IMFVideoProcessor
*iface
, DWORD prop
, DXVA2_ValueRange
*range
)
1539 FIXME("%p, %#x, %p.\n", iface
, prop
, range
);
1544 static HRESULT WINAPI
video_mixer_processor_GetProcAmpValues(IMFVideoProcessor
*iface
, DWORD flags
, DXVA2_ProcAmpValues
*values
)
1546 FIXME("%p, %#x, %p.\n", iface
, flags
, values
);
1551 static HRESULT WINAPI
video_mixer_processor_SetProcAmpValues(IMFVideoProcessor
*iface
, DWORD flags
, DXVA2_ProcAmpValues
*values
)
1553 FIXME("%p, %#x, %p.\n", iface
, flags
, values
);
1558 static HRESULT WINAPI
video_mixer_processor_GetFilteringRange(IMFVideoProcessor
*iface
, DWORD prop
, DXVA2_ValueRange
*range
)
1560 FIXME("%p, %#x, %p.\n", iface
, prop
, range
);
1565 static HRESULT WINAPI
video_mixer_processor_GetFilteringValue(IMFVideoProcessor
*iface
, DWORD prop
, DXVA2_Fixed32
*value
)
1567 FIXME("%p, %#x, %p.\n", iface
, prop
, value
);
1572 static HRESULT WINAPI
video_mixer_processor_SetFilteringValue(IMFVideoProcessor
*iface
, DWORD prop
, DXVA2_Fixed32
*value
)
1574 FIXME("%p, %#x, %p.\n", iface
, prop
, value
);
1579 static HRESULT WINAPI
video_mixer_processor_GetBackgroundColor(IMFVideoProcessor
*iface
, COLORREF
*color
)
1581 struct video_mixer
*mixer
= impl_from_IMFVideoProcessor(iface
);
1583 TRACE("%p, %p.\n", iface
, color
);
1588 EnterCriticalSection(&mixer
->cs
);
1589 *color
= mixer
->bkgnd_color
;
1590 LeaveCriticalSection(&mixer
->cs
);
1595 static HRESULT WINAPI
video_mixer_processor_SetBackgroundColor(IMFVideoProcessor
*iface
, COLORREF color
)
1597 struct video_mixer
*mixer
= impl_from_IMFVideoProcessor(iface
);
1599 TRACE("%p, %#x.\n", iface
, color
);
1601 EnterCriticalSection(&mixer
->cs
);
1602 mixer
->bkgnd_color
= color
;
1603 LeaveCriticalSection(&mixer
->cs
);
1608 static const IMFVideoProcessorVtbl video_mixer_processor_vtbl
=
1610 video_mixer_processor_QueryInterface
,
1611 video_mixer_processor_AddRef
,
1612 video_mixer_processor_Release
,
1613 video_mixer_processor_GetAvailableVideoProcessorModes
,
1614 video_mixer_processor_GetVideoProcessorCaps
,
1615 video_mixer_processor_GetVideoProcessorMode
,
1616 video_mixer_processor_SetVideoProcessorMode
,
1617 video_mixer_processor_GetProcAmpRange
,
1618 video_mixer_processor_GetProcAmpValues
,
1619 video_mixer_processor_SetProcAmpValues
,
1620 video_mixer_processor_GetFilteringRange
,
1621 video_mixer_processor_GetFilteringValue
,
1622 video_mixer_processor_SetFilteringValue
,
1623 video_mixer_processor_GetBackgroundColor
,
1624 video_mixer_processor_SetBackgroundColor
,
1627 static HRESULT WINAPI
video_mixer_attributes_QueryInterface(IMFAttributes
*iface
, REFIID riid
, void **out
)
1629 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1630 return IMFTransform_QueryInterface(&mixer
->IMFTransform_iface
, riid
, out
);
1633 static ULONG WINAPI
video_mixer_attributes_AddRef(IMFAttributes
*iface
)
1635 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1636 return IMFTransform_AddRef(&mixer
->IMFTransform_iface
);
1639 static ULONG WINAPI
video_mixer_attributes_Release(IMFAttributes
*iface
)
1641 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1642 return IMFTransform_Release(&mixer
->IMFTransform_iface
);
1645 static HRESULT WINAPI
video_mixer_attributes_GetItem(IMFAttributes
*iface
, REFGUID key
, PROPVARIANT
*value
)
1647 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1649 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
1651 return IMFAttributes_GetItem(mixer
->internal_attributes
, key
, value
);
1654 static HRESULT WINAPI
video_mixer_attributes_GetItemType(IMFAttributes
*iface
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
1656 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1658 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), type
);
1660 return IMFAttributes_GetItemType(mixer
->internal_attributes
, key
, type
);
1663 static HRESULT WINAPI
video_mixer_attributes_CompareItem(IMFAttributes
*iface
, REFGUID key
,
1664 REFPROPVARIANT value
, BOOL
*result
)
1666 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1668 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_guid(key
), value
, result
);
1670 return IMFAttributes_CompareItem(mixer
->internal_attributes
, key
, value
, result
);
1673 static HRESULT WINAPI
video_mixer_attributes_Compare(IMFAttributes
*iface
, IMFAttributes
*theirs
,
1674 MF_ATTRIBUTES_MATCH_TYPE match_type
, BOOL
*ret
)
1676 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1678 TRACE("%p, %p, %d, %p.\n", iface
, theirs
, match_type
, ret
);
1680 return IMFAttributes_Compare(mixer
->internal_attributes
, theirs
, match_type
, ret
);
1683 static HRESULT WINAPI
video_mixer_attributes_GetUINT32(IMFAttributes
*iface
, REFGUID key
, UINT32
*value
)
1685 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1687 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
1689 return IMFAttributes_GetUINT32(mixer
->internal_attributes
, key
, value
);
1692 static HRESULT WINAPI
video_mixer_attributes_GetUINT64(IMFAttributes
*iface
, REFGUID key
, UINT64
*value
)
1694 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1696 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
1698 return IMFAttributes_GetUINT64(mixer
->internal_attributes
, key
, value
);
1701 static HRESULT WINAPI
video_mixer_attributes_GetDouble(IMFAttributes
*iface
, REFGUID key
, double *value
)
1703 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1705 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
1707 return IMFAttributes_GetDouble(mixer
->internal_attributes
, key
, value
);
1710 static HRESULT WINAPI
video_mixer_attributes_GetGUID(IMFAttributes
*iface
, REFGUID key
, GUID
*value
)
1712 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1714 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
1716 return IMFAttributes_GetGUID(mixer
->internal_attributes
, key
, value
);
1719 static HRESULT WINAPI
video_mixer_attributes_GetStringLength(IMFAttributes
*iface
, REFGUID key
, UINT32
*length
)
1721 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1723 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), length
);
1725 return IMFAttributes_GetStringLength(mixer
->internal_attributes
, key
, length
);
1728 static HRESULT WINAPI
video_mixer_attributes_GetString(IMFAttributes
*iface
, REFGUID key
, WCHAR
*value
,
1729 UINT32 size
, UINT32
*length
)
1731 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1733 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_guid(key
), value
, size
, length
);
1735 return IMFAttributes_GetString(mixer
->internal_attributes
, key
, value
, size
, length
);
1738 static HRESULT WINAPI
video_mixer_attributes_GetAllocatedString(IMFAttributes
*iface
, REFGUID key
,
1739 WCHAR
**value
, UINT32
*length
)
1741 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1743 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_guid(key
), value
, length
);
1745 return IMFAttributes_GetAllocatedString(mixer
->internal_attributes
, key
, value
, length
);
1748 static HRESULT WINAPI
video_mixer_attributes_GetBlobSize(IMFAttributes
*iface
, REFGUID key
, UINT32
*size
)
1750 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1752 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), size
);
1754 return IMFAttributes_GetBlobSize(mixer
->internal_attributes
, key
, size
);
1757 static HRESULT WINAPI
video_mixer_attributes_GetBlob(IMFAttributes
*iface
, REFGUID key
, UINT8
*buf
,
1758 UINT32 bufsize
, UINT32
*blobsize
)
1760 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1762 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_guid(key
), buf
, bufsize
, blobsize
);
1764 return IMFAttributes_GetBlob(mixer
->internal_attributes
, key
, buf
, bufsize
, blobsize
);
1767 static HRESULT WINAPI
video_mixer_attributes_GetAllocatedBlob(IMFAttributes
*iface
, REFGUID key
, UINT8
**buf
, UINT32
*size
)
1769 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1771 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_guid(key
), buf
, size
);
1773 return IMFAttributes_GetAllocatedBlob(mixer
->internal_attributes
, key
, buf
, size
);
1776 static HRESULT WINAPI
video_mixer_attributes_GetUnknown(IMFAttributes
*iface
, REFGUID key
, REFIID riid
, void **out
)
1778 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1780 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_guid(key
), debugstr_guid(riid
), out
);
1782 return IMFAttributes_GetUnknown(mixer
->internal_attributes
, key
, riid
, out
);
1785 static HRESULT WINAPI
video_mixer_attributes_SetItem(IMFAttributes
*iface
, REFGUID key
, REFPROPVARIANT value
)
1787 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1789 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
1791 return IMFAttributes_SetItem(mixer
->internal_attributes
, key
, value
);
1794 static HRESULT WINAPI
video_mixer_attributes_DeleteItem(IMFAttributes
*iface
, REFGUID key
)
1796 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1798 TRACE("%p, %s.\n", iface
, debugstr_guid(key
));
1800 return IMFAttributes_DeleteItem(mixer
->internal_attributes
, key
);
1803 static HRESULT WINAPI
video_mixer_attributes_DeleteAllItems(IMFAttributes
*iface
)
1805 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1807 TRACE("%p.\n", iface
);
1809 return IMFAttributes_DeleteAllItems(mixer
->internal_attributes
);
1812 static HRESULT WINAPI
video_mixer_attributes_SetUINT32(IMFAttributes
*iface
, REFGUID key
, UINT32 value
)
1814 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1816 TRACE("%p, %s, %u.\n", iface
, debugstr_guid(key
), value
);
1818 return IMFAttributes_SetUINT32(mixer
->internal_attributes
, key
, value
);
1821 static HRESULT WINAPI
video_mixer_attributes_SetUINT64(IMFAttributes
*iface
, REFGUID key
, UINT64 value
)
1823 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1825 TRACE("%p, %s, %s.\n", iface
, debugstr_guid(key
), wine_dbgstr_longlong(value
));
1827 return IMFAttributes_SetUINT64(mixer
->internal_attributes
, key
, value
);
1830 static HRESULT WINAPI
video_mixer_attributes_SetDouble(IMFAttributes
*iface
, REFGUID key
, double value
)
1832 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1834 TRACE("%p, %s, %f.\n", iface
, debugstr_guid(key
), value
);
1836 return IMFAttributes_SetDouble(mixer
->internal_attributes
, key
, value
);
1839 static HRESULT WINAPI
video_mixer_attributes_SetGUID(IMFAttributes
*iface
, REFGUID key
, REFGUID value
)
1841 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1843 TRACE("%p, %s, %s.\n", iface
, debugstr_guid(key
), debugstr_guid(value
));
1845 return IMFAttributes_SetGUID(mixer
->internal_attributes
, key
, value
);
1848 static HRESULT WINAPI
video_mixer_attributes_SetString(IMFAttributes
*iface
, REFGUID key
, const WCHAR
*value
)
1850 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1852 TRACE("%p, %s, %s.\n", iface
, debugstr_guid(key
), debugstr_w(value
));
1854 return IMFAttributes_SetString(mixer
->internal_attributes
, key
, value
);
1857 static HRESULT WINAPI
video_mixer_attributes_SetBlob(IMFAttributes
*iface
, REFGUID key
, const UINT8
*buf
, UINT32 size
)
1859 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1861 TRACE("%p, %s, %p, %u.\n", iface
, debugstr_guid(key
), buf
, size
);
1863 return IMFAttributes_SetBlob(mixer
->internal_attributes
, key
, buf
, size
);
1866 static HRESULT WINAPI
video_mixer_attributes_SetUnknown(IMFAttributes
*iface
, REFGUID key
, IUnknown
*unknown
)
1868 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1870 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), unknown
);
1872 return IMFAttributes_SetUnknown(mixer
->internal_attributes
, key
, unknown
);
1875 static HRESULT WINAPI
video_mixer_attributes_LockStore(IMFAttributes
*iface
)
1877 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1879 TRACE("%p.\n", iface
);
1881 return IMFAttributes_LockStore(mixer
->internal_attributes
);
1884 static HRESULT WINAPI
video_mixer_attributes_UnlockStore(IMFAttributes
*iface
)
1886 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1888 TRACE("%p.\n", iface
);
1890 return IMFAttributes_UnlockStore(mixer
->internal_attributes
);
1893 static HRESULT WINAPI
video_mixer_attributes_GetCount(IMFAttributes
*iface
, UINT32
*count
)
1895 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1897 TRACE("%p, %p.\n", iface
, count
);
1899 return IMFAttributes_GetCount(mixer
->internal_attributes
, count
);
1902 static HRESULT WINAPI
video_mixer_attributes_GetItemByIndex(IMFAttributes
*iface
, UINT32 index
,
1903 GUID
*key
, PROPVARIANT
*value
)
1905 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1907 TRACE("%p, %u, %p, %p.\n", iface
, index
, key
, value
);
1909 return IMFAttributes_GetItemByIndex(mixer
->internal_attributes
, index
, key
, value
);
1912 static HRESULT WINAPI
video_mixer_attributes_CopyAllItems(IMFAttributes
*iface
, IMFAttributes
*dest
)
1914 struct video_mixer
*mixer
= impl_from_IMFAttributes(iface
);
1916 TRACE("%p, %p.\n", iface
, dest
);
1918 return IMFAttributes_CopyAllItems(mixer
->internal_attributes
, dest
);
1921 static const IMFAttributesVtbl video_mixer_attributes_vtbl
=
1923 video_mixer_attributes_QueryInterface
,
1924 video_mixer_attributes_AddRef
,
1925 video_mixer_attributes_Release
,
1926 video_mixer_attributes_GetItem
,
1927 video_mixer_attributes_GetItemType
,
1928 video_mixer_attributes_CompareItem
,
1929 video_mixer_attributes_Compare
,
1930 video_mixer_attributes_GetUINT32
,
1931 video_mixer_attributes_GetUINT64
,
1932 video_mixer_attributes_GetDouble
,
1933 video_mixer_attributes_GetGUID
,
1934 video_mixer_attributes_GetStringLength
,
1935 video_mixer_attributes_GetString
,
1936 video_mixer_attributes_GetAllocatedString
,
1937 video_mixer_attributes_GetBlobSize
,
1938 video_mixer_attributes_GetBlob
,
1939 video_mixer_attributes_GetAllocatedBlob
,
1940 video_mixer_attributes_GetUnknown
,
1941 video_mixer_attributes_SetItem
,
1942 video_mixer_attributes_DeleteItem
,
1943 video_mixer_attributes_DeleteAllItems
,
1944 video_mixer_attributes_SetUINT32
,
1945 video_mixer_attributes_SetUINT64
,
1946 video_mixer_attributes_SetDouble
,
1947 video_mixer_attributes_SetGUID
,
1948 video_mixer_attributes_SetString
,
1949 video_mixer_attributes_SetBlob
,
1950 video_mixer_attributes_SetUnknown
,
1951 video_mixer_attributes_LockStore
,
1952 video_mixer_attributes_UnlockStore
,
1953 video_mixer_attributes_GetCount
,
1954 video_mixer_attributes_GetItemByIndex
,
1955 video_mixer_attributes_CopyAllItems
1958 static HRESULT WINAPI
video_mixer_quality_advise_QueryInterface(IMFQualityAdvise
*iface
, REFIID riid
, void **out
)
1960 struct video_mixer
*mixer
= impl_from_IMFQualityAdvise(iface
);
1961 return IMFTransform_QueryInterface(&mixer
->IMFTransform_iface
, riid
, out
);
1964 static ULONG WINAPI
video_mixer_quality_advise_AddRef(IMFQualityAdvise
*iface
)
1966 struct video_mixer
*mixer
= impl_from_IMFQualityAdvise(iface
);
1967 return IMFTransform_AddRef(&mixer
->IMFTransform_iface
);
1970 static ULONG WINAPI
video_mixer_quality_Release(IMFQualityAdvise
*iface
)
1972 struct video_mixer
*mixer
= impl_from_IMFQualityAdvise(iface
);
1973 return IMFTransform_Release(&mixer
->IMFTransform_iface
);
1976 static HRESULT WINAPI
video_mixer_quality_advise_SetDropMode(IMFQualityAdvise
*iface
, MF_QUALITY_DROP_MODE mode
)
1978 FIXME("%p, %u.\n", iface
, mode
);
1983 static HRESULT WINAPI
video_mixer_quality_advise_SetQualityLevel(IMFQualityAdvise
*iface
, MF_QUALITY_LEVEL level
)
1985 FIXME("%p, %u.\n", iface
, level
);
1990 static HRESULT WINAPI
video_mixer_quality_advise_GetDropMode(IMFQualityAdvise
*iface
, MF_QUALITY_DROP_MODE
*mode
)
1992 FIXME("%p, %p.\n", iface
, mode
);
1997 static HRESULT WINAPI
video_mixer_quality_advise_GetQualityLevel(IMFQualityAdvise
*iface
, MF_QUALITY_LEVEL
*level
)
1999 FIXME("%p, %p.\n", iface
, level
);
2004 static HRESULT WINAPI
video_mixer_quality_advise_DropTime(IMFQualityAdvise
*iface
, LONGLONG interval
)
2006 FIXME("%p, %s.\n", iface
, wine_dbgstr_longlong(interval
));
2011 static const IMFQualityAdviseVtbl video_mixer_quality_advise_vtbl
=
2013 video_mixer_quality_advise_QueryInterface
,
2014 video_mixer_quality_advise_AddRef
,
2015 video_mixer_quality_Release
,
2016 video_mixer_quality_advise_SetDropMode
,
2017 video_mixer_quality_advise_SetQualityLevel
,
2018 video_mixer_quality_advise_GetDropMode
,
2019 video_mixer_quality_advise_GetQualityLevel
,
2020 video_mixer_quality_advise_DropTime
,
2023 HRESULT WINAPI
MFCreateVideoMixer(IUnknown
*owner
, REFIID riid_device
, REFIID riid
, void **obj
)
2025 TRACE("%p, %s, %s, %p.\n", owner
, debugstr_guid(riid_device
), debugstr_guid(riid
), obj
);
2029 if (!IsEqualIID(riid_device
, &IID_IDirect3DDevice9
))
2030 return E_INVALIDARG
;
2032 return CoCreateInstance(&CLSID_MFVideoMixer9
, owner
, CLSCTX_INPROC_SERVER
, riid
, obj
);
2035 HRESULT
evr_mixer_create(IUnknown
*outer
, void **out
)
2037 struct video_mixer
*object
;
2038 MFVideoNormalizedRect rect
;
2041 if (!(object
= calloc(1, sizeof(*object
))))
2042 return E_OUTOFMEMORY
;
2044 object
->IMFTransform_iface
.lpVtbl
= &video_mixer_transform_vtbl
;
2045 object
->IMFVideoDeviceID_iface
.lpVtbl
= &video_mixer_device_id_vtbl
;
2046 object
->IMFTopologyServiceLookupClient_iface
.lpVtbl
= &video_mixer_service_client_vtbl
;
2047 object
->IMFVideoMixerControl2_iface
.lpVtbl
= &video_mixer_control_vtbl
;
2048 object
->IMFGetService_iface
.lpVtbl
= &video_mixer_getservice_vtbl
;
2049 object
->IMFVideoMixerBitmap_iface
.lpVtbl
= &video_mixer_bitmap_vtbl
;
2050 object
->IMFVideoPositionMapper_iface
.lpVtbl
= &video_mixer_position_mapper_vtbl
;
2051 object
->IMFVideoProcessor_iface
.lpVtbl
= &video_mixer_processor_vtbl
;
2052 object
->IMFAttributes_iface
.lpVtbl
= &video_mixer_attributes_vtbl
;
2053 object
->IMFQualityAdvise_iface
.lpVtbl
= &video_mixer_quality_advise_vtbl
;
2054 object
->IUnknown_inner
.lpVtbl
= &video_mixer_inner_vtbl
;
2055 object
->outer_unk
= outer
? outer
: &object
->IUnknown_inner
;
2056 object
->refcount
= 1;
2057 object
->input_count
= 1;
2058 object
->lower_bound
= MFT_OUTPUT_BOUND_LOWER_UNBOUNDED
;
2059 object
->upper_bound
= MFT_OUTPUT_BOUND_UPPER_UNBOUNDED
;
2060 video_mixer_init_input(&object
->inputs
[0]);
2061 InitializeCriticalSection(&object
->cs
);
2062 if (FAILED(hr
= MFCreateAttributes(&object
->attributes
, 0)))
2064 IUnknown_Release(&object
->IUnknown_inner
);
2067 if (FAILED(hr
= MFCreateAttributes(&object
->internal_attributes
, 0)))
2069 IUnknown_Release(&object
->IUnknown_inner
);
2073 /* Default attributes configuration. */
2075 rect
.left
= rect
.top
= 0.0f
;
2076 rect
.right
= rect
.bottom
= 1.0f
;
2077 IMFAttributes_SetBlob(object
->attributes
, &VIDEO_ZOOM_RECT
, (const UINT8
*)&rect
, sizeof(rect
));
2079 IMFAttributes_SetUINT32(object
->internal_attributes
, &MF_SA_D3D_AWARE
, 1);
2081 *out
= &object
->IUnknown_inner
;