[PATCH 5/5] winegstreamer: Use wg_sample to provide data in wg_parser_reply_read.

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


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

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/winegstreamer/gst_private.h   |  3 ++-
 dlls/winegstreamer/main.c          |  7 +++---
 dlls/winegstreamer/media_source.c  | 25 +++++++++-------------
 dlls/winegstreamer/quartz_parser.c | 26 +++++++++--------------
 dlls/winegstreamer/unixlib.h       |  3 +--
 dlls/winegstreamer/wg_parser.c     | 14 ++++++------
 dlls/winegstreamer/wg_sample.c     | 34 ++++++++++++++++++++++++++++++
 dlls/winegstreamer/wm_reader.c     | 27 ++++++++++--------------
 8 files changed, 78 insertions(+), 61 deletions(-)

diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index 2552e1d7f61..9974090ecf2 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -77,7 +77,7 @@ HRESULT wg_parser_connect(struct wg_parser *parser, uint64_t file_size);
 void wg_parser_disconnect(struct wg_parser *parser);
 
 bool wg_parser_wait_request(struct wg_parser *parser, struct wg_request *request);
-void wg_parser_reply_read(struct wg_parser *parser, const void *data, uint32_t size);
+void wg_parser_reply_read(struct wg_parser *parser, struct wg_sample *sample);
 
 uint32_t wg_parser_get_stream_count(struct wg_parser *parser);
 struct wg_parser_stream *wg_parser_get_stream(struct wg_parser *parser, uint32_t index);
@@ -123,6 +123,7 @@ extern HRESULT mfplat_DllRegisterServer(void);
 IMFMediaType *mf_media_type_from_wg_format(const struct wg_format *format);
 void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format);
 
+HRESULT wg_sample_create_raw(UINT32 size, struct wg_sample **out);
 HRESULT wg_sample_create_mf(IMFSample *sample, struct wg_sample **out);
 HRESULT wg_sample_create_quartz(IMediaSample *sample, struct wg_sample **out);
 void wg_sample_release(struct wg_sample *wg_sample);
diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c
index 25f0c38b700..0beae8f4b31 100644
--- a/dlls/winegstreamer/main.c
+++ b/dlls/winegstreamer/main.c
@@ -122,16 +122,15 @@ bool wg_parser_wait_request(struct wg_parser *parser, struct wg_request *wg_requ
     return true;
 }
 
-void wg_parser_reply_read(struct wg_parser *parser, const void *data, uint32_t size)
+void wg_parser_reply_read(struct wg_parser *parser, struct wg_sample *sample)
 {
     struct wg_parser_reply_read_params params =
     {
         .parser = parser,
-        .data = data,
-        .size = size,
+        .sample = sample,
     };
 
-    TRACE("parser %p, data %p, size %u.\n", parser, data, size);
+    TRACE("parser %p, sample %p.\n", parser, sample);
 
     __wine_unix_call(unix_handle, unix_wg_parser_reply_read, &params);
 }
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
index 5b98c90a8b4..401ad22c06b 100644
--- a/dlls/winegstreamer/media_source.c
+++ b/dlls/winegstreamer/media_source.c
@@ -593,26 +593,25 @@ static const IMFAsyncCallbackVtbl source_async_commands_callback_vtbl =
 };
 
 static void handle_read_request(struct media_source *source, QWORD file_size,
-        void **buffer, size_t *buffer_size, struct wg_request *request)
+        struct wg_request *request)
 {
     IMFByteStream *byte_stream = source->byte_stream;
     uint64_t offset = request->u.read.offset;
     uint32_t size = request->u.read.size;
+    struct wg_sample *wg_sample;
     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))
+    if (FAILED(wg_sample_create_raw(size, &wg_sample)))
     {
-        wg_parser_reply_read(source->wg_parser, NULL, 0);
+        wg_parser_reply_read(source->wg_parser, NULL);
         return;
     }
-    data = *buffer;
 
     /* Some IMFByteStreams (including the standard file-based stream) return
      * an error when reading past the file size. */
@@ -620,12 +619,12 @@ static void handle_read_request(struct media_source *source, QWORD 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);
+        hr = IMFByteStream_Read(byte_stream, wg_sample->data, size, &ret_size);
 
     if (FAILED(hr))
     {
         ERR("Failed to read %u bytes at offset %I64u, hr %#lx.\n", size, offset, hr);
-        data = NULL;
+        wg_sample->data = NULL;
     }
     else if (ret_size != size)
     {
@@ -633,19 +632,16 @@ static void handle_read_request(struct media_source *source, QWORD file_size,
         size = ret_size;
     }
 
-    wg_parser_reply_read(source->wg_parser, data, size);
+    wg_sample->size = size;
+    wg_parser_reply_read(source->wg_parser, wg_sample);
+    wg_sample_release(wg_sample);
 }
 
 static DWORD CALLBACK read_thread(void *arg)
 {
     struct media_source *source = arg;
     IMFByteStream *byte_stream = source->byte_stream;
-    size_t buffer_size = 4096;
     QWORD file_size;
-    void *data;
-
-    if (!(data = malloc(buffer_size)))
-        return 0;
 
     IMFByteStream_GetLength(byte_stream, &file_size);
 
@@ -661,7 +657,7 @@ static DWORD CALLBACK read_thread(void *arg)
         switch (request.type)
         {
             case WG_REQUEST_READ:
-                handle_read_request(source, file_size, &data, &buffer_size, &request);
+                handle_read_request(source, file_size, &request);
                 break;
 
             default:
@@ -670,7 +666,6 @@ static DWORD CALLBACK read_thread(void *arg)
         }
     }
 
-    free(data);
     TRACE("Media source is shutting down; exiting.\n");
     return 0;
 }
diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c
index edf7ed6454b..dc2be99d5e3 100644
--- a/dlls/winegstreamer/quartz_parser.c
+++ b/dlls/winegstreamer/quartz_parser.c
@@ -866,45 +866,40 @@ static DWORD CALLBACK stream_thread(void *arg)
 }
 
 static void handle_read_request(struct parser *filter, LONGLONG file_size,
-        void **buffer, size_t *buffer_size, struct wg_request *request)
+        struct wg_request *request)
 {
     uint64_t offset = request->u.read.offset;
     uint32_t size = request->u.read.size;
+    struct wg_sample *wg_sample;
     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))
+    if (FAILED(wg_sample_create_raw(size, &wg_sample)))
     {
-        wg_parser_reply_read(filter->wg_parser, NULL, 0);
+        wg_parser_reply_read(filter->wg_parser, NULL);
         return;
     }
-    data = *buffer;
-
-    hr = IAsyncReader_SyncRead(filter->reader, offset, size, data);
 
+    hr = IAsyncReader_SyncRead(filter->reader, offset, size, wg_sample->data);
     if (FAILED(hr))
     {
         ERR("Failed to read %u bytes at offset %I64u, hr %#lx.\n", size, offset, hr);
-        data = NULL;
+        wg_sample->data = NULL;
     }
 
-    wg_parser_reply_read(filter->wg_parser, data, size);
+    wg_sample->size = size;
+    wg_parser_reply_read(filter->wg_parser, wg_sample);
+    wg_sample_release(wg_sample);
 }
 
 static DWORD CALLBACK read_thread(void *arg)
 {
     struct parser *filter = arg;
     LONGLONG file_size, unused;
-    size_t buffer_size = 4096;
-    void *data;
-
-    if (!(data = malloc(buffer_size)))
-        return 0;
 
     IAsyncReader_Length(filter->reader, &file_size, &unused);
 
@@ -920,7 +915,7 @@ static DWORD CALLBACK read_thread(void *arg)
         switch (request.type)
         {
             case WG_REQUEST_READ:
-                handle_read_request(filter, file_size, &data, &buffer_size, &request);
+                handle_read_request(filter, file_size, &request);
                 break;
 
             default:
@@ -929,7 +924,6 @@ static DWORD CALLBACK read_thread(void *arg)
         }
     }
 
-    free(data);
     TRACE("Streaming stopped; exiting.\n");
     return 0;
 }
diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h
index f767daed513..a621ea9d4bf 100644
--- a/dlls/winegstreamer/unixlib.h
+++ b/dlls/winegstreamer/unixlib.h
@@ -192,8 +192,7 @@ struct wg_parser_wait_request_params
 struct wg_parser_reply_read_params
 {
     struct wg_parser *parser;
-    const void *data;
-    UINT32 size;
+    struct wg_sample *sample;
 };
 
 struct wg_parser_get_stream_count_params
diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c
index 56525da1348..ee3ed1807d2 100644
--- a/dlls/winegstreamer/wg_parser.c
+++ b/dlls/winegstreamer/wg_parser.c
@@ -154,21 +154,20 @@ static NTSTATUS wg_parser_reply_read(void *args)
 {
     const struct wg_parser_reply_read_params *params = args;
     struct wg_parser *parser = params->parser;
-    const void *data = params->data;
-    uint32_t size = params->size;
+    struct wg_sample *sample = params->sample;
     GstBuffer *buffer = NULL;
     GstFlowReturn result;
 
-    if (!data)
+    if (!sample || !sample->data)
         result = GST_FLOW_ERROR;
-    else if (!size)
+    else if (!sample->size)
         result = GST_FLOW_EOS;
-    else if (!(buffer = gst_buffer_new_and_alloc(size)))
+    else if (!(buffer = gst_buffer_new_and_alloc(sample->size)))
         result = GST_FLOW_ERROR;
     else
     {
-        gst_buffer_fill(buffer, 0, data, size);
-        GST_INFO("Copied %u bytes from data %p to buffer %p", size, data, buffer);
+        gst_buffer_fill(buffer, 0, sample->data, sample->size);
+        GST_INFO("Copied %u bytes from sample %p to buffer %p", sample->size, sample, buffer);
         result = GST_FLOW_OK;
     }
 
@@ -901,6 +900,7 @@ static GstFlowReturn src_getrange_cb(GstPad *pad, GstObject *parent,
         pthread_cond_wait(&parser->read_done_cond, &parser->mutex);
 
     *buffer = parser->read_request.buffer;
+    parser->read_request.buffer = NULL;
     ret = parser->read_request.ret;
 
     pthread_mutex_unlock(&parser->mutex);
diff --git a/dlls/winegstreamer/wg_sample.c b/dlls/winegstreamer/wg_sample.c
index ae8a2d4d0c7..eb46982fabf 100644
--- a/dlls/winegstreamer/wg_sample.c
+++ b/dlls/winegstreamer/wg_sample.c
@@ -47,6 +47,11 @@ struct sample
 
     union
     {
+        struct
+        {
+            void *__pad[3];
+            BYTE buffer[];
+        } raw;
         struct
         {
             IMFSample *sample;
@@ -59,6 +64,35 @@ struct sample
     } u;
 };
 
+C_ASSERT(sizeof(struct sample) == offsetof(struct sample, u.raw.buffer[0]));
+
+static void raw_sample_destroy(struct wg_sample *wg_sample)
+{
+    TRACE("wg_sample %p\n", wg_sample);
+}
+
+static const struct wg_sample_ops raw_sample_ops =
+{
+    raw_sample_destroy,
+};
+
+HRESULT wg_sample_create_raw(UINT32 size, struct wg_sample **out)
+{
+    struct sample *sample;
+
+    if (!(sample = calloc(1, offsetof(struct sample, u.raw.buffer[size]))))
+        return E_OUTOFMEMORY;
+
+    sample->wg_sample.data = sample->u.raw.buffer;
+    sample->wg_sample.size = 0;
+    sample->wg_sample.max_size = size;
+    sample->ops = &raw_sample_ops;
+
+    TRACE("Created wg_sample %p, size %u.\n", &sample->wg_sample, size);
+    *out = &sample->wg_sample;
+    return S_OK;
+}
+
 static const struct wg_sample_ops mf_sample_ops;
 
 static inline struct sample *unsafe_mf_from_wg_sample(struct wg_sample *wg_sample)
diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c
index 9de7ab6edf3..a2851f8df31 100644
--- a/dlls/winegstreamer/wm_reader.c
+++ b/dlls/winegstreamer/wm_reader.c
@@ -527,28 +527,27 @@ static const IWMMediaPropsVtbl stream_props_vtbl =
 };
 
 static void handle_read_request(struct wm_reader *reader, uint64_t file_size,
-        void **buffer, size_t *buffer_size, struct wg_request *request)
+        struct wg_request *request)
 {
     uint64_t offset = request->u.read.offset;
     IStream *stream = reader->source_stream;
     uint32_t size = request->u.read.size;
+    struct wg_sample *wg_sample;
     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))
+    if (FAILED(wg_sample_create_raw(size, &wg_sample)))
     {
-        wg_parser_reply_read(reader->wg_parser, NULL, 0);
+        wg_parser_reply_read(reader->wg_parser, NULL);
         return;
     }
-    data = *buffer;
 
     large_offset.QuadPart = offset;
     if (!size)
@@ -556,7 +555,7 @@ static void handle_read_request(struct wm_reader *reader, uint64_t file_size,
     else if (file)
     {
         if (!SetFilePointerEx(file, large_offset, NULL, FILE_BEGIN)
-                || !ReadFile(file, data, size, &ret_size, NULL))
+                || !ReadFile(file, wg_sample->data, size, &ret_size, NULL))
             hr = HRESULT_FROM_WIN32(GetLastError());
         else
             hr = S_OK;
@@ -564,13 +563,13 @@ static void handle_read_request(struct wm_reader *reader, uint64_t file_size,
     else
     {
         if (SUCCEEDED(hr = IStream_Seek(stream, large_offset, STREAM_SEEK_SET, NULL)))
-            hr = IStream_Read(stream, data, size, &ret_size);
+            hr = IStream_Read(stream, wg_sample->data, size, &ret_size);
     }
 
     if (FAILED(hr))
     {
         ERR("Failed to read %u bytes at offset %I64u, hr %#lx.\n", size, offset, hr);
-        data = NULL;
+        wg_sample->data = NULL;
     }
     else if (ret_size != size)
     {
@@ -578,7 +577,9 @@ static void handle_read_request(struct wm_reader *reader, uint64_t file_size,
         size = ret_size;
     }
 
-    wg_parser_reply_read(reader->wg_parser, data, size);
+    wg_sample->size = size;
+    wg_parser_reply_read(reader->wg_parser, wg_sample);
+    wg_sample_release(wg_sample);
 }
 
 static DWORD CALLBACK read_thread(void *arg)
@@ -586,12 +587,7 @@ static DWORD CALLBACK read_thread(void *arg)
     struct wm_reader *reader = arg;
     IStream *stream = reader->source_stream;
     HANDLE file = reader->file;
-    size_t buffer_size = 4096;
     uint64_t file_size;
-    void *data;
-
-    if (!(data = malloc(buffer_size)))
-        return 0;
 
     if (file)
     {
@@ -620,7 +616,7 @@ static DWORD CALLBACK read_thread(void *arg)
         switch (request.type)
         {
             case WG_REQUEST_READ:
-                handle_read_request(reader, file_size, &data, &buffer_size, &request);
+                handle_read_request(reader, file_size, &request);
                 break;
 
             default:
@@ -629,7 +625,6 @@ static DWORD CALLBACK read_thread(void *arg)
         }
     }
 
-    free(data);
     TRACE("Reader is shutting down; exiting.\n");
     return 0;
 }
-- 
GitLab

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



More information about the wine-devel mailing list