Nikolay Sivov : mfplat/allocator: Improve initialization handling.

Alexandre Julliard julliard at winehq.org
Wed Feb 10 15:34:02 CST 2021


Module: wine
Branch: master
Commit: 14f6c095089f6943a0cf54067bb7391be35e069b
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=14f6c095089f6943a0cf54067bb7391be35e069b

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Wed Feb 10 13:32:28 2021 +0300

mfplat/allocator: Improve initialization handling.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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);




More information about the wine-cvs mailing list