[PATCH 3/5] winegstreamer: Split read threads into a handle_read_request helper.

Rémi Bernon wine at gitlab.winehq.org
Tue Jun 14 02:27:01 CDT 2022


From: Rémi Bernon <rbernon at codeweavers.com>

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/winegstreamer/media_source.c  |  75 ++++++++++++---------
 dlls/winegstreamer/quartz_parser.c |  49 +++++++++-----
 dlls/winegstreamer/wm_reader.c     | 102 +++++++++++++++--------------
 3 files changed, 129 insertions(+), 97 deletions(-)

diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
index f07b83f413e..ac23b1bc94c 100644
--- a/dlls/winegstreamer/media_source.c
+++ b/dlls/winegstreamer/media_source.c
@@ -592,12 +592,54 @@ static const IMFAsyncCallbackVtbl source_async_commands_callback_vtbl =
     source_async_commands_Invoke,
 };
 
+static void handle_read_request(struct media_source *source, QWORD file_size,
+        void **buffer, size_t *buffer_size, uint64_t offset, uint32_t size)
+{
+    IMFByteStream *byte_stream = source->byte_stream;
+    ULONG ret_size = 0;
+    HRESULT hr;
+    void *data;
+
+    if (offset >= file_size)
+        size = 0;
+    else if (offset + size >= file_size)
+        size = file_size - offset;
+
+    if (!array_reserve(buffer, buffer_size, size, 1))
+    {
+        wg_parser_push_data(source->wg_parser, NULL, 0);
+        return;
+    }
+    data = *buffer;
+
+    /* Some IMFByteStreams (including the standard file-based stream) return
+     * an error when reading past the file size. */
+
+    if (!size)
+        hr = S_OK;
+    else if (SUCCEEDED(hr = IMFByteStream_SetCurrentPosition(byte_stream, offset)))
+        hr = IMFByteStream_Read(byte_stream, data, size, &ret_size);
+
+    if (FAILED(hr))
+    {
+        ERR("Failed to read %u bytes at offset %I64u, hr %#lx.\n", size, offset, hr);
+        data = NULL;
+    }
+    else if (ret_size != size)
+    {
+        ERR("Unexpected short read: requested %u bytes, got %lu.\n", size, ret_size);
+        size = ret_size;
+    }
+
+    wg_parser_push_data(source->wg_parser, data, size);
+}
+
 static DWORD CALLBACK read_thread(void *arg)
 {
     struct media_source *source = arg;
     IMFByteStream *byte_stream = source->byte_stream;
     size_t buffer_size = 4096;
-    uint64_t file_size;
+    QWORD file_size;
     void *data;
 
     if (!(data = malloc(buffer_size)))
@@ -610,41 +652,12 @@ static DWORD CALLBACK read_thread(void *arg)
     while (!source->read_thread_shutdown)
     {
         uint64_t offset;
-        ULONG ret_size;
         uint32_t size;
-        HRESULT hr;
 
         if (!wg_parser_get_next_read_offset(source->wg_parser, &offset, &size))
             continue;
 
-        if (offset >= file_size)
-            size = 0;
-        else if (offset + size >= file_size)
-            size = file_size - offset;
-
-        /* Some IMFByteStreams (including the standard file-based stream) return
-         * an error when reading past the file size. */
-        if (!size)
-        {
-            wg_parser_push_data(source->wg_parser, data, 0);
-            continue;
-        }
-
-        if (!array_reserve(&data, &buffer_size, size, 1))
-        {
-            free(data);
-            return 0;
-        }
-
-        ret_size = 0;
-
-        if (SUCCEEDED(hr = IMFByteStream_SetCurrentPosition(byte_stream, offset)))
-            hr = IMFByteStream_Read(byte_stream, data, size, &ret_size);
-        if (FAILED(hr))
-            ERR("Failed to read %u bytes at offset %I64u, hr %#lx.\n", size, offset, hr);
-        else if (ret_size != size)
-            ERR("Unexpected short read: requested %u bytes, got %lu.\n", size, ret_size);
-        wg_parser_push_data(source->wg_parser, SUCCEEDED(hr) ? data : NULL, ret_size);
+        handle_read_request(source, file_size, &data, &buffer_size, offset, size);
     }
 
     free(data);
diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c
index 34848c0b503..0e9f183d499 100644
--- a/dlls/winegstreamer/quartz_parser.c
+++ b/dlls/winegstreamer/quartz_parser.c
@@ -865,12 +865,41 @@ static DWORD CALLBACK stream_thread(void *arg)
     return 0;
 }
 
+static void handle_read_request(struct parser *filter, LONGLONG file_size,
+        void **buffer, size_t *buffer_size, uint64_t offset, uint32_t size)
+{
+    HRESULT hr;
+    void *data;
+
+    if (offset >= file_size)
+        size = 0;
+    else if (offset + size >= file_size)
+        size = file_size - offset;
+
+    if (!array_reserve(buffer, buffer_size, size, 1))
+    {
+        wg_parser_push_data(filter->wg_parser, NULL, 0);
+        return;
+    }
+    data = *buffer;
+
+    hr = IAsyncReader_SyncRead(filter->reader, offset, size, data);
+
+    if (FAILED(hr))
+    {
+        ERR("Failed to read %u bytes at offset %I64u, hr %#lx.\n", size, offset, hr);
+        data = NULL;
+    }
+
+    wg_parser_push_data(filter->wg_parser, data, size);
+}
+
 static DWORD CALLBACK read_thread(void *arg)
 {
     struct parser *filter = arg;
     LONGLONG file_size, unused;
     size_t buffer_size = 4096;
-    void *data = NULL;
+    void *data;
 
     if (!(data = malloc(buffer_size)))
         return 0;
@@ -883,27 +912,11 @@ static DWORD CALLBACK read_thread(void *arg)
     {
         uint64_t offset;
         uint32_t size;
-        HRESULT hr;
 
         if (!wg_parser_get_next_read_offset(filter->wg_parser, &offset, &size))
             continue;
 
-        if (offset >= file_size)
-            size = 0;
-        else if (offset + size >= file_size)
-            size = file_size - offset;
-
-        if (!array_reserve(&data, &buffer_size, size, 1))
-        {
-            free(data);
-            return 0;
-        }
-
-        hr = IAsyncReader_SyncRead(filter->reader, offset, size, data);
-        if (FAILED(hr))
-            ERR("Failed to read %u bytes at offset %I64u, hr %#lx.\n", size, offset, hr);
-
-        wg_parser_push_data(filter->wg_parser, SUCCEEDED(hr) ? data : NULL, size);
+        handle_read_request(filter, file_size, &data, &buffer_size, offset, size);
     }
 
     free(data);
diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c
index 03adea8a318..9d1eb2a95ed 100644
--- a/dlls/winegstreamer/wm_reader.c
+++ b/dlls/winegstreamer/wm_reader.c
@@ -526,6 +526,59 @@ static const IWMMediaPropsVtbl stream_props_vtbl =
     stream_props_SetMediaType,
 };
 
+static void handle_read_request(struct wm_reader *reader, uint64_t file_size,
+        void **buffer, size_t *buffer_size, uint64_t offset, uint32_t size)
+{
+    IStream *stream = reader->source_stream;
+    LARGE_INTEGER large_offset;
+    HANDLE file = reader->file;
+    ULONG ret_size = 0;
+    HRESULT hr;
+    void *data;
+
+    if (offset >= file_size)
+        size = 0;
+    else if (offset + size >= file_size)
+        size = file_size - offset;
+
+    if (!array_reserve(buffer, buffer_size, size, 1))
+    {
+        wg_parser_push_data(reader->wg_parser, NULL, 0);
+        return;
+    }
+    data = *buffer;
+
+    large_offset.QuadPart = offset;
+    if (!size)
+        hr = S_OK;
+    else if (file)
+    {
+        if (!SetFilePointerEx(file, large_offset, NULL, FILE_BEGIN)
+                || !ReadFile(file, data, size, &ret_size, NULL))
+            hr = HRESULT_FROM_WIN32(GetLastError());
+        else
+            hr = S_OK;
+    }
+    else
+    {
+        if (SUCCEEDED(hr = IStream_Seek(stream, large_offset, STREAM_SEEK_SET, NULL)))
+            hr = IStream_Read(stream, data, size, &ret_size);
+    }
+
+    if (FAILED(hr))
+    {
+        ERR("Failed to read %u bytes at offset %I64u, hr %#lx.\n", size, offset, hr);
+        data = NULL;
+    }
+    else if (ret_size != size)
+    {
+        ERR("Unexpected short read: requested %u bytes, got %lu.\n", size, ret_size);
+        size = ret_size;
+    }
+
+    wg_parser_push_data(reader->wg_parser, data, size);
+}
+
 static DWORD CALLBACK read_thread(void *arg)
 {
     struct wm_reader *reader = arg;
@@ -557,60 +610,13 @@ static DWORD CALLBACK read_thread(void *arg)
 
     while (!reader->read_thread_shutdown)
     {
-        LARGE_INTEGER large_offset;
         uint64_t offset;
-        ULONG ret_size;
         uint32_t size;
-        HRESULT hr;
 
         if (!wg_parser_get_next_read_offset(reader->wg_parser, &offset, &size))
             continue;
 
-        if (offset >= file_size)
-            size = 0;
-        else if (offset + size >= file_size)
-            size = file_size - offset;
-
-        if (!size)
-        {
-            wg_parser_push_data(reader->wg_parser, data, 0);
-            continue;
-        }
-
-        if (!array_reserve(&data, &buffer_size, size, 1))
-        {
-            free(data);
-            return 0;
-        }
-
-        ret_size = 0;
-
-        large_offset.QuadPart = offset;
-        if (file)
-        {
-            if (!SetFilePointerEx(file, large_offset, NULL, FILE_BEGIN)
-                    || !ReadFile(file, data, size, &ret_size, NULL))
-            {
-                ERR("Failed to read %u bytes at offset %I64u, error %lu.\n", size, offset, GetLastError());
-                wg_parser_push_data(reader->wg_parser, NULL, 0);
-                continue;
-            }
-        }
-        else
-        {
-            if (SUCCEEDED(hr = IStream_Seek(stream, large_offset, STREAM_SEEK_SET, NULL)))
-                hr = IStream_Read(stream, data, size, &ret_size);
-            if (FAILED(hr))
-            {
-                ERR("Failed to read %u bytes at offset %I64u, hr %#lx.\n", size, offset, hr);
-                wg_parser_push_data(reader->wg_parser, NULL, 0);
-                continue;
-            }
-        }
-
-        if (ret_size != size)
-            ERR("Unexpected short read: requested %u bytes, got %lu.\n", size, ret_size);
-        wg_parser_push_data(reader->wg_parser, data, ret_size);
+        handle_read_request(reader, file_size, &data, &buffer_size, offset, size);
     }
 
     free(data);
-- 
GitLab


https://gitlab.winehq.org/wine/wine/-/merge_requests/242



More information about the wine-devel mailing list