From: Conor McCarthy cmccarthy@codeweavers.com
Shows that the stream does not hold a reference until Start() is called, and releases it during Shutdown(). --- dlls/mfplat/tests/mfplat.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-)
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 40bb12b683b..6535890b6c7 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -1321,6 +1321,10 @@ static void test_source_resolver(void) ok(mediasource != NULL, "got %p\n", mediasource); ok(obj_type == MF_OBJECT_MEDIASOURCE, "got %d\n", obj_type);
+ /* Test that no extra refs to mediasource are held if Start() was not called */ + todo_wine + EXPECT_REF(mediasource, 1); + refcount = IMFMediaSource_Release(mediasource); todo_wine ok(!refcount, "Unexpected refcount %ld\n", refcount); @@ -1409,15 +1413,24 @@ static void test_source_resolver(void) ok(mediasource != NULL, "got %p\n", mediasource); ok(obj_type == MF_OBJECT_MEDIASOURCE, "got %d\n", obj_type);
+ todo_wine + EXPECT_REF(mediasource, 1); + check_interface(mediasource, &IID_IMFGetService, TRUE); check_service_interface(mediasource, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, TRUE);
hr = IMFMediaSource_QueryInterface(mediasource, &IID_IMFGetService, (void**)&get_service); ok(hr == S_OK, "Failed to get service interface, hr %#lx.\n", hr);
+ todo_wine + EXPECT_REF(mediasource, 2); + hr = IMFGetService_GetService(get_service, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, (void**)&rate_support); ok(hr == S_OK, "Failed to get rate support interface, hr %#lx.\n", hr);
+ todo_wine + EXPECT_REF(mediasource, 3); + hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_FORWARD, FALSE, &rate); ok(hr == S_OK, "Failed to query fastest rate, hr %#lx.\n", hr); ok(rate == 1e6f, "Unexpected fastest rate %f.\n", rate); @@ -1506,6 +1519,10 @@ static void test_source_resolver(void) hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var); ok(hr == S_OK, "Failed to start media source, hr %#lx.\n", hr);
+ /* The stream holds a reference. It is unclear which object holds the fifth + * reference in Windows, but it's released after MENewStream is retrieved. */ + EXPECT_REF(mediasource, 5); + video_stream = NULL; if (get_event((IMFMediaEventGenerator *)mediasource, MENewStream, &var)) { @@ -1513,6 +1530,8 @@ static void test_source_resolver(void) video_stream = (IMFMediaStream *)var.punkVal; }
+ EXPECT_REF(mediasource, 4); + hr = IMFMediaSource_Pause(mediasource); ok(hr == S_OK, "Failed to pause media source, hr %#lx.\n", hr); if (get_event((IMFMediaEventGenerator *)mediasource, MESourcePaused, &var)) @@ -1621,14 +1640,23 @@ static void test_source_resolver(void) hr = IMFMediaSource_Shutdown(mediasource); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ /* During shutdown, circular references such as source <-> stream should be released. */ + EXPECT_REF(mediasource, 3); + ok(bytestream_closed, "Missing IMFByteStream::Close call\n");
hr = IMFMediaSource_CreatePresentationDescriptor(mediasource, NULL); ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
IMFRateSupport_Release(rate_support); + + EXPECT_REF(mediasource, 2); + IMFGetService_Release(get_service); - IMFMediaSource_Release(mediasource); + + refcount = IMFMediaSource_Release(mediasource); + ok(!refcount, "Unexpected refcount %ld\n", refcount); + IMFByteStream_Release(stream);
/* Create directly through scheme handler. */