Zebediah Figura : winegstreamer: Use the size of the data read when allocating the read buffer.

Alexandre Julliard julliard at winehq.org
Thu Dec 30 16:11:34 CST 2021


Module: wine
Branch: master
Commit: 4d2a628dfe9e4aad9ba772854717253d0c6a7bb7
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=4d2a628dfe9e4aad9ba772854717253d0c6a7bb7

Author: Zebediah Figura <zfigura at codeweavers.com>
Date:   Wed Dec 29 21:01:52 2021 -0600

winegstreamer: Use the size of the data read when allocating the read buffer.

Instead of the size of the data requested, which may be e.g. UINT_MAX.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52277
Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/winegstreamer/wg_parser.c | 67 ++++++++++++++++++++++++------------------
 1 file changed, 39 insertions(+), 28 deletions(-)

diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c
index 0178538fa81..013566b25e9 100644
--- a/dlls/winegstreamer/wg_parser.c
+++ b/dlls/winegstreamer/wg_parser.c
@@ -80,11 +80,11 @@ struct wg_parser
     pthread_cond_t read_cond, read_done_cond;
     struct
     {
-        void *data;
+        GstBuffer *buffer;
         uint64_t offset;
         uint32_t size;
         bool done;
-        bool ret;
+        GstFlowReturn ret;
     } read_request;
 
     bool flushing, sink_connected;
@@ -556,7 +556,7 @@ static NTSTATUS wg_parser_get_next_read_offset(void *args)
 
     pthread_mutex_lock(&parser->mutex);
 
-    while (parser->sink_connected && !parser->read_request.data)
+    while (parser->sink_connected && !parser->read_request.size)
         pthread_cond_wait(&parser->read_cond, &parser->mutex);
 
     if (!parser->sink_connected)
@@ -580,12 +580,35 @@ static NTSTATUS wg_parser_push_data(void *args)
     uint32_t size = params->size;
 
     pthread_mutex_lock(&parser->mutex);
-    parser->read_request.size = size;
-    parser->read_request.done = true;
-    parser->read_request.ret = !!data;
+
     if (data)
-        memcpy(parser->read_request.data, data, size);
-    parser->read_request.data = NULL;
+    {
+        if (size)
+        {
+            GstMapInfo map_info;
+
+            /* Note that we don't allocate the buffer until we have a size.
+             * midiparse passes a NULL buffer and a size of UINT_MAX, in an
+             * apparent attempt to read the whole input stream at once. */
+            if (!parser->read_request.buffer)
+                parser->read_request.buffer = gst_buffer_new_and_alloc(size);
+            gst_buffer_map(parser->read_request.buffer, &map_info, GST_MAP_WRITE);
+            memcpy(map_info.data, data, size);
+            gst_buffer_unmap(parser->read_request.buffer, &map_info);
+            parser->read_request.ret = GST_FLOW_OK;
+        }
+        else
+        {
+            parser->read_request.ret = GST_FLOW_EOS;
+        }
+    }
+    else
+    {
+        parser->read_request.ret = GST_FLOW_ERROR;
+    }
+    parser->read_request.done = true;
+    parser->read_request.size = 0;
+
     pthread_mutex_unlock(&parser->mutex);
     pthread_cond_signal(&parser->read_done_cond);
 
@@ -1279,9 +1302,7 @@ static GstFlowReturn src_getrange_cb(GstPad *pad, GstObject *parent,
         guint64 offset, guint size, GstBuffer **buffer)
 {
     struct wg_parser *parser = gst_pad_get_element_private(pad);
-    GstBuffer *new_buffer = NULL;
-    GstMapInfo map_info;
-    bool ret;
+    GstFlowReturn ret;
 
     GST_LOG("pad %p, offset %" G_GINT64_MODIFIER "u, size %u, buffer %p.", pad, offset, size, *buffer);
 
@@ -1289,25 +1310,22 @@ static GstFlowReturn src_getrange_cb(GstPad *pad, GstObject *parent,
         offset = parser->next_pull_offset;
     parser->next_pull_offset = offset + size;
 
-    if (!*buffer)
-        *buffer = new_buffer = gst_buffer_new_and_alloc(size);
-
     if (!size)
     {
         /* asfreader occasionally asks for zero bytes. gst_buffer_map() will
          * return NULL in this case. Avoid confusing the read thread by asking
          * it for zero bytes. */
+        if (!*buffer)
+            *buffer = gst_buffer_new_and_alloc(0);
         gst_buffer_set_size(*buffer, 0);
         GST_LOG("Returning empty buffer.");
         return GST_FLOW_OK;
     }
 
-    gst_buffer_map(*buffer, &map_info, GST_MAP_WRITE);
-
     pthread_mutex_lock(&parser->mutex);
 
-    assert(!parser->read_request.data);
-    parser->read_request.data = map_info.data;
+    assert(!parser->read_request.size);
+    parser->read_request.buffer = *buffer;
     parser->read_request.offset = offset;
     parser->read_request.size = size;
     parser->read_request.done = false;
@@ -1320,21 +1338,14 @@ static GstFlowReturn src_getrange_cb(GstPad *pad, GstObject *parent,
     while (!parser->read_request.done)
         pthread_cond_wait(&parser->read_done_cond, &parser->mutex);
 
+    *buffer = parser->read_request.buffer;
     ret = parser->read_request.ret;
-    gst_buffer_set_size(*buffer, parser->read_request.size);
 
     pthread_mutex_unlock(&parser->mutex);
 
-    gst_buffer_unmap(*buffer, &map_info);
-
-    GST_LOG("Request returned %d.", ret);
+    GST_LOG("Request returned %s.", gst_flow_get_name(ret));
 
-    if ((!ret || !size) && new_buffer)
-        gst_buffer_unref(new_buffer);
-
-    if (ret)
-        return size ? GST_FLOW_OK : GST_FLOW_EOS;
-    return GST_FLOW_ERROR;
+    return ret;
 }
 
 static gboolean src_query_cb(GstPad *pad, GstObject *parent, GstQuery *query)




More information about the wine-cvs mailing list