[PATCH 4/5] mfreadwrite/reader: Setup the sample allocator in ReadSample.

Giovanni Mascellani gmascellani at codeweavers.com
Fri Mar 18 08:27:18 CDT 2022


Currently the source reader creates a sample allocator as soon as
SetCurrentMediaType() is called. However on Windows if the output
attribute MF_SA_D3D11_SHARED_WITHOUT_MUTEX is set on the transform
after SetCurrentMediaType() is called, but before ReadSample() is
called, the sample allocator will generate shareable samples.

In order to emulate the same behavior, we defer creating the sample
allocator to the first ReadSample() call, so the most updated
attributes are picked up.

With this and the previous two patches, some video playback bugs
are solved for some games (e.g. Trailmakers, Rustler, TOHU and
others) when using DXVK (wined3d doesn't currently support
shared resources, so there is no way to check with it).

Signed-off-by: Giovanni Mascellani <gmascellani at codeweavers.com>
---
Again, it's not easy to check that this is what's really happening
on Windows. OTOH, AFAIK, neither we know that the sample allocator
is created in SetCurrentMediaType().
---
 dlls/mfreadwrite/reader.c | 30 ++++++++++++++++++++++++++----
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/dlls/mfreadwrite/reader.c b/dlls/mfreadwrite/reader.c
index 2ff56f6e978..7ae9f88c4c4 100644
--- a/dlls/mfreadwrite/reader.c
+++ b/dlls/mfreadwrite/reader.c
@@ -1696,6 +1696,8 @@ static HRESULT source_reader_flush(struct source_reader *reader, unsigned int in
     return hr;
 }
 
+static HRESULT source_reader_setup_sample_allocator(struct source_reader *reader, unsigned int index);
+
 static HRESULT WINAPI source_reader_async_commands_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
 {
     struct source_reader *reader = impl_from_async_commands_callback_IMFAsyncCallback(iface);
@@ -1725,7 +1727,15 @@ static HRESULT WINAPI source_reader_async_commands_callback_Invoke(IMFAsyncCallb
                 {
                     stream = &reader->streams[stream_index];
 
-                    if (!(report_sample = source_reader_get_read_result(reader, stream, command->u.read.flags, &status,
+                    if (!stream->allocator)
+                    {
+                        hr = source_reader_setup_sample_allocator(reader, stream_index);
+
+                        if (FAILED(hr))
+                            WARN("Failed to setup the sample allocator, hr %#x.\n", hr);
+                    }
+
+                    if (SUCCEEDED(hr) && !(report_sample = source_reader_get_read_result(reader, stream, command->u.read.flags, &status,
                             &stream_index, &stream_flags, &timestamp, &sample)))
                     {
                         stream->requests++;
@@ -2359,8 +2369,12 @@ static HRESULT WINAPI src_reader_SetCurrentMediaType(IMFSourceReader *iface, DWO
         hr = source_reader_create_decoder_for_stream(reader, index, type);
     else if (hr == S_OK)
         hr = source_reader_add_passthrough_transform(reader, index, reader->streams[index].current);
-    if (SUCCEEDED(hr))
-        hr = source_reader_setup_sample_allocator(reader, index);
+
+    if (reader->streams[index].allocator)
+    {
+        IMFVideoSampleAllocatorEx_Release(reader->streams[index].allocator);
+        reader->streams[index].allocator = NULL;
+    }
 
     LeaveCriticalSection(&reader->cs);
 
@@ -2454,7 +2468,15 @@ static HRESULT source_reader_read_sample(struct source_reader *reader, DWORD ind
 
             stream = &reader->streams[stream_index];
 
-            if (!source_reader_get_read_result(reader, stream, flags, &hr, actual_index, stream_flags,
+            if (!stream->allocator)
+            {
+                hr = source_reader_setup_sample_allocator(reader, stream_index);
+
+                if (FAILED(hr))
+                    WARN("Failed to setup the sample allocator, hr %#x.\n", hr);
+            }
+
+            if (SUCCEEDED(hr) && !source_reader_get_read_result(reader, stream, flags, &hr, actual_index, stream_flags,
                    timestamp, sample))
             {
                 while (!source_reader_got_response_for_stream(reader, stream) && stream->state != STREAM_STATE_EOS)
-- 
2.35.1




More information about the wine-devel mailing list