amstream: Add stubbed implementation of DirectDrawStreamSample.
[wine] / dlls / amstream / tests / 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 COBJMACROS
22
23 #include "wine/test.h"
24 #include "initguid.h"
25 #include "uuids.h"
26 #include "amstream.h"
27 #include "vfwmsgs.h"
28
29 static const WCHAR filenameW[] = {'t','e','s','t','.','a','v','i',0};
30
31 static IAMMultiMediaStream* pams;
32 static IDirectDraw7* pdd7;
33 static IDirectDrawSurface7* pdds7;
34
35 static int create_ammultimediastream(void)
36 {
37     return S_OK == CoCreateInstance(
38         &CLSID_AMMultiMediaStream, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMultiMediaStream, (LPVOID*)&pams);
39 }
40
41 static void release_ammultimediastream(void)
42 {
43     IAMMultiMediaStream_Release(pams);
44 }
45
46 static int create_directdraw(void)
47 {
48     HRESULT hr;
49     IDirectDraw* pdd = NULL;
50     DDSURFACEDESC2 ddsd;
51
52     hr = DirectDrawCreate(NULL, &pdd, NULL);
53     ok(hr==DD_OK, "DirectDrawCreate returned: %x\n", hr);
54     if (hr != DD_OK)
55        goto error;
56
57     hr = IDirectDraw_QueryInterface(pdd, &IID_IDirectDraw7, (LPVOID*)&pdd7);
58     ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
59     if (hr != DD_OK) goto error;
60
61     hr = IDirectDraw7_SetCooperativeLevel(pdd7, GetDesktopWindow(), DDSCL_NORMAL);
62     ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
63
64     ZeroMemory(&ddsd, sizeof(ddsd));
65     ddsd.dwSize = sizeof(ddsd);
66     ddsd.dwFlags = DDSD_CAPS;
67     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
68     hr = IDirectDraw7_CreateSurface(pdd7, &ddsd, &pdds7, NULL);
69     ok(hr==DD_OK, "CreateSurface returned: %x\n", hr);
70
71     return TRUE;
72
73 error:
74     if (pdds7)
75         IDirectDrawSurface7_Release(pdds7);
76     if (pdd7)
77         IDirectDraw7_Release(pdd7);
78     if (pdd)
79         IDirectDraw_Release(pdd);
80
81     return FALSE;
82 }
83
84 static void release_directdraw(void)
85 {
86     IDirectDrawSurface7_Release(pdds7);
87     IDirectDraw7_Release(pdd7);
88 }
89
90 static void test_openfile(void)
91 {
92     HRESULT hr;
93     IGraphBuilder* pgraph;
94
95     if (!create_ammultimediastream())
96         return;
97
98     hr = IAMMultiMediaStream_GetFilterGraph(pams, &pgraph);
99     ok(hr==S_OK, "IAMMultiMediaStream_GetFilterGraph returned: %x\n", hr);
100     ok(pgraph==NULL, "Filtergraph should not be created yet\n");
101
102     if (pgraph)
103         IGraphBuilder_Release(pgraph);
104
105     hr = IAMMultiMediaStream_OpenFile(pams, filenameW, 0);
106     ok(hr==S_OK, "IAMMultiMediaStream_OpenFile returned: %x\n", hr);
107
108     hr = IAMMultiMediaStream_GetFilterGraph(pams, &pgraph);
109     ok(hr==S_OK, "IAMMultiMediaStream_GetFilterGraph returned: %x\n", hr);
110     ok(pgraph!=NULL, "Filtergraph should be created\n");
111
112     if (pgraph)
113         IGraphBuilder_Release(pgraph);
114
115     release_ammultimediastream();
116 }
117
118 static void test_renderfile(void)
119 {
120     HRESULT hr;
121     IMediaStream *pvidstream = NULL;
122     IDirectDrawMediaStream *pddstream = NULL;
123     IDirectDrawStreamSample *pddsample = NULL;
124
125     if (!create_ammultimediastream())
126         return;
127     if (!create_directdraw())
128     {
129         release_ammultimediastream();
130         return;
131     }
132
133     hr = IAMMultiMediaStream_Initialize(pams, STREAMTYPE_READ, 0, NULL);
134     ok(hr==S_OK, "IAMMultiMediaStream_Initialize returned: %x\n", hr);
135
136     hr = IAMMultiMediaStream_AddMediaStream(pams, (IUnknown*)pdd7, &MSPID_PrimaryVideo, 0, NULL);
137     ok(hr==S_OK, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
138
139     hr = IAMMultiMediaStream_AddMediaStream(pams, NULL, &MSPID_PrimaryAudio, AMMSF_ADDDEFAULTRENDERER, NULL);
140     ok(hr==S_OK, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
141
142     hr = IAMMultiMediaStream_OpenFile(pams, filenameW, 0);
143     ok(hr==S_OK, "IAMMultiMediaStream_OpenFile returned: %x\n", hr);
144
145     hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryVideo, &pvidstream);
146     ok(hr==S_OK, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);
147     if (FAILED(hr)) goto error;
148
149     hr = IMediaStream_QueryInterface(pvidstream, &IID_IDirectDrawMediaStream, (LPVOID*)&pddstream);
150     ok(hr==S_OK, "IMediaStream_QueryInterface returned: %x\n", hr);
151     if (FAILED(hr)) goto error;
152
153     hr = IDirectDrawMediaStream_CreateSample(pddstream, NULL, NULL, 0, &pddsample);
154     ok(hr == S_OK, "IDirectDrawMediaStream_CreateSample returned: %x\n", hr);
155
156 error:
157     if (pddsample)
158         IDirectDrawMediaSample_Release(pddsample);
159     if (pddstream)
160         IDirectDrawMediaStream_Release(pddstream);
161     if (pvidstream)
162         IMediaStream_Release(pvidstream);
163
164     release_directdraw();
165     release_ammultimediastream();
166 }
167
168 static void test_media_streams(void)
169 {
170     HRESULT hr;
171     IMediaStream *video_stream = NULL;
172     IMediaStream *audio_stream = NULL;
173     IMediaStream *dummy_stream;
174     IMediaStreamFilter* media_stream_filter = NULL;
175
176     if (!create_ammultimediastream())
177         return;
178     if (!create_directdraw())
179     {
180         release_ammultimediastream();
181         return;
182     }
183
184     hr = IAMMultiMediaStream_Initialize(pams, STREAMTYPE_READ, 0, NULL);
185     ok(hr == S_OK, "IAMMultiMediaStream_Initialize returned: %x\n", hr);
186
187     /* Retreive media stream filter */
188     hr = IAMMultiMediaStream_GetFilter(pams, NULL);
189     ok(hr == E_POINTER, "IAMMultiMediaStream_GetFilter returned: %x\n", hr);
190     hr = IAMMultiMediaStream_GetFilter(pams, &media_stream_filter);
191     ok(hr == S_OK, "IAMMultiMediaStream_GetFilter returned: %x\n", hr);
192
193     /* Verify behaviour with invalid purpose id */
194     hr = IAMMultiMediaStream_GetMediaStream(pams, &IID_IUnknown, &dummy_stream);
195     ok(hr == MS_E_NOSTREAM, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);
196     hr = IAMMultiMediaStream_AddMediaStream(pams, NULL, &IID_IUnknown, 0, NULL);
197     ok(hr == MS_E_PURPOSEID, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
198
199     /* Verify there is no video media stream */
200     hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryVideo, &video_stream);
201     ok(hr == MS_E_NOSTREAM, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);
202
203     /* Verify there is no default renderer for video stream */
204     hr = IAMMultiMediaStream_AddMediaStream(pams, (IUnknown*)pdd7, &MSPID_PrimaryVideo, AMMSF_ADDDEFAULTRENDERER, NULL);
205     ok(hr == MS_E_PURPOSEID, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
206     hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryVideo, &video_stream);
207     ok(hr == MS_E_NOSTREAM, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);
208     hr = IAMMultiMediaStream_AddMediaStream(pams, NULL, &MSPID_PrimaryVideo, AMMSF_ADDDEFAULTRENDERER, NULL);
209     ok(hr == MS_E_PURPOSEID, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
210     hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryVideo, &video_stream);
211     ok(hr == MS_E_NOSTREAM, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);
212
213     /* Verify normal case for video stream */
214     hr = IAMMultiMediaStream_AddMediaStream(pams, NULL, &MSPID_PrimaryVideo, 0, NULL);
215     ok(hr == S_OK, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
216     hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryVideo, &video_stream);
217     ok(hr == S_OK, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);
218
219     /* Verify the video stream has been added to the media stream filter */
220     if (media_stream_filter)
221     {
222         hr = IMediaStreamFilter_GetMediaStream(media_stream_filter, &MSPID_PrimaryVideo, &dummy_stream);
223         ok(hr == S_OK, "IMediaStreamFilter_GetMediaStream returned: %x\n", hr);
224         ok(dummy_stream == video_stream, "Got wrong returned pointer %p, expected %p\n", dummy_stream, video_stream);
225         if (SUCCEEDED(hr))
226             IMediaStream_Release(dummy_stream);
227     }
228
229     /* Check interfaces and samples for video */
230     if (video_stream)
231     {
232         IAMMediaStream* am_media_stream;
233         IAudioMediaStream* audio_media_stream;
234         IDirectDrawMediaStream *ddraw_stream = NULL;
235         IDirectDrawStreamSample *ddraw_sample = NULL;
236
237         hr = IMediaStream_QueryInterface(video_stream, &IID_IAMMediaStream, (LPVOID*)&am_media_stream);
238         todo_wine ok(hr == S_OK, "IMediaStream_QueryInterface returned: %x\n", hr);
239         todo_wine ok((void*)am_media_stream == (void*)video_stream, "Not same interface, got %p expected %p\n", am_media_stream, video_stream);
240         if (hr == S_OK)
241             IAMMediaStream_Release(am_media_stream);
242
243         hr = IMediaStream_QueryInterface(video_stream, &IID_IAudioMediaStream, (LPVOID*)&audio_media_stream);
244         ok(hr == E_NOINTERFACE, "IMediaStream_QueryInterface returned: %x\n", hr);
245
246         hr = IMediaStream_QueryInterface(video_stream, &IID_IDirectDrawMediaStream, (LPVOID*)&ddraw_stream);
247         ok(hr == S_OK, "IMediaStream_QueryInterface returned: %x\n", hr);
248
249         if (SUCCEEDED(hr))
250         {
251             hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &ddraw_sample);
252             ok(hr == S_OK, "IDirectDrawMediaStream_CreateSample returned: %x\n", hr);
253         }
254
255         if (ddraw_sample)
256             IDirectDrawMediaSample_Release(ddraw_sample);
257         if (ddraw_stream)
258             IDirectDrawMediaStream_Release(ddraw_stream);
259     }
260
261     /* Verify there is no audio media stream */
262     hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryAudio, &audio_stream);
263     ok(hr == MS_E_NOSTREAM, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);
264
265     /* Verify no stream is created when using the default renderer for audio stream */
266     hr = IAMMultiMediaStream_AddMediaStream(pams, NULL, &MSPID_PrimaryAudio, AMMSF_ADDDEFAULTRENDERER, NULL);
267     ok((hr == S_OK) || (hr == VFW_E_NO_AUDIO_HARDWARE), "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
268     if (hr == S_OK)
269     {
270         IGraphBuilder* filtergraph = NULL;
271         IBaseFilter* filter = NULL;
272         const WCHAR name[] = {'0','0','0','1',0};
273         CLSID clsid;
274
275         hr = IAMMultiMediaStream_GetFilterGraph(pams, &filtergraph);
276         ok(hr == S_OK, "IAMMultiMediaStream_GetFilterGraph returned: %x\n", hr);
277         if (hr == S_OK)
278         {
279             hr = IGraphBuilder_FindFilterByName(filtergraph, name, &filter);
280             ok(hr == S_OK, "IGraphBuilder_FindFilterByName returned: %x\n", hr);
281         }
282         if (hr == S_OK)
283         {
284             hr = IBaseFilter_GetClassID(filter, &clsid);
285             ok(hr == S_OK, "IGraphBuilder_FindFilterByName returned: %x\n", hr);
286         }
287         if (hr == S_OK)
288             ok(IsEqualGUID(&clsid, &CLSID_DSoundRender), "Got wrong CLSID\n");
289         if (filter)
290             IBaseFilter_Release(filter);
291         if (filtergraph)
292             IGraphBuilder_Release(filtergraph);
293     }
294     hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryAudio, &audio_stream);
295     ok(hr == MS_E_NOSTREAM, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);
296
297     /* Verify a stream is created when no default renderer is used */
298     hr = IAMMultiMediaStream_AddMediaStream(pams, NULL, &MSPID_PrimaryAudio, 0, NULL);
299     ok(hr == S_OK, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
300     hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryAudio, &audio_stream);
301     ok(hr == S_OK, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);
302
303     /* verify the audio stream has been added to the media stream filter */
304     if (media_stream_filter)
305     {
306         hr = IMediaStreamFilter_GetMediaStream(media_stream_filter, &MSPID_PrimaryAudio, &dummy_stream);
307         ok(hr == S_OK, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);
308         ok(dummy_stream == audio_stream, "Got wrong returned pointer %p, expected %p\n", dummy_stream, audio_stream);
309         if (SUCCEEDED(hr))
310             IMediaStream_Release(dummy_stream);
311     }
312
313    /* Check interfaces and samples for audio */
314     if (audio_stream)
315     {
316         IAMMediaStream* am_media_stream;
317         IDirectDrawMediaStream* ddraw_stream = NULL;
318         IAudioMediaStream* audio_media_stream = NULL;
319         IAudioStreamSample *audio_sample = NULL;
320
321         hr = IMediaStream_QueryInterface(audio_stream, &IID_IAMMediaStream, (LPVOID*)&am_media_stream);
322         todo_wine ok(hr == S_OK, "IMediaStream_QueryInterface returned: %x\n", hr);
323         todo_wine ok((void*)am_media_stream == (void*)audio_stream, "Not same interface, got %p expected %p\n", am_media_stream, video_stream);
324         if (hr == S_OK)
325             IAMMediaStream_Release(am_media_stream);
326
327         hr = IMediaStream_QueryInterface(audio_stream, &IID_IDirectDrawMediaStream, (LPVOID*)&ddraw_stream);
328         ok(hr == E_NOINTERFACE, "IMediaStream_QueryInterface returned: %x\n", hr);
329
330         hr = IMediaStream_QueryInterface(audio_stream, &IID_IAudioMediaStream, (LPVOID*)&audio_media_stream);
331         ok(hr == S_OK, "IMediaStream_QueryInterface returned: %x\n", hr);
332
333         if (SUCCEEDED(hr))
334         {
335             IAudioData* audio_data = NULL;
336             hr = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, &IID_IAudioData, (void **)&audio_data);
337             ok(hr == S_OK, "CoCreateInstance returned: %x\n", hr);
338
339             hr = IAudioMediaStream_CreateSample(audio_media_stream, NULL, 0, &audio_sample);
340             todo_wine ok(hr == E_POINTER, "IAudioMediaStream_CreateSample returned: %x\n", hr);
341             hr = IAudioMediaStream_CreateSample(audio_media_stream, audio_data, 0, &audio_sample);
342             todo_wine ok(hr == S_OK, "IAudioMediaStream_CreateSample returned: %x\n", hr);
343
344             if (audio_data)
345                 IAudioData_Release(audio_data);
346             if (audio_sample)
347                 IAudioStreamSample_Release(audio_sample);
348             if (audio_media_stream)
349                 IAudioMediaStream_Release(audio_media_stream);
350         }
351     }
352
353     if (video_stream)
354         IMediaStream_Release(video_stream);
355     if (audio_stream)
356         IMediaStream_Release(audio_stream);
357     if (media_stream_filter)
358         IMediaStreamFilter_Release(media_stream_filter);
359
360     release_directdraw();
361     release_ammultimediastream();
362 }
363
364 START_TEST(amstream)
365 {
366     HANDLE file;
367
368     CoInitializeEx(NULL, COINIT_MULTITHREADED);
369
370     test_media_streams();
371
372     file = CreateFileW(filenameW, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
373     if (file != INVALID_HANDLE_VALUE)
374     {
375         CloseHandle(file);
376
377         test_openfile();
378         test_renderfile();
379     }
380
381     CoUninitialize();
382 }