Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/evr/tests/evr.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-)
diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c index 31434bde43a..94bf327dd92 100644 --- a/dlls/evr/tests/evr.c +++ b/dlls/evr/tests/evr.c @@ -1422,17 +1422,14 @@ static void test_MFCreateVideoSampleAllocator(void) ok(hr == S_OK, "Unexpected hr %#x.\n", hr); ok(count == 4, "Unexpected count %d.\n", count);
- hr = IMFSample_QueryInterface(sample, &IID_IMFDesiredSample, (void **)&unk); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); - IUnknown_Release(unk); - - hr = IMFSample_QueryInterface(sample, &IID_IMFTrackedSample, (void **)&unk); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); - IUnknown_Release(unk); + check_interface(sample, &IID_IMFDesiredSample, TRUE); + check_interface(sample, &IID_IMFTrackedSample, TRUE);
hr = IMFSample_GetBufferByIndex(sample, 0, &buffer); ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ check_interface(buffer, &IID_IMF2DBuffer, TRUE); + hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFGetService, (void **)&gs); ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* Win7 */, "Unexpected hr %#x.\n", hr);
@@ -1444,10 +1441,6 @@ static void test_MFCreateVideoSampleAllocator(void) IMFGetService_Release(gs); }
- hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&unk); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); - IUnknown_Release(unk); - IMFMediaBuffer_Release(buffer);
IMFSample_Release(sample); @@ -1489,14 +1482,15 @@ static void test_MFCreateVideoSampleAllocator(void) hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample); ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ check_interface(sample, &IID_IMFTrackedSample, TRUE); + check_interface(sample, &IID_IMFDesiredSample, TRUE); + hr = IMFSample_GetBufferByIndex(sample, 0, &buffer); ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
check_service_interface(buffer, &MR_BUFFER_SERVICE, &IID_IDirect3DSurface9, TRUE); - - hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&unk); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); - IUnknown_Release(unk); + check_interface(buffer, &IID_IMF2DBuffer, TRUE); + check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL); ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/sample.c | 57 ++++++++++++++++++++++++++++---- dlls/mfplat/tests/mfplat.c | 66 +++++++++++++++++++++++++++++++++++--- 2 files changed, 112 insertions(+), 11 deletions(-)
diff --git a/dlls/mfplat/sample.c b/dlls/mfplat/sample.c index acdc8836cc8..4ecce4fbe84 100644 --- a/dlls/mfplat/sample.c +++ b/dlls/mfplat/sample.c @@ -76,6 +76,7 @@ struct sample_allocator } frame_desc;
IMFAttributes *attributes; + IMFMediaType *media_type;
unsigned int free_sample_count; unsigned int cold_sample_count; @@ -1114,6 +1115,48 @@ static void sample_allocator_release_samples(struct sample_allocator *allocator) list_remove(&iter->entry); heap_free(iter); } + + allocator->free_sample_count = 0; + allocator->cold_sample_count = 0; +} + +static void sample_allocator_set_media_type(struct sample_allocator *allocator, IMFMediaType *media_type) +{ + UINT64 frame_size; + GUID subtype; + + if (!media_type) + { + if (allocator->media_type) + IMFMediaType_Release(allocator->media_type); + allocator->media_type = NULL; + return; + } + + /* Check if type is the same. */ + IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &frame_size); + IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &subtype); + + if (frame_size == ((UINT64) allocator->frame_desc.width << 32 | allocator->frame_desc.height) && + subtype.Data1 == allocator->frame_desc.d3d9_format) + { + return; + } + + if (allocator->media_type) + IMFMediaType_Release(allocator->media_type); + allocator->media_type = media_type; + if (allocator->media_type) + IMFMediaType_AddRef(allocator->media_type); +} + +static void sample_allocator_set_attributes(struct sample_allocator *allocator, IMFAttributes *attributes) +{ + if (allocator->attributes) + IMFAttributes_Release(allocator->attributes); + allocator->attributes = attributes; + if (allocator->attributes) + IMFAttributes_AddRef(allocator->attributes); }
static ULONG WINAPI sample_allocator_Release(IMFVideoSampleAllocatorEx *iface) @@ -1133,6 +1176,8 @@ static ULONG WINAPI sample_allocator_Release(IMFVideoSampleAllocatorEx *iface) IMFDXGIDeviceManager_Release(allocator->dxgi_device_manager); if (allocator->attributes) IMFAttributes_Release(allocator->attributes); + sample_allocator_set_media_type(allocator, NULL); + sample_allocator_set_attributes(allocator, NULL); sample_allocator_release_samples(allocator); DeleteCriticalSection(&allocator->cs); heap_free(allocator); @@ -1190,7 +1235,9 @@ static HRESULT WINAPI sample_allocator_UninitializeSampleAllocator(IMFVideoSampl EnterCriticalSection(&allocator->cs);
sample_allocator_release_samples(allocator); - allocator->free_sample_count = 0; + sample_allocator_set_media_type(allocator, NULL); + sample_allocator_set_attributes(allocator, NULL); + memset(&allocator->frame_desc, 0, sizeof(allocator->frame_desc));
LeaveCriticalSection(&allocator->cs);
@@ -1348,16 +1395,14 @@ static HRESULT sample_allocator_initialize(struct sample_allocator *allocator, u if (sample_count > max_sample_count) return E_INVALIDARG;
+ sample_allocator_set_media_type(allocator, media_type); + sample_allocator_set_attributes(allocator, attributes); + sample_count = max(1, sample_count); max_sample_count = max(1, max_sample_count);
if (attributes) - { - allocator->attributes = attributes; - IMFAttributes_AddRef(allocator->attributes); - IMFAttributes_GetUINT32(attributes, &MF_SA_BUFFERS_PER_SAMPLE, &allocator->frame_desc.buffer_count); - }
allocator->frame_desc.d3d9_format = subtype.Data1; allocator->frame_desc.dxgi_format = MFMapDX9FormatToDXGIFormat(allocator->frame_desc.d3d9_format); diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 0464293b37f..9e3a3da08ea 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -6290,27 +6290,27 @@ static void test_dxgi_surface_buffer(void) static void test_sample_allocator(void) { IMFVideoSampleAllocatorNotify test_notify = { &test_notify_callback_vtbl }; + IMFMediaType *media_type, *video_type, *video_type2; IMFVideoSampleAllocatorCallback *allocator_cb; IMFVideoSampleAllocatorEx *allocatorex; - IMFMediaType *media_type, *video_type; + IDirect3DDeviceManager9 *d3d9_manager; IMFVideoSampleAllocator *allocator; + unsigned int buffer_count, token; + IDirect3DDevice9 *d3d9_device; IMFDXGIDeviceManager *manager; IMFSample *sample, *sample2; IMFDXGIBuffer *dxgi_buffer; IMFAttributes *attributes; D3D11_TEXTURE2D_DESC desc; - unsigned int buffer_count, token; ID3D11Texture2D *texture; IMFMediaBuffer *buffer; ID3D11Device *device; LONG refcount, count; + IDirect3D9 *d3d9; IUnknown *unk; HRESULT hr; BYTE *data; - IDirect3D9 *d3d9; HWND window; - IDirect3DDeviceManager9 *d3d9_manager; - IDirect3DDevice9 *d3d9_device;
if (!pMFCreateVideoSampleAllocatorEx) { @@ -6366,6 +6366,7 @@ static void test_sample_allocator(void) ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
video_type = create_video_type(&MFVideoFormat_RGB32); + video_type2 = create_video_type(&MFVideoFormat_RGB32);
hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, video_type); ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr); @@ -6374,11 +6375,42 @@ static void test_sample_allocator(void) hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 240); ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 240); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 0, video_type); ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+ EXPECT_REF(video_type, 1); hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + EXPECT_REF(video_type, 2); + + hr = IMFMediaType_SetUINT64(video_type2, &IID_IUnknown, (UINT64) 320 << 32 | 240); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + /* Setting identical type does not replace it. */ + hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type2); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + EXPECT_REF(video_type, 2); + EXPECT_REF(video_type2, 1); + + hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 64 << 32 | 64); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type2); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + EXPECT_REF(video_type2, 2); + EXPECT_REF(video_type, 1); + + /* Modify referenced type. */ + hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 64); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + EXPECT_REF(video_type, 2); + EXPECT_REF(video_type2, 1);
count = 0; hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count); @@ -6401,6 +6433,7 @@ static void test_sample_allocator(void) hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, video_type); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); ok(refcount == get_refcount(sample), "Unexpected refcount %u.\n", get_refcount(sample)); + EXPECT_REF(video_type, 2);
hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); @@ -6426,6 +6459,18 @@ todo_wine
IMFSample_Release(sample);
+ hr = IMFVideoSampleAllocator_UninitializeSampleAllocator(allocator); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); +todo_wine + EXPECT_REF(video_type, 2); + + hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(!count, "Unexpected count %d.\n", count); + + hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample); + ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr); + IMFVideoSampleAllocatorCallback_Release(allocator_cb); IMFVideoSampleAllocator_Release(allocator);
@@ -6468,6 +6513,15 @@ todo_wine hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample2); ok(hr == MF_E_SAMPLEALLOCATOR_EMPTY, "Unexpected hr %#x.\n", hr);
+ /* Reinitialize with already allocated samples. */ + hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, NULL, video_type); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + EXPECT_REF(attributes, 1); + + hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample2); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + IMFSample_Release(sample2); + IMFSample_Release(sample);
IMFVideoSampleAllocatorCallback_Release(allocator_cb); @@ -6490,8 +6544,10 @@ todo_wine hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator); ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ EXPECT_REF(manager, 1); hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, (IUnknown *)manager); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + EXPECT_REF(manager, 2);
hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 0, video_type); ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=85370
Your paranoid android.
=== w7u_adm (32 bit report) ===
mfplat: 0a38:mfplat: unhandled exception c0000005 at 6D537D1C
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfreadwrite/reader.c | 6 ++++++ dlls/mfreadwrite/tests/mfplat.c | 16 +++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/dlls/mfreadwrite/reader.c b/dlls/mfreadwrite/reader.c index 0e0fe1ad9cd..86507bde5a1 100644 --- a/dlls/mfreadwrite/reader.c +++ b/dlls/mfreadwrite/reader.c @@ -169,6 +169,7 @@ struct source_reader IMFMediaSource *source; IMFPresentationDescriptor *descriptor; IMFSourceReaderCallback *async_callback; + IMFAttributes *attributes; unsigned int first_audio_stream_index; unsigned int first_video_stream_index; unsigned int last_read_index; @@ -1268,6 +1269,8 @@ static ULONG WINAPI src_reader_Release(IMFSourceReader *iface) IMFMediaSource_Shutdown(reader->source); if (reader->descriptor) IMFPresentationDescriptor_Release(reader->descriptor); + if (reader->attributes) + IMFAttributes_Release(reader->attributes); IMFMediaSource_Release(reader->source);
for (i = 0; i < reader->stream_count; ++i) @@ -2162,6 +2165,9 @@ static HRESULT create_source_reader_from_source(IMFMediaSource *source, IMFAttri
if (attributes) { + object->attributes = attributes; + IMFAttributes_AddRef(object->attributes); + IMFAttributes_GetUnknown(attributes, &MF_SOURCE_READER_ASYNC_CALLBACK, &IID_IMFSourceReaderCallback, (void **)&object->async_callback); if (object->async_callback) diff --git a/dlls/mfreadwrite/tests/mfplat.c b/dlls/mfreadwrite/tests/mfplat.c index 8455ac64688..9d84265244a 100644 --- a/dlls/mfreadwrite/tests/mfplat.c +++ b/dlls/mfreadwrite/tests/mfplat.c @@ -41,6 +41,13 @@ DEFINE_GUID(GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); #include "wine/heap.h" #include "wine/test.h"
+static ULONG get_refcount(void *iface) +{ + IUnknown *unknown = iface; + IUnknown_AddRef(unknown); + return IUnknown_Release(unknown); +} + static HRESULT (WINAPI *pMFCreateMFByteStreamOnStream)(IStream *stream, IMFByteStream **bytestream);
static void init_functions(void) @@ -620,6 +627,7 @@ static void test_source_reader(void) IMFByteStream *stream; LONGLONG timestamp; IMFSample *sample; + ULONG refcount; BOOL selected; HRESULT hr;
@@ -836,9 +844,12 @@ skip_read_sample: ok(hr == S_OK, "Failed to set attribute value, hr %#x.\n", hr); IMFSourceReaderCallback_Release(&callback->IMFSourceReaderCallback_iface);
+ refcount = get_refcount(attributes); hr = MFCreateSourceReaderFromByteStream(stream, attributes, &reader); -todo_wine +todo_wine { ok(hr == S_OK, "Failed to create source reader, hr %#x.\n", hr); + ok(get_refcount(attributes) > refcount, "Unexpected refcount.\n"); +} IMFAttributes_Release(attributes); if (hr == S_OK) IMFSourceReader_Release(reader); @@ -856,6 +867,7 @@ static void test_source_reader_from_media_source(void) IMFSample *sample; LONGLONG timestamp; IMFAttributes *attributes; + ULONG refcount; int i;
source = create_test_source(); @@ -967,8 +979,10 @@ static void test_source_reader_from_media_source(void) ok(hr == S_OK, "Failed to set attribute value, hr %#x.\n", hr); IMFSourceReaderCallback_Release(&callback->IMFSourceReaderCallback_iface);
+ refcount = get_refcount(attributes); hr = MFCreateSourceReaderFromMediaSource(source, attributes, &reader); ok(hr == S_OK, "Failed to create source reader, hr %#x.\n", hr); + ok(get_refcount(attributes) > refcount, "Unexpected refcount.\n");
hr = IMFSourceReader_SetStreamSelection(reader, 0, TRUE); ok(hr == S_OK, "Failed to select a stream, hr %#x.\n", hr);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfreadwrite/reader.c | 78 ++++++++++++++++++++++++++- dlls/mfreadwrite/tests/Makefile.in | 2 +- dlls/mfreadwrite/tests/mfplat.c | 85 ++++++++++++++++++++++++++++++ 3 files changed, 163 insertions(+), 2 deletions(-)
diff --git a/dlls/mfreadwrite/reader.c b/dlls/mfreadwrite/reader.c index 86507bde5a1..6a69196054a 100644 --- a/dlls/mfreadwrite/reader.c +++ b/dlls/mfreadwrite/reader.c @@ -33,6 +33,9 @@ #include "mferror.h" #include "mfidl.h" #include "mfreadwrite.h" +#include "d3d9.h" +#include "initguid.h" +#include "dxva2api.h"
#include "wine/debug.h" #include "wine/heap.h" @@ -108,6 +111,7 @@ struct media_stream IMFMediaStream *stream; IMFMediaType *current; IMFTransform *decoder; + IMFVideoSampleAllocatorEx *allocator; unsigned int id; unsigned int index; enum media_stream_state state; @@ -157,6 +161,9 @@ enum source_reader_flags SOURCE_READER_FLUSHING = 0x1, SOURCE_READER_SEEKING = 0x2, SOURCE_READER_SHUTDOWN_ON_RELEASE = 0x4, + SOURCE_READER_D3D9_DEVICE_MANAGER = 0x8, + SOURCE_READER_DXGI_DEVICE_MANAGER = 0x10, + SOURCE_READER_HAS_DEVICE_MANAGER = SOURCE_READER_D3D9_DEVICE_MANAGER | SOURCE_READER_DXGI_DEVICE_MANAGER, };
struct source_reader @@ -170,6 +177,7 @@ struct source_reader IMFPresentationDescriptor *descriptor; IMFSourceReaderCallback *async_callback; IMFAttributes *attributes; + IUnknown *device_manager; unsigned int first_audio_stream_index; unsigned int first_video_stream_index; unsigned int last_read_index; @@ -1283,6 +1291,8 @@ static ULONG WINAPI src_reader_Release(IMFSourceReader *iface) IMFMediaType_Release(stream->current); if (stream->decoder) IMFTransform_Release(stream->decoder); + if (stream->allocator) + IMFVideoSampleAllocatorEx_Release(stream->allocator); } source_reader_release_responses(reader, NULL); heap_free(reader->streams); @@ -1519,6 +1529,48 @@ static HRESULT source_reader_set_compatible_media_type(struct source_reader *rea return type_set ? S_OK : S_FALSE; }
+static HRESULT source_reader_setup_sample_allocator(struct source_reader *reader, unsigned int index, + IMFMediaType *media_type) +{ + struct media_stream *stream = &reader->streams[index]; + GUID major = { 0 }; + HRESULT hr; + + IMFMediaType_GetMajorType(media_type, &major); + if (!IsEqualGUID(&major, &MFMediaType_Video)) + return S_OK; + + if (!(reader->flags & SOURCE_READER_HAS_DEVICE_MANAGER)) + return S_OK; + + if (reader->flags & SOURCE_READER_DXGI_DEVICE_MANAGER) + { + FIXME("DXGI device manager is not supported.\n"); + return S_OK; + } + + if (!stream->allocator) + { + if (FAILED(hr = MFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocatorEx, (void **)&stream->allocator))) + { + WARN("Failed to create sample allocator, hr %#x.\n", hr); + return hr; + } + } + + IMFVideoSampleAllocatorEx_UninitializeSampleAllocator(stream->allocator); + if (FAILED(hr = IMFVideoSampleAllocatorEx_SetDirectXManager(stream->allocator, reader->device_manager))) + { + WARN("Failed to set device manager, hr %#x.\n", hr); + return hr; + } + + if (FAILED(hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(stream->allocator, 2, 8, NULL, media_type))) + WARN("Failed to initialize sample allocator, hr %#x.\n", hr); + + return hr; +} + static HRESULT source_reader_configure_decoder(struct source_reader *reader, DWORD index, const CLSID *clsid, IMFMediaType *input_type, IMFMediaType *output_type) { @@ -1668,8 +1720,11 @@ static HRESULT WINAPI src_reader_SetCurrentMediaType(IMFSourceReader *iface, DWO
EnterCriticalSection(&reader->cs);
- if ((hr = source_reader_set_compatible_media_type(reader, index, type)) == S_FALSE) + hr = source_reader_set_compatible_media_type(reader, index, type); + if (hr == S_FALSE) hr = source_reader_create_decoder_for_stream(reader, index, type); + if (SUCCEEDED(hr)) + hr = source_reader_setup_sample_allocator(reader, index, type);
LeaveCriticalSection(&reader->cs);
@@ -2172,6 +2227,27 @@ static HRESULT create_source_reader_from_source(IMFMediaSource *source, IMFAttri (void **)&object->async_callback); if (object->async_callback) TRACE("Using async callback %p.\n", object->async_callback); + + IMFAttributes_GetUnknown(attributes, &MF_SOURCE_READER_D3D_MANAGER, &IID_IUnknown, (void **)&object->device_manager); + if (object->device_manager) + { + IUnknown *unk = NULL; + + if (SUCCEEDED(IUnknown_QueryInterface(object->device_manager, &IID_IMFDXGIDeviceManager, (void **)&unk))) + object->flags |= SOURCE_READER_DXGI_DEVICE_MANAGER; + else if (SUCCEEDED(IUnknown_QueryInterface(object->device_manager, &IID_IDirect3DDeviceManager9, (void **)&unk))) + object->flags |= SOURCE_READER_D3D9_DEVICE_MANAGER; + + if (!(object->flags & (SOURCE_READER_HAS_DEVICE_MANAGER))) + { + WARN("Unknown device manager.\n"); + IUnknown_Release(object->device_manager); + object->device_manager = NULL; + } + + if (unk) + IUnknown_Release(unk); + } }
hr = IMFSourceReader_QueryInterface(&object->IMFSourceReader_iface, riid, out); diff --git a/dlls/mfreadwrite/tests/Makefile.in b/dlls/mfreadwrite/tests/Makefile.in index ae86fed95f6..c7476c14c6b 100644 --- a/dlls/mfreadwrite/tests/Makefile.in +++ b/dlls/mfreadwrite/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = mfreadwrite.dll -IMPORTS = ole32 mfplat mfreadwrite mfuuid +IMPORTS = ole32 user32 d3d9 dxva2 mfplat mfreadwrite mfuuid
C_SRCS = \ mfplat.c diff --git a/dlls/mfreadwrite/tests/mfplat.c b/dlls/mfreadwrite/tests/mfplat.c index 9d84265244a..c6191767164 100644 --- a/dlls/mfreadwrite/tests/mfplat.c +++ b/dlls/mfreadwrite/tests/mfplat.c @@ -37,6 +37,8 @@ DEFINE_GUID(GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); #include "mfidl.h" #include "mferror.h" #include "mfreadwrite.h" +#include "d3d9.h" +#include "dxva2api.h"
#include "wine/heap.h" #include "wine/test.h" @@ -48,6 +50,37 @@ static ULONG get_refcount(void *iface) return IUnknown_Release(unknown); }
+static HWND create_window(void) +{ + RECT r = {0, 0, 640, 480}; + + AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE); + + return CreateWindowA("static", "mfreadwrite_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, + 0, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL); +} + +static IDirect3DDevice9 *create_d3d9_device(IDirect3D9 *d3d9, HWND focus_window) +{ + D3DPRESENT_PARAMETERS present_parameters = {0}; + IDirect3DDevice9 *device = NULL; + + present_parameters.BackBufferWidth = 640; + present_parameters.BackBufferHeight = 480; + present_parameters.BackBufferFormat = D3DFMT_X8R8G8B8; + present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD; + present_parameters.hDeviceWindow = focus_window; + present_parameters.Windowed = TRUE; + present_parameters.EnableAutoDepthStencil = TRUE; + present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8; + present_parameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; + + IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window, + D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device); + + return device; +} + static HRESULT (WINAPI *pMFCreateMFByteStreamOnStream)(IStream *stream, IMFByteStream **bytestream);
static void init_functions(void) @@ -1054,6 +1087,57 @@ static void test_source_reader_from_media_source(void) fail_request_sample = FALSE; }
+static void test_reader_d3d9(void) +{ + IDirect3DDeviceManager9 *d3d9_manager; + IDirect3DDevice9 *d3d9_device; + IMFAttributes *attributes; + IMFSourceReader *reader; + IMFMediaSource *source; + IDirect3D9 *d3d9; + HWND window; + HRESULT hr; + UINT token; + + window = create_window(); + d3d9 = Direct3DCreate9(D3D_SDK_VERSION); + ok(!!d3d9, "Failed to create a D3D9 object.\n"); + if (!(d3d9_device = create_d3d9_device(d3d9, window))) + { + skip("Failed to create a D3D9 device, skipping tests.\n"); + goto done; + } + + hr = DXVA2CreateDirect3DDeviceManager9(&token, &d3d9_manager); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IDirect3DDeviceManager9_ResetDevice(d3d9_manager, d3d9_device, token); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + source = create_test_source(); + ok(!!source, "Failed to create test source.\n"); + + hr = MFCreateAttributes(&attributes, 1); + ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr); + + hr = IMFAttributes_SetUnknown(attributes, &MF_SOURCE_READER_D3D_MANAGER, (IUnknown *)d3d9_manager); + ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr); + + hr = MFCreateSourceReaderFromMediaSource(source, attributes, &reader); + ok(hr == S_OK, "Failed to create source reader, hr %#x.\n", hr); + + IMFAttributes_Release(attributes); + + IMFSourceReader_Release(reader); + + IDirect3DDeviceManager9_Release(d3d9_manager); + IDirect3DDevice9_Release(d3d9_device); + +done: + IDirect3D9_Release(d3d9); + DestroyWindow(window); +} + START_TEST(mfplat) { HRESULT hr; @@ -1066,6 +1150,7 @@ START_TEST(mfplat) test_factory(); test_source_reader(); test_source_reader_from_media_source(); + test_reader_d3d9();
hr = MFShutdown(); ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);