Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/dlls/amstream/tests/amstream.c
4395 views
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
#include <stdbool.h>
23
#include "wine/test.h"
24
#include "dshow.h"
25
#include "amstream.h"
26
#include "mmreg.h"
27
#include "ks.h"
28
#include "initguid.h"
29
#include "ksmedia.h"
30
#include "dvdmedia.h"
31
#include "wmcodecdsp.h"
32
#include "wine/strmbase.h"
33
34
static const WAVEFORMATEX audio_format =
35
{
36
.wFormatTag = WAVE_FORMAT_PCM,
37
.nChannels = 1,
38
.nSamplesPerSec = 11025,
39
.wBitsPerSample = 16,
40
.nBlockAlign = 2,
41
.nAvgBytesPerSec = 2 * 11025,
42
};
43
44
static const AM_MEDIA_TYPE audio_mt =
45
{
46
/* MEDIATYPE_Audio, MEDIASUBTYPE_PCM, FORMAT_WaveFormatEx */
47
.majortype = {0x73647561, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
48
.subtype = {0x00000001, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
49
.formattype = {0x05589f81, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}},
50
.cbFormat = sizeof(WAVEFORMATEX),
51
.pbFormat = (BYTE *)&audio_format,
52
};
53
54
static const VIDEOINFO rgb8_video_info =
55
{
56
.bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
57
.bmiHeader.biWidth = 333,
58
.bmiHeader.biHeight = -444,
59
.bmiHeader.biPlanes = 1,
60
.bmiHeader.biBitCount = 8,
61
.bmiHeader.biCompression = BI_RGB,
62
};
63
64
static const VIDEOINFO rgb555_video_info =
65
{
66
.bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
67
.bmiHeader.biWidth = 333,
68
.bmiHeader.biHeight = -444,
69
.bmiHeader.biPlanes = 1,
70
.bmiHeader.biBitCount = 16,
71
.bmiHeader.biCompression = BI_RGB,
72
};
73
74
static const VIDEOINFO rgb565_video_info =
75
{
76
.bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
77
.bmiHeader.biWidth = 333,
78
.bmiHeader.biHeight = -444,
79
.bmiHeader.biPlanes = 1,
80
.bmiHeader.biBitCount = 16,
81
.bmiHeader.biCompression = BI_BITFIELDS,
82
.dwBitMasks = {0xf800, 0x07e0, 0x001f},
83
};
84
85
static const VIDEOINFO rgb24_video_info =
86
{
87
.bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
88
.bmiHeader.biWidth = 333,
89
.bmiHeader.biHeight = -444,
90
.bmiHeader.biPlanes = 1,
91
.bmiHeader.biBitCount = 24,
92
.bmiHeader.biCompression = BI_RGB,
93
};
94
95
static const VIDEOINFO rgb32_video_info =
96
{
97
.bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
98
.bmiHeader.biWidth = 333,
99
.bmiHeader.biHeight = -444,
100
.bmiHeader.biPlanes = 1,
101
.bmiHeader.biBitCount = 32,
102
.bmiHeader.biCompression = BI_RGB,
103
};
104
105
static const AM_MEDIA_TYPE rgb8_mt =
106
{
107
/* MEDIATYPE_Video, MEDIASUBTYPE_RGB8, FORMAT_VideoInfo */
108
.majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
109
.subtype = {0xe436eb7a, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}},
110
.formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}},
111
.cbFormat = sizeof(VIDEOINFO),
112
.pbFormat = (BYTE *)&rgb8_video_info,
113
};
114
115
static const AM_MEDIA_TYPE rgb555_mt =
116
{
117
/* MEDIATYPE_Video, MEDIASUBTYPE_RGB555, FORMAT_VideoInfo */
118
.majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
119
.subtype = {0xe436eb7c, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}},
120
.formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}},
121
.cbFormat = sizeof(VIDEOINFO),
122
.pbFormat = (BYTE *)&rgb555_video_info,
123
};
124
125
static const AM_MEDIA_TYPE rgb565_mt =
126
{
127
/* MEDIATYPE_Video, MEDIASUBTYPE_RGB565, FORMAT_VideoInfo */
128
.majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
129
.subtype = {0xe436eb7b, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}},
130
.formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}},
131
.cbFormat = sizeof(VIDEOINFO),
132
.pbFormat = (BYTE *)&rgb565_video_info,
133
};
134
135
static const AM_MEDIA_TYPE rgb24_mt =
136
{
137
/* MEDIATYPE_Video, MEDIASUBTYPE_RGB24, FORMAT_VideoInfo */
138
.majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
139
.subtype = {0xe436eb7d, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}},
140
.formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}},
141
.cbFormat = sizeof(VIDEOINFO),
142
.pbFormat = (BYTE *)&rgb24_video_info,
143
};
144
145
static const AM_MEDIA_TYPE rgb32_mt =
146
{
147
/* MEDIATYPE_Video, MEDIASUBTYPE_RGB32, FORMAT_VideoInfo */
148
.majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
149
.subtype = {0xe436eb7e, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}},
150
.formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}},
151
.cbFormat = sizeof(VIDEOINFO),
152
.pbFormat = (BYTE *)&rgb32_video_info,
153
};
154
155
static const DDSURFACEDESC rgb8_format =
156
{
157
.dwSize = sizeof(DDSURFACEDESC),
158
.dwFlags = DDSD_PIXELFORMAT,
159
.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
160
.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8,
161
.ddpfPixelFormat.dwRGBBitCount = 8,
162
};
163
164
static const DDSURFACEDESC rgb555_format =
165
{
166
.dwSize = sizeof(DDSURFACEDESC),
167
.dwFlags = DDSD_PIXELFORMAT,
168
.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
169
.ddpfPixelFormat.dwFlags = DDPF_RGB,
170
.ddpfPixelFormat.dwRGBBitCount = 16,
171
.ddpfPixelFormat.dwRBitMask = 0x7c00,
172
.ddpfPixelFormat.dwGBitMask = 0x03e0,
173
.ddpfPixelFormat.dwBBitMask = 0x001f,
174
};
175
176
static const DDSURFACEDESC rgb565_format =
177
{
178
.dwSize = sizeof(DDSURFACEDESC),
179
.dwFlags = DDSD_PIXELFORMAT,
180
.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
181
.ddpfPixelFormat.dwFlags = DDPF_RGB,
182
.ddpfPixelFormat.dwRGBBitCount = 16,
183
.ddpfPixelFormat.dwRBitMask = 0xf800,
184
.ddpfPixelFormat.dwGBitMask = 0x07e0,
185
.ddpfPixelFormat.dwBBitMask = 0x001f,
186
};
187
188
static const DDSURFACEDESC rgb24_format =
189
{
190
.dwSize = sizeof(DDSURFACEDESC),
191
.dwFlags = DDSD_PIXELFORMAT,
192
.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
193
.ddpfPixelFormat.dwFlags = DDPF_RGB,
194
.ddpfPixelFormat.dwRGBBitCount = 24,
195
.ddpfPixelFormat.dwRBitMask = 0xff0000,
196
.ddpfPixelFormat.dwGBitMask = 0x00ff00,
197
.ddpfPixelFormat.dwBBitMask = 0x0000ff,
198
};
199
200
static const DDSURFACEDESC rgb32_format =
201
{
202
.dwSize = sizeof(DDSURFACEDESC),
203
.dwFlags = DDSD_PIXELFORMAT,
204
.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
205
.ddpfPixelFormat.dwFlags = DDPF_RGB,
206
.ddpfPixelFormat.dwRGBBitCount = 32,
207
.ddpfPixelFormat.dwRBitMask = 0xff0000,
208
.ddpfPixelFormat.dwGBitMask = 0x00ff00,
209
.ddpfPixelFormat.dwBBitMask = 0x0000ff,
210
};
211
212
static const DDSURFACEDESC argb32_format =
213
{
214
.dwSize = sizeof(DDSURFACEDESC),
215
.dwFlags = DDSD_PIXELFORMAT,
216
.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
217
.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS,
218
.ddpfPixelFormat.dwRGBBitCount = 32,
219
.ddpfPixelFormat.dwRBitMask = 0xff0000,
220
.ddpfPixelFormat.dwGBitMask = 0x00ff00,
221
.ddpfPixelFormat.dwBBitMask = 0x0000ff,
222
.ddpfPixelFormat.dwRGBAlphaBitMask = 0xff000000,
223
};
224
225
static const DDSURFACEDESC yuy2_format =
226
{
227
.dwSize = sizeof(DDSURFACEDESC),
228
.dwFlags = DDSD_PIXELFORMAT,
229
.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
230
.ddpfPixelFormat.dwFlags = DDPF_FOURCC,
231
.ddpfPixelFormat.dwFourCC = MAKEFOURCC('Y', 'U', 'Y', '2'),
232
.ddpfPixelFormat.dwYUVBitCount = 16,
233
};
234
235
static const DDSURFACEDESC yv12_format =
236
{
237
.dwSize = sizeof(DDSURFACEDESC),
238
.dwFlags = DDSD_PIXELFORMAT,
239
.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
240
.ddpfPixelFormat.dwFlags = DDPF_FOURCC,
241
.ddpfPixelFormat.dwFourCC = MAKEFOURCC('Y', 'V', '1', '2'),
242
.ddpfPixelFormat.dwYUVBitCount = 12,
243
};
244
245
static const WCHAR primary_video_sink_id[] = L"I{A35FF56A-9FDA-11D0-8FDF-00C04FD9189D}";
246
static const WCHAR primary_audio_sink_id[] = L"I{A35FF56B-9FDA-11D0-8FDF-00C04FD9189D}";
247
248
static const WCHAR *load_resource(const WCHAR *name)
249
{
250
HMODULE module = GetModuleHandleA(NULL);
251
HRSRC resource;
252
DWORD written;
253
HANDLE file;
254
WCHAR *path;
255
DWORD size;
256
void *ptr;
257
258
path = calloc(MAX_PATH + 1, sizeof(WCHAR));
259
ok(!!path, "Failed to allocate temp path string.\n");
260
GetTempPathW(MAX_PATH + 1, path);
261
wcscat(path, name);
262
263
file = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
264
ok(file != INVALID_HANDLE_VALUE, "Failed to create file %s, error %lu.\n", wine_dbgstr_w(path), GetLastError());
265
266
resource = FindResourceW(module, name, (const WCHAR *)RT_RCDATA);
267
ok(!!resource, "Failed to find resource %s, error %lu.\n", wine_dbgstr_w(name), GetLastError());
268
269
size = SizeofResource(module, resource);
270
ptr = LockResource(LoadResource(module, resource));
271
272
WriteFile(file, ptr, size, &written, NULL);
273
ok(written == size, "Failed to write file %s.\n", wine_dbgstr_w(path));
274
275
CloseHandle(file);
276
277
return path;
278
}
279
280
static void unload_resource(const WCHAR *path)
281
{
282
BOOL ret = DeleteFileW(path);
283
ok(ret, "Failed to delete file %s.\n", wine_dbgstr_w(path));
284
free((void *)path);
285
}
286
287
#define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
288
static void _expect_ref(IUnknown* obj, ULONG ref, int line)
289
{
290
ULONG rc;
291
IUnknown_AddRef(obj);
292
rc = IUnknown_Release(obj);
293
ok_(__FILE__,line)(rc == ref, "expected refcount %ld, got %ld\n", ref, rc);
294
}
295
296
static IAMMultiMediaStream *create_ammultimediastream(void)
297
{
298
IAMMultiMediaStream *stream = NULL;
299
HRESULT hr = CoCreateInstance(&CLSID_AMMultiMediaStream, NULL, CLSCTX_INPROC_SERVER,
300
&IID_IAMMultiMediaStream, (void **)&stream);
301
ok(hr == S_OK, "Got hr %#lx.\n", hr);
302
return stream;
303
}
304
305
static ULONG get_refcount(void *iface)
306
{
307
IUnknown *unknown = iface;
308
IUnknown_AddRef(unknown);
309
return IUnknown_Release(unknown);
310
}
311
312
#define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
313
static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
314
{
315
IUnknown *iface = iface_ptr;
316
HRESULT hr, expected_hr;
317
IUnknown *unk;
318
319
expected_hr = supported ? S_OK : E_NOINTERFACE;
320
321
hr = IUnknown_QueryInterface(iface, iid, (void **)&unk);
322
ok_(__FILE__, line)(hr == expected_hr, "Got hr %#lx, expected %#lx.\n", hr, expected_hr);
323
if (SUCCEEDED(hr))
324
IUnknown_Release(unk);
325
}
326
327
static void test_interfaces(void)
328
{
329
IAMMultiMediaStream *mmstream = create_ammultimediastream();
330
IMediaStreamFilter *filter;
331
IMediaStream *stream;
332
HRESULT hr;
333
ULONG ref;
334
335
check_interface(mmstream, &IID_IAMMultiMediaStream, TRUE);
336
check_interface(mmstream, &IID_IMultiMediaStream, TRUE);
337
check_interface(mmstream, &IID_IUnknown, TRUE);
338
339
check_interface(mmstream, &IID_IAMMediaStream, FALSE);
340
check_interface(mmstream, &IID_IAMMediaTypeStream, FALSE);
341
check_interface(mmstream, &IID_IAudioMediaStream, FALSE);
342
check_interface(mmstream, &IID_IBaseFilter, FALSE);
343
check_interface(mmstream, &IID_IDirectDrawMediaStream, FALSE);
344
check_interface(mmstream, &IID_IMediaFilter, FALSE);
345
check_interface(mmstream, &IID_IMediaStream, FALSE);
346
check_interface(mmstream, &IID_IMediaStreamFilter, FALSE);
347
check_interface(mmstream, &IID_IPin, FALSE);
348
349
hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
350
ok(hr == S_OK, "Got hr %#lx.\n", hr);
351
352
check_interface(filter, &IID_IBaseFilter, TRUE);
353
check_interface(filter, &IID_IMediaFilter, TRUE);
354
check_interface(filter, &IID_IMediaStreamFilter, TRUE);
355
check_interface(filter, &IID_IPersist, TRUE);
356
check_interface(filter, &IID_IUnknown, TRUE);
357
358
check_interface(filter, &IID_IAMMediaStream, FALSE);
359
check_interface(filter, &IID_IAMMediaTypeStream, FALSE);
360
check_interface(filter, &IID_IAMMultiMediaStream, FALSE);
361
check_interface(filter, &IID_IAudioMediaStream, FALSE);
362
check_interface(filter, &IID_IDirectDrawMediaStream, FALSE);
363
check_interface(filter, &IID_IMediaStream, FALSE);
364
check_interface(filter, &IID_IMultiMediaStream, FALSE);
365
check_interface(filter, &IID_IPin, FALSE);
366
367
IMediaStreamFilter_Release(filter);
368
369
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
370
ok(hr == S_OK, "Got hr %#lx.\n", hr);
371
372
check_interface(stream, &IID_IAMMediaStream, TRUE);
373
check_interface(stream, &IID_IAudioMediaStream, TRUE);
374
check_interface(stream, &IID_IMediaStream, TRUE);
375
check_interface(stream, &IID_IMemInputPin, TRUE);
376
check_interface(stream, &IID_IPin, TRUE);
377
check_interface(stream, &IID_IUnknown, TRUE);
378
379
check_interface(stream, &IID_IAMMediaTypeStream, FALSE);
380
check_interface(stream, &IID_IAMMultiMediaStream, FALSE);
381
check_interface(stream, &IID_IBaseFilter, FALSE);
382
check_interface(stream, &IID_IDirectDrawMediaStream, FALSE);
383
check_interface(stream, &IID_IMediaFilter, FALSE);
384
check_interface(stream, &IID_IMediaStreamFilter, FALSE);
385
check_interface(stream, &IID_IMultiMediaStream, FALSE);
386
check_interface(stream, &IID_IPersist, FALSE);
387
check_interface(stream, &IID_IQualityControl, FALSE);
388
389
IMediaStream_Release(stream);
390
391
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
392
ok(hr == S_OK, "Got hr %#lx.\n", hr);
393
394
check_interface(stream, &IID_IAMMediaStream, TRUE);
395
check_interface(stream, &IID_IDirectDrawMediaStream, TRUE);
396
check_interface(stream, &IID_IMediaStream, TRUE);
397
check_interface(stream, &IID_IMemAllocator, TRUE);
398
check_interface(stream, &IID_IMemInputPin, TRUE);
399
check_interface(stream, &IID_IPin, TRUE);
400
check_interface(stream, &IID_IUnknown, TRUE);
401
402
check_interface(stream, &IID_IAMMediaTypeStream, FALSE);
403
check_interface(stream, &IID_IAMMultiMediaStream, FALSE);
404
check_interface(stream, &IID_IAudioMediaStream, FALSE);
405
check_interface(stream, &IID_IBaseFilter, FALSE);
406
check_interface(stream, &IID_IDirectDraw, FALSE);
407
check_interface(stream, &IID_IMediaFilter, FALSE);
408
check_interface(stream, &IID_IMediaStreamFilter, FALSE);
409
check_interface(stream, &IID_IMultiMediaStream, FALSE);
410
check_interface(stream, &IID_IPersist, FALSE);
411
check_interface(stream, &IID_IQualityControl, FALSE);
412
413
IMediaStream_Release(stream);
414
415
ref = IAMMultiMediaStream_Release(mmstream);
416
ok(!ref, "Got outstanding refcount %lu.\n", ref);
417
}
418
419
static void test_openfile(const WCHAR *test_avi_path)
420
{
421
IAMMultiMediaStream *mmstream = create_ammultimediastream();
422
IMediaControl *media_control;
423
IMediaStreamFilter *filter;
424
IMediaFilter *media_filter;
425
IReferenceClock *clock;
426
IGraphBuilder *graph;
427
OAFilterState state;
428
HRESULT hr;
429
ULONG ref;
430
431
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
432
ok(hr == S_OK, "Got hr %#lx.\n", hr);
433
ok(!graph, "Expected NULL graph.\n");
434
435
hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
436
ok(!!filter, "Expected non-NULL filter.\n");
437
ok(hr == S_OK, "Got hr %#lx.\n", hr);
438
439
check_interface(filter, &IID_IMediaSeeking, FALSE);
440
441
hr = IAMMultiMediaStream_OpenFile(mmstream, test_avi_path, AMMSF_NORENDER);
442
ok(hr == S_OK, "Got hr %#lx.\n", hr);
443
444
check_interface(filter, &IID_IMediaSeeking, FALSE);
445
446
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
447
ok(hr == S_OK, "Got hr %#lx.\n", hr);
448
ok(!!graph, "Expected non-NULL graph.\n");
449
IGraphBuilder_Release(graph);
450
IMediaStreamFilter_Release(filter);
451
452
ref = IAMMultiMediaStream_Release(mmstream);
453
ok(!ref, "Got outstanding refcount %ld.\n", ref);
454
455
mmstream = create_ammultimediastream();
456
457
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
458
ok(hr == S_OK, "Got hr %#lx.\n", hr);
459
ok(!graph, "Expected NULL graph.\n");
460
461
hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
462
ok(!!filter, "Expected non-NULL filter.\n");
463
ok(hr == S_OK, "Got hr %#lx.\n", hr);
464
465
check_interface(filter, &IID_IMediaSeeking, FALSE);
466
467
hr = IAMMultiMediaStream_OpenFile(mmstream, test_avi_path, AMMSF_RENDERALLSTREAMS);
468
ok(hr == S_OK, "Got hr %#lx.\n", hr);
469
470
check_interface(filter, &IID_IMediaSeeking, FALSE);
471
472
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
473
ok(hr == S_OK, "Got hr %#lx.\n", hr);
474
ok(!!graph, "Expected non-NULL graph.\n");
475
476
hr = IGraphBuilder_QueryInterface(graph, &IID_IMediaFilter, (void **)&media_filter);
477
ok(hr == S_OK, "Got hr %#lx.\n", hr);
478
479
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
480
ok(hr == S_OK, "Got hr %#lx.\n", hr);
481
482
clock = NULL;
483
IMediaFilter_GetSyncSource(media_filter, &clock);
484
ok(!!clock, "Expected non-NULL clock.\n");
485
486
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
487
ok(hr == S_OK, "Got hr %#lx.\n", hr);
488
489
ref = IAMMultiMediaStream_Release(mmstream);
490
ok(!ref, "Got outstanding refcount %ld.\n", ref);
491
IMediaFilter_Release(media_filter);
492
ref = IGraphBuilder_Release(graph);
493
ok(!ref, "Got outstanding refcount %ld.\n", ref);
494
ref = IMediaStreamFilter_Release(filter);
495
ok(!ref, "Got outstanding refcount %ld.\n", ref);
496
ref = IReferenceClock_Release(clock);
497
ok(!ref, "Got outstanding refcount %ld.\n", ref);
498
499
mmstream = create_ammultimediastream();
500
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
501
ok(hr == S_OK, "Got hr %#lx.\n", hr);
502
ok(!graph, "Expected NULL graph.\n");
503
504
hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
505
ok(!!filter, "Expected non-NULL filter.\n");
506
ok(hr == S_OK, "Got hr %#lx.\n", hr);
507
508
check_interface(filter, &IID_IMediaSeeking, FALSE);
509
510
hr = IAMMultiMediaStream_OpenFile(mmstream, test_avi_path, AMMSF_RENDERTOEXISTING);
511
ok(hr == VFW_E_CANNOT_CONNECT, "Got hr %#lx.\n", hr);
512
513
check_interface(filter, &IID_IMediaSeeking, FALSE);
514
515
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
516
ok(hr == S_OK, "Got hr %#lx.\n", hr);
517
ok(!!graph, "Expected non-NULL graph.\n");
518
IGraphBuilder_Release(graph);
519
IMediaStreamFilter_Release(filter);
520
521
ref = IAMMultiMediaStream_Release(mmstream);
522
ok(!ref, "Got outstanding refcount %ld.\n", ref);
523
524
mmstream = create_ammultimediastream();
525
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, NULL);
526
ok(hr == S_OK, "Got hr %#lx.\n", hr);
527
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
528
ok(hr == S_OK, "Got hr %#lx.\n", hr);
529
ok(!!graph, "Expected non-NULL graph.\n");
530
hr = IGraphBuilder_QueryInterface(graph, &IID_IMediaFilter, (void **)&media_filter);
531
ok(hr == S_OK, "Got hr %#lx.\n", hr);
532
hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
533
ok(hr == S_OK, "Got hr %#lx.\n", hr);
534
535
check_interface(filter, &IID_IMediaSeeking, FALSE);
536
537
hr = IAMMultiMediaStream_OpenFile(mmstream, test_avi_path, AMMSF_RENDERTOEXISTING);
538
ok(hr == S_OK, "Got hr %#lx.\n", hr);
539
540
check_interface(filter, &IID_IMediaSeeking, TRUE);
541
542
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
543
ok(hr == S_OK, "Got hr %#lx.\n", hr);
544
545
clock = NULL;
546
IMediaFilter_GetSyncSource(media_filter, &clock);
547
ok(!!clock, "Expected non-NULL clock.\n");
548
549
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
550
ok(hr == S_OK, "Got hr %#lx.\n", hr);
551
552
ref = IAMMultiMediaStream_Release(mmstream);
553
ok(!ref, "Got outstanding refcount %ld.\n", ref);
554
IMediaFilter_Release(media_filter);
555
ref = IGraphBuilder_Release(graph);
556
ok(!ref, "Got outstanding refcount %ld.\n", ref);
557
ref = IMediaStreamFilter_Release(filter);
558
ok(!ref, "Got outstanding refcount %ld.\n", ref);
559
ref = IReferenceClock_Release(clock);
560
ok(!ref, "Got outstanding refcount %ld.\n", ref);
561
562
mmstream = create_ammultimediastream();
563
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, NULL);
564
ok(hr == S_OK, "Got hr %#lx.\n", hr);
565
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
566
ok(hr == S_OK, "Got hr %#lx.\n", hr);
567
ok(!!graph, "Expected non-NULL graph.\n");
568
hr = IGraphBuilder_QueryInterface(graph, &IID_IMediaControl, (void **)&media_control);
569
ok(hr == S_OK, "Got hr %#lx.\n", hr);
570
571
hr = IAMMultiMediaStream_OpenFile(mmstream, test_avi_path, AMMSF_RUN);
572
ok(hr == S_OK, "Got hr %#lx.\n", hr);
573
574
state = 0xdeadbeef;
575
hr = IMediaControl_GetState(media_control, INFINITE, &state);
576
ok(hr == S_OK, "Got hr %#lx.\n", hr);
577
ok(state == State_Running, "Got state %#lx.\n", state);
578
579
ref = IAMMultiMediaStream_Release(mmstream);
580
ok(!ref, "Got outstanding refcount %ld.\n", ref);
581
IMediaControl_Release(media_control);
582
ref = IGraphBuilder_Release(graph);
583
ok(!ref, "Got outstanding refcount %ld.\n", ref);
584
585
mmstream = create_ammultimediastream();
586
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, NULL);
587
ok(hr == S_OK, "Got hr %#lx.\n", hr);
588
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
589
ok(hr == S_OK, "Got hr %#lx.\n", hr);
590
ok(!!graph, "Expected non-NULL graph.\n");
591
hr = IGraphBuilder_QueryInterface(graph, &IID_IMediaFilter, (void **)&media_filter);
592
ok(hr == S_OK, "Got hr %#lx.\n", hr);
593
594
hr = IAMMultiMediaStream_OpenFile(mmstream, test_avi_path, AMMSF_NOCLOCK);
595
ok(hr == S_OK, "Got hr %#lx.\n", hr);
596
597
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
598
ok(hr == S_OK, "Got hr %#lx.\n", hr);
599
600
clock = (IReferenceClock *)0xdeadbeef;
601
IMediaFilter_GetSyncSource(media_filter, &clock);
602
ok(!clock, "Got clock %p.\n", clock);
603
604
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
605
ok(hr == S_OK, "Got hr %#lx.\n", hr);
606
607
ref = IAMMultiMediaStream_Release(mmstream);
608
ok(!ref, "Got outstanding refcount %ld.\n", ref);
609
IMediaFilter_Release(media_filter);
610
ref = IGraphBuilder_Release(graph);
611
ok(!ref, "Got outstanding refcount %ld.\n", ref);
612
}
613
614
static void test_mmstream_get_duration(const WCHAR *test_avi_path)
615
{
616
IAMMultiMediaStream *mmstream = create_ammultimediastream();
617
HRESULT hr, audio_hr;
618
LONGLONG duration;
619
ULONG ref;
620
621
duration = 0xdeadbeefdeadbeefULL;
622
hr = IAMMultiMediaStream_GetDuration(mmstream, &duration);
623
ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
624
ok(duration == 0xdeadbeefdeadbeefULL, "Got duration %s.\n", wine_dbgstr_longlong(duration));
625
626
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, NULL);
627
ok(hr == S_OK, "Got hr %#lx.\n", hr);
628
629
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, AMMSF_ADDDEFAULTRENDERER, NULL);
630
ok(hr == S_OK || hr == VFW_E_NO_AUDIO_HARDWARE, "Got hr %#lx.\n", hr);
631
audio_hr = hr;
632
633
hr = IAMMultiMediaStream_OpenFile(mmstream, test_avi_path, AMMSF_RENDERTOEXISTING);
634
ok(hr == S_OK, "Got hr %#lx.\n", hr);
635
636
duration = 0xdeadbeefdeadbeefULL;
637
hr = IAMMultiMediaStream_GetDuration(mmstream, &duration);
638
if (audio_hr == S_OK)
639
{
640
ok(hr == S_OK, "Got hr %#lx.\n", hr);
641
ok(duration == 1000000LL, "Got duration %s.\n", wine_dbgstr_longlong(duration));
642
}
643
else
644
{
645
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
646
ok(!duration, "Got duration %s.\n", wine_dbgstr_longlong(duration));
647
}
648
649
ref = IAMMultiMediaStream_Release(mmstream);
650
ok(!ref, "Got outstanding refcount %ld.\n", ref);
651
652
mmstream = create_ammultimediastream();
653
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, NULL);
654
ok(hr == S_OK, "Got hr %#lx.\n", hr);
655
656
duration = 0xdeadbeefdeadbeefULL;
657
hr = IAMMultiMediaStream_GetDuration(mmstream, &duration);
658
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
659
ok(duration == 0, "Got duration %s.\n", wine_dbgstr_longlong(duration));
660
661
ref = IAMMultiMediaStream_Release(mmstream);
662
ok(!ref, "Got outstanding refcount %ld.\n", ref);
663
664
mmstream = create_ammultimediastream();
665
666
hr = IAMMultiMediaStream_OpenFile(mmstream, test_avi_path, AMMSF_RENDERTOEXISTING);
667
ok(hr == VFW_E_CANNOT_CONNECT, "Got hr %#lx.\n", hr);
668
669
duration = 0xdeadbeefdeadbeefULL;
670
hr = IAMMultiMediaStream_GetDuration(mmstream, &duration);
671
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
672
ok(duration == 0, "Got duration %s.\n", wine_dbgstr_longlong(duration));
673
674
ref = IAMMultiMediaStream_Release(mmstream);
675
ok(!ref, "Got outstanding refcount %ld.\n", ref);
676
677
mmstream = create_ammultimediastream();
678
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, NULL);
679
ok(hr == S_OK, "Got hr %#lx.\n", hr);
680
681
hr = IAMMultiMediaStream_OpenFile(mmstream, test_avi_path, AMMSF_NORENDER);
682
ok(hr == S_OK, "Got hr %#lx.\n", hr);
683
684
duration = 0xdeadbeefdeadbeefULL;
685
hr = IAMMultiMediaStream_GetDuration(mmstream, &duration);
686
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
687
ok(duration == 0, "Got duration %s.\n", wine_dbgstr_longlong(duration));
688
689
ref = IAMMultiMediaStream_Release(mmstream);
690
ok(!ref, "Got outstanding refcount %ld.\n", ref);
691
}
692
693
static const GUID test_mspid = {0x88888888};
694
695
struct teststream
696
{
697
IAMMediaStream IAMMediaStream_iface;
698
IPin IPin_iface;
699
LONG refcount;
700
GUID mspid;
701
IAMMultiMediaStream *mmstream;
702
IMediaStreamFilter *filter;
703
IFilterGraph *graph;
704
FILTER_STATE state;
705
HRESULT set_state_result;
706
};
707
708
static struct teststream *impl_from_IAMMediaStream(IAMMediaStream *iface)
709
{
710
return CONTAINING_RECORD(iface, struct teststream, IAMMediaStream_iface);
711
}
712
713
static struct teststream *impl_from_IPin(IPin *iface)
714
{
715
return CONTAINING_RECORD(iface, struct teststream, IPin_iface);
716
}
717
718
static HRESULT WINAPI pin_QueryInterface(IPin *iface, REFIID iid, void **out)
719
{
720
struct teststream *stream = impl_from_IPin(iface);
721
return IAMMediaStream_QueryInterface(&stream->IAMMediaStream_iface, iid, out);
722
}
723
724
static ULONG WINAPI pin_AddRef(IPin *iface)
725
{
726
struct teststream *stream = impl_from_IPin(iface);
727
return IAMMediaStream_AddRef(&stream->IAMMediaStream_iface);
728
}
729
730
static ULONG WINAPI pin_Release(IPin *iface)
731
{
732
struct teststream *stream = impl_from_IPin(iface);
733
return IAMMediaStream_Release(&stream->IAMMediaStream_iface);
734
}
735
736
static HRESULT WINAPI pin_Connect(IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
737
{
738
ok(0, "Unexpected call.\n");
739
return E_NOTIMPL;
740
}
741
742
static HRESULT WINAPI pin_ReceiveConnection(IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
743
{
744
ok(0, "Unexpected call.\n");
745
return E_NOTIMPL;
746
}
747
748
static HRESULT WINAPI pin_Disconnect(IPin *iface)
749
{
750
if (winetest_debug > 1) trace("Disconnect\n");
751
return E_NOTIMPL;
752
}
753
754
static HRESULT WINAPI pin_ConnectedTo(IPin *iface, IPin **peer)
755
{
756
if (winetest_debug > 1) trace("ConnectedTo\n");
757
return E_NOTIMPL;
758
}
759
760
static HRESULT WINAPI pin_ConnectionMediaType(IPin *iface, AM_MEDIA_TYPE *mt)
761
{
762
ok(0, "Unexpected call.\n");
763
return E_NOTIMPL;
764
}
765
766
static HRESULT WINAPI pin_QueryPinInfo(IPin *iface, PIN_INFO *info)
767
{
768
ok(0, "Unexpected call.\n");
769
return E_NOTIMPL;
770
}
771
772
static HRESULT WINAPI pin_QueryDirection(IPin *iface, PIN_DIRECTION *dir)
773
{
774
if (winetest_debug > 1) trace("QueryDirection\n");
775
*dir = PINDIR_INPUT;
776
return S_OK;
777
}
778
779
static HRESULT WINAPI pin_QueryId(IPin *iface, WCHAR **id)
780
{
781
ok(0, "Unexpected call.\n");
782
return E_NOTIMPL;
783
}
784
785
static HRESULT WINAPI pin_QueryAccept(IPin *iface, const AM_MEDIA_TYPE *mt)
786
{
787
ok(0, "Unexpected call.\n");
788
return E_NOTIMPL;
789
}
790
791
static HRESULT WINAPI pin_EnumMediaTypes(IPin *iface, IEnumMediaTypes **out)
792
{
793
ok(0, "Unexpected call.\n");
794
return E_NOTIMPL;
795
}
796
797
static HRESULT WINAPI pin_QueryInternalConnections(IPin *iface, IPin **pins, ULONG *count)
798
{
799
ok(0, "Unexpected call.\n");
800
return E_NOTIMPL;
801
}
802
803
static HRESULT WINAPI pin_EndOfStream(IPin *iface)
804
{
805
ok(0, "Unexpected call.\n");
806
return E_NOTIMPL;
807
}
808
809
static HRESULT WINAPI pin_BeginFlush(IPin *iface)
810
{
811
ok(0, "Unexpected call.\n");
812
return E_NOTIMPL;
813
}
814
815
static HRESULT WINAPI pin_EndFlush(IPin *iface)
816
{
817
ok(0, "Unexpected call.\n");
818
return E_NOTIMPL;
819
}
820
821
static HRESULT WINAPI pin_NewSegment(IPin *iface, REFERENCE_TIME start, REFERENCE_TIME stop, double rate)
822
{
823
ok(0, "Unexpected call.\n");
824
return E_NOTIMPL;
825
}
826
827
static const IPinVtbl pin_vtbl =
828
{
829
pin_QueryInterface,
830
pin_AddRef,
831
pin_Release,
832
pin_Connect,
833
pin_ReceiveConnection,
834
pin_Disconnect,
835
pin_ConnectedTo,
836
pin_ConnectionMediaType,
837
pin_QueryPinInfo,
838
pin_QueryDirection,
839
pin_QueryId,
840
pin_QueryAccept,
841
pin_EnumMediaTypes,
842
pin_QueryInternalConnections,
843
pin_EndOfStream,
844
pin_BeginFlush,
845
pin_EndFlush,
846
pin_NewSegment
847
};
848
849
static HRESULT WINAPI stream_QueryInterface(IAMMediaStream *iface, REFIID iid, void **out)
850
{
851
struct teststream *stream = impl_from_IAMMediaStream(iface);
852
853
if (winetest_debug > 1) trace("QueryInterface(%s)\n", wine_dbgstr_guid(iid));
854
855
if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IMediaStream) || IsEqualGUID(iid, &IID_IAMMediaStream))
856
{
857
IAMMediaStream_AddRef(iface);
858
*out = iface;
859
return S_OK;
860
}
861
else if (IsEqualGUID(iid, &IID_IPin))
862
{
863
IAMMediaStream_AddRef(iface);
864
*out = &stream->IPin_iface;
865
return S_OK;
866
}
867
868
ok(0, "Unexpected interface %s.\n", wine_dbgstr_guid(iid));
869
return E_NOINTERFACE;
870
}
871
872
static ULONG WINAPI stream_AddRef(IAMMediaStream *iface)
873
{
874
struct teststream *stream = impl_from_IAMMediaStream(iface);
875
return InterlockedIncrement(&stream->refcount);
876
}
877
878
static ULONG WINAPI stream_Release(IAMMediaStream *iface)
879
{
880
struct teststream *stream = impl_from_IAMMediaStream(iface);
881
return InterlockedDecrement(&stream->refcount);
882
}
883
884
static HRESULT WINAPI stream_GetMultiMediaStream(IAMMediaStream *iface, IMultiMediaStream **mmstream)
885
{
886
ok(0, "Unexpected call.\n");
887
return E_NOTIMPL;
888
}
889
890
static HRESULT WINAPI stream_GetInformation(IAMMediaStream *iface, MSPID *id, STREAM_TYPE *type)
891
{
892
struct teststream *stream = impl_from_IAMMediaStream(iface);
893
if (winetest_debug > 1) trace("GetInformation(%p, %p)\n", id, type);
894
if (id)
895
*id = stream->mspid;
896
if (type)
897
*type = STREAMTYPE_READ;
898
return S_OK;
899
}
900
901
static HRESULT WINAPI stream_SetSameFormat(IAMMediaStream *iface, IMediaStream *ref, DWORD flags)
902
{
903
ok(0, "Unexpected call.\n");
904
return E_NOTIMPL;
905
}
906
907
static HRESULT WINAPI stream_AllocateSample(IAMMediaStream *iface, DWORD flags, IStreamSample **sample)
908
{
909
ok(0, "Unexpected call.\n");
910
return E_NOTIMPL;
911
}
912
913
static HRESULT WINAPI stream_CreateSharedSample(IAMMediaStream *iface,
914
IStreamSample *existing, DWORD flags, IStreamSample **out)
915
{
916
ok(0, "Unexpected call.\n");
917
return E_NOTIMPL;
918
}
919
920
static HRESULT WINAPI stream_SendEndOfStream(IAMMediaStream *iface, DWORD flags)
921
{
922
ok(0, "Unexpected call.\n");
923
return E_NOTIMPL;
924
}
925
926
static HRESULT WINAPI stream_Initialize(IAMMediaStream *iface, IUnknown *source,
927
DWORD flags, REFMSPID id, const STREAM_TYPE type)
928
{
929
ok(0, "Unexpected call.\n");
930
return E_NOTIMPL;
931
}
932
933
static HRESULT WINAPI stream_SetState(IAMMediaStream *iface, FILTER_STATE state)
934
{
935
struct teststream *stream = impl_from_IAMMediaStream(iface);
936
if (winetest_debug > 1) trace("SetState(%#x)\n", state);
937
if (SUCCEEDED(stream->set_state_result))
938
stream->state = state;
939
return stream->set_state_result;
940
}
941
942
static HRESULT WINAPI stream_JoinAMMultiMediaStream(IAMMediaStream *iface, IAMMultiMediaStream *mmstream)
943
{
944
struct teststream *stream = impl_from_IAMMediaStream(iface);
945
if (winetest_debug > 1) trace("JoinAMMultiMediaStream(%p)\n", mmstream);
946
stream->mmstream = mmstream;
947
return S_OK;
948
}
949
950
static HRESULT WINAPI stream_JoinFilter(IAMMediaStream *iface, IMediaStreamFilter *filter)
951
{
952
struct teststream *stream = impl_from_IAMMediaStream(iface);
953
if (winetest_debug > 1) trace("JoinFilter(%p)\n", filter);
954
stream->filter = filter;
955
return S_OK;
956
}
957
958
static HRESULT WINAPI stream_JoinFilterGraph(IAMMediaStream *iface, IFilterGraph *graph)
959
{
960
struct teststream *stream = impl_from_IAMMediaStream(iface);
961
if (winetest_debug > 1) trace("JoinFilterGraph(%p)\n", graph);
962
stream->graph = graph;
963
return S_OK;
964
}
965
966
static const IAMMediaStreamVtbl stream_vtbl =
967
{
968
stream_QueryInterface,
969
stream_AddRef,
970
stream_Release,
971
stream_GetMultiMediaStream,
972
stream_GetInformation,
973
stream_SetSameFormat,
974
stream_AllocateSample,
975
stream_CreateSharedSample,
976
stream_SendEndOfStream,
977
stream_Initialize,
978
stream_SetState,
979
stream_JoinAMMultiMediaStream,
980
stream_JoinFilter,
981
stream_JoinFilterGraph,
982
};
983
984
static void teststream_init(struct teststream *stream)
985
{
986
memset(stream, 0, sizeof(*stream));
987
stream->IAMMediaStream_iface.lpVtbl = &stream_vtbl;
988
stream->IPin_iface.lpVtbl = &pin_vtbl;
989
stream->refcount = 1;
990
stream->mspid = test_mspid;
991
stream->set_state_result = S_OK;
992
}
993
994
#define check_enum_stream(a,b,c,d) check_enum_stream_(__LINE__,a,b,c,d)
995
static void check_enum_stream_(int line, IAMMultiMediaStream *mmstream,
996
IMediaStreamFilter *filter, LONG index, IMediaStream *expect)
997
{
998
IMediaStream *stream = NULL, *stream2 = NULL;
999
HRESULT hr;
1000
1001
hr = IAMMultiMediaStream_EnumMediaStreams(mmstream, index, &stream);
1002
ok_(__FILE__, line)(hr == (expect ? S_OK : S_FALSE),
1003
"IAMMultiMediaStream::EnumMediaStreams() returned %#lx.\n", hr);
1004
hr = IMediaStreamFilter_EnumMediaStreams(filter, index, &stream2);
1005
ok_(__FILE__, line)(hr == (expect ? S_OK : S_FALSE),
1006
"IMediaStreamFilter::EnumMediaStreams() returned %#lx.\n", hr);
1007
if (hr == S_OK)
1008
{
1009
ok_(__FILE__, line)(stream == expect, "Expected stream %p, got %p.\n", expect, stream);
1010
ok_(__FILE__, line)(stream2 == expect, "Expected stream %p, got %p.\n", expect, stream2);
1011
IMediaStream_Release(stream);
1012
IMediaStream_Release(stream2);
1013
}
1014
}
1015
1016
struct testfilter
1017
{
1018
struct strmbase_filter filter;
1019
struct strmbase_source source;
1020
IMediaSeeking IMediaSeeking_iface;
1021
IQualityControl IQualityControl_iface;
1022
LONGLONG current_position;
1023
LONGLONG stop_position;
1024
const AM_MEDIA_TYPE *preferred_mt;
1025
HANDLE wait_state_event;
1026
IBaseFilter *qc_notify_sender;
1027
Quality qc_notify_quality;
1028
BOOL use_input_pin_allocator;
1029
HRESULT get_duration_hr;
1030
HRESULT get_stop_position_hr;
1031
HRESULT set_positions_hr;
1032
HRESULT init_stream_hr;
1033
HRESULT cleanup_stream_hr;
1034
HRESULT wait_state_hr;
1035
HRESULT is_format_supported_hr;
1036
HRESULT qc_notify_hr;
1037
HRESULT query_accept_hr;
1038
1039
bool verify_query_accept_mt;
1040
GUID query_accept_subtype;
1041
bool query_accept_rgb8_palette;
1042
unsigned int query_accept_width, query_accept_height;
1043
};
1044
1045
static inline struct testfilter *impl_from_BaseFilter(struct strmbase_filter *iface)
1046
{
1047
return CONTAINING_RECORD(iface, struct testfilter, filter);
1048
}
1049
1050
static struct strmbase_pin *testfilter_get_pin(struct strmbase_filter *iface, unsigned int index)
1051
{
1052
struct testfilter *filter = impl_from_BaseFilter(iface);
1053
if (!index)
1054
return &filter->source.pin;
1055
return NULL;
1056
}
1057
1058
static void testfilter_destroy(struct strmbase_filter *iface)
1059
{
1060
struct testfilter *filter = impl_from_BaseFilter(iface);
1061
CloseHandle(filter->wait_state_event);
1062
strmbase_source_cleanup(&filter->source);
1063
strmbase_filter_cleanup(&filter->filter);
1064
}
1065
1066
static HRESULT testfilter_init_stream(struct strmbase_filter *iface)
1067
{
1068
struct testfilter *filter = impl_from_BaseFilter(iface);
1069
HRESULT hr;
1070
1071
if (SUCCEEDED(filter->init_stream_hr) && filter->source.pin.peer)
1072
{
1073
hr = IMemAllocator_Commit(filter->source.pAllocator);
1074
ok(hr == S_OK, "Got hr %#lx.\n", hr);
1075
}
1076
1077
return filter->init_stream_hr;
1078
}
1079
1080
static HRESULT testfilter_cleanup_stream(struct strmbase_filter *iface)
1081
{
1082
struct testfilter *filter = impl_from_BaseFilter(iface);
1083
HRESULT hr;
1084
1085
if (SUCCEEDED(filter->cleanup_stream_hr) && filter->source.pin.peer)
1086
{
1087
hr = IMemAllocator_Decommit(filter->source.pAllocator);
1088
ok(hr == S_OK, "Got hr %#lx.\n", hr);
1089
}
1090
1091
return filter->cleanup_stream_hr;
1092
}
1093
1094
static HRESULT testfilter_wait_state(struct strmbase_filter *iface, DWORD timeout)
1095
{
1096
struct testfilter *filter = impl_from_BaseFilter(iface);
1097
HRESULT hr;
1098
1099
LeaveCriticalSection(&filter->filter.filter_cs);
1100
WaitForSingleObject(filter->wait_state_event, timeout);
1101
EnterCriticalSection(&filter->filter.filter_cs);
1102
1103
hr = filter->wait_state_hr;
1104
1105
return hr;
1106
}
1107
1108
static const struct strmbase_filter_ops testfilter_ops =
1109
{
1110
.filter_get_pin = testfilter_get_pin,
1111
.filter_destroy = testfilter_destroy,
1112
.filter_init_stream = testfilter_init_stream,
1113
.filter_cleanup_stream = testfilter_cleanup_stream,
1114
.filter_wait_state = testfilter_wait_state,
1115
};
1116
1117
static inline struct testfilter *impl_from_base_pin(struct strmbase_pin *iface)
1118
{
1119
return CONTAINING_RECORD(iface, struct testfilter, source.pin);
1120
}
1121
1122
static HRESULT testsource_get_media_type(struct strmbase_pin *iface, unsigned int index, AM_MEDIA_TYPE *mt)
1123
{
1124
struct testfilter *filter = impl_from_base_pin(iface);
1125
1126
if (index < 1 && filter->preferred_mt)
1127
return CopyMediaType(mt, filter->preferred_mt);
1128
1129
return VFW_S_NO_MORE_ITEMS;
1130
}
1131
1132
static HRESULT testsource_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
1133
{
1134
struct testfilter *filter = impl_from_base_pin(iface);
1135
1136
if (IsEqualGUID(iid, &IID_IMediaSeeking) && filter->IMediaSeeking_iface.lpVtbl)
1137
*out = &filter->IMediaSeeking_iface;
1138
else if (IsEqualGUID(iid, &IID_IQualityControl) && filter->IQualityControl_iface.lpVtbl)
1139
*out = &filter->IQualityControl_iface;
1140
else
1141
return E_NOINTERFACE;
1142
1143
IUnknown_AddRef((IUnknown *)*out);
1144
1145
return S_OK;
1146
}
1147
1148
static HRESULT testsource_query_accept(struct strmbase_pin *iface, const AM_MEDIA_TYPE *mt)
1149
{
1150
struct testfilter *filter = impl_from_base_pin(iface);
1151
1152
if (filter->verify_query_accept_mt)
1153
{
1154
unsigned int depth = 0;
1155
VIDEOINFO expect_video_info =
1156
{
1157
.bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
1158
.bmiHeader.biPlanes = 1,
1159
};
1160
1161
if (IsEqualGUID(&filter->query_accept_subtype, &MEDIASUBTYPE_RGB32))
1162
{
1163
depth = 32;
1164
}
1165
else if (IsEqualGUID(&filter->query_accept_subtype, &MEDIASUBTYPE_RGB24))
1166
{
1167
depth = 24;
1168
}
1169
else if (IsEqualGUID(&filter->query_accept_subtype, &MEDIASUBTYPE_RGB555))
1170
{
1171
depth = 16;
1172
}
1173
else if (IsEqualGUID(&filter->query_accept_subtype, &MEDIASUBTYPE_RGB565))
1174
{
1175
expect_video_info.bmiHeader.biCompression = BI_BITFIELDS;
1176
depth = 16;
1177
expect_video_info.dwBitMasks[iRED] = 0xf800;
1178
expect_video_info.dwBitMasks[iGREEN] = 0x07e0;
1179
expect_video_info.dwBitMasks[iBLUE] = 0x001f;
1180
}
1181
else
1182
{
1183
expect_video_info.bmiHeader.biClrUsed = 256;
1184
depth = 8;
1185
1186
if (filter->query_accept_rgb8_palette)
1187
{
1188
expect_video_info.bmiColors[0].rgbRed = 0x12;
1189
expect_video_info.bmiColors[1].rgbBlue = 0x34;
1190
expect_video_info.bmiColors[2].rgbGreen = 0x56;
1191
}
1192
}
1193
1194
SetRect(&expect_video_info.rcSource, 0, 0, filter->query_accept_width, filter->query_accept_height);
1195
SetRect(&expect_video_info.rcTarget, 0, 0, filter->query_accept_width, filter->query_accept_height);
1196
expect_video_info.bmiHeader.biWidth = filter->query_accept_width;
1197
expect_video_info.bmiHeader.biHeight = -filter->query_accept_height;
1198
expect_video_info.bmiHeader.biBitCount = depth;
1199
expect_video_info.bmiHeader.biSizeImage = filter->query_accept_width * filter->query_accept_height * depth / 8;
1200
1201
ok(IsEqualGUID(&mt->majortype, &MEDIATYPE_Video), "Got major type %s.\n", debugstr_guid(&mt->majortype));
1202
ok(IsEqualGUID(&mt->subtype, &filter->query_accept_subtype), "Expected subtype %s, got %s.\n",
1203
debugstr_guid(&filter->query_accept_subtype), debugstr_guid(&mt->subtype));
1204
ok(mt->bFixedSizeSamples == TRUE, "Got fixed size %d.\n", mt->bFixedSizeSamples);
1205
ok(!mt->bTemporalCompression, "Got temporal compression %d.\n", mt->bTemporalCompression);
1206
ok(mt->lSampleSize == expect_video_info.bmiHeader.biSizeImage,
1207
"Expected sample size %lu, got %lu.\n", expect_video_info.bmiHeader.biSizeImage, mt->lSampleSize);
1208
ok(IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo),
1209
"Got format type %s.\n", debugstr_guid(&mt->formattype));
1210
ok(!mt->pUnk, "Got pUnk %p.\n", mt->pUnk);
1211
ok(mt->cbFormat == sizeof(VIDEOINFO), "Got format size %lu.\n", mt->cbFormat);
1212
todo_wine_if (filter->query_accept_rgb8_palette)
1213
ok(!memcmp(mt->pbFormat, &expect_video_info, mt->cbFormat), "Format blocks didn't match.\n");
1214
}
1215
1216
return filter->query_accept_hr;
1217
}
1218
1219
static HRESULT WINAPI testsource_DecideAllocator(struct strmbase_source *iface, IMemInputPin *pin, IMemAllocator **alloc)
1220
{
1221
struct testfilter *filter = impl_from_base_pin(&iface->pin);
1222
ALLOCATOR_PROPERTIES props = {0};
1223
HRESULT hr;
1224
1225
if (filter->use_input_pin_allocator)
1226
{
1227
hr = IMemInputPin_GetAllocator(pin, alloc);
1228
ok(hr == S_OK, "Got hr %#lx.\n", hr);
1229
}
1230
else
1231
{
1232
hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER,
1233
&IID_IMemAllocator, (void **)alloc);
1234
ok(hr == S_OK, "Got hr %#lx.\n", hr);
1235
}
1236
1237
hr = iface->pFuncsTable->pfnDecideBufferSize(iface, *alloc, &props);
1238
ok(hr == S_OK, "Got hr %#lx.\n", hr);
1239
1240
return IMemInputPin_NotifyAllocator(pin, *alloc, FALSE);
1241
}
1242
1243
static HRESULT WINAPI testsource_DecideBufferSize(struct strmbase_source *iface,
1244
IMemAllocator *alloc, ALLOCATOR_PROPERTIES *requested)
1245
{
1246
ALLOCATOR_PROPERTIES actual;
1247
1248
if (!requested->cbAlign)
1249
requested->cbAlign = 1;
1250
1251
if (requested->cbBuffer < 4096)
1252
requested->cbBuffer = 4096;
1253
1254
if (!requested->cBuffers)
1255
requested->cBuffers = 2;
1256
1257
return IMemAllocator_SetProperties(alloc, requested, &actual);
1258
}
1259
1260
static const struct strmbase_source_ops testsource_ops =
1261
{
1262
.base.pin_get_media_type = testsource_get_media_type,
1263
.base.pin_query_interface = testsource_query_interface,
1264
.base.pin_query_accept = testsource_query_accept,
1265
.pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection,
1266
.pfnDecideBufferSize = testsource_DecideBufferSize,
1267
.pfnDecideAllocator = testsource_DecideAllocator,
1268
};
1269
1270
static void testfilter_init(struct testfilter *filter)
1271
{
1272
static const GUID clsid = {0xabacab};
1273
memset(filter, 0, sizeof(*filter));
1274
strmbase_filter_init(&filter->filter, NULL, &clsid, &testfilter_ops);
1275
strmbase_source_init(&filter->source, &filter->filter, L"", &testsource_ops);
1276
filter->query_accept_hr = S_OK;
1277
filter->use_input_pin_allocator = FALSE;
1278
filter->stop_position = 0x8000000000000000ULL;
1279
filter->wait_state_event = CreateEventW(NULL, TRUE, TRUE, NULL);
1280
}
1281
1282
static inline struct testfilter *impl_from_IMediaSeeking(IMediaSeeking *iface)
1283
{
1284
return CONTAINING_RECORD(iface, struct testfilter, IMediaSeeking_iface);
1285
}
1286
1287
static HRESULT WINAPI testsource_seeking_QueryInterface(IMediaSeeking *iface, REFIID iid, void **out)
1288
{
1289
struct testfilter *filter = impl_from_IMediaSeeking(iface);
1290
return IBaseFilter_QueryInterface(&filter->filter.IBaseFilter_iface, iid, out);
1291
}
1292
1293
static ULONG WINAPI testsource_seeking_AddRef(IMediaSeeking *iface)
1294
{
1295
struct testfilter *filter = impl_from_IMediaSeeking(iface);
1296
return IBaseFilter_AddRef(&filter->filter.IBaseFilter_iface);
1297
}
1298
1299
static ULONG WINAPI testsource_seeking_Release(IMediaSeeking *iface)
1300
{
1301
struct testfilter *filter = impl_from_IMediaSeeking(iface);
1302
return IBaseFilter_Release(&filter->filter.IBaseFilter_iface);
1303
}
1304
1305
static HRESULT WINAPI testsource_seeking_GetCapabilities(IMediaSeeking *iface, DWORD *capabilities)
1306
{
1307
return E_NOTIMPL;
1308
}
1309
1310
static HRESULT WINAPI testsource_seeking_CheckCapabilities(IMediaSeeking *iface, DWORD *capabilities)
1311
{
1312
ok(0, "Unexpected call.\n");
1313
return E_NOTIMPL;
1314
}
1315
1316
static HRESULT WINAPI testsource_seeking_IsFormatSupported(IMediaSeeking *iface, const GUID *format)
1317
{
1318
struct testfilter *filter = impl_from_IMediaSeeking(iface);
1319
1320
ok(IsEqualGUID(format, &TIME_FORMAT_MEDIA_TIME),
1321
"Got format %s.\n", wine_dbgstr_guid(format));
1322
1323
return filter->is_format_supported_hr;
1324
}
1325
1326
static HRESULT WINAPI testsource_seeking_QueryPreferredFormat(IMediaSeeking *iface, GUID *format)
1327
{
1328
ok(0, "Unexpected call.\n");
1329
return E_NOTIMPL;
1330
}
1331
1332
static HRESULT WINAPI testsource_seeking_GetTimeFormat(IMediaSeeking *iface, GUID *format)
1333
{
1334
ok(0, "Unexpected call.\n");
1335
return E_NOTIMPL;
1336
}
1337
1338
static HRESULT WINAPI testsource_seeking_IsUsingTimeFormat(IMediaSeeking *iface, const GUID *format)
1339
{
1340
return E_NOTIMPL;
1341
}
1342
1343
static HRESULT WINAPI testsource_seeking_SetTimeFormat(IMediaSeeking *iface, const GUID *format)
1344
{
1345
ok(0, "Unexpected call.\n");
1346
return E_NOTIMPL;
1347
}
1348
1349
static HRESULT WINAPI testsource_seeking_GetDuration(IMediaSeeking *iface, LONGLONG *duration)
1350
{
1351
struct testfilter *filter = impl_from_IMediaSeeking(iface);
1352
1353
if (SUCCEEDED(filter->get_duration_hr))
1354
*duration = 0x8000000000000000ULL;
1355
1356
return filter->get_duration_hr;
1357
}
1358
1359
static HRESULT WINAPI testsource_seeking_GetStopPosition(IMediaSeeking *iface, LONGLONG *stop)
1360
{
1361
struct testfilter *filter = impl_from_IMediaSeeking(iface);
1362
1363
if (SUCCEEDED(filter->get_stop_position_hr))
1364
*stop = 0x8000000000000000ULL;
1365
1366
return filter->get_stop_position_hr;
1367
}
1368
1369
static HRESULT WINAPI testsource_seeking_GetCurrentPosition(IMediaSeeking *iface, LONGLONG *current)
1370
{
1371
*current = 0;
1372
return S_OK;
1373
}
1374
1375
static HRESULT WINAPI testsource_seeking_ConvertTimeFormat(IMediaSeeking *iface, LONGLONG *target,
1376
const GUID *target_format, LONGLONG source, const GUID *source_format)
1377
{
1378
ok(0, "Unexpected call.\n");
1379
return E_NOTIMPL;
1380
}
1381
1382
static HRESULT WINAPI testsource_seeking_SetPositions(IMediaSeeking *iface, LONGLONG *current_ptr, DWORD current_flags,
1383
LONGLONG *stop_ptr, DWORD stop_flags)
1384
{
1385
struct testfilter *filter = impl_from_IMediaSeeking(iface);
1386
1387
if (SUCCEEDED(filter->set_positions_hr))
1388
{
1389
if (current_ptr)
1390
filter->current_position = *current_ptr;
1391
1392
if (stop_ptr)
1393
filter->stop_position = *stop_ptr;
1394
}
1395
1396
return filter->set_positions_hr;
1397
}
1398
1399
static HRESULT WINAPI testsource_seeking_GetPositions(IMediaSeeking *iface, LONGLONG *current, LONGLONG *stop)
1400
{
1401
ok(0, "Unexpected call.\n");
1402
return E_NOTIMPL;
1403
}
1404
1405
static HRESULT WINAPI testsource_seeking_GetAvailable(IMediaSeeking *iface, LONGLONG *earliest, LONGLONG *latest)
1406
{
1407
ok(0, "Unexpected call.\n");
1408
return E_NOTIMPL;
1409
}
1410
1411
static HRESULT WINAPI testsource_seeking_SetRate(IMediaSeeking *iface, double rate)
1412
{
1413
ok(0, "Unexpected call.\n");
1414
return E_NOTIMPL;
1415
}
1416
1417
static HRESULT WINAPI testsource_seeking_GetRate(IMediaSeeking *iface, double *rate)
1418
{
1419
ok(0, "Unexpected call.\n");
1420
return E_NOTIMPL;
1421
}
1422
1423
static HRESULT WINAPI testsource_seeking_GetPreroll(IMediaSeeking *iface, LONGLONG *preroll)
1424
{
1425
ok(0, "Unexpected call.\n");
1426
return E_NOTIMPL;
1427
}
1428
1429
static const IMediaSeekingVtbl testsource_seeking_vtbl =
1430
{
1431
testsource_seeking_QueryInterface,
1432
testsource_seeking_AddRef,
1433
testsource_seeking_Release,
1434
testsource_seeking_GetCapabilities,
1435
testsource_seeking_CheckCapabilities,
1436
testsource_seeking_IsFormatSupported,
1437
testsource_seeking_QueryPreferredFormat,
1438
testsource_seeking_GetTimeFormat,
1439
testsource_seeking_IsUsingTimeFormat,
1440
testsource_seeking_SetTimeFormat,
1441
testsource_seeking_GetDuration,
1442
testsource_seeking_GetStopPosition,
1443
testsource_seeking_GetCurrentPosition,
1444
testsource_seeking_ConvertTimeFormat,
1445
testsource_seeking_SetPositions,
1446
testsource_seeking_GetPositions,
1447
testsource_seeking_GetAvailable,
1448
testsource_seeking_SetRate,
1449
testsource_seeking_GetRate,
1450
testsource_seeking_GetPreroll,
1451
};
1452
1453
static inline struct testfilter *impl_from_IQualityControl(IQualityControl *iface)
1454
{
1455
return CONTAINING_RECORD(iface, struct testfilter, IQualityControl_iface);
1456
}
1457
1458
static HRESULT WINAPI testsource_qc_QueryInterface(IQualityControl *iface, REFIID iid, void **out)
1459
{
1460
struct testfilter *filter = impl_from_IQualityControl(iface);
1461
return IBaseFilter_QueryInterface(&filter->filter.IBaseFilter_iface, iid, out);
1462
}
1463
1464
static ULONG WINAPI testsource_qc_AddRef(IQualityControl *iface)
1465
{
1466
struct testfilter *filter = impl_from_IQualityControl(iface);
1467
return IBaseFilter_AddRef(&filter->filter.IBaseFilter_iface);
1468
}
1469
1470
static ULONG WINAPI testsource_qc_Release(IQualityControl *iface)
1471
{
1472
struct testfilter *filter = impl_from_IQualityControl(iface);
1473
return IBaseFilter_Release(&filter->filter.IBaseFilter_iface);
1474
}
1475
1476
static HRESULT WINAPI testsource_qc_Notify(IQualityControl *iface, IBaseFilter *sender, Quality q)
1477
{
1478
struct testfilter *filter = impl_from_IQualityControl(iface);
1479
1480
filter->qc_notify_sender = sender;
1481
filter->qc_notify_quality = q;
1482
1483
return filter->qc_notify_hr;
1484
}
1485
1486
static HRESULT WINAPI testsource_qc_SetSink(IQualityControl *iface, IQualityControl *sink)
1487
{
1488
ok(0, "Unexpected call.\n");
1489
return E_NOTIMPL;
1490
}
1491
1492
static const IQualityControlVtbl testsource_qc_vtbl =
1493
{
1494
testsource_qc_QueryInterface,
1495
testsource_qc_AddRef,
1496
testsource_qc_Release,
1497
testsource_qc_Notify,
1498
testsource_qc_SetSink,
1499
};
1500
1501
#define check_get_stream(a,b,c,d) check_get_stream_(__LINE__,a,b,c,d)
1502
static void check_get_stream_(int line, IAMMultiMediaStream *mmstream,
1503
IMediaStreamFilter *filter, const GUID *mspid, IMediaStream *expect)
1504
{
1505
IMediaStream *stream = NULL, *stream2 = NULL;
1506
HRESULT hr;
1507
1508
hr = IAMMultiMediaStream_GetMediaStream(mmstream, mspid, &stream);
1509
ok_(__FILE__, line)(hr == (expect ? S_OK : MS_E_NOSTREAM),
1510
"IAMMultiMediaStream::GetMediaStream() returned %#lx.\n", hr);
1511
hr = IMediaStreamFilter_GetMediaStream(filter, mspid, &stream2);
1512
ok_(__FILE__, line)(hr == (expect ? S_OK : MS_E_NOSTREAM),
1513
"IMediaStreamFilter::GetMediaStream() returned %#lx.\n", hr);
1514
if (hr == S_OK)
1515
{
1516
ok_(__FILE__, line)(stream == expect, "Expected stream %p, got %p.\n", expect, stream);
1517
ok_(__FILE__, line)(stream2 == expect, "Expected stream %p, got %p.\n", expect, stream2);
1518
}
1519
1520
if (stream) IMediaStream_Release(stream);
1521
if (stream2) IMediaStream_Release(stream2);
1522
}
1523
1524
static void test_add_stream(void)
1525
{
1526
IAMMultiMediaStream *mmstream = create_ammultimediastream();
1527
IMediaStream *video_stream, *audio_stream, *stream;
1528
IDirectDrawMediaStream *ddraw_stream;
1529
IMediaStreamFilter *stream_filter;
1530
struct teststream teststream;
1531
IDirectDraw *ddraw, *ddraw2;
1532
IEnumFilters *enum_filters;
1533
IBaseFilter *filters[3];
1534
IGraphBuilder *graph;
1535
FILTER_INFO info;
1536
ULONG ref, count;
1537
CLSID clsid;
1538
HRESULT hr;
1539
1540
teststream_init(&teststream);
1541
1542
hr = IAMMultiMediaStream_GetFilter(mmstream, &stream_filter);
1543
ok(hr == S_OK, "Got hr %#lx.\n", hr);
1544
1545
hr = IAMMultiMediaStream_EnumMediaStreams(mmstream, 0, NULL);
1546
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1547
hr = IMediaStreamFilter_EnumMediaStreams(stream_filter, 0, NULL);
1548
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1549
1550
hr = IAMMultiMediaStream_GetMediaStream(mmstream, &MSPID_PrimaryAudio, NULL);
1551
ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
1552
hr = IMediaStreamFilter_GetMediaStream(stream_filter, &MSPID_PrimaryAudio, NULL);
1553
ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
1554
hr = IAMMultiMediaStream_GetMediaStream(mmstream, &MSPID_PrimaryVideo, NULL);
1555
ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
1556
hr = IMediaStreamFilter_GetMediaStream(stream_filter, &MSPID_PrimaryVideo, NULL);
1557
ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
1558
1559
check_enum_stream(mmstream, stream_filter, 0, NULL);
1560
1561
check_get_stream(mmstream, stream_filter, NULL, NULL);
1562
check_get_stream(mmstream, stream_filter, &MSPID_PrimaryAudio, NULL);
1563
check_get_stream(mmstream, stream_filter, &MSPID_PrimaryVideo, NULL);
1564
check_get_stream(mmstream, stream_filter, &test_mspid, NULL);
1565
1566
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &test_mspid, 0, &stream);
1567
ok(hr == MS_E_PURPOSEID, "Got hr %#lx.\n", hr);
1568
1569
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &video_stream);
1570
ok(hr == S_OK, "Got hr %#lx.\n", hr);
1571
1572
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
1573
ok(hr == MS_E_PURPOSEID, "Got hr %#lx.\n", hr);
1574
1575
hr = IAMMultiMediaStream_EnumMediaStreams(mmstream, 0, NULL);
1576
ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
1577
hr = IMediaStreamFilter_EnumMediaStreams(stream_filter, 0, NULL);
1578
ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
1579
hr = IAMMultiMediaStream_EnumMediaStreams(mmstream, 1, NULL);
1580
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1581
hr = IMediaStreamFilter_EnumMediaStreams(stream_filter, 1, NULL);
1582
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1583
1584
check_enum_stream(mmstream, stream_filter, 0, video_stream);
1585
check_enum_stream(mmstream, stream_filter, 1, NULL);
1586
1587
check_get_stream(mmstream, stream_filter, &MSPID_PrimaryVideo, video_stream);
1588
check_get_stream(mmstream, stream_filter, &MSPID_PrimaryAudio, NULL);
1589
check_get_stream(mmstream, stream_filter, &test_mspid, NULL);
1590
1591
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &audio_stream);
1592
ok(hr == S_OK, "Got hr %#lx.\n", hr);
1593
1594
check_enum_stream(mmstream, stream_filter, 0, video_stream);
1595
check_enum_stream(mmstream, stream_filter, 1, audio_stream);
1596
check_enum_stream(mmstream, stream_filter, 2, NULL);
1597
1598
check_get_stream(mmstream, stream_filter, &MSPID_PrimaryVideo, video_stream);
1599
check_get_stream(mmstream, stream_filter, &MSPID_PrimaryAudio, audio_stream);
1600
check_get_stream(mmstream, stream_filter, &test_mspid, NULL);
1601
1602
hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)&teststream, &IID_IUnknown, 0, &stream);
1603
ok(hr == MS_E_PURPOSEID, "Got hr %#lx.\n", hr);
1604
1605
hr = IMediaStreamFilter_QueryFilterInfo(stream_filter, &info);
1606
ok(hr == S_OK, "Got hr %#lx.\n", hr);
1607
1608
hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)&teststream, &test_mspid, 0, &stream);
1609
ok(hr == S_OK, "Got hr %#lx.\n", hr);
1610
ok(stream == (IMediaStream *)&teststream, "Streams didn't match.\n");
1611
IMediaStream_Release(stream);
1612
ok(teststream.mmstream == mmstream, "IAMMultiMediaStream objects didn't match.\n");
1613
ok(teststream.filter == stream_filter, "IMediaStreamFilter objects didn't match.\n");
1614
ok(teststream.graph == info.pGraph, "IFilterGraph objects didn't match.\n");
1615
1616
IFilterGraph_Release(info.pGraph);
1617
1618
check_enum_stream(mmstream, stream_filter, 0, video_stream);
1619
check_enum_stream(mmstream, stream_filter, 1, audio_stream);
1620
check_enum_stream(mmstream, stream_filter, 2, (IMediaStream *)&teststream);
1621
check_enum_stream(mmstream, stream_filter, 3, NULL);
1622
1623
check_get_stream(mmstream, stream_filter, &MSPID_PrimaryVideo, video_stream);
1624
check_get_stream(mmstream, stream_filter, &MSPID_PrimaryAudio, audio_stream);
1625
check_get_stream(mmstream, stream_filter, &test_mspid, (IMediaStream *)&teststream);
1626
1627
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
1628
ok(hr == MS_E_PURPOSEID, "Got hr %#lx.\n", hr);
1629
1630
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
1631
ok(hr == S_OK, "Got hr %#lx.\n", hr);
1632
ok(!!graph, "Expected a non-NULL graph.\n");
1633
1634
hr = IGraphBuilder_EnumFilters(graph, &enum_filters);
1635
ok(hr == S_OK, "Got hr %#lx.\n", hr);
1636
hr = IEnumFilters_Next(enum_filters, 3, filters, &count);
1637
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1638
ok(count == 1, "Got count %lu.\n", count);
1639
ok(filters[0] == (IBaseFilter *)stream_filter,
1640
"Expected filter %p, got %p.\n", stream_filter, filters[0]);
1641
IBaseFilter_Release(filters[0]);
1642
IEnumFilters_Release(enum_filters);
1643
IGraphBuilder_Release(graph);
1644
1645
IMediaStreamFilter_Release(stream_filter);
1646
ref = IAMMultiMediaStream_Release(mmstream);
1647
ok(!ref, "Got outstanding refcount %ld.\n", ref);
1648
ref = IMediaStream_Release(video_stream);
1649
ok(!ref, "Got outstanding refcount %ld.\n", ref);
1650
ref = IMediaStream_Release(audio_stream);
1651
ok(!ref, "Got outstanding refcount %ld.\n", ref);
1652
ok(teststream.refcount == 1, "Got outstanding refcount %ld.\n", teststream.refcount);
1653
1654
/* The return parameter is optional. */
1655
1656
mmstream = create_ammultimediastream();
1657
1658
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, NULL);
1659
ok(hr == S_OK, "Got hr %#lx.\n", hr);
1660
1661
hr = IAMMultiMediaStream_GetMediaStream(mmstream, &MSPID_PrimaryVideo, &stream);
1662
ok(hr == S_OK, "Got hr %#lx.\n", hr);
1663
IMediaStream_Release(stream);
1664
1665
ref = IAMMultiMediaStream_Release(mmstream);
1666
ok(!ref, "Got outstanding refcount %ld.\n", ref);
1667
1668
/* Test supplying a DirectDraw object with the primary video stream. */
1669
1670
hr = DirectDrawCreate(NULL, &ddraw, NULL);
1671
ok(hr == DD_OK, "Got hr %#lx.\n", hr);
1672
mmstream = create_ammultimediastream();
1673
1674
hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)ddraw, &MSPID_PrimaryVideo, 0, &video_stream);
1675
ok(hr == S_OK, "Got hr %#lx.\n", hr);
1676
1677
hr = IMediaStream_QueryInterface(video_stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
1678
ok(hr == S_OK, "Got hr %#lx.\n", hr);
1679
hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw2);
1680
ok(hr == S_OK, "Got hr %#lx.\n", hr);
1681
ok(ddraw2 == ddraw, "Expected IDirectDraw %p, got %p.\n", ddraw, ddraw2);
1682
IDirectDraw_Release(ddraw2);
1683
IDirectDrawMediaStream_Release(ddraw_stream);
1684
1685
ref = IAMMultiMediaStream_Release(mmstream);
1686
ok(!ref, "Got outstanding refcount %ld.\n", ref);
1687
ref = IMediaStream_Release(video_stream);
1688
ok(!ref, "Got outstanding refcount %ld.\n", ref);
1689
ref = IDirectDraw_Release(ddraw);
1690
ok(!ref, "Got outstanding refcount %ld.\n", ref);
1691
1692
mmstream = create_ammultimediastream();
1693
1694
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &video_stream);
1695
ok(hr == S_OK, "Got hr %#lx.\n", hr);
1696
1697
hr = IMediaStream_QueryInterface(video_stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
1698
ok(hr == S_OK, "Got hr %#lx.\n", hr);
1699
hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw);
1700
ok(hr == S_OK, "Got hr %#lx.\n", hr);
1701
ok(!!ddraw, "Expected a non-NULL IDirectDraw.\n");
1702
IDirectDraw_Release(ddraw);
1703
IDirectDrawMediaStream_Release(ddraw_stream);
1704
1705
ref = IAMMultiMediaStream_Release(mmstream);
1706
ok(!ref, "Got outstanding refcount %ld.\n", ref);
1707
ref = IMediaStream_Release(video_stream);
1708
ok(!ref, "Got outstanding refcount %ld.\n", ref);
1709
1710
/* Test the AMMSF_ADDDEFAULTRENDERER flag. No stream is added; however, a
1711
* new filter will be added to the graph. */
1712
1713
mmstream = create_ammultimediastream();
1714
hr = IAMMultiMediaStream_GetFilter(mmstream, &stream_filter);
1715
ok(hr == S_OK, "Got hr %#lx.\n", hr);
1716
1717
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo,
1718
AMMSF_ADDDEFAULTRENDERER, &video_stream);
1719
ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
1720
1721
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo,
1722
AMMSF_ADDDEFAULTRENDERER, NULL);
1723
ok(hr == MS_E_PURPOSEID, "Got hr %#lx.\n", hr);
1724
1725
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio,
1726
AMMSF_ADDDEFAULTRENDERER, &audio_stream);
1727
ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
1728
1729
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio,
1730
AMMSF_ADDDEFAULTRENDERER, NULL);
1731
ok(hr == S_OK || hr == VFW_E_NO_AUDIO_HARDWARE, "Got hr %#lx.\n", hr);
1732
1733
check_enum_stream(mmstream, stream_filter, 0, NULL);
1734
1735
check_get_stream(mmstream, stream_filter, &MSPID_PrimaryAudio, NULL);
1736
check_get_stream(mmstream, stream_filter, &MSPID_PrimaryVideo, NULL);
1737
1738
if (hr == S_OK)
1739
{
1740
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
1741
ok(hr == S_OK, "Got hr %#lx.\n", hr);
1742
ok(!!graph, "Got graph %p.\n", graph);
1743
hr = IGraphBuilder_EnumFilters(graph, &enum_filters);
1744
ok(hr == S_OK, "Got hr %#lx.\n", hr);
1745
hr = IEnumFilters_Next(enum_filters, 3, filters, &count);
1746
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1747
ok(count == 2, "Got count %lu.\n", count);
1748
ok(filters[1] == (IBaseFilter *)stream_filter,
1749
"Expected filter %p, got %p.\n", stream_filter, filters[1]);
1750
hr = IBaseFilter_GetClassID(filters[0], &clsid);
1751
ok(hr == S_OK, "Got hr %#lx.\n", hr);
1752
ok(IsEqualGUID(&clsid, &CLSID_DSoundRender), "Got unexpected filter %s.\n", wine_dbgstr_guid(&clsid));
1753
IBaseFilter_Release(filters[0]);
1754
IBaseFilter_Release(filters[1]);
1755
IEnumFilters_Release(enum_filters);
1756
IGraphBuilder_Release(graph);
1757
}
1758
1759
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &test_mspid,
1760
AMMSF_ADDDEFAULTRENDERER, NULL);
1761
ok(hr == MS_E_PURPOSEID, "Got hr %#lx.\n", hr);
1762
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &test_mspid,
1763
AMMSF_ADDDEFAULTRENDERER, &audio_stream);
1764
ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
1765
1766
ref = IAMMultiMediaStream_Release(mmstream);
1767
ok(!ref, "Got outstanding refcount %ld.\n", ref);
1768
ref = IMediaStreamFilter_Release(stream_filter);
1769
ok(!ref, "Got outstanding refcount %ld.\n", ref);
1770
}
1771
1772
static void test_media_streams(void)
1773
{
1774
IAMMultiMediaStream *pams;
1775
HRESULT hr;
1776
IMediaStream *video_stream = NULL;
1777
IMediaStream *audio_stream = NULL;
1778
IMediaStreamFilter* media_stream_filter = NULL;
1779
1780
if (!(pams = create_ammultimediastream()))
1781
return;
1782
1783
hr = IAMMultiMediaStream_Initialize(pams, STREAMTYPE_READ, 0, NULL);
1784
ok(hr == S_OK, "IAMMultiMediaStream_Initialize returned: %lx\n", hr);
1785
1786
/* Retrieve media stream filter */
1787
hr = IAMMultiMediaStream_GetFilter(pams, NULL);
1788
ok(hr == E_POINTER, "IAMMultiMediaStream_GetFilter returned: %lx\n", hr);
1789
hr = IAMMultiMediaStream_GetFilter(pams, &media_stream_filter);
1790
ok(hr == S_OK, "IAMMultiMediaStream_GetFilter returned: %lx\n", hr);
1791
1792
hr = IAMMultiMediaStream_AddMediaStream(pams, NULL, &MSPID_PrimaryVideo, 0, NULL);
1793
ok(hr == S_OK, "IAMMultiMediaStream_AddMediaStream returned: %lx\n", hr);
1794
hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryVideo, &video_stream);
1795
ok(hr == S_OK, "IAMMultiMediaStream_GetMediaStream returned: %lx\n", hr);
1796
1797
/* Check interfaces and samples for video */
1798
if (video_stream)
1799
{
1800
IAMMediaStream* am_media_stream;
1801
IMultiMediaStream *multi_media_stream;
1802
IPin *pin = NULL;
1803
IAudioMediaStream* audio_media_stream;
1804
IDirectDrawMediaStream *ddraw_stream = NULL;
1805
IDirectDrawStreamSample *ddraw_sample = NULL;
1806
1807
hr = IMediaStream_QueryInterface(video_stream, &IID_IAMMediaStream, (LPVOID*)&am_media_stream);
1808
ok(hr == S_OK, "IMediaStream_QueryInterface returned: %lx\n", hr);
1809
ok((void*)am_media_stream == (void*)video_stream, "Not same interface, got %p expected %p\n", am_media_stream, video_stream);
1810
1811
hr = IAMMediaStream_GetMultiMediaStream(am_media_stream, NULL);
1812
ok(hr == E_POINTER, "Expected E_POINTER, got %lx\n", hr);
1813
1814
multi_media_stream = (void *)0xdeadbeef;
1815
hr = IAMMediaStream_GetMultiMediaStream(am_media_stream, &multi_media_stream);
1816
ok(hr == S_OK, "IAMMediaStream_GetMultiMediaStream returned: %lx\n", hr);
1817
ok((void *)multi_media_stream == (void *)pams, "Expected %p, got %p\n", pams, multi_media_stream);
1818
IMultiMediaStream_Release(multi_media_stream);
1819
1820
IAMMediaStream_Release(am_media_stream);
1821
1822
hr = IMediaStream_QueryInterface(video_stream, &IID_IPin, (void **)&pin);
1823
ok(hr == S_OK, "IMediaStream_QueryInterface returned: %lx\n", hr);
1824
1825
IPin_Release(pin);
1826
1827
hr = IMediaStream_QueryInterface(video_stream, &IID_IAudioMediaStream, (LPVOID*)&audio_media_stream);
1828
ok(hr == E_NOINTERFACE, "IMediaStream_QueryInterface returned: %lx\n", hr);
1829
1830
hr = IMediaStream_QueryInterface(video_stream, &IID_IDirectDrawMediaStream, (LPVOID*)&ddraw_stream);
1831
ok(hr == S_OK, "IMediaStream_QueryInterface returned: %lx\n", hr);
1832
1833
if (SUCCEEDED(hr))
1834
{
1835
DDSURFACEDESC current_format, desired_format;
1836
IDirectDrawPalette *palette;
1837
DWORD flags;
1838
1839
hr = IDirectDrawMediaStream_GetFormat(ddraw_stream, &current_format, &palette, &desired_format, &flags);
1840
ok(hr == MS_E_NOSTREAM, "IDirectDrawoMediaStream_GetFormat returned: %lx\n", hr);
1841
1842
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &ddraw_sample);
1843
ok(hr == S_OK, "IDirectDrawMediaStream_CreateSample returned: %lx\n", hr);
1844
1845
hr = IDirectDrawMediaStream_GetMultiMediaStream(ddraw_stream, NULL);
1846
ok(hr == E_POINTER, "Expected E_POINTER, got %lx\n", hr);
1847
1848
multi_media_stream = (void *)0xdeadbeef;
1849
hr = IDirectDrawMediaStream_GetMultiMediaStream(ddraw_stream, &multi_media_stream);
1850
ok(hr == S_OK, "IDirectDrawMediaStream_GetMultiMediaStream returned: %lx\n", hr);
1851
ok((void *)multi_media_stream == (void *)pams, "Expected %p, got %p\n", pams, multi_media_stream);
1852
IMultiMediaStream_Release(multi_media_stream);
1853
}
1854
1855
if (ddraw_sample)
1856
IDirectDrawStreamSample_Release(ddraw_sample);
1857
if (ddraw_stream)
1858
IDirectDrawMediaStream_Release(ddraw_stream);
1859
}
1860
1861
hr = IAMMultiMediaStream_AddMediaStream(pams, NULL, &MSPID_PrimaryAudio, 0, NULL);
1862
ok(hr == S_OK, "IAMMultiMediaStream_AddMediaStream returned: %lx\n", hr);
1863
hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryAudio, &audio_stream);
1864
ok(hr == S_OK, "IAMMultiMediaStream_GetMediaStream returned: %lx\n", hr);
1865
1866
/* Check interfaces and samples for audio */
1867
if (audio_stream)
1868
{
1869
IAMMediaStream* am_media_stream;
1870
IMultiMediaStream *multi_media_stream;
1871
IPin *pin = NULL;
1872
IDirectDrawMediaStream* ddraw_stream = NULL;
1873
IAudioMediaStream* audio_media_stream = NULL;
1874
IAudioStreamSample *audio_sample = NULL;
1875
1876
hr = IMediaStream_QueryInterface(audio_stream, &IID_IAMMediaStream, (LPVOID*)&am_media_stream);
1877
ok(hr == S_OK, "IMediaStream_QueryInterface returned: %lx\n", hr);
1878
ok((void*)am_media_stream == (void*)audio_stream, "Not same interface, got %p expected %p\n", am_media_stream, audio_stream);
1879
1880
hr = IAMMediaStream_GetMultiMediaStream(am_media_stream, NULL);
1881
ok(hr == E_POINTER, "Expected E_POINTER, got %lx\n", hr);
1882
1883
multi_media_stream = (void *)0xdeadbeef;
1884
hr = IAMMediaStream_GetMultiMediaStream(am_media_stream, &multi_media_stream);
1885
ok(hr == S_OK, "IAMMediaStream_GetMultiMediaStream returned: %lx\n", hr);
1886
ok((void *)multi_media_stream == (void *)pams, "Expected %p, got %p\n", pams, multi_media_stream);
1887
IMultiMediaStream_Release(multi_media_stream);
1888
1889
IAMMediaStream_Release(am_media_stream);
1890
1891
hr = IMediaStream_QueryInterface(audio_stream, &IID_IPin, (void **)&pin);
1892
ok(hr == S_OK, "IMediaStream_QueryInterface returned: %lx\n", hr);
1893
1894
IPin_Release(pin);
1895
1896
hr = IMediaStream_QueryInterface(audio_stream, &IID_IDirectDrawMediaStream, (LPVOID*)&ddraw_stream);
1897
ok(hr == E_NOINTERFACE, "IMediaStream_QueryInterface returned: %lx\n", hr);
1898
1899
hr = IMediaStream_QueryInterface(audio_stream, &IID_IAudioMediaStream, (LPVOID*)&audio_media_stream);
1900
ok(hr == S_OK, "IMediaStream_QueryInterface returned: %lx\n", hr);
1901
1902
if (SUCCEEDED(hr))
1903
{
1904
IAudioData* audio_data = NULL;
1905
1906
hr = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, &IID_IAudioData, (void **)&audio_data);
1907
ok(hr == S_OK, "CoCreateInstance returned: %lx\n", hr);
1908
1909
hr = IAudioMediaStream_CreateSample(audio_media_stream, NULL, 0, &audio_sample);
1910
ok(hr == E_POINTER, "IAudioMediaStream_CreateSample returned: %lx\n", hr);
1911
1912
EXPECT_REF(audio_stream, 3);
1913
EXPECT_REF(audio_data, 1);
1914
hr = IAudioMediaStream_CreateSample(audio_media_stream, audio_data, 0, &audio_sample);
1915
ok(hr == S_OK, "IAudioMediaStream_CreateSample returned: %lx\n", hr);
1916
EXPECT_REF(audio_stream, 4);
1917
EXPECT_REF(audio_data, 2);
1918
1919
hr = IAudioMediaStream_GetMultiMediaStream(audio_media_stream, NULL);
1920
ok(hr == E_POINTER, "Expected E_POINTER, got %lx\n", hr);
1921
1922
multi_media_stream = (void *)0xdeadbeef;
1923
hr = IAudioMediaStream_GetMultiMediaStream(audio_media_stream, &multi_media_stream);
1924
ok(hr == S_OK, "IAudioMediaStream_GetMultiMediaStream returned: %lx\n", hr);
1925
ok((void *)multi_media_stream == (void *)pams, "Expected %p, got %p\n", pams, multi_media_stream);
1926
IMultiMediaStream_Release(multi_media_stream);
1927
1928
if (audio_data)
1929
IAudioData_Release(audio_data);
1930
if (audio_sample)
1931
IAudioStreamSample_Release(audio_sample);
1932
if (audio_media_stream)
1933
IAudioMediaStream_Release(audio_media_stream);
1934
}
1935
}
1936
1937
if (media_stream_filter)
1938
{
1939
IEnumPins *enum_pins;
1940
1941
hr = IMediaStreamFilter_EnumPins(media_stream_filter, &enum_pins);
1942
ok(hr == S_OK, "IBaseFilter_EnumPins returned: %lx\n", hr);
1943
if (hr == S_OK)
1944
{
1945
IPin* pins[3] = { NULL, NULL, NULL };
1946
ULONG nb_pins;
1947
ULONG expected_nb_pins = audio_stream ? 2 : 1;
1948
int i;
1949
1950
hr = IEnumPins_Next(enum_pins, 3, pins, &nb_pins);
1951
ok(SUCCEEDED(hr), "IEnumPins_Next returned: %lx\n", hr);
1952
ok(nb_pins == expected_nb_pins, "Number of pins is %lu instead of %lu\n", nb_pins, expected_nb_pins);
1953
for (i = 0; i < min(nb_pins, expected_nb_pins); i++)
1954
{
1955
IPin* pin;
1956
1957
hr = IPin_ConnectedTo(pins[i], &pin);
1958
ok(hr == VFW_E_NOT_CONNECTED, "IPin_ConnectedTo returned: %lx\n", hr);
1959
IPin_Release(pins[i]);
1960
}
1961
IEnumPins_Release(enum_pins);
1962
}
1963
}
1964
1965
/* Test open file with no filename */
1966
hr = IAMMultiMediaStream_OpenFile(pams, NULL, AMMSF_RENDERTOEXISTING);
1967
ok(hr == E_POINTER, "IAMMultiMediaStream_OpenFile returned %lx instead of %lx\n", hr, E_POINTER);
1968
1969
if (video_stream)
1970
IMediaStream_Release(video_stream);
1971
if (audio_stream)
1972
IMediaStream_Release(audio_stream);
1973
if (media_stream_filter)
1974
IMediaStreamFilter_Release(media_stream_filter);
1975
1976
IAMMultiMediaStream_Release(pams);
1977
}
1978
1979
static void test_enum_pins(void)
1980
{
1981
IAMMultiMediaStream *mmstream = create_ammultimediastream();
1982
IMediaStream *stream0, *stream1;
1983
IPin *pins[3], *pin0, *pin1;
1984
IMediaStreamFilter *filter;
1985
IEnumPins *enum1, *enum2;
1986
ULONG ref, count;
1987
HRESULT hr;
1988
1989
hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
1990
ok(hr == S_OK, "Got hr %#lx.\n", hr);
1991
1992
ref = get_refcount(filter);
1993
ok(ref == 3, "Got unexpected refcount %ld.\n", ref);
1994
1995
hr = IMediaStreamFilter_EnumPins(filter, NULL);
1996
ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
1997
1998
hr = IMediaStreamFilter_EnumPins(filter, &enum1);
1999
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2000
ref = get_refcount(filter);
2001
ok(ref == 3, "Got unexpected refcount %ld.\n", ref);
2002
ref = get_refcount(enum1);
2003
ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
2004
2005
hr = IEnumPins_Next(enum1, 1, NULL, NULL);
2006
ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2007
2008
hr = IEnumPins_Next(enum1, 1, pins, NULL);
2009
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2010
2011
hr = IEnumPins_Reset(enum1);
2012
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2013
2014
hr = IEnumPins_Skip(enum1, 0);
2015
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2016
2017
hr = IEnumPins_Skip(enum1, 1);
2018
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2019
2020
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream0);
2021
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2022
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream1);
2023
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2024
hr = IMediaStream_QueryInterface(stream0, &IID_IPin, (void **)&pin0);
2025
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2026
hr = IMediaStream_QueryInterface(stream1, &IID_IPin, (void **)&pin1);
2027
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2028
2029
/* Reset() isn't enough; we have to call EnumPins() again to see the updated
2030
* pin count. */
2031
hr = IEnumPins_Reset(enum1);
2032
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2033
2034
hr = IEnumPins_Next(enum1, 1, pins, NULL);
2035
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2036
2037
IEnumPins_Release(enum1);
2038
2039
hr = IMediaStreamFilter_EnumPins(filter, &enum1);
2040
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2041
2042
ref = get_refcount(filter);
2043
ok(ref == 4, "Got unexpected refcount %ld.\n", ref);
2044
ref = get_refcount(enum1);
2045
ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
2046
ref = get_refcount(pin0);
2047
ok(ref == 4, "Got unexpected refcount %ld.\n", ref);
2048
ref = get_refcount(pin1);
2049
ok(ref == 4, "Got unexpected refcount %ld.\n", ref);
2050
2051
hr = IEnumPins_Next(enum1, 1, pins, NULL);
2052
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2053
ok(pins[0] == pin0, "Expected pin %p, got %p.\n", pin0, pins[0]);
2054
ref = get_refcount(filter);
2055
ok(ref == 4, "Got unexpected refcount %ld.\n", ref);
2056
ref = get_refcount(enum1);
2057
ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
2058
ref = get_refcount(pin0);
2059
ok(ref == 5, "Got unexpected refcount %ld.\n", ref);
2060
IPin_Release(pins[0]);
2061
2062
hr = IEnumPins_Next(enum1, 1, pins, NULL);
2063
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2064
ok(pins[0] == pin1, "Expected pin %p, got %p.\n", pin1, pins[0]);
2065
ref = get_refcount(filter);
2066
ok(ref == 4, "Got unexpected refcount %ld.\n", ref);
2067
ref = get_refcount(enum1);
2068
ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
2069
ref = get_refcount(pin1);
2070
ok(ref == 5, "Got unexpected refcount %ld.\n", ref);
2071
IPin_Release(pins[0]);
2072
2073
hr = IEnumPins_Next(enum1, 1, pins, NULL);
2074
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2075
2076
hr = IEnumPins_Reset(enum1);
2077
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2078
2079
hr = IEnumPins_Next(enum1, 1, pins, &count);
2080
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2081
ok(count == 1, "Got count %lu.\n", count);
2082
ok(pins[0] == pin0, "Expected pin %p, got %p.\n", pin0, pins[0]);
2083
IPin_Release(pins[0]);
2084
2085
hr = IEnumPins_Next(enum1, 1, pins, &count);
2086
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2087
ok(count == 1, "Got count %lu.\n", count);
2088
ok(pins[0] == pin1, "Expected pin %p, got %p.\n", pin1, pins[0]);
2089
IPin_Release(pins[0]);
2090
2091
hr = IEnumPins_Reset(enum1);
2092
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2093
2094
hr = IEnumPins_Next(enum1, 3, pins, NULL);
2095
ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2096
2097
hr = IEnumPins_Next(enum1, 3, pins, &count);
2098
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2099
ok(count == 2, "Got count %lu.\n", count);
2100
ok(pins[0] == pin0, "Expected pin %p, got %p.\n", pin0, pins[0]);
2101
ok(pins[1] == pin1, "Expected pin %p, got %p.\n", pin1, pins[1]);
2102
IPin_Release(pins[0]);
2103
IPin_Release(pins[1]);
2104
2105
hr = IEnumPins_Reset(enum1);
2106
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2107
2108
hr = IEnumPins_Clone(enum1, &enum2);
2109
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2110
2111
hr = IEnumPins_Skip(enum1, 0);
2112
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2113
2114
hr = IEnumPins_Skip(enum1, 2);
2115
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2116
2117
hr = IEnumPins_Next(enum1, 1, pins, NULL);
2118
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2119
2120
hr = IEnumPins_Next(enum2, 1, pins, NULL);
2121
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2122
ok(pins[0] == pin0, "Expected pin %p, got %p.\n", pin0, pins[0]);
2123
IPin_Release(pins[0]);
2124
2125
hr = IEnumPins_Next(enum2, 1, pins, NULL);
2126
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2127
ok(pins[0] == pin1, "Expected pin %p, got %p.\n", pin1, pins[0]);
2128
IPin_Release(pins[0]);
2129
2130
IEnumPins_Release(enum2);
2131
IEnumPins_Release(enum1);
2132
2133
IMediaStreamFilter_Release(filter);
2134
ref = IAMMultiMediaStream_Release(mmstream);
2135
ok(!ref, "Got outstanding refcount %ld.\n", ref);
2136
IMediaStream_Release(stream1);
2137
IMediaStream_Release(stream0);
2138
ref = IPin_Release(pin1);
2139
ok(!ref, "Got outstanding refcount %ld.\n", ref);
2140
ref = IPin_Release(pin0);
2141
ok(!ref, "Got outstanding refcount %ld.\n", ref);
2142
}
2143
2144
static void test_find_pin(void)
2145
{
2146
IAMMultiMediaStream *mmstream = create_ammultimediastream();
2147
IMediaStreamFilter *filter;
2148
IMediaStream *stream;
2149
IPin *pin, *pin2;
2150
HRESULT hr;
2151
ULONG ref;
2152
2153
hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
2154
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2155
2156
hr = IMediaStreamFilter_FindPin(filter, primary_video_sink_id, &pin2);
2157
ok(hr == VFW_E_NOT_FOUND, "Got hr %#lx.\n", hr);
2158
2159
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
2160
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2161
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
2162
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2163
2164
hr = IMediaStreamFilter_FindPin(filter, primary_video_sink_id, &pin2);
2165
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2166
ok(pin2 == pin, "Expected pin %p, got %p.\n", pin, pin2);
2167
2168
IPin_Release(pin2);
2169
IPin_Release(pin);
2170
IMediaStream_Release(stream);
2171
IMediaStreamFilter_Release(filter);
2172
ref = IAMMultiMediaStream_Release(mmstream);
2173
ok(!ref, "Got outstanding refcount %ld.\n", ref);
2174
}
2175
2176
static void test_pin_info(void)
2177
{
2178
IAMMultiMediaStream *mmstream = create_ammultimediastream();
2179
IMediaStreamFilter *filter;
2180
IMediaStream *stream;
2181
PIN_DIRECTION dir;
2182
ULONG ref, count;
2183
PIN_INFO info;
2184
HRESULT hr;
2185
WCHAR *id;
2186
IPin *pin;
2187
2188
hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
2189
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2190
2191
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
2192
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2193
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
2194
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2195
2196
hr = IPin_QueryPinInfo(pin, &info);
2197
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2198
ok(info.pFilter == (IBaseFilter *)filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
2199
ok(info.dir == PINDIR_INPUT, "Got direction %d.\n", info.dir);
2200
ok(!wcscmp(info.achName, primary_video_sink_id), "Got name %s.\n", wine_dbgstr_w(info.achName));
2201
IBaseFilter_Release(info.pFilter);
2202
2203
hr = IPin_QueryDirection(pin, &dir);
2204
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2205
ok(dir == PINDIR_INPUT, "Got direction %d.\n", dir);
2206
2207
hr = IPin_QueryId(pin, &id);
2208
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2209
ok(!wcscmp(id, primary_video_sink_id), "Got id %s.\n", wine_dbgstr_w(id));
2210
CoTaskMemFree(id);
2211
2212
hr = IPin_QueryInternalConnections(pin, NULL, &count);
2213
ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
2214
2215
IPin_Release(pin);
2216
IMediaStream_Release(stream);
2217
2218
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
2219
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2220
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
2221
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2222
2223
hr = IPin_QueryPinInfo(pin, &info);
2224
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2225
ok(info.pFilter == (IBaseFilter *)filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
2226
ok(info.dir == PINDIR_INPUT, "Got direction %d.\n", info.dir);
2227
ok(!wcscmp(info.achName, primary_audio_sink_id), "Got name %s.\n", wine_dbgstr_w(info.achName));
2228
IBaseFilter_Release(info.pFilter);
2229
2230
hr = IPin_QueryDirection(pin, &dir);
2231
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2232
ok(dir == PINDIR_INPUT, "Got direction %d.\n", dir);
2233
2234
hr = IPin_QueryId(pin, &id);
2235
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2236
ok(!wcscmp(id, primary_audio_sink_id), "Got id %s.\n", wine_dbgstr_w(id));
2237
CoTaskMemFree(id);
2238
2239
hr = IPin_QueryInternalConnections(pin, NULL, &count);
2240
ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
2241
2242
IPin_Release(pin);
2243
IMediaStream_Release(stream);
2244
2245
IMediaStreamFilter_Release(filter);
2246
ref = IAMMultiMediaStream_Release(mmstream);
2247
ok(!ref, "Got outstanding refcount %ld.\n", ref);
2248
}
2249
2250
struct graph
2251
{
2252
IFilterGraph2 IFilterGraph2_iface;
2253
IMediaEventSink IMediaEventSink_iface;
2254
IUnknown *inner_unk;
2255
IFilterGraph2 *inner;
2256
IMediaEventSink *inner_event_sink;
2257
LONG refcount;
2258
unsigned int got_add_filter;
2259
IBaseFilter *filter;
2260
WCHAR filter_name[128];
2261
unsigned int got_notify;
2262
LONG event_code;
2263
LONG_PTR event_param1;
2264
LONG_PTR event_param2;
2265
};
2266
2267
static struct graph *impl_from_IFilterGraph2(IFilterGraph2 *iface)
2268
{
2269
return CONTAINING_RECORD(iface, struct graph, IFilterGraph2_iface);
2270
}
2271
2272
static struct graph *impl_from_IMediaEventSink(IMediaEventSink *iface)
2273
{
2274
return CONTAINING_RECORD(iface, struct graph, IMediaEventSink_iface);
2275
}
2276
2277
static HRESULT WINAPI graph_QueryInterface(IFilterGraph2 *iface, REFIID iid, void **out)
2278
{
2279
struct graph *graph = impl_from_IFilterGraph2(iface);
2280
if (winetest_debug > 1) trace("QueryInterface(%s)\n", wine_dbgstr_guid(iid));
2281
if (IsEqualGUID(iid, &IID_IFilterGraph2)
2282
|| IsEqualGUID(iid, &IID_IGraphBuilder)
2283
|| IsEqualGUID(iid, &IID_IFilterGraph)
2284
|| IsEqualGUID(iid, &IID_IUnknown))
2285
{
2286
*out = iface;
2287
IFilterGraph2_AddRef(iface);
2288
return S_OK;
2289
}
2290
else if (IsEqualGUID(iid, &IID_IMediaEventSink))
2291
{
2292
*out = &graph->IMediaEventSink_iface;
2293
IFilterGraph2_AddRef(iface);
2294
return S_OK;
2295
}
2296
else
2297
{
2298
return IUnknown_QueryInterface(graph->inner_unk, iid, out);
2299
}
2300
return E_NOINTERFACE;
2301
}
2302
2303
static ULONG WINAPI graph_AddRef(IFilterGraph2 *iface)
2304
{
2305
struct graph *graph = impl_from_IFilterGraph2(iface);
2306
return InterlockedIncrement(&graph->refcount);
2307
}
2308
2309
static ULONG WINAPI graph_Release(IFilterGraph2 *iface)
2310
{
2311
struct graph *graph = impl_from_IFilterGraph2(iface);
2312
return InterlockedDecrement(&graph->refcount);
2313
}
2314
2315
static HRESULT WINAPI graph_AddFilter(IFilterGraph2 *iface, IBaseFilter *filter, const WCHAR *name)
2316
{
2317
struct graph *graph = impl_from_IFilterGraph2(iface);
2318
if (winetest_debug > 1) trace("AddFilter(%p, %s)\n", filter, wine_dbgstr_w(name));
2319
++graph->got_add_filter;
2320
graph->filter = filter;
2321
if (name)
2322
wcscpy(graph->filter_name, name);
2323
else
2324
graph->filter_name[0] = 0;
2325
return IFilterGraph2_AddFilter(graph->inner, filter, name);
2326
}
2327
2328
static HRESULT WINAPI graph_RemoveFilter(IFilterGraph2 *iface, IBaseFilter *filter)
2329
{
2330
ok(0, "Unexpected call.\n");
2331
return E_NOTIMPL;
2332
}
2333
2334
static HRESULT WINAPI graph_EnumFilters(IFilterGraph2 *iface, IEnumFilters **enumfilters)
2335
{
2336
struct graph *graph = impl_from_IFilterGraph2(iface);
2337
if (winetest_debug > 1) trace("EnumFilters()\n");
2338
return IFilterGraph2_EnumFilters(graph->inner, enumfilters);
2339
}
2340
2341
static HRESULT WINAPI graph_FindFilterByName(IFilterGraph2 *iface, const WCHAR *name, IBaseFilter **filter)
2342
{
2343
ok(0, "Unexpected call.\n");
2344
return E_NOTIMPL;
2345
}
2346
2347
static HRESULT WINAPI graph_ConnectDirect(IFilterGraph2 *iface, IPin *source, IPin *sink, const AM_MEDIA_TYPE *mt)
2348
{
2349
struct graph *graph = impl_from_IFilterGraph2(iface);
2350
return IFilterGraph2_ConnectDirect(graph->inner, source, sink, mt);
2351
}
2352
2353
static HRESULT WINAPI graph_Reconnect(IFilterGraph2 *iface, IPin *pin)
2354
{
2355
ok(0, "Unexpected call.\n");
2356
return E_NOTIMPL;
2357
}
2358
2359
static HRESULT WINAPI graph_Disconnect(IFilterGraph2 *iface, IPin *pin)
2360
{
2361
struct graph *graph = impl_from_IFilterGraph2(iface);
2362
return IFilterGraph2_Disconnect(graph->inner, pin);
2363
}
2364
2365
static HRESULT WINAPI graph_SetDefaultSyncSource(IFilterGraph2 *iface)
2366
{
2367
ok(0, "Unexpected call.\n");
2368
return E_NOTIMPL;
2369
}
2370
2371
static HRESULT WINAPI graph_Connect(IFilterGraph2 *iface, IPin *source, IPin *sink)
2372
{
2373
ok(0, "Unexpected call.\n");
2374
return E_NOTIMPL;
2375
}
2376
2377
static HRESULT WINAPI graph_Render(IFilterGraph2 *iface, IPin *source)
2378
{
2379
ok(0, "Unexpected call.\n");
2380
return E_NOTIMPL;
2381
}
2382
2383
static HRESULT WINAPI graph_RenderFile(IFilterGraph2 *iface, const WCHAR *filename, const WCHAR *playlist)
2384
{
2385
ok(0, "Unexpected call.\n");
2386
return E_NOTIMPL;
2387
}
2388
2389
static HRESULT WINAPI graph_AddSourceFilter(IFilterGraph2 *iface,
2390
const WCHAR *filename, const WCHAR *filter_name, IBaseFilter **filter)
2391
{
2392
ok(0, "Unexpected call.\n");
2393
return E_NOTIMPL;
2394
}
2395
2396
static HRESULT WINAPI graph_SetLogFile(IFilterGraph2 *iface, DWORD_PTR file)
2397
{
2398
ok(0, "Unexpected call.\n");
2399
return E_NOTIMPL;
2400
}
2401
2402
static HRESULT WINAPI graph_Abort(IFilterGraph2 *iface)
2403
{
2404
ok(0, "Unexpected call.\n");
2405
return E_NOTIMPL;
2406
}
2407
2408
static HRESULT WINAPI graph_ShouldOperationContinue(IFilterGraph2 *iface)
2409
{
2410
ok(0, "Unexpected call.\n");
2411
return E_NOTIMPL;
2412
}
2413
2414
static HRESULT WINAPI graph_AddSourceFilterForMoniker(IFilterGraph2 *iface,
2415
IMoniker *moniker, IBindCtx *bind_ctx, const WCHAR *filter_name, IBaseFilter **filter)
2416
{
2417
ok(0, "Unexpected call.\n");
2418
return E_NOTIMPL;
2419
}
2420
2421
static HRESULT WINAPI graph_ReconnectEx(IFilterGraph2 *iface, IPin *pin, const AM_MEDIA_TYPE *mt)
2422
{
2423
ok(0, "Unexpected call.\n");
2424
return E_NOTIMPL;
2425
}
2426
2427
static HRESULT WINAPI graph_RenderEx(IFilterGraph2 *iface, IPin *pin, DWORD flags, DWORD *context)
2428
{
2429
ok(0, "Unexpected call.\n");
2430
return E_NOTIMPL;
2431
}
2432
2433
static const IFilterGraph2Vtbl graph_vtbl =
2434
{
2435
graph_QueryInterface,
2436
graph_AddRef,
2437
graph_Release,
2438
graph_AddFilter,
2439
graph_RemoveFilter,
2440
graph_EnumFilters,
2441
graph_FindFilterByName,
2442
graph_ConnectDirect,
2443
graph_Reconnect,
2444
graph_Disconnect,
2445
graph_SetDefaultSyncSource,
2446
graph_Connect,
2447
graph_Render,
2448
graph_RenderFile,
2449
graph_AddSourceFilter,
2450
graph_SetLogFile,
2451
graph_Abort,
2452
graph_ShouldOperationContinue,
2453
graph_AddSourceFilterForMoniker,
2454
graph_ReconnectEx,
2455
graph_RenderEx,
2456
};
2457
2458
static HRESULT WINAPI event_sink_QueryInterface(IMediaEventSink *iface, REFIID iid, void **out)
2459
{
2460
struct graph *graph = impl_from_IMediaEventSink(iface);
2461
return IFilterGraph2_QueryInterface(&graph->IFilterGraph2_iface, iid, out);
2462
}
2463
2464
static ULONG WINAPI event_sink_AddRef(IMediaEventSink *iface)
2465
{
2466
struct graph *graph = impl_from_IMediaEventSink(iface);
2467
return IFilterGraph2_AddRef(&graph->IFilterGraph2_iface);
2468
}
2469
2470
static ULONG WINAPI event_sink_Release(IMediaEventSink *iface)
2471
{
2472
struct graph *graph = impl_from_IMediaEventSink(iface);
2473
return IFilterGraph2_Release(&graph->IFilterGraph2_iface);
2474
}
2475
2476
static HRESULT WINAPI event_sink_Notify(IMediaEventSink *iface,
2477
LONG code, LONG_PTR param1, LONG_PTR param2)
2478
{
2479
struct graph *graph = impl_from_IMediaEventSink(iface);
2480
++graph->got_notify;
2481
graph->event_code = code;
2482
graph->event_param1 = param1;
2483
graph->event_param2 = param2;
2484
return IMediaEventSink_Notify(graph->inner_event_sink, code, param1, param2);
2485
}
2486
2487
static const IMediaEventSinkVtbl event_sink_vtbl =
2488
{
2489
event_sink_QueryInterface,
2490
event_sink_AddRef,
2491
event_sink_Release,
2492
event_sink_Notify,
2493
};
2494
2495
static void graph_init(struct graph *graph)
2496
{
2497
HRESULT hr;
2498
2499
memset(graph, 0, sizeof(*graph));
2500
graph->IFilterGraph2_iface.lpVtbl = &graph_vtbl;
2501
graph->IMediaEventSink_iface.lpVtbl = &event_sink_vtbl;
2502
graph->refcount = 1;
2503
hr = CoCreateInstance(&CLSID_FilterGraph, (IUnknown *)&graph->IFilterGraph2_iface, CLSCTX_INPROC_SERVER,
2504
&IID_IUnknown, (void **)&graph->inner_unk);
2505
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2506
hr = IUnknown_QueryInterface(graph->inner_unk, &IID_IFilterGraph2, (void **)&graph->inner);
2507
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2508
hr = IUnknown_QueryInterface(graph->inner_unk, &IID_IMediaEventSink, (void **)&graph->inner_event_sink);
2509
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2510
}
2511
2512
static void graph_destroy(struct graph *graph)
2513
{
2514
ULONG ref;
2515
2516
IMediaEventSink_Release(graph->inner_event_sink);
2517
IFilterGraph2_Release(graph->inner);
2518
ref = IUnknown_Release(graph->inner_unk);
2519
ok(!ref, "Got outstanding refcount %ld.\n", ref);
2520
}
2521
2522
static void test_initialize(void)
2523
{
2524
IAMMultiMediaStream *mmstream = create_ammultimediastream();
2525
IMediaStreamFilter *filter;
2526
IGraphBuilder *ret_graph;
2527
IMediaStream *stream;
2528
struct graph graph;
2529
STREAM_TYPE type;
2530
HRESULT hr;
2531
ULONG ref;
2532
2533
ret_graph = (IGraphBuilder *)0xdeadbeef;
2534
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &ret_graph);
2535
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2536
ok(!ret_graph, "Got unexpected graph %p.\n", ret_graph);
2537
2538
hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
2539
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2540
ok(!!filter, "Expected a non-NULL filter.");
2541
IMediaStreamFilter_Release(filter);
2542
2543
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
2544
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2545
2546
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
2547
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2548
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_WRITE, 0, NULL);
2549
ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2550
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_TRANSFORM, 0, NULL);
2551
ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2552
2553
ret_graph = (IGraphBuilder *)0xdeadbeef;
2554
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &ret_graph);
2555
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2556
ok(!ret_graph, "Got unexpected graph %p.\n", ret_graph);
2557
2558
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
2559
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2560
type = 0xdeadbeef;
2561
hr = IMediaStream_GetInformation(stream, NULL, &type);
2562
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2563
ok(type == STREAMTYPE_READ, "Got type %u.\n", type);
2564
IMediaStream_Release(stream);
2565
2566
ret_graph = NULL;
2567
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &ret_graph);
2568
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2569
ok(!!ret_graph, "Got unexpected graph %p.\n", ret_graph);
2570
IGraphBuilder_Release(ret_graph);
2571
2572
ref = IAMMultiMediaStream_Release(mmstream);
2573
ok(!ref, "Got outstanding refcount %ld.\n", ref);
2574
2575
mmstream = create_ammultimediastream();
2576
2577
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_WRITE, 0, NULL);
2578
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2579
2580
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_WRITE, 0, NULL);
2581
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2582
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
2583
ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2584
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_TRANSFORM, 0, NULL);
2585
ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2586
2587
ret_graph = (IGraphBuilder *)0xdeadbeef;
2588
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &ret_graph);
2589
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2590
ok(!ret_graph, "Got unexpected graph %p.\n", ret_graph);
2591
2592
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
2593
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2594
type = 0xdeadbeef;
2595
hr = IMediaStream_GetInformation(stream, NULL, &type);
2596
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2597
ok(type == STREAMTYPE_WRITE, "Got type %u.\n", type);
2598
IMediaStream_Release(stream);
2599
2600
ref = IAMMultiMediaStream_Release(mmstream);
2601
ok(!ref, "Got outstanding refcount %ld.\n", ref);
2602
2603
mmstream = create_ammultimediastream();
2604
2605
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_TRANSFORM, 0, NULL);
2606
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2607
2608
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_TRANSFORM, 0, NULL);
2609
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2610
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
2611
ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2612
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_WRITE, 0, NULL);
2613
ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2614
2615
ret_graph = (IGraphBuilder *)0xdeadbeef;
2616
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &ret_graph);
2617
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2618
ok(!ret_graph, "Got unexpected graph %p.\n", ret_graph);
2619
2620
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
2621
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2622
type = 0xdeadbeef;
2623
hr = IMediaStream_GetInformation(stream, NULL, &type);
2624
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2625
ok(type == STREAMTYPE_TRANSFORM, "Got type %u.\n", type);
2626
IMediaStream_Release(stream);
2627
2628
ref = IAMMultiMediaStream_Release(mmstream);
2629
ok(!ref, "Got outstanding refcount %ld.\n", ref);
2630
2631
mmstream = create_ammultimediastream();
2632
2633
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
2634
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2635
2636
type = 0xdeadbeef;
2637
hr = IMediaStream_GetInformation(stream, NULL, &type);
2638
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2639
ok(type == STREAMTYPE_READ, "Got type %u.\n", type);
2640
2641
ret_graph = NULL;
2642
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &ret_graph);
2643
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2644
ok(!!ret_graph, "Got unexpected graph %p.\n", ret_graph);
2645
IGraphBuilder_Release(ret_graph);
2646
2647
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_TRANSFORM, 0, NULL);
2648
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2649
2650
type = 0xdeadbeef;
2651
hr = IMediaStream_GetInformation(stream, NULL, &type);
2652
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2653
ok(type == STREAMTYPE_READ, "Got type %u.\n", type);
2654
2655
IMediaStream_Release(stream);
2656
ref = IAMMultiMediaStream_Release(mmstream);
2657
ok(!ref, "Got outstanding refcount %ld.\n", ref);
2658
2659
/* Test with a custom filter graph. */
2660
2661
mmstream = create_ammultimediastream();
2662
2663
graph_init(&graph);
2664
2665
ret_graph = (IGraphBuilder *)0xdeadbeef;
2666
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &ret_graph);
2667
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2668
ok(!ret_graph, "Got unexpected graph %p.\n", ret_graph);
2669
2670
hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
2671
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2672
ok(!!filter, "Expected a non-NULL filter.");
2673
2674
graph.got_add_filter = 0;
2675
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, (IGraphBuilder *)&graph.IFilterGraph2_iface);
2676
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2677
ok(graph.got_add_filter == 1, "Got %d calls to IGraphBuilder::AddFilter().\n", graph.got_add_filter);
2678
ok(graph.filter == (IBaseFilter *)filter, "Got filter %p.\n", filter);
2679
ok(!wcscmp(graph.filter_name, L"MediaStreamFilter"), "Got unexpected name %s.\n", wine_dbgstr_w(graph.filter_name));
2680
2681
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &ret_graph);
2682
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2683
ok(ret_graph == (IGraphBuilder *)&graph, "Got unexpected graph %p.\n", ret_graph);
2684
IGraphBuilder_Release(ret_graph);
2685
2686
graph.got_add_filter = 0;
2687
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, NULL);
2688
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2689
ok(!graph.got_add_filter, "Got %d calls to IGraphBuilder::AddFilter().\n", graph.got_add_filter);
2690
2691
graph.got_add_filter = 0;
2692
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, NULL);
2693
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2694
ok(!graph.got_add_filter, "Got %d calls to IGraphBuilder::AddFilter().\n", graph.got_add_filter);
2695
2696
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, (IGraphBuilder *)&graph);
2697
ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2698
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
2699
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2700
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_WRITE, 0, NULL);
2701
ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2702
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_TRANSFORM, 0, NULL);
2703
ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2704
2705
IMediaStreamFilter_Release(filter);
2706
ref = IAMMultiMediaStream_Release(mmstream);
2707
ok(!ref, "Got outstanding refcount %ld.\n", ref);
2708
2709
graph_destroy(&graph);
2710
}
2711
2712
static IAMMultiMediaStream *mmstream_mmstream;
2713
static STREAM_STATE mmstream_state;
2714
2715
static DWORD CALLBACK mmstream_set_state(void *param)
2716
{
2717
HRESULT hr;
2718
2719
hr = IAMMultiMediaStream_SetState(mmstream_mmstream, mmstream_state);
2720
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2721
2722
return 0;
2723
}
2724
2725
static void test_set_state(void)
2726
{
2727
IAMMultiMediaStream *mmstream = create_ammultimediastream();
2728
IMediaControl *media_control;
2729
struct testfilter source;
2730
IGraphBuilder *graph;
2731
STREAM_STATE state;
2732
HANDLE thread;
2733
HRESULT hr;
2734
ULONG ref;
2735
2736
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
2737
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2738
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, NULL);
2739
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2740
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
2741
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2742
ok(graph != NULL, "Expected non-NULL graph.\n");
2743
hr = IGraphBuilder_QueryInterface(graph, &IID_IMediaControl, (void **)&media_control);
2744
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2745
testfilter_init(&source);
2746
2747
hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
2748
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2749
2750
source.init_stream_hr = E_FAIL;
2751
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
2752
ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
2753
source.init_stream_hr = S_OK;
2754
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
2755
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2756
2757
source.init_stream_hr = S_FALSE;
2758
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
2759
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2760
source.init_stream_hr = S_OK;
2761
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
2762
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2763
2764
source.wait_state_hr = E_FAIL;
2765
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
2766
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2767
source.wait_state_hr = S_OK;
2768
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
2769
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2770
2771
source.wait_state_hr = VFW_S_STATE_INTERMEDIATE;
2772
ResetEvent(source.wait_state_event);
2773
2774
mmstream_mmstream = mmstream;
2775
mmstream_state = STREAMSTATE_RUN;
2776
thread = CreateThread(NULL, 0, mmstream_set_state, NULL, 0, NULL);
2777
2778
ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "SetState returned prematurely.\n");
2779
2780
EnterCriticalSection(&source.filter.filter_cs);
2781
source.wait_state_hr = S_OK;
2782
SetEvent(source.wait_state_event);
2783
LeaveCriticalSection(&source.filter.filter_cs);
2784
2785
ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
2786
CloseHandle(thread);
2787
2788
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
2789
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2790
2791
source.init_stream_hr = E_FAIL;
2792
source.wait_state_hr = VFW_S_STATE_INTERMEDIATE;
2793
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
2794
ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
2795
source.init_stream_hr = S_OK;
2796
source.wait_state_hr = S_OK;
2797
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
2798
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2799
2800
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
2801
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2802
source.cleanup_stream_hr = E_FAIL;
2803
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
2804
ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
2805
source.cleanup_stream_hr = S_OK;
2806
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
2807
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2808
2809
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
2810
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2811
source.cleanup_stream_hr = S_FALSE;
2812
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
2813
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2814
source.cleanup_stream_hr = S_OK;
2815
2816
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
2817
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2818
source.wait_state_hr = VFW_S_STATE_INTERMEDIATE;
2819
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
2820
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2821
source.wait_state_hr = S_OK;
2822
2823
/* Crashes on native. */
2824
if (0)
2825
{
2826
hr = IAMMultiMediaStream_GetState(mmstream, NULL);
2827
ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2828
}
2829
2830
state = 0xdeadbeef;
2831
hr = IAMMultiMediaStream_GetState(mmstream, &state);
2832
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2833
ok(state == STREAMSTATE_STOP, "Got state %#x.\n", state);
2834
2835
hr = IMediaControl_Run(media_control);
2836
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2837
2838
state = 0xdeadbeef;
2839
hr = IAMMultiMediaStream_GetState(mmstream, &state);
2840
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2841
ok(state == STREAMSTATE_STOP, "Got state %#x.\n", state);
2842
2843
hr = IMediaControl_Stop(media_control);
2844
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2845
2846
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
2847
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2848
2849
state = 0xdeadbeef;
2850
hr = IAMMultiMediaStream_GetState(mmstream, &state);
2851
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2852
ok(state == STREAMSTATE_RUN, "Got state %#x.\n", state);
2853
2854
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
2855
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2856
2857
state = 0xdeadbeef;
2858
hr = IAMMultiMediaStream_GetState(mmstream, &state);
2859
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2860
ok(state == STREAMSTATE_STOP, "Got state %#x.\n", state);
2861
2862
source.init_stream_hr = E_FAIL;
2863
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
2864
ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
2865
2866
state = 0xdeadbeef;
2867
hr = IAMMultiMediaStream_GetState(mmstream, &state);
2868
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2869
ok(state == STREAMSTATE_STOP, "Got state %#x.\n", state);
2870
2871
ref = IAMMultiMediaStream_Release(mmstream);
2872
ok(!ref, "Got outstanding refcount %ld.\n", ref);
2873
IMediaControl_Release(media_control);
2874
ref = IGraphBuilder_Release(graph);
2875
ok(!ref, "Got outstanding refcount %ld.\n", ref);
2876
}
2877
2878
static void test_enum_media_types(void)
2879
{
2880
IAMMultiMediaStream *mmstream = create_ammultimediastream();
2881
IEnumMediaTypes *enum1, *enum2;
2882
AM_MEDIA_TYPE *mts[2];
2883
IMediaStream *stream;
2884
ULONG ref, count;
2885
HRESULT hr;
2886
IPin *pin;
2887
2888
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
2889
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2890
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
2891
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2892
2893
hr = IPin_EnumMediaTypes(pin, &enum1);
2894
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2895
2896
hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
2897
ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2898
2899
hr = IEnumMediaTypes_Next(enum1, 0, mts, &count);
2900
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2901
ok(!count, "Got count %lu.\n", count);
2902
2903
hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
2904
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2905
ok(count == 1, "Got count %lu.\n", count);
2906
CoTaskMemFree(mts[0]);
2907
2908
hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
2909
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2910
ok(!count, "Got count %lu.\n", count);
2911
2912
hr = IEnumMediaTypes_Reset(enum1);
2913
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2914
2915
hr = IEnumMediaTypes_Next(enum1, 2, mts, &count);
2916
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2917
ok(count == 1, "Got count %lu.\n", count);
2918
CoTaskMemFree(mts[0]);
2919
2920
hr = IEnumMediaTypes_Reset(enum1);
2921
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2922
2923
hr = IEnumMediaTypes_Clone(enum1, &enum2);
2924
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2925
2926
hr = IEnumMediaTypes_Skip(enum1, 2);
2927
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2928
2929
hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
2930
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2931
ok(!count, "Got count %lu.\n", count);
2932
2933
hr = IEnumMediaTypes_Next(enum2, 1, mts, &count);
2934
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2935
ok(count == 1, "Got count %lu.\n", count);
2936
CoTaskMemFree(mts[0]);
2937
2938
IEnumMediaTypes_Release(enum2);
2939
IEnumMediaTypes_Release(enum1);
2940
IPin_Release(pin);
2941
IMediaStream_Release(stream);
2942
2943
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
2944
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2945
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
2946
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2947
2948
hr = IPin_EnumMediaTypes(pin, &enum1);
2949
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2950
2951
hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
2952
ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2953
2954
hr = IEnumMediaTypes_Next(enum1, 0, mts, &count);
2955
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2956
ok(!count, "Got count %lu.\n", count);
2957
2958
hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
2959
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2960
ok(count == 1, "Got count %lu.\n", count);
2961
CoTaskMemFree(mts[0]->pbFormat);
2962
CoTaskMemFree(mts[0]);
2963
2964
hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
2965
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2966
ok(!count, "Got count %lu.\n", count);
2967
2968
hr = IEnumMediaTypes_Reset(enum1);
2969
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2970
2971
hr = IEnumMediaTypes_Next(enum1, 2, mts, &count);
2972
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2973
ok(count == 1, "Got count %lu.\n", count);
2974
CoTaskMemFree(mts[0]->pbFormat);
2975
CoTaskMemFree(mts[0]);
2976
2977
hr = IEnumMediaTypes_Reset(enum1);
2978
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2979
2980
hr = IEnumMediaTypes_Clone(enum1, &enum2);
2981
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2982
2983
hr = IEnumMediaTypes_Skip(enum1, 2);
2984
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2985
2986
hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
2987
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2988
ok(!count, "Got count %lu.\n", count);
2989
2990
hr = IEnumMediaTypes_Next(enum2, 1, mts, &count);
2991
ok(hr == S_OK, "Got hr %#lx.\n", hr);
2992
ok(count == 1, "Got count %lu.\n", count);
2993
CoTaskMemFree(mts[0]->pbFormat);
2994
CoTaskMemFree(mts[0]);
2995
2996
IEnumMediaTypes_Release(enum2);
2997
IEnumMediaTypes_Release(enum1);
2998
IPin_Release(pin);
2999
IMediaStream_Release(stream);
3000
3001
ref = IAMMultiMediaStream_Release(mmstream);
3002
ok(!ref, "Got outstanding refcount %ld.\n", ref);
3003
}
3004
3005
static void test_media_types(void)
3006
{
3007
static const VIDEOINFOHEADER2 req_vih2;
3008
static const VIDEOINFOHEADER req_vih;
3009
static const MPEG2VIDEOINFO req_m2vi;
3010
static const MPEG1VIDEOINFO req_m1vi;
3011
static const WAVEFORMATEX req_wfx;
3012
static const WAVEFORMATEX expect_wfx =
3013
{
3014
.wFormatTag = WAVE_FORMAT_PCM,
3015
.nChannels = 1,
3016
.nSamplesPerSec = 11025,
3017
.nAvgBytesPerSec = 11025 * 2,
3018
.nBlockAlign = 2,
3019
.wBitsPerSample = 16,
3020
.cbSize = 0,
3021
};
3022
IAMMultiMediaStream *mmstream = create_ammultimediastream();
3023
IEnumMediaTypes *enummt;
3024
IMediaStream *stream;
3025
AM_MEDIA_TYPE *pmt;
3026
ULONG ref, count;
3027
unsigned int i;
3028
HRESULT hr;
3029
IPin *pin;
3030
3031
static const struct
3032
{
3033
const GUID *type;
3034
BYTE *format;
3035
ULONG size;
3036
}
3037
tests[] =
3038
{
3039
{&GUID_NULL, NULL, 0 },
3040
{&FORMAT_None, NULL, 0 },
3041
{&FORMAT_WaveFormatEx, (BYTE *)&req_wfx, sizeof(WAVEFORMATEX)},
3042
{&FORMAT_MPEG2Video, (BYTE *)&req_m2vi, sizeof(MPEG2VIDEOINFO)},
3043
{&FORMAT_MPEGVideo, (BYTE *)&req_m1vi, sizeof(MPEG2VIDEOINFO)},
3044
{&FORMAT_VideoInfo2, (BYTE *)&req_vih2, sizeof(VIDEOINFOHEADER2)},
3045
{&FORMAT_VideoInfo, (BYTE *)&req_vih, sizeof(VIDEOINFOHEADER)},
3046
};
3047
3048
static const GUID *rejected_subtypes[] =
3049
{
3050
&MEDIASUBTYPE_RGB1,
3051
&MEDIASUBTYPE_RGB4,
3052
&MEDIASUBTYPE_RGB565,
3053
&MEDIASUBTYPE_RGB555,
3054
&MEDIASUBTYPE_RGB24,
3055
&MEDIASUBTYPE_RGB32,
3056
&MEDIASUBTYPE_ARGB32,
3057
&MEDIASUBTYPE_ARGB1555,
3058
&MEDIASUBTYPE_ARGB4444,
3059
&MEDIASUBTYPE_Avi,
3060
&MEDIASUBTYPE_I420,
3061
&MEDIASUBTYPE_AYUV,
3062
&MEDIASUBTYPE_YV12,
3063
&MEDIASUBTYPE_YUY2,
3064
&MEDIASUBTYPE_UYVY,
3065
&MEDIASUBTYPE_YVYU,
3066
&MEDIASUBTYPE_NV12,
3067
&GUID_NULL,
3068
};
3069
3070
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
3071
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3072
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
3073
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3074
3075
hr = IPin_EnumMediaTypes(pin, &enummt);
3076
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3077
3078
hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL);
3079
ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3080
3081
hr = IEnumMediaTypes_Next(enummt, 1, &pmt, &count);
3082
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3083
ok(count == 1, "Got count %lu.\n", count);
3084
ok(IsEqualGUID(&pmt->majortype, &MEDIATYPE_Video), "Got major type %s\n",
3085
wine_dbgstr_guid(&pmt->majortype));
3086
ok(IsEqualGUID(&pmt->subtype, &MEDIASUBTYPE_RGB8), "Got subtype %s\n",
3087
wine_dbgstr_guid(&pmt->subtype));
3088
ok(pmt->bFixedSizeSamples == TRUE, "Got fixed size %d.\n", pmt->bFixedSizeSamples);
3089
ok(!pmt->bTemporalCompression, "Got temporal compression %d.\n", pmt->bTemporalCompression);
3090
ok(pmt->lSampleSize == 10000, "Got sample size %lu.\n", pmt->lSampleSize);
3091
ok(IsEqualGUID(&pmt->formattype, &GUID_NULL), "Got format type %s.\n",
3092
wine_dbgstr_guid(&pmt->formattype));
3093
ok(!pmt->pUnk, "Got pUnk %p.\n", pmt->pUnk);
3094
3095
for (i = 0; i < ARRAY_SIZE(tests); ++i)
3096
{
3097
pmt->formattype = *tests[i].type;
3098
pmt->cbFormat = tests[i].size;
3099
pmt->pbFormat = tests[i].format;
3100
hr = IPin_QueryAccept(pin, pmt);
3101
ok(hr == (i == 6 ? S_OK : VFW_E_TYPE_NOT_ACCEPTED), "Got hr %#lx.\n", hr);
3102
}
3103
3104
pmt->bFixedSizeSamples = FALSE;
3105
pmt->bTemporalCompression = TRUE;
3106
pmt->lSampleSize = 123;
3107
hr = IPin_QueryAccept(pin, pmt);
3108
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3109
3110
pmt->majortype = MEDIATYPE_NULL;
3111
hr = IPin_QueryAccept(pin, pmt);
3112
ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
3113
pmt->majortype = MEDIATYPE_Audio;
3114
hr = IPin_QueryAccept(pin, pmt);
3115
ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
3116
pmt->majortype = MEDIATYPE_Stream;
3117
hr = IPin_QueryAccept(pin, pmt);
3118
ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
3119
pmt->majortype = MEDIATYPE_Video;
3120
3121
for (i = 0; i < ARRAY_SIZE(rejected_subtypes); ++i)
3122
{
3123
pmt->subtype = *rejected_subtypes[i];
3124
hr = IPin_QueryAccept(pin, pmt);
3125
ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx for subtype %s.\n",
3126
hr, wine_dbgstr_guid(rejected_subtypes[i]));
3127
}
3128
3129
CoTaskMemFree(pmt);
3130
3131
hr = IEnumMediaTypes_Next(enummt, 1, &pmt, &count);
3132
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3133
3134
IEnumMediaTypes_Release(enummt);
3135
IPin_Release(pin);
3136
IMediaStream_Release(stream);
3137
3138
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
3139
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3140
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
3141
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3142
3143
hr = IPin_EnumMediaTypes(pin, &enummt);
3144
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3145
3146
hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL);
3147
ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3148
3149
hr = IEnumMediaTypes_Next(enummt, 1, &pmt, &count);
3150
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3151
ok(count == 1, "Got count %lu.\n", count);
3152
ok(IsEqualGUID(&pmt->majortype, &MEDIATYPE_Audio), "Got major type %s\n",
3153
wine_dbgstr_guid(&pmt->majortype));
3154
ok(IsEqualGUID(&pmt->subtype, &GUID_NULL), "Got subtype %s\n",
3155
wine_dbgstr_guid(&pmt->subtype));
3156
ok(pmt->bFixedSizeSamples == TRUE, "Got fixed size %d.\n", pmt->bFixedSizeSamples);
3157
ok(!pmt->bTemporalCompression, "Got temporal compression %d.\n", pmt->bTemporalCompression);
3158
ok(pmt->lSampleSize == 2, "Got sample size %lu.\n", pmt->lSampleSize);
3159
ok(IsEqualGUID(&pmt->formattype, &FORMAT_WaveFormatEx), "Got format type %s.\n",
3160
wine_dbgstr_guid(&pmt->formattype));
3161
ok(!pmt->pUnk, "Got pUnk %p.\n", pmt->pUnk);
3162
ok(pmt->cbFormat == sizeof(WAVEFORMATEX), "Got format size %lu.\n", pmt->cbFormat);
3163
ok(!memcmp(pmt->pbFormat, &expect_wfx, pmt->cbFormat), "Format blocks didn't match.\n");
3164
3165
hr = IPin_QueryAccept(pin, pmt);
3166
ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
3167
3168
CoTaskMemFree(pmt->pbFormat);
3169
CoTaskMemFree(pmt);
3170
3171
hr = IEnumMediaTypes_Next(enummt, 1, &pmt, &count);
3172
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3173
3174
IEnumMediaTypes_Release(enummt);
3175
IPin_Release(pin);
3176
IMediaStream_Release(stream);
3177
3178
ref = IAMMultiMediaStream_Release(mmstream);
3179
ok(!ref, "Got outstanding refcount %ld.\n", ref);
3180
}
3181
3182
static void test_get_end_of_stream_event_handle(void)
3183
{
3184
IAMMultiMediaStream *mmstream = create_ammultimediastream();
3185
IMediaStreamFilter *filter;
3186
struct testfilter source;
3187
IGraphBuilder *graph;
3188
IMediaStream *stream;
3189
HANDLE event;
3190
HRESULT hr;
3191
ULONG ref;
3192
IPin *pin;
3193
3194
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
3195
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3196
hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
3197
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3198
ok(!!filter, "Expected non-null filter.\n");
3199
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
3200
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3201
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
3202
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3203
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
3204
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3205
ok(!!graph, "Expected non-NULL graph.\n");
3206
testfilter_init(&source);
3207
source.IMediaSeeking_iface.lpVtbl = &testsource_seeking_vtbl;
3208
hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
3209
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3210
3211
hr = IAMMultiMediaStream_GetEndOfStreamEventHandle(mmstream, NULL);
3212
ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3213
3214
event = INVALID_HANDLE_VALUE;
3215
hr = IAMMultiMediaStream_GetEndOfStreamEventHandle(mmstream, &event);
3216
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3217
3218
hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &rgb32_mt);
3219
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3220
3221
hr = IMediaStreamFilter_SupportSeeking(filter, TRUE);
3222
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3223
3224
ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n");
3225
3226
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
3227
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3228
3229
ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n");
3230
3231
hr = IPin_EndOfStream(pin);
3232
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3233
3234
ok(WaitForSingleObject(event, 0) == 0, "Event should be signaled.\n");
3235
3236
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
3237
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3238
3239
ok(WaitForSingleObject(event, 0) == 0, "Event should be signaled.\n");
3240
3241
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
3242
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3243
3244
ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n");
3245
3246
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
3247
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3248
3249
IGraphBuilder_Disconnect(graph, pin);
3250
IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
3251
3252
ref = IAMMultiMediaStream_Release(mmstream);
3253
ok(!ref, "Got outstanding refcount %ld.\n", ref);
3254
ref = IGraphBuilder_Release(graph);
3255
ok(!ref, "Got outstanding refcount %ld.\n", ref);
3256
ref = IMediaStreamFilter_Release(filter);
3257
ok(!ref, "Got outstanding refcount %ld.\n", ref);
3258
IPin_Release(pin);
3259
ref = IMediaStream_Release(stream);
3260
ok(!ref, "Got outstanding refcount %ld.\n", ref);
3261
}
3262
3263
static IUnknown *create_audio_data(void)
3264
{
3265
IUnknown *audio_data = NULL;
3266
HRESULT result = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER,
3267
&IID_IUnknown, (void **)&audio_data);
3268
ok(S_OK == result, "got 0x%08lx\n", result);
3269
return audio_data;
3270
}
3271
3272
static void test_audiodata_query_interface(void)
3273
{
3274
IUnknown *unknown = create_audio_data();
3275
IMemoryData *memory_data = NULL;
3276
IAudioData *audio_data = NULL;
3277
3278
HRESULT result;
3279
3280
result = IUnknown_QueryInterface(unknown, &IID_IMemoryData, (void **)&memory_data);
3281
ok(E_NOINTERFACE == result, "got 0x%08lx\n", result);
3282
3283
result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data);
3284
ok(S_OK == result, "got 0x%08lx\n", result);
3285
if (S_OK == result)
3286
{
3287
result = IAudioData_QueryInterface(audio_data, &IID_IMemoryData, (void **)&memory_data);
3288
ok(E_NOINTERFACE == result, "got 0x%08lx\n", result);
3289
3290
IAudioData_Release(audio_data);
3291
}
3292
3293
IUnknown_Release(unknown);
3294
}
3295
3296
static void test_audiodata_get_info(void)
3297
{
3298
IUnknown *unknown = create_audio_data();
3299
IAudioData *audio_data = NULL;
3300
3301
HRESULT result;
3302
3303
result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data);
3304
if (FAILED(result))
3305
{
3306
/* test_audiodata_query_interface handles this case */
3307
skip("No IAudioData\n");
3308
goto out_unknown;
3309
}
3310
3311
result = IAudioData_GetInfo(audio_data, NULL, NULL, NULL);
3312
ok(MS_E_NOTINIT == result, "got 0x%08lx\n", result);
3313
3314
IAudioData_Release(audio_data);
3315
3316
out_unknown:
3317
IUnknown_Release(unknown);
3318
}
3319
3320
static void test_audiodata_set_buffer(void)
3321
{
3322
IUnknown *unknown = create_audio_data();
3323
IAudioData *audio_data = NULL;
3324
BYTE buffer[100] = {0};
3325
DWORD length = 0;
3326
BYTE *data = NULL;
3327
3328
HRESULT result;
3329
3330
result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data);
3331
if (FAILED(result))
3332
{
3333
/* test_audiodata_query_interface handles this case */
3334
skip("No IAudioData\n");
3335
goto out_unknown;
3336
}
3337
3338
result = IAudioData_SetBuffer(audio_data, 100, NULL, 0);
3339
ok(S_OK == result, "got 0x%08lx\n", result);
3340
3341
data = (BYTE *)0xdeadbeef;
3342
length = 0xdeadbeef;
3343
result = IAudioData_GetInfo(audio_data, &length, &data, NULL);
3344
ok(S_OK == result, "got 0x%08lx\n", result);
3345
ok(100 == length, "got %lu\n", length);
3346
ok(NULL != data, "got %p\n", data);
3347
3348
result = IAudioData_SetBuffer(audio_data, 0, buffer, 0);
3349
ok(E_INVALIDARG == result, "got 0x%08lx\n", result);
3350
3351
result = IAudioData_SetBuffer(audio_data, sizeof(buffer), buffer, 0);
3352
ok(S_OK == result, "got 0x%08lx\n", result);
3353
3354
data = (BYTE *)0xdeadbeef;
3355
length = 0xdeadbeef;
3356
result = IAudioData_GetInfo(audio_data, &length, &data, NULL);
3357
ok(S_OK == result, "got 0x%08lx\n", result);
3358
ok(sizeof(buffer) == length, "got %lu\n", length);
3359
ok(buffer == data, "got %p\n", data);
3360
3361
IAudioData_Release(audio_data);
3362
3363
out_unknown:
3364
IUnknown_Release(unknown);
3365
}
3366
3367
static void test_audiodata_set_actual(void)
3368
{
3369
IUnknown *unknown = create_audio_data();
3370
IAudioData *audio_data = NULL;
3371
BYTE buffer[100] = {0};
3372
DWORD actual_data = 0;
3373
3374
HRESULT result;
3375
3376
result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data);
3377
if (FAILED(result))
3378
{
3379
/* test_audiodata_query_interface handles this case */
3380
skip("No IAudioData\n");
3381
goto out_unknown;
3382
}
3383
3384
result = IAudioData_SetActual(audio_data, 0);
3385
ok(S_OK == result, "got 0x%08lx\n", result);
3386
3387
result = IAudioData_SetBuffer(audio_data, sizeof(buffer), buffer, 0);
3388
ok(S_OK == result, "got 0x%08lx\n", result);
3389
3390
result = IAudioData_SetActual(audio_data, sizeof(buffer) + 1);
3391
ok(E_INVALIDARG == result, "got 0x%08lx\n", result);
3392
3393
result = IAudioData_SetActual(audio_data, sizeof(buffer));
3394
ok(S_OK == result, "got 0x%08lx\n", result);
3395
3396
actual_data = 0xdeadbeef;
3397
result = IAudioData_GetInfo(audio_data, NULL, NULL, &actual_data);
3398
ok(S_OK == result, "got 0x%08lx\n", result);
3399
ok(sizeof(buffer) == actual_data, "got %lu\n", actual_data);
3400
3401
result = IAudioData_SetActual(audio_data, 0);
3402
ok(S_OK == result, "got 0x%08lx\n", result);
3403
3404
actual_data = 0xdeadbeef;
3405
result = IAudioData_GetInfo(audio_data, NULL, NULL, &actual_data);
3406
ok(S_OK == result, "got 0x%08lx\n", result);
3407
ok(0 == actual_data, "got %lu\n", actual_data);
3408
3409
IAudioData_Release(audio_data);
3410
3411
out_unknown:
3412
IUnknown_Release(unknown);
3413
}
3414
3415
static void test_audiodata_get_format(void)
3416
{
3417
IUnknown *unknown = create_audio_data();
3418
IAudioData *audio_data = NULL;
3419
WAVEFORMATEX wave_format = {0};
3420
3421
HRESULT result;
3422
3423
result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data);
3424
if (FAILED(result))
3425
{
3426
/* test_audiodata_query_interface handles this case */
3427
skip("No IAudioData\n");
3428
goto out_unknown;
3429
}
3430
3431
result = IAudioData_GetFormat(audio_data, NULL);
3432
ok(E_POINTER == result, "got 0x%08lx\n", result);
3433
3434
wave_format.wFormatTag = 0xdead;
3435
wave_format.nChannels = 0xdead;
3436
wave_format.nSamplesPerSec = 0xdeadbeef;
3437
wave_format.nAvgBytesPerSec = 0xdeadbeef;
3438
wave_format.nBlockAlign = 0xdead;
3439
wave_format.wBitsPerSample = 0xdead;
3440
wave_format.cbSize = 0xdead;
3441
result = IAudioData_GetFormat(audio_data, &wave_format);
3442
ok(S_OK == result, "got 0x%08lx\n", result);
3443
ok(WAVE_FORMAT_PCM == wave_format.wFormatTag, "got %u\n", wave_format.wFormatTag);
3444
ok(1 == wave_format.nChannels, "got %u\n", wave_format.nChannels);
3445
ok(11025 == wave_format.nSamplesPerSec, "got %lu\n", wave_format.nSamplesPerSec);
3446
ok(22050 == wave_format.nAvgBytesPerSec, "got %lu\n", wave_format.nAvgBytesPerSec);
3447
ok(2 == wave_format.nBlockAlign, "got %u\n", wave_format.nBlockAlign);
3448
ok(16 == wave_format.wBitsPerSample, "got %u\n", wave_format.wBitsPerSample);
3449
ok(0 == wave_format.cbSize, "got %u\n", wave_format.cbSize);
3450
3451
IAudioData_Release(audio_data);
3452
3453
out_unknown:
3454
IUnknown_Release(unknown);
3455
}
3456
3457
static void test_audiodata_set_format(void)
3458
{
3459
IUnknown *unknown = create_audio_data();
3460
IAudioData *audio_data = NULL;
3461
WAVEFORMATPCMEX wave_format = {{0}};
3462
3463
HRESULT result;
3464
3465
result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data);
3466
if (FAILED(result))
3467
{
3468
/* test_audiodata_query_interface handles this case */
3469
skip("No IAudioData\n");
3470
goto out_unknown;
3471
}
3472
3473
result = IAudioData_SetFormat(audio_data, NULL);
3474
ok(E_POINTER == result, "got 0x%08lx\n", result);
3475
3476
wave_format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
3477
wave_format.Format.nChannels = 2;
3478
wave_format.Format.nSamplesPerSec = 44100;
3479
wave_format.Format.nAvgBytesPerSec = 176400;
3480
wave_format.Format.nBlockAlign = 4;
3481
wave_format.Format.wBitsPerSample = 16;
3482
wave_format.Format.cbSize = 22;
3483
wave_format.Samples.wValidBitsPerSample = 16;
3484
wave_format.dwChannelMask = KSAUDIO_SPEAKER_STEREO;
3485
wave_format.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
3486
result = IAudioData_SetFormat(audio_data, &wave_format.Format);
3487
ok(E_INVALIDARG == result, "got 0x%08lx\n", result);
3488
3489
wave_format.Format.wFormatTag = WAVE_FORMAT_PCM;
3490
wave_format.Format.nChannels = 2;
3491
wave_format.Format.nSamplesPerSec = 44100;
3492
wave_format.Format.nAvgBytesPerSec = 176400;
3493
wave_format.Format.nBlockAlign = 4;
3494
wave_format.Format.wBitsPerSample = 16;
3495
wave_format.Format.cbSize = 0;
3496
result = IAudioData_SetFormat(audio_data, &wave_format.Format);
3497
ok(S_OK == result, "got 0x%08lx\n", result);
3498
3499
wave_format.Format.wFormatTag = 0xdead;
3500
wave_format.Format.nChannels = 0xdead;
3501
wave_format.Format.nSamplesPerSec = 0xdeadbeef;
3502
wave_format.Format.nAvgBytesPerSec = 0xdeadbeef;
3503
wave_format.Format.nBlockAlign = 0xdead;
3504
wave_format.Format.wBitsPerSample = 0xdead;
3505
wave_format.Format.cbSize = 0xdead;
3506
result = IAudioData_GetFormat(audio_data, &wave_format.Format);
3507
ok(S_OK == result, "got 0x%08lx\n", result);
3508
ok(WAVE_FORMAT_PCM == wave_format.Format.wFormatTag, "got %u\n", wave_format.Format.wFormatTag);
3509
ok(2 == wave_format.Format.nChannels, "got %u\n", wave_format.Format.nChannels);
3510
ok(44100 == wave_format.Format.nSamplesPerSec, "got %lu\n", wave_format.Format.nSamplesPerSec);
3511
ok(176400 == wave_format.Format.nAvgBytesPerSec, "got %lu\n", wave_format.Format.nAvgBytesPerSec);
3512
ok(4 == wave_format.Format.nBlockAlign, "got %u\n", wave_format.Format.nBlockAlign);
3513
ok(16 == wave_format.Format.wBitsPerSample, "got %u\n", wave_format.Format.wBitsPerSample);
3514
ok(0 == wave_format.Format.cbSize, "got %u\n", wave_format.Format.cbSize);
3515
3516
IAudioData_Release(audio_data);
3517
3518
out_unknown:
3519
IUnknown_Release(unknown);
3520
}
3521
3522
struct advise_time_cookie
3523
{
3524
LONGLONG base;
3525
LONGLONG offset;
3526
HANDLE event;
3527
HANDLE advise_time_called_event;
3528
BOOL unadvise_called;
3529
};
3530
3531
struct testclock
3532
{
3533
IReferenceClock IReferenceClock_iface;
3534
LONG refcount;
3535
LONGLONG time;
3536
struct advise_time_cookie *advise_time_cookie;
3537
HRESULT get_time_hr;
3538
};
3539
3540
static inline struct testclock *impl_from_IReferenceClock(IReferenceClock *iface)
3541
{
3542
return CONTAINING_RECORD(iface, struct testclock, IReferenceClock_iface);
3543
}
3544
3545
static HRESULT WINAPI testclock_QueryInterface(IReferenceClock *iface, REFIID iid, void **out)
3546
{
3547
if (winetest_debug > 1) trace("QueryInterface(%s)\n", wine_dbgstr_guid(iid));
3548
if (IsEqualGUID(iid, &IID_IReferenceClock)
3549
|| IsEqualGUID(iid, &IID_IUnknown))
3550
{
3551
*out = iface;
3552
IReferenceClock_AddRef(iface);
3553
return S_OK;
3554
}
3555
return E_NOINTERFACE;
3556
}
3557
3558
static ULONG WINAPI testclock_AddRef(IReferenceClock *iface)
3559
{
3560
struct testclock *clock = impl_from_IReferenceClock(iface);
3561
return InterlockedIncrement(&clock->refcount);
3562
}
3563
3564
static ULONG WINAPI testclock_Release(IReferenceClock *iface)
3565
{
3566
struct testclock *clock = impl_from_IReferenceClock(iface);
3567
return InterlockedDecrement(&clock->refcount);
3568
}
3569
3570
static HRESULT WINAPI testclock_GetTime(IReferenceClock *iface, REFERENCE_TIME *time)
3571
{
3572
struct testclock *clock = impl_from_IReferenceClock(iface);
3573
if (SUCCEEDED(clock->get_time_hr))
3574
*time = clock->time;
3575
return clock->get_time_hr;
3576
}
3577
3578
static HRESULT WINAPI testclock_AdviseTime(IReferenceClock *iface, REFERENCE_TIME base, REFERENCE_TIME offset, HEVENT event, DWORD_PTR *cookie)
3579
{
3580
struct testclock *clock = impl_from_IReferenceClock(iface);
3581
if (clock->advise_time_cookie)
3582
{
3583
clock->advise_time_cookie->base = base;
3584
clock->advise_time_cookie->offset = offset;
3585
clock->advise_time_cookie->event = (HANDLE)event;
3586
SetEvent(clock->advise_time_cookie->advise_time_called_event);
3587
}
3588
else
3589
{
3590
SetEvent((HANDLE)event);
3591
}
3592
*cookie = (DWORD_PTR)clock->advise_time_cookie;
3593
return S_OK;
3594
}
3595
3596
static HRESULT WINAPI testclock_AdvisePeriodic(IReferenceClock *iface, REFERENCE_TIME start, REFERENCE_TIME period, HSEMAPHORE semaphore, DWORD_PTR *cookie)
3597
{
3598
ok(0, "Unexpected call.\n");
3599
return E_NOTIMPL;
3600
}
3601
3602
static HRESULT WINAPI testclock_Unadvise(IReferenceClock *iface, DWORD_PTR cookie)
3603
{
3604
if (cookie)
3605
((struct advise_time_cookie *)cookie)->unadvise_called = TRUE;
3606
return S_OK;
3607
}
3608
3609
static IReferenceClockVtbl testclock_vtbl =
3610
{
3611
testclock_QueryInterface,
3612
testclock_AddRef,
3613
testclock_Release,
3614
testclock_GetTime,
3615
testclock_AdviseTime,
3616
testclock_AdvisePeriodic,
3617
testclock_Unadvise,
3618
};
3619
3620
static void testclock_init(struct testclock *clock)
3621
{
3622
memset(clock, 0, sizeof(*clock));
3623
clock->IReferenceClock_iface.lpVtbl = &testclock_vtbl;
3624
}
3625
3626
static void test_audiostream_get_format(void)
3627
{
3628
static const WAVEFORMATEX pin_format =
3629
{
3630
.wFormatTag = WAVE_FORMAT_PCM,
3631
.nChannels = 2,
3632
.nSamplesPerSec = 44100,
3633
.wBitsPerSample = 16,
3634
.nBlockAlign = 4,
3635
.nAvgBytesPerSec = 4 * 44100,
3636
};
3637
AM_MEDIA_TYPE mt =
3638
{
3639
.majortype = MEDIATYPE_Audio,
3640
.subtype = MEDIASUBTYPE_PCM,
3641
.formattype = FORMAT_WaveFormatEx,
3642
.cbFormat = sizeof(WAVEFORMATEX),
3643
.pbFormat = (BYTE *)&pin_format,
3644
};
3645
IAMMultiMediaStream *mmstream = create_ammultimediastream();
3646
IAudioMediaStream *audio_stream;
3647
struct testfilter source;
3648
IGraphBuilder *graph;
3649
IMediaStream *stream;
3650
WAVEFORMATEX format;
3651
HRESULT hr;
3652
ULONG ref;
3653
IPin *pin;
3654
3655
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
3656
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3657
hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
3658
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3659
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
3660
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3661
3662
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
3663
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3664
ok(!!graph, "Expected non-NULL graph.\n");
3665
3666
testfilter_init(&source);
3667
3668
hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, L"source");
3669
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3670
3671
hr = IAudioMediaStream_GetFormat(audio_stream, NULL);
3672
ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3673
3674
hr = IAudioMediaStream_GetFormat(audio_stream, &format);
3675
ok(hr == MS_E_NOSTREAM, "Got hr %#lx.\n", hr);
3676
3677
hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
3678
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3679
3680
memset(&format, 0xcc, sizeof(format));
3681
hr = IAudioMediaStream_GetFormat(audio_stream, &format);
3682
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3683
ok(format.wFormatTag == WAVE_FORMAT_PCM, "Got tag %#x.\n", format.wFormatTag);
3684
ok(format.nChannels == 2, "Got %u channels.\n", format.nChannels);
3685
ok(format.nSamplesPerSec == 44100, "Got sample rate %lu.\n", format.nSamplesPerSec);
3686
ok(format.nAvgBytesPerSec == 176400, "Got %lu bytes/sec.\n", format.nAvgBytesPerSec);
3687
ok(format.nBlockAlign == 4, "Got alignment %u.\n", format.nBlockAlign);
3688
ok(format.wBitsPerSample == 16, "Got %u bits/sample.\n", format.wBitsPerSample);
3689
ok(!format.cbSize, "Got extra size %u.\n", format.cbSize);
3690
3691
hr = IGraphBuilder_Disconnect(graph, pin);
3692
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3693
hr = IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
3694
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3695
3696
hr = IAudioMediaStream_GetFormat(audio_stream, &format);
3697
ok(hr == MS_E_NOSTREAM, "Got hr %#lx.\n", hr);
3698
3699
ref = IAMMultiMediaStream_Release(mmstream);
3700
ok(!ref, "Got outstanding refcount %ld.\n", ref);
3701
ref = IGraphBuilder_Release(graph);
3702
ok(!ref, "Got outstanding refcount %ld.\n", ref);
3703
IPin_Release(pin);
3704
IAudioMediaStream_Release(audio_stream);
3705
ref = IMediaStream_Release(stream);
3706
ok(!ref, "Got outstanding refcount %ld.\n", ref);
3707
ref = IBaseFilter_Release(&source.filter.IBaseFilter_iface);
3708
ok(!ref, "Got outstanding refcount %ld.\n", ref);
3709
}
3710
3711
static HRESULT set_audiostream_format(const WAVEFORMATEX *format)
3712
{
3713
IAMMultiMediaStream *mmstream = create_ammultimediastream();
3714
IAudioMediaStream *audio_stream;
3715
IMediaStream *stream;
3716
HRESULT hr;
3717
ULONG ref;
3718
3719
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
3720
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3721
hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
3722
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3723
3724
hr = IAudioMediaStream_SetFormat(audio_stream, format);
3725
3726
ref = IAMMultiMediaStream_Release(mmstream);
3727
ok(!ref, "Got outstanding refcount %ld.\n", ref);
3728
IAudioMediaStream_Release(audio_stream);
3729
ref = IMediaStream_Release(stream);
3730
ok(!ref, "Got outstanding refcount %ld.\n", ref);
3731
3732
return hr;
3733
}
3734
3735
static void test_audiostream_set_format(void)
3736
{
3737
static const WAVEFORMATEX valid_format =
3738
{
3739
.wFormatTag = WAVE_FORMAT_PCM,
3740
.nChannels = 2,
3741
.nSamplesPerSec = 44100,
3742
.wBitsPerSample = 16,
3743
.nBlockAlign = 4,
3744
.nAvgBytesPerSec = 4 * 44100,
3745
};
3746
3747
const AM_MEDIA_TYPE mt =
3748
{
3749
.majortype = MEDIATYPE_Audio,
3750
.subtype = MEDIASUBTYPE_PCM,
3751
.formattype = FORMAT_WaveFormatEx,
3752
.cbFormat = sizeof(WAVEFORMATEX),
3753
.pbFormat = (BYTE *)&valid_format,
3754
};
3755
3756
WAVEFORMATEXTENSIBLE extensible_format;
3757
IAudioMediaStream *audio_stream;
3758
IAMMultiMediaStream *mmstream;
3759
struct testfilter source;
3760
IGraphBuilder *graph;
3761
IMediaStream *stream;
3762
WAVEFORMATEX format;
3763
HRESULT hr;
3764
ULONG ref;
3765
IPin *pin;
3766
3767
hr = set_audiostream_format(&valid_format);
3768
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3769
hr = set_audiostream_format(NULL);
3770
ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3771
3772
extensible_format.Format = valid_format;
3773
extensible_format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
3774
extensible_format.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
3775
extensible_format.Samples.wValidBitsPerSample = valid_format.wBitsPerSample;
3776
extensible_format.dwChannelMask = KSAUDIO_SPEAKER_STEREO;
3777
extensible_format.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
3778
hr = set_audiostream_format(&extensible_format.Format);
3779
ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
3780
3781
format = valid_format;
3782
format.nBlockAlign = 1;
3783
hr = set_audiostream_format(&format);
3784
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3785
3786
format = valid_format;
3787
format.nAvgBytesPerSec = 1234;
3788
hr = set_audiostream_format(&format);
3789
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3790
3791
mmstream = create_ammultimediastream();
3792
3793
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
3794
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3795
hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
3796
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3797
3798
hr = IAudioMediaStream_SetFormat(audio_stream, &valid_format);
3799
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3800
3801
hr = IAudioMediaStream_GetFormat(audio_stream, &format);
3802
ok(hr == MS_E_NOSTREAM, "Got hr %#lx.\n", hr);
3803
3804
format = valid_format;
3805
format.nChannels = 1;
3806
hr = IAudioMediaStream_SetFormat(audio_stream, &format);
3807
ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
3808
3809
format = valid_format;
3810
format.nSamplesPerSec = 11025;
3811
hr = IAudioMediaStream_SetFormat(audio_stream, &format);
3812
ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
3813
3814
format = valid_format;
3815
format.nAvgBytesPerSec = 1234;
3816
hr = IAudioMediaStream_SetFormat(audio_stream, &format);
3817
ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
3818
3819
format = valid_format;
3820
format.nBlockAlign = 1;
3821
hr = IAudioMediaStream_SetFormat(audio_stream, &format);
3822
ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
3823
3824
format = valid_format;
3825
format.wBitsPerSample = 8;
3826
hr = IAudioMediaStream_SetFormat(audio_stream, &format);
3827
ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
3828
3829
format = valid_format;
3830
format.cbSize = 1;
3831
hr = IAudioMediaStream_SetFormat(audio_stream, &format);
3832
ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
3833
3834
hr = IAudioMediaStream_SetFormat(audio_stream, &valid_format);
3835
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3836
3837
ref = IAMMultiMediaStream_Release(mmstream);
3838
ok(!ref, "Got outstanding refcount %ld.\n", ref);
3839
IAudioMediaStream_Release(audio_stream);
3840
ref = IMediaStream_Release(stream);
3841
ok(!ref, "Got outstanding refcount %ld.\n", ref);
3842
3843
mmstream = create_ammultimediastream();
3844
3845
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
3846
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3847
hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
3848
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3849
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
3850
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3851
3852
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
3853
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3854
ok(!!graph, "Expected non-NULL graph.\n");
3855
3856
testfilter_init(&source);
3857
3858
hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
3859
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3860
3861
hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
3862
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3863
3864
format = valid_format;
3865
format.nChannels = 1;
3866
hr = IAudioMediaStream_SetFormat(audio_stream, &format);
3867
ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
3868
3869
hr = IGraphBuilder_Disconnect(graph, pin);
3870
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3871
hr = IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
3872
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3873
3874
format = valid_format;
3875
format.nChannels = 1;
3876
hr = IAudioMediaStream_SetFormat(audio_stream, &format);
3877
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3878
3879
ref = IAMMultiMediaStream_Release(mmstream);
3880
ok(!ref, "Got outstanding refcount %ld.\n", ref);
3881
ref = IGraphBuilder_Release(graph);
3882
ok(!ref, "Got outstanding refcount %ld.\n", ref);
3883
IPin_Release(pin);
3884
IAudioMediaStream_Release(audio_stream);
3885
ref = IMediaStream_Release(stream);
3886
ok(!ref, "Got outstanding refcount %ld.\n", ref);
3887
ref = IBaseFilter_Release(&source.filter.IBaseFilter_iface);
3888
ok(!ref, "Got outstanding refcount %ld.\n", ref);
3889
}
3890
3891
static void test_audiostream_receive_connection(void)
3892
{
3893
WAVEFORMATEXTENSIBLE extensible_format;
3894
IAudioMediaStream *audio_stream;
3895
IAMMultiMediaStream *mmstream;
3896
struct testfilter source;
3897
IGraphBuilder *graph;
3898
IMediaStream *stream;
3899
WAVEFORMATEX format;
3900
AM_MEDIA_TYPE mt;
3901
HRESULT hr;
3902
ULONG ref;
3903
IPin *pin;
3904
3905
mmstream = create_ammultimediastream();
3906
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
3907
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3908
hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
3909
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3910
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
3911
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3912
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
3913
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3914
ok(graph != NULL, "Expected non-null graph\n");
3915
testfilter_init(&source);
3916
hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
3917
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3918
3919
hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &audio_mt);
3920
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3921
IGraphBuilder_Disconnect(graph, pin);
3922
IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
3923
3924
mt = audio_mt;
3925
mt.majortype = GUID_NULL;
3926
hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt);
3927
ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
3928
3929
mt = audio_mt;
3930
mt.subtype = MEDIASUBTYPE_RGB24;
3931
hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
3932
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3933
IGraphBuilder_Disconnect(graph, pin);
3934
IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
3935
3936
mt = audio_mt;
3937
mt.formattype = GUID_NULL;
3938
hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt);
3939
ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
3940
3941
mt = audio_mt;
3942
mt.cbFormat = sizeof(WAVEFORMATEX) - 1;
3943
hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
3944
ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
3945
3946
extensible_format.Format = audio_format;
3947
extensible_format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
3948
extensible_format.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
3949
extensible_format.Samples.wValidBitsPerSample = audio_format.wBitsPerSample;
3950
extensible_format.dwChannelMask = KSAUDIO_SPEAKER_STEREO;
3951
extensible_format.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
3952
mt = audio_mt;
3953
mt.cbFormat = sizeof(extensible_format);
3954
mt.pbFormat = (BYTE *)&extensible_format;
3955
hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
3956
ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
3957
3958
hr = IAudioMediaStream_SetFormat(audio_stream, &audio_format);
3959
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3960
3961
format = audio_format;
3962
format.nChannels = 2;
3963
mt = audio_mt;
3964
mt.pbFormat = (BYTE *)&format;
3965
hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
3966
ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
3967
3968
hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &audio_mt);
3969
ok(hr == S_OK, "Got hr %#lx.\n", hr);
3970
IGraphBuilder_Disconnect(graph, pin);
3971
IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
3972
3973
ref = IAMMultiMediaStream_Release(mmstream);
3974
ok(!ref, "Got outstanding refcount %ld.\n", ref);
3975
ref = IGraphBuilder_Release(graph);
3976
ok(!ref, "Got outstanding refcount %ld.\n", ref);
3977
IPin_Release(pin);
3978
IAudioMediaStream_Release(audio_stream);
3979
ref = IMediaStream_Release(stream);
3980
ok(!ref, "Got outstanding refcount %ld.\n", ref);
3981
ref = IBaseFilter_Release(&source.filter.IBaseFilter_iface);
3982
ok(!ref, "Got outstanding refcount %ld.\n", ref);
3983
}
3984
3985
static void test_ddrawstream_receive_connection(void)
3986
{
3987
static const VIDEOINFOHEADER req_vih;
3988
IDirectDrawMediaStream *ddraw_stream;
3989
IAMMultiMediaStream *mmstream;
3990
struct testfilter source;
3991
DDSURFACEDESC format;
3992
IMediaStream *stream;
3993
VIDEOINFO video_info;
3994
AM_MEDIA_TYPE mt;
3995
HRESULT hr;
3996
ULONG ref;
3997
IPin *pin;
3998
int i;
3999
4000
static const VIDEOINFO yuy2_video_info =
4001
{
4002
.bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
4003
.bmiHeader.biWidth = 333,
4004
.bmiHeader.biHeight = -444,
4005
.bmiHeader.biPlanes = 1,
4006
.bmiHeader.biBitCount = 16,
4007
.bmiHeader.biCompression = MAKEFOURCC('Y', 'U', 'Y', '2'),
4008
};
4009
4010
const AM_MEDIA_TYPE yuy2_mt =
4011
{
4012
.majortype = MEDIATYPE_Video,
4013
.subtype = MEDIASUBTYPE_YUY2,
4014
.formattype = FORMAT_VideoInfo,
4015
.cbFormat = sizeof(VIDEOINFOHEADER),
4016
.pbFormat = (BYTE *)&yuy2_video_info,
4017
};
4018
4019
const AM_MEDIA_TYPE video_mt =
4020
{
4021
.majortype = MEDIATYPE_Video,
4022
.subtype = MEDIASUBTYPE_RGB8,
4023
.formattype = FORMAT_VideoInfo,
4024
.cbFormat = sizeof(VIDEOINFOHEADER),
4025
.pbFormat = (BYTE *)&req_vih,
4026
};
4027
4028
static const GUID *subtypes[] =
4029
{
4030
&MEDIASUBTYPE_RGB24,
4031
&MEDIASUBTYPE_RGB32,
4032
&MEDIASUBTYPE_RGB555,
4033
&MEDIASUBTYPE_RGB565,
4034
&MEDIASUBTYPE_RGB1,
4035
&MEDIASUBTYPE_RGB4,
4036
&MEDIASUBTYPE_ARGB32,
4037
&MEDIASUBTYPE_ARGB1555,
4038
&MEDIASUBTYPE_ARGB4444,
4039
&MEDIASUBTYPE_Avi,
4040
&MEDIASUBTYPE_I420,
4041
&MEDIASUBTYPE_AYUV,
4042
&MEDIASUBTYPE_YV12,
4043
&MEDIASUBTYPE_YUY2,
4044
&MEDIASUBTYPE_UYVY,
4045
&MEDIASUBTYPE_YVYU,
4046
&MEDIASUBTYPE_NV12,
4047
&GUID_NULL,
4048
};
4049
4050
mmstream = create_ammultimediastream();
4051
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
4052
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4053
hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
4054
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4055
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
4056
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4057
4058
testfilter_init(&source);
4059
4060
mt = video_mt;
4061
hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt);
4062
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4063
hr = IPin_Disconnect(pin);
4064
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4065
4066
for (i = 0; i < ARRAY_SIZE(subtypes); ++i)
4067
{
4068
mt = video_mt;
4069
mt.subtype = *subtypes[i];
4070
hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt);
4071
ok(hr == (i < 4 ? S_OK : VFW_E_TYPE_NOT_ACCEPTED), "Got hr %#lx.\n", hr);
4072
if (hr == S_OK)
4073
{
4074
hr = IPin_Disconnect(pin);
4075
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4076
}
4077
}
4078
4079
format = rgb8_format;
4080
format.dwFlags = DDSD_WIDTH;
4081
format.dwWidth = 222;
4082
format.dwHeight = 555;
4083
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &format, NULL);
4084
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4085
4086
hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb32_mt);
4087
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4088
hr = IPin_Disconnect(pin);
4089
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4090
4091
format = rgb8_format;
4092
format.dwFlags = DDSD_HEIGHT;
4093
format.dwWidth = 333;
4094
format.dwHeight = 444;
4095
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &format, NULL);
4096
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4097
4098
video_info = rgb555_video_info;
4099
video_info.bmiHeader.biWidth = 333;
4100
video_info.bmiHeader.biHeight = 444;
4101
mt = rgb555_mt;
4102
mt.pbFormat = (BYTE *)&video_info;
4103
hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt);
4104
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4105
hr = IPin_Disconnect(pin);
4106
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4107
4108
hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb32_mt);
4109
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4110
hr = IPin_Disconnect(pin);
4111
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4112
4113
video_info = rgb32_video_info;
4114
video_info.bmiHeader.biWidth = 332;
4115
video_info.bmiHeader.biHeight = 444;
4116
mt = rgb32_mt;
4117
mt.pbFormat = (BYTE *)&video_info;
4118
hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt);
4119
ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
4120
4121
video_info = rgb32_video_info;
4122
video_info.bmiHeader.biWidth = 333;
4123
video_info.bmiHeader.biHeight = 443;
4124
mt = rgb32_mt;
4125
mt.pbFormat = (BYTE *)&video_info;
4126
hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt);
4127
ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
4128
4129
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb8_format, NULL);
4130
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4131
4132
hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb555_mt);
4133
ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
4134
4135
hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb8_mt);
4136
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4137
hr = IPin_Disconnect(pin);
4138
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4139
4140
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb555_format, NULL);
4141
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4142
4143
hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb565_mt);
4144
ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
4145
4146
hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb555_mt);
4147
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4148
hr = IPin_Disconnect(pin);
4149
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4150
4151
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb565_format, NULL);
4152
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4153
4154
hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb24_mt);
4155
ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
4156
4157
hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb565_mt);
4158
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4159
hr = IPin_Disconnect(pin);
4160
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4161
4162
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb24_format, NULL);
4163
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4164
4165
hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb32_mt);
4166
ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
4167
4168
hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb24_mt);
4169
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4170
hr = IPin_Disconnect(pin);
4171
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4172
4173
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb32_format, NULL);
4174
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4175
4176
hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb8_mt);
4177
ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
4178
4179
hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb32_mt);
4180
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4181
hr = IPin_Disconnect(pin);
4182
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4183
4184
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &yuy2_format, NULL);
4185
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4186
4187
hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &yuy2_mt);
4188
ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
4189
4190
format = yuy2_format;
4191
format.ddpfPixelFormat.dwRBitMask = 0xf800;
4192
format.ddpfPixelFormat.dwGBitMask = 0x07e0;
4193
format.ddpfPixelFormat.dwBBitMask = 0x001f;
4194
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &format, NULL);
4195
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4196
4197
hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb565_mt);
4198
ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
4199
4200
format = rgb8_format;
4201
format.dwFlags = 0;
4202
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &format, NULL);
4203
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4204
4205
hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb565_mt);
4206
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4207
hr = IPin_Disconnect(pin);
4208
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4209
4210
ref = IAMMultiMediaStream_Release(mmstream);
4211
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4212
IPin_Release(pin);
4213
IDirectDrawMediaStream_Release(ddraw_stream);
4214
ref = IMediaStream_Release(stream);
4215
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4216
ref = IBaseFilter_Release(&source.filter.IBaseFilter_iface);
4217
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4218
}
4219
4220
static void test_audiostream_receive(void)
4221
{
4222
ALLOCATOR_PROPERTIES properties =
4223
{
4224
.cBuffers = 3,
4225
.cbBuffer = 16,
4226
.cbAlign = 1,
4227
};
4228
4229
IAMMultiMediaStream *mmstream = create_ammultimediastream();
4230
ALLOCATOR_PROPERTIES actual;
4231
struct testfilter source;
4232
IMemAllocator *allocator;
4233
IGraphBuilder *graph;
4234
IMediaStream *stream;
4235
IMediaSample *sample1;
4236
IMediaSample *sample2;
4237
IMediaSample *sample3;
4238
HRESULT hr;
4239
ULONG ref;
4240
IPin *pin;
4241
4242
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
4243
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4244
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
4245
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4246
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
4247
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4248
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
4249
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4250
ok(graph != NULL, "Expected non-NULL graph.\n");
4251
testfilter_init(&source);
4252
hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
4253
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4254
hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER, &IID_IMemAllocator, (void **)&allocator);
4255
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4256
hr = IMemAllocator_SetProperties(allocator, &properties, &actual);
4257
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4258
hr = IMemAllocator_Commit(allocator);
4259
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4260
4261
hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &audio_mt);
4262
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4263
4264
hr = IMemAllocator_GetBuffer(allocator, &sample1, NULL, NULL, 0);
4265
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4266
hr = IMemInputPin_Receive(source.source.pMemInputPin, sample1);
4267
ok(hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr);
4268
ref = IMediaSample_Release(sample1);
4269
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4270
4271
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
4272
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4273
4274
hr = IMemAllocator_GetBuffer(allocator, &sample1, NULL, NULL, 0);
4275
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4276
hr = IMemInputPin_Receive(source.source.pMemInputPin, sample1);
4277
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4278
ref = get_refcount(sample1);
4279
ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
4280
4281
hr = IMemAllocator_GetBuffer(allocator, &sample2, NULL, NULL, 0);
4282
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4283
hr = IMemInputPin_Receive(source.source.pMemInputPin, sample2);
4284
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4285
ref = get_refcount(sample2);
4286
ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
4287
4288
hr = IPin_EndOfStream(pin);
4289
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4290
4291
hr = IMemAllocator_GetBuffer(allocator, &sample3, NULL, NULL, 0);
4292
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4293
hr = IMemInputPin_Receive(source.source.pMemInputPin, sample3);
4294
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4295
ref = get_refcount(sample3);
4296
ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
4297
4298
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
4299
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4300
4301
ref = IMediaSample_Release(sample1);
4302
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4303
ref = IMediaSample_Release(sample2);
4304
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4305
ref = IMediaSample_Release(sample3);
4306
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4307
4308
hr = IMemAllocator_GetBuffer(allocator, &sample1, NULL, NULL, 0);
4309
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4310
hr = IMemInputPin_Receive(source.source.pMemInputPin, sample1);
4311
ok(hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr);
4312
ref = IMediaSample_Release(sample1);
4313
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4314
4315
IGraphBuilder_Disconnect(graph, pin);
4316
IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
4317
4318
hr = IMemAllocator_Decommit(allocator);
4319
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4320
4321
ref = IAMMultiMediaStream_Release(mmstream);
4322
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4323
ref = IGraphBuilder_Release(graph);
4324
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4325
IPin_Release(pin);
4326
ref = IMediaStream_Release(stream);
4327
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4328
ref = IMemAllocator_Release(allocator);
4329
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4330
}
4331
4332
static void test_audiostream_initialize(void)
4333
{
4334
IAMMediaStream *stream;
4335
STREAM_TYPE type;
4336
MSPID mspid;
4337
HRESULT hr;
4338
ULONG ref;
4339
4340
hr = CoCreateInstance(&CLSID_AMAudioStream, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream);
4341
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4342
4343
/* Crashes on native. */
4344
if (0)
4345
{
4346
hr = IAMMediaStream_Initialize(stream, NULL, 0, NULL, STREAMTYPE_WRITE);
4347
ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
4348
}
4349
4350
hr = IAMMediaStream_Initialize(stream, NULL, 0, &test_mspid, STREAMTYPE_WRITE);
4351
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4352
4353
hr = IAMMediaStream_GetInformation(stream, &mspid, &type);
4354
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4355
ok(IsEqualGUID(&mspid, &test_mspid), "Got mspid %s.\n", wine_dbgstr_guid(&mspid));
4356
ok(type == STREAMTYPE_WRITE, "Got type %u.\n", type);
4357
4358
hr = IAMMediaStream_Initialize(stream, NULL, 0, &MSPID_PrimaryAudio, STREAMTYPE_READ);
4359
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4360
4361
hr = IAMMediaStream_GetInformation(stream, &mspid, &type);
4362
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4363
ok(IsEqualGUID(&mspid, &MSPID_PrimaryAudio), "Got mspid %s.\n", wine_dbgstr_guid(&mspid));
4364
ok(type == STREAMTYPE_READ, "Got type %u.\n", type);
4365
4366
ref = IAMMediaStream_Release(stream);
4367
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4368
}
4369
4370
static void test_audiostream_begin_flush_end_flush(void)
4371
{
4372
IAMMultiMediaStream *mmstream = create_ammultimediastream();
4373
static const MSPID mspid = {0x88888888, 1};
4374
IAudioStreamSample *stream_sample;
4375
IAudioMediaStream *audio_stream;
4376
IMediaStreamFilter *filter;
4377
IMediaSample *media_sample;
4378
struct testfilter source2;
4379
struct testfilter source;
4380
IAMMediaStream *stream2;
4381
IAudioData *audio_data;
4382
IMediaStream *stream;
4383
struct graph graph;
4384
HRESULT hr;
4385
IPin *pin2;
4386
ULONG ref;
4387
IPin *pin;
4388
4389
graph_init(&graph);
4390
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, (IGraphBuilder *)&graph.IFilterGraph2_iface);
4391
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4392
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
4393
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4394
hr = CoCreateInstance(&CLSID_AMAudioStream, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream2);
4395
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4396
hr = IAMMediaStream_Initialize(stream2, NULL, 0, &mspid, STREAMTYPE_READ);
4397
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4398
hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)stream2, &mspid, 0, NULL);
4399
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4400
hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
4401
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4402
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
4403
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4404
hr = IAMMediaStream_QueryInterface(stream2, &IID_IPin, (void **)&pin2);
4405
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4406
hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
4407
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4408
testfilter_init(&source);
4409
testfilter_init(&source2);
4410
source.IMediaSeeking_iface.lpVtbl = &testsource_seeking_vtbl;
4411
hr = IFilterGraph2_AddFilter(&graph.IFilterGraph2_iface, &source.filter.IBaseFilter_iface, NULL);
4412
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4413
hr = IFilterGraph2_AddFilter(&graph.IFilterGraph2_iface, &source2.filter.IBaseFilter_iface, NULL);
4414
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4415
hr = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, &IID_IAudioData, (void **)&audio_data);
4416
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4417
hr = IAudioData_SetBuffer(audio_data, 16, NULL, 0);
4418
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4419
hr = IAudioMediaStream_CreateSample(audio_stream, audio_data, 0, &stream_sample);
4420
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4421
4422
hr = IFilterGraph2_ConnectDirect(&graph.IFilterGraph2_iface, &source.source.pin.IPin_iface, pin, &audio_mt);
4423
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4424
hr = IFilterGraph2_ConnectDirect(&graph.IFilterGraph2_iface, &source2.source.pin.IPin_iface, pin2, &audio_mt);
4425
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4426
4427
hr = IMediaStreamFilter_SupportSeeking(filter, TRUE);
4428
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4429
4430
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
4431
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4432
4433
hr = IMemAllocator_GetBuffer(source.source.pAllocator, &media_sample, NULL, NULL, 0);
4434
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4435
hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
4436
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4437
ref = get_refcount(media_sample);
4438
ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
4439
4440
hr = IPin_EndOfStream(pin);
4441
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4442
4443
hr = IPin_BeginFlush(pin);
4444
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4445
4446
ref = IMediaSample_Release(media_sample);
4447
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4448
4449
hr = IMemAllocator_GetBuffer(source.source.pAllocator, &media_sample, NULL, NULL, 0);
4450
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4451
hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
4452
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
4453
4454
ref = IMediaSample_Release(media_sample);
4455
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4456
4457
hr = IAudioStreamSample_Update(stream_sample, SSUPDATE_ASYNC, NULL, NULL, 0);
4458
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
4459
4460
hr = IPin_EndOfStream(pin);
4461
ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
4462
4463
hr = IPin_EndFlush(pin);
4464
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4465
4466
hr = IMemAllocator_GetBuffer(source.source.pAllocator, &media_sample, NULL, NULL, 0);
4467
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4468
hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
4469
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4470
ref = IMediaSample_Release(media_sample);
4471
ok(ref == 1, "Got outstanding refcount %ld.\n", ref);
4472
4473
hr = IPin_EndOfStream(pin);
4474
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4475
4476
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
4477
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4478
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
4479
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4480
4481
hr = IPin_BeginFlush(pin);
4482
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4483
hr = IPin_EndFlush(pin);
4484
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4485
4486
hr = IPin_EndOfStream(pin);
4487
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4488
4489
graph.got_notify = 0;
4490
4491
hr = IPin_EndOfStream(pin2);
4492
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4493
4494
ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
4495
ok(graph.event_code == EC_COMPLETE, "Got event code %ld.\n", graph.event_code);
4496
4497
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
4498
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4499
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
4500
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4501
4502
hr = IPin_EndOfStream(pin);
4503
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4504
4505
hr = IPin_BeginFlush(pin);
4506
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4507
hr = IPin_EndFlush(pin);
4508
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4509
4510
graph.got_notify = 0;
4511
graph.event_code = 0xcc;
4512
4513
hr = IPin_EndOfStream(pin2);
4514
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4515
4516
ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
4517
4518
hr = IPin_EndOfStream(pin);
4519
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4520
4521
ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
4522
ok(graph.event_code == EC_COMPLETE, "Got event code %ld.\n", graph.event_code);
4523
4524
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
4525
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4526
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
4527
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4528
4529
hr = IPin_EndOfStream(pin);
4530
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4531
4532
hr = IPin_BeginFlush(pin);
4533
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4534
hr = IPin_EndFlush(pin);
4535
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4536
hr = IPin_BeginFlush(pin);
4537
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4538
hr = IPin_EndFlush(pin);
4539
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4540
4541
hr = IPin_EndOfStream(pin);
4542
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4543
4544
graph.got_notify = 0;
4545
graph.event_code = 0xcc;
4546
4547
hr = IPin_EndOfStream(pin2);
4548
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4549
4550
ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
4551
ok(graph.event_code == EC_COMPLETE, "Got event code %ld.\n", graph.event_code);
4552
4553
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
4554
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4555
4556
IFilterGraph2_Disconnect(&graph.IFilterGraph2_iface, pin);
4557
IFilterGraph2_Disconnect(&graph.IFilterGraph2_iface, &source.source.pin.IPin_iface);
4558
IFilterGraph2_Disconnect(&graph.IFilterGraph2_iface, pin2);
4559
IFilterGraph2_Disconnect(&graph.IFilterGraph2_iface, &source2.source.pin.IPin_iface);
4560
4561
ref = IAudioStreamSample_Release(stream_sample);
4562
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4563
ref = IAudioData_Release(audio_data);
4564
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4565
ref = IAMMultiMediaStream_Release(mmstream);
4566
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4567
graph_destroy(&graph);
4568
ref = IMediaStreamFilter_Release(filter);
4569
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4570
IPin_Release(pin);
4571
IAudioMediaStream_Release(audio_stream);
4572
ref = IMediaStream_Release(stream);
4573
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4574
IPin_Release(pin2);
4575
ref = IAMMediaStream_Release(stream2);
4576
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4577
}
4578
4579
static IMediaSample *ammediastream_allocate_sample(struct testfilter *source, const BYTE *input_data, DWORD input_length)
4580
{
4581
IMediaSample *sample;
4582
BYTE *sample_data;
4583
HRESULT hr;
4584
4585
hr = IMemAllocator_GetBuffer(source->source.pAllocator, &sample, NULL, NULL, 0);
4586
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4587
4588
hr = IMediaSample_GetPointer(sample, &sample_data);
4589
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4590
4591
hr = IMediaSample_SetActualDataLength(sample, input_length);
4592
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4593
4594
memcpy(sample_data, input_data, input_length);
4595
4596
return sample;
4597
}
4598
4599
static void test_audiostream_new_segment(void)
4600
{
4601
IAMMultiMediaStream *mmstream = create_ammultimediastream();
4602
static const BYTE test_data[8] = { 0 };
4603
IAudioStreamSample *stream_sample;
4604
IAudioMediaStream *audio_stream;
4605
IMemInputPin *mem_input_pin;
4606
IMediaSample *media_sample;
4607
struct testfilter source;
4608
IAudioData *audio_data;
4609
STREAM_TIME start_time;
4610
STREAM_TIME end_time;
4611
IGraphBuilder *graph;
4612
IMediaStream *stream;
4613
HRESULT hr;
4614
ULONG ref;
4615
IPin *pin;
4616
4617
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
4618
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4619
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
4620
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4621
hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
4622
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4623
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
4624
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4625
hr = IMediaStream_QueryInterface(stream, &IID_IMemInputPin, (void **)&mem_input_pin);
4626
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4627
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
4628
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4629
ok(graph != NULL, "Expected non-NULL graph.\n");
4630
testfilter_init(&source);
4631
hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
4632
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4633
hr = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, &IID_IAudioData, (void **)&audio_data);
4634
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4635
hr = IAudioMediaStream_CreateSample(audio_stream, audio_data, 0, &stream_sample);
4636
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4637
hr = IAudioData_SetBuffer(audio_data, 5, NULL, 0);
4638
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4639
4640
hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &audio_mt);
4641
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4642
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
4643
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4644
4645
hr = IPin_NewSegment(pin, 11111111, 22222222, 1.0);
4646
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4647
4648
media_sample = ammediastream_allocate_sample(&source, test_data, 5);
4649
start_time = 12345678;
4650
end_time = 23456789;
4651
hr = IMediaSample_SetTime(media_sample, &start_time, &end_time);
4652
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4653
hr = IMemInputPin_Receive(mem_input_pin, media_sample);
4654
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4655
IMediaSample_Release(media_sample);
4656
4657
hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4658
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4659
4660
start_time = 0xdeadbeefdeadbeef;
4661
end_time = 0xdeadbeefdeadbeef;
4662
hr = IAudioStreamSample_GetSampleTimes(stream_sample, &start_time, &end_time, NULL);
4663
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4664
ok(start_time == 23456789, "Got start time %s.\n", wine_dbgstr_longlong(start_time));
4665
ok(end_time == 23459057, "Got end time %s.\n", wine_dbgstr_longlong(end_time));
4666
4667
hr = IPin_NewSegment(pin, 11111111, 22222222, 2.0);
4668
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4669
4670
media_sample = ammediastream_allocate_sample(&source, test_data, 5);
4671
start_time = 12345678;
4672
end_time = 23456789;
4673
hr = IMediaSample_SetTime(media_sample, &start_time, &end_time);
4674
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4675
hr = IMemInputPin_Receive(mem_input_pin, media_sample);
4676
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4677
IMediaSample_Release(media_sample);
4678
4679
hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4680
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4681
4682
start_time = 0xdeadbeefdeadbeef;
4683
end_time = 0xdeadbeefdeadbeef;
4684
hr = IAudioStreamSample_GetSampleTimes(stream_sample, &start_time, &end_time, NULL);
4685
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4686
ok(start_time == 23456789, "Got start time %s.\n", wine_dbgstr_longlong(start_time));
4687
ok(end_time == 23459057, "Got end time %s.\n", wine_dbgstr_longlong(end_time));
4688
4689
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
4690
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4691
IGraphBuilder_Disconnect(graph, pin);
4692
IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
4693
4694
ref = IAudioStreamSample_Release(stream_sample);
4695
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4696
ref = IAudioData_Release(audio_data);
4697
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4698
ref = IAMMultiMediaStream_Release(mmstream);
4699
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4700
ref = IGraphBuilder_Release(graph);
4701
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4702
IPin_Release(pin);
4703
IMemInputPin_Release(mem_input_pin);
4704
IAudioMediaStream_Release(audio_stream);
4705
ref = IMediaStream_Release(stream);
4706
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4707
}
4708
4709
static void CALLBACK apc_func(ULONG_PTR param)
4710
{
4711
}
4712
4713
static IPin *ammediastream_pin;
4714
static IMemInputPin *ammediastream_mem_input_pin;
4715
static IMediaSample *ammediastream_media_sample;
4716
static DWORD ammediastream_sleep_time;
4717
static HRESULT ammediastream_expected_hr;
4718
4719
static DWORD CALLBACK ammediastream_end_of_stream(void *param)
4720
{
4721
HRESULT hr;
4722
4723
Sleep(ammediastream_sleep_time);
4724
hr = IPin_EndOfStream(ammediastream_pin);
4725
ok(hr == ammediastream_expected_hr, "Got hr %#lx.\n", hr);
4726
4727
return 0;
4728
}
4729
4730
static DWORD CALLBACK ammediastream_receive(void *param)
4731
{
4732
HRESULT hr;
4733
4734
Sleep(ammediastream_sleep_time);
4735
hr = IMemInputPin_Receive(ammediastream_mem_input_pin, ammediastream_media_sample);
4736
ok(hr == ammediastream_expected_hr, "Got hr %#lx.\n", hr);
4737
4738
return 0;
4739
}
4740
4741
struct ammediastream_receive_release_param
4742
{
4743
IMemInputPin *mem_input_pin;
4744
IMediaSample *media_sample;
4745
};
4746
4747
static DWORD CALLBACK ammediastream_receive_release(void *p)
4748
{
4749
struct ammediastream_receive_release_param *param = (struct ammediastream_receive_release_param *)p;
4750
HRESULT hr;
4751
ULONG ref;
4752
4753
hr = IMemInputPin_Receive(param->mem_input_pin, param->media_sample);
4754
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4755
4756
ref = IMediaSample_Release(param->media_sample);
4757
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4758
4759
free(p);
4760
4761
return 0;
4762
}
4763
4764
static HANDLE ammediastream_async_receive_time(struct testfilter *source,
4765
REFERENCE_TIME start_time, REFERENCE_TIME end_time, const BYTE *input_data, DWORD input_length)
4766
{
4767
struct ammediastream_receive_release_param *param;
4768
IMediaSample *sample;
4769
HRESULT hr;
4770
4771
sample = ammediastream_allocate_sample(source, input_data, input_length);
4772
hr = IMediaSample_SetTime(sample, &start_time, &end_time);
4773
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4774
4775
param = calloc(1, sizeof(*param));
4776
param->mem_input_pin = source->source.pMemInputPin;
4777
param->media_sample = sample;
4778
return CreateThread(NULL, 0, ammediastream_receive_release, param, 0, NULL);
4779
}
4780
4781
static IStreamSample *streamsample_sample;
4782
static DWORD streamsample_flags;
4783
static DWORD streamsample_timeout;
4784
static HRESULT streamsample_expected_hr;
4785
4786
static DWORD CALLBACK streamsample_completion_status(void *param)
4787
{
4788
HRESULT hr;
4789
4790
hr = IStreamSample_CompletionStatus(streamsample_sample, streamsample_flags, streamsample_timeout);
4791
ok(hr == streamsample_expected_hr, "Got hr %#lx.\n", hr);
4792
4793
return 0;
4794
}
4795
4796
static void test_audiostreamsample_update(void)
4797
{
4798
static const BYTE test_data[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
4799
IAMMultiMediaStream *mmstream = create_ammultimediastream();
4800
IAudioStreamSample *stream_sample;
4801
IAudioMediaStream *audio_stream;
4802
IMediaControl *media_control;
4803
IMemInputPin *mem_input_pin;
4804
IMediaSample *media_sample1;
4805
IMediaSample *media_sample2;
4806
struct testfilter source;
4807
IAudioData *audio_data;
4808
IGraphBuilder *graph;
4809
IMediaStream *stream;
4810
DWORD actual_length;
4811
BYTE buffer[6];
4812
HANDLE thread;
4813
HANDLE event;
4814
HRESULT hr;
4815
ULONG ref;
4816
IPin *pin;
4817
4818
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
4819
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4820
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
4821
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4822
hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
4823
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4824
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
4825
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4826
hr = IMediaStream_QueryInterface(stream, &IID_IMemInputPin, (void **)&mem_input_pin);
4827
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4828
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
4829
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4830
ok(graph != NULL, "Expected non-NULL graph.\n");
4831
hr = IGraphBuilder_QueryInterface(graph, &IID_IMediaControl, (void **)&media_control);
4832
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4833
testfilter_init(&source);
4834
hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
4835
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4836
hr = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, &IID_IAudioData, (void **)&audio_data);
4837
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4838
hr = IAudioMediaStream_CreateSample(audio_stream, audio_data, 0, &stream_sample);
4839
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4840
event = CreateEventW(NULL, FALSE, FALSE, NULL);
4841
ok(event != NULL, "Expected non-NULL event.");
4842
4843
hr = IAudioStreamSample_Update(stream_sample, 0, event, apc_func, 0);
4844
ok(hr == MS_E_NOTINIT, "Got hr %#lx.\n", hr);
4845
4846
hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4847
ok(hr == MS_E_NOTINIT, "Got hr %#lx.\n", hr);
4848
4849
hr = IAudioData_SetBuffer(audio_data, sizeof(buffer), buffer, 0);
4850
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4851
4852
hr = IAudioStreamSample_Update(stream_sample, 0, event, apc_func, 0);
4853
ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
4854
4855
hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4856
ok(hr == MS_E_NOTRUNNING, "Got hr %#lx.\n", hr);
4857
4858
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
4859
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4860
4861
hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4862
ok(hr == MS_S_ENDOFSTREAM, "Got hr %#lx.\n", hr);
4863
4864
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
4865
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4866
hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &audio_mt);
4867
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4868
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
4869
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4870
4871
media_sample1 = ammediastream_allocate_sample(&source, test_data, 8);
4872
hr = IMemInputPin_Receive(mem_input_pin, media_sample1);
4873
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4874
ref = get_refcount(media_sample1);
4875
ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
4876
4877
hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4878
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4879
4880
hr = IAudioData_GetInfo(audio_data, NULL, NULL, &actual_length);
4881
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4882
ok(actual_length == 6, "Got actual length %lu.\n", actual_length);
4883
4884
ok(memcmp(buffer, test_data, 6) == 0, "Sample data didn't match.\n");
4885
4886
ref = get_refcount(media_sample1);
4887
ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
4888
4889
media_sample2 = ammediastream_allocate_sample(&source, test_data, 8);
4890
hr = IMemInputPin_Receive(mem_input_pin, media_sample2);
4891
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4892
ref = get_refcount(media_sample2);
4893
ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
4894
4895
hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4896
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4897
4898
hr = IAudioData_GetInfo(audio_data, NULL, NULL, &actual_length);
4899
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4900
ok(actual_length == 6, "Got actual length %lu.\n", actual_length);
4901
4902
ok(memcmp(buffer, &test_data[6], 2) == 0, "Sample data didn't match.\n");
4903
ok(memcmp(&buffer[2], test_data, 4) == 0, "Sample data didn't match.\n");
4904
4905
ref = IMediaSample_Release(media_sample1);
4906
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4907
4908
hr = IPin_EndOfStream(pin);
4909
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4910
4911
hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4912
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4913
4914
hr = IAudioData_GetInfo(audio_data, NULL, NULL, &actual_length);
4915
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4916
ok(actual_length == 4, "Got actual length %lu.\n", actual_length);
4917
4918
ok(memcmp(buffer, &test_data[4], 4) == 0, "Sample data didn't match.\n");
4919
4920
ref = IMediaSample_Release(media_sample2);
4921
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4922
4923
hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4924
ok(hr == MS_S_ENDOFSTREAM, "Got hr %#lx.\n", hr);
4925
4926
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
4927
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4928
hr = IMediaControl_Pause(media_control);
4929
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4930
4931
media_sample1 = ammediastream_allocate_sample(&source, test_data, 6);
4932
hr = IMemInputPin_Receive(mem_input_pin, media_sample1);
4933
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4934
ref = IMediaSample_Release(media_sample1);
4935
ok(ref == 1, "Got outstanding refcount %ld.\n", ref);
4936
4937
hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4938
ok(hr == MS_E_NOTRUNNING, "Got hr %#lx.\n", hr);
4939
4940
hr = IMediaControl_Stop(media_control);
4941
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4942
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
4943
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4944
4945
media_sample1 = ammediastream_allocate_sample(&source, test_data, 6);
4946
4947
ammediastream_mem_input_pin = mem_input_pin;
4948
ammediastream_media_sample = media_sample1;
4949
ammediastream_sleep_time = 100;
4950
ammediastream_expected_hr = S_OK;
4951
thread = CreateThread(NULL, 0, ammediastream_receive, NULL, 0, NULL);
4952
4953
hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4954
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4955
4956
hr = IAudioData_GetInfo(audio_data, NULL, NULL, &actual_length);
4957
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4958
ok(actual_length == 6, "Got actual length %lu.\n", actual_length);
4959
4960
ok(memcmp(buffer, test_data, 6) == 0, "Sample data didn't match.\n");
4961
4962
ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
4963
CloseHandle(thread);
4964
4965
ref = IMediaSample_Release(media_sample1);
4966
ok(!ref, "Got outstanding refcount %ld.\n", ref);
4967
4968
ammediastream_pin = pin;
4969
ammediastream_sleep_time = 100;
4970
ammediastream_expected_hr = S_OK;
4971
thread = CreateThread(NULL, 0, ammediastream_end_of_stream, NULL, 0, NULL);
4972
4973
hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4974
ok(hr == MS_S_ENDOFSTREAM, "Got hr %#lx.\n", hr);
4975
4976
ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
4977
CloseHandle(thread);
4978
4979
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
4980
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4981
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
4982
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4983
4984
hr = IAudioStreamSample_Update(stream_sample, SSUPDATE_ASYNC, NULL, NULL, 0);
4985
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
4986
4987
IAudioStreamSample_AddRef(stream_sample);
4988
ref = IAudioStreamSample_Release(stream_sample);
4989
ok(ref == 1, "Got outstanding refcount %ld.\n", ref);
4990
4991
hr = IAudioStreamSample_Update(stream_sample, SSUPDATE_ASYNC, NULL, NULL, 0);
4992
ok(hr == MS_E_BUSY, "Got hr %#lx.\n", hr);
4993
4994
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
4995
ok(hr == S_OK, "Got hr %#lx.\n", hr);
4996
IGraphBuilder_Disconnect(graph, pin);
4997
IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
4998
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
4999
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5000
5001
hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
5002
ok(hr == MS_S_ENDOFSTREAM, "Got hr %#lx.\n", hr);
5003
5004
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
5005
5006
CloseHandle(event);
5007
ref = IAudioStreamSample_Release(stream_sample);
5008
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5009
ref = IAudioData_Release(audio_data);
5010
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5011
ref = IAMMultiMediaStream_Release(mmstream);
5012
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5013
IMediaControl_Release(media_control);
5014
ref = IGraphBuilder_Release(graph);
5015
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5016
IPin_Release(pin);
5017
IMemInputPin_Release(mem_input_pin);
5018
IAudioMediaStream_Release(audio_stream);
5019
ref = IMediaStream_Release(stream);
5020
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5021
}
5022
5023
void test_audiostreamsample_completion_status(void)
5024
{
5025
static const BYTE test_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
5026
IAMMultiMediaStream *mmstream = create_ammultimediastream();
5027
IAudioStreamSample *stream_sample1;
5028
IAudioStreamSample *stream_sample2;
5029
IAudioMediaStream *audio_stream;
5030
IMediaSample *media_sample;
5031
struct testfilter source;
5032
IAudioData *audio_data1;
5033
IAudioData *audio_data2;
5034
IGraphBuilder *graph;
5035
IMediaStream *stream;
5036
HANDLE event;
5037
HRESULT hr;
5038
ULONG ref;
5039
IPin *pin;
5040
5041
event = CreateEventW(NULL, FALSE, FALSE, NULL);
5042
ok(event != NULL, "Expected non-NULL event.");
5043
5044
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
5045
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5046
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
5047
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5048
hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
5049
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5050
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
5051
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5052
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
5053
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5054
ok(graph != NULL, "Expected non-NULL graph.\n");
5055
testfilter_init(&source);
5056
hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
5057
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5058
hr = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, &IID_IAudioData, (void **)&audio_data1);
5059
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5060
hr = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, &IID_IAudioData, (void **)&audio_data2);
5061
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5062
hr = IAudioData_SetBuffer(audio_data1, 6, NULL, 0);
5063
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5064
hr = IAudioData_SetBuffer(audio_data2, 6, NULL, 0);
5065
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5066
hr = IAudioMediaStream_CreateSample(audio_stream, audio_data1, 0, &stream_sample1);
5067
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5068
hr = IAudioMediaStream_CreateSample(audio_stream, audio_data2, 0, &stream_sample2);
5069
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5070
5071
hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &audio_mt);
5072
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5073
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
5074
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5075
5076
hr = IAudioStreamSample_CompletionStatus(stream_sample1, 0, 0);
5077
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5078
5079
hr = IAudioStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
5080
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
5081
5082
hr = IAudioStreamSample_CompletionStatus(stream_sample1, 0, 0);
5083
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
5084
5085
media_sample = ammediastream_allocate_sample(&source, test_data, 6);
5086
hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
5087
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5088
ref = IMediaSample_Release(media_sample);
5089
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5090
5091
hr = IAudioStreamSample_CompletionStatus(stream_sample1, 0, 0);
5092
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5093
5094
hr = IAudioStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
5095
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
5096
5097
hr = IAudioStreamSample_Update(stream_sample2, SSUPDATE_ASYNC, NULL, NULL, 0);
5098
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
5099
5100
media_sample = ammediastream_allocate_sample(&source, test_data, 12);
5101
hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
5102
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5103
ref = IMediaSample_Release(media_sample);
5104
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5105
5106
hr = IAudioStreamSample_CompletionStatus(stream_sample1, 0, 0);
5107
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5108
5109
hr = IAudioStreamSample_CompletionStatus(stream_sample2, 0, 0);
5110
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5111
5112
hr = IAudioStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
5113
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
5114
5115
hr = IPin_EndOfStream(pin);
5116
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5117
5118
hr = IAudioStreamSample_CompletionStatus(stream_sample1, 0, 0);
5119
ok(hr == MS_S_ENDOFSTREAM, "Got hr %#lx.\n", hr);
5120
5121
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
5122
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5123
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
5124
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5125
5126
hr = IAudioStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
5127
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
5128
5129
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
5130
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5131
5132
hr = IAudioStreamSample_CompletionStatus(stream_sample1, 0, 0);
5133
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
5134
5135
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
5136
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5137
5138
media_sample = ammediastream_allocate_sample(&source, test_data, 6);
5139
hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
5140
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5141
ref = IMediaSample_Release(media_sample);
5142
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5143
5144
hr = IAudioStreamSample_CompletionStatus(stream_sample1, 0, 0);
5145
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5146
5147
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
5148
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5149
5150
IGraphBuilder_Disconnect(graph, pin);
5151
IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
5152
5153
ref = IAudioStreamSample_Release(stream_sample1);
5154
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5155
ref = IAudioStreamSample_Release(stream_sample2);
5156
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5157
ref = IAudioData_Release(audio_data1);
5158
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5159
ref = IAudioData_Release(audio_data2);
5160
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5161
ref = IAMMultiMediaStream_Release(mmstream);
5162
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5163
ref = IGraphBuilder_Release(graph);
5164
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5165
IPin_Release(pin);
5166
IAudioMediaStream_Release(audio_stream);
5167
ref = IMediaStream_Release(stream);
5168
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5169
5170
CloseHandle(event);
5171
}
5172
5173
static void test_audiostreamsample_get_sample_times(void)
5174
{
5175
IAMMultiMediaStream *mmstream = create_ammultimediastream();
5176
static const BYTE test_data[8] = { 0 };
5177
IAudioStreamSample *stream_sample;
5178
IMediaFilter *graph_media_filter;
5179
IAudioMediaStream *audio_stream;
5180
STREAM_TIME filter_start_time;
5181
IMemInputPin *mem_input_pin;
5182
IMediaStreamFilter *filter;
5183
IMediaSample *media_sample;
5184
struct testfilter source;
5185
STREAM_TIME current_time;
5186
struct testclock clock;
5187
IAudioData *audio_data;
5188
STREAM_TIME start_time;
5189
STREAM_TIME end_time;
5190
IGraphBuilder *graph;
5191
IMediaStream *stream;
5192
HRESULT hr;
5193
ULONG ref;
5194
IPin *pin;
5195
5196
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
5197
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5198
hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
5199
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5200
ok(!!filter, "Expected non-null filter.\n");
5201
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
5202
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5203
hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
5204
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5205
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
5206
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5207
hr = IMediaStream_QueryInterface(stream, &IID_IMemInputPin, (void **)&mem_input_pin);
5208
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5209
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
5210
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5211
ok(graph != NULL, "Expected non-NULL graph.\n");
5212
hr = IGraphBuilder_QueryInterface(graph, &IID_IMediaFilter, (void **)&graph_media_filter);
5213
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5214
testfilter_init(&source);
5215
hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
5216
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5217
hr = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, &IID_IAudioData, (void **)&audio_data);
5218
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5219
hr = IAudioMediaStream_CreateSample(audio_stream, audio_data, 0, &stream_sample);
5220
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5221
hr = IAudioData_SetBuffer(audio_data, 5, NULL, 0);
5222
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5223
testclock_init(&clock);
5224
5225
clock.time = 12345678;
5226
5227
current_time = 0xdeadbeefdeadbeef;
5228
hr = IAudioStreamSample_GetSampleTimes(stream_sample, NULL, NULL, &current_time);
5229
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5230
ok(current_time == 0, "Got current time %s.\n", wine_dbgstr_longlong(current_time));
5231
5232
hr = IMediaFilter_SetSyncSource(graph_media_filter, &clock.IReferenceClock_iface);
5233
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5234
5235
current_time = 0xdeadbeefdeadbeef;
5236
hr = IAudioStreamSample_GetSampleTimes(stream_sample, NULL, NULL, &current_time);
5237
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5238
ok(current_time == 0, "Got current time %s.\n", wine_dbgstr_longlong(current_time));
5239
5240
hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &audio_mt);
5241
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5242
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
5243
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5244
5245
hr = IMediaStreamFilter_GetCurrentStreamTime(filter, &filter_start_time);
5246
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5247
5248
clock.get_time_hr = E_FAIL;
5249
5250
current_time = 0xdeadbeefdeadbeef;
5251
hr = IAudioStreamSample_GetSampleTimes(stream_sample, NULL, NULL, &current_time);
5252
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5253
ok(current_time == 0xdeadbeefddf15da1 + filter_start_time, "Expected current time %s, got %s.\n",
5254
wine_dbgstr_longlong(0xdeadbeefddf15da1 + filter_start_time), wine_dbgstr_longlong(current_time));
5255
5256
clock.get_time_hr = S_OK;
5257
5258
current_time = 0xdeadbeefdeadbeef;
5259
hr = IAudioStreamSample_GetSampleTimes(stream_sample, NULL, NULL, &current_time);
5260
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5261
ok(current_time == filter_start_time, "Expected current time %s, got %s.\n",
5262
wine_dbgstr_longlong(filter_start_time), wine_dbgstr_longlong(current_time));
5263
5264
clock.time = 23456789;
5265
5266
current_time = 0xdeadbeefdeadbeef;
5267
hr = IAudioStreamSample_GetSampleTimes(stream_sample, NULL, NULL, &current_time);
5268
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5269
ok(current_time == filter_start_time + 11111111, "Expected current time %s, got %s.\n",
5270
wine_dbgstr_longlong(filter_start_time + 11111111), wine_dbgstr_longlong(current_time));
5271
5272
start_time = 0xdeadbeefdeadbeef;
5273
end_time = 0xdeadbeefdeadbeef;
5274
hr = IAudioStreamSample_GetSampleTimes(stream_sample, &start_time, &end_time, NULL);
5275
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5276
ok(start_time == 0, "Got start time %s.\n", wine_dbgstr_longlong(start_time));
5277
ok(end_time == 0, "Got end time %s.\n", wine_dbgstr_longlong(end_time));
5278
5279
media_sample = ammediastream_allocate_sample(&source, test_data, 8);
5280
start_time = 12345678;
5281
end_time = 23456789;
5282
hr = IMediaSample_SetTime(media_sample, &start_time, &end_time);
5283
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5284
hr = IMemInputPin_Receive(mem_input_pin, media_sample);
5285
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5286
IMediaSample_Release(media_sample);
5287
5288
hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
5289
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5290
5291
start_time = 0xdeadbeefdeadbeef;
5292
end_time = 0xdeadbeefdeadbeef;
5293
hr = IAudioStreamSample_GetSampleTimes(stream_sample, &start_time, &end_time, NULL);
5294
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5295
ok(start_time == 12345678, "Got start time %s.\n", wine_dbgstr_longlong(start_time));
5296
ok(end_time == 12347946, "Got end time %s.\n", wine_dbgstr_longlong(end_time));
5297
5298
media_sample = ammediastream_allocate_sample(&source, test_data, 6);
5299
start_time = 12345678;
5300
end_time = 23456789;
5301
hr = IMediaSample_SetTime(media_sample, &start_time, &end_time);
5302
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5303
hr = IMemInputPin_Receive(mem_input_pin, media_sample);
5304
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5305
IMediaSample_Release(media_sample);
5306
5307
hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
5308
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5309
5310
start_time = 0xdeadbeefdeadbeef;
5311
end_time = 0xdeadbeefdeadbeef;
5312
hr = IAudioStreamSample_GetSampleTimes(stream_sample, &start_time, &end_time, NULL);
5313
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5314
ok(start_time == 12347946, "Got start time %s.\n", wine_dbgstr_longlong(start_time));
5315
ok(end_time == 12346585, "Got end time %s.\n", wine_dbgstr_longlong(end_time));
5316
5317
hr = IPin_EndOfStream(pin);
5318
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5319
5320
hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
5321
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5322
5323
start_time = 0xdeadbeefdeadbeef;
5324
end_time = 0xdeadbeefdeadbeef;
5325
hr = IAudioStreamSample_GetSampleTimes(stream_sample, &start_time, &end_time, NULL);
5326
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5327
ok(start_time == 12346585, "Got start time %s.\n", wine_dbgstr_longlong(start_time));
5328
ok(end_time == 12348399, "Got end time %s.\n", wine_dbgstr_longlong(end_time));
5329
5330
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
5331
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5332
IGraphBuilder_Disconnect(graph, pin);
5333
IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
5334
5335
ref = IAudioStreamSample_Release(stream_sample);
5336
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5337
ref = IAudioData_Release(audio_data);
5338
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5339
ref = IAMMultiMediaStream_Release(mmstream);
5340
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5341
IMediaFilter_Release(graph_media_filter);
5342
ref = IGraphBuilder_Release(graph);
5343
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5344
ref = IMediaStreamFilter_Release(filter);
5345
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5346
IPin_Release(pin);
5347
IMemInputPin_Release(mem_input_pin);
5348
IAudioMediaStream_Release(audio_stream);
5349
ref = IMediaStream_Release(stream);
5350
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5351
}
5352
5353
static void test_ddrawstream_initialize(void)
5354
{
5355
IDirectDrawMediaStream *ddraw_stream;
5356
IAMMediaStream *stream;
5357
IDirectDraw *ddraw2;
5358
IDirectDraw *ddraw;
5359
STREAM_TYPE type;
5360
MSPID mspid;
5361
HRESULT hr;
5362
ULONG ref;
5363
5364
hr = DirectDrawCreate(NULL, &ddraw, NULL);
5365
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5366
5367
hr = CoCreateInstance(&CLSID_AMDirectDrawStream, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream);
5368
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5369
5370
hr = IAMMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
5371
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5372
5373
/* Crashes on native. */
5374
if (0)
5375
{
5376
hr = IAMMediaStream_Initialize(stream, NULL, 0, NULL, STREAMTYPE_WRITE);
5377
ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
5378
}
5379
5380
hr = IAMMediaStream_Initialize(stream, NULL, 0, &test_mspid, STREAMTYPE_WRITE);
5381
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5382
5383
hr = IAMMediaStream_GetInformation(stream, &mspid, &type);
5384
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5385
ok(IsEqualGUID(&mspid, &test_mspid), "Got mspid %s.\n", wine_dbgstr_guid(&mspid));
5386
ok(type == STREAMTYPE_WRITE, "Got type %u.\n", type);
5387
5388
hr = IAMMediaStream_Initialize(stream, (IUnknown *)ddraw, 0, &MSPID_PrimaryAudio, STREAMTYPE_READ);
5389
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5390
5391
hr = IAMMediaStream_GetInformation(stream, &mspid, &type);
5392
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5393
ok(IsEqualGUID(&mspid, &MSPID_PrimaryAudio), "Got mspid %s.\n", wine_dbgstr_guid(&mspid));
5394
ok(type == STREAMTYPE_READ, "Got type %u.\n", type);
5395
5396
hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw2);
5397
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5398
ok(ddraw2 == ddraw, "Expected ddraw %p, got %p.\n", ddraw, ddraw2);
5399
5400
IDirectDrawMediaStream_Release(ddraw_stream);
5401
ref = IAMMediaStream_Release(stream);
5402
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5403
IDirectDraw_Release(ddraw2);
5404
ref = IDirectDraw_Release(ddraw);
5405
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5406
}
5407
5408
#define check_ddrawstream_get_format(a,b,c) check_ddrawstream_get_format_(__LINE__,a,b,c)
5409
static void check_ddrawstream_get_format_(int line, IDirectDrawMediaStream *stream,
5410
const AM_MEDIA_TYPE *mt, const DDSURFACEDESC *expected_format)
5411
{
5412
DDSURFACEDESC current_format;
5413
DDSURFACEDESC desired_format;
5414
struct testfilter source;
5415
FILTER_INFO filter_info;
5416
DDSURFACEDESC format;
5417
PIN_INFO pin_info;
5418
DWORD flags;
5419
HRESULT hr;
5420
IPin *pin;
5421
5422
hr = IDirectDrawMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
5423
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
5424
hr = IPin_QueryPinInfo(pin, &pin_info);
5425
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
5426
hr = IBaseFilter_QueryFilterInfo(pin_info.pFilter, &filter_info);
5427
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
5428
5429
testfilter_init(&source);
5430
5431
hr = IFilterGraph_AddFilter(filter_info.pGraph, &source.filter.IBaseFilter_iface, L"source");
5432
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
5433
5434
hr = IFilterGraph_ConnectDirect(filter_info.pGraph, &source.source.pin.IPin_iface, pin, mt);
5435
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
5436
5437
hr = IDirectDrawMediaStream_GetFormat(stream, NULL, NULL, NULL, NULL);
5438
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
5439
5440
memset(&current_format, 0xcc, sizeof(current_format));
5441
current_format.dwSize = sizeof(current_format);
5442
memset(&desired_format, 0xcc, sizeof(desired_format));
5443
desired_format.dwSize = sizeof(desired_format);
5444
flags = 0xdeadbeef;
5445
hr = IDirectDrawMediaStream_GetFormat(stream, &current_format, NULL, &desired_format, &flags);
5446
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
5447
memset(&format, 0xcc, sizeof(format));
5448
format.dwSize = sizeof(format);
5449
format.ddpfPixelFormat = expected_format->ddpfPixelFormat;
5450
format.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
5451
format.dwWidth = 333;
5452
format.dwHeight = 444;
5453
format.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
5454
ok_(__FILE__, line)(memcmp(&current_format, &format, sizeof(DDSURFACEDESC)) == 0, "Current format didn't match.\n");
5455
format.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
5456
ok_(__FILE__, line)(memcmp(&desired_format, &format, sizeof(DDSURFACEDESC)) == 0, "Desired format didn't match.\n");
5457
5458
hr = IFilterGraph_Disconnect(filter_info.pGraph, &source.source.pin.IPin_iface);
5459
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
5460
hr = IFilterGraph_Disconnect(filter_info.pGraph, pin);
5461
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
5462
5463
hr = IFilterGraph_RemoveFilter(filter_info.pGraph, &source.filter.IBaseFilter_iface);
5464
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
5465
5466
IFilterGraph_Release(filter_info.pGraph);
5467
IBaseFilter_Release(pin_info.pFilter);
5468
IPin_Release(pin);
5469
}
5470
5471
static void test_ddrawstream_get_format(void)
5472
{
5473
IAMMultiMediaStream *mmstream = create_ammultimediastream();
5474
IDirectDrawMediaStream *ddraw_stream;
5475
DDSURFACEDESC current_format;
5476
DDSURFACEDESC desired_format;
5477
IDirectDrawPalette *palette;
5478
IMediaStream *stream;
5479
VIDEOINFO video_info;
5480
AM_MEDIA_TYPE mt;
5481
DWORD flags;
5482
HRESULT hr;
5483
ULONG ref;
5484
5485
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
5486
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5487
hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
5488
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5489
5490
current_format.dwSize = sizeof(current_format);
5491
desired_format.dwSize = sizeof(desired_format);
5492
hr = IDirectDrawMediaStream_GetFormat(ddraw_stream, &current_format, &palette, &desired_format, &flags);
5493
ok(hr == MS_E_NOSTREAM, "Got hr %#lx.\n", hr);
5494
5495
video_info = rgb32_video_info;
5496
video_info.rcSource.right = 222;
5497
video_info.rcSource.bottom = 333;
5498
video_info.rcTarget.right = 444;
5499
video_info.rcTarget.bottom = 666;
5500
mt = rgb32_mt;
5501
mt.pbFormat = (BYTE *)&video_info;
5502
check_ddrawstream_get_format(ddraw_stream, &mt, &rgb32_format);
5503
5504
video_info = rgb32_video_info;
5505
video_info.bmiHeader.biHeight = 444;
5506
mt = rgb32_mt;
5507
mt.pbFormat = (BYTE *)&video_info;
5508
check_ddrawstream_get_format(ddraw_stream, &mt, &rgb32_format);
5509
5510
check_ddrawstream_get_format(ddraw_stream, &rgb8_mt, &rgb8_format);
5511
check_ddrawstream_get_format(ddraw_stream, &rgb555_mt, &rgb555_format);
5512
check_ddrawstream_get_format(ddraw_stream, &rgb565_mt, &rgb565_format);
5513
check_ddrawstream_get_format(ddraw_stream, &rgb24_mt, &rgb24_format);
5514
check_ddrawstream_get_format(ddraw_stream, &rgb32_mt, &rgb32_format);
5515
5516
current_format.dwSize = sizeof(current_format);
5517
desired_format.dwSize = sizeof(desired_format);
5518
hr = IDirectDrawMediaStream_GetFormat(ddraw_stream, &current_format, &palette, &desired_format, &flags);
5519
ok(hr == MS_E_NOSTREAM, "Got hr %#lx.\n", hr);
5520
5521
ref = IAMMultiMediaStream_Release(mmstream);
5522
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5523
IDirectDrawMediaStream_Release(ddraw_stream);
5524
ref = IMediaStream_Release(stream);
5525
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5526
}
5527
5528
#define check_ddrawstream_set_format(a,b,c,d) check_ddrawstream_set_format_(__LINE__,a,b,c,d)
5529
static void check_ddrawstream_set_format_(int line, IDirectDrawMediaStream *stream,
5530
const DDSURFACEDESC *format, const AM_MEDIA_TYPE *mt, HRESULT expected_hr)
5531
{
5532
struct testfilter source;
5533
FILTER_INFO filter_info;
5534
PIN_INFO pin_info;
5535
HRESULT hr;
5536
IPin *pin;
5537
5538
hr = IDirectDrawMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
5539
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
5540
hr = IPin_QueryPinInfo(pin, &pin_info);
5541
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
5542
hr = IBaseFilter_QueryFilterInfo(pin_info.pFilter, &filter_info);
5543
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
5544
5545
testfilter_init(&source);
5546
5547
hr = IFilterGraph_AddFilter(filter_info.pGraph, &source.filter.IBaseFilter_iface, L"source");
5548
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
5549
5550
hr = IDirectDrawMediaStream_SetFormat(stream, format, NULL);
5551
ok_(__FILE__, line)(hr == expected_hr, "Got hr %#lx.\n", hr);
5552
5553
if (mt)
5554
{
5555
DDSURFACEDESC current_format;
5556
DDSURFACEDESC desired_format;
5557
DWORD flags;
5558
5559
hr = IFilterGraph_ConnectDirect(filter_info.pGraph, &source.source.pin.IPin_iface, pin, mt);
5560
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
5561
5562
memset(&current_format, 0xcc, sizeof(current_format));
5563
memset(&desired_format, 0xcc, sizeof(desired_format));
5564
flags = 0xdeadbeef;
5565
current_format.dwSize = sizeof(current_format);
5566
desired_format.dwSize = sizeof(desired_format);
5567
hr = IDirectDrawMediaStream_GetFormat(stream, &current_format, NULL, &desired_format, &flags);
5568
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
5569
if (format->dwFlags & DDSD_PIXELFORMAT)
5570
{
5571
ok_(__FILE__, line)(current_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT),
5572
"Got current format flags %#lx.\n", current_format.dwFlags);
5573
ok_(__FILE__, line)(memcmp(&current_format.ddpfPixelFormat, &format->ddpfPixelFormat, sizeof(DDPIXELFORMAT)) == 0,
5574
"Current pixel format didn't match.\n");
5575
ok_(__FILE__, line)(memcmp(&desired_format.ddpfPixelFormat, &format->ddpfPixelFormat, sizeof(DDPIXELFORMAT)) == 0,
5576
"Desired pixel format didn't match.\n");
5577
}
5578
else
5579
{
5580
ok_(__FILE__, line)(current_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS),
5581
"Got flags %#lx.\n", current_format.dwFlags);
5582
}
5583
ok_(__FILE__, line)(desired_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT),
5584
"Got desired format flags %#lx.\n", desired_format.dwFlags);
5585
ok_(__FILE__, line)(current_format.ddsCaps.dwCaps == (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY),
5586
"Got current format caps %#lx.\n", current_format.ddsCaps.dwCaps);
5587
ok_(__FILE__, line)(desired_format.ddsCaps.dwCaps == (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY),
5588
"Got desired format caps %#lx.\n", desired_format.ddsCaps.dwCaps);
5589
ok_(__FILE__, line)(flags == 0, "Got flags %#lx.\n", flags);
5590
5591
hr = IFilterGraph_Disconnect(filter_info.pGraph, &source.source.pin.IPin_iface);
5592
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
5593
hr = IFilterGraph_Disconnect(filter_info.pGraph, pin);
5594
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
5595
}
5596
5597
hr = IFilterGraph_RemoveFilter(filter_info.pGraph, &source.filter.IBaseFilter_iface);
5598
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
5599
5600
IFilterGraph_Release(filter_info.pGraph);
5601
IBaseFilter_Release(pin_info.pFilter);
5602
IPin_Release(pin);
5603
}
5604
5605
static void test_ddrawstream_set_format(void)
5606
{
5607
static const DDSURFACEDESC rgb1_format =
5608
{
5609
.dwSize = sizeof(DDSURFACEDESC),
5610
.dwFlags = DDSD_PIXELFORMAT,
5611
.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
5612
.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED1,
5613
.ddpfPixelFormat.dwRGBBitCount = 1,
5614
};
5615
static const DDSURFACEDESC rgb2_format =
5616
{
5617
.dwSize = sizeof(DDSURFACEDESC),
5618
.dwFlags = DDSD_PIXELFORMAT,
5619
.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
5620
.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED2,
5621
.ddpfPixelFormat.dwRGBBitCount = 2,
5622
};
5623
static const DDSURFACEDESC rgb4_format =
5624
{
5625
.dwSize = sizeof(DDSURFACEDESC),
5626
.dwFlags = DDSD_PIXELFORMAT,
5627
.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
5628
.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED4,
5629
.ddpfPixelFormat.dwRGBBitCount = 4,
5630
};
5631
static const DDSURFACEDESC rgb4to8_format =
5632
{
5633
.dwSize = sizeof(DDSURFACEDESC),
5634
.dwFlags = DDSD_PIXELFORMAT,
5635
.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
5636
.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXEDTO8,
5637
.ddpfPixelFormat.dwRGBBitCount = 4,
5638
};
5639
static const DDSURFACEDESC rgb332_format =
5640
{
5641
.dwSize = sizeof(DDSURFACEDESC),
5642
.dwFlags = DDSD_PIXELFORMAT,
5643
.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
5644
.ddpfPixelFormat.dwFlags = DDPF_RGB,
5645
.ddpfPixelFormat.dwRGBBitCount = 8,
5646
.ddpfPixelFormat.dwRBitMask = 0xe0,
5647
.ddpfPixelFormat.dwGBitMask = 0x1c,
5648
.ddpfPixelFormat.dwBBitMask = 0x03,
5649
};
5650
5651
IDirectDrawStreamSample *sample, *sample2;
5652
IDirectDrawMediaStream *ddraw_stream;
5653
VIDEOINFOHEADER *video_info_ptr;
5654
IAMMultiMediaStream *mmstream;
5655
DDSURFACEDESC current_format;
5656
DDSURFACEDESC desired_format;
5657
IDirectDrawSurface *surface;
5658
struct testfilter source;
5659
IGraphBuilder *graph;
5660
DDSURFACEDESC format;
5661
IMediaStream *stream;
5662
VIDEOINFO video_info;
5663
IDirectDraw *ddraw;
5664
AM_MEDIA_TYPE mt;
5665
HRESULT hr;
5666
ULONG ref;
5667
IPin *pin;
5668
RECT rect;
5669
5670
mmstream = create_ammultimediastream();
5671
5672
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
5673
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5674
hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
5675
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5676
5677
check_ddrawstream_set_format(ddraw_stream, &rgb8_format, &rgb8_mt, S_OK);
5678
check_ddrawstream_set_format(ddraw_stream, &rgb555_format, &rgb555_mt, S_OK);
5679
check_ddrawstream_set_format(ddraw_stream, &rgb565_format, &rgb565_mt, S_OK);
5680
check_ddrawstream_set_format(ddraw_stream, &rgb24_format, &rgb24_mt, S_OK);
5681
check_ddrawstream_set_format(ddraw_stream, &rgb32_format, &rgb32_mt, S_OK);
5682
check_ddrawstream_set_format(ddraw_stream, &argb32_format, &rgb32_mt, S_OK);
5683
check_ddrawstream_set_format(ddraw_stream, &yuy2_format, NULL, S_OK);
5684
check_ddrawstream_set_format(ddraw_stream, &yv12_format, NULL, S_OK);
5685
5686
format = rgb32_format;
5687
format.ddpfPixelFormat.dwFlags |= DDPF_ALPHAPIXELS | DDPF_ALPHA
5688
| DDPF_COMPRESSED | DDPF_RGBTOYUV | DDPF_ZBUFFER | DDPF_ZPIXELS | DDPF_STENCILBUFFER
5689
| DDPF_ALPHAPREMULT | DDPF_LUMINANCE | DDPF_BUMPLUMINANCE | DDPF_BUMPDUDV;
5690
check_ddrawstream_set_format(ddraw_stream, &format, &rgb32_mt, S_OK);
5691
5692
format = yuy2_format;
5693
format.ddpfPixelFormat.dwFlags |= DDPF_ALPHAPIXELS | DDPF_ALPHA
5694
| DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXEDTO8 | DDPF_PALETTEINDEXED8
5695
| DDPF_RGB | DDPF_COMPRESSED | DDPF_RGBTOYUV | DDPF_YUV | DDPF_ZBUFFER
5696
| DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 | DDPF_ZPIXELS
5697
| DDPF_STENCILBUFFER | DDPF_ALPHAPREMULT | DDPF_LUMINANCE
5698
| DDPF_BUMPLUMINANCE | DDPF_BUMPDUDV;
5699
check_ddrawstream_set_format(ddraw_stream, &format, NULL, S_OK);
5700
5701
format = rgb32_format;
5702
format.dwFlags |= DDSD_CAPS;
5703
format.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
5704
check_ddrawstream_set_format(ddraw_stream, &format, &rgb32_mt, S_OK);
5705
5706
format = rgb8_format;
5707
format.dwFlags = 0;
5708
check_ddrawstream_set_format(ddraw_stream, &format, &rgb32_mt, S_OK);
5709
5710
check_ddrawstream_set_format(ddraw_stream, &rgb1_format, NULL, DDERR_INVALIDSURFACETYPE);
5711
check_ddrawstream_set_format(ddraw_stream, &rgb2_format, NULL, DDERR_INVALIDSURFACETYPE);
5712
check_ddrawstream_set_format(ddraw_stream, &rgb4_format, NULL, DDERR_INVALIDSURFACETYPE);
5713
check_ddrawstream_set_format(ddraw_stream, &rgb4to8_format, NULL, DDERR_INVALIDSURFACETYPE);
5714
check_ddrawstream_set_format(ddraw_stream, &rgb332_format, NULL, DDERR_INVALIDSURFACETYPE);
5715
5716
format = rgb8_format;
5717
format.ddpfPixelFormat.dwFlags &= ~DDPF_RGB;
5718
check_ddrawstream_set_format(ddraw_stream, &format, NULL, DDERR_INVALIDSURFACETYPE);
5719
5720
format = rgb8_format;
5721
format.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED1;
5722
check_ddrawstream_set_format(ddraw_stream, &format, NULL, DDERR_INVALIDSURFACETYPE);
5723
5724
format = rgb32_format;
5725
format.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED8;
5726
check_ddrawstream_set_format(ddraw_stream, &format, NULL, DDERR_INVALIDSURFACETYPE);
5727
5728
format = rgb32_format;
5729
format.ddpfPixelFormat.dwFlags |= DDPF_YUV;
5730
check_ddrawstream_set_format(ddraw_stream, &format, NULL, DDERR_INVALIDSURFACETYPE);
5731
5732
format = rgb565_format;
5733
format.ddpfPixelFormat.dwRBitMask = 0x001f;
5734
format.ddpfPixelFormat.dwGBitMask = 0x07e0;
5735
format.ddpfPixelFormat.dwBBitMask = 0xf800;
5736
check_ddrawstream_set_format(ddraw_stream, &format, NULL, DDERR_INVALIDSURFACETYPE);
5737
5738
format = rgb32_format;
5739
format.ddpfPixelFormat.dwRBitMask = 0x00ff00;
5740
format.ddpfPixelFormat.dwGBitMask = 0x0000ff;
5741
format.ddpfPixelFormat.dwBBitMask = 0xff0000;
5742
check_ddrawstream_set_format(ddraw_stream, &format, NULL, DDERR_INVALIDSURFACETYPE);
5743
5744
format = yuy2_format;
5745
format.ddpfPixelFormat.dwYUVBitCount = 0;
5746
check_ddrawstream_set_format(ddraw_stream, &format, NULL, E_INVALIDARG);
5747
5748
format = rgb32_format;
5749
format.dwSize = sizeof(DDSURFACEDESC) + 1;
5750
check_ddrawstream_set_format(ddraw_stream, &format, NULL, E_INVALIDARG);
5751
5752
format = rgb32_format;
5753
format.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT) + 1;
5754
check_ddrawstream_set_format(ddraw_stream, &format, NULL, DDERR_INVALIDSURFACETYPE);
5755
5756
ref = IAMMultiMediaStream_Release(mmstream);
5757
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5758
IDirectDrawMediaStream_Release(ddraw_stream);
5759
ref = IMediaStream_Release(stream);
5760
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5761
5762
mmstream = create_ammultimediastream();
5763
5764
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
5765
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5766
hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
5767
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5768
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
5769
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5770
5771
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
5772
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5773
ok(!!graph, "Expected non-NULL graph.\n");
5774
5775
testfilter_init(&source);
5776
5777
hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, L"source");
5778
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5779
5780
hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &rgb8_mt);
5781
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5782
5783
source.preferred_mt = NULL;
5784
5785
/* amstream reconnects with a NULL media type. It doesn't enumerate the
5786
* only format it'll accept, and we don't enumerate it either, so we fail
5787
* to connect with that format here. */
5788
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb555_format, NULL);
5789
ok(hr == DDERR_INVALIDSURFACETYPE, "Got hr %#lx.\n", hr);
5790
ok(IsEqualGUID(&source.source.pin.mt.subtype, &MEDIASUBTYPE_RGB8),
5791
"Got subtype %s.\n", wine_dbgstr_guid(&source.source.pin.mt.subtype));
5792
hr = IDirectDrawMediaStream_GetFormat(ddraw_stream, &current_format, NULL, &desired_format, NULL);
5793
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5794
ok(current_format.ddpfPixelFormat.dwRGBBitCount == 8,
5795
"Got rgb bit count %lu.\n", current_format.ddpfPixelFormat.dwRGBBitCount);
5796
ok(desired_format.ddpfPixelFormat.dwRGBBitCount == 8,
5797
"Got rgb bit count %lu.\n", desired_format.ddpfPixelFormat.dwRGBBitCount);
5798
5799
format = rgb555_format;
5800
format.dwFlags = 0;
5801
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &format, NULL);
5802
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5803
ok(IsEqualGUID(&source.source.pin.mt.subtype, &MEDIASUBTYPE_RGB8),
5804
"Got subtype %s.\n", wine_dbgstr_guid(&source.source.pin.mt.subtype));
5805
5806
/* Now enumerate the corresponding target media type, and we can set
5807
* that format. */
5808
source.preferred_mt = &rgb555_mt;
5809
5810
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb8_format, NULL);
5811
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5812
5813
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb555_format, NULL);
5814
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5815
ok(IsEqualGUID(&source.source.pin.mt.subtype, &MEDIASUBTYPE_RGB555),
5816
"Got subtype %s.\n", wine_dbgstr_guid(&source.source.pin.mt.subtype));
5817
video_info_ptr = (VIDEOINFOHEADER *)source.source.pin.mt.pbFormat;
5818
ok(video_info_ptr->bmiHeader.biWidth == 333, "Got width %ld.\n", video_info_ptr->bmiHeader.biWidth);
5819
ok(video_info_ptr->bmiHeader.biHeight == -444, "Got width %ld.\n", video_info_ptr->bmiHeader.biHeight);
5820
hr = IDirectDrawMediaStream_GetFormat(ddraw_stream, &current_format, NULL, &desired_format, NULL);
5821
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5822
ok(current_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT),
5823
"Got flags %#lx.\n", current_format.dwFlags);
5824
ok(current_format.dwWidth == 333, "Got width %ld.\n", current_format.dwWidth);
5825
ok(current_format.dwHeight == 444, "Got height %ld.\n", current_format.dwHeight);
5826
ok(current_format.ddpfPixelFormat.dwRGBBitCount == 16,
5827
"Got rgb bit count %lu.\n", current_format.ddpfPixelFormat.dwRGBBitCount);
5828
ok(desired_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT),
5829
"Got flags %#lx.\n", desired_format.dwFlags);
5830
ok(desired_format.dwWidth == 333, "Got width %ld.\n", desired_format.dwWidth);
5831
ok(desired_format.dwHeight == 444, "Got height %ld.\n", desired_format.dwHeight);
5832
ok(desired_format.ddpfPixelFormat.dwRGBBitCount == 16,
5833
"Got rgb bit count %lu.\n", desired_format.ddpfPixelFormat.dwRGBBitCount);
5834
5835
video_info = rgb555_video_info;
5836
video_info.bmiHeader.biWidth = 222;
5837
video_info.bmiHeader.biHeight = -555;
5838
mt = rgb555_mt;
5839
mt.pbFormat = (BYTE *)&video_info;
5840
source.preferred_mt = &mt;
5841
5842
format = rgb555_format;
5843
format.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT;
5844
format.dwWidth = 222;
5845
format.dwHeight = 555;
5846
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &format, NULL);
5847
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5848
ok(IsEqualGUID(&source.source.pin.mt.subtype, &MEDIASUBTYPE_RGB555),
5849
"Got subtype %s.\n", wine_dbgstr_guid(&source.source.pin.mt.subtype));
5850
ok(((VIDEOINFO *)source.source.pin.mt.pbFormat)->bmiHeader.biWidth == 222,
5851
"Got width %ld.\n", ((VIDEOINFO *)source.source.pin.mt.pbFormat)->bmiHeader.biWidth);
5852
ok(((VIDEOINFO *)source.source.pin.mt.pbFormat)->bmiHeader.biHeight == -555,
5853
"Got height %ld.\n", ((VIDEOINFO *)source.source.pin.mt.pbFormat)->bmiHeader.biHeight);
5854
5855
/* Test with CreateSample() instead of SetFormat(). */
5856
5857
hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw);
5858
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5859
5860
/* As above, this fails because amstream wants to reconnect with an RGB32
5861
* format, but doesn't enumerate that format, and we don't either. */
5862
format = rgb32_format;
5863
format.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT;
5864
format.dwWidth = 333;
5865
format.dwHeight = 444;
5866
hr = IDirectDraw_CreateSurface(ddraw, &format, &surface, NULL);
5867
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5868
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, surface, NULL, 0, &sample);
5869
ok(hr == DDERR_INVALIDSURFACETYPE, "Got hr %#lx.\n", hr);
5870
5871
/* Offer RGB32, and now we can reconnect. */
5872
video_info = rgb32_video_info;
5873
video_info.bmiHeader.biWidth = 333;
5874
video_info.bmiHeader.biHeight = -444;
5875
mt = rgb32_mt;
5876
mt.pbFormat = (BYTE *)&video_info;
5877
source.preferred_mt = &mt;
5878
5879
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, surface, NULL, 0, &sample);
5880
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5881
ok(IsEqualGUID(&source.source.pin.mt.subtype, &MEDIASUBTYPE_RGB32),
5882
"Got subtype %s.\n", wine_dbgstr_guid(&source.source.pin.mt.subtype));
5883
ok(((VIDEOINFO *)source.source.pin.mt.pbFormat)->bmiHeader.biWidth == 333,
5884
"Got width %ld.\n", ((VIDEOINFO *)source.source.pin.mt.pbFormat)->bmiHeader.biWidth);
5885
ok(((VIDEOINFO *)source.source.pin.mt.pbFormat)->bmiHeader.biHeight == -444,
5886
"Got height %ld.\n", ((VIDEOINFO *)source.source.pin.mt.pbFormat)->bmiHeader.biHeight);
5887
5888
hr = IDirectDrawMediaStream_GetFormat(ddraw_stream, &current_format, NULL, &desired_format, NULL);
5889
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5890
ok(current_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT),
5891
"Got flags %#lx.\n", current_format.dwFlags);
5892
ok(current_format.dwWidth == 333, "Got width %ld.\n", current_format.dwWidth);
5893
ok(current_format.dwHeight == 444, "Got height %ld.\n", current_format.dwHeight);
5894
ok(current_format.ddpfPixelFormat.dwRGBBitCount == 32,
5895
"Got rgb bit count %lu.\n", current_format.ddpfPixelFormat.dwRGBBitCount);
5896
ok(desired_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT),
5897
"Got flags %#lx.\n", desired_format.dwFlags);
5898
ok(desired_format.dwWidth == 333, "Got width %ld.\n", desired_format.dwWidth);
5899
ok(desired_format.dwHeight == 444, "Got height %ld.\n", desired_format.dwHeight);
5900
ok(desired_format.ddpfPixelFormat.dwRGBBitCount == 32,
5901
"Got rgb bit count %lu.\n", desired_format.ddpfPixelFormat.dwRGBBitCount);
5902
5903
SetRect(&rect, 100, 200, 300, 400);
5904
5905
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, surface, &rect, 0, &sample2);
5906
ok(hr == MS_E_SAMPLEALLOC, "Got hr %#lx.\n", hr);
5907
5908
IDirectDrawStreamSample_Release(sample);
5909
5910
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, surface, &rect, 0, &sample);
5911
ok(hr == DDERR_INVALIDSURFACETYPE, "Got hr %#lx.\n", hr);
5912
5913
video_info.bmiHeader.biWidth = 200;
5914
video_info.bmiHeader.biHeight = -200;
5915
5916
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, surface, &rect, 0, &sample);
5917
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5918
IDirectDrawStreamSample_Release(sample);
5919
ok(IsEqualGUID(&source.source.pin.mt.subtype, &MEDIASUBTYPE_RGB32),
5920
"Got subtype %s.\n", wine_dbgstr_guid(&source.source.pin.mt.subtype));
5921
ok(((VIDEOINFO *)source.source.pin.mt.pbFormat)->bmiHeader.biWidth == 200,
5922
"Got width %ld.\n", ((VIDEOINFO *)source.source.pin.mt.pbFormat)->bmiHeader.biWidth);
5923
ok(((VIDEOINFO *)source.source.pin.mt.pbFormat)->bmiHeader.biHeight == -200,
5924
"Got height %ld.\n", ((VIDEOINFO *)source.source.pin.mt.pbFormat)->bmiHeader.biHeight);
5925
5926
IDirectDrawSurface_Release(surface);
5927
5928
hr = IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
5929
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5930
hr = IGraphBuilder_Disconnect(graph, pin);
5931
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5932
5933
ref = IAMMultiMediaStream_Release(mmstream);
5934
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5935
ref = IGraphBuilder_Release(graph);
5936
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5937
IPin_Release(pin);
5938
IDirectDraw_Release(ddraw);
5939
IDirectDrawMediaStream_Release(ddraw_stream);
5940
ref = IMediaStream_Release(stream);
5941
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5942
}
5943
5944
static void test_ddrawstream_receive(void)
5945
{
5946
ALLOCATOR_PROPERTIES properties =
5947
{
5948
.cBuffers = 1,
5949
.cbBuffer = 16,
5950
.cbAlign = 1,
5951
};
5952
5953
IAMMultiMediaStream *mmstream = create_ammultimediastream();
5954
ALLOCATOR_PROPERTIES actual;
5955
IMediaStreamFilter *filter;
5956
struct testfilter source;
5957
IMemAllocator *allocator;
5958
IGraphBuilder *graph;
5959
IMediaStream *stream;
5960
IMediaSample *sample;
5961
HANDLE thread;
5962
HRESULT hr;
5963
ULONG ref;
5964
IPin *pin;
5965
5966
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
5967
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5968
hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
5969
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5970
ok(!!filter, "Expected non-null filter.\n");
5971
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
5972
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5973
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
5974
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5975
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
5976
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5977
ok(graph != NULL, "Expected non-NULL graph.\n");
5978
testfilter_init(&source);
5979
hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
5980
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5981
hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER, &IID_IMemAllocator, (void **)&allocator);
5982
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5983
hr = IMemAllocator_SetProperties(allocator, &properties, &actual);
5984
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5985
hr = IMemAllocator_Commit(allocator);
5986
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5987
5988
hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &rgb32_mt);
5989
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5990
5991
hr = IMemAllocator_GetBuffer(allocator, &sample, NULL, NULL, 0);
5992
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5993
hr = IMemInputPin_Receive(source.source.pMemInputPin, sample);
5994
ok(hr == S_OK, "Got hr %#lx.\n", hr);
5995
ref = IMediaSample_Release(sample);
5996
ok(!ref, "Got outstanding refcount %ld.\n", ref);
5997
5998
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
5999
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6000
6001
hr = IMemAllocator_GetBuffer(allocator, &sample, NULL, NULL, 0);
6002
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6003
6004
ammediastream_mem_input_pin = source.source.pMemInputPin;
6005
ammediastream_media_sample = sample;
6006
ammediastream_sleep_time = 0;
6007
ammediastream_expected_hr = S_OK;
6008
thread = CreateThread(NULL, 0, ammediastream_receive, NULL, 0, NULL);
6009
6010
ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Receive returned prematurely.\n");
6011
6012
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
6013
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6014
6015
ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
6016
CloseHandle(thread);
6017
6018
ref = IMediaSample_Release(sample);
6019
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6020
6021
hr = IMemAllocator_GetBuffer(allocator, &sample, NULL, NULL, 0);
6022
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6023
hr = IMemInputPin_Receive(source.source.pMemInputPin, sample);
6024
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6025
ref = IMediaSample_Release(sample);
6026
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6027
6028
IGraphBuilder_Disconnect(graph, pin);
6029
IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
6030
6031
hr = IMemAllocator_Decommit(allocator);
6032
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6033
6034
ref = IAMMultiMediaStream_Release(mmstream);
6035
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6036
ref = IGraphBuilder_Release(graph);
6037
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6038
ref = IMediaStreamFilter_Release(filter);
6039
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6040
IPin_Release(pin);
6041
ref = IMediaStream_Release(stream);
6042
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6043
ref = IMemAllocator_Release(allocator);
6044
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6045
}
6046
6047
static void test_ddrawstream_begin_flush_end_flush(void)
6048
{
6049
IAMMultiMediaStream *mmstream = create_ammultimediastream();
6050
static const MSPID mspid = {0x88888888, 1};
6051
IDirectDrawStreamSample *stream_sample;
6052
IDirectDrawMediaStream *ddraw_stream;
6053
IMediaStreamFilter *filter;
6054
IMediaSample *media_sample;
6055
IMediaFilter *media_filter;
6056
struct testfilter source2;
6057
struct testfilter source;
6058
IAMMediaStream *stream2;
6059
IMediaStream *stream;
6060
VIDEOINFO video_info;
6061
struct graph graph;
6062
AM_MEDIA_TYPE mt;
6063
HANDLE thread;
6064
HRESULT hr;
6065
IPin *pin2;
6066
ULONG ref;
6067
IPin *pin;
6068
6069
graph_init(&graph);
6070
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, (IGraphBuilder *)&graph.IFilterGraph2_iface);
6071
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6072
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
6073
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6074
hr = CoCreateInstance(&CLSID_AMDirectDrawStream, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream2);
6075
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6076
hr = IAMMediaStream_Initialize(stream2, NULL, 0, &mspid, STREAMTYPE_READ);
6077
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6078
hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)stream2, &mspid, 0, NULL);
6079
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6080
hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
6081
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6082
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
6083
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6084
hr = IAMMediaStream_QueryInterface(stream2, &IID_IPin, (void **)&pin2);
6085
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6086
hr = IFilterGraph2_QueryInterface(&graph.IFilterGraph2_iface, &IID_IMediaFilter, (void **)&media_filter);
6087
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6088
hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
6089
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6090
testfilter_init(&source);
6091
testfilter_init(&source2);
6092
source.IMediaSeeking_iface.lpVtbl = &testsource_seeking_vtbl;
6093
hr = IFilterGraph2_AddFilter(&graph.IFilterGraph2_iface, &source.filter.IBaseFilter_iface, NULL);
6094
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6095
hr = IFilterGraph2_AddFilter(&graph.IFilterGraph2_iface, &source2.filter.IBaseFilter_iface, NULL);
6096
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6097
6098
hr = IMediaFilter_SetSyncSource(media_filter, NULL);
6099
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6100
6101
video_info = rgb32_video_info;
6102
video_info.bmiHeader.biWidth = 3;
6103
video_info.bmiHeader.biHeight = 1;
6104
mt = rgb32_mt;
6105
mt.pbFormat = (BYTE *)&video_info;
6106
hr = IFilterGraph2_ConnectDirect(&graph.IFilterGraph2_iface, &source.source.pin.IPin_iface, pin, &mt);
6107
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6108
hr = IFilterGraph2_ConnectDirect(&graph.IFilterGraph2_iface, &source2.source.pin.IPin_iface, pin2, &mt);
6109
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6110
6111
hr = IMediaStreamFilter_SupportSeeking(filter, TRUE);
6112
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6113
6114
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &stream_sample);
6115
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6116
6117
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
6118
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6119
6120
hr = IMemAllocator_GetBuffer(source.source.pAllocator, &media_sample, NULL, NULL, 0);
6121
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6122
6123
ammediastream_mem_input_pin = source.source.pMemInputPin;
6124
ammediastream_media_sample = media_sample;
6125
ammediastream_sleep_time = 0;
6126
ammediastream_expected_hr = S_FALSE;
6127
thread = CreateThread(NULL, 0, ammediastream_receive, NULL, 0, NULL);
6128
6129
hr = IPin_BeginFlush(pin);
6130
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6131
6132
ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
6133
CloseHandle(thread);
6134
6135
ref = IMediaSample_Release(media_sample);
6136
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6137
6138
hr = IMemAllocator_GetBuffer(source.source.pAllocator, &media_sample, NULL, NULL, 0);
6139
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6140
hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
6141
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
6142
6143
ref = IMediaSample_Release(media_sample);
6144
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6145
6146
hr = IDirectDrawStreamSample_Update(stream_sample, SSUPDATE_ASYNC, NULL, NULL, 0);
6147
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
6148
6149
hr = IPin_EndOfStream(pin);
6150
ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
6151
6152
hr = IPin_EndFlush(pin);
6153
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6154
6155
hr = IMemAllocator_GetBuffer(source.source.pAllocator, &media_sample, NULL, NULL, 0);
6156
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6157
hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
6158
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6159
ref = IMediaSample_Release(media_sample);
6160
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6161
6162
hr = IPin_EndOfStream(pin);
6163
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6164
6165
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
6166
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6167
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
6168
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6169
6170
hr = IPin_BeginFlush(pin);
6171
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6172
hr = IPin_EndFlush(pin);
6173
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6174
6175
hr = IPin_EndOfStream(pin);
6176
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6177
6178
graph.got_notify = 0;
6179
6180
hr = IPin_EndOfStream(pin2);
6181
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6182
6183
ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
6184
ok(graph.event_code == EC_COMPLETE, "Got event code %ld.\n", graph.event_code);
6185
6186
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
6187
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6188
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
6189
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6190
6191
hr = IPin_EndOfStream(pin);
6192
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6193
6194
hr = IPin_BeginFlush(pin);
6195
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6196
hr = IPin_EndFlush(pin);
6197
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6198
6199
graph.got_notify = 0;
6200
graph.event_code = 0xcc;
6201
6202
hr = IPin_EndOfStream(pin2);
6203
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6204
6205
ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
6206
6207
hr = IPin_EndOfStream(pin);
6208
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6209
6210
ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
6211
ok(graph.event_code == EC_COMPLETE, "Got event code %ld.\n", graph.event_code);
6212
6213
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
6214
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6215
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
6216
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6217
6218
hr = IPin_EndOfStream(pin);
6219
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6220
6221
hr = IPin_BeginFlush(pin);
6222
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6223
hr = IPin_EndFlush(pin);
6224
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6225
hr = IPin_BeginFlush(pin);
6226
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6227
hr = IPin_EndFlush(pin);
6228
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6229
6230
hr = IPin_EndOfStream(pin);
6231
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6232
6233
graph.got_notify = 0;
6234
graph.event_code = 0xcc;
6235
6236
hr = IPin_EndOfStream(pin2);
6237
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6238
6239
ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
6240
ok(graph.event_code == EC_COMPLETE, "Got event code %ld.\n", graph.event_code);
6241
6242
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
6243
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6244
6245
IFilterGraph2_Disconnect(&graph.IFilterGraph2_iface, pin);
6246
IFilterGraph2_Disconnect(&graph.IFilterGraph2_iface, &source.source.pin.IPin_iface);
6247
IFilterGraph2_Disconnect(&graph.IFilterGraph2_iface, pin2);
6248
IFilterGraph2_Disconnect(&graph.IFilterGraph2_iface, &source2.source.pin.IPin_iface);
6249
6250
ref = IDirectDrawStreamSample_Release(stream_sample);
6251
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6252
ref = IAMMultiMediaStream_Release(mmstream);
6253
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6254
IMediaFilter_Release(media_filter);
6255
graph_destroy(&graph);
6256
ref = IMediaStreamFilter_Release(filter);
6257
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6258
IPin_Release(pin);
6259
IDirectDrawMediaStream_Release(ddraw_stream);
6260
ref = IMediaStream_Release(stream);
6261
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6262
IPin_Release(pin2);
6263
ref = IAMMediaStream_Release(stream2);
6264
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6265
}
6266
6267
static void test_ddrawstream_new_segment(void)
6268
{
6269
static const BYTE test_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
6270
IAMMultiMediaStream *mmstream = create_ammultimediastream();
6271
IDirectDrawStreamSample *stream_sample;
6272
IDirectDrawMediaStream *ddraw_stream;
6273
IMemInputPin *mem_input_pin;
6274
IMediaSample *media_sample;
6275
IMediaFilter *media_filter;
6276
struct testfilter source;
6277
STREAM_TIME start_time;
6278
STREAM_TIME end_time;
6279
IGraphBuilder *graph;
6280
IMediaStream *stream;
6281
VIDEOINFO video_info;
6282
AM_MEDIA_TYPE mt;
6283
HRESULT hr;
6284
ULONG ref;
6285
IPin *pin;
6286
6287
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
6288
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6289
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
6290
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6291
hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
6292
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6293
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
6294
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6295
hr = IMediaStream_QueryInterface(stream, &IID_IMemInputPin, (void **)&mem_input_pin);
6296
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6297
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
6298
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6299
ok(graph != NULL, "Expected non-NULL graph.\n");
6300
hr = IGraphBuilder_QueryInterface(graph, &IID_IMediaFilter, (void **)&media_filter);
6301
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6302
testfilter_init(&source);
6303
hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
6304
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6305
6306
hr = IMediaFilter_SetSyncSource(media_filter, NULL);
6307
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6308
6309
video_info = rgb32_video_info;
6310
video_info.bmiHeader.biWidth = 3;
6311
video_info.bmiHeader.biHeight = 1;
6312
mt = rgb32_mt;
6313
mt.pbFormat = (BYTE *)&video_info;
6314
hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
6315
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6316
6317
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &stream_sample);
6318
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6319
6320
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
6321
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6322
6323
hr = IPin_NewSegment(pin, 11111111, 22222222, 1.0);
6324
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6325
6326
hr = IDirectDrawStreamSample_Update(stream_sample, SSUPDATE_ASYNC, NULL, NULL, 0);
6327
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
6328
6329
media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
6330
start_time = 12345678;
6331
end_time = 23456789;
6332
hr = IMediaSample_SetTime(media_sample, &start_time, &end_time);
6333
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6334
hr = IMemInputPin_Receive(mem_input_pin, media_sample);
6335
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6336
IMediaSample_Release(media_sample);
6337
6338
start_time = 0xdeadbeefdeadbeef;
6339
end_time = 0xdeadbeefdeadbeef;
6340
hr = IDirectDrawStreamSample_GetSampleTimes(stream_sample, &start_time, &end_time, NULL);
6341
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6342
ok(start_time == 23456789, "Got start time %s.\n", wine_dbgstr_longlong(start_time));
6343
ok(end_time == 34567900, "Got end time %s.\n", wine_dbgstr_longlong(end_time));
6344
6345
hr = IPin_NewSegment(pin, 11111111, 22222222, 2.0);
6346
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6347
6348
hr = IDirectDrawStreamSample_Update(stream_sample, SSUPDATE_ASYNC, NULL, NULL, 0);
6349
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
6350
6351
media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
6352
start_time = 12345678;
6353
end_time = 23456789;
6354
hr = IMediaSample_SetTime(media_sample, &start_time, &end_time);
6355
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6356
hr = IMemInputPin_Receive(mem_input_pin, media_sample);
6357
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6358
IMediaSample_Release(media_sample);
6359
6360
start_time = 0xdeadbeefdeadbeef;
6361
end_time = 0xdeadbeefdeadbeef;
6362
hr = IDirectDrawStreamSample_GetSampleTimes(stream_sample, &start_time, &end_time, NULL);
6363
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6364
ok(start_time == 23456789, "Got start time %s.\n", wine_dbgstr_longlong(start_time));
6365
ok(end_time == 34567900, "Got end time %s.\n", wine_dbgstr_longlong(end_time));
6366
6367
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
6368
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6369
IGraphBuilder_Disconnect(graph, pin);
6370
IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
6371
6372
ref = IDirectDrawStreamSample_Release(stream_sample);
6373
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6374
ref = IAMMultiMediaStream_Release(mmstream);
6375
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6376
IMediaFilter_Release(media_filter);
6377
ref = IGraphBuilder_Release(graph);
6378
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6379
IPin_Release(pin);
6380
IMemInputPin_Release(mem_input_pin);
6381
IDirectDrawMediaStream_Release(ddraw_stream);
6382
ref = IMediaStream_Release(stream);
6383
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6384
}
6385
6386
static void test_ddrawstream_get_time_per_frame(void)
6387
{
6388
IAMMultiMediaStream *mmstream = create_ammultimediastream();
6389
IDirectDrawMediaStream *ddraw_stream;
6390
struct testfilter source;
6391
STREAM_TIME frame_time;
6392
IGraphBuilder *graph;
6393
IMediaStream *stream;
6394
VIDEOINFO video_info;
6395
AM_MEDIA_TYPE mt;
6396
HRESULT hr;
6397
ULONG ref;
6398
IPin *pin;
6399
6400
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
6401
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6402
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
6403
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6404
hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
6405
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6406
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
6407
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6408
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
6409
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6410
ok(graph != NULL, "Expected non-NULL graph.\n");
6411
testfilter_init(&source);
6412
hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
6413
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6414
6415
hr = IDirectDrawMediaStream_GetTimePerFrame(ddraw_stream, NULL);
6416
ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
6417
6418
hr = IDirectDrawMediaStream_GetTimePerFrame(ddraw_stream, &frame_time);
6419
ok(hr == MS_E_NOSTREAM, "Got hr %#lx.\n", hr);
6420
6421
video_info = rgb32_video_info;
6422
video_info.AvgTimePerFrame = 12345678;
6423
mt = rgb32_mt;
6424
mt.pbFormat = (BYTE *)&video_info;
6425
hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
6426
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6427
6428
frame_time = 0xdeadbeefdeadbeef;
6429
hr = IDirectDrawMediaStream_GetTimePerFrame(ddraw_stream, &frame_time);
6430
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6431
ok(frame_time == 12345678, "Got frame time %s.\n", wine_dbgstr_longlong(frame_time));
6432
6433
ref = IAMMultiMediaStream_Release(mmstream);
6434
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6435
ref = IGraphBuilder_Release(graph);
6436
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6437
IPin_Release(pin);
6438
IDirectDrawMediaStream_Release(ddraw_stream);
6439
ref = IMediaStream_Release(stream);
6440
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6441
}
6442
6443
static void check_ammediastream_join_am_multi_media_stream(const CLSID *clsid)
6444
{
6445
IAMMultiMediaStream *mmstream = create_ammultimediastream();
6446
IMultiMediaStream *mmstream2;
6447
IAMMediaStream *stream;
6448
HRESULT hr;
6449
ULONG mmstream_ref;
6450
ULONG ref;
6451
6452
hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream);
6453
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6454
6455
mmstream_ref = get_refcount(mmstream);
6456
6457
hr = IAMMediaStream_JoinAMMultiMediaStream(stream, mmstream);
6458
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6459
6460
ref = get_refcount(mmstream);
6461
ok(ref == mmstream_ref, "Expected outstanding refcount %ld, got %ld.\n", mmstream_ref, ref);
6462
6463
hr = IAMMediaStream_GetMultiMediaStream(stream, &mmstream2);
6464
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6465
ok(mmstream2 == (IMultiMediaStream *)mmstream, "Expected mmstream %p, got %p.\n", mmstream, mmstream2);
6466
6467
IMultiMediaStream_Release(mmstream2);
6468
6469
hr = IAMMediaStream_JoinAMMultiMediaStream(stream, NULL);
6470
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6471
6472
hr = IAMMediaStream_GetMultiMediaStream(stream, &mmstream2);
6473
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6474
ok(mmstream2 == NULL, "Got mmstream %p.\n", mmstream2);
6475
6476
ref = IAMMediaStream_Release(stream);
6477
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6478
ref = IAMMultiMediaStream_Release(mmstream);
6479
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6480
}
6481
6482
static void test_ammediastream_join_am_multi_media_stream(void)
6483
{
6484
check_ammediastream_join_am_multi_media_stream(&CLSID_AMAudioStream);
6485
check_ammediastream_join_am_multi_media_stream(&CLSID_AMDirectDrawStream);
6486
}
6487
6488
static void check_ammediastream_join_filter(const CLSID *clsid)
6489
{
6490
IAMMultiMediaStream *mmstream = create_ammultimediastream();
6491
IMediaStreamFilter *filter, *filter2, *filter3;
6492
IAMMediaStream *stream;
6493
HRESULT hr;
6494
ULONG ref;
6495
6496
hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
6497
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6498
ok(!!filter, "Expected non-null filter.\n");
6499
EXPECT_REF(filter, 3);
6500
6501
hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream);
6502
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6503
EXPECT_REF(filter, 3);
6504
6505
hr = CoCreateInstance(&CLSID_MediaStreamFilter, NULL, CLSCTX_INPROC_SERVER,
6506
&IID_IMediaStreamFilter, (void **)&filter2);
6507
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6508
EXPECT_REF(filter, 3);
6509
EXPECT_REF(filter2, 1);
6510
6511
hr = IAMMediaStream_JoinFilter(stream, filter2);
6512
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6513
EXPECT_REF(filter, 3);
6514
EXPECT_REF(filter2, 1);
6515
6516
/* Crashes on native. */
6517
if (0)
6518
{
6519
hr = IAMMediaStream_JoinFilter(stream, NULL);
6520
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6521
}
6522
6523
hr = IAMMultiMediaStream_GetFilter(mmstream, &filter3);
6524
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6525
ok(filter3 == filter, "Expected filter %p, got %p.\n", filter, filter3);
6526
EXPECT_REF(filter, 4);
6527
6528
IMediaStreamFilter_Release(filter3);
6529
EXPECT_REF(filter, 3);
6530
6531
ref = IMediaStreamFilter_Release(filter2);
6532
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6533
ref = IAMMediaStream_Release(stream);
6534
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6535
EXPECT_REF(filter, 3);
6536
ref = IAMMultiMediaStream_Release(mmstream);
6537
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6538
EXPECT_REF(filter, 1);
6539
ref = IMediaStreamFilter_Release(filter);
6540
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6541
}
6542
6543
static void test_ammediastream_join_filter(void)
6544
{
6545
check_ammediastream_join_filter(&CLSID_AMAudioStream);
6546
check_ammediastream_join_filter(&CLSID_AMDirectDrawStream);
6547
}
6548
6549
static void check_ammediastream_join_filter_graph(const MSPID *id)
6550
{
6551
IAMMultiMediaStream *mmstream = create_ammultimediastream();
6552
IGraphBuilder *builder, *builder2;
6553
IMediaStreamFilter *filter;
6554
IAMMediaStream *stream;
6555
IFilterGraph *graph;
6556
FILTER_INFO info;
6557
HRESULT hr;
6558
ULONG ref;
6559
6560
hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
6561
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6562
ok(!!filter, "Expected non-null filter.\n");
6563
6564
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, id, 0, (IMediaStream **)&stream);
6565
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6566
6567
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &builder);
6568
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6569
ok(!!builder, "Expected non-null graph.\n");
6570
EXPECT_REF(builder, 4);
6571
6572
hr = IMediaStreamFilter_QueryFilterInfo(filter, &info);
6573
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6574
ok(info.pGraph == (IFilterGraph *)builder, "Expected graph %p, got %p.\n", (IFilterGraph *)builder, info.pGraph);
6575
EXPECT_REF(builder, 5);
6576
IFilterGraph_Release(info.pGraph);
6577
EXPECT_REF(builder, 4);
6578
6579
hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, &IID_IFilterGraph, (void **)&graph);
6580
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6581
EXPECT_REF(builder, 4);
6582
EXPECT_REF(graph, 1);
6583
6584
/* Crashes on native. */
6585
if (0)
6586
{
6587
hr = IAMMediaStream_JoinFilterGraph(stream, NULL);
6588
ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
6589
}
6590
6591
hr = IAMMediaStream_JoinFilterGraph(stream, graph);
6592
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6593
EXPECT_REF(builder, 4);
6594
EXPECT_REF(graph, 1);
6595
6596
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &builder2);
6597
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6598
ok(builder2 == builder, "Expected graph %p, got %p.\n", builder, builder2);
6599
EXPECT_REF(builder, 5);
6600
EXPECT_REF(graph, 1);
6601
IGraphBuilder_Release(builder2);
6602
EXPECT_REF(builder, 4);
6603
EXPECT_REF(graph, 1);
6604
6605
hr = IMediaStreamFilter_QueryFilterInfo(filter, &info);
6606
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6607
ok(info.pGraph == (IFilterGraph *)builder, "Expected graph %p, got %p.\n", (IFilterGraph *)builder, info.pGraph);
6608
EXPECT_REF(builder, 5);
6609
EXPECT_REF(graph, 1);
6610
IFilterGraph_Release(info.pGraph);
6611
EXPECT_REF(builder, 4);
6612
EXPECT_REF(graph, 1);
6613
6614
ref = IFilterGraph_Release(graph);
6615
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6616
ref = IAMMultiMediaStream_Release(mmstream);
6617
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6618
ref = IGraphBuilder_Release(builder);
6619
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6620
ref = IMediaStreamFilter_Release(filter);
6621
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6622
ref = IAMMediaStream_Release(stream);
6623
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6624
}
6625
6626
static void test_ammediastream_join_filter_graph(void)
6627
{
6628
check_ammediastream_join_filter_graph(&MSPID_PrimaryAudio);
6629
check_ammediastream_join_filter_graph(&MSPID_PrimaryVideo);
6630
}
6631
6632
static void check_ammediastream_set_state(const MSPID *id)
6633
{
6634
IAMMultiMediaStream *mmstream = create_ammultimediastream();
6635
IAMMediaStream *am_stream;
6636
IMediaStream *stream;
6637
HRESULT hr;
6638
ULONG ref;
6639
6640
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
6641
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6642
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, id, 0, &stream);
6643
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6644
hr = IMediaStream_QueryInterface(stream, &IID_IAMMediaStream, (void **)&am_stream);
6645
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6646
6647
hr = IAMMediaStream_SetState(am_stream, 4);
6648
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6649
6650
hr = IAMMediaStream_SetState(am_stream, State_Running);
6651
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6652
6653
hr = IAMMediaStream_SetState(am_stream, State_Paused);
6654
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6655
6656
hr = IAMMediaStream_SetState(am_stream, State_Stopped);
6657
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6658
6659
ref = IAMMultiMediaStream_Release(mmstream);
6660
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6661
IAMMediaStream_Release(am_stream);
6662
ref = IMediaStream_Release(stream);
6663
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6664
}
6665
6666
static void test_ammediastream_set_state(void)
6667
{
6668
check_ammediastream_set_state(&MSPID_PrimaryAudio);
6669
check_ammediastream_set_state(&MSPID_PrimaryVideo);
6670
}
6671
6672
static void check_ammediastream_end_of_stream(const CLSID *clsid, const MSPID *id, const AM_MEDIA_TYPE *mt)
6673
{
6674
IAMMultiMediaStream *mmstream = create_ammultimediastream();
6675
IMediaStreamFilter *filter;
6676
struct testfilter source;
6677
IMediaStream *stream;
6678
struct graph graph;
6679
HRESULT hr;
6680
ULONG ref;
6681
IPin *pin;
6682
6683
graph_init(&graph);
6684
6685
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, (IGraphBuilder *)&graph.IFilterGraph2_iface);
6686
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6687
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, id, 0, &stream);
6688
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6689
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
6690
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6691
hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
6692
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6693
testfilter_init(&source);
6694
source.IMediaSeeking_iface.lpVtbl = &testsource_seeking_vtbl;
6695
hr = IFilterGraph2_AddFilter(&graph.IFilterGraph2_iface, &source.filter.IBaseFilter_iface, NULL);
6696
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6697
6698
hr = IFilterGraph2_ConnectDirect(&graph.IFilterGraph2_iface, &source.source.pin.IPin_iface, pin, mt);
6699
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6700
6701
hr = IMediaStreamFilter_SupportSeeking(filter, TRUE);
6702
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6703
6704
hr = IPin_EndOfStream(pin);
6705
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6706
6707
hr = IPin_EndOfStream(pin);
6708
ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
6709
6710
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
6711
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6712
6713
hr = IPin_EndOfStream(pin);
6714
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6715
6716
hr = IPin_EndOfStream(pin);
6717
ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
6718
6719
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
6720
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6721
6722
hr = IPin_EndOfStream(pin);
6723
ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
6724
6725
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
6726
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6727
6728
graph.got_notify = 0;
6729
graph.event_code = 0xcc;
6730
6731
hr = IPin_EndOfStream(pin);
6732
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6733
6734
ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
6735
ok(graph.event_code == EC_COMPLETE, "Got event code %ld.\n", graph.event_code);
6736
6737
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
6738
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6739
6740
IFilterGraph2_Disconnect(&graph.IFilterGraph2_iface, pin);
6741
IFilterGraph2_Disconnect(&graph.IFilterGraph2_iface, &source.source.pin.IPin_iface);
6742
6743
ref = IAMMultiMediaStream_Release(mmstream);
6744
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6745
graph_destroy(&graph);
6746
ref = IMediaStreamFilter_Release(filter);
6747
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6748
IPin_Release(pin);
6749
ref = IMediaStream_Release(stream);
6750
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6751
}
6752
6753
static void test_ammediastream_end_of_stream(void)
6754
{
6755
check_ammediastream_end_of_stream(&CLSID_AMAudioStream, &MSPID_PrimaryAudio, &audio_mt);
6756
check_ammediastream_end_of_stream(&CLSID_AMDirectDrawStream, &MSPID_PrimaryVideo, &rgb32_mt);
6757
}
6758
6759
void test_mediastreamfilter_get_state(void)
6760
{
6761
IAMMultiMediaStream *mmstream = create_ammultimediastream();
6762
IMediaStreamFilter *filter;
6763
FILTER_STATE state;
6764
HRESULT hr;
6765
ULONG ref;
6766
6767
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
6768
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6769
hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
6770
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6771
ok(!!filter, "Expected non-null filter.\n");
6772
6773
/* Crashes on native. */
6774
if (0)
6775
{
6776
hr = IMediaStreamFilter_GetState(filter, 0, NULL);
6777
ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
6778
}
6779
6780
state = 0xcc;
6781
hr = IMediaStreamFilter_GetState(filter, 0, &state);
6782
ok(state == State_Stopped, "Got state %#x.\n", state);
6783
6784
ref = IAMMultiMediaStream_Release(mmstream);
6785
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6786
ref = IMediaStreamFilter_Release(filter);
6787
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6788
}
6789
6790
void check_mediastreamfilter_state(FILTER_STATE expected_state, HRESULT (*set_state)(IMediaStreamFilter *),
6791
HRESULT (*reset_state)(IMediaStreamFilter *))
6792
{
6793
IAMMultiMediaStream *mmstream = create_ammultimediastream();
6794
struct teststream teststream, teststream2;
6795
IMediaStreamFilter *filter;
6796
FILTER_STATE state;
6797
HRESULT hr;
6798
ULONG ref;
6799
6800
teststream_init(&teststream);
6801
teststream_init(&teststream2);
6802
6803
teststream2.mspid.Data2 = 1;
6804
6805
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
6806
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6807
hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)&teststream, &teststream.mspid, 0, NULL);
6808
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6809
hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)&teststream2, &teststream2.mspid, 0, NULL);
6810
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6811
hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
6812
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6813
ok(filter != NULL, "Expected non-null filter\n");
6814
6815
hr = reset_state(filter);
6816
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6817
6818
teststream.state = 0xcc;
6819
teststream2.state = 0xcc;
6820
hr = set_state(filter);
6821
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6822
ok(teststream.state == expected_state, "Got state %#x.\n", teststream.state);
6823
ok(teststream2.state == expected_state, "Got state %#x.\n", teststream2.state);
6824
hr = IMediaStreamFilter_GetState(filter, 0, &state);
6825
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6826
ok(state == expected_state, "Got state %#x.\n", state);
6827
6828
teststream.state = 0xcc;
6829
teststream2.state = 0xcc;
6830
hr = set_state(filter);
6831
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6832
ok(teststream.state == 0xcc, "Got state %#x.\n", teststream.state);
6833
ok(teststream2.state == 0xcc, "Got state %#x.\n", teststream2.state);
6834
6835
hr = reset_state(filter);
6836
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6837
6838
teststream.set_state_result = E_FAIL;
6839
teststream.state = 0xcc;
6840
teststream2.state = 0xcc;
6841
hr = set_state(filter);
6842
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6843
ok(teststream.state == 0xcc, "Got state %#x.\n", teststream.state);
6844
ok(teststream2.state == expected_state, "Got state %#x.\n", teststream2.state);
6845
hr = IMediaStreamFilter_GetState(filter, 0, &state);
6846
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6847
ok(state == expected_state, "Got state %#x.\n", state);
6848
6849
hr = reset_state(filter);
6850
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6851
6852
teststream.set_state_result = E_FAIL;
6853
teststream2.set_state_result = E_FAIL;
6854
teststream.state = 0xcc;
6855
teststream2.state = 0xcc;
6856
hr = set_state(filter);
6857
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6858
ok(teststream.state == 0xcc, "Got state %#x.\n", teststream.state);
6859
ok(teststream2.state == 0xcc, "Got state %#x.\n", teststream2.state);
6860
hr = IMediaStreamFilter_GetState(filter, 0, &state);
6861
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6862
ok(state == expected_state, "Got state %#x.\n", state);
6863
6864
ref = IAMMultiMediaStream_Release(mmstream);
6865
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6866
ref = IMediaStreamFilter_Release(filter);
6867
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6868
ok(teststream.refcount == 1, "Got outstanding refcount %ld.\n", teststream.refcount);
6869
ok(teststream2.refcount == 1, "Got outstanding refcount %ld.\n", teststream2.refcount);
6870
}
6871
6872
static HRESULT mediastreamfilter_stop(IMediaStreamFilter *filter)
6873
{
6874
return IMediaStreamFilter_Stop(filter);
6875
}
6876
6877
static HRESULT mediastreamfilter_pause(IMediaStreamFilter *filter)
6878
{
6879
return IMediaStreamFilter_Pause(filter);
6880
}
6881
6882
static HRESULT mediastreamfilter_run(IMediaStreamFilter *filter)
6883
{
6884
return IMediaStreamFilter_Run(filter, 0);
6885
}
6886
6887
void test_mediastreamfilter_stop_pause_run(void)
6888
{
6889
check_mediastreamfilter_state(State_Stopped, mediastreamfilter_stop, mediastreamfilter_run);
6890
check_mediastreamfilter_state(State_Paused, mediastreamfilter_pause, mediastreamfilter_stop);
6891
check_mediastreamfilter_state(State_Running, mediastreamfilter_run, mediastreamfilter_stop);
6892
}
6893
6894
static void test_mediastreamfilter_support_seeking(void)
6895
{
6896
IAMMultiMediaStream *mmstream = create_ammultimediastream();
6897
static const MSPID mspid1 = {0x88888888, 1};
6898
static const MSPID mspid2 = {0x88888888, 2};
6899
static const MSPID mspid3 = {0x88888888, 3};
6900
struct testfilter source1, source2, source3;
6901
IAMMediaStream *stream1, *stream2, *stream3;
6902
IMediaStreamFilter *filter;
6903
IPin *pin1, *pin2, *pin3;
6904
ULONG ref, seeking_ref;
6905
IGraphBuilder *graph;
6906
HRESULT hr;
6907
6908
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
6909
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6910
hr = CoCreateInstance(&CLSID_AMAudioStream, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream1);
6911
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6912
hr = CoCreateInstance(&CLSID_AMAudioStream, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream2);
6913
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6914
hr = CoCreateInstance(&CLSID_AMAudioStream, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream3);
6915
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6916
hr = IAMMediaStream_Initialize(stream1, NULL, 0, &mspid1, STREAMTYPE_READ);
6917
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6918
hr = IAMMediaStream_Initialize(stream2, NULL, 0, &mspid2, STREAMTYPE_READ);
6919
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6920
hr = IAMMediaStream_Initialize(stream3, NULL, 0, &mspid3, STREAMTYPE_READ);
6921
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6922
hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)stream1, &mspid1, 0, NULL);
6923
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6924
hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)stream2, &mspid2, 0, NULL);
6925
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6926
hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)stream3, &mspid3, 0, NULL);
6927
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6928
hr = IAMMediaStream_QueryInterface(stream1, &IID_IPin, (void **)&pin1);
6929
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6930
hr = IAMMediaStream_QueryInterface(stream2, &IID_IPin, (void **)&pin2);
6931
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6932
hr = IAMMediaStream_QueryInterface(stream3, &IID_IPin, (void **)&pin3);
6933
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6934
hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
6935
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6936
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
6937
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6938
ok(graph != NULL, "Expected non-NULL graph.\n");
6939
testfilter_init(&source1);
6940
testfilter_init(&source2);
6941
testfilter_init(&source3);
6942
source2.IMediaSeeking_iface.lpVtbl = &testsource_seeking_vtbl;
6943
source3.IMediaSeeking_iface.lpVtbl = &testsource_seeking_vtbl;
6944
hr = IGraphBuilder_AddFilter(graph, &source1.filter.IBaseFilter_iface, NULL);
6945
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6946
hr = IGraphBuilder_AddFilter(graph, &source2.filter.IBaseFilter_iface, NULL);
6947
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6948
hr = IGraphBuilder_AddFilter(graph, &source3.filter.IBaseFilter_iface, NULL);
6949
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6950
6951
hr = IMediaStreamFilter_SupportSeeking(filter, TRUE);
6952
ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
6953
6954
hr = IGraphBuilder_ConnectDirect(graph, &source1.source.pin.IPin_iface, pin1, &audio_mt);
6955
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6956
6957
source2.get_duration_hr = E_FAIL;
6958
6959
hr = IMediaStreamFilter_SupportSeeking(filter, TRUE);
6960
ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
6961
6962
hr = IGraphBuilder_ConnectDirect(graph, &source2.source.pin.IPin_iface, pin2, &audio_mt);
6963
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6964
6965
hr = IMediaStreamFilter_SupportSeeking(filter, TRUE);
6966
ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
6967
6968
hr = IGraphBuilder_ConnectDirect(graph, &source3.source.pin.IPin_iface, pin3, &audio_mt);
6969
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6970
6971
check_interface(filter, &IID_IMediaSeeking, FALSE);
6972
6973
seeking_ref = get_refcount(&source3.IMediaSeeking_iface);
6974
6975
hr = IMediaStreamFilter_SupportSeeking(filter, TRUE);
6976
ok(hr == S_OK, "Got hr %#lx.\n", hr);
6977
6978
check_interface(filter, &IID_IMediaSeeking, TRUE);
6979
6980
ref = get_refcount(&source3.IMediaSeeking_iface);
6981
ok(ref == seeking_ref, "Expected outstanding refcount %ld, got %ld.\n", seeking_ref, ref);
6982
6983
hr = IMediaStreamFilter_SupportSeeking(filter, TRUE);
6984
ok(hr == HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED), "Got hr %#lx.\n", hr);
6985
6986
IGraphBuilder_Disconnect(graph, pin1);
6987
IGraphBuilder_Disconnect(graph, &source1.source.pin.IPin_iface);
6988
6989
IGraphBuilder_Disconnect(graph, pin2);
6990
IGraphBuilder_Disconnect(graph, &source2.source.pin.IPin_iface);
6991
6992
IGraphBuilder_Disconnect(graph, pin3);
6993
IGraphBuilder_Disconnect(graph, &source3.source.pin.IPin_iface);
6994
6995
ref = IAMMultiMediaStream_Release(mmstream);
6996
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6997
ref = IGraphBuilder_Release(graph);
6998
ok(!ref, "Got outstanding refcount %ld.\n", ref);
6999
ref = IMediaStreamFilter_Release(filter);
7000
ok(!ref, "Got outstanding refcount %ld.\n", ref);
7001
IPin_Release(pin1);
7002
ref = IAMMediaStream_Release(stream1);
7003
ok(!ref, "Got outstanding refcount %ld.\n", ref);
7004
IPin_Release(pin2);
7005
ref = IAMMediaStream_Release(stream2);
7006
ok(!ref, "Got outstanding refcount %ld.\n", ref);
7007
IPin_Release(pin3);
7008
ref = IAMMediaStream_Release(stream3);
7009
ok(!ref, "Got outstanding refcount %ld.\n", ref);
7010
}
7011
7012
static void check_mediastreamfilter_seeking(void (*check)(IMediaSeeking *seeking, struct testfilter *source1,
7013
struct testfilter *source2, struct testfilter *source3, HRESULT source2_hr, HRESULT expected_hr))
7014
{
7015
IAMMultiMediaStream *mmstream = create_ammultimediastream();
7016
static const MSPID mspid1 = {0x88888888, 1};
7017
static const MSPID mspid2 = {0x88888888, 2};
7018
static const MSPID mspid3 = {0x88888888, 3};
7019
IMediaStreamFilter *filter;
7020
struct testfilter source1;
7021
struct testfilter source2;
7022
struct testfilter source3;
7023
IAMMediaStream *stream1;
7024
IAMMediaStream *stream2;
7025
IAMMediaStream *stream3;
7026
IMediaSeeking *seeking;
7027
IGraphBuilder *graph;
7028
IPin *pin1;
7029
IPin *pin2;
7030
IPin *pin3;
7031
HRESULT hr;
7032
ULONG ref;
7033
7034
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
7035
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7036
hr = CoCreateInstance(&CLSID_AMAudioStream, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream1);
7037
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7038
hr = CoCreateInstance(&CLSID_AMAudioStream, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream2);
7039
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7040
hr = CoCreateInstance(&CLSID_AMAudioStream, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream3);
7041
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7042
hr = IAMMediaStream_Initialize(stream1, NULL, 0, &mspid1, STREAMTYPE_READ);
7043
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7044
hr = IAMMediaStream_Initialize(stream2, NULL, 0, &mspid2, STREAMTYPE_READ);
7045
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7046
hr = IAMMediaStream_Initialize(stream3, NULL, 0, &mspid3, STREAMTYPE_READ);
7047
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7048
hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)stream1, &mspid1, 0, NULL);
7049
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7050
hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)stream2, &mspid2, 0, NULL);
7051
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7052
hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)stream3, &mspid3, 0, NULL);
7053
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7054
hr = IAMMediaStream_QueryInterface(stream1, &IID_IPin, (void **)&pin1);
7055
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7056
hr = IAMMediaStream_QueryInterface(stream2, &IID_IPin, (void **)&pin2);
7057
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7058
hr = IAMMediaStream_QueryInterface(stream3, &IID_IPin, (void **)&pin3);
7059
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7060
hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
7061
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7062
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
7063
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7064
ok(graph != NULL, "Expected non-NULL graph.\n");
7065
testfilter_init(&source1);
7066
testfilter_init(&source2);
7067
testfilter_init(&source3);
7068
source1.IMediaSeeking_iface.lpVtbl = &testsource_seeking_vtbl;
7069
source2.IMediaSeeking_iface.lpVtbl = &testsource_seeking_vtbl;
7070
source3.IMediaSeeking_iface.lpVtbl = &testsource_seeking_vtbl;
7071
hr = IGraphBuilder_AddFilter(graph, &source1.filter.IBaseFilter_iface, NULL);
7072
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7073
hr = IGraphBuilder_AddFilter(graph, &source2.filter.IBaseFilter_iface, NULL);
7074
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7075
hr = IGraphBuilder_AddFilter(graph, &source3.filter.IBaseFilter_iface, NULL);
7076
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7077
7078
hr = IGraphBuilder_ConnectDirect(graph, &source2.source.pin.IPin_iface, pin2, &audio_mt);
7079
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7080
hr = IGraphBuilder_ConnectDirect(graph, &source3.source.pin.IPin_iface, pin3, &audio_mt);
7081
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7082
7083
hr = IMediaStreamFilter_SupportSeeking(filter, TRUE);
7084
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7085
7086
hr = IGraphBuilder_ConnectDirect(graph, &source1.source.pin.IPin_iface, pin1, &audio_mt);
7087
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7088
7089
hr = IMediaStreamFilter_QueryInterface(filter, &IID_IMediaSeeking, (void **)&seeking);
7090
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7091
7092
check(seeking, &source1, &source2, &source3, S_OK, S_OK);
7093
check(seeking, &source1, &source2, &source3, E_FAIL, E_FAIL);
7094
check(seeking, &source1, &source2, &source3, E_NOTIMPL, E_NOTIMPL);
7095
7096
source2.IMediaSeeking_iface.lpVtbl = NULL;
7097
7098
check(seeking, &source1, &source2, &source3, S_OK, E_NOTIMPL);
7099
7100
source2.IMediaSeeking_iface.lpVtbl = &testsource_seeking_vtbl;
7101
7102
IGraphBuilder_Disconnect(graph, pin2);
7103
IGraphBuilder_Disconnect(graph, &source2.source.pin.IPin_iface);
7104
7105
check(seeking, &source1, &source2, &source3, S_OK, E_NOTIMPL);
7106
7107
IGraphBuilder_Disconnect(graph, pin2);
7108
IGraphBuilder_Disconnect(graph, &source2.source.pin.IPin_iface);
7109
IGraphBuilder_Disconnect(graph, pin3);
7110
IGraphBuilder_Disconnect(graph, &source3.source.pin.IPin_iface);
7111
7112
ref = IAMMultiMediaStream_Release(mmstream);
7113
ok(!ref, "Got outstanding refcount %ld.\n", ref);
7114
ref = IGraphBuilder_Release(graph);
7115
ok(!ref, "Got outstanding refcount %ld.\n", ref);
7116
IMediaSeeking_Release(seeking);
7117
ref = IMediaStreamFilter_Release(filter);
7118
ok(!ref, "Got outstanding refcount %ld.\n", ref);
7119
IPin_Release(pin1);
7120
ref = IAMMediaStream_Release(stream1);
7121
ok(!ref, "Got outstanding refcount %ld.\n", ref);
7122
IPin_Release(pin2);
7123
ref = IAMMediaStream_Release(stream2);
7124
ok(!ref, "Got outstanding refcount %ld.\n", ref);
7125
IPin_Release(pin3);
7126
ref = IAMMediaStream_Release(stream3);
7127
ok(!ref, "Got outstanding refcount %ld.\n", ref);
7128
}
7129
7130
static void check_mediastreamfilter_set_positions(IMediaSeeking *seeking, struct testfilter *source1,
7131
struct testfilter *source2, struct testfilter *source3, HRESULT source2_hr, HRESULT expected_hr)
7132
{
7133
LONGLONG current_position = 12345678;
7134
LONGLONG stop_position = 87654321;
7135
HRESULT hr;
7136
7137
source2->set_positions_hr = source2_hr;
7138
source1->current_position = 0xdeadbeefdeadbeefULL;
7139
source1->stop_position = 0xdeadbeefdeadbeefULL;
7140
source2->current_position = 0xdeadbeefdeadbeefULL;
7141
source2->stop_position = 0xdeadbeefdeadbeefULL;
7142
source3->current_position = 0xdeadbeefdeadbeefULL;
7143
source3->stop_position = 0xdeadbeefdeadbeefULL;
7144
hr = IMediaSeeking_SetPositions(seeking, &current_position, AM_SEEKING_AbsolutePositioning,
7145
&stop_position, AM_SEEKING_AbsolutePositioning);
7146
ok(hr == expected_hr, "Got hr %#lx.\n", hr);
7147
ok(source1->current_position == 0xdeadbeefdeadbeefULL, "Got current position %s.\n",
7148
wine_dbgstr_longlong(source1->current_position));
7149
ok(source1->stop_position == 0xdeadbeefdeadbeefULL, "Got stop position %s.\n",
7150
wine_dbgstr_longlong(source1->stop_position));
7151
if (SUCCEEDED(expected_hr))
7152
{
7153
ok(source2->current_position == 12345678, "Got current position %s.\n",
7154
wine_dbgstr_longlong(source2->current_position));
7155
ok(source2->stop_position == 87654321, "Got stop position %s.\n",
7156
wine_dbgstr_longlong(source2->stop_position));
7157
}
7158
ok(source3->current_position == 0xdeadbeefdeadbeefULL, "Got current position %s.\n",
7159
wine_dbgstr_longlong(source3->current_position));
7160
ok(source3->stop_position == 0xdeadbeefdeadbeefULL, "Got stop position %s.\n",
7161
wine_dbgstr_longlong(source3->stop_position));
7162
}
7163
7164
static void check_mediastreamfilter_get_duration(IMediaSeeking *seeking, struct testfilter *source1,
7165
struct testfilter *source2, struct testfilter *source3, HRESULT source2_hr, HRESULT expected_hr)
7166
{
7167
LONGLONG duration = 0xdeadbeefdeadbeefULL;
7168
HRESULT hr;
7169
7170
source2->get_duration_hr = source2_hr;
7171
hr = IMediaSeeking_GetDuration(seeking, &duration);
7172
ok(hr == expected_hr, "Got hr %#lx.\n", hr);
7173
if (SUCCEEDED(expected_hr))
7174
ok(duration == 0x8000000000000000ULL, "Got duration %s.\n", wine_dbgstr_longlong(duration));
7175
else
7176
ok(duration == 0xdeadbeefdeadbeefULL, "Got duration %s.\n", wine_dbgstr_longlong(duration));
7177
}
7178
7179
static void check_mediastreamfilter_get_stop_position(IMediaSeeking *seeking, struct testfilter *source1,
7180
struct testfilter *source2, struct testfilter *source3, HRESULT source2_hr, HRESULT expected_hr)
7181
{
7182
LONGLONG stop = 0xdeadbeefdeadbeefULL;
7183
HRESULT hr;
7184
7185
source2->get_stop_position_hr = source2_hr;
7186
hr = IMediaSeeking_GetStopPosition(seeking, &stop);
7187
ok(hr == expected_hr, "Got hr %#lx.\n", hr);
7188
if (SUCCEEDED(expected_hr))
7189
ok(stop == 0x8000000000000000ULL, "Got stop position %s.\n", wine_dbgstr_longlong(stop));
7190
else
7191
ok(stop == 0xdeadbeefdeadbeefULL, "Got stop position %s.\n", wine_dbgstr_longlong(stop));
7192
}
7193
7194
static void check_mediastreamfilter_is_format_supported(IMediaSeeking *seeking, struct testfilter *source1,
7195
struct testfilter *source2, struct testfilter *source3, HRESULT source2_hr, HRESULT expected_hr)
7196
{
7197
HRESULT hr;
7198
7199
source2->is_format_supported_hr = source2_hr;
7200
hr = IMediaSeeking_IsFormatSupported(seeking, &TIME_FORMAT_MEDIA_TIME);
7201
ok(hr == expected_hr, "Got hr %#lx.\n", hr);
7202
}
7203
7204
static void test_mediastreamfilter_seeking(void)
7205
{
7206
check_mediastreamfilter_seeking(check_mediastreamfilter_set_positions);
7207
check_mediastreamfilter_seeking(check_mediastreamfilter_get_duration);
7208
check_mediastreamfilter_seeking(check_mediastreamfilter_get_stop_position);
7209
check_mediastreamfilter_seeking(check_mediastreamfilter_is_format_supported);
7210
}
7211
7212
static void test_mediastreamfilter_get_current_stream_time(void)
7213
{
7214
IAMMultiMediaStream *mmstream = create_ammultimediastream();
7215
STREAM_TIME filter_start_time;
7216
IMediaStreamFilter *filter;
7217
IMediaFilter *media_filter;
7218
struct testclock clock;
7219
IGraphBuilder *graph;
7220
STREAM_TIME time;
7221
HRESULT hr;
7222
ULONG ref;
7223
7224
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
7225
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7226
hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
7227
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7228
ok(!!filter, "Expected non-null filter.\n");
7229
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, NULL);
7230
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7231
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
7232
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7233
ok(graph != NULL, "Expected non-NULL graph.\n");
7234
hr = IGraphBuilder_QueryInterface(graph, &IID_IMediaFilter, (void **)&media_filter);
7235
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7236
testclock_init(&clock);
7237
7238
/* Crashes on native. */
7239
if (0)
7240
{
7241
hr = IMediaStreamFilter_GetCurrentStreamTime(filter, NULL);
7242
ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
7243
hr = IAMMultiMediaStream_GetTime(mmstream, NULL);
7244
ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
7245
}
7246
7247
time = 0xdeadbeefdeadbeef;
7248
hr = IMediaStreamFilter_GetCurrentStreamTime(filter, &time);
7249
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
7250
ok(time == 0, "Got time %s.\n", wine_dbgstr_longlong(time));
7251
time = 0xdeadbeefdeadbeef;
7252
hr = IAMMultiMediaStream_GetTime(mmstream, &time);
7253
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
7254
ok(time == 0, "Got time %s.\n", wine_dbgstr_longlong(time));
7255
7256
hr = IMediaFilter_SetSyncSource(media_filter, &clock.IReferenceClock_iface);
7257
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7258
7259
clock.get_time_hr = E_FAIL;
7260
7261
time = 0xdeadbeefdeadbeef;
7262
hr = IMediaStreamFilter_GetCurrentStreamTime(filter, &time);
7263
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
7264
ok(time == 0, "Got time %s.\n", wine_dbgstr_longlong(time));
7265
time = 0xdeadbeefdeadbeef;
7266
hr = IAMMultiMediaStream_GetTime(mmstream, &time);
7267
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
7268
ok(time == 0, "Got time %s.\n", wine_dbgstr_longlong(time));
7269
7270
clock.time = 23456789;
7271
clock.get_time_hr = S_OK;
7272
7273
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
7274
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7275
7276
hr = IMediaStreamFilter_GetCurrentStreamTime(filter, &filter_start_time);
7277
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7278
7279
clock.time = 34567890;
7280
7281
time = 0xdeadbeefdeadbeef;
7282
hr = IMediaStreamFilter_GetCurrentStreamTime(filter, &time);
7283
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7284
ok(time == 11111101 + filter_start_time, "Got time %s.\n", wine_dbgstr_longlong(time));
7285
time = 0xdeadbeefdeadbeef;
7286
hr = IAMMultiMediaStream_GetTime(mmstream, &time);
7287
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7288
ok(time == 11111101 + filter_start_time, "Got time %s.\n", wine_dbgstr_longlong(time));
7289
7290
ref = IAMMultiMediaStream_Release(mmstream);
7291
ok(!ref, "Got outstanding refcount %ld.\n", ref);
7292
IMediaFilter_Release(media_filter);
7293
ref = IGraphBuilder_Release(graph);
7294
ok(!ref, "Got outstanding refcount %ld.\n", ref);
7295
ref = IMediaStreamFilter_Release(filter);
7296
ok(!ref, "Got outstanding refcount %ld.\n", ref);
7297
}
7298
7299
static void test_mediastreamfilter_reference_time_to_stream_time(void)
7300
{
7301
IMediaStreamFilter *filter;
7302
struct testclock clock;
7303
REFERENCE_TIME time;
7304
HRESULT hr;
7305
ULONG ref;
7306
7307
hr = CoCreateInstance(&CLSID_MediaStreamFilter, NULL, CLSCTX_INPROC_SERVER,
7308
&IID_IMediaStreamFilter, (void **)&filter);
7309
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7310
testclock_init(&clock);
7311
7312
hr = IMediaStreamFilter_ReferenceTimeToStreamTime(filter, NULL);
7313
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
7314
7315
time = 0xdeadbeefdeadbeef;
7316
hr = IMediaStreamFilter_ReferenceTimeToStreamTime(filter, &time);
7317
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
7318
ok(time == 0xdeadbeefdeadbeef, "Got time %s.\n", wine_dbgstr_longlong(time));
7319
7320
hr = IMediaStreamFilter_SetSyncSource(filter, &clock.IReferenceClock_iface);
7321
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7322
7323
clock.get_time_hr = E_FAIL;
7324
7325
/* Crashes on native. */
7326
if (0)
7327
{
7328
hr = IMediaStreamFilter_ReferenceTimeToStreamTime(filter, NULL);
7329
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
7330
}
7331
7332
time = 0xdeadbeefdeadbeef;
7333
hr = IMediaStreamFilter_ReferenceTimeToStreamTime(filter, &time);
7334
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7335
ok(time == 0xdeadbeefdeadbeef, "Got time %s.\n", wine_dbgstr_longlong(time));
7336
7337
hr = IMediaStreamFilter_Run(filter, 23456789);
7338
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7339
7340
time = 0xdeadbeefdeadbeef;
7341
hr = IMediaStreamFilter_ReferenceTimeToStreamTime(filter, &time);
7342
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7343
ok(time == 0xdeadbeefdd47d2da, "Got time %s.\n", wine_dbgstr_longlong(time));
7344
7345
clock.time = 34567890;
7346
clock.get_time_hr = S_OK;
7347
7348
time = 0xdeadbeefdeadbeef;
7349
hr = IMediaStreamFilter_ReferenceTimeToStreamTime(filter, &time);
7350
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7351
ok(time == 0xdeadbeefdd47d2da, "Got time %s.\n", wine_dbgstr_longlong(time));
7352
7353
ref = IMediaStreamFilter_Release(filter);
7354
ok(!ref, "Got outstanding refcount %ld.\n", ref);
7355
}
7356
7357
struct mediastreamfilter_wait_until_params
7358
{
7359
IMediaStreamFilter *filter;
7360
REFERENCE_TIME time;
7361
HRESULT expected_hr;
7362
};
7363
7364
static DWORD CALLBACK mediastreamfilter_wait_until(void *p)
7365
{
7366
struct mediastreamfilter_wait_until_params *params = (struct mediastreamfilter_wait_until_params *)p;
7367
HRESULT hr;
7368
7369
hr = IMediaStreamFilter_WaitUntil(params->filter, params->time);
7370
ok(hr == params->expected_hr, "Got hr %#lx.\n", hr);
7371
7372
return 0;
7373
}
7374
7375
static void test_mediastreamfilter_wait_until(void)
7376
{
7377
struct mediastreamfilter_wait_until_params params1;
7378
struct mediastreamfilter_wait_until_params params2;
7379
struct advise_time_cookie cookie1 = { 0 };
7380
struct advise_time_cookie cookie2 = { 0 };
7381
IMediaStreamFilter *filter;
7382
struct testclock clock;
7383
HANDLE thread1;
7384
HANDLE thread2;
7385
HRESULT hr;
7386
ULONG ref;
7387
7388
hr = CoCreateInstance(&CLSID_MediaStreamFilter, NULL, CLSCTX_INPROC_SERVER,
7389
&IID_IMediaStreamFilter, (void **)&filter);
7390
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7391
testclock_init(&clock);
7392
cookie1.advise_time_called_event = CreateEventW(NULL, FALSE, FALSE, NULL);
7393
cookie2.advise_time_called_event = CreateEventW(NULL, FALSE, FALSE, NULL);
7394
7395
hr = IMediaStreamFilter_Run(filter, 12345678);
7396
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7397
7398
hr = IMediaStreamFilter_WaitUntil(filter, 23456789);
7399
ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
7400
7401
hr = IMediaStreamFilter_Stop(filter);
7402
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7403
7404
hr = IMediaStreamFilter_SetSyncSource(filter, &clock.IReferenceClock_iface);
7405
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7406
7407
clock.advise_time_cookie = &cookie1;
7408
7409
params1.filter = filter;
7410
params1.time = 23456789;
7411
params1.expected_hr = S_OK;
7412
thread1 = CreateThread(NULL, 0, mediastreamfilter_wait_until, &params1, 0, NULL);
7413
ok(!WaitForSingleObject(cookie1.advise_time_called_event, 2000), "Expected AdviseTime to be called.\n");
7414
ok(WaitForSingleObject(thread1, 100) == WAIT_TIMEOUT, "WaitUntil returned prematurely.\n");
7415
7416
ok(cookie1.base == 23456789, "Got base %s.\n", wine_dbgstr_longlong(cookie1.base));
7417
ok(cookie1.offset == 12345678, "Got offset %s.\n", wine_dbgstr_longlong(cookie1.offset));
7418
ok(!!cookie1.event, "Expected non-NULL event.\n");
7419
7420
SetEvent(cookie1.event);
7421
7422
ok(!WaitForSingleObject(thread1, 2000), "Wait timed out.\n");
7423
CloseHandle(thread1);
7424
7425
ok(!cookie1.unadvise_called, "Unexpected Unadvise call.\n");
7426
7427
hr = IMediaStreamFilter_Run(filter, 12345678);
7428
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7429
7430
clock.time = 30000000;
7431
7432
clock.advise_time_cookie = &cookie1;
7433
7434
params1.filter = filter;
7435
params1.time = 23456789;
7436
params1.expected_hr = S_OK;
7437
thread1 = CreateThread(NULL, 0, mediastreamfilter_wait_until, &params1, 0, NULL);
7438
ok(!WaitForSingleObject(cookie1.advise_time_called_event, 2000), "Expected AdviseTime to be called.\n");
7439
ok(WaitForSingleObject(thread1, 100) == WAIT_TIMEOUT, "WaitUntil returned prematurely.\n");
7440
7441
ok(cookie1.base == 23456789, "Got base %s.\n", wine_dbgstr_longlong(cookie1.base));
7442
ok(cookie1.offset == 12345678, "Got offset %s.\n", wine_dbgstr_longlong(cookie1.offset));
7443
ok(!!cookie1.event, "Expected non-NULL event.\n");
7444
7445
clock.advise_time_cookie = &cookie2;
7446
7447
params2.filter = filter;
7448
params2.time = 11111111;
7449
params2.expected_hr = S_OK;
7450
thread2 = CreateThread(NULL, 0, mediastreamfilter_wait_until, &params2, 0, NULL);
7451
ok(!WaitForSingleObject(cookie2.advise_time_called_event, 2000), "Expected AdviseTime to be called.\n");
7452
ok(WaitForSingleObject(thread2, 100) == WAIT_TIMEOUT, "WaitUntil returned prematurely.\n");
7453
7454
ok(cookie2.base == 11111111, "Got base %s.\n", wine_dbgstr_longlong(cookie2.base));
7455
ok(cookie2.offset == 12345678, "Got offset %s.\n", wine_dbgstr_longlong(cookie2.offset));
7456
ok(!!cookie2.event, "Expected non-NULL event.\n");
7457
7458
SetEvent(cookie1.event);
7459
7460
ok(!WaitForSingleObject(thread1, 2000), "Wait timed out.\n");
7461
CloseHandle(thread1);
7462
7463
ok(WaitForSingleObject(thread2, 100) == WAIT_TIMEOUT, "WaitUntil returned prematurely.\n");
7464
7465
SetEvent(cookie2.event);
7466
7467
ok(!WaitForSingleObject(thread2, 2000), "Wait timed out.\n");
7468
CloseHandle(thread2);
7469
7470
clock.advise_time_cookie = &cookie1;
7471
7472
params1.filter = filter;
7473
params1.time = 23456789;
7474
params1.expected_hr = S_FALSE;
7475
thread1 = CreateThread(NULL, 0, mediastreamfilter_wait_until, &params1, 0, NULL);
7476
ok(!WaitForSingleObject(cookie1.advise_time_called_event, 2000), "Expected AdviseTime to be called.\n");
7477
ok(WaitForSingleObject(thread1, 100) == WAIT_TIMEOUT, "WaitUntil returned prematurely.\n");
7478
7479
clock.advise_time_cookie = &cookie2;
7480
7481
params2.filter = filter;
7482
params2.time = 23456789;
7483
params2.expected_hr = S_FALSE;
7484
thread2 = CreateThread(NULL, 0, mediastreamfilter_wait_until, &params2, 0, NULL);
7485
ok(!WaitForSingleObject(cookie2.advise_time_called_event, 2000), "Expected AdviseTime to be called.\n");
7486
ok(WaitForSingleObject(thread2, 100) == WAIT_TIMEOUT, "WaitUntil returned prematurely.\n");
7487
7488
hr = IMediaStreamFilter_Flush(filter, FALSE);
7489
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7490
7491
ok(cookie1.unadvise_called, "Expected Unadvise to be called.\n");
7492
ok(cookie2.unadvise_called, "Expected Unadvise to be called.\n");
7493
7494
ok(!WaitForSingleObject(thread1, 2000), "Wait timed out.\n");
7495
CloseHandle(thread1);
7496
ok(!WaitForSingleObject(thread2, 2000), "Wait timed out.\n");
7497
CloseHandle(thread2);
7498
7499
clock.advise_time_cookie = &cookie1;
7500
7501
params1.filter = filter;
7502
params1.time = 23456789;
7503
params1.expected_hr = S_FALSE;
7504
thread1 = CreateThread(NULL, 0, mediastreamfilter_wait_until, &params1, 0, NULL);
7505
ok(!WaitForSingleObject(cookie1.advise_time_called_event, 2000), "Expected AdviseTime to be called.\n");
7506
ok(WaitForSingleObject(thread1, 100) == WAIT_TIMEOUT, "WaitUntil returned prematurely.\n");
7507
7508
clock.advise_time_cookie = &cookie2;
7509
7510
params2.filter = filter;
7511
params2.time = 23456789;
7512
params2.expected_hr = S_FALSE;
7513
thread2 = CreateThread(NULL, 0, mediastreamfilter_wait_until, &params2, 0, NULL);
7514
ok(!WaitForSingleObject(cookie2.advise_time_called_event, 2000), "Expected AdviseTime to be called.\n");
7515
ok(WaitForSingleObject(thread2, 100) == WAIT_TIMEOUT, "WaitUntil returned prematurely.\n");
7516
7517
hr = IMediaStreamFilter_Stop(filter);
7518
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7519
7520
ok(cookie1.unadvise_called, "Expected Unadvise to be called.\n");
7521
ok(cookie2.unadvise_called, "Expected Unadvise to be called.\n");
7522
7523
ok(!WaitForSingleObject(thread1, 2000), "Wait timed out.\n");
7524
CloseHandle(thread1);
7525
ok(!WaitForSingleObject(thread2, 2000), "Wait timed out.\n");
7526
CloseHandle(thread2);
7527
7528
CloseHandle(cookie1.advise_time_called_event);
7529
CloseHandle(cookie2.advise_time_called_event);
7530
7531
ref = IMediaStreamFilter_Release(filter);
7532
ok(!ref, "Got outstanding refcount %ld.\n", ref);
7533
}
7534
7535
static void test_mediastreamfilter_end_of_stream(void)
7536
{
7537
IAMMultiMediaStream *mmstream = create_ammultimediastream();
7538
struct testfilter source1, source2;
7539
IMediaStream *stream1, *stream2;
7540
IMediaControl *media_control;
7541
IMediaStreamFilter *filter;
7542
struct graph graph;
7543
IPin *pin1, *pin2;
7544
HRESULT hr;
7545
ULONG ref;
7546
7547
graph_init(&graph);
7548
hr = IFilterGraph2_QueryInterface(&graph.IFilterGraph2_iface, &IID_IMediaControl, (void **)&media_control);
7549
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7550
7551
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, (IGraphBuilder *)&graph.IFilterGraph2_iface);
7552
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7553
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream1);
7554
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7555
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream2);
7556
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7557
hr = IMediaStream_QueryInterface(stream1, &IID_IPin, (void **)&pin1);
7558
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7559
hr = IMediaStream_QueryInterface(stream2, &IID_IPin, (void **)&pin2);
7560
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7561
hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
7562
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7563
ok(filter != NULL, "Expected non-null filter\n");
7564
testfilter_init(&source1);
7565
testfilter_init(&source2);
7566
hr = IFilterGraph2_AddFilter(&graph.IFilterGraph2_iface, &source1.filter.IBaseFilter_iface, NULL);
7567
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7568
hr = IFilterGraph2_AddFilter(&graph.IFilterGraph2_iface, &source2.filter.IBaseFilter_iface, NULL);
7569
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7570
7571
hr = IPin_Connect(&source1.source.pin.IPin_iface, pin1, &audio_mt);
7572
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7573
hr = IPin_Connect(&source2.source.pin.IPin_iface, pin2, &rgb32_mt);
7574
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7575
7576
/* Initially, EC_COMPLETE notifications are disabled. */
7577
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
7578
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7579
7580
graph.got_notify = 0;
7581
7582
hr = IMediaStreamFilter_EndOfStream(filter);
7583
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7584
hr = IMediaStreamFilter_EndOfStream(filter);
7585
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7586
7587
ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
7588
7589
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
7590
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7591
7592
/* Unsuccsessful call to SupportSeeking does not enable EC_COMPLETE notifications. */
7593
hr = IMediaStreamFilter_SupportSeeking(filter, TRUE);
7594
ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
7595
7596
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
7597
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7598
7599
graph.got_notify = 0;
7600
7601
hr = IMediaStreamFilter_EndOfStream(filter);
7602
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7603
hr = IMediaStreamFilter_EndOfStream(filter);
7604
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7605
7606
ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
7607
7608
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
7609
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7610
7611
/* Successful call to SupportSeeking enables EC_COMPLETE notifications. */
7612
source1.IMediaSeeking_iface.lpVtbl = &testsource_seeking_vtbl;
7613
7614
hr = IMediaStreamFilter_SupportSeeking(filter, TRUE);
7615
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7616
7617
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
7618
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7619
7620
graph.got_notify = 0;
7621
7622
hr = IMediaStreamFilter_EndOfStream(filter);
7623
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7624
7625
ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
7626
7627
hr = IMediaStreamFilter_EndOfStream(filter);
7628
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7629
7630
ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
7631
7632
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
7633
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7634
7635
/* EC_COMPLETE is sent on paused->running state transition
7636
* if EndOfStream has been called for all streams. */
7637
graph.got_notify = 0;
7638
7639
hr = IMediaStreamFilter_EndOfStream(filter);
7640
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7641
hr = IMediaStreamFilter_EndOfStream(filter);
7642
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7643
7644
ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
7645
7646
hr = IMediaControl_Pause(media_control);
7647
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7648
7649
ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
7650
7651
hr = IMediaControl_Run(media_control);
7652
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7653
7654
ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
7655
7656
hr = IMediaControl_Run(media_control);
7657
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7658
7659
ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
7660
7661
hr = IMediaControl_Stop(media_control);
7662
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7663
7664
/* EC_COMPLETE is sent on paused->running state transition
7665
* if EndOfStream has been called for all streams. */
7666
graph.got_notify = 0;
7667
7668
hr = IMediaStreamFilter_EndOfStream(filter);
7669
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7670
hr = IMediaStreamFilter_EndOfStream(filter);
7671
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7672
7673
ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
7674
7675
hr = IMediaControl_Pause(media_control);
7676
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7677
7678
ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
7679
7680
hr = IMediaControl_Run(media_control);
7681
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7682
7683
ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
7684
7685
hr = IMediaControl_Stop(media_control);
7686
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7687
7688
/* EndOfStream count is reset on paused->stopped state transition. */
7689
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
7690
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7691
7692
graph.got_notify = 0;
7693
7694
hr = IMediaStreamFilter_EndOfStream(filter);
7695
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7696
7697
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
7698
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7699
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
7700
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7701
7702
hr = IMediaStreamFilter_EndOfStream(filter);
7703
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7704
7705
ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
7706
7707
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
7708
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7709
7710
/* EOS count is not reset on running->paused state transition. */
7711
hr = IMediaControl_Run(media_control);
7712
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7713
7714
graph.got_notify = 0;
7715
7716
hr = IMediaStreamFilter_EndOfStream(filter);
7717
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7718
7719
hr = IMediaControl_Pause(media_control);
7720
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7721
hr = IMediaControl_Run(media_control);
7722
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7723
7724
hr = IMediaStreamFilter_EndOfStream(filter);
7725
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7726
7727
ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
7728
7729
hr = IMediaControl_Stop(media_control);
7730
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7731
7732
/* EndOfStream count is not reset when Stop() is called on an already stopped filter. */
7733
hr = IMediaStreamFilter_EndOfStream(filter);
7734
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7735
7736
hr = IMediaStreamFilter_Stop(filter);
7737
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7738
7739
hr = IMediaStreamFilter_EndOfStream(filter);
7740
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7741
7742
graph.got_notify = 0;
7743
7744
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
7745
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7746
7747
ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
7748
7749
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
7750
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7751
7752
/* Flush with cancel_eos=TRUE decrements EOS count. */
7753
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
7754
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7755
7756
graph.got_notify = 0;
7757
7758
hr = IMediaStreamFilter_EndOfStream(filter);
7759
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7760
7761
hr = IMediaStreamFilter_Flush(filter, TRUE);
7762
7763
hr = IMediaStreamFilter_EndOfStream(filter);
7764
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7765
7766
ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
7767
7768
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
7769
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7770
7771
/* Flush followed by EndOfStream causes another EC_COMPLETE to be sent. */
7772
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
7773
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7774
7775
graph.got_notify = 0;
7776
7777
hr = IMediaStreamFilter_EndOfStream(filter);
7778
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7779
hr = IMediaStreamFilter_EndOfStream(filter);
7780
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7781
7782
ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
7783
7784
hr = IMediaStreamFilter_Flush(filter, TRUE);
7785
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7786
7787
hr = IMediaStreamFilter_EndOfStream(filter);
7788
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7789
7790
ok(graph.got_notify == 2, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
7791
7792
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
7793
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7794
7795
/* Flush decrements EOS count event when it is 0. */
7796
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
7797
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7798
7799
graph.got_notify = 0;
7800
7801
hr = IMediaStreamFilter_Flush(filter, TRUE);
7802
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7803
7804
hr = IMediaStreamFilter_EndOfStream(filter);
7805
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7806
hr = IMediaStreamFilter_EndOfStream(filter);
7807
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7808
7809
ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
7810
7811
hr = IMediaStreamFilter_EndOfStream(filter);
7812
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7813
7814
ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
7815
7816
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
7817
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7818
7819
/* Flush with cancel_eos=FALSE does not decrement EOS count. */
7820
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
7821
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7822
7823
graph.got_notify = 0;
7824
7825
hr = IMediaStreamFilter_EndOfStream(filter);
7826
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7827
7828
hr = IMediaStreamFilter_Flush(filter, FALSE);
7829
7830
hr = IMediaStreamFilter_EndOfStream(filter);
7831
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7832
7833
ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
7834
7835
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
7836
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7837
7838
ref = IAMMultiMediaStream_Release(mmstream);
7839
ok(!ref, "Got outstanding refcount %ld.\n", ref);
7840
IMediaControl_Release(media_control);
7841
graph_destroy(&graph);
7842
ref = IMediaStreamFilter_Release(filter);
7843
ok(!ref, "Got outstanding refcount %ld.\n", ref);
7844
IPin_Release(pin1);
7845
ref = IMediaStream_Release(stream1);
7846
ok(!ref, "Got outstanding refcount %ld.\n", ref);
7847
IPin_Release(pin2);
7848
ref = IMediaStream_Release(stream2);
7849
ok(!ref, "Got outstanding refcount %ld.\n", ref);
7850
}
7851
7852
static void test_ddrawstream_getsetdirectdraw(void)
7853
{
7854
IAMMultiMediaStream *mmstream = create_ammultimediastream();
7855
IDirectDraw *ddraw, *ddraw2, *ddraw3, *ddraw4;
7856
IDirectDrawMediaStream *ddraw_stream;
7857
IDirectDrawStreamSample *sample;
7858
IDirectDraw7 *ddraw7;
7859
IMediaStream *stream;
7860
HRESULT hr;
7861
ULONG ref;
7862
7863
hr = DirectDrawCreate(NULL, &ddraw, NULL);
7864
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7865
hr = IDirectDraw_QueryInterface(ddraw, &IID_IDirectDraw7, (void **)&ddraw7);
7866
ok(hr == DD_OK, "Got hr %#lx.\n", hr);
7867
hr = IDirectDraw7_SetCooperativeLevel(ddraw7, GetDesktopWindow(), DDSCL_NORMAL);
7868
ok(hr == DD_OK, "Got hr %#lx.\n", hr);
7869
EXPECT_REF(ddraw, 1);
7870
EXPECT_REF(ddraw7, 1);
7871
7872
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
7873
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7874
7875
hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)ddraw7, &MSPID_PrimaryVideo, 0, &stream);
7876
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7877
EXPECT_REF(ddraw, 2);
7878
7879
hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
7880
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7881
7882
hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, NULL);
7883
ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
7884
7885
hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw2);
7886
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7887
ok(ddraw2 == ddraw, "Expected ddraw %p, got %p.\n", ddraw, ddraw2);
7888
EXPECT_REF(ddraw, 3);
7889
7890
hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw3);
7891
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7892
ok(ddraw3 == ddraw2, "Expected ddraw %p, got %p.\n", ddraw2, ddraw3);
7893
EXPECT_REF(ddraw, 4);
7894
IDirectDraw_Release(ddraw3);
7895
EXPECT_REF(ddraw, 3);
7896
7897
/* The current ddraw is released when SetDirectDraw() is called. */
7898
hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, NULL);
7899
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7900
EXPECT_REF(ddraw, 2);
7901
7902
hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw3);
7903
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7904
ok(ddraw3 == NULL, "Expected NULL, got %p.\n", ddraw3);
7905
7906
hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, ddraw2);
7907
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7908
EXPECT_REF(ddraw, 3);
7909
7910
hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw3);
7911
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7912
ok(ddraw3 == ddraw2, "Expected ddraw %p, got %p.\n", ddraw2, ddraw3);
7913
EXPECT_REF(ddraw, 4);
7914
IDirectDraw_Release(ddraw3);
7915
EXPECT_REF(ddraw, 3);
7916
7917
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &sample);
7918
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7919
7920
/* SetDirectDraw() doesn't take an extra reference to the ddraw object
7921
* if there are samples extant. */
7922
hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, ddraw2);
7923
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7924
EXPECT_REF(ddraw, 3);
7925
7926
hr = DirectDrawCreate(NULL, &ddraw3, NULL);
7927
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7928
hr = IDirectDraw_SetCooperativeLevel(ddraw3, GetDesktopWindow(), DDSCL_NORMAL);
7929
ok(hr == DD_OK, "Got hr %#lx.\n", hr);
7930
EXPECT_REF(ddraw3, 1);
7931
7932
hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, ddraw3);
7933
ok(hr == MS_E_SAMPLEALLOC, "Got hr %#lx.\n", hr);
7934
7935
hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw4);
7936
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7937
ok(ddraw4 == ddraw2, "Expected ddraw %p, got %p.\n", ddraw2, ddraw4);
7938
EXPECT_REF(ddraw, 4);
7939
IDirectDraw_Release(ddraw4);
7940
EXPECT_REF(ddraw, 3);
7941
7942
ref = IDirectDrawStreamSample_Release(sample);
7943
ok(!ref, "Got outstanding refcount %ld.\n", ref);
7944
7945
hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, ddraw3);
7946
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7947
EXPECT_REF(ddraw, 2);
7948
EXPECT_REF(ddraw3, 2);
7949
7950
hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw4);
7951
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7952
ok(ddraw4 == ddraw3, "Expected ddraw %p, got %p.\n", ddraw3, ddraw4);
7953
EXPECT_REF(ddraw3, 3);
7954
IDirectDraw_Release(ddraw4);
7955
EXPECT_REF(ddraw3, 2);
7956
7957
hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, NULL);
7958
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7959
EXPECT_REF(ddraw3, 1);
7960
7961
ref = IDirectDraw_Release(ddraw3);
7962
ok(!ref, "Got outstanding refcount %ld.\n", ref);
7963
7964
EXPECT_REF(stream, 3);
7965
IDirectDrawMediaStream_Release(ddraw_stream);
7966
EXPECT_REF(stream, 2);
7967
ref = IAMMultiMediaStream_Release(mmstream);
7968
ok(!ref, "Got outstanding refcount %ld.\n", ref);
7969
EXPECT_REF(stream, 1);
7970
ref = IMediaStream_Release(stream);
7971
ok(!ref, "Got outstanding refcount %ld.\n", ref);
7972
ref = IDirectDraw7_Release(ddraw7);
7973
ok(!ref, "Got outstanding refcount %ld.\n", ref);
7974
IDirectDraw_Release(ddraw2);
7975
EXPECT_REF(ddraw, 1);
7976
ref = IDirectDraw_Release(ddraw);
7977
ok(!ref, "Got outstanding refcount %ld.\n", ref);
7978
}
7979
7980
static void test_audiostreamsample_get_media_stream(void)
7981
{
7982
IAMMultiMediaStream *mmstream = create_ammultimediastream();
7983
IAudioStreamSample *audio_sample;
7984
IAudioMediaStream *audio_stream;
7985
IMediaStream *stream, *stream2;
7986
IAudioData *audio_data;
7987
HRESULT hr;
7988
ULONG ref;
7989
7990
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
7991
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7992
7993
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
7994
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7995
7996
hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
7997
ok(hr == S_OK, "Got hr %#lx.\n", hr);
7998
7999
hr = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, &IID_IAudioData, (void **)&audio_data);
8000
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8001
8002
hr = IAudioMediaStream_CreateSample(audio_stream, audio_data, 0, &audio_sample);
8003
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8004
8005
/* Crashes on native. */
8006
if (0)
8007
{
8008
hr = IAudioStreamSample_GetMediaStream(audio_sample, NULL);
8009
ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
8010
}
8011
8012
EXPECT_REF(stream, 4);
8013
hr = IAudioStreamSample_GetMediaStream(audio_sample, &stream2);
8014
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8015
ok(stream2 == stream, "Expected stream %p, got %p.\n", stream, stream2);
8016
EXPECT_REF(stream, 5);
8017
8018
IMediaStream_Release(stream2);
8019
8020
IAudioMediaStream_Release(audio_stream);
8021
ref = IAudioStreamSample_Release(audio_sample);
8022
ok(!ref, "Got outstanding refcount %ld.\n", ref);
8023
ref = IAudioData_Release(audio_data);
8024
ok(!ref, "Got outstanding refcount %ld.\n", ref);
8025
ref = IAMMultiMediaStream_Release(mmstream);
8026
ok(!ref, "Got outstanding refcount %ld.\n", ref);
8027
ref = IMediaStream_Release(stream);
8028
ok(!ref, "Got outstanding refcount %ld.\n", ref);
8029
}
8030
8031
static void test_audiostreamsample_get_audio_data(void)
8032
{
8033
IAMMultiMediaStream *mmstream = create_ammultimediastream();
8034
IAudioData *audio_data, *audio_data2;
8035
IAudioStreamSample *audio_sample;
8036
IAudioMediaStream *audio_stream;
8037
IMediaStream *stream;
8038
HRESULT hr;
8039
ULONG ref;
8040
8041
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
8042
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8043
8044
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
8045
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8046
8047
hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
8048
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8049
8050
hr = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, &IID_IAudioData, (void **)&audio_data);
8051
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8052
8053
hr = IAudioMediaStream_CreateSample(audio_stream, audio_data, 0, &audio_sample);
8054
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8055
8056
hr = IAudioStreamSample_GetAudioData(audio_sample, NULL);
8057
ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
8058
8059
EXPECT_REF(audio_data, 2);
8060
hr = IAudioStreamSample_GetAudioData(audio_sample, &audio_data2);
8061
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8062
ok(audio_data2 == audio_data, "Expected audio data %p, got %p.\n", audio_data, audio_data2);
8063
EXPECT_REF(audio_data, 3);
8064
8065
IAudioData_Release(audio_data2);
8066
8067
IAudioMediaStream_Release(audio_stream);
8068
ref = IAudioStreamSample_Release(audio_sample);
8069
ok(!ref, "Got outstanding refcount %ld.\n", ref);
8070
ref = IAudioData_Release(audio_data);
8071
ok(!ref, "Got outstanding refcount %ld.\n", ref);
8072
ref = IAMMultiMediaStream_Release(mmstream);
8073
ok(!ref, "Got outstanding refcount %ld.\n", ref);
8074
ref = IMediaStream_Release(stream);
8075
ok(!ref, "Got outstanding refcount %ld.\n", ref);
8076
}
8077
8078
#define get_ddrawstream_create_sample_desc(a,b,c,d) get_ddrawstream_create_sample_desc_(__LINE__,a,b,c,d)
8079
static void get_ddrawstream_create_sample_desc_(int line, const DDSURFACEDESC *format1,
8080
const DDSURFACEDESC *format2, const AM_MEDIA_TYPE *mt, DDSURFACEDESC *desc)
8081
{
8082
IAMMultiMediaStream *mmstream = create_ammultimediastream();
8083
IDirectDrawMediaStream *ddraw_stream;
8084
IDirectDrawStreamSample *sample;
8085
IDirectDrawSurface *surface;
8086
struct testfilter source;
8087
IGraphBuilder *graph;
8088
IMediaStream *stream;
8089
HRESULT hr;
8090
ULONG ref;
8091
IPin *pin;
8092
8093
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
8094
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
8095
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
8096
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
8097
hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
8098
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
8099
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
8100
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
8101
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
8102
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
8103
8104
testfilter_init(&source);
8105
8106
hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
8107
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
8108
8109
if (format1)
8110
{
8111
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, format1, NULL);
8112
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
8113
}
8114
if (format2)
8115
{
8116
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, format2, NULL);
8117
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
8118
}
8119
if (mt)
8120
{
8121
hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, mt);
8122
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
8123
8124
hr = IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
8125
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
8126
hr = IGraphBuilder_Disconnect(graph, pin);
8127
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
8128
}
8129
8130
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &sample);
8131
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
8132
8133
hr = IDirectDrawStreamSample_GetSurface(sample, &surface, NULL);
8134
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
8135
ok_(__FILE__, line)(!!surface, "Expected non-NULL sufrace.\n");
8136
8137
desc->dwSize = sizeof(*desc);
8138
hr = IDirectDrawSurface_GetSurfaceDesc(surface, desc);
8139
ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
8140
8141
ref = IDirectDrawStreamSample_Release(sample);
8142
ok_(__FILE__, line)(!ref, "Got outstanding refcount %ld.\n", ref);
8143
ref = IDirectDrawSurface_Release(surface);
8144
ok_(__FILE__, line)(!ref, "Got outstanding refcount %ld.\n", ref);
8145
ref = IAMMultiMediaStream_Release(mmstream);
8146
ok_(__FILE__, line)(!ref, "Got outstanding refcount %ld.\n", ref);
8147
ref = IGraphBuilder_Release(graph);
8148
ok_(__FILE__, line)(!ref, "Got outstanding refcount %ld.\n", ref);
8149
IPin_Release(pin);
8150
IDirectDrawMediaStream_Release(ddraw_stream);
8151
ref = IMediaStream_Release(stream);
8152
ok_(__FILE__, line)(!ref, "Got outstanding refcount %ld.\n", ref);
8153
}
8154
8155
static void test_ddrawstream_create_sample(void)
8156
{
8157
IAMMultiMediaStream *mmstream = create_ammultimediastream();
8158
DDSURFACEDESC desc2 = { sizeof(desc2) };
8159
IDirectDrawSurface *surface, *surface2;
8160
DDSURFACEDESC desc = { sizeof(desc) };
8161
IDirectDrawMediaStream *ddraw_stream;
8162
IDirectDrawStreamSample *sample;
8163
DDSURFACEDESC format1;
8164
DDSURFACEDESC format2;
8165
IMediaStream *stream;
8166
IDirectDraw *ddraw;
8167
HRESULT hr;
8168
RECT rect;
8169
ULONG ref;
8170
8171
hr = DirectDrawCreate(NULL, &ddraw, NULL);
8172
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8173
8174
hr = IDirectDraw_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL);
8175
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8176
8177
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
8178
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8179
8180
hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)ddraw, &MSPID_PrimaryVideo, 0, &stream);
8181
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8182
8183
hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
8184
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8185
8186
/* Crashes on native. */
8187
if (0)
8188
{
8189
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, NULL);
8190
ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
8191
}
8192
8193
SetRectEmpty(&rect);
8194
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, &rect, 0, &sample);
8195
ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
8196
8197
EXPECT_REF(mmstream, 1);
8198
EXPECT_REF(stream, 3);
8199
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &sample);
8200
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8201
EXPECT_REF(mmstream, 2);
8202
EXPECT_REF(stream, 4);
8203
8204
hr = IDirectDrawStreamSample_GetSurface(sample, NULL, NULL);
8205
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8206
8207
hr = IDirectDrawStreamSample_GetSurface(sample, NULL, &rect);
8208
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8209
8210
hr = IDirectDrawStreamSample_GetSurface(sample, &surface, NULL);
8211
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8212
ok(surface != NULL, "Expected non-NULL surface.\n");
8213
IDirectDrawSurface_Release(surface);
8214
8215
surface = NULL;
8216
hr = IDirectDrawStreamSample_GetSurface(sample, &surface, &rect);
8217
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8218
ok(surface != NULL, "Expected non-NULL surface.\n");
8219
8220
hr = IDirectDrawSurface_GetSurfaceDesc(surface, &desc);
8221
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8222
ok(desc.dwWidth == 100, "Expected width 100, got %ld.\n", desc.dwWidth);
8223
ok(desc.dwHeight == 100, "Expected height 100, got %ld.\n", desc.dwHeight);
8224
ok(desc.ddpfPixelFormat.dwFlags == DDPF_RGB, "Expected format flags DDPF_RGB, got %#lx.\n", desc.ddpfPixelFormat.dwFlags);
8225
ok(desc.ddpfPixelFormat.dwRGBBitCount, "Expected non-zero RGB bit count.\n");
8226
IDirectDrawSurface_Release(surface);
8227
IDirectDrawStreamSample_Release(sample);
8228
EXPECT_REF(stream, 3);
8229
8230
memset(&desc, 0, sizeof(desc));
8231
desc.dwSize = sizeof(desc);
8232
desc.dwFlags = DDSD_CAPS;
8233
desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
8234
hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
8235
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8236
8237
EXPECT_REF(surface, 1);
8238
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, surface, NULL, 0, &sample);
8239
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8240
EXPECT_REF(surface, 2);
8241
8242
surface2 = NULL;
8243
SetRectEmpty(&rect);
8244
hr = IDirectDrawStreamSample_GetSurface(sample, &surface2, &rect);
8245
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8246
ok(surface2 == surface, "Expected surface %p, got %p.\n", surface, surface2);
8247
ok(rect.right > 0 && rect.bottom > 0, "Got rect %ld, %ld.\n", rect.right, rect.bottom);
8248
EXPECT_REF(surface, 3);
8249
IDirectDrawSurface_Release(surface2);
8250
EXPECT_REF(surface, 2);
8251
IDirectDrawStreamSample_Release(sample);
8252
EXPECT_REF(surface, 1);
8253
8254
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, surface, &rect, 0, &sample);
8255
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8256
8257
ref = IDirectDrawStreamSample_Release(sample);
8258
ok(!ref, "Got outstanding refcount %ld.\n", ref);
8259
ref = IDirectDrawSurface_Release(surface);
8260
ok(!ref, "Got outstanding refcount %ld.\n", ref);
8261
8262
memset(&desc, 0, sizeof(desc));
8263
desc.dwSize = sizeof(desc);
8264
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
8265
desc.dwWidth = 444;
8266
desc.dwHeight = 400;
8267
desc.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
8268
desc.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
8269
desc.ddpfPixelFormat.dwRGBBitCount = 32;
8270
desc.ddpfPixelFormat.dwRBitMask = 0xff0000;
8271
desc.ddpfPixelFormat.dwGBitMask = 0x00ff00;
8272
desc.ddpfPixelFormat.dwBBitMask = 0x0000ff;
8273
desc.ddpfPixelFormat.dwRGBAlphaBitMask = 0xff000000;
8274
desc.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
8275
hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
8276
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8277
8278
SetRect(&rect, 111, 100, 333, 300);
8279
8280
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, surface, &rect, 0, &sample);
8281
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8282
ref = IDirectDrawStreamSample_Release(sample);
8283
ok(!ref, "Got outstanding refcount %ld.\n", ref);
8284
8285
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &sample);
8286
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8287
surface2 = NULL;
8288
hr = IDirectDrawStreamSample_GetSurface(sample, &surface2, &rect);
8289
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8290
8291
hr = IDirectDrawSurface_GetSurfaceDesc(surface, &desc);
8292
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8293
hr = IDirectDrawSurface_GetSurfaceDesc(surface2, &desc2);
8294
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8295
ok(desc2.dwWidth == 222, "Got width %lu.\n", desc2.dwWidth);
8296
ok(desc2.dwHeight == 200, "Got height %lu.\n", desc2.dwHeight);
8297
ok(memcmp(&desc2.ddpfPixelFormat, &desc.ddpfPixelFormat, sizeof(DDPIXELFORMAT)) == 0,
8298
"Pixel format didn't match.\n");
8299
8300
ref = IDirectDrawStreamSample_Release(sample);
8301
ok(!ref, "Got outstanding refcount %ld.\n", ref);
8302
ref = IDirectDrawSurface_Release(surface);
8303
ok(!ref, "Got outstanding refcount %ld.\n", ref);
8304
ref = IDirectDrawSurface_Release(surface2);
8305
ok(!ref, "Got outstanding refcount %ld.\n", ref);
8306
8307
memset(&desc, 0, sizeof(desc));
8308
desc.dwSize = sizeof(desc);
8309
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
8310
desc.dwWidth = 444;
8311
desc.dwHeight = 400;
8312
desc.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
8313
desc.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED4;
8314
desc.ddpfPixelFormat.dwRGBBitCount = 4;
8315
desc.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
8316
hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
8317
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8318
8319
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, surface, NULL, 0, &sample);
8320
ok(hr == DDERR_INVALIDSURFACETYPE, "Got hr %#lx.\n", hr);
8321
8322
IDirectDrawMediaStream_Release(ddraw_stream);
8323
ref = IDirectDrawSurface_Release(surface);
8324
ok(!ref, "Got outstanding refcount %ld.\n", ref);
8325
ref = IAMMultiMediaStream_Release(mmstream);
8326
ok(!ref, "Got outstanding refcount %ld.\n", ref);
8327
ref = IMediaStream_Release(stream);
8328
ok(!ref, "Got outstanding refcount %ld.\n", ref);
8329
ref = IDirectDraw_Release(ddraw);
8330
ok(!ref, "Got outstanding refcount %ld.\n", ref);
8331
8332
format1 = rgb8_format;
8333
format1.dwFlags = 0;
8334
format1.dwWidth = 333;
8335
format1.dwHeight = 444;
8336
get_ddrawstream_create_sample_desc(&format1, NULL, NULL, &desc);
8337
ok(desc.dwWidth == 100, "Got width %lu.\n", desc.dwWidth);
8338
ok(desc.dwHeight == 100, "Got height %lu.\n", desc.dwHeight);
8339
ok(desc.ddpfPixelFormat.dwFlags == DDPF_RGB, "Got flags %#lx.\n", desc.ddpfPixelFormat.dwFlags);
8340
ok(desc.ddpfPixelFormat.dwRGBBitCount == 32, "Got rgb bit count %lu.\n", desc.ddpfPixelFormat.dwRGBBitCount);
8341
ok(desc.ddpfPixelFormat.dwRBitMask == 0xff0000, "Got r bit mask %#lx.\n", desc.ddpfPixelFormat.dwRBitMask);
8342
ok(desc.ddpfPixelFormat.dwGBitMask == 0x00ff00, "Got g bit mask %#lx.\n", desc.ddpfPixelFormat.dwGBitMask);
8343
ok(desc.ddpfPixelFormat.dwBBitMask == 0x0000ff, "Got b bit mask %#lx.\n", desc.ddpfPixelFormat.dwBBitMask);
8344
8345
format1 = rgb8_format;
8346
format1.dwFlags |= DDSD_WIDTH;
8347
format1.dwWidth = 333;
8348
format1.dwHeight = 444;
8349
format2 = rgb8_format;
8350
format2.dwFlags = 0;
8351
get_ddrawstream_create_sample_desc(&format1, &format2, NULL, &desc);
8352
ok(desc.dwWidth == 333, "Got width %lu.\n", desc.dwWidth);
8353
ok(desc.dwHeight == 444, "Got height %lu.\n", desc.dwHeight);
8354
8355
format1 = rgb8_format;
8356
format1.dwFlags |= DDSD_HEIGHT;
8357
format1.dwWidth = 333;
8358
format1.dwHeight = 444;
8359
format2 = rgb8_format;
8360
format2.dwFlags = 0;
8361
get_ddrawstream_create_sample_desc(&format1, &format2, NULL, &desc);
8362
ok(desc.dwWidth == 333, "Got width %lu.\n", desc.dwWidth);
8363
ok(desc.dwHeight == 444, "Got height %lu.\n", desc.dwHeight);
8364
8365
get_ddrawstream_create_sample_desc(NULL, NULL, &rgb8_mt, &desc);
8366
ok(desc.dwWidth == 333, "Got width %lu.\n", desc.dwWidth);
8367
ok(desc.dwHeight == 444, "Got height %lu.\n", desc.dwHeight);
8368
ok(desc.ddpfPixelFormat.dwFlags == DDPF_RGB, "Got flags %#lx.\n", desc.ddpfPixelFormat.dwFlags);
8369
ok(desc.ddpfPixelFormat.dwRGBBitCount == 32, "Got rgb bit count %lu.\n", desc.ddpfPixelFormat.dwRGBBitCount);
8370
ok(desc.ddpfPixelFormat.dwRBitMask == 0xff0000, "Got r bit mask %#lx.\n", desc.ddpfPixelFormat.dwRBitMask);
8371
ok(desc.ddpfPixelFormat.dwGBitMask == 0x00ff00, "Got g bit mask %#lx.\n", desc.ddpfPixelFormat.dwGBitMask);
8372
ok(desc.ddpfPixelFormat.dwBBitMask == 0x0000ff, "Got b bit mask %#lx.\n", desc.ddpfPixelFormat.dwBBitMask);
8373
8374
get_ddrawstream_create_sample_desc(&rgb565_format, NULL, NULL, &desc);
8375
ok(desc.dwWidth == 100, "Got width %lu.\n", desc.dwWidth);
8376
ok(desc.dwHeight == 100, "Got height %lu.\n", desc.dwHeight);
8377
ok(desc.ddpfPixelFormat.dwFlags == DDPF_RGB, "Got flags %#lx.\n", desc.ddpfPixelFormat.dwFlags);
8378
ok(desc.ddpfPixelFormat.dwRGBBitCount == 16, "Got rgb bit count %lu.\n", desc.ddpfPixelFormat.dwRGBBitCount);
8379
ok(desc.ddpfPixelFormat.dwRBitMask == 0xf800, "Got r bit mask %#lx.\n", desc.ddpfPixelFormat.dwRBitMask);
8380
ok(desc.ddpfPixelFormat.dwGBitMask == 0x07e0, "Got g bit mask %#lx.\n", desc.ddpfPixelFormat.dwGBitMask);
8381
ok(desc.ddpfPixelFormat.dwBBitMask == 0x001f, "Got b bit mask %#lx.\n", desc.ddpfPixelFormat.dwBBitMask);
8382
8383
get_ddrawstream_create_sample_desc(&argb32_format, NULL, NULL, &desc);
8384
ok(desc.dwWidth == 100, "Got width %lu.\n", desc.dwWidth);
8385
ok(desc.dwHeight == 100, "Got height %lu.\n", desc.dwHeight);
8386
ok(desc.ddpfPixelFormat.dwFlags == (DDPF_RGB | DDPF_ALPHAPIXELS), "Got flags %#lx.\n", desc.ddpfPixelFormat.dwFlags);
8387
ok(desc.ddpfPixelFormat.dwRGBBitCount == 32, "Got rgb bit count %lu.\n", desc.ddpfPixelFormat.dwRGBBitCount);
8388
ok(desc.ddpfPixelFormat.dwRBitMask == 0xff0000, "Got r bit mask %#lx.\n", desc.ddpfPixelFormat.dwRBitMask);
8389
ok(desc.ddpfPixelFormat.dwGBitMask == 0x00ff00, "Got g bit mask %#lx.\n", desc.ddpfPixelFormat.dwGBitMask);
8390
ok(desc.ddpfPixelFormat.dwBBitMask == 0x0000ff, "Got b bit mask %#lx.\n", desc.ddpfPixelFormat.dwBBitMask);
8391
ok(desc.ddpfPixelFormat.dwRGBAlphaBitMask == 0xff000000,
8392
"Got alpha bit mask %#lx.\n", desc.ddpfPixelFormat.dwBBitMask);
8393
8394
format1 = rgb32_format;
8395
format1.dwFlags |= DDSD_CAPS;
8396
format1.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
8397
get_ddrawstream_create_sample_desc(&format1, NULL, NULL, &desc);
8398
ok(desc.ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN, "Expected set DDSCAPS_OFFSCREENPLAIN.\n");
8399
ok(desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY, "Expected set DDSCAPS_SYSTEMMEMORY.\n");
8400
ok(!(desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY), "Expected unset DDSCAPS_VIDEOMEMORY.\n");
8401
ok(desc.dwWidth == 100, "Got width %lu.\n", desc.dwWidth);
8402
ok(desc.dwHeight == 100, "Got height %lu.\n", desc.dwHeight);
8403
ok(desc.ddpfPixelFormat.dwFlags == DDPF_RGB, "Got flags %#lx.\n", desc.ddpfPixelFormat.dwFlags);
8404
ok(desc.ddpfPixelFormat.dwRGBBitCount == 32, "Got rgb bit count %lu.\n", desc.ddpfPixelFormat.dwRGBBitCount);
8405
ok(desc.ddpfPixelFormat.dwRBitMask == 0xff0000, "Got r bit mask %#lx.\n", desc.ddpfPixelFormat.dwRBitMask);
8406
ok(desc.ddpfPixelFormat.dwGBitMask == 0x00ff00, "Got g bit mask %#lx.\n", desc.ddpfPixelFormat.dwGBitMask);
8407
ok(desc.ddpfPixelFormat.dwBBitMask == 0x0000ff, "Got b bit mask %#lx.\n", desc.ddpfPixelFormat.dwBBitMask);
8408
8409
format1 = rgb32_format;
8410
format1.dwFlags |= DDSD_CKSRCBLT;
8411
format1.ddckCKSrcBlt.dwColorSpaceLowValue = 0xff00ff;
8412
format1.ddckCKSrcBlt.dwColorSpaceHighValue = 0xff00ff;
8413
get_ddrawstream_create_sample_desc(&format1, NULL, NULL, &desc);
8414
ok(!(desc.dwFlags & DDSD_CKSRCBLT), "Expected unset DDSD_CKSRCBLT.\n");
8415
ok(desc.dwWidth == 100, "Got width %lu.\n", desc.dwWidth);
8416
ok(desc.dwHeight == 100, "Got height %lu.\n", desc.dwHeight);
8417
ok(desc.ddpfPixelFormat.dwFlags == DDPF_RGB, "Got flags %#lx.\n", desc.ddpfPixelFormat.dwFlags);
8418
ok(desc.ddpfPixelFormat.dwRGBBitCount == 32, "Got rgb bit count %lu.\n", desc.ddpfPixelFormat.dwRGBBitCount);
8419
ok(desc.ddpfPixelFormat.dwRBitMask == 0xff0000, "Got r bit mask %#lx.\n", desc.ddpfPixelFormat.dwRBitMask);
8420
ok(desc.ddpfPixelFormat.dwGBitMask == 0x00ff00, "Got g bit mask %#lx.\n", desc.ddpfPixelFormat.dwGBitMask);
8421
ok(desc.ddpfPixelFormat.dwBBitMask == 0x0000ff, "Got b bit mask %#lx.\n", desc.ddpfPixelFormat.dwBBitMask);
8422
ok(desc.ddckCKSrcBlt.dwColorSpaceLowValue == 0, "Got color key low value %#lx.\n",
8423
desc.ddckCKSrcBlt.dwColorSpaceLowValue);
8424
ok(desc.ddckCKSrcBlt.dwColorSpaceHighValue == 0, "Got color key high value %#lx.\n",
8425
desc.ddckCKSrcBlt.dwColorSpaceHighValue);
8426
}
8427
8428
static void test_ddrawstream_qc(void)
8429
{
8430
static const BYTE test_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
8431
IAMMultiMediaStream *mmstream = create_ammultimediastream();
8432
struct advise_time_cookie cookie = { 0 };
8433
IDirectDrawStreamSample *stream_sample;
8434
IDirectDrawMediaStream *ddraw_stream;
8435
IMediaFilter *graph_media_filter;
8436
STREAM_TIME filter_start_time;
8437
IMemInputPin *mem_input_pin;
8438
IMediaStreamFilter *filter;
8439
struct testfilter source;
8440
struct testclock clock;
8441
STREAM_TIME start_time;
8442
STREAM_TIME end_time;
8443
IGraphBuilder *graph;
8444
IMediaStream *stream;
8445
VIDEOINFO video_info;
8446
AM_MEDIA_TYPE mt;
8447
HANDLE thread;
8448
HRESULT hr;
8449
ULONG ref;
8450
IPin *pin;
8451
8452
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
8453
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8454
hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
8455
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8456
ok(!!filter, "Expected non-null filter.\n");
8457
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
8458
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8459
hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
8460
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8461
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
8462
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8463
hr = IMediaStream_QueryInterface(stream, &IID_IMemInputPin, (void **)&mem_input_pin);
8464
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8465
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
8466
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8467
ok(graph != NULL, "Expected non-NULL graph.\n");
8468
hr = IGraphBuilder_QueryInterface(graph, &IID_IMediaFilter, (void **)&graph_media_filter);
8469
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8470
testfilter_init(&source);
8471
source.IQualityControl_iface.lpVtbl = &testsource_qc_vtbl;
8472
hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
8473
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8474
testclock_init(&clock);
8475
cookie.advise_time_called_event = CreateEventW(NULL, FALSE, FALSE, NULL);
8476
ok(cookie.advise_time_called_event != NULL, "Expected non-NULL event.");
8477
8478
video_info = rgb32_video_info;
8479
video_info.bmiHeader.biWidth = 3;
8480
video_info.bmiHeader.biHeight = 1;
8481
mt = rgb32_mt;
8482
mt.pbFormat = (BYTE *)&video_info;
8483
hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
8484
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8485
8486
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &stream_sample);
8487
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8488
8489
/* There are no quality control messages without a sync source. */
8490
hr = IMediaFilter_SetSyncSource(graph_media_filter, NULL);
8491
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8492
8493
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
8494
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8495
8496
source.qc_notify_sender = (IBaseFilter *)0xdeadbeef;
8497
source.qc_notify_quality.Type = Flood;
8498
source.qc_notify_quality.Proportion = 0xdeadbeef;
8499
source.qc_notify_quality.Late = 0xdeadbeef;
8500
source.qc_notify_quality.TimeStamp = 0xdeadbeef;
8501
8502
thread = ammediastream_async_receive_time(&source,
8503
11111111, 11111111, test_data, sizeof(test_data));
8504
ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Receive returned prematurely.\n");
8505
8506
hr = IDirectDrawStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
8507
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8508
8509
ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
8510
CloseHandle(thread);
8511
8512
ok(source.qc_notify_sender == (IBaseFilter *)0xdeadbeef, "Got sender %p.\n",
8513
source.qc_notify_sender);
8514
ok(source.qc_notify_quality.Type == Flood, "Got type %d.\n",
8515
source.qc_notify_quality.Type);
8516
ok(source.qc_notify_quality.Proportion == 0xdeadbeef, "Got proportion %ld.\n",
8517
source.qc_notify_quality.Proportion);
8518
ok(source.qc_notify_quality.Late == 0xdeadbeef,
8519
"Got late %s.\n", wine_dbgstr_longlong(source.qc_notify_quality.Late));
8520
ok(source.qc_notify_quality.TimeStamp == 0xdeadbeef, "Got time stamp %s.\n",
8521
wine_dbgstr_longlong(source.qc_notify_quality.TimeStamp));
8522
8523
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
8524
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8525
8526
hr = IMediaFilter_SetSyncSource(graph_media_filter, &clock.IReferenceClock_iface);
8527
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8528
8529
clock.time = 12345678;
8530
8531
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
8532
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8533
8534
hr = IMediaStreamFilter_GetCurrentStreamTime(filter, &filter_start_time);
8535
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8536
8537
/* Quality control message is sent on update completion, q.Late is computed
8538
* as a difference between sample start time and update completion time. */
8539
8540
/* Test Update() before Reveive(). */
8541
source.qc_notify_sender = (IBaseFilter *)0xdeadbeef;
8542
source.qc_notify_quality.Type = Flood;
8543
source.qc_notify_quality.Proportion = 0xdeadbeef;
8544
source.qc_notify_quality.Late = 0xdeadbeef;
8545
source.qc_notify_quality.TimeStamp = 0xdeadbeef;
8546
8547
clock.time = 12345678 - filter_start_time + 11111111;
8548
8549
hr = IDirectDrawStreamSample_Update(stream_sample, SSUPDATE_ASYNC, NULL, NULL, 0);
8550
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
8551
8552
clock.advise_time_cookie = &cookie;
8553
clock.time = 12345678 - filter_start_time + 11111111 + 100000;
8554
8555
start_time = 11111111 + 200000;
8556
end_time = 11111111 + 200000;
8557
thread = ammediastream_async_receive_time(&source,
8558
start_time, end_time, test_data, sizeof(test_data));
8559
ok(!WaitForSingleObject(cookie.advise_time_called_event, 2000), "Wait timed out.\n");
8560
8561
ok(source.qc_notify_sender == (IBaseFilter *)0xdeadbeef, "Got sender %p.\n",
8562
source.qc_notify_sender);
8563
ok(source.qc_notify_quality.Type == Flood, "Got type %d.\n",
8564
source.qc_notify_quality.Type);
8565
ok(source.qc_notify_quality.Proportion == 0xdeadbeef, "Got proportion %ld.\n",
8566
source.qc_notify_quality.Proportion);
8567
ok(source.qc_notify_quality.Late == 0xdeadbeef,
8568
"Got late %s.\n", wine_dbgstr_longlong(source.qc_notify_quality.Late));
8569
ok(source.qc_notify_quality.TimeStamp == 0xdeadbeef, "Got time stamp %s.\n",
8570
wine_dbgstr_longlong(source.qc_notify_quality.TimeStamp));
8571
8572
clock.time = 12345678 - filter_start_time + 11111111 + 200000;
8573
8574
SetEvent(cookie.event);
8575
8576
ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
8577
CloseHandle(thread);
8578
8579
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample, 0, 0);
8580
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8581
8582
ok(source.qc_notify_sender == (IBaseFilter *)filter, "Got sender %p.\n",
8583
source.qc_notify_sender);
8584
ok(source.qc_notify_quality.Type == Famine, "Got type %d.\n",
8585
source.qc_notify_quality.Type);
8586
ok(source.qc_notify_quality.Proportion == 1000, "Got proportion %ld.\n",
8587
source.qc_notify_quality.Proportion);
8588
ok(source.qc_notify_quality.Late == 0, "Got late %s.\n",
8589
wine_dbgstr_longlong(source.qc_notify_quality.Late));
8590
ok(source.qc_notify_quality.TimeStamp == start_time, "Got time stamp %s.\n",
8591
wine_dbgstr_longlong(source.qc_notify_quality.TimeStamp));
8592
8593
/* Test Update() after Reveive(). */
8594
source.qc_notify_sender = (IBaseFilter *)0xdeadbeef;
8595
source.qc_notify_quality.Type = Flood;
8596
source.qc_notify_quality.Proportion = 0xdeadbeef;
8597
source.qc_notify_quality.Late = 0xdeadbeef;
8598
source.qc_notify_quality.TimeStamp = 0xdeadbeef;
8599
8600
clock.advise_time_cookie = &cookie;
8601
clock.time = 12345678 - filter_start_time + 11111111 + 300000;
8602
8603
start_time = 11111111 + 400000;
8604
end_time = 11111111 + 400000;
8605
thread = ammediastream_async_receive_time(&source,
8606
start_time, end_time, test_data, sizeof(test_data));
8607
ok(!WaitForSingleObject(cookie.advise_time_called_event, 2000), "Wait timed out.\n");
8608
8609
clock.time = 12345678 - filter_start_time + 11111111 + 400000;
8610
SetEvent(cookie.event);
8611
8612
ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Receive returned prematurely.\n");
8613
8614
ok(source.qc_notify_sender == (IBaseFilter *)0xdeadbeef, "Got sender %p.\n",
8615
source.qc_notify_sender);
8616
ok(source.qc_notify_quality.Type == Flood, "Got type %d.\n",
8617
source.qc_notify_quality.Type);
8618
ok(source.qc_notify_quality.Proportion == 0xdeadbeef, "Got proportion %ld.\n",
8619
source.qc_notify_quality.Proportion);
8620
ok(source.qc_notify_quality.Late == 0xdeadbeef,
8621
"Got late %s.\n", wine_dbgstr_longlong(source.qc_notify_quality.Late));
8622
ok(source.qc_notify_quality.TimeStamp == 0xdeadbeef, "Got time stamp %s.\n",
8623
wine_dbgstr_longlong(source.qc_notify_quality.TimeStamp));
8624
8625
clock.time = 12345678 - filter_start_time + 11111111 + 500000;
8626
8627
hr = IDirectDrawStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
8628
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8629
8630
ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
8631
CloseHandle(thread);
8632
8633
ok(source.qc_notify_sender == (IBaseFilter *)filter, "Got sender %p.\n",
8634
source.qc_notify_sender);
8635
ok(source.qc_notify_quality.Type == Famine, "Got type %d.\n",
8636
source.qc_notify_quality.Type);
8637
ok(source.qc_notify_quality.Proportion == 1000, "Got proportion %ld.\n",
8638
source.qc_notify_quality.Proportion);
8639
ok(source.qc_notify_quality.Late == 100000, "Got late %s.\n",
8640
wine_dbgstr_longlong(source.qc_notify_quality.Late));
8641
ok(source.qc_notify_quality.TimeStamp == start_time, "Got time stamp %s.\n",
8642
wine_dbgstr_longlong(source.qc_notify_quality.TimeStamp));
8643
8644
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
8645
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8646
IGraphBuilder_Disconnect(graph, pin);
8647
IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
8648
8649
CloseHandle(cookie.advise_time_called_event);
8650
ref = IDirectDrawStreamSample_Release(stream_sample);
8651
ok(!ref, "Got outstanding refcount %ld.\n", ref);
8652
ref = IAMMultiMediaStream_Release(mmstream);
8653
ok(!ref, "Got outstanding refcount %ld.\n", ref);
8654
IMediaFilter_Release(graph_media_filter);
8655
ref = IGraphBuilder_Release(graph);
8656
ok(!ref, "Got outstanding refcount %ld.\n", ref);
8657
ref = IMediaStreamFilter_Release(filter);
8658
ok(!ref, "Got outstanding refcount %ld.\n", ref);
8659
IPin_Release(pin);
8660
IMemInputPin_Release(mem_input_pin);
8661
IDirectDrawMediaStream_Release(ddraw_stream);
8662
ref = IMediaStream_Release(stream);
8663
ok(!ref, "Got outstanding refcount %ld.\n", ref);
8664
}
8665
8666
static void test_ddrawstream_mem_allocator(void)
8667
{
8668
IDirectDrawStreamSample *ddraw_sample1, *ddraw_sample2, *ddraw_sample3;
8669
IMemAllocator *ddraw_allocator, *mem_allocator, *new_allocator;
8670
IAMMultiMediaStream *mmstream = create_ammultimediastream();
8671
IMediaSample *media_sample1, *media_sample2, *media_sample3;
8672
ALLOCATOR_PROPERTIES props, ret_props;
8673
IDirectDrawMediaStream *ddraw_stream;
8674
VIDEOINFO connect_video_info;
8675
IDirectDrawSurface *surface;
8676
VIDEOINFOHEADER *video_info;
8677
REFERENCE_TIME start, end;
8678
unsigned int expect_pitch;
8679
AM_MEDIA_TYPE *sample_mt;
8680
struct testfilter source;
8681
AM_MEDIA_TYPE connect_mt;
8682
IMemInputPin *mem_input;
8683
IGraphBuilder *graph;
8684
DDSURFACEDESC format;
8685
IMediaStream *stream;
8686
IDirectDraw *ddraw;
8687
HRESULT hr;
8688
ULONG ref;
8689
IPin *pin;
8690
LONG size;
8691
8692
DDSURFACEDESC surface_desc =
8693
{
8694
.dwSize = sizeof(DDSURFACEDESC),
8695
.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT,
8696
.dwHeight = 444,
8697
.dwWidth = 333,
8698
.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN,
8699
};
8700
8701
VIDEOINFO expect_video_info =
8702
{
8703
.rcSource = {0, 0, 333, 444},
8704
.rcTarget = {0, 0, 333, 444},
8705
.bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
8706
.bmiHeader.biHeight = -444,
8707
.bmiHeader.biPlanes = 1,
8708
.bmiHeader.biBitCount = 16,
8709
};
8710
8711
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
8712
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8713
8714
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
8715
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8716
8717
hr = IMediaStream_QueryInterface(stream, &IID_IMemInputPin, (void **)&mem_input);
8718
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8719
8720
hr = IMemInputPin_GetAllocatorRequirements(mem_input, &props);
8721
ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
8722
8723
hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
8724
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8725
8726
ddraw_allocator = NULL;
8727
hr = IMediaStream_QueryInterface(stream, &IID_IMemAllocator, (void **)&ddraw_allocator);
8728
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8729
8730
/* Check default properties. */
8731
hr = IMemAllocator_GetProperties(ddraw_allocator, &props);
8732
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8733
todo_wine ok(props.cbBuffer == 10000, "Got size %ld.\n", props.cbBuffer);
8734
ok(props.cBuffers == 1, "Got %ld buffers\n", props.cBuffers);
8735
ok(props.cbAlign == 1, "Got alignment %ld.\n", props.cbAlign);
8736
ok(!props.cbPrefix, "Got prefix %ld.\n", props.cbPrefix);
8737
8738
/* Try changing allocator properties. */
8739
props.cbAlign = 2;
8740
props.cbBuffer = 1000;
8741
props.cBuffers = 4;
8742
props.cbPrefix = 2;
8743
hr = IMemAllocator_SetProperties(ddraw_allocator, &props, &ret_props);
8744
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8745
todo_wine ok(ret_props.cbBuffer == 10000, "Got size %ld.\n", ret_props.cbBuffer);
8746
ok(ret_props.cBuffers == 4, "Got %ld buffers.\n", ret_props.cBuffers);
8747
ok(ret_props.cbAlign == 1, "Got alignment %ld.\n", ret_props.cbAlign);
8748
ok(!ret_props.cbPrefix, "Got prefix %ld.\n", ret_props.cbPrefix);
8749
8750
/* Check how allocator properties change when setting a new format. */
8751
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb32_format, NULL);
8752
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8753
8754
hr = IMemAllocator_GetProperties(ddraw_allocator, &props);
8755
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8756
ok(props.cbBuffer == 40000, "Got size %ld.\n", props.cbBuffer);
8757
ok(props.cBuffers == 4, "Got %ld buffers.\n", props.cBuffers);
8758
ok(props.cbAlign == 1, "Got alignment %ld.\n", props.cbAlign);
8759
ok(!props.cbPrefix, "Got prefix %ld.\n", props.cbPrefix);
8760
8761
props.cbAlign = 0;
8762
props.cbBuffer = 1000;
8763
props.cBuffers = 0;
8764
props.cbPrefix = 0;
8765
hr = IMemAllocator_SetProperties(ddraw_allocator, &props, &ret_props);
8766
ok(hr == VFW_E_BADALIGN, "Got hr %#lx.\n", hr);
8767
8768
props.cbAlign = 1;
8769
props.cbBuffer = 1000;
8770
props.cBuffers = 0;
8771
props.cbPrefix = 0;
8772
hr = IMemAllocator_SetProperties(ddraw_allocator, &props, &ret_props);
8773
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8774
ok(ret_props.cbBuffer == 40000, "Got size %ld.\n", ret_props.cbBuffer);
8775
ok(ret_props.cBuffers == 1, "Got %ld buffers.\n", ret_props.cBuffers);
8776
ok(ret_props.cbAlign == 1, "Got alignment %ld.\n", ret_props.cbAlign);
8777
ok(!ret_props.cbPrefix, "Got prefix %ld.\n", ret_props.cbPrefix);
8778
8779
/* Try setting a larger buffer size. */
8780
props.cbAlign = 1;
8781
props.cbBuffer = 50000;
8782
props.cBuffers = 1;
8783
props.cbPrefix = 0;
8784
hr = IMemAllocator_SetProperties(ddraw_allocator, &props, &ret_props);
8785
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8786
ok(ret_props.cbBuffer == 40000, "Got size %ld.\n", ret_props.cbBuffer);
8787
ok(ret_props.cBuffers == 1, "Got %ld buffers.\n", ret_props.cBuffers);
8788
ok(ret_props.cbAlign == 1, "Got alignment %ld.\n", ret_props.cbAlign);
8789
ok(!ret_props.cbPrefix, "Got prefix %ld.\n", ret_props.cbPrefix);
8790
8791
hr = IMemAllocator_GetBuffer(ddraw_allocator, &media_sample1, NULL, NULL, 0);
8792
ok(hr == VFW_E_NOT_COMMITTED, "Got hr %#lx.\n", hr);
8793
8794
hr = IMemAllocator_Commit(ddraw_allocator);
8795
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8796
8797
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb555_format, NULL);
8798
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8799
8800
hr = IMemAllocator_GetProperties(ddraw_allocator, &props);
8801
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8802
ok(props.cbBuffer == 20000, "Got size %ld.\n", props.cbBuffer);
8803
ok(props.cBuffers == 1, "Got %ld buffers.\n", props.cBuffers);
8804
ok(props.cbAlign == 1, "Got alignment %ld.\n", props.cbAlign);
8805
ok(!props.cbPrefix, "Got prefix %ld.\n", props.cbPrefix);
8806
8807
/* GetBuffer() hangs here, even with AM_GBF_NOWAIT. */
8808
8809
hr = IMemAllocator_Decommit(ddraw_allocator);
8810
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8811
8812
hr = IMemAllocator_GetBuffer(ddraw_allocator, &media_sample1, NULL, NULL, 0);
8813
ok(hr == VFW_E_NOT_COMMITTED, "Got hr %#lx.\n", hr);
8814
8815
mem_allocator = NULL;
8816
hr = IMemInputPin_GetAllocator(mem_input, &mem_allocator);
8817
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8818
ok(mem_allocator == ddraw_allocator, "Expected GetAllocator to return ddraw allocator.\n");
8819
8820
check_interface(mem_allocator, &IID_IDirectDrawMediaStream, TRUE);
8821
IMemAllocator_Release(mem_allocator);
8822
8823
hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER,
8824
&IID_IMemAllocator, (void **)&new_allocator);
8825
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8826
8827
props.cbAlign = 1;
8828
props.cbBuffer = 10000;
8829
props.cBuffers = 0;
8830
props.cbPrefix = 0;
8831
hr = IMemAllocator_SetProperties(new_allocator, &props, &ret_props);
8832
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8833
8834
hr = IMemInputPin_NotifyAllocator(mem_input, new_allocator, TRUE);
8835
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8836
8837
mem_allocator = NULL;
8838
hr = IMemInputPin_GetAllocator(mem_input, &mem_allocator);
8839
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8840
ok(mem_allocator == ddraw_allocator, "Expected GetAllocator to return ddraw allocator.\n");
8841
check_interface(mem_allocator, &IID_IDirectDrawMediaStream, TRUE);
8842
8843
IMemInputPin_Release(mem_input);
8844
8845
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
8846
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8847
ok(!!graph, "Expected non-NULL graph.\n");
8848
8849
testfilter_init(&source);
8850
source.use_input_pin_allocator = TRUE;
8851
source.preferred_mt = &rgb24_mt;
8852
8853
hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, L"source");
8854
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8855
8856
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
8857
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8858
8859
/* Connect with a bottom-up format. Note that the media type set on the
8860
* returned samples is top-down regardless. */
8861
connect_video_info = rgb555_video_info;
8862
connect_video_info.bmiHeader.biHeight = 444;
8863
connect_mt = rgb555_mt;
8864
connect_mt.pbFormat = (BYTE *)&connect_video_info;
8865
hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &connect_mt);
8866
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8867
video_info = (VIDEOINFOHEADER *)source.source.pin.mt.pbFormat;
8868
ok(video_info->bmiHeader.biHeight == 444, "Got height %ld.\n", video_info->bmiHeader.biHeight);
8869
8870
source.verify_query_accept_mt = true;
8871
8872
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb555_format, NULL);
8873
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8874
8875
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
8876
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8877
8878
props.cbAlign = 1;
8879
props.cbBuffer = 50000;
8880
props.cBuffers = 1;
8881
props.cbPrefix = 0;
8882
hr = IMemAllocator_SetProperties(ddraw_allocator, &props, &ret_props);
8883
ok(hr == VFW_E_ALREADY_COMMITTED, "Got hr %#lx.\n", hr);
8884
8885
source.query_accept_subtype = MEDIASUBTYPE_RGB32;
8886
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb32_format, NULL);
8887
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8888
8889
hr = IMemAllocator_GetProperties(ddraw_allocator, &props);
8890
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8891
ok(props.cbBuffer == 333 * 444 * 4, "Got size %ld.\n", props.cbBuffer);
8892
ok(props.cBuffers == 2, "Got %ld buffers.\n", props.cBuffers);
8893
ok(props.cbAlign == 1, "Got alignment %ld.\n", props.cbAlign);
8894
ok(!props.cbPrefix, "Got prefix %ld.\n", props.cbPrefix);
8895
8896
source.query_accept_subtype = MEDIASUBTYPE_RGB555;
8897
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb555_format, NULL);
8898
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8899
8900
hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw);
8901
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8902
surface_desc.ddpfPixelFormat = rgb555_format.ddpfPixelFormat;
8903
hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface, NULL);
8904
ok(hr == S_OK, "got hr %#lx\n", hr);
8905
hr = IDirectDrawSurface_GetSurfaceDesc(surface, &surface_desc);
8906
ok(hr == S_OK, "got hr %#lx\n", hr);
8907
expect_pitch = surface_desc.lPitch;
8908
expect_video_info.bmiHeader.biWidth = expect_pitch / 2;
8909
expect_video_info.bmiHeader.biSizeImage = expect_pitch * 444;
8910
IDirectDrawSurface_Release(surface);
8911
IDirectDraw_Release(ddraw);
8912
8913
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &ddraw_sample1);
8914
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8915
8916
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb32_format, NULL);
8917
ok(hr == MS_E_SAMPLEALLOC, "Got hr %#lx.\n", hr);
8918
8919
/* We cannot retrieve the sample from GetBuffer() without calling Update().
8920
* Otherwise GetBuffer() will hang as there are no samples to return. */
8921
hr = IDirectDrawStreamSample_Update(ddraw_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
8922
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
8923
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &ddraw_sample2);
8924
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8925
hr = IDirectDrawStreamSample_Update(ddraw_sample2, SSUPDATE_ASYNC, NULL, NULL, 0);
8926
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
8927
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &ddraw_sample3);
8928
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8929
hr = IDirectDrawStreamSample_Update(ddraw_sample3, SSUPDATE_ASYNC, NULL, NULL, 0);
8930
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
8931
8932
hr = IMemAllocator_GetBuffer(mem_allocator, &media_sample1, NULL, NULL, 0);
8933
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8934
hr = IMediaSample_GetMediaType(media_sample1, &sample_mt);
8935
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8936
ok(IsEqualGUID(&sample_mt->majortype, &MEDIATYPE_Video),
8937
"Got major type %s.\n", debugstr_guid(&sample_mt->majortype));
8938
ok(IsEqualGUID(&sample_mt->subtype, &MEDIASUBTYPE_RGB555),
8939
"Got subtype %s.\n", debugstr_guid(&sample_mt->subtype));
8940
ok(sample_mt->bFixedSizeSamples == TRUE, "Got fixed size %d.\n", sample_mt->bFixedSizeSamples);
8941
ok(!sample_mt->bTemporalCompression, "Got temporal compression %d.\n", sample_mt->bTemporalCompression);
8942
ok(sample_mt->lSampleSize == expect_pitch * 444,
8943
"Expected sample size %u, got %lu.\n", expect_pitch * 444, sample_mt->lSampleSize);
8944
ok(IsEqualGUID(&sample_mt->formattype, &FORMAT_VideoInfo),
8945
"Got format type %s.\n", debugstr_guid(&sample_mt->formattype));
8946
ok(!sample_mt->pUnk, "Got pUnk %p.\n", sample_mt->pUnk);
8947
ok(sample_mt->cbFormat == sizeof(VIDEOINFO), "Got format size %lu.\n", sample_mt->cbFormat);
8948
ok(!memcmp(sample_mt->pbFormat, &expect_video_info, sizeof(VIDEOINFO)), "Format blocks didn't match.\n");
8949
8950
sample_mt->lSampleSize = 123;
8951
hr = IMediaSample_SetMediaType(media_sample1, sample_mt);
8952
todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
8953
8954
DeleteMediaType(sample_mt);
8955
8956
hr = IMediaSample_GetMediaType(media_sample1, &sample_mt);
8957
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8958
ok(sample_mt->lSampleSize == expect_pitch * 444,
8959
"Expected sample size %u, got %lu.\n", expect_pitch * 444, sample_mt->lSampleSize);
8960
8961
video_info = (VIDEOINFOHEADER *)sample_mt->pbFormat;
8962
video_info->bmiHeader.biWidth = 400;
8963
video_info->bmiHeader.biHeight = -400;
8964
video_info->bmiHeader.biSizeImage = 400 * 400 * 2;
8965
SetRect(&video_info->rcSource, 0, 0, 400, 400);
8966
SetRect(&video_info->rcTarget, 0, 0, 400, 400);
8967
hr = IMediaSample_SetMediaType(media_sample1, sample_mt);
8968
todo_wine ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
8969
8970
DeleteMediaType(sample_mt);
8971
8972
hr = IMemAllocator_GetBuffer(mem_allocator, &media_sample2, NULL, NULL, 0);
8973
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8974
hr = IMediaSample_GetMediaType(media_sample2, &sample_mt);
8975
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8976
ok(IsEqualGUID(&sample_mt->subtype, &MEDIASUBTYPE_RGB555),
8977
"Got subtype %s.\n", wine_dbgstr_guid(&sample_mt->subtype));
8978
DeleteMediaType(sample_mt);
8979
8980
hr = IMemAllocator_GetBuffer(mem_allocator, &media_sample3, NULL, NULL, AM_GBF_NOWAIT);
8981
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8982
8983
/* GetBuffer() again blocks, even with AM_GBF_NOWAIT. */
8984
8985
ok(media_sample1 != media_sample2, "Expected different samples.\n");
8986
8987
check_interface(media_sample1, &IID_IDirectDrawStreamSample, FALSE);
8988
check_interface(media_sample1, &IID_IMediaSample2, FALSE);
8989
8990
hr = IMemAllocator_GetProperties(ddraw_allocator, &props);
8991
ok(hr == S_OK, "Got hr %#lx.\n", hr);
8992
ok(props.cBuffers == 2, "Expected 2 samples got %ld\n", props.cBuffers);
8993
8994
size = IMediaSample_GetSize(media_sample1);
8995
ok(size == expect_pitch * 444, "Expected size %u, got %ld.\n", expect_pitch * 444, size);
8996
size = IMediaSample_GetActualDataLength(media_sample1);
8997
ok(size == expect_pitch * 444, "Expected size %u, got %ld.\n", expect_pitch * 444, size);
8998
hr = IMediaSample_SetActualDataLength(media_sample1, size);
8999
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9000
hr = IMediaSample_SetActualDataLength(media_sample1, size + 1);
9001
ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
9002
hr = IMediaSample_SetActualDataLength(media_sample1, size - 1);
9003
ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
9004
9005
start = end = 0xdeadbeef;
9006
hr = IMediaSample_GetTime(media_sample1, &start, &end);
9007
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9008
ok(!start, "Got start %I64d.\n", start);
9009
ok(!end, "Got end %I64d.\n", end);
9010
9011
start = end = 0xdeadbeef;
9012
hr = IMediaSample_GetMediaTime(media_sample1, &start, &end);
9013
ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
9014
ok(start == 0xdeadbeef, "Got start %I64d.\n", start);
9015
ok(end == 0xdeadbeef, "Got end %I64d.\n", end);
9016
9017
hr = IMediaSample_IsSyncPoint(media_sample1);
9018
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9019
hr = IMediaSample_IsPreroll(media_sample1);
9020
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
9021
hr = IMediaSample_IsDiscontinuity(media_sample1);
9022
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
9023
9024
start = 123;
9025
end = 456;
9026
hr = IMediaSample_SetMediaTime(media_sample1, &start, &end);
9027
ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
9028
hr = IMediaSample_SetTime(media_sample1, &start, &end);
9029
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9030
start = end = 0xdeadbeef;
9031
hr = IMediaSample_GetTime(media_sample1, &start, &end);
9032
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9033
ok(start == 123, "Got start %I64d.\n", start);
9034
ok(end == 456, "Got end %I64d.\n", end);
9035
9036
/* SetTime() does not correctly handle NULL parameters. Instead they are
9037
* interpreted as "no change". */
9038
start = 555;
9039
end = 666;
9040
hr = IMediaSample_SetTime(media_sample1, &start, NULL);
9041
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9042
hr = IMediaSample_SetTime(media_sample1, NULL, &end);
9043
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9044
hr = IMediaSample_SetTime(media_sample1, NULL, NULL);
9045
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9046
start = end = 0xdeadbeef;
9047
hr = IMediaSample_GetTime(media_sample1, &start, &end);
9048
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9049
ok(start == 555, "Got start %I64d.\n", start);
9050
ok(end == 666, "Got end %I64d.\n", end);
9051
9052
start = end = 0xdeadbeef;
9053
hr = IDirectDrawStreamSample_GetSampleTimes(ddraw_sample1, &start, &end, NULL);
9054
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9055
ok(start == 555, "Got start %I64d.\n", start);
9056
ok(end == 666, "Got end %I64d.\n", end);
9057
9058
hr = IMediaSample_SetSyncPoint(media_sample1, FALSE);
9059
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9060
hr = IMediaSample_SetDiscontinuity(media_sample1, TRUE);
9061
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9062
hr = IMediaSample_SetPreroll(media_sample1, TRUE);
9063
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9064
9065
hr = IMediaSample_IsSyncPoint(media_sample1);
9066
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
9067
hr = IMediaSample_IsPreroll(media_sample1);
9068
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9069
hr = IMediaSample_IsDiscontinuity(media_sample1);
9070
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9071
9072
ref = IMediaSample_Release(media_sample1);
9073
ok(!ref, "Got refcount %ld.\n", ref);
9074
9075
hr = IMemAllocator_GetBuffer(mem_allocator, &media_sample1, NULL, NULL, 0);
9076
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9077
9078
start = end = 0xdeadbeef;
9079
hr = IMediaSample_GetTime(media_sample1, &start, &end);
9080
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9081
ok(start == 555, "Got start %I64d.\n", start);
9082
ok(end == 666, "Got end %I64d.\n", end);
9083
hr = IMediaSample_IsSyncPoint(media_sample1);
9084
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9085
hr = IMediaSample_IsPreroll(media_sample1);
9086
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9087
hr = IMediaSample_IsDiscontinuity(media_sample1);
9088
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
9089
9090
hr = IDirectDrawStreamSample_CompletionStatus(ddraw_sample2, 0, 0);
9091
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
9092
9093
hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample2);
9094
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9095
9096
hr = IDirectDrawStreamSample_CompletionStatus(ddraw_sample2, 0, 0);
9097
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
9098
hr = IDirectDrawStreamSample_Update(ddraw_sample2, SSUPDATE_ASYNC, NULL, NULL, 0);
9099
ok(hr == MS_E_BUSY, "Got hr %#lx.\n", hr);
9100
9101
ref = IMediaSample_Release(media_sample2);
9102
ok(!ref, "Got refcount %ld.\n", ref);
9103
9104
hr = IDirectDrawStreamSample_CompletionStatus(ddraw_sample2, 0, 0);
9105
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9106
9107
hr = IMemAllocator_SetProperties(mem_allocator, &props, &ret_props);
9108
ok(hr == VFW_E_ALREADY_COMMITTED, "Got hr %#lx.\n", hr);
9109
hr = IMemAllocator_Decommit(mem_allocator);
9110
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9111
hr = IMemAllocator_SetProperties(mem_allocator, &props, &ret_props);
9112
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9113
9114
hr = IDirectDrawStreamSample_CompletionStatus(ddraw_sample3, COMPSTAT_NOUPDATEOK, 0);
9115
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
9116
9117
ref = IMediaSample_Release(media_sample3);
9118
ok(!ref, "Got refcount %ld.\n", ref);
9119
9120
hr = IDirectDrawStreamSample_CompletionStatus(ddraw_sample3, 0, 0);
9121
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
9122
hr = IDirectDrawStreamSample_CompletionStatus(ddraw_sample3, COMPSTAT_NOUPDATEOK, 0);
9123
todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
9124
9125
hr = IMemAllocator_GetBuffer(mem_allocator, &media_sample3, NULL, NULL, 0);
9126
ok(hr == VFW_E_NOT_COMMITTED, "Got hr %#lx.\n", hr);
9127
9128
ref = IMediaSample_Release(media_sample1);
9129
ok(!ref, "Got refcount %ld.\n", ref);
9130
9131
/* The sample does need to be received before it's considered updated. */
9132
hr = IDirectDrawStreamSample_CompletionStatus(ddraw_sample1, 0, 0);
9133
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
9134
9135
ref = IDirectDrawStreamSample_Release(ddraw_sample1);
9136
ok(!ref, "Got refcount %ld.\n", ref);
9137
ref = IDirectDrawStreamSample_Release(ddraw_sample2);
9138
ok(!ref, "Got refcount %ld.\n", ref);
9139
ref = IDirectDrawStreamSample_Release(ddraw_sample3);
9140
ok(!ref, "Got refcount %ld.\n", ref);
9141
9142
source.query_accept_width = 222;
9143
source.query_accept_height = 555;
9144
source.query_accept_subtype = MEDIASUBTYPE_RGB32;
9145
9146
format = rgb32_format;
9147
format.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT;
9148
format.dwWidth = 222;
9149
format.dwHeight = 555;
9150
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &format, NULL);
9151
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9152
/* And clear the flags. As with sample allocation in general, the format is
9153
* retained. */
9154
format = rgb32_format;
9155
format.dwFlags = 0;
9156
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &format, NULL);
9157
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9158
9159
ok(IsEqualGUID(&source.source.pin.mt.subtype, &MEDIASUBTYPE_RGB555),
9160
"Got subtype %s.\n", wine_dbgstr_guid(&source.source.pin.mt.subtype));
9161
video_info = (VIDEOINFOHEADER *)source.source.pin.mt.pbFormat;
9162
ok(video_info->bmiHeader.biWidth == 333, "Got width %ld.\n", video_info->bmiHeader.biWidth);
9163
ok(video_info->bmiHeader.biHeight == 444, "Got height %ld.\n", video_info->bmiHeader.biHeight);
9164
9165
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &ddraw_sample1);
9166
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9167
hr = IDirectDrawStreamSample_Update(ddraw_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
9168
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
9169
9170
hr = IMemAllocator_Commit(mem_allocator);
9171
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9172
9173
hr = IMemAllocator_GetBuffer(mem_allocator, &media_sample1, NULL, NULL, 0);
9174
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9175
9176
SetRect(&expect_video_info.rcSource, 0, 0, 222, 555);
9177
SetRect(&expect_video_info.rcTarget, 0, 0, 222, 555);
9178
expect_video_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
9179
expect_video_info.bmiHeader.biWidth = 222,
9180
expect_video_info.bmiHeader.biHeight = -555,
9181
expect_video_info.bmiHeader.biSizeImage = 222 * 555 * 4,
9182
expect_video_info.bmiHeader.biPlanes = 1,
9183
expect_video_info.bmiHeader.biBitCount = 32,
9184
9185
hr = IMediaSample_GetMediaType(media_sample1, &sample_mt);
9186
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9187
ok(IsEqualGUID(&sample_mt->majortype, &MEDIATYPE_Video),
9188
"Got major type %s.\n", debugstr_guid(&sample_mt->majortype));
9189
ok(IsEqualGUID(&sample_mt->subtype, &MEDIASUBTYPE_RGB32),
9190
"Got subtype %s.\n", debugstr_guid(&sample_mt->subtype));
9191
ok(sample_mt->bFixedSizeSamples == TRUE, "Got fixed size %d.\n", sample_mt->bFixedSizeSamples);
9192
ok(!sample_mt->bTemporalCompression, "Got temporal compression %d.\n", sample_mt->bTemporalCompression);
9193
ok(sample_mt->lSampleSize == 222 * 555 * 4,
9194
"Expected sample size %u, got %lu.\n", 222 * 555 * 4, sample_mt->lSampleSize);
9195
ok(IsEqualGUID(&sample_mt->formattype, &FORMAT_VideoInfo),
9196
"Got format type %s.\n", debugstr_guid(&sample_mt->formattype));
9197
ok(!sample_mt->pUnk, "Got pUnk %p.\n", sample_mt->pUnk);
9198
ok(sample_mt->cbFormat == sizeof(VIDEOINFO), "Got format size %lu.\n", sample_mt->cbFormat);
9199
ok(!memcmp(sample_mt->pbFormat, &expect_video_info, sizeof(VIDEOINFO)), "Format blocks didn't match.\n");
9200
9201
ref = IMediaSample_Release(media_sample1);
9202
ok(!ref, "Got refcount %ld.\n", ref);
9203
ref = IDirectDrawStreamSample_Release(ddraw_sample1);
9204
ok(!ref, "Got refcount %ld.\n", ref);
9205
9206
IMemAllocator_Release(mem_allocator);
9207
9208
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
9209
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9210
9211
ref = IMemAllocator_Release(new_allocator);
9212
ok(!ref, "Got outstanding refcount %ld.\n", ref);
9213
IDirectDrawMediaStream_Release(ddraw_stream);
9214
IMemAllocator_Release(ddraw_allocator);
9215
IGraphBuilder_Disconnect(graph, pin);
9216
IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
9217
IPin_Release(pin);
9218
IGraphBuilder_Release(graph);
9219
9220
ref = IAMMultiMediaStream_Release(mmstream);
9221
ok(!ref, "Got outstanding refcount %ld.\n", ref);
9222
ref = IMediaStream_Release(stream);
9223
ok(!ref, "Got outstanding refcount %ld.\n", ref);
9224
}
9225
9226
static void test_ddrawstream_set_format_dynamic(void)
9227
{
9228
PALETTEENTRY palette_entries[256] = {0};
9229
IDirectDrawMediaStream *ddraw_stream;
9230
IAMMultiMediaStream *mmstream;
9231
DDSURFACEDESC current_format;
9232
DDSURFACEDESC desired_format;
9233
IDirectDrawPalette *palette;
9234
struct testfilter source;
9235
IGraphBuilder *graph;
9236
DDSURFACEDESC format;
9237
IMediaStream *stream;
9238
VIDEOINFO video_info;
9239
IDirectDraw *ddraw;
9240
AM_MEDIA_TYPE mt;
9241
HRESULT hr;
9242
ULONG ref;
9243
IPin *pin;
9244
9245
mmstream = create_ammultimediastream();
9246
9247
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
9248
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9249
hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
9250
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9251
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
9252
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9253
9254
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
9255
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9256
ok(!!graph, "Expected non-NULL graph.\n");
9257
9258
testfilter_init(&source);
9259
source.use_input_pin_allocator = TRUE;
9260
9261
hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, L"source");
9262
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9263
9264
hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &rgb8_mt);
9265
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9266
9267
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
9268
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9269
9270
source.preferred_mt = NULL;
9271
source.query_accept_hr = S_OK;
9272
source.verify_query_accept_mt = true;
9273
9274
source.query_accept_subtype = MEDIASUBTYPE_RGB565;
9275
9276
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb565_format, NULL);
9277
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9278
ok(IsEqualGUID(&source.source.pin.mt.subtype, &MEDIASUBTYPE_RGB8),
9279
"Got subtype %s.\n", wine_dbgstr_guid(&source.source.pin.mt.subtype));
9280
hr = IPin_ConnectionMediaType(pin, &mt);
9281
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9282
ok(IsEqualGUID(&mt.subtype, &MEDIASUBTYPE_RGB8),
9283
"Got subtype %s.\n", wine_dbgstr_guid(&mt.subtype));
9284
CoTaskMemFree(mt.pbFormat);
9285
hr = IDirectDrawMediaStream_GetFormat(ddraw_stream, &current_format, NULL, &desired_format, NULL);
9286
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9287
ok(current_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT),
9288
"Got flags %#lx.\n", current_format.dwFlags);
9289
ok(current_format.dwWidth == 333, "Got width %ld.\n", current_format.dwWidth);
9290
ok(current_format.dwHeight == 444, "Got height %ld.\n", current_format.dwHeight);
9291
ok(current_format.ddpfPixelFormat.dwRGBBitCount == 16,
9292
"Got rgb bit count %lu.\n", current_format.ddpfPixelFormat.dwRGBBitCount);
9293
ok(desired_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT),
9294
"Got flags %#lx.\n", desired_format.dwFlags);
9295
ok(desired_format.dwWidth == 333, "Got width %ld.\n", desired_format.dwWidth);
9296
ok(desired_format.dwHeight == 444, "Got height %ld.\n", desired_format.dwHeight);
9297
ok(desired_format.ddpfPixelFormat.dwRGBBitCount == 16,
9298
"Got rgb bit count %lu.\n", desired_format.ddpfPixelFormat.dwRGBBitCount);
9299
9300
format = rgb555_format;
9301
format.dwFlags = 0;
9302
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &format, NULL);
9303
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9304
ok(IsEqualGUID(&source.source.pin.mt.subtype, &MEDIASUBTYPE_RGB8),
9305
"Got subtype %s.\n", wine_dbgstr_guid(&source.source.pin.mt.subtype));
9306
9307
source.preferred_mt = &rgb555_mt;
9308
9309
/* RGB8 without a palette translate to a palette full of zeroes. */
9310
source.query_accept_subtype = MEDIASUBTYPE_RGB8;
9311
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb8_format, NULL);
9312
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9313
9314
hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw);
9315
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9316
palette_entries[0].peRed = 0x12;
9317
palette_entries[1].peBlue = 0x34;
9318
palette_entries[2].peGreen = 0x56;
9319
hr = IDirectDraw_CreatePalette(ddraw, DDPCAPS_8BIT | DDPCAPS_ALLOW256, palette_entries, &palette, NULL);
9320
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9321
9322
/* Setting a new palette when the format is already RGB8 does not trigger
9323
* QueryAccept(). */
9324
source.query_accept_subtype = MEDIASUBTYPE_RGB8;
9325
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb8_format, palette);
9326
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9327
9328
source.query_accept_subtype = MEDIASUBTYPE_RGB24;
9329
format = rgb24_format;
9330
/* Set the width and height but don't set the flags. */
9331
format.dwWidth = 100;
9332
format.dwHeight = 200;
9333
source.query_accept_width = 100;
9334
source.query_accept_height = 200;
9335
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &format, NULL);
9336
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9337
source.query_accept_width = source.query_accept_height = 0;
9338
9339
/* Setting RGB8 with a palette does translate the palette. */
9340
source.query_accept_subtype = MEDIASUBTYPE_RGB8;
9341
source.query_accept_rgb8_palette = true;
9342
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb8_format, palette);
9343
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9344
source.query_accept_rgb8_palette = false;
9345
IDirectDrawPalette_Release(palette);
9346
IDirectDraw_Release(ddraw);
9347
9348
source.query_accept_subtype = MEDIASUBTYPE_RGB555;
9349
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb555_format, NULL);
9350
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9351
ok(IsEqualGUID(&source.source.pin.mt.subtype, &MEDIASUBTYPE_RGB8),
9352
"Got subtype %s.\n", wine_dbgstr_guid(&source.source.pin.mt.subtype));
9353
hr = IDirectDrawMediaStream_GetFormat(ddraw_stream, &current_format, NULL, &desired_format, NULL);
9354
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9355
ok(current_format.ddpfPixelFormat.dwRGBBitCount == 16,
9356
"Got rgb bit count %lu.\n", current_format.ddpfPixelFormat.dwRGBBitCount);
9357
ok(desired_format.ddpfPixelFormat.dwRGBBitCount == 16,
9358
"Got rgb bit count %lu.\n", desired_format.ddpfPixelFormat.dwRGBBitCount);
9359
9360
video_info = rgb555_video_info;
9361
video_info.bmiHeader.biWidth = 222;
9362
video_info.bmiHeader.biHeight = -555;
9363
mt = rgb555_mt;
9364
mt.pbFormat = (BYTE *)&video_info;
9365
source.preferred_mt = &mt;
9366
9367
source.query_accept_subtype = MEDIASUBTYPE_RGB555;
9368
source.query_accept_width = 222;
9369
source.query_accept_height = 555;
9370
9371
format = rgb555_format;
9372
format.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT;
9373
format.dwWidth = 222;
9374
format.dwHeight = 555;
9375
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &format, NULL);
9376
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9377
ok(IsEqualGUID(&source.source.pin.mt.subtype, &MEDIASUBTYPE_RGB8),
9378
"Got subtype %s.\n", wine_dbgstr_guid(&source.source.pin.mt.subtype));
9379
ok(((VIDEOINFO *)source.source.pin.mt.pbFormat)->bmiHeader.biWidth == 333,
9380
"Got width %ld.\n", ((VIDEOINFO *)source.source.pin.mt.pbFormat)->bmiHeader.biWidth);
9381
ok(((VIDEOINFO *)source.source.pin.mt.pbFormat)->bmiHeader.biHeight == -444,
9382
"Got height %ld.\n", ((VIDEOINFO *)source.source.pin.mt.pbFormat)->bmiHeader.biHeight);
9383
9384
source.query_accept_hr = S_FALSE;
9385
source.query_accept_subtype = MEDIASUBTYPE_RGB8;
9386
source.query_accept_width = source.query_accept_height = 0;
9387
9388
hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb8_format, NULL);
9389
ok(hr == DDERR_INVALIDSURFACETYPE, "Got hr %#lx.\n", hr);
9390
ok(IsEqualGUID(&source.source.pin.mt.subtype, &MEDIASUBTYPE_RGB8),
9391
"Got subtype %s.\n", wine_dbgstr_guid(&source.source.pin.mt.subtype));
9392
memset(&current_format, 0, sizeof(current_format));
9393
memset(&desired_format, 0, sizeof(desired_format));
9394
hr = IDirectDrawMediaStream_GetFormat(ddraw_stream, &current_format, NULL, &desired_format, NULL);
9395
/* FIXME: The peer is not able to reconnect while the stream is running, so it stays disconnected. */
9396
todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
9397
todo_wine ok(current_format.ddpfPixelFormat.dwRGBBitCount == 16,
9398
"Got rgb bit count %lu.\n", current_format.ddpfPixelFormat.dwRGBBitCount);
9399
todo_wine ok(desired_format.ddpfPixelFormat.dwRGBBitCount == 16,
9400
"Got rgb bit count %lu.\n", desired_format.ddpfPixelFormat.dwRGBBitCount);
9401
9402
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
9403
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9404
hr = IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
9405
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9406
hr = IGraphBuilder_Disconnect(graph, pin);
9407
todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
9408
9409
ref = IAMMultiMediaStream_Release(mmstream);
9410
ok(!ref, "Got outstanding refcount %ld.\n", ref);
9411
ref = IGraphBuilder_Release(graph);
9412
ok(!ref, "Got outstanding refcount %ld.\n", ref);
9413
IPin_Release(pin);
9414
IDirectDrawMediaStream_Release(ddraw_stream);
9415
ref = IMediaStream_Release(stream);
9416
ok(!ref, "Got outstanding refcount %ld.\n", ref);
9417
}
9418
9419
static void test_ddrawstreamsample_get_media_stream(void)
9420
{
9421
IAMMultiMediaStream *mmstream = create_ammultimediastream();
9422
IDirectDrawMediaStream *ddraw_stream;
9423
IDirectDrawStreamSample *sample;
9424
IMediaStream *stream, *stream2;
9425
IDirectDraw *ddraw;
9426
HRESULT hr;
9427
ULONG ref;
9428
9429
hr = DirectDrawCreate(NULL, &ddraw, NULL);
9430
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9431
9432
hr = IDirectDraw_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL);
9433
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9434
9435
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
9436
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9437
9438
hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)ddraw, &MSPID_PrimaryVideo, 0, &stream);
9439
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9440
9441
hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
9442
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9443
9444
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &sample);
9445
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9446
9447
/* Crashes on native. */
9448
if (0)
9449
{
9450
hr = IDirectDrawStreamSample_GetMediaStream(sample, NULL);
9451
ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
9452
}
9453
9454
EXPECT_REF(stream, 4);
9455
hr = IDirectDrawStreamSample_GetMediaStream(sample, &stream2);
9456
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9457
ok(stream2 == stream, "Expected stream %p, got %p.\n", stream, stream2);
9458
EXPECT_REF(stream, 5);
9459
IMediaStream_Release(stream2);
9460
EXPECT_REF(stream, 4);
9461
9462
IDirectDrawMediaStream_Release(ddraw_stream);
9463
ref = IDirectDrawStreamSample_Release(sample);
9464
ok(!ref, "Got outstanding refcount %ld.\n", ref);
9465
ref = IAMMultiMediaStream_Release(mmstream);
9466
ok(!ref, "Got outstanding refcount %ld.\n", ref);
9467
ref = IMediaStream_Release(stream);
9468
ok(!ref, "Got outstanding refcount %ld.\n", ref);
9469
ref = IDirectDraw_Release(ddraw);
9470
ok(!ref, "Got outstanding refcount %ld.\n", ref);
9471
}
9472
9473
static void test_ddrawstreamsample_update(void)
9474
{
9475
static const BYTE initial_data[] =
9476
{
9477
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
9478
};
9479
static const BYTE test_data[] =
9480
{
9481
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
9482
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
9483
};
9484
IAMMultiMediaStream *mmstream = create_ammultimediastream();
9485
IDirectDrawStreamSample *stream_sample;
9486
struct advise_time_cookie cookie = {0};
9487
IDirectDrawMediaStream *ddraw_stream;
9488
IMediaControl *media_control;
9489
IDirectDrawSurface *surface;
9490
IMemInputPin *mem_input_pin;
9491
IMediaSample *media_sample;
9492
IMediaFilter *media_filter;
9493
REFERENCE_TIME start_time;
9494
REFERENCE_TIME end_time;
9495
struct testfilter source;
9496
struct testclock clock;
9497
IGraphBuilder *graph;
9498
IMediaStream *stream;
9499
VIDEOINFO video_info;
9500
DDSURFACEDESC desc;
9501
IDirectDraw *ddraw;
9502
AM_MEDIA_TYPE mt;
9503
HANDLE thread;
9504
HANDLE event;
9505
HRESULT hr;
9506
ULONG ref;
9507
IPin *pin;
9508
RECT rect;
9509
int i;
9510
9511
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
9512
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9513
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
9514
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9515
hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
9516
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9517
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
9518
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9519
hr = IMediaStream_QueryInterface(stream, &IID_IMemInputPin, (void **)&mem_input_pin);
9520
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9521
hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw);
9522
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9523
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
9524
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9525
ok(graph != NULL, "Expected non-NULL graph.\n");
9526
hr = IGraphBuilder_QueryInterface(graph, &IID_IMediaControl, (void **)&media_control);
9527
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9528
hr = IGraphBuilder_QueryInterface(graph, &IID_IMediaFilter, (void **)&media_filter);
9529
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9530
testfilter_init(&source);
9531
hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
9532
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9533
testclock_init(&clock);
9534
event = CreateEventW(NULL, FALSE, FALSE, NULL);
9535
ok(event != NULL, "Expected non-NULL event.");
9536
cookie.advise_time_called_event = CreateEventW(NULL, FALSE, FALSE, NULL);
9537
ok(cookie.advise_time_called_event != NULL, "Expected non-NULL event.");
9538
9539
hr = IMediaFilter_SetSyncSource(media_filter, NULL);
9540
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9541
9542
desc = rgb24_format;
9543
desc.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
9544
desc.dwWidth = 4;
9545
desc.dwHeight = 5;
9546
desc.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
9547
hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
9548
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9549
/* Make the rect width equal to the surface width, as the native
9550
* implementation incorrectly handles rects that are not full-width
9551
* when the ddraw stream's custom allocator is not used. */
9552
SetRect(&rect, 0, 1, 4, 3);
9553
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, surface, &rect, 0, &stream_sample);
9554
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9555
9556
hr = IDirectDrawStreamSample_Update(stream_sample, 0, event, apc_func, 0);
9557
ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
9558
9559
hr = IDirectDrawStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
9560
ok(hr == MS_E_NOTRUNNING, "Got hr %#lx.\n", hr);
9561
9562
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
9563
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9564
9565
hr = IDirectDrawStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
9566
ok(hr == MS_S_ENDOFSTREAM, "Got hr %#lx.\n", hr);
9567
9568
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
9569
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9570
video_info = rgb24_video_info;
9571
video_info.bmiHeader.biWidth = 4;
9572
video_info.bmiHeader.biHeight = -2;
9573
mt = rgb24_mt;
9574
mt.pbFormat = (BYTE *)&video_info;
9575
hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
9576
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9577
9578
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
9579
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9580
9581
hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
9582
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9583
for (i = 0; i < 5; ++i)
9584
memcpy((BYTE *)desc.lpSurface + i * desc.lPitch, initial_data, 12);
9585
hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
9586
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9587
9588
media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
9589
9590
ammediastream_mem_input_pin = mem_input_pin;
9591
ammediastream_media_sample = media_sample;
9592
ammediastream_sleep_time = 0;
9593
ammediastream_expected_hr = S_OK;
9594
thread = CreateThread(NULL, 0, ammediastream_receive, NULL, 0, NULL);
9595
9596
Sleep(100);
9597
hr = IDirectDrawStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
9598
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9599
hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
9600
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9601
ok(memcmp((BYTE *)desc.lpSurface + 0 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
9602
ok(memcmp((BYTE *)desc.lpSurface + 1 * desc.lPitch, &test_data[0], 12) == 0, "Sample data didn't match.\n");
9603
ok(memcmp((BYTE *)desc.lpSurface + 2 * desc.lPitch, &test_data[12], 12) == 0, "Sample data didn't match.\n");
9604
ok(memcmp((BYTE *)desc.lpSurface + 3 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
9605
ok(memcmp((BYTE *)desc.lpSurface + 4 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
9606
hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
9607
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9608
9609
ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
9610
CloseHandle(thread);
9611
9612
ref = IMediaSample_Release(media_sample);
9613
ok(!ref, "Got outstanding refcount %ld.\n", ref);
9614
9615
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
9616
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9617
IGraphBuilder_Disconnect(graph, pin);
9618
IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
9619
video_info = rgb24_video_info;
9620
video_info.bmiHeader.biWidth = 4;
9621
video_info.bmiHeader.biHeight = 2;
9622
mt = rgb24_mt;
9623
mt.pbFormat = (BYTE *)&video_info;
9624
hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
9625
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9626
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
9627
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9628
9629
hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
9630
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9631
for (i = 0; i < 5; ++i)
9632
memcpy((BYTE *)desc.lpSurface + i * desc.lPitch, initial_data, 12);
9633
hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
9634
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9635
9636
media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
9637
9638
ammediastream_mem_input_pin = mem_input_pin;
9639
ammediastream_media_sample = media_sample;
9640
ammediastream_sleep_time = 0;
9641
ammediastream_expected_hr = S_OK;
9642
thread = CreateThread(NULL, 0, ammediastream_receive, NULL, 0, NULL);
9643
9644
Sleep(100);
9645
hr = IDirectDrawStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
9646
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9647
hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
9648
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9649
ok(memcmp((BYTE *)desc.lpSurface + 0 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
9650
ok(memcmp((BYTE *)desc.lpSurface + 1 * desc.lPitch, &test_data[12], 12) == 0, "Sample data didn't match.\n");
9651
ok(memcmp((BYTE *)desc.lpSurface + 2 * desc.lPitch, &test_data[0], 12) == 0, "Sample data didn't match.\n");
9652
ok(memcmp((BYTE *)desc.lpSurface + 3 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
9653
ok(memcmp((BYTE *)desc.lpSurface + 4 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
9654
hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
9655
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9656
9657
ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
9658
CloseHandle(thread);
9659
9660
ref = IMediaSample_Release(media_sample);
9661
ok(!ref, "Got outstanding refcount %ld.\n", ref);
9662
9663
hr = IPin_EndOfStream(pin);
9664
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9665
9666
hr = IDirectDrawStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
9667
ok(hr == MS_S_ENDOFSTREAM, "Got hr %#lx.\n", hr);
9668
9669
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
9670
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9671
hr = IMediaControl_Pause(media_control);
9672
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9673
9674
hr = IDirectDrawStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
9675
ok(hr == MS_E_NOTRUNNING, "Got hr %#lx.\n", hr);
9676
9677
hr = IMediaControl_Stop(media_control);
9678
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9679
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
9680
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9681
9682
hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
9683
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9684
for (i = 0; i < 5; ++i)
9685
memcpy((BYTE *)desc.lpSurface + i * desc.lPitch, initial_data, 12);
9686
hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
9687
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9688
9689
media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
9690
9691
ammediastream_mem_input_pin = mem_input_pin;
9692
ammediastream_media_sample = media_sample;
9693
ammediastream_sleep_time = 100;
9694
ammediastream_expected_hr = S_OK;
9695
thread = CreateThread(NULL, 0, ammediastream_receive, NULL, 0, NULL);
9696
9697
hr = IDirectDrawStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
9698
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9699
hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
9700
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9701
ok(memcmp((BYTE *)desc.lpSurface + 0 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
9702
ok(memcmp((BYTE *)desc.lpSurface + 1 * desc.lPitch, &test_data[12], 12) == 0, "Sample data didn't match.\n");
9703
ok(memcmp((BYTE *)desc.lpSurface + 2 * desc.lPitch, &test_data[0], 12) == 0, "Sample data didn't match.\n");
9704
ok(memcmp((BYTE *)desc.lpSurface + 3 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
9705
ok(memcmp((BYTE *)desc.lpSurface + 4 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
9706
hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
9707
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9708
9709
ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
9710
CloseHandle(thread);
9711
9712
ref = IMediaSample_Release(media_sample);
9713
ok(!ref, "Got outstanding refcount %ld.\n", ref);
9714
9715
ammediastream_pin = pin;
9716
ammediastream_sleep_time = 100;
9717
ammediastream_expected_hr = S_OK;
9718
thread = CreateThread(NULL, 0, ammediastream_end_of_stream, NULL, 0, NULL);
9719
9720
hr = IDirectDrawStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
9721
ok(hr == MS_S_ENDOFSTREAM, "Got hr %#lx.\n", hr);
9722
9723
ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
9724
CloseHandle(thread);
9725
9726
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
9727
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9728
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
9729
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9730
9731
hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
9732
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9733
for (i = 0; i < 5; ++i)
9734
memcpy((BYTE *)desc.lpSurface + i * desc.lPitch, initial_data, 12);
9735
hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
9736
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9737
9738
media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
9739
9740
ammediastream_mem_input_pin = mem_input_pin;
9741
ammediastream_media_sample = media_sample;
9742
ammediastream_sleep_time = 100;
9743
ammediastream_expected_hr = S_OK;
9744
thread = CreateThread(NULL, 0, ammediastream_receive, NULL, 0, NULL);
9745
9746
hr = IDirectDrawStreamSample_Update(stream_sample, SSUPDATE_CONTINUOUS, NULL, NULL, 0);
9747
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9748
hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
9749
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9750
ok(memcmp((BYTE *)desc.lpSurface + 0 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
9751
ok(memcmp((BYTE *)desc.lpSurface + 1 * desc.lPitch, &test_data[12], 12) == 0, "Sample data didn't match.\n");
9752
ok(memcmp((BYTE *)desc.lpSurface + 2 * desc.lPitch, &test_data[0], 12) == 0, "Sample data didn't match.\n");
9753
ok(memcmp((BYTE *)desc.lpSurface + 3 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
9754
ok(memcmp((BYTE *)desc.lpSurface + 4 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
9755
hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
9756
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9757
9758
ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
9759
CloseHandle(thread);
9760
9761
ref = IMediaSample_Release(media_sample);
9762
ok(!ref, "Got outstanding refcount %ld.\n", ref);
9763
9764
hr = IDirectDrawStreamSample_Update(stream_sample, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
9765
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
9766
9767
hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
9768
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9769
for (i = 0; i < 5; ++i)
9770
memcpy((BYTE *)desc.lpSurface + i * desc.lPitch, initial_data, 12);
9771
hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
9772
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9773
9774
media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
9775
hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
9776
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9777
ref = IMediaSample_Release(media_sample);
9778
ok(!ref, "Got outstanding refcount %ld.\n", ref);
9779
9780
hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
9781
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9782
ok(memcmp((BYTE *)desc.lpSurface + 0 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
9783
ok(memcmp((BYTE *)desc.lpSurface + 1 * desc.lPitch, &test_data[12], 12) == 0, "Sample data didn't match.\n");
9784
ok(memcmp((BYTE *)desc.lpSurface + 2 * desc.lPitch, &test_data[0], 12) == 0, "Sample data didn't match.\n");
9785
ok(memcmp((BYTE *)desc.lpSurface + 3 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
9786
ok(memcmp((BYTE *)desc.lpSurface + 4 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
9787
hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
9788
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9789
9790
hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
9791
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9792
for (i = 0; i < 5; ++i)
9793
memcpy((BYTE *)desc.lpSurface + i * desc.lPitch, initial_data, 12);
9794
hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
9795
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9796
9797
media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
9798
hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
9799
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9800
ref = IMediaSample_Release(media_sample);
9801
ok(!ref, "Got outstanding refcount %ld.\n", ref);
9802
9803
hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
9804
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9805
ok(memcmp((BYTE *)desc.lpSurface + 0 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
9806
ok(memcmp((BYTE *)desc.lpSurface + 1 * desc.lPitch, &test_data[12], 12) == 0, "Sample data didn't match.\n");
9807
ok(memcmp((BYTE *)desc.lpSurface + 2 * desc.lPitch, &test_data[0], 12) == 0, "Sample data didn't match.\n");
9808
ok(memcmp((BYTE *)desc.lpSurface + 3 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
9809
ok(memcmp((BYTE *)desc.lpSurface + 4 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
9810
hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
9811
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9812
9813
hr = IPin_EndOfStream(pin);
9814
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9815
9816
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
9817
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9818
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
9819
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9820
9821
hr = IDirectDrawStreamSample_Update(stream_sample, 0, event, NULL, 0);
9822
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
9823
9824
ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n");
9825
9826
media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
9827
hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
9828
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9829
ref = IMediaSample_Release(media_sample);
9830
ok(!ref, "Got outstanding refcount %ld.\n", ref);
9831
9832
ok(WaitForSingleObject(event, 0) == 0, "Event should be signaled.\n");
9833
9834
hr = IDirectDrawStreamSample_Update(stream_sample, SSUPDATE_ASYNC, NULL, NULL, 0);
9835
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
9836
EXPECT_REF(stream_sample, 1);
9837
9838
hr = IDirectDrawStreamSample_Update(stream_sample, SSUPDATE_ASYNC, NULL, NULL, 0);
9839
ok(hr == MS_E_BUSY, "Got hr %#lx.\n", hr);
9840
9841
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
9842
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9843
hr = IMediaFilter_SetSyncSource(media_filter, &clock.IReferenceClock_iface);
9844
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9845
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
9846
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9847
9848
hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
9849
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9850
for (i = 0; i < 5; ++i)
9851
memcpy((BYTE *)desc.lpSurface + i * desc.lPitch, initial_data, 12);
9852
hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
9853
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9854
9855
hr = IDirectDrawStreamSample_Update(stream_sample, SSUPDATE_ASYNC, NULL, NULL, 0);
9856
ok(hr == MS_E_BUSY, "Got hr %#lx.\n", hr);
9857
9858
clock.advise_time_cookie = &cookie;
9859
9860
media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
9861
start_time = 11111111;
9862
end_time = 11111111;
9863
hr = IMediaSample_SetTime(media_sample, &start_time, &end_time);
9864
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9865
9866
ammediastream_mem_input_pin = mem_input_pin;
9867
ammediastream_media_sample = media_sample;
9868
ammediastream_sleep_time = 0;
9869
ammediastream_expected_hr = S_OK;
9870
thread = CreateThread(NULL, 0, ammediastream_receive, NULL, 0, NULL);
9871
ok(!WaitForSingleObject(cookie.advise_time_called_event, 2000), "Expected AdviseTime to be called.\n");
9872
ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Receive returned prematurely.\n");
9873
9874
hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
9875
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9876
for (i = 0; i < 5; ++i)
9877
ok(memcmp((BYTE *)desc.lpSurface + i * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
9878
hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
9879
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9880
9881
SetEvent(cookie.event);
9882
9883
ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
9884
CloseHandle(thread);
9885
9886
hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
9887
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9888
ok(memcmp((BYTE *)desc.lpSurface + 0 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
9889
ok(memcmp((BYTE *)desc.lpSurface + 1 * desc.lPitch, &test_data[12], 12) == 0, "Sample data didn't match.\n");
9890
ok(memcmp((BYTE *)desc.lpSurface + 2 * desc.lPitch, &test_data[0], 12) == 0, "Sample data didn't match.\n");
9891
ok(memcmp((BYTE *)desc.lpSurface + 3 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
9892
ok(memcmp((BYTE *)desc.lpSurface + 4 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
9893
hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
9894
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9895
9896
ref = IMediaSample_Release(media_sample);
9897
ok(!ref, "Got outstanding refcount %ld.\n", ref);
9898
9899
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
9900
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9901
IGraphBuilder_Disconnect(graph, pin);
9902
IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
9903
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
9904
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9905
9906
hr = IDirectDrawStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
9907
ok(hr == MS_S_ENDOFSTREAM, "Got hr %#lx.\n", hr);
9908
9909
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
9910
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9911
9912
CloseHandle(cookie.advise_time_called_event);
9913
CloseHandle(event);
9914
ref = IDirectDrawStreamSample_Release(stream_sample);
9915
ok(!ref, "Got outstanding refcount %ld.\n", ref);
9916
ref = IDirectDrawSurface_Release(surface);
9917
ok(!ref, "Got outstanding refcount %ld.\n", ref);
9918
ref = IAMMultiMediaStream_Release(mmstream);
9919
ok(!ref, "Got outstanding refcount %ld.\n", ref);
9920
IMediaControl_Release(media_control);
9921
IMediaFilter_Release(media_filter);
9922
ref = IGraphBuilder_Release(graph);
9923
ok(!ref, "Got outstanding refcount %ld.\n", ref);
9924
IPin_Release(pin);
9925
IMemInputPin_Release(mem_input_pin);
9926
IDirectDrawMediaStream_Release(ddraw_stream);
9927
ref = IMediaStream_Release(stream);
9928
ok(!ref, "Got outstanding refcount %ld.\n", ref);
9929
ref = IDirectDraw_Release(ddraw);
9930
ok(!ref, "Got outstanding refcount %ld.\n", ref);
9931
}
9932
9933
static void test_ddrawstreamsample_completion_status(void)
9934
{
9935
static const BYTE test_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
9936
IAMMultiMediaStream *mmstream = create_ammultimediastream();
9937
struct advise_time_cookie cookie = { 0 };
9938
IDirectDrawStreamSample *stream_sample1;
9939
IDirectDrawStreamSample *stream_sample2;
9940
IDirectDrawMediaStream *ddraw_stream;
9941
STREAM_TIME filter_start_time;
9942
IMediaStreamFilter *filter;
9943
IMediaSample *media_sample;
9944
IMediaFilter *media_filter;
9945
struct testfilter source;
9946
struct testclock clock;
9947
VIDEOINFO video_info;
9948
IGraphBuilder *graph;
9949
IMediaStream *stream;
9950
AM_MEDIA_TYPE mt;
9951
HANDLE thread;
9952
HRESULT hr;
9953
ULONG ref;
9954
IPin *pin;
9955
9956
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
9957
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9958
hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
9959
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9960
ok(!!filter, "Expected non-null filter.\n");
9961
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
9962
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9963
hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
9964
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9965
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
9966
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9967
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
9968
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9969
ok(graph != NULL, "Expected non-NULL graph.\n");
9970
hr = IGraphBuilder_QueryInterface(graph, &IID_IMediaFilter, (void **)&media_filter);
9971
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9972
testfilter_init(&source);
9973
hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
9974
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9975
testclock_init(&clock);
9976
cookie.advise_time_called_event = CreateEventW(NULL, FALSE, FALSE, NULL);
9977
9978
hr = IMediaFilter_SetSyncSource(media_filter, NULL);
9979
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9980
9981
video_info = rgb32_video_info;
9982
video_info.bmiHeader.biWidth = 3;
9983
video_info.bmiHeader.biHeight = 1;
9984
mt = rgb32_mt;
9985
mt.pbFormat = (BYTE *)&video_info;
9986
hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
9987
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9988
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
9989
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9990
9991
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &stream_sample1);
9992
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9993
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &stream_sample2);
9994
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9995
9996
/* Initial status is S_OK. */
9997
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
9998
ok(hr == S_OK, "Got hr %#lx.\n", hr);
9999
10000
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_WAIT, INFINITE);
10001
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10002
10003
/* Update changes the status to MS_S_PENDING. */
10004
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
10005
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10006
10007
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
10008
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10009
10010
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_WAIT, 100);
10011
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10012
10013
/* Each Receive call changes the status of one queued sample to S_OK in the same order Update was called. */
10014
hr = IDirectDrawStreamSample_Update(stream_sample2, SSUPDATE_ASYNC, NULL, NULL, 0);
10015
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10016
10017
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample2, 0, 0);
10018
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10019
10020
media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
10021
hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
10022
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10023
ref = IMediaSample_Release(media_sample);
10024
ok(!ref, "Got outstanding refcount %ld.\n", ref);
10025
10026
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
10027
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10028
10029
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_WAIT, INFINITE);
10030
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10031
10032
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample2, 0, 0);
10033
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10034
10035
media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
10036
hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
10037
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10038
ref = IMediaSample_Release(media_sample);
10039
ok(!ref, "Got outstanding refcount %ld.\n", ref);
10040
10041
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample2, 0, 0);
10042
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10043
10044
/* COMPSTAT_NOUPDATEOK removes the sample from the queue and changes the status to MS_S_NOUPDATE. */
10045
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
10046
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10047
10048
hr = IDirectDrawStreamSample_Update(stream_sample2, SSUPDATE_ASYNC, NULL, NULL, 0);
10049
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10050
10051
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_NOUPDATEOK, 0);
10052
ok(hr == MS_S_NOUPDATE, "Got hr %#lx.\n", hr);
10053
10054
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_WAIT, INFINITE);
10055
ok(hr == MS_S_NOUPDATE, "Got hr %#lx.\n", hr);
10056
10057
media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
10058
hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
10059
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10060
ref = IMediaSample_Release(media_sample);
10061
ok(!ref, "Got outstanding refcount %ld.\n", ref);
10062
10063
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
10064
ok(hr == MS_S_NOUPDATE, "Got hr %#lx.\n", hr);
10065
10066
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample2, 0, 0);
10067
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10068
10069
/* COMPSTAT_ABORT removes the sample from the queue and changes the status to MS_S_NOUPDATE. */
10070
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
10071
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10072
10073
hr = IDirectDrawStreamSample_Update(stream_sample2, SSUPDATE_ASYNC, NULL, NULL, 0);
10074
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10075
10076
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_ABORT, 0);
10077
ok(hr == MS_S_NOUPDATE, "Got hr %#lx.\n", hr);
10078
10079
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_WAIT, INFINITE);
10080
ok(hr == MS_S_NOUPDATE, "Got hr %#lx.\n", hr);
10081
10082
media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
10083
hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
10084
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10085
ref = IMediaSample_Release(media_sample);
10086
ok(!ref, "Got outstanding refcount %ld.\n", ref);
10087
10088
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
10089
ok(hr == MS_S_NOUPDATE, "Got hr %#lx.\n", hr);
10090
10091
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample2, 0, 0);
10092
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10093
10094
/* COMPSTAT_WAIT has no effect when combined with COMPSTAT_NOUPDATEOK. */
10095
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
10096
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10097
10098
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_NOUPDATEOK | COMPSTAT_WAIT, INFINITE);
10099
ok(hr == MS_S_NOUPDATE, "Got hr %#lx.\n", hr);
10100
10101
/* COMPSTAT_WAIT has no effect when combined with COMPSTAT_ABORT. */
10102
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
10103
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10104
10105
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_ABORT | COMPSTAT_WAIT, INFINITE);
10106
ok(hr == MS_S_NOUPDATE, "Got hr %#lx.\n", hr);
10107
10108
/* EndOfStream changes the status of the queued samples to MS_S_ENDOFSTREAM. */
10109
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
10110
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10111
10112
hr = IPin_EndOfStream(pin);
10113
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10114
10115
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
10116
ok(hr == MS_S_ENDOFSTREAM, "Got hr %#lx.\n", hr);
10117
10118
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_WAIT, INFINITE);
10119
ok(hr == MS_S_ENDOFSTREAM, "Got hr %#lx.\n", hr);
10120
10121
/* Update after EndOfStream changes the status to MS_S_ENDOFSTREAM. */
10122
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
10123
ok(hr == MS_S_ENDOFSTREAM, "Got hr %#lx.\n", hr);
10124
10125
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
10126
ok(hr == MS_S_ENDOFSTREAM, "Got hr %#lx.\n", hr);
10127
10128
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_WAIT, INFINITE);
10129
ok(hr == MS_S_ENDOFSTREAM, "Got hr %#lx.\n", hr);
10130
10131
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
10132
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10133
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
10134
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10135
10136
/* Continuous update can be canceled by COMPSTAT_NOUPDATEOK. */
10137
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
10138
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10139
10140
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_NOUPDATEOK, 0);
10141
ok(hr == MS_S_NOUPDATE, "Got hr %#lx.\n", hr);
10142
10143
/* Continuous update can be canceled by COMPSTAT_ABORT. */
10144
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
10145
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10146
10147
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_ABORT, 0);
10148
ok(hr == MS_S_NOUPDATE, "Got hr %#lx.\n", hr);
10149
10150
/* If a sample is in countinuous update mode, when Receive is called it's status remains MS_S_PENDING
10151
* and the sample is moved to the end of the queue. */
10152
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
10153
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10154
10155
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
10156
ok(hr == MS_E_BUSY, "Got hr %#lx.\n", hr);
10157
10158
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
10159
ok(hr == MS_E_BUSY, "Got hr %#lx.\n", hr);
10160
10161
hr = IDirectDrawStreamSample_Update(stream_sample2, SSUPDATE_ASYNC, NULL, NULL, 0);
10162
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10163
10164
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
10165
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10166
10167
media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
10168
hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
10169
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10170
ref = IMediaSample_Release(media_sample);
10171
ok(!ref, "Got outstanding refcount %ld.\n", ref);
10172
10173
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
10174
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10175
10176
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample2, 0, 0);
10177
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10178
10179
media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
10180
hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
10181
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10182
ref = IMediaSample_Release(media_sample);
10183
ok(!ref, "Got outstanding refcount %ld.\n", ref);
10184
10185
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
10186
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10187
10188
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample2, 0, 0);
10189
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10190
10191
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_NOUPDATEOK, 0);
10192
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10193
10194
/* In continuous update mode, flushing does not affect the status. */
10195
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
10196
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10197
10198
hr = IPin_BeginFlush(pin);
10199
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10200
10201
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
10202
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10203
10204
hr = IPin_EndFlush(pin);
10205
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10206
10207
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
10208
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10209
10210
/* In continuous update mode, stopping and running the stream does not affect the status. */
10211
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
10212
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10213
10214
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
10215
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10216
10217
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
10218
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10219
10220
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
10221
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10222
10223
/* In continuous update mode, EndOfStream changes the status to MS_S_ENDOFSTREAM. */
10224
hr = IPin_EndOfStream(pin);
10225
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10226
10227
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
10228
ok(hr == MS_S_ENDOFSTREAM, "Got hr %#lx.\n", hr);
10229
10230
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
10231
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10232
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
10233
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10234
10235
/* COMPSTAT_WAIT resets the sample to the non-continuous update mode. */
10236
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
10237
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10238
10239
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_WAIT, 0);
10240
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10241
10242
media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
10243
hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
10244
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10245
ref = IMediaSample_Release(media_sample);
10246
ok(!ref, "Got outstanding refcount %ld.\n", ref);
10247
10248
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
10249
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10250
10251
/* In continuous update mode, CompletionStatus with COMPSTAT_WAIT returns when Receive is called. */
10252
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
10253
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10254
10255
streamsample_sample = (IStreamSample *)stream_sample1;
10256
streamsample_flags = COMPSTAT_WAIT;
10257
streamsample_timeout = INFINITE;
10258
streamsample_expected_hr = S_OK;
10259
thread = CreateThread(NULL, 0, streamsample_completion_status, NULL, 0, NULL);
10260
ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "CompletionStatus returned prematurely.\n");
10261
10262
media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
10263
hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
10264
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10265
ref = IMediaSample_Release(media_sample);
10266
ok(!ref, "Got outstanding refcount %ld.\n", ref);
10267
10268
ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
10269
CloseHandle(thread);
10270
10271
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
10272
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10273
10274
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
10275
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10276
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
10277
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10278
10279
/* CompletionStatus with COMPSTAT_WAIT returns when Receive is called. */
10280
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
10281
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10282
10283
streamsample_sample = (IStreamSample *)stream_sample1;
10284
streamsample_flags = COMPSTAT_WAIT;
10285
streamsample_timeout = INFINITE;
10286
streamsample_expected_hr = S_OK;
10287
thread = CreateThread(NULL, 0, streamsample_completion_status, NULL, 0, NULL);
10288
ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "CompletionStatus returned prematurely.\n");
10289
10290
media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
10291
hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
10292
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10293
ref = IMediaSample_Release(media_sample);
10294
ok(!ref, "Got outstanding refcount %ld.\n", ref);
10295
10296
ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
10297
CloseHandle(thread);
10298
10299
/* CompletionStatus with COMPSTAT_WAIT returns when EndOfStream is called. */
10300
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
10301
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10302
10303
streamsample_sample = (IStreamSample *)stream_sample1;
10304
streamsample_flags = COMPSTAT_WAIT;
10305
streamsample_timeout = INFINITE;
10306
streamsample_expected_hr = MS_S_ENDOFSTREAM;
10307
thread = CreateThread(NULL, 0, streamsample_completion_status, NULL, 0, NULL);
10308
ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "CompletionStatus returned prematurely.\n");
10309
10310
hr = IPin_EndOfStream(pin);
10311
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10312
10313
ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
10314
CloseHandle(thread);
10315
10316
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
10317
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10318
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
10319
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10320
10321
/* Stopping and running the stream does not affect the status and does not remove the sample from the queue. */
10322
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
10323
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10324
10325
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
10326
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10327
10328
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
10329
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10330
10331
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
10332
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10333
10334
media_sample = ammediastream_allocate_sample(&source, test_data, 6);
10335
hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
10336
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10337
ref = IMediaSample_Release(media_sample);
10338
ok(!ref, "Got outstanding refcount %ld.\n", ref);
10339
10340
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
10341
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10342
10343
/* When the stream is stopped Update does not change the status. */
10344
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
10345
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10346
10347
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
10348
ok(hr == MS_E_NOTRUNNING, "Got hr %#lx.\n", hr);
10349
10350
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
10351
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10352
10353
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_WAIT, INFINITE);
10354
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10355
10356
/* When the wait time is less than 1ms the sample is updated immediately. */
10357
hr = IMediaFilter_SetSyncSource(media_filter, &clock.IReferenceClock_iface);
10358
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10359
10360
clock.time = 12345678;
10361
10362
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
10363
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10364
10365
hr = IMediaStreamFilter_GetCurrentStreamTime(filter, &filter_start_time);
10366
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10367
10368
clock.time = 12345678 - filter_start_time + 11111111;
10369
10370
clock.advise_time_cookie = &cookie;
10371
10372
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
10373
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10374
10375
thread = ammediastream_async_receive_time(&source,
10376
11111111 + 9999, 11111111 + 9999, test_data, sizeof(test_data));
10377
ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
10378
CloseHandle(thread);
10379
10380
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, INFINITE);
10381
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10382
10383
/* When the wait time is 1ms or greater AdviseTime is called
10384
* with base equal to the sample start time and offset equal to the filter start time. */
10385
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
10386
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10387
10388
thread = ammediastream_async_receive_time(&source,
10389
11111111 + 10000, 11111111 + 10000, test_data, sizeof(test_data));
10390
ok(!WaitForSingleObject(cookie.advise_time_called_event, 2000), "Expected AdviseTime to be called.\n");
10391
ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Receive returned prematurely.\n");
10392
10393
ok(cookie.base == 11111111 + 10000, "Got base %s.\n", wine_dbgstr_longlong(cookie.base));
10394
ok(cookie.offset == 12345678 - filter_start_time, "Got offset %s.\n", wine_dbgstr_longlong(cookie.offset));
10395
10396
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
10397
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10398
10399
clock.time = 12345678 - filter_start_time + 11111111 + 10000;
10400
SetEvent(cookie.event);
10401
10402
ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
10403
CloseHandle(thread);
10404
10405
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
10406
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10407
10408
/* NewSegment does not affect the values passed to AdviseTime. */
10409
hr = IPin_NewSegment(pin, 22222222, 33333333, 1.0);
10410
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10411
10412
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
10413
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10414
10415
thread = ammediastream_async_receive_time(&source,
10416
11111111 + 20000, 11111111 + 20000, test_data, sizeof(test_data));
10417
ok(!WaitForSingleObject(cookie.advise_time_called_event, 2000), "Expected AdviseTime to be called.\n");
10418
ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Receive returned prematurely.\n");
10419
10420
ok(cookie.base == 11111111 + 20000, "Got base %s.\n", wine_dbgstr_longlong(cookie.base));
10421
ok(cookie.offset == 12345678 - filter_start_time, "Got offset %s.\n", wine_dbgstr_longlong(cookie.offset));
10422
10423
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_NOUPDATEOK, 0);
10424
ok(hr == MS_S_NOUPDATE, "Got hr %#lx.\n", hr);
10425
10426
ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Receive returned prematurely.\n");
10427
10428
clock.time = 12345678 - filter_start_time + 11111111 + 20000;
10429
SetEvent(cookie.event);
10430
10431
ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Receive returned prematurely.\n");
10432
10433
/* COMPSTAT_NOUPDATEOK does not cause Receive to return.
10434
* Receive waits for the next sample to be queued and updates it. */
10435
hr = IDirectDrawStreamSample_Update(stream_sample1, 0, NULL, NULL, 0);
10436
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10437
10438
ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
10439
CloseHandle(thread);
10440
10441
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
10442
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10443
10444
thread = ammediastream_async_receive_time(&source,
10445
11111111 + 30000, 11111111 + 30000, test_data, sizeof(test_data));
10446
ok(!WaitForSingleObject(cookie.advise_time_called_event, 2000), "Expected AdviseTime to be called.\n");
10447
ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Receive returned prematurely.\n");
10448
10449
ok(cookie.base == 11111111 + 30000, "Got base %s.\n", wine_dbgstr_longlong(cookie.base));
10450
ok(cookie.offset == 12345678 - filter_start_time, "Got offset %s.\n", wine_dbgstr_longlong(cookie.offset));
10451
10452
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_NOUPDATEOK | COMPSTAT_WAIT, INFINITE);
10453
ok(hr == MS_S_NOUPDATE, "Got hr %#lx.\n", hr);
10454
10455
ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Receive returned prematurely.\n");
10456
10457
clock.time = 12345678 - filter_start_time + 11111111 + 30000;
10458
SetEvent(cookie.event);
10459
10460
ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Receive returned prematurely.\n");
10461
10462
hr = IDirectDrawStreamSample_Update(stream_sample1, 0, NULL, NULL, 0);
10463
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10464
10465
ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
10466
CloseHandle(thread);
10467
10468
/* COMPSTAT_ABORT does not cause Receive to return.
10469
* Receive waits for the next sample to be queued and updates it. */
10470
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
10471
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10472
10473
thread = ammediastream_async_receive_time(&source,
10474
11111111 + 40000, 11111111 + 40000, test_data, sizeof(test_data));
10475
ok(!WaitForSingleObject(cookie.advise_time_called_event, 2000), "Expected AdviseTime to be called.\n");
10476
ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Receive returned prematurely.\n");
10477
10478
ok(cookie.base == 11111111 + 40000, "Got base %s.\n", wine_dbgstr_longlong(cookie.base));
10479
ok(cookie.offset == 12345678 - filter_start_time, "Got offset %s.\n", wine_dbgstr_longlong(cookie.offset));
10480
10481
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_ABORT, 0);
10482
ok(hr == MS_S_NOUPDATE, "Got hr %#lx.\n", hr);
10483
10484
ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Receive returned prematurely.\n");
10485
10486
clock.time = 12345678 - filter_start_time + 11111111 + 40000;
10487
SetEvent(cookie.event);
10488
10489
ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Receive returned prematurely.\n");
10490
10491
hr = IDirectDrawStreamSample_Update(stream_sample1, 0, NULL, NULL, 0);
10492
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10493
10494
ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
10495
CloseHandle(thread);
10496
10497
/* Stopping the stream causes Receive to return and leaves the sample with MS_S_PENDING status. */
10498
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
10499
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10500
10501
thread = ammediastream_async_receive_time(&source,
10502
11111111 + 50000, 11111111 + 50000, test_data, sizeof(test_data));
10503
ok(!WaitForSingleObject(cookie.advise_time_called_event, 2000), "Expected AdviseTime to be called.\n");
10504
ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Receive returned prematurely.\n");
10505
10506
ok(cookie.base == 11111111 + 50000, "Got base %s.\n", wine_dbgstr_longlong(cookie.base));
10507
ok(cookie.offset == 12345678 - filter_start_time, "Got offset %s.\n", wine_dbgstr_longlong(cookie.offset));
10508
10509
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
10510
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10511
10512
ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
10513
CloseHandle(thread);
10514
10515
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
10516
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10517
10518
IGraphBuilder_Disconnect(graph, pin);
10519
IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
10520
10521
CloseHandle(cookie.advise_time_called_event);
10522
ref = IDirectDrawStreamSample_Release(stream_sample1);
10523
ok(!ref, "Got outstanding refcount %ld.\n", ref);
10524
ref = IDirectDrawStreamSample_Release(stream_sample2);
10525
ok(!ref, "Got outstanding refcount %ld.\n", ref);
10526
ref = IAMMultiMediaStream_Release(mmstream);
10527
ok(!ref, "Got outstanding refcount %ld.\n", ref);
10528
IMediaFilter_Release(media_filter);
10529
ref = IGraphBuilder_Release(graph);
10530
ok(!ref, "Got outstanding refcount %ld.\n", ref);
10531
ref = IMediaStreamFilter_Release(filter);
10532
ok(!ref, "Got outstanding refcount %ld.\n", ref);
10533
IPin_Release(pin);
10534
IDirectDrawMediaStream_Release(ddraw_stream);
10535
ref = IMediaStream_Release(stream);
10536
ok(!ref, "Got outstanding refcount %ld.\n", ref);
10537
}
10538
10539
static void test_ddrawstreamsample_get_sample_times(void)
10540
{
10541
static const BYTE test_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
10542
IAMMultiMediaStream *mmstream = create_ammultimediastream();
10543
IDirectDrawStreamSample *stream_sample;
10544
IMediaFilter *graph_media_filter;
10545
IDirectDrawMediaStream *ddraw_stream;
10546
STREAM_TIME filter_start_time;
10547
IMemInputPin *mem_input_pin;
10548
IMediaStreamFilter *filter;
10549
IMediaSample *media_sample;
10550
struct testfilter source;
10551
STREAM_TIME current_time;
10552
struct testclock clock;
10553
STREAM_TIME start_time;
10554
STREAM_TIME end_time;
10555
IGraphBuilder *graph;
10556
IMediaStream *stream;
10557
VIDEOINFO video_info;
10558
AM_MEDIA_TYPE mt;
10559
HRESULT hr;
10560
ULONG ref;
10561
IPin *pin;
10562
10563
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
10564
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10565
hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
10566
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10567
ok(!!filter, "Expected non-null filter.\n");
10568
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
10569
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10570
hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
10571
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10572
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
10573
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10574
hr = IMediaStream_QueryInterface(stream, &IID_IMemInputPin, (void **)&mem_input_pin);
10575
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10576
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
10577
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10578
ok(graph != NULL, "Expected non-NULL graph.\n");
10579
hr = IGraphBuilder_QueryInterface(graph, &IID_IMediaFilter, (void **)&graph_media_filter);
10580
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10581
testfilter_init(&source);
10582
hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
10583
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10584
testclock_init(&clock);
10585
10586
video_info = rgb32_video_info;
10587
video_info.bmiHeader.biWidth = 3;
10588
video_info.bmiHeader.biHeight = 1;
10589
mt = rgb32_mt;
10590
mt.pbFormat = (BYTE *)&video_info;
10591
hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
10592
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10593
10594
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &stream_sample);
10595
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10596
10597
clock.time = 12345678;
10598
10599
current_time = 0xdeadbeefdeadbeef;
10600
hr = IDirectDrawStreamSample_GetSampleTimes(stream_sample, NULL, NULL, &current_time);
10601
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10602
ok(current_time == 0, "Got current time %s.\n", wine_dbgstr_longlong(current_time));
10603
10604
hr = IMediaFilter_SetSyncSource(graph_media_filter, &clock.IReferenceClock_iface);
10605
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10606
10607
current_time = 0xdeadbeefdeadbeef;
10608
hr = IDirectDrawStreamSample_GetSampleTimes(stream_sample, NULL, NULL, &current_time);
10609
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10610
ok(current_time == 0, "Got current time %s.\n", wine_dbgstr_longlong(current_time));
10611
10612
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
10613
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10614
10615
hr = IMediaStreamFilter_GetCurrentStreamTime(filter, &filter_start_time);
10616
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10617
10618
clock.get_time_hr = E_FAIL;
10619
10620
current_time = 0xdeadbeefdeadbeef;
10621
hr = IDirectDrawStreamSample_GetSampleTimes(stream_sample, NULL, NULL, &current_time);
10622
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10623
ok(current_time == 0xdeadbeefddf15da1 + filter_start_time, "Expected current time %s, got %s.\n",
10624
wine_dbgstr_longlong(0xdeadbeefddf15da1 + filter_start_time), wine_dbgstr_longlong(current_time));
10625
10626
clock.get_time_hr = S_OK;
10627
10628
current_time = 0xdeadbeefdeadbeef;
10629
hr = IDirectDrawStreamSample_GetSampleTimes(stream_sample, NULL, NULL, &current_time);
10630
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10631
ok(current_time == filter_start_time, "Expected current time %s, got %s.\n",
10632
wine_dbgstr_longlong(filter_start_time), wine_dbgstr_longlong(current_time));
10633
10634
clock.time = 23456789;
10635
10636
current_time = 0xdeadbeefdeadbeef;
10637
hr = IDirectDrawStreamSample_GetSampleTimes(stream_sample, NULL, NULL, &current_time);
10638
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10639
ok(current_time == filter_start_time + 11111111, "Expected current time %s, got %s.\n",
10640
wine_dbgstr_longlong(filter_start_time + 11111111), wine_dbgstr_longlong(current_time));
10641
10642
start_time = 0xdeadbeefdeadbeef;
10643
end_time = 0xdeadbeefdeadbeef;
10644
hr = IDirectDrawStreamSample_GetSampleTimes(stream_sample, &start_time, &end_time, NULL);
10645
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10646
ok(start_time == 0, "Got start time %s.\n", wine_dbgstr_longlong(start_time));
10647
ok(end_time == 0, "Got end time %s.\n", wine_dbgstr_longlong(end_time));
10648
10649
hr = IDirectDrawStreamSample_Update(stream_sample, SSUPDATE_ASYNC, NULL, NULL, 0);
10650
ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr);
10651
10652
media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
10653
start_time = 12345678;
10654
end_time = 23456789;
10655
hr = IMediaSample_SetTime(media_sample, &start_time, &end_time);
10656
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10657
hr = IMemInputPin_Receive(mem_input_pin, media_sample);
10658
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10659
IMediaSample_Release(media_sample);
10660
10661
start_time = 0xdeadbeefdeadbeef;
10662
end_time = 0xdeadbeefdeadbeef;
10663
hr = IDirectDrawStreamSample_GetSampleTimes(stream_sample, &start_time, &end_time, NULL);
10664
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10665
ok(start_time == 12345678, "Got start time %s.\n", wine_dbgstr_longlong(start_time));
10666
ok(end_time == 23456789, "Got end time %s.\n", wine_dbgstr_longlong(end_time));
10667
10668
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
10669
ok(hr == S_OK, "Got hr %#lx.\n", hr);
10670
IGraphBuilder_Disconnect(graph, pin);
10671
IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
10672
10673
ref = IDirectDrawStreamSample_Release(stream_sample);
10674
ok(!ref, "Got outstanding refcount %ld.\n", ref);
10675
ref = IAMMultiMediaStream_Release(mmstream);
10676
ok(!ref, "Got outstanding refcount %ld.\n", ref);
10677
IMediaFilter_Release(graph_media_filter);
10678
ref = IGraphBuilder_Release(graph);
10679
ok(!ref, "Got outstanding refcount %ld.\n", ref);
10680
ref = IMediaStreamFilter_Release(filter);
10681
ok(!ref, "Got outstanding refcount %ld.\n", ref);
10682
IPin_Release(pin);
10683
IMemInputPin_Release(mem_input_pin);
10684
IDirectDrawMediaStream_Release(ddraw_stream);
10685
ref = IMediaStream_Release(stream);
10686
ok(!ref, "Got outstanding refcount %ld.\n", ref);
10687
}
10688
10689
START_TEST(amstream)
10690
{
10691
const WCHAR *test_avi_path;
10692
10693
CoInitializeEx(NULL, COINIT_MULTITHREADED);
10694
10695
test_interfaces();
10696
test_add_stream();
10697
test_media_streams();
10698
test_enum_pins();
10699
test_find_pin();
10700
test_pin_info();
10701
test_initialize();
10702
test_set_state();
10703
test_enum_media_types();
10704
test_media_types();
10705
test_get_end_of_stream_event_handle();
10706
10707
test_avi_path = load_resource(L"test.avi");
10708
10709
test_openfile(test_avi_path);
10710
test_mmstream_get_duration(test_avi_path);
10711
10712
unload_resource(test_avi_path);
10713
10714
test_audiodata_query_interface();
10715
test_audiodata_get_info();
10716
test_audiodata_set_buffer();
10717
test_audiodata_set_actual();
10718
test_audiodata_get_format();
10719
test_audiodata_set_format();
10720
10721
test_audiostream_get_format();
10722
test_audiostream_set_format();
10723
test_audiostream_receive_connection();
10724
test_audiostream_receive();
10725
test_audiostream_initialize();
10726
test_audiostream_begin_flush_end_flush();
10727
test_audiostream_new_segment();
10728
10729
test_audiostreamsample_update();
10730
test_audiostreamsample_completion_status();
10731
test_audiostreamsample_get_sample_times();
10732
test_audiostreamsample_get_media_stream();
10733
test_audiostreamsample_get_audio_data();
10734
10735
test_ddrawstream_initialize();
10736
test_ddrawstream_getsetdirectdraw();
10737
test_ddrawstream_receive_connection();
10738
test_ddrawstream_create_sample();
10739
test_ddrawstream_get_format();
10740
test_ddrawstream_set_format();
10741
test_ddrawstream_receive();
10742
test_ddrawstream_begin_flush_end_flush();
10743
test_ddrawstream_new_segment();
10744
test_ddrawstream_get_time_per_frame();
10745
test_ddrawstream_qc();
10746
test_ddrawstream_mem_allocator();
10747
test_ddrawstream_set_format_dynamic();
10748
10749
test_ddrawstreamsample_get_media_stream();
10750
test_ddrawstreamsample_update();
10751
test_ddrawstreamsample_completion_status();
10752
test_ddrawstreamsample_get_sample_times();
10753
10754
test_ammediastream_join_am_multi_media_stream();
10755
test_ammediastream_join_filter();
10756
test_ammediastream_join_filter_graph();
10757
test_ammediastream_set_state();
10758
test_ammediastream_end_of_stream();
10759
10760
test_mediastreamfilter_get_state();
10761
test_mediastreamfilter_stop_pause_run();
10762
test_mediastreamfilter_support_seeking();
10763
test_mediastreamfilter_seeking();
10764
test_mediastreamfilter_get_current_stream_time();
10765
test_mediastreamfilter_reference_time_to_stream_time();
10766
test_mediastreamfilter_wait_until();
10767
test_mediastreamfilter_end_of_stream();
10768
10769
CoUninitialize();
10770
}
10771
10772