The issue found by Derek Lesho.
Signed-off-by: Nikolay Sivov <nsivov(a)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@R-$e*%%DGx+CF@`ik|L}DS&UP!LkKM^chNNX_cIj9Atd<{DdnJiN*lZEK&*TH
zLUnilE|&Pi#`t<(V2JeCh0xUFbE~$JpP!3QD)e^to@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@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@AbuA79AjpWMkq|c1;#tZJ#~+J(2cx>Nm%BvdmP*5AP|wGW~$TESZLVhn6a1
ztO^C+GL%><v}DW7eXsQJ-HUG|I!ZcwqEv0#Ya@m<t5KG7N5rlo$2IYtr*eGsbj8h0
z?c@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@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@_=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