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