From: Santino Mazza smazza@codeweavers.com
--- dlls/amstream/tests/amstream.c | 161 +++++++++++++++++++++++++++++++-- 1 file changed, 154 insertions(+), 7 deletions(-)
diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index 759c4b75fda..a05ffb44406 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -1027,6 +1027,7 @@ struct testfilter HANDLE wait_state_event; IBaseFilter *qc_notify_sender; Quality qc_notify_quality; + BOOL use_input_pin_allocator; HRESULT get_duration_hr; HRESULT get_stop_position_hr; HRESULT set_positions_hr; @@ -1142,16 +1143,21 @@ static HRESULT testsource_query_interface(struct strmbase_pin *iface, REFIID iid
static HRESULT WINAPI testsource_DecideAllocator(struct strmbase_source *iface, IMemInputPin *pin, IMemAllocator **alloc) { + struct testfilter *filter = impl_from_base_pin(&iface->pin); ALLOCATOR_PROPERTIES props = {0}; HRESULT hr;
- /* AMDirectDrawStream tries to use it's custom allocator and - * when it is able to do so it's behavior changes slightly - * (e.g. it uses dynamic format change instead of reconnecting in SetFormat). - * We don't yet implement the custom allocator so force the standard one for now. */ - hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER, - &IID_IMemAllocator, (void **)alloc); - ok(hr == S_OK, "Got hr %#lx.\n", hr); + if (filter->use_input_pin_allocator) + { + hr = IMemInputPin_GetAllocator(pin, alloc); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + } + else + { + hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER, + &IID_IMemAllocator, (void **)alloc); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + }
IMemInputPin_GetAllocatorRequirements(pin, &props); hr = iface->pFuncsTable->pfnDecideBufferSize(iface, *alloc, &props); @@ -1192,6 +1198,7 @@ static void testfilter_init(struct testfilter *filter) memset(filter, 0, sizeof(*filter)); strmbase_filter_init(&filter->filter, NULL, &clsid, &testfilter_ops); strmbase_source_init(&filter->source, &filter->filter, L"", &testsource_ops); + filter->use_input_pin_allocator = FALSE; filter->stop_position = 0x8000000000000000ULL; filter->wait_state_event = CreateEventW(NULL, TRUE, TRUE, NULL); } @@ -8485,6 +8492,145 @@ static void test_ddrawstream_qc(void) ok(!ref, "Got outstanding refcount %ld.\n", ref); }
+static void test_ddrawstream_mem_allocator(void) { + IAMMultiMediaStream *mmstream = create_ammultimediastream(); + IMemAllocator *ddraw_allocator, *mem_allocator, *new_allocator; + IDirectDrawMediaStream *ddraw_stream; + IMediaSample *media_sample1, *media_sample2; + IDirectDrawStreamSample *ddraw_sample1, *ddraw_sample2; + ALLOCATOR_PROPERTIES props, props2; + AM_MEDIA_TYPE *sample_mt; + struct testfilter source; + IMemInputPin *mem_input; + IMediaStream *stream; + IGraphBuilder *graph; + IPin *pin; + HRESULT hr; + ULONG ref; + + hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IMediaStream_QueryInterface(stream, &IID_IMemInputPin, (void**)&mem_input); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void**)&ddraw_stream); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + ddraw_allocator = NULL; + hr = IMediaStream_QueryInterface(stream, &IID_IMemAllocator, (void**)&ddraw_allocator); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + mem_allocator = NULL; + hr = IMemInputPin_GetAllocator(mem_input, &mem_allocator); + todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); + todo_wine ok(mem_allocator == ddraw_allocator, "Expected GetAllocator to return ddraw allocator.\n"); + + if (mem_allocator) + { + check_interface(mem_allocator, &IID_IDirectDrawMediaStream, TRUE); + IMemAllocator_Release(mem_allocator); + } + + hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER, + &IID_IMemAllocator, (void **)&new_allocator); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + props.cbAlign = 1; + props.cbBuffer = 10000; + props.cBuffers = 0; + props.cbPrefix = 0; + hr = IMemAllocator_SetProperties(new_allocator, &props, &props2); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IMemInputPin_NotifyAllocator(mem_input, new_allocator, TRUE); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + mem_allocator = NULL; + hr = IMemInputPin_GetAllocator(mem_input, &mem_allocator); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + todo_wine ok(mem_allocator == ddraw_allocator, "Expected GetAllocator to return ddraw allocator.\n"); + todo_wine check_interface(mem_allocator, &IID_IDirectDrawMediaStream, TRUE); + + IMemInputPin_Release(mem_input); + + hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(!!graph, "Expected non-NULL graph.\n"); + + testfilter_init(&source); + source.use_input_pin_allocator = TRUE; + source.preferred_mt = &rgb24_mt; + + hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, L"source"); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void**)&pin); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &rgb555_mt); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb555_format, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &ddraw_sample1); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IDirectDrawStreamSample_Update(ddraw_sample1, SSUPDATE_ASYNC, NULL, NULL, 0); + ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr); + hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &ddraw_sample2); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IDirectDrawStreamSample_Update(ddraw_sample2, SSUPDATE_ASYNC, NULL, NULL, 0); + ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr); + + hr = IMemAllocator_GetBuffer(mem_allocator, &media_sample1, NULL, NULL, 0); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IMediaSample_GetMediaType(media_sample1, &sample_mt); + todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); + if (sample_mt) + { + ok(IsEqualGUID(&sample_mt->subtype, &MEDIASUBTYPE_RGB555), "Got subtype %s.\n", wine_dbgstr_guid(&sample_mt->subtype)); + DeleteMediaType(sample_mt); + } + hr = IMemAllocator_GetBuffer(mem_allocator, &media_sample2, NULL, NULL, 0); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IMediaSample_GetMediaType(media_sample2, &sample_mt); + todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); + if (sample_mt) + { + ok(IsEqualGUID(&sample_mt->subtype, &MEDIASUBTYPE_RGB555), "Got subtype %s.\n", wine_dbgstr_guid(&sample_mt->subtype)); + DeleteMediaType(sample_mt); + } + IMediaSample_Release(media_sample1); + IMediaSample_Release(media_sample2); + IDirectDrawStreamSample_Release(ddraw_sample1); + IDirectDrawStreamSample_Release(ddraw_sample2); + IMemAllocator_Release(mem_allocator); + + hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + IMemAllocator_Release(new_allocator); + IDirectDrawMediaStream_Release(ddraw_stream); + IMemAllocator_Release(ddraw_allocator); + IGraphBuilder_Disconnect(graph, pin); + IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface); + IPin_Release(pin); + IGraphBuilder_Release(graph); + + ref = IAMMultiMediaStream_Release(mmstream); + ok(!ref, "Got outstanding refcount %ld.\n", ref); + ref = IMediaStream_Release(stream); + ok(!ref, "Got outstanding refcount %ld.\n", ref); +} + + static void test_ddrawstreamsample_get_media_stream(void) { IAMMultiMediaStream *mmstream = create_ammultimediastream(); @@ -9812,6 +9958,7 @@ START_TEST(amstream) test_ddrawstream_new_segment(); test_ddrawstream_get_time_per_frame(); test_ddrawstream_qc(); + test_ddrawstream_mem_allocator();
test_ddrawstreamsample_get_media_stream(); test_ddrawstreamsample_update();