[PSDK]
[reactos.git] / rostests / winetests / amstream / amstream.c
1 /*
2 * Unit tests for MultiMedia Stream functions
3 *
4 * Copyright (C) 2009, 2012 Christian Costa
5 *
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.
10 *
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.
15 *
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
19 */
20
21 #define WIN32_NO_STATUS
22 #define _INC_WINDOWS
23 #define COM_NO_WINDOWS_H
24
25 #define COBJMACROS
26
27 #include <wine/test.h>
28 #include <wingdi.h>
29 #include <winnls.h>
30 #include <vfwmsgs.h>
31 #include <objbase.h>
32 #include <mmreg.h>
33 #include <ks.h>
34 #include <ksmedia.h>
35 #include <initguid.h>
36 #include <amstream.h>
37 #include <dxsdk/uuids.h>
38
39 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
40 static void _expect_ref(IUnknown* obj, ULONG ref, int line)
41 {
42 ULONG rc;
43 IUnknown_AddRef(obj);
44 rc = IUnknown_Release(obj);
45 ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc);
46 }
47
48 static const WCHAR filenameW[] = {'t','e','s','t','.','a','v','i',0};
49
50 static IDirectDraw7* pdd7;
51 static IDirectDrawSurface7* pdds7;
52
53 static IAMMultiMediaStream *create_ammultimediastream(void)
54 {
55 IAMMultiMediaStream *stream = NULL;
56 CoCreateInstance(&CLSID_AMMultiMediaStream, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMultiMediaStream,
57 (void**)&stream);
58 return stream;
59 }
60
61 static int create_directdraw(void)
62 {
63 HRESULT hr;
64 IDirectDraw* pdd = NULL;
65 DDSURFACEDESC2 ddsd;
66
67 hr = DirectDrawCreate(NULL, &pdd, NULL);
68 ok(hr==DD_OK, "DirectDrawCreate returned: %x\n", hr);
69 if (hr != DD_OK)
70 goto error;
71
72 hr = IDirectDraw_QueryInterface(pdd, &IID_IDirectDraw7, (LPVOID*)&pdd7);
73 ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
74 if (hr != DD_OK) goto error;
75
76 hr = IDirectDraw7_SetCooperativeLevel(pdd7, GetDesktopWindow(), DDSCL_NORMAL);
77 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
78
79 ZeroMemory(&ddsd, sizeof(ddsd));
80 ddsd.dwSize = sizeof(ddsd);
81 ddsd.dwFlags = DDSD_CAPS;
82 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
83 hr = IDirectDraw7_CreateSurface(pdd7, &ddsd, &pdds7, NULL);
84 ok(hr==DD_OK, "CreateSurface returned: %x\n", hr);
85
86 return TRUE;
87
88 error:
89 if (pdds7)
90 IDirectDrawSurface7_Release(pdds7);
91 if (pdd7)
92 IDirectDraw7_Release(pdd7);
93 if (pdd)
94 IDirectDraw_Release(pdd);
95
96 return FALSE;
97 }
98
99 static void release_directdraw(void)
100 {
101 IDirectDrawSurface7_Release(pdds7);
102 IDirectDraw7_Release(pdd7);
103 }
104
105 static void test_openfile(void)
106 {
107 IAMMultiMediaStream *pams;
108 HRESULT hr;
109 IGraphBuilder* pgraph;
110
111 if (!(pams = create_ammultimediastream()))
112 return;
113
114 hr = IAMMultiMediaStream_GetFilterGraph(pams, &pgraph);
115 ok(hr==S_OK, "IAMMultiMediaStream_GetFilterGraph returned: %x\n", hr);
116 ok(pgraph==NULL, "Filtergraph should not be created yet\n");
117
118 if (pgraph)
119 IGraphBuilder_Release(pgraph);
120
121 hr = IAMMultiMediaStream_OpenFile(pams, filenameW, 0);
122 ok(hr==S_OK, "IAMMultiMediaStream_OpenFile returned: %x\n", hr);
123
124 hr = IAMMultiMediaStream_GetFilterGraph(pams, &pgraph);
125 ok(hr==S_OK, "IAMMultiMediaStream_GetFilterGraph returned: %x\n", hr);
126 ok(pgraph!=NULL, "Filtergraph should be created\n");
127
128 if (pgraph)
129 IGraphBuilder_Release(pgraph);
130
131 IAMMultiMediaStream_Release(pams);
132 }
133
134 static void test_renderfile(void)
135 {
136 IAMMultiMediaStream *pams;
137 HRESULT hr;
138 IMediaStream *pvidstream = NULL;
139 IDirectDrawMediaStream *pddstream = NULL;
140 IDirectDrawStreamSample *pddsample = NULL;
141 IDirectDrawSurface *surface;
142 RECT rect;
143
144 if (!(pams = create_ammultimediastream()))
145 return;
146 if (!create_directdraw())
147 {
148 IAMMultiMediaStream_Release(pams);
149 return;
150 }
151
152 hr = IAMMultiMediaStream_Initialize(pams, STREAMTYPE_READ, 0, NULL);
153 ok(hr==S_OK, "IAMMultiMediaStream_Initialize returned: %x\n", hr);
154
155 hr = IAMMultiMediaStream_AddMediaStream(pams, (IUnknown*)pdd7, &MSPID_PrimaryVideo, 0, NULL);
156 ok(hr==S_OK, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
157
158 hr = IAMMultiMediaStream_AddMediaStream(pams, NULL, &MSPID_PrimaryAudio, AMMSF_ADDDEFAULTRENDERER, NULL);
159 ok(hr==S_OK, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
160
161 hr = IAMMultiMediaStream_OpenFile(pams, filenameW, 0);
162 ok(hr==S_OK, "IAMMultiMediaStream_OpenFile returned: %x\n", hr);
163
164 hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryVideo, &pvidstream);
165 ok(hr==S_OK, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);
166 if (FAILED(hr)) goto error;
167
168 hr = IMediaStream_QueryInterface(pvidstream, &IID_IDirectDrawMediaStream, (LPVOID*)&pddstream);
169 ok(hr==S_OK, "IMediaStream_QueryInterface returned: %x\n", hr);
170 if (FAILED(hr)) goto error;
171
172 hr = IDirectDrawMediaStream_CreateSample(pddstream, NULL, NULL, 0, &pddsample);
173 ok(hr == S_OK, "IDirectDrawMediaStream_CreateSample returned: %x\n", hr);
174
175 surface = NULL;
176 hr = IDirectDrawStreamSample_GetSurface(pddsample, &surface, &rect);
177 ok(hr == S_OK, "got 0x%08x\n", hr);
178 ok(surface == NULL, "got %p\n", surface);
179 IDirectDrawStreamSample_Release(pddsample);
180
181 hr = IDirectDrawSurface7_QueryInterface(pdds7, &IID_IDirectDrawSurface, (void**)&surface);
182 ok(hr == S_OK, "got 0x%08x\n", hr);
183
184 EXPECT_REF(surface, 1);
185 hr = IDirectDrawMediaStream_CreateSample(pddstream, surface, NULL, 0, &pddsample);
186 ok(hr == S_OK, "IDirectDrawMediaStream_CreateSample returned: %x\n", hr);
187 EXPECT_REF(surface, 2);
188 IDirectDrawStreamSample_Release(pddsample);
189 IDirectDrawSurface_Release(surface);
190
191 error:
192 if (pddstream)
193 IDirectDrawMediaStream_Release(pddstream);
194 if (pvidstream)
195 IMediaStream_Release(pvidstream);
196
197 release_directdraw();
198 IAMMultiMediaStream_Release(pams);
199 }
200
201 static void test_media_streams(void)
202 {
203 IAMMultiMediaStream *pams;
204 HRESULT hr;
205 IMediaStream *video_stream = NULL;
206 IMediaStream *audio_stream = NULL;
207 IMediaStream *dummy_stream;
208 IMediaStreamFilter* media_stream_filter = NULL;
209
210 if (!(pams = create_ammultimediastream()))
211 return;
212 if (!create_directdraw())
213 {
214 IAMMultiMediaStream_Release(pams);
215 return;
216 }
217
218 hr = IAMMultiMediaStream_Initialize(pams, STREAMTYPE_READ, 0, NULL);
219 ok(hr == S_OK, "IAMMultiMediaStream_Initialize returned: %x\n", hr);
220
221 /* Retrieve media stream filter */
222 hr = IAMMultiMediaStream_GetFilter(pams, NULL);
223 ok(hr == E_POINTER, "IAMMultiMediaStream_GetFilter returned: %x\n", hr);
224 hr = IAMMultiMediaStream_GetFilter(pams, &media_stream_filter);
225 ok(hr == S_OK, "IAMMultiMediaStream_GetFilter returned: %x\n", hr);
226
227 /* Verify behaviour with invalid purpose id */
228 hr = IAMMultiMediaStream_GetMediaStream(pams, &IID_IUnknown, &dummy_stream);
229 ok(hr == MS_E_NOSTREAM, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);
230 hr = IAMMultiMediaStream_AddMediaStream(pams, NULL, &IID_IUnknown, 0, NULL);
231 ok(hr == MS_E_PURPOSEID, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
232
233 /* Verify there is no video media stream */
234 hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryVideo, &video_stream);
235 ok(hr == MS_E_NOSTREAM, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);
236
237 /* Verify there is no default renderer for video stream */
238 hr = IAMMultiMediaStream_AddMediaStream(pams, (IUnknown*)pdd7, &MSPID_PrimaryVideo, AMMSF_ADDDEFAULTRENDERER, NULL);
239 ok(hr == MS_E_PURPOSEID, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
240 hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryVideo, &video_stream);
241 ok(hr == MS_E_NOSTREAM, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);
242 hr = IAMMultiMediaStream_AddMediaStream(pams, NULL, &MSPID_PrimaryVideo, AMMSF_ADDDEFAULTRENDERER, NULL);
243 ok(hr == MS_E_PURPOSEID, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
244 hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryVideo, &video_stream);
245 ok(hr == MS_E_NOSTREAM, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);
246
247 /* Verify normal case for video stream */
248 hr = IAMMultiMediaStream_AddMediaStream(pams, NULL, &MSPID_PrimaryVideo, 0, NULL);
249 ok(hr == S_OK, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
250 hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryVideo, &video_stream);
251 ok(hr == S_OK, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);
252
253 /* Verify the video stream has been added to the media stream filter */
254 if (media_stream_filter)
255 {
256 hr = IMediaStreamFilter_GetMediaStream(media_stream_filter, &MSPID_PrimaryVideo, &dummy_stream);
257 ok(hr == S_OK, "IMediaStreamFilter_GetMediaStream returned: %x\n", hr);
258 ok(dummy_stream == video_stream, "Got wrong returned pointer %p, expected %p\n", dummy_stream, video_stream);
259 if (SUCCEEDED(hr))
260 IMediaStream_Release(dummy_stream);
261 }
262
263 /* Check interfaces and samples for video */
264 if (video_stream)
265 {
266 IAMMediaStream* am_media_stream;
267 IMultiMediaStream *multi_media_stream;
268 IAudioMediaStream* audio_media_stream;
269 IDirectDrawMediaStream *ddraw_stream = NULL;
270 IDirectDrawStreamSample *ddraw_sample = NULL;
271
272 hr = IMediaStream_QueryInterface(video_stream, &IID_IAMMediaStream, (LPVOID*)&am_media_stream);
273 ok(hr == S_OK, "IMediaStream_QueryInterface returned: %x\n", hr);
274 ok((void*)am_media_stream == (void*)video_stream, "Not same interface, got %p expected %p\n", am_media_stream, video_stream);
275
276 hr = IAMMediaStream_GetMultiMediaStream(am_media_stream, NULL);
277 ok(hr == E_POINTER, "Expected E_POINTER, got %x\n", hr);
278
279 multi_media_stream = (void *)0xdeadbeef;
280 hr = IAMMediaStream_GetMultiMediaStream(am_media_stream, &multi_media_stream);
281 ok(hr == S_OK, "IAMMediaStream_GetMultiMediaStream returned: %x\n", hr);
282 ok((void *)multi_media_stream == (void *)pams, "Expected %p, got %p\n", pams, multi_media_stream);
283 IMultiMediaStream_Release(multi_media_stream);
284
285 IAMMediaStream_Release(am_media_stream);
286
287 hr = IMediaStream_QueryInterface(video_stream, &IID_IAudioMediaStream, (LPVOID*)&audio_media_stream);
288 ok(hr == E_NOINTERFACE, "IMediaStream_QueryInterface returned: %x\n", hr);
289
290 hr = IMediaStream_QueryInterface(video_stream, &IID_IDirectDrawMediaStream, (LPVOID*)&ddraw_stream);
291 ok(hr == S_OK, "IMediaStream_QueryInterface returned: %x\n", hr);
292
293 if (SUCCEEDED(hr))
294 {
295 DDSURFACEDESC current_format, desired_format;
296 IDirectDrawPalette *palette;
297 DWORD flags;
298
299 hr = IDirectDrawMediaStream_GetFormat(ddraw_stream, &current_format, &palette, &desired_format, &flags);
300 ok(hr == MS_E_NOSTREAM, "IDirectDrawoMediaStream_GetFormat returned: %x\n", hr);
301
302 hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &ddraw_sample);
303 ok(hr == S_OK, "IDirectDrawMediaStream_CreateSample returned: %x\n", hr);
304
305 hr = IDirectDrawMediaStream_GetMultiMediaStream(ddraw_stream, NULL);
306 ok(hr == E_POINTER, "Expected E_POINTER, got %x\n", hr);
307
308 multi_media_stream = (void *)0xdeadbeef;
309 hr = IDirectDrawMediaStream_GetMultiMediaStream(ddraw_stream, &multi_media_stream);
310 ok(hr == S_OK, "IDirectDrawMediaStream_GetMultiMediaStream returned: %x\n", hr);
311 ok((void *)multi_media_stream == (void *)pams, "Expected %p, got %p\n", pams, multi_media_stream);
312 IMultiMediaStream_Release(multi_media_stream);
313 }
314
315 if (ddraw_sample)
316 IDirectDrawStreamSample_Release(ddraw_sample);
317 if (ddraw_stream)
318 IDirectDrawMediaStream_Release(ddraw_stream);
319 }
320
321 /* Verify there is no audio media stream */
322 hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryAudio, &audio_stream);
323 ok(hr == MS_E_NOSTREAM, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);
324
325 /* Verify no stream is created when using the default renderer for audio stream */
326 hr = IAMMultiMediaStream_AddMediaStream(pams, NULL, &MSPID_PrimaryAudio, AMMSF_ADDDEFAULTRENDERER, NULL);
327 ok((hr == S_OK) || (hr == VFW_E_NO_AUDIO_HARDWARE), "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
328 if (hr == S_OK)
329 {
330 IGraphBuilder* filtergraph = NULL;
331 IBaseFilter* filter = NULL;
332 const WCHAR name[] = {'0','0','0','1',0};
333 CLSID clsid;
334
335 hr = IAMMultiMediaStream_GetFilterGraph(pams, &filtergraph);
336 ok(hr == S_OK, "IAMMultiMediaStream_GetFilterGraph returned: %x\n", hr);
337 if (hr == S_OK)
338 {
339 hr = IGraphBuilder_FindFilterByName(filtergraph, name, &filter);
340 ok(hr == S_OK, "IGraphBuilder_FindFilterByName returned: %x\n", hr);
341 }
342 if (hr == S_OK)
343 {
344 hr = IBaseFilter_GetClassID(filter, &clsid);
345 ok(hr == S_OK, "IGraphBuilder_FindFilterByName returned: %x\n", hr);
346 }
347 if (hr == S_OK)
348 ok(IsEqualGUID(&clsid, &CLSID_DSoundRender), "Got wrong CLSID\n");
349 if (filter)
350 IBaseFilter_Release(filter);
351 if (filtergraph)
352 IGraphBuilder_Release(filtergraph);
353 }
354 hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryAudio, &audio_stream);
355 ok(hr == MS_E_NOSTREAM, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);
356
357 /* Verify a stream is created when no default renderer is used */
358 hr = IAMMultiMediaStream_AddMediaStream(pams, NULL, &MSPID_PrimaryAudio, 0, NULL);
359 ok(hr == S_OK, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
360 hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryAudio, &audio_stream);
361 ok(hr == S_OK, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);
362
363 /* verify the audio stream has been added to the media stream filter */
364 if (media_stream_filter)
365 {
366 hr = IMediaStreamFilter_GetMediaStream(media_stream_filter, &MSPID_PrimaryAudio, &dummy_stream);
367 ok(hr == S_OK, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);
368 ok(dummy_stream == audio_stream, "Got wrong returned pointer %p, expected %p\n", dummy_stream, audio_stream);
369 if (SUCCEEDED(hr))
370 IMediaStream_Release(dummy_stream);
371 }
372
373 /* Check interfaces and samples for audio */
374 if (audio_stream)
375 {
376 IAMMediaStream* am_media_stream;
377 IMultiMediaStream *multi_media_stream;
378 IDirectDrawMediaStream* ddraw_stream = NULL;
379 IAudioMediaStream* audio_media_stream = NULL;
380 IAudioStreamSample *audio_sample = NULL;
381
382 hr = IMediaStream_QueryInterface(audio_stream, &IID_IAMMediaStream, (LPVOID*)&am_media_stream);
383 ok(hr == S_OK, "IMediaStream_QueryInterface returned: %x\n", hr);
384 ok((void*)am_media_stream == (void*)audio_stream, "Not same interface, got %p expected %p\n", am_media_stream, audio_stream);
385
386 hr = IAMMediaStream_GetMultiMediaStream(am_media_stream, NULL);
387 ok(hr == E_POINTER, "Expected E_POINTER, got %x\n", hr);
388
389 multi_media_stream = (void *)0xdeadbeef;
390 hr = IAMMediaStream_GetMultiMediaStream(am_media_stream, &multi_media_stream);
391 ok(hr == S_OK, "IAMMediaStream_GetMultiMediaStream returned: %x\n", hr);
392 ok((void *)multi_media_stream == (void *)pams, "Expected %p, got %p\n", pams, multi_media_stream);
393 IMultiMediaStream_Release(multi_media_stream);
394
395 IAMMediaStream_Release(am_media_stream);
396
397 hr = IMediaStream_QueryInterface(audio_stream, &IID_IDirectDrawMediaStream, (LPVOID*)&ddraw_stream);
398 ok(hr == E_NOINTERFACE, "IMediaStream_QueryInterface returned: %x\n", hr);
399
400 hr = IMediaStream_QueryInterface(audio_stream, &IID_IAudioMediaStream, (LPVOID*)&audio_media_stream);
401 ok(hr == S_OK, "IMediaStream_QueryInterface returned: %x\n", hr);
402
403 if (SUCCEEDED(hr))
404 {
405 IAudioData* audio_data = NULL;
406 WAVEFORMATEX format;
407
408 hr = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, &IID_IAudioData, (void **)&audio_data);
409 ok(hr == S_OK, "CoCreateInstance returned: %x\n", hr);
410
411 hr = IAudioMediaStream_GetFormat(audio_media_stream, NULL);
412 ok(hr == E_POINTER, "IAudioMediaStream_GetFormat returned: %x\n", hr);
413 hr = IAudioMediaStream_GetFormat(audio_media_stream, &format);
414 ok(hr == MS_E_NOSTREAM, "IAudioMediaStream_GetFormat returned: %x\n", hr);
415
416 hr = IAudioMediaStream_CreateSample(audio_media_stream, NULL, 0, &audio_sample);
417 ok(hr == E_POINTER, "IAudioMediaStream_CreateSample returned: %x\n", hr);
418 hr = IAudioMediaStream_CreateSample(audio_media_stream, audio_data, 0, &audio_sample);
419 ok(hr == S_OK, "IAudioMediaStream_CreateSample returned: %x\n", hr);
420
421 hr = IAudioMediaStream_GetMultiMediaStream(audio_media_stream, NULL);
422 ok(hr == E_POINTER, "Expected E_POINTER, got %x\n", hr);
423
424 multi_media_stream = (void *)0xdeadbeef;
425 hr = IAudioMediaStream_GetMultiMediaStream(audio_media_stream, &multi_media_stream);
426 ok(hr == S_OK, "IAudioMediaStream_GetMultiMediaStream returned: %x\n", hr);
427 ok((void *)multi_media_stream == (void *)pams, "Expected %p, got %p\n", pams, multi_media_stream);
428 IMultiMediaStream_Release(multi_media_stream);
429
430 if (audio_data)
431 IAudioData_Release(audio_data);
432 if (audio_sample)
433 IAudioStreamSample_Release(audio_sample);
434 if (audio_media_stream)
435 IAudioMediaStream_Release(audio_media_stream);
436 }
437 }
438
439 if (media_stream_filter)
440 {
441 IEnumPins *enum_pins;
442
443 hr = IMediaStreamFilter_EnumPins(media_stream_filter, &enum_pins);
444 ok(hr == S_OK, "IBaseFilter_EnumPins returned: %x\n", hr);
445 if (hr == S_OK)
446 {
447 IPin* pins[3] = { NULL, NULL, NULL };
448 ULONG nb_pins;
449 ULONG expected_nb_pins = audio_stream ? 2 : 1;
450 int i;
451
452 hr = IEnumPins_Next(enum_pins, 3, pins, &nb_pins);
453 ok(SUCCEEDED(hr), "IEnumPins_Next returned: %x\n", hr);
454 ok(nb_pins == expected_nb_pins, "Number of pins is %u instead of %u\n", nb_pins, expected_nb_pins);
455 for (i = 0; i < min(nb_pins, expected_nb_pins); i++)
456 {
457 IEnumMediaTypes* enum_media_types;
458 AM_MEDIA_TYPE* media_types[10];
459 ULONG nb_media_types;
460 IPin* pin;
461 PIN_INFO info;
462 WCHAR id[40];
463
464 /* Pin name is "I{guid MSPID_PrimaryVideo or MSPID_PrimaryAudio}" */
465 id[0] = 'I';
466 StringFromGUID2(i ? &MSPID_PrimaryAudio : &MSPID_PrimaryVideo, id + 1, 40);
467
468 hr = IPin_ConnectedTo(pins[i], &pin);
469 ok(hr == VFW_E_NOT_CONNECTED, "IPin_ConnectedTo returned: %x\n", hr);
470 hr = IPin_QueryPinInfo(pins[i], &info);
471 ok(hr == S_OK, "IPin_QueryPinInfo returned: %x\n", hr);
472 IBaseFilter_Release(info.pFilter);
473 ok(info.dir == PINDIR_INPUT, "Pin direction is %u instead of %u\n", info.dir, PINDIR_INPUT);
474 ok(!lstrcmpW(info.achName, id), "Pin name is %s instead of %s\n", wine_dbgstr_w(info.achName), wine_dbgstr_w(id));
475 hr = IPin_EnumMediaTypes(pins[i], &enum_media_types);
476 ok(hr == S_OK, "IPin_EnumMediaTypes returned: %x\n", hr);
477 hr = IEnumMediaTypes_Next(enum_media_types, sizeof(media_types) / sizeof(media_types[0]), media_types, &nb_media_types);
478 ok(SUCCEEDED(hr), "IEnumMediaTypes_Next returned: %x\n", hr);
479 ok(nb_media_types > 0, "nb_media_types should be >0\n");
480 IEnumMediaTypes_Release(enum_media_types);
481 IPin_Release(pins[i]);
482 }
483 IEnumPins_Release(enum_pins);
484 }
485 }
486
487 /* Test open file with no filename */
488 hr = IAMMultiMediaStream_OpenFile(pams, NULL, 0);
489 ok(hr == E_POINTER, "IAMMultiMediaStream_OpenFile returned %x instead of %x\n", hr, E_POINTER);
490
491 if (video_stream)
492 IMediaStream_Release(video_stream);
493 if (audio_stream)
494 IMediaStream_Release(audio_stream);
495 if (media_stream_filter)
496 IMediaStreamFilter_Release(media_stream_filter);
497
498 release_directdraw();
499 IAMMultiMediaStream_Release(pams);
500 }
501
502 static void test_IDirectDrawStreamSample(void)
503 {
504 DDSURFACEDESC desc = { sizeof(desc) };
505 IAMMultiMediaStream *pams;
506 HRESULT hr;
507 IMediaStream *pvidstream = NULL;
508 IDirectDrawMediaStream *pddstream = NULL;
509 IDirectDrawStreamSample *pddsample = NULL;
510 IDirectDrawSurface7 *surface7;
511 IDirectDrawSurface *surface, *surface2;
512 IDirectDraw *ddraw, *ddraw2;
513 IDirectDraw7 *ddraw7;
514 RECT rect;
515
516 if (!(pams = create_ammultimediastream()))
517 return;
518 if (!create_directdraw())
519 {
520 IAMMultiMediaStream_Release(pams);
521 return;
522 }
523
524 hr = IAMMultiMediaStream_Initialize(pams, STREAMTYPE_READ, 0, NULL);
525 ok(hr == S_OK, "got 0x%08x\n", hr);
526
527 hr = IAMMultiMediaStream_AddMediaStream(pams, (IUnknown*)pdd7, &MSPID_PrimaryVideo, 0, NULL);
528 ok(hr == S_OK, "got 0x%08x\n", hr);
529
530 hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryVideo, &pvidstream);
531 ok(hr == S_OK, "got 0x%08x\n", hr);
532 if (FAILED(hr)) goto error;
533
534 hr = IMediaStream_QueryInterface(pvidstream, &IID_IDirectDrawMediaStream, (LPVOID*)&pddstream);
535 ok(hr == S_OK, "got 0x%08x\n", hr);
536 if (FAILED(hr)) goto error;
537
538 hr = IDirectDrawMediaStream_GetDirectDraw(pddstream, &ddraw);
539 ok(hr == S_OK, "got 0x%08x\n", hr);
540
541 hr = IDirectDrawMediaStream_GetDirectDraw(pddstream, &ddraw2);
542 ok(hr == S_OK, "got 0x%08x\n", hr);
543 ok(ddraw == ddraw2, "got %p, %p\n", ddraw, ddraw2);
544
545 hr = IDirectDraw_QueryInterface(ddraw, &IID_IDirectDraw7, (void**)&ddraw7);
546 ok(hr == S_OK, "got 0x%08x\n", hr);
547 IDirectDraw7_Release(ddraw7);
548
549 IDirectDraw_Release(ddraw2);
550 IDirectDraw_Release(ddraw);
551
552 hr = IDirectDrawMediaStream_CreateSample(pddstream, NULL, NULL, 0, &pddsample);
553 ok(hr == S_OK, "got 0x%08x\n", hr);
554
555 surface = NULL;
556 hr = IDirectDrawStreamSample_GetSurface(pddsample, &surface, &rect);
557 ok(hr == S_OK, "got 0x%08x\n", hr);
558 ok(surface != NULL, "got %p\n", surface);
559
560 hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirectDrawSurface7, (void**)&surface7);
561 ok(hr == S_OK, "got 0x%08x\n", hr);
562 IDirectDrawSurface7_Release(surface7);
563
564 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &desc);
565 ok(hr == S_OK, "got 0x%08x\n", hr);
566 ok(desc.dwWidth == 100, "width %d\n", desc.dwWidth);
567 ok(desc.dwHeight == 100, "height %d\n", desc.dwHeight);
568 ok(desc.ddpfPixelFormat.dwFlags == DDPF_RGB, "format flags %08x\n", desc.ddpfPixelFormat.dwFlags);
569 ok(desc.ddpfPixelFormat.dwRGBBitCount, "dwRGBBitCount %d\n", desc.ddpfPixelFormat.dwRGBBitCount);
570 IDirectDrawSurface_Release(surface);
571 IDirectDrawStreamSample_Release(pddsample);
572
573 hr = IDirectDrawSurface7_QueryInterface(pdds7, &IID_IDirectDrawSurface, (void**)&surface);
574 ok(hr == S_OK, "got 0x%08x\n", hr);
575
576 EXPECT_REF(surface, 1);
577 hr = IDirectDrawMediaStream_CreateSample(pddstream, surface, NULL, 0, &pddsample);
578 ok(hr == S_OK, "got 0x%08x\n", hr);
579 EXPECT_REF(surface, 2);
580
581 surface2 = NULL;
582 memset(&rect, 0, sizeof(rect));
583 hr = IDirectDrawStreamSample_GetSurface(pddsample, &surface2, &rect);
584 ok(hr == S_OK, "got 0x%08x\n", hr);
585 ok(surface == surface2, "got %p\n", surface2);
586 ok(rect.right > 0 && rect.bottom > 0, "got %d, %d\n", rect.right, rect.bottom);
587 EXPECT_REF(surface, 3);
588 IDirectDrawSurface_Release(surface2);
589
590 hr = IDirectDrawStreamSample_GetSurface(pddsample, NULL, NULL);
591 ok(hr == S_OK, "got 0x%08x\n", hr);
592
593 IDirectDrawStreamSample_Release(pddsample);
594 IDirectDrawSurface_Release(surface);
595
596 error:
597 if (pddstream)
598 IDirectDrawMediaStream_Release(pddstream);
599 if (pvidstream)
600 IMediaStream_Release(pvidstream);
601
602 release_directdraw();
603 IAMMultiMediaStream_Release(pams);
604 }
605
606 static IUnknown *create_audio_data(void)
607 {
608 IUnknown *audio_data = NULL;
609 HRESULT result = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER,
610 &IID_IUnknown, (void **)&audio_data);
611 ok(S_OK == result, "got 0x%08x\n", result);
612 return audio_data;
613 }
614
615 static void test_audiodata_query_interface(void)
616 {
617 IUnknown *unknown = create_audio_data();
618 IMemoryData *memory_data = NULL;
619 IAudioData *audio_data = NULL;
620
621 HRESULT result;
622
623 result = IUnknown_QueryInterface(unknown, &IID_IMemoryData, (void **)&memory_data);
624 ok(E_NOINTERFACE == result, "got 0x%08x\n", result);
625
626 result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data);
627 ok(S_OK == result, "got 0x%08x\n", result);
628 if (S_OK == result)
629 {
630 result = IAudioData_QueryInterface(audio_data, &IID_IMemoryData, (void **)&memory_data);
631 ok(E_NOINTERFACE == result, "got 0x%08x\n", result);
632
633 IAudioData_Release(audio_data);
634 }
635
636 IUnknown_Release(unknown);
637 }
638
639 static void test_audiodata_get_info(void)
640 {
641 IUnknown *unknown = create_audio_data();
642 IAudioData *audio_data = NULL;
643
644 HRESULT result;
645
646 result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data);
647 if (FAILED(result))
648 {
649 /* test_audiodata_query_interface handles this case */
650 skip("No IAudioData\n");
651 goto out_unknown;
652 }
653
654 result = IAudioData_GetInfo(audio_data, NULL, NULL, NULL);
655 ok(MS_E_NOTINIT == result, "got 0x%08x\n", result);
656
657 IAudioData_Release(audio_data);
658
659 out_unknown:
660 IUnknown_Release(unknown);
661 }
662
663 static void test_audiodata_set_buffer(void)
664 {
665 IUnknown *unknown = create_audio_data();
666 IAudioData *audio_data = NULL;
667 BYTE buffer[100] = {0};
668 DWORD length = 0;
669 BYTE *data = NULL;
670
671 HRESULT result;
672
673 result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data);
674 if (FAILED(result))
675 {
676 /* test_audiodata_query_interface handles this case */
677 skip("No IAudioData\n");
678 goto out_unknown;
679 }
680
681 result = IAudioData_SetBuffer(audio_data, 100, NULL, 0);
682 ok(S_OK == result, "got 0x%08x\n", result);
683
684 data = (BYTE *)0xdeadbeef;
685 length = 0xdeadbeef;
686 result = IAudioData_GetInfo(audio_data, &length, &data, NULL);
687 ok(S_OK == result, "got 0x%08x\n", result);
688 ok(100 == length, "got %u\n", length);
689 ok(NULL != data, "got %p\n", data);
690
691 result = IAudioData_SetBuffer(audio_data, 0, buffer, 0);
692 ok(E_INVALIDARG == result, "got 0x%08x\n", result);
693
694 result = IAudioData_SetBuffer(audio_data, sizeof(buffer), buffer, 0);
695 ok(S_OK == result, "got 0x%08x\n", result);
696
697 data = (BYTE *)0xdeadbeef;
698 length = 0xdeadbeef;
699 result = IAudioData_GetInfo(audio_data, &length, &data, NULL);
700 ok(S_OK == result, "got 0x%08x\n", result);
701 ok(sizeof(buffer) == length, "got %u\n", length);
702 ok(buffer == data, "got %p\n", data);
703
704 IAudioData_Release(audio_data);
705
706 out_unknown:
707 IUnknown_Release(unknown);
708 }
709
710 static void test_audiodata_set_actual(void)
711 {
712 IUnknown *unknown = create_audio_data();
713 IAudioData *audio_data = NULL;
714 BYTE buffer[100] = {0};
715 DWORD actual_data = 0;
716
717 HRESULT result;
718
719 result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data);
720 if (FAILED(result))
721 {
722 /* test_audiodata_query_interface handles this case */
723 skip("No IAudioData\n");
724 goto out_unknown;
725 }
726
727 result = IAudioData_SetActual(audio_data, 0);
728 ok(S_OK == result, "got 0x%08x\n", result);
729
730 result = IAudioData_SetBuffer(audio_data, sizeof(buffer), buffer, 0);
731 ok(S_OK == result, "got 0x%08x\n", result);
732
733 result = IAudioData_SetActual(audio_data, sizeof(buffer) + 1);
734 ok(E_INVALIDARG == result, "got 0x%08x\n", result);
735
736 result = IAudioData_SetActual(audio_data, sizeof(buffer));
737 ok(S_OK == result, "got 0x%08x\n", result);
738
739 actual_data = 0xdeadbeef;
740 result = IAudioData_GetInfo(audio_data, NULL, NULL, &actual_data);
741 ok(S_OK == result, "got 0x%08x\n", result);
742 ok(sizeof(buffer) == actual_data, "got %u\n", actual_data);
743
744 result = IAudioData_SetActual(audio_data, 0);
745 ok(S_OK == result, "got 0x%08x\n", result);
746
747 actual_data = 0xdeadbeef;
748 result = IAudioData_GetInfo(audio_data, NULL, NULL, &actual_data);
749 ok(S_OK == result, "got 0x%08x\n", result);
750 ok(0 == actual_data, "got %u\n", actual_data);
751
752 IAudioData_Release(audio_data);
753
754 out_unknown:
755 IUnknown_Release(unknown);
756 }
757
758 static void test_audiodata_get_format(void)
759 {
760 IUnknown *unknown = create_audio_data();
761 IAudioData *audio_data = NULL;
762 WAVEFORMATEX wave_format = {0};
763
764 HRESULT result;
765
766 result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data);
767 if (FAILED(result))
768 {
769 /* test_audiodata_query_interface handles this case */
770 skip("No IAudioData\n");
771 goto out_unknown;
772 }
773
774 result = IAudioData_GetFormat(audio_data, NULL);
775 ok(E_POINTER == result, "got 0x%08x\n", result);
776
777 wave_format.wFormatTag = 0xdead;
778 wave_format.nChannels = 0xdead;
779 wave_format.nSamplesPerSec = 0xdeadbeef;
780 wave_format.nAvgBytesPerSec = 0xdeadbeef;
781 wave_format.nBlockAlign = 0xdead;
782 wave_format.wBitsPerSample = 0xdead;
783 wave_format.cbSize = 0xdead;
784 result = IAudioData_GetFormat(audio_data, &wave_format);
785 ok(S_OK == result, "got 0x%08x\n", result);
786 ok(WAVE_FORMAT_PCM == wave_format.wFormatTag, "got %u\n", wave_format.wFormatTag);
787 ok(1 == wave_format.nChannels, "got %u\n", wave_format.nChannels);
788 ok(11025 == wave_format.nSamplesPerSec, "got %u\n", wave_format.nSamplesPerSec);
789 ok(22050 == wave_format.nAvgBytesPerSec, "got %u\n", wave_format.nAvgBytesPerSec);
790 ok(2 == wave_format.nBlockAlign, "got %u\n", wave_format.nBlockAlign);
791 ok(16 == wave_format.wBitsPerSample, "got %u\n", wave_format.wBitsPerSample);
792 ok(0 == wave_format.cbSize, "got %u\n", wave_format.cbSize);
793
794 IAudioData_Release(audio_data);
795
796 out_unknown:
797 IUnknown_Release(unknown);
798 }
799
800 static void test_audiodata_set_format(void)
801 {
802 IUnknown *unknown = create_audio_data();
803 IAudioData *audio_data = NULL;
804 WAVEFORMATPCMEX wave_format = {{0}};
805
806 HRESULT result;
807
808 result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data);
809 if (FAILED(result))
810 {
811 /* test_audiodata_query_interface handles this case */
812 skip("No IAudioData\n");
813 goto out_unknown;
814 }
815
816 result = IAudioData_SetFormat(audio_data, NULL);
817 ok(E_POINTER == result, "got 0x%08x\n", result);
818
819 wave_format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
820 wave_format.Format.nChannels = 2;
821 wave_format.Format.nSamplesPerSec = 44100;
822 wave_format.Format.nAvgBytesPerSec = 176400;
823 wave_format.Format.nBlockAlign = 4;
824 wave_format.Format.wBitsPerSample = 16;
825 wave_format.Format.cbSize = 22;
826 wave_format.Samples.wValidBitsPerSample = 16;
827 wave_format.dwChannelMask = KSAUDIO_SPEAKER_STEREO;
828 wave_format.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
829 result = IAudioData_SetFormat(audio_data, &wave_format.Format);
830 ok(E_INVALIDARG == result, "got 0x%08x\n", result);
831
832 wave_format.Format.wFormatTag = WAVE_FORMAT_PCM;
833 wave_format.Format.nChannels = 2;
834 wave_format.Format.nSamplesPerSec = 44100;
835 wave_format.Format.nAvgBytesPerSec = 176400;
836 wave_format.Format.nBlockAlign = 4;
837 wave_format.Format.wBitsPerSample = 16;
838 wave_format.Format.cbSize = 0;
839 result = IAudioData_SetFormat(audio_data, &wave_format.Format);
840 ok(S_OK == result, "got 0x%08x\n", result);
841
842 wave_format.Format.wFormatTag = 0xdead;
843 wave_format.Format.nChannels = 0xdead;
844 wave_format.Format.nSamplesPerSec = 0xdeadbeef;
845 wave_format.Format.nAvgBytesPerSec = 0xdeadbeef;
846 wave_format.Format.nBlockAlign = 0xdead;
847 wave_format.Format.wBitsPerSample = 0xdead;
848 wave_format.Format.cbSize = 0xdead;
849 result = IAudioData_GetFormat(audio_data, &wave_format.Format);
850 ok(S_OK == result, "got 0x%08x\n", result);
851 ok(WAVE_FORMAT_PCM == wave_format.Format.wFormatTag, "got %u\n", wave_format.Format.wFormatTag);
852 ok(2 == wave_format.Format.nChannels, "got %u\n", wave_format.Format.nChannels);
853 ok(44100 == wave_format.Format.nSamplesPerSec, "got %u\n", wave_format.Format.nSamplesPerSec);
854 ok(176400 == wave_format.Format.nAvgBytesPerSec, "got %u\n", wave_format.Format.nAvgBytesPerSec);
855 ok(4 == wave_format.Format.nBlockAlign, "got %u\n", wave_format.Format.nBlockAlign);
856 ok(16 == wave_format.Format.wBitsPerSample, "got %u\n", wave_format.Format.wBitsPerSample);
857 ok(0 == wave_format.Format.cbSize, "got %u\n", wave_format.Format.cbSize);
858
859 IAudioData_Release(audio_data);
860
861 out_unknown:
862 IUnknown_Release(unknown);
863 }
864
865 START_TEST(amstream)
866 {
867 HANDLE file;
868
869 CoInitializeEx(NULL, COINIT_MULTITHREADED);
870
871 test_media_streams();
872 test_IDirectDrawStreamSample();
873
874 file = CreateFileW(filenameW, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
875 if (file != INVALID_HANDLE_VALUE)
876 {
877 CloseHandle(file);
878
879 test_openfile();
880 test_renderfile();
881 }
882
883 test_audiodata_query_interface();
884 test_audiodata_get_info();
885 test_audiodata_set_buffer();
886 test_audiodata_set_actual();
887 test_audiodata_get_format();
888 test_audiodata_set_format();
889
890 CoUninitialize();
891 }