2 * Enhanced Video Renderer filter unit tests
4 * Copyright 2018 Zebediah Figura
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
24 #include "wine/test.h"
32 static const WCHAR sink_id
[] = {'E','V','R',' ','I','n','p','u','t','0',0};
34 static HRESULT (WINAPI
*pMFCreateVideoMediaTypeFromSubtype
)(const GUID
*subtype
, IMFVideoMediaType
**video_type
);
36 static HWND
create_window(void)
38 RECT r
= {0, 0, 640, 480};
40 AdjustWindowRect(&r
, WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, FALSE
);
42 return CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
43 0, 0, r
.right
- r
.left
, r
.bottom
- r
.top
, NULL
, NULL
, NULL
, NULL
);
46 static IDirect3DDevice9
*create_device(IDirect3D9
*d3d9
, HWND focus_window
)
48 D3DPRESENT_PARAMETERS present_parameters
= {0};
49 IDirect3DDevice9
*device
= NULL
;
51 present_parameters
.BackBufferWidth
= 640;
52 present_parameters
.BackBufferHeight
= 480;
53 present_parameters
.BackBufferFormat
= D3DFMT_A8R8G8B8
;
54 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
55 present_parameters
.hDeviceWindow
= focus_window
;
56 present_parameters
.Windowed
= TRUE
;
57 present_parameters
.EnableAutoDepthStencil
= TRUE
;
58 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
60 IDirect3D9_CreateDevice(d3d9
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, focus_window
,
61 D3DCREATE_HARDWARE_VERTEXPROCESSING
, &present_parameters
, &device
);
66 static IBaseFilter
*create_evr(void)
68 IBaseFilter
*filter
= NULL
;
69 HRESULT hr
= CoCreateInstance(&CLSID_EnhancedVideoRenderer
, NULL
, CLSCTX_INPROC_SERVER
,
70 &IID_IBaseFilter
, (void **)&filter
);
71 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
75 static ULONG
get_refcount(void *iface
)
77 IUnknown
*unknown
= iface
;
78 IUnknown_AddRef(unknown
);
79 return IUnknown_Release(unknown
);
82 static const GUID test_iid
= {0x33333333};
83 static LONG outer_ref
= 1;
85 static HRESULT WINAPI
outer_QueryInterface(IUnknown
*iface
, REFIID iid
, void **out
)
87 if (IsEqualGUID(iid
, &IID_IUnknown
)
88 || IsEqualGUID(iid
, &IID_IBaseFilter
)
89 || IsEqualGUID(iid
, &test_iid
))
91 *out
= (IUnknown
*)0xdeadbeef;
94 ok(0, "unexpected call %s\n", wine_dbgstr_guid(iid
));
98 static ULONG WINAPI
outer_AddRef(IUnknown
*iface
)
100 return InterlockedIncrement(&outer_ref
);
103 static ULONG WINAPI
outer_Release(IUnknown
*iface
)
105 return InterlockedDecrement(&outer_ref
);
108 static const IUnknownVtbl outer_vtbl
=
110 outer_QueryInterface
,
115 static IUnknown test_outer
= {&outer_vtbl
};
117 static void test_aggregation(void)
119 IBaseFilter
*filter
, *filter2
;
120 IUnknown
*unk
, *unk2
;
124 filter
= (IBaseFilter
*)0xdeadbeef;
125 hr
= CoCreateInstance(&CLSID_EnhancedVideoRenderer
, &test_outer
, CLSCTX_INPROC_SERVER
,
126 &IID_IBaseFilter
, (void **)&filter
);
127 ok(hr
== E_NOINTERFACE
, "Got hr %#x.\n", hr
);
128 ok(!filter
, "Got interface %p.\n", filter
);
130 hr
= CoCreateInstance(&CLSID_EnhancedVideoRenderer
, &test_outer
, CLSCTX_INPROC_SERVER
,
131 &IID_IUnknown
, (void **)&unk
);
132 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
133 ok(outer_ref
== 1, "Got unexpected refcount %d.\n", outer_ref
);
134 ok(unk
!= &test_outer
, "Returned IUnknown should not be outer IUnknown.\n");
135 ref
= get_refcount(unk
);
136 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
138 ref
= IUnknown_AddRef(unk
);
139 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
140 ok(outer_ref
== 1, "Got unexpected refcount %d.\n", outer_ref
);
142 ref
= IUnknown_Release(unk
);
143 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
144 ok(outer_ref
== 1, "Got unexpected refcount %d.\n", outer_ref
);
146 hr
= IUnknown_QueryInterface(unk
, &IID_IUnknown
, (void **)&unk2
);
147 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
148 ok(unk2
== unk
, "Got unexpected IUnknown %p.\n", unk2
);
149 IUnknown_Release(unk2
);
151 hr
= IUnknown_QueryInterface(unk
, &IID_IBaseFilter
, (void **)&filter
);
152 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
154 hr
= IBaseFilter_QueryInterface(filter
, &IID_IUnknown
, (void **)&unk2
);
155 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
156 ok(unk2
== (IUnknown
*)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2
);
158 hr
= IBaseFilter_QueryInterface(filter
, &IID_IBaseFilter
, (void **)&filter2
);
159 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
160 ok(filter2
== (IBaseFilter
*)0xdeadbeef, "Got unexpected IBaseFilter %p.\n", filter2
);
162 hr
= IUnknown_QueryInterface(unk
, &test_iid
, (void **)&unk2
);
163 ok(hr
== E_NOINTERFACE
, "Got hr %#x.\n", hr
);
164 ok(!unk2
, "Got unexpected IUnknown %p.\n", unk2
);
166 hr
= IBaseFilter_QueryInterface(filter
, &test_iid
, (void **)&unk2
);
167 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
168 ok(unk2
== (IUnknown
*)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2
);
170 IBaseFilter_Release(filter
);
171 ref
= IUnknown_Release(unk
);
172 ok(!ref
, "Got unexpected refcount %d.\n", ref
);
173 ok(outer_ref
== 1, "Got unexpected refcount %d.\n", outer_ref
);
176 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
177 static void check_interface_(unsigned int line
, void *iface_ptr
, REFIID iid
, BOOL supported
)
179 IUnknown
*iface
= iface_ptr
;
180 HRESULT hr
, expected_hr
;
183 expected_hr
= supported
? S_OK
: E_NOINTERFACE
;
185 hr
= IUnknown_QueryInterface(iface
, iid
, (void **)&unk
);
186 ok_(__FILE__
, line
)(hr
== expected_hr
, "Got hr %#x, expected %#x.\n", hr
, expected_hr
);
188 IUnknown_Release(unk
);
191 static void test_interfaces(void)
193 IBaseFilter
*filter
= create_evr();
196 todo_wine
check_interface(filter
, &IID_IAMFilterMiscFlags
, TRUE
);
197 check_interface(filter
, &IID_IBaseFilter
, TRUE
);
198 check_interface(filter
, &IID_IMediaFilter
, TRUE
);
199 check_interface(filter
, &IID_IMediaPosition
, TRUE
);
200 check_interface(filter
, &IID_IMediaSeeking
, TRUE
);
201 check_interface(filter
, &IID_IPersist
, TRUE
);
202 check_interface(filter
, &IID_IUnknown
, TRUE
);
204 check_interface(filter
, &IID_IBasicAudio
, FALSE
);
205 check_interface(filter
, &IID_IBasicVideo
, FALSE
);
206 check_interface(filter
, &IID_IDirectXVideoMemoryConfiguration
, FALSE
);
207 check_interface(filter
, &IID_IMemInputPin
, FALSE
);
208 check_interface(filter
, &IID_IPersistPropertyBag
, FALSE
);
209 check_interface(filter
, &IID_IPin
, FALSE
);
210 check_interface(filter
, &IID_IReferenceClock
, FALSE
);
211 check_interface(filter
, &IID_IVideoWindow
, FALSE
);
213 ref
= IBaseFilter_Release(filter
);
214 ok(!ref
, "Got unexpected refcount %d.\n", ref
);
217 static void test_enum_pins(void)
219 IBaseFilter
*filter
= create_evr();
220 IEnumPins
*enum1
, *enum2
;
225 ref
= get_refcount(filter
);
226 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
228 hr
= IBaseFilter_EnumPins(filter
, NULL
);
229 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
231 hr
= IBaseFilter_EnumPins(filter
, &enum1
);
232 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
233 ref
= get_refcount(filter
);
234 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
235 ref
= get_refcount(enum1
);
236 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
238 hr
= IEnumPins_Next(enum1
, 1, NULL
, NULL
);
239 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
241 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
242 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
243 ref
= get_refcount(filter
);
244 ok(ref
== 3, "Got unexpected refcount %d.\n", ref
);
245 ref
= get_refcount(pins
[0]);
246 ok(ref
== 3, "Got unexpected refcount %d.\n", ref
);
247 ref
= get_refcount(enum1
);
248 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
249 IPin_Release(pins
[0]);
250 ref
= get_refcount(filter
);
251 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
253 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
254 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
256 hr
= IEnumPins_Reset(enum1
);
257 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
259 hr
= IEnumPins_Next(enum1
, 1, pins
, &count
);
260 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
261 ok(count
== 1, "Got count %u.\n", count
);
262 IPin_Release(pins
[0]);
264 hr
= IEnumPins_Next(enum1
, 1, pins
, &count
);
265 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
266 ok(!count
, "Got count %u.\n", count
);
268 hr
= IEnumPins_Reset(enum1
);
269 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
271 hr
= IEnumPins_Next(enum1
, 2, pins
, NULL
);
272 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
274 hr
= IEnumPins_Next(enum1
, 2, pins
, &count
);
275 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
276 ok(count
== 1, "Got count %u.\n", count
);
277 IPin_Release(pins
[0]);
279 hr
= IEnumPins_Reset(enum1
);
280 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
282 hr
= IEnumPins_Clone(enum1
, &enum2
);
283 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
285 hr
= IEnumPins_Skip(enum1
, 2);
286 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
288 hr
= IEnumPins_Skip(enum1
, 1);
289 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
291 hr
= IEnumPins_Skip(enum1
, 1);
292 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
294 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
295 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
297 hr
= IEnumPins_Next(enum2
, 1, pins
, NULL
);
298 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
299 IPin_Release(pins
[0]);
301 IEnumPins_Release(enum2
);
302 IEnumPins_Release(enum1
);
303 ref
= IBaseFilter_Release(filter
);
304 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
307 static void test_find_pin(void)
309 IBaseFilter
*filter
= create_evr();
310 IEnumPins
*enum_pins
;
315 hr
= IBaseFilter_EnumPins(filter
, &enum_pins
);
316 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
318 hr
= IBaseFilter_FindPin(filter
, sink_id
, &pin
);
319 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
320 hr
= IEnumPins_Next(enum_pins
, 1, &pin2
, NULL
);
321 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
322 ok(pin2
== pin
, "Expected pin %p, got %p.\n", pin
, pin2
);
326 IEnumPins_Release(enum_pins
);
327 ref
= IBaseFilter_Release(filter
);
328 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
331 static void test_pin_info(void)
333 IBaseFilter
*filter
= create_evr();
341 hr
= IBaseFilter_FindPin(filter
, sink_id
, &pin
);
342 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
343 ref
= get_refcount(filter
);
344 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
345 ref
= get_refcount(pin
);
346 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
348 hr
= IPin_QueryPinInfo(pin
, &info
);
349 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
350 ok(info
.pFilter
== filter
, "Expected filter %p, got %p.\n", filter
, info
.pFilter
);
351 ok(info
.dir
== PINDIR_INPUT
, "Got direction %d.\n", info
.dir
);
352 ok(!lstrcmpW(info
.achName
, sink_id
), "Got name %s.\n", wine_dbgstr_w(info
.achName
));
353 ref
= get_refcount(filter
);
354 ok(ref
== 3, "Got unexpected refcount %d.\n", ref
);
355 ref
= get_refcount(pin
);
356 ok(ref
== 3, "Got unexpected refcount %d.\n", ref
);
357 IBaseFilter_Release(info
.pFilter
);
359 hr
= IPin_QueryDirection(pin
, &dir
);
360 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
361 ok(dir
== PINDIR_INPUT
, "Got direction %d.\n", dir
);
363 hr
= IPin_QueryId(pin
, &id
);
364 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
365 ok(!lstrcmpW(id
, sink_id
), "Got id %s.\n", wine_dbgstr_w(id
));
368 hr
= IPin_QueryInternalConnections(pin
, NULL
, NULL
);
369 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
372 ref
= IBaseFilter_Release(filter
);
373 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
376 static void test_default_mixer(void)
378 DWORD input_min
, input_max
, output_min
, output_max
;
379 MFT_OUTPUT_STREAM_INFO output_info
;
380 MFT_INPUT_STREAM_INFO input_info
;
381 DWORD input_count
, output_count
;
382 IMFVideoDeviceID
*deviceid
;
383 DWORD input_id
, output_id
;
384 IMFAttributes
*attributes
, *attributes2
;
385 IMFTransform
*transform
;
393 hr
= MFCreateVideoMixer(NULL
, &IID_IDirect3DDevice9
, &IID_IMFTransform
, (void **)&transform
);
394 ok(hr
== S_OK
, "Failed to create default mixer, hr %#x.\n", hr
);
396 hr
= IMFTransform_QueryInterface(transform
, &IID_IMFTopologyServiceLookupClient
, (void **)&unk
);
397 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
398 IUnknown_Release(unk
);
400 hr
= IMFTransform_QueryInterface(transform
, &IID_IMFGetService
, (void **)&gs
);
401 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
403 hr
= IMFGetService_GetService(gs
, &MR_VIDEO_MIXER_SERVICE
, &IID_IMFVideoMixerBitmap
, (void **)&unk
);
404 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
405 IUnknown_Release(unk
);
407 hr
= IMFGetService_GetService(gs
, &MR_VIDEO_MIXER_SERVICE
, &IID_IMFVideoProcessor
, (void **)&unk
);
409 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
411 IUnknown_Release(unk
);
413 hr
= IMFGetService_GetService(gs
, &MR_VIDEO_MIXER_SERVICE
, &IID_IMFVideoPositionMapper
, (void **)&unk
);
414 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
415 IUnknown_Release(unk
);
417 IMFGetService_Release(gs
);
419 hr
= IMFTransform_QueryInterface(transform
, &IID_IMFVideoMixerBitmap
, (void **)&unk
);
420 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
421 IUnknown_Release(unk
);
423 hr
= IMFTransform_QueryInterface(transform
, &IID_IMFVideoPositionMapper
, (void **)&unk
);
424 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
425 IUnknown_Release(unk
);
427 hr
= IMFTransform_QueryInterface(transform
, &IID_IMFVideoProcessor
, (void **)&unk
);
429 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
431 IUnknown_Release(unk
);
433 hr
= IMFTransform_QueryInterface(transform
, &IID_IMFVideoMixerControl
, (void **)&unk
);
434 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
435 IUnknown_Release(unk
);
437 hr
= IMFTransform_QueryInterface(transform
, &IID_IMFVideoDeviceID
, (void **)&deviceid
);
438 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
440 hr
= IMFVideoDeviceID_GetDeviceID(deviceid
, NULL
);
441 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
443 hr
= IMFVideoDeviceID_GetDeviceID(deviceid
, &iid
);
444 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
445 ok(IsEqualIID(&iid
, &IID_IDirect3DDevice9
), "Unexpected id %s.\n", wine_dbgstr_guid(&iid
));
447 IMFVideoDeviceID_Release(deviceid
);
449 /* Stream configuration. */
450 input_count
= output_count
= 0;
451 hr
= IMFTransform_GetStreamCount(transform
, &input_count
, &output_count
);
452 ok(hr
== S_OK
, "Failed to get stream count, hr %#x.\n", hr
);
453 ok(input_count
== 1 && output_count
== 1, "Unexpected stream count %u/%u.\n", input_count
, output_count
);
455 hr
= IMFTransform_GetStreamLimits(transform
, &input_min
, &input_max
, &output_min
, &output_max
);
456 ok(hr
== S_OK
, "Failed to get stream limits, hr %#x.\n", hr
);
457 ok(input_min
== 1 && input_max
== 16 && output_min
== 1 && output_max
== 1, "Unexpected stream limits %u/%u, %u/%u.\n",
458 input_min
, input_max
, output_min
, output_max
);
460 hr
= IMFTransform_GetInputStreamInfo(transform
, 1, &input_info
);
461 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#x.\n", hr
);
463 hr
= IMFTransform_GetOutputStreamInfo(transform
, 1, &output_info
);
464 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#x.\n", hr
);
466 memset(&input_info
, 0xcc, sizeof(input_info
));
467 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
468 ok(hr
== S_OK
, "Failed to get input info, hr %#x.\n", hr
);
470 memset(&output_info
, 0xcc, sizeof(output_info
));
471 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
472 ok(hr
== S_OK
, "Failed to get input info, hr %#x.\n", hr
);
473 ok(!(output_info
.dwFlags
& (MFT_OUTPUT_STREAM_PROVIDES_SAMPLES
| MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES
)),
474 "Unexpected output flags %#x.\n", output_info
.dwFlags
);
476 hr
= IMFTransform_GetStreamIDs(transform
, 1, &input_id
, 1, &output_id
);
477 ok(hr
== S_OK
, "Failed to get input info, hr %#x.\n", hr
);
478 ok(input_id
== 0 && output_id
== 0, "Unexpected stream ids.\n");
480 hr
= IMFTransform_GetInputStreamAttributes(transform
, 1, &attributes
);
481 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#x.\n", hr
);
483 hr
= IMFTransform_GetOutputStreamAttributes(transform
, 1, &attributes
);
484 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
486 hr
= IMFTransform_GetOutputStreamAttributes(transform
, 0, &attributes
);
487 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
489 hr
= IMFTransform_AddInputStreams(transform
, 16, NULL
);
490 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
492 hr
= IMFTransform_AddInputStreams(transform
, 16, ids
);
493 ok(hr
== E_INVALIDARG
, "Unexpected hr %#x.\n", hr
);
495 memset(ids
, 0, sizeof(ids
));
496 hr
= IMFTransform_AddInputStreams(transform
, 15, ids
);
497 ok(hr
== E_INVALIDARG
, "Unexpected hr %#x.\n", hr
);
499 for (i
= 0; i
< ARRAY_SIZE(ids
); ++i
)
502 hr
= IMFTransform_AddInputStreams(transform
, 15, ids
);
503 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
505 input_count
= output_count
= 0;
506 hr
= IMFTransform_GetStreamCount(transform
, &input_count
, &output_count
);
507 ok(hr
== S_OK
, "Failed to get stream count, hr %#x.\n", hr
);
508 ok(input_count
== 16 && output_count
== 1, "Unexpected stream count %u/%u.\n", input_count
, output_count
);
510 memset(&input_info
, 0, sizeof(input_info
));
511 hr
= IMFTransform_GetInputStreamInfo(transform
, 1, &input_info
);
512 ok(hr
== S_OK
, "Failed to get input info, hr %#x.\n", hr
);
513 ok((input_info
.dwFlags
& (MFT_INPUT_STREAM_REMOVABLE
| MFT_INPUT_STREAM_OPTIONAL
)) ==
514 (MFT_INPUT_STREAM_REMOVABLE
| MFT_INPUT_STREAM_OPTIONAL
), "Unexpected flags %#x.\n", input_info
.dwFlags
);
517 hr
= IMFTransform_GetInputStreamAttributes(transform
, 0, &attributes
);
518 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
519 ok(!!attributes
, "Unexpected attributes.\n");
522 hr
= IMFTransform_GetInputStreamAttributes(transform
, 0, &attributes2
);
523 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
524 ok(attributes
== attributes2
, "Unexpected instance.\n");
526 IMFAttributes_Release(attributes2
);
527 IMFAttributes_Release(attributes
);
530 hr
= IMFTransform_GetInputStreamAttributes(transform
, 1, &attributes
);
531 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
532 ok(!!attributes
, "Unexpected attributes.\n");
533 IMFAttributes_Release(attributes
);
535 hr
= IMFTransform_DeleteInputStream(transform
, 0);
536 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#x.\n", hr
);
538 hr
= IMFTransform_DeleteInputStream(transform
, 1);
539 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
541 input_count
= output_count
= 0;
542 hr
= IMFTransform_GetStreamCount(transform
, &input_count
, &output_count
);
543 ok(hr
== S_OK
, "Failed to get stream count, hr %#x.\n", hr
);
544 ok(input_count
== 15 && output_count
== 1, "Unexpected stream count %u/%u.\n", input_count
, output_count
);
546 IMFTransform_Release(transform
);
548 hr
= MFCreateVideoMixer(NULL
, &IID_IMFTransform
, &IID_IMFTransform
, (void **)&transform
);
549 ok(hr
== E_INVALIDARG
, "Unexpected hr %#x.\n", hr
);
551 hr
= CoCreateInstance(&CLSID_MFVideoMixer9
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMFTransform
, (void **)&transform
);
552 ok(hr
== S_OK
, "Failed to create default mixer, hr %#x.\n", hr
);
553 IMFTransform_Release(transform
);
556 static void test_surface_sample(void)
558 IDirect3DSurface9
*backbuffer
= NULL
;
559 IMFMediaBuffer
*buffer
, *buffer2
;
560 IDirect3DSwapChain9
*swapchain
;
561 IDirect3DDevice9
*device
;
571 window
= create_window();
572 d3d
= Direct3DCreate9(D3D_SDK_VERSION
);
573 ok(!!d3d
, "Failed to create a D3D object.\n");
574 if (!(device
= create_device(d3d
, window
)))
576 skip("Failed to create a D3D device, skipping tests.\n");
580 hr
= IDirect3DDevice9_GetSwapChain(device
, 0, &swapchain
);
581 ok(SUCCEEDED(hr
), "Failed to get the implicit swapchain (%08x)\n", hr
);
583 hr
= IDirect3DSwapChain9_GetBackBuffer(swapchain
, 0, D3DBACKBUFFER_TYPE_MONO
, &backbuffer
);
584 ok(SUCCEEDED(hr
), "Failed to get the back buffer (%08x)\n", hr
);
585 ok(backbuffer
!= NULL
, "The back buffer is NULL\n");
587 IDirect3DSwapChain9_Release(swapchain
);
589 hr
= MFCreateVideoSampleFromSurface((IUnknown
*)backbuffer
, &sample
);
591 ok(hr
== S_OK
, "Failed to create surface sample, hr %#x.\n", hr
);
592 if (FAILED(hr
)) goto done
;
594 hr
= IMFSample_QueryInterface(sample
, &IID_IMFTrackedSample
, (void **)&unk
);
595 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
596 IUnknown_Release(unk
);
598 hr
= IMFSample_QueryInterface(sample
, &IID_IMFDesiredSample
, (void **)&unk
);
599 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
600 IUnknown_Release(unk
);
602 hr
= IMFSample_GetCount(sample
, &count
);
603 ok(hr
== S_OK
, "Failed to get attribute count, hr %#x.\n", hr
);
604 ok(!count
, "Unexpected attribute count.\n");
606 hr
= IMFSample_GetBufferCount(sample
, &count
);
607 ok(hr
== S_OK
, "Failed to get buffer count, hr %#x.\n", hr
);
608 ok(count
== 1, "Unexpected attribute count.\n");
610 hr
= IMFSample_GetTotalLength(sample
, &length
);
611 ok(hr
== S_OK
, "Failed to get length, hr %#x.\n", hr
);
612 ok(!length
, "Unexpected length %u.\n", length
);
614 hr
= IMFSample_GetSampleDuration(sample
, &duration
);
615 ok(hr
== MF_E_NO_SAMPLE_DURATION
, "Unexpected hr %#x.\n", hr
);
617 hr
= IMFSample_GetSampleTime(sample
, &duration
);
618 ok(hr
== MF_E_NO_SAMPLE_TIMESTAMP
, "Unexpected hr %#x.\n", hr
);
620 hr
= IMFSample_GetBufferByIndex(sample
, 0, &buffer
);
621 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
623 hr
= IMFMediaBuffer_GetMaxLength(buffer
, &length
);
624 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
626 hr
= IMFMediaBuffer_GetCurrentLength(buffer
, &length
);
627 ok(hr
== S_OK
, "Failed to get length, hr %#x.\n", hr
);
628 ok(!length
, "Unexpected length %u.\n", length
);
630 hr
= IMFMediaBuffer_Lock(buffer
, &data
, NULL
, NULL
);
631 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
633 hr
= IMFMediaBuffer_QueryInterface(buffer
, &IID_IMF2DBuffer
, (void **)&unk
);
634 ok(hr
== E_NOINTERFACE
, "Unexpected hr %#x.\n", hr
);
636 hr
= IMFSample_AddBuffer(sample
, buffer
);
637 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
639 hr
= IMFSample_GetBufferCount(sample
, &count
);
640 ok(hr
== S_OK
, "Failed to get buffer count, hr %#x.\n", hr
);
641 ok(count
== 2, "Unexpected attribute count.\n");
643 hr
= IMFSample_ConvertToContiguousBuffer(sample
, &buffer2
);
644 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
646 hr
= IMFSample_CopyToBuffer(sample
, buffer
);
647 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
649 hr
= IMFSample_RemoveAllBuffers(sample
);
650 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
652 hr
= IMFSample_GetBufferCount(sample
, &count
);
653 ok(hr
== S_OK
, "Failed to get buffer count, hr %#x.\n", hr
);
654 ok(!count
, "Unexpected attribute count.\n");
656 IMFMediaBuffer_Release(buffer
);
658 IMFSample_Release(sample
);
662 IDirect3DSurface9_Release(backbuffer
);
663 IDirect3D9_Release(d3d
);
664 DestroyWindow(window
);
667 static void test_default_mixer_type_negotiation(void)
669 IDirect3DDeviceManager9
*manager
;
670 IMFVideoMediaType
*video_type
;
671 IMFMediaType
*media_type
;
672 IDirect3DDevice9
*device
;
673 IMFTransform
*transform
;
679 if (!pMFCreateVideoMediaTypeFromSubtype
)
681 win_skip("Skipping mixer types tests.\n");
685 hr
= MFCreateVideoMixer(NULL
, &IID_IDirect3DDevice9
, &IID_IMFTransform
, (void **)&transform
);
686 ok(hr
== S_OK
, "Failed to create default mixer, hr %#x.\n", hr
);
688 hr
= IMFTransform_GetInputAvailableType(transform
, 0, 0, &media_type
);
689 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
691 hr
= IMFTransform_GetInputCurrentType(transform
, 0, &media_type
);
693 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#x.\n", hr
);
695 hr
= MFCreateMediaType(&media_type
);
696 ok(hr
== S_OK
, "Failed to create media type, hr %#x.\n", hr
);
698 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
699 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
701 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB32
);
702 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
704 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
705 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#x.\n", hr
);
707 /* Now try with device manager. */
709 window
= create_window();
710 d3d
= Direct3DCreate9(D3D_SDK_VERSION
);
711 ok(!!d3d
, "Failed to create a D3D object.\n");
712 if (!(device
= create_device(d3d
, window
)))
714 skip("Failed to create a D3D device, skipping tests.\n");
718 hr
= DXVA2CreateDirect3DDeviceManager9(&token
, &manager
);
719 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
721 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_SET_D3D_MANAGER
, (ULONG_PTR
)manager
);
722 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
724 /* Now manager is not initialized. */
725 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
726 ok(hr
== DXVA2_E_NOT_INITIALIZED
, "Unexpected hr %#x.\n", hr
);
728 hr
= IDirect3DDeviceManager9_ResetDevice(manager
, device
, token
);
729 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
731 /* And now type description is incomplete. */
732 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
733 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#x.\n", hr
);
734 IMFMediaType_Release(media_type
);
736 hr
= pMFCreateVideoMediaTypeFromSubtype(&MFVideoFormat_RGB32
, &video_type
);
737 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
739 /* Partially initialized type. */
740 hr
= IMFTransform_SetInputType(transform
, 0, (IMFMediaType
*)video_type
, 0);
741 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#x.\n", hr
);
743 /* Only required data - frame size and uncompressed marker. */
744 hr
= IMFVideoMediaType_SetUINT64(video_type
, &MF_MT_FRAME_SIZE
, (UINT64
)640 << 32 | 480);
745 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
746 hr
= IMFVideoMediaType_SetUINT32(video_type
, &MF_MT_ALL_SAMPLES_INDEPENDENT
, TRUE
);
747 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
749 hr
= IMFTransform_SetInputType(transform
, 0, (IMFMediaType
*)video_type
, 0);
751 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
753 hr
= IMFTransform_GetInputCurrentType(transform
, 0, &media_type
);
755 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
758 ok(media_type
!= (IMFMediaType
*)video_type
, "Unexpected pointer.\n");
759 IMFMediaType_Release(media_type
);
762 IMFVideoMediaType_Release(video_type
);
764 IDirect3DDeviceManager9_Release(manager
);
766 IDirect3DDevice9_Release(device
);
769 IMFTransform_Release(transform
);
770 IDirect3D9_Release(d3d
);
771 DestroyWindow(window
);
778 pMFCreateVideoMediaTypeFromSubtype
= (void *)GetProcAddress(GetModuleHandleA("mfplat.dll"), "MFCreateVideoMediaTypeFromSubtype");
785 test_default_mixer();
786 test_default_mixer_type_negotiation();
787 test_surface_sample();