[PATCH] mfreadwrite/reader: Propagate resource sharing mode to the sample allocator.

Nikolay Sivov nsivov at codeweavers.com
Tue May 17 03:26:37 CDT 2022


The issue found by Derek Lesho.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/mfreadwrite/reader.c          |  32 ++++++-
 dlls/mfreadwrite/tests/mfplat.c    | 145 ++++++++++++++++++++++++++++-
 dlls/mfreadwrite/tests/resource.rc |   3 +
 dlls/mfreadwrite/tests/test.mp4    | Bin 0 -> 1554 bytes
 4 files changed, 178 insertions(+), 2 deletions(-)
 create mode 100644 dlls/mfreadwrite/tests/test.mp4

diff --git a/dlls/mfreadwrite/reader.c b/dlls/mfreadwrite/reader.c
index 741ef93f367..b1175479dec 100644
--- a/dlls/mfreadwrite/reader.c
+++ b/dlls/mfreadwrite/reader.c
@@ -1651,9 +1651,30 @@ static HRESULT source_reader_set_compatible_media_type(struct source_reader *rea
     return type_set ? S_OK : S_FALSE;
 }
 
+static HRESULT source_reader_create_sample_allocator_attributes(const struct source_reader *reader,
+        IMFAttributes **attributes)
+{
+    UINT32 shared = 0, shared_without_mutex = 0;
+    HRESULT hr;
+
+    if (FAILED(hr = MFCreateAttributes(attributes, 1)))
+        return hr;
+
+    IMFAttributes_GetUINT32(reader->attributes, &MF_SA_D3D11_SHARED, &shared);
+    IMFAttributes_GetUINT32(reader->attributes, &MF_SA_D3D11_SHARED_WITHOUT_MUTEX, &shared_without_mutex);
+
+    if (shared_without_mutex)
+        hr = IMFAttributes_SetUINT32(*attributes, &MF_SA_D3D11_SHARED_WITHOUT_MUTEX, TRUE);
+    else if (shared)
+        hr = IMFAttributes_SetUINT32(*attributes, &MF_SA_D3D11_SHARED, TRUE);
+
+    return hr;
+}
+
 static HRESULT source_reader_setup_sample_allocator(struct source_reader *reader, unsigned int index)
 {
     struct media_stream *stream = &reader->streams[index];
+    IMFAttributes *attributes = NULL;
     GUID major = { 0 };
     HRESULT hr;
 
@@ -1680,8 +1701,17 @@ static HRESULT source_reader_setup_sample_allocator(struct source_reader *reader
         return hr;
     }
 
-    if (FAILED(hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(stream->allocator, 2, 8, NULL, stream->current)))
+    if (FAILED(hr = source_reader_create_sample_allocator_attributes(reader, &attributes)))
+        WARN("Failed to create allocator attributes, hr %#lx.\n", hr);
+
+    if (FAILED(hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(stream->allocator, 2, 8,
+            attributes, stream->current)))
+    {
         WARN("Failed to initialize sample allocator, hr %#lx.\n", hr);
+    }
+
+    if (attributes)
+        IMFAttributes_Release(attributes);
 
     return hr;
 }
diff --git a/dlls/mfreadwrite/tests/mfplat.c b/dlls/mfreadwrite/tests/mfplat.c
index fcf642859d5..10aa74cd60f 100644
--- a/dlls/mfreadwrite/tests/mfplat.c
+++ b/dlls/mfreadwrite/tests/mfplat.c
@@ -26,8 +26,10 @@
 #include "winuser.h"
 #include "winreg.h"
 
+#define D3D11_INIT_GUID
 #include "initguid.h"
 #include "ole2.h"
+#include "d3d11_4.h"
 
 DEFINE_GUID(GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
 
@@ -42,6 +44,12 @@ DEFINE_GUID(GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
 
 #include "wine/test.h"
 
+static HRESULT (WINAPI *pD3D11CreateDevice)(IDXGIAdapter *adapter, D3D_DRIVER_TYPE driver_type, HMODULE swrast, UINT flags,
+        const D3D_FEATURE_LEVEL *feature_levels, UINT levels, UINT sdk_version, ID3D11Device **device_out,
+        D3D_FEATURE_LEVEL *obtained_feature_level, ID3D11DeviceContext **immediate_context);
+static HRESULT (WINAPI *pMFCreateMFByteStreamOnStream)(IStream *stream, IMFByteStream **bytestream);
+static HRESULT (WINAPI *pMFCreateDXGIDeviceManager)(UINT *token, IMFDXGIDeviceManager **manager);
+
 static ULONG get_refcount(void *iface)
 {
     IUnknown *unknown = iface;
@@ -80,7 +88,33 @@ static IDirect3DDevice9 *create_d3d9_device(IDirect3D9 *d3d9, HWND focus_window)
     return device;
 }
 
-static HRESULT (WINAPI *pMFCreateMFByteStreamOnStream)(IStream *stream, IMFByteStream **bytestream);
+static ID3D11Device *create_d3d11_device(void)
+{
+    static const D3D_FEATURE_LEVEL default_feature_level[] =
+    {
+        D3D_FEATURE_LEVEL_11_0,
+        D3D_FEATURE_LEVEL_10_1,
+        D3D_FEATURE_LEVEL_10_0,
+    };
+    const D3D_FEATURE_LEVEL *feature_level;
+    unsigned int feature_level_count;
+    ID3D11Device *device;
+
+    feature_level = default_feature_level;
+    feature_level_count = ARRAY_SIZE(default_feature_level);
+
+    if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
+            feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
+        return device;
+    if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_WARP, NULL, 0,
+            feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
+        return device;
+    if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, 0,
+            feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
+        return device;
+
+    return NULL;
+}
 
 static void init_functions(void)
 {
@@ -88,6 +122,12 @@ static void init_functions(void)
 
 #define X(f) if (!(p##f = (void*)GetProcAddress(mod, #f))) return;
     X(MFCreateMFByteStreamOnStream);
+    X(MFCreateDXGIDeviceManager);
+
+    if ((mod = LoadLibraryA("d3d11.dll")))
+    {
+        X(D3D11CreateDevice);
+    }
 #undef X
 }
 
@@ -1225,6 +1265,108 @@ done:
     DestroyWindow(window);
 }
 
+static void test_reader_d3d11(void)
+{
+    D3D11_TEXTURE2D_DESC texture_desc;
+    IMFDXGIDeviceManager *manager;
+    IMFDXGIBuffer *dxgi_buffer;
+    IMFAttributes *attributes;
+    IMFMediaType *media_type;
+    ID3D11Texture2D *texture;
+    IMFSourceReader *reader;
+    IMFMediaBuffer *buffer;
+    IMFByteStream *stream;
+    ID3D11Device *device;
+    DWORD count, flags;
+    IMFSample *sample;
+    HRESULT hr;
+    UINT token;
+
+    if (!(device = create_d3d11_device()))
+    {
+        skip("Failed to create a D3D11 device, skipping tests.\n");
+        return;
+    }
+
+    hr = pMFCreateDXGIDeviceManager(&token, &manager);
+    ok(hr == S_OK, "Failed to create device manager, hr %#lx.\n", hr);
+
+    hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)device, token);
+    ok(hr == S_OK, "Failed to set a device, hr %#lx.\n", hr);
+
+    stream = get_resource_stream("test.mp4");
+
+    hr = MFCreateAttributes(&attributes, 1);
+    ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+
+    hr = IMFAttributes_SetUnknown(attributes, &MF_SOURCE_READER_D3D_MANAGER, (IUnknown *)manager);
+    ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+    hr = IMFAttributes_SetUINT32(attributes, &MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING, TRUE);
+    ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+    hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_SHARED, TRUE);
+    ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+    hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_SHARED_WITHOUT_MUTEX, TRUE);
+    ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+    hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_BINDFLAGS, D3D11_BIND_SHADER_RESOURCE);
+    ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+    hr = IMFAttributes_SetUINT32(attributes, &MF_SA_BUFFERS_PER_SAMPLE, 2);
+    ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+
+    hr = MFCreateSourceReaderFromByteStream(stream, attributes, &reader);
+    ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+
+    hr = MFCreateMediaType(&media_type);
+    ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+
+    hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
+    ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+    hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32);
+    ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+    hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE, (UINT64)4 << 32 | 4);
+    ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+
+    hr = IMFSourceReader_SetCurrentMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, NULL, media_type);
+    todo_wine
+    ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+    if (FAILED(hr))
+    {
+        goto done;
+    }
+
+    hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, NULL, &flags, NULL, &sample);
+    ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+
+    hr = IMFSample_GetBufferCount(sample, &count);
+    ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+    ok(count == 1, "Unexpected count %lu.\n", count);
+    hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
+    ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+    hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
+    ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+    hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&texture);
+    ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+    ID3D11Texture2D_GetDesc(texture, &texture_desc);
+
+    ok(texture_desc.BindFlags == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET),
+            "Unexpected bind flags %#x.\n", texture_desc.BindFlags);
+    ok(texture_desc.MiscFlags == D3D11_RESOURCE_MISC_SHARED, "Unexpected Misc flags %#x.\n", texture_desc.MiscFlags);
+
+    ID3D11Texture2D_Release(texture);
+    IMFDXGIBuffer_Release(dxgi_buffer);
+    IMFMediaBuffer_Release(buffer);
+
+    IMFSample_Release(sample);
+
+done:
+    IMFAttributes_Release(attributes);
+    IMFSourceReader_Release(reader);
+
+    IMFMediaType_Release(media_type);
+    IMFByteStream_Release(stream);
+    IMFDXGIDeviceManager_Release(manager);
+    ID3D11Device_Release(device);
+}
+
 START_TEST(mfplat)
 {
     HRESULT hr;
@@ -1238,6 +1380,7 @@ START_TEST(mfplat)
     test_source_reader();
     test_source_reader_from_media_source();
     test_reader_d3d9();
+    test_reader_d3d11();
 
     hr = MFShutdown();
     ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
diff --git a/dlls/mfreadwrite/tests/resource.rc b/dlls/mfreadwrite/tests/resource.rc
index f54212a8c8f..9cd83ce3217 100644
--- a/dlls/mfreadwrite/tests/resource.rc
+++ b/dlls/mfreadwrite/tests/resource.rc
@@ -20,3 +20,6 @@
 
 /* @makedep: test.wav */
 test.wav RCDATA test.wav
+
+/* @makedep: test.mp4 */
+test.mp4 RCDATA test.mp4
diff --git a/dlls/mfreadwrite/tests/test.mp4 b/dlls/mfreadwrite/tests/test.mp4
new file mode 100644
index 0000000000000000000000000000000000000000..a5bbca6bbf7692eab047050b79b8ccc83516e6b4
GIT binary patch
literal 1554
zcmZuxeN0nV6u<3bttg}g3M<<3v4A5C7=;cYskS&=aH+Gw(TQ=|2k#+BpKbac6$q26
zgvfMZE^O--6L1NclR1flh8QLw4%rM5#eGC{R2Jv(j|s9(8MANazOwnmo#gk<x#yhw
zyZ4 at R-$e*%%DGx+CF@`ik|L}DS&UP!LkKM^chNNX_cIj9Atd<{DdnJiN*lZEK&*TH
zLUnilE|&Pi#`t<(V2JeCh0xUFbE~$JpP!3QD)e^to at B05Kdu~jt~KuYz}1=h$wy;^
z-(P&iYuL#r*6qMlmYD;w&8gboiuVmim)E`@VY(w}d_`I2ihOP3>WzsJPV$oN<)LWX
zeE-6+iWMz`xA<B45szMa^nqwQ5w>wzrc-v;{3ns3&Hgygab at co_v%sWh^~kxZdgv1
zG$e27=y&X0FwfM)&vJ1wQfF>hX5`>p!|hca@<xwAt#6-gnD>;lG>BPmWrt3nUp`73
z+Yr|+TbnzS=UsV1v;C6gviW|rw)-!S-=bHn;0v1+QGDC}Ia|1D&?ob%jF`h$Wc#Ew
zV;vf3`obS*$vM<kEDwCQ`|#nw>4L6xr#4wnKY06wGT*}wdIn7LW=}zVn#?n%4mVMz
zS*QG<-xMcs%$)a1n<6jX{=IjfF~joa!xMeyYRwY|Cr0Vm>*3w%uu#*`=0;_WapAn$
zU<`El at AbuA79AjpWMkq|c1;#tZJ#~+J(2cx>Nm%BvdmP*5AP|wGW~$TESZLVhn6a1
ztO^C+GL%><v}DW7eXsQJ-HUG|I!ZcwqEv0#Ya at m<t5KG7N5rlo$2IYtr*eGsbj8h0
z?c at jJ8?GH6PW~!_$shUIcJraKf^47ff8>qKKRQs;^7r5rKP{`hCoZsRD*LTIOV>}^
zv}Z#0Dsy%(f4!(s5zT+wRX-W1@{bU&DxT$gcYNB95Wz4GhZ`=WopD!CphZIb3Y&Tt
zN#HB;J~@EE6G4Pb;@qcgDO~ywITu+4q3v9iuqGi&TV#WEm&%fL{&(FFn1q2)5>0U|
zXbo*=;Rh207#4X2E~$c{DoKbWFx1ksXMtOViZ2NB(km#tOR(VMuB70{eJoZOI||7?
zl%2*olCw<Zo^mi$Zbl##Z##(!#x#_R#yMDUJgnMfPYBwQI+iQ7gFVc0?7t1cIX-wf
zaHFt at IfI@MICdeJ7+9Xp2>Ks?)jSUa8_iO<Oo;G!Jey%!2<ZHT2<$>SD4dRa20SkU
zV;68rdYYqx<dOt*;hjTh6eXe7GH{(SlkT#Yax=1Y8M;ip4CY9n)kw{9LK`q0-qUjY
z7J{U}>4bH`mH}`KUjy7ccnDD_0CJHA at _=3toU_OwXamIR7Gqf9{35_wfE7@%h&<3n
zKs;bQARC}!xiSZ6ESNJ5P+CoKB<O7nEod-NqPX>NU0kHoiM#Wkq*n&-SMq0^0~2cD
TJ;x-N6hTeOp(eUDP!ruh^$B~#

literal 0
HcmV?d00001

-- 
2.35.1




More information about the wine-devel mailing list