[PATCH v4 3/5] winegstreamer: Introduce a new wg_allocator_set_next_sample helper.

Rémi Bernon wine at gitlab.winehq.org
Thu Jun 30 03:04:28 CDT 2022


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

Using the allocator lock and replacing the transform_request_sample
callback with a default wg_allocator callback.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/winegstreamer/unix_private.h |  2 ++
 dlls/winegstreamer/wg_allocator.c | 42 +++++++++++++++++++++++++++++--
 dlls/winegstreamer/wg_transform.c | 22 +++-------------
 3 files changed, 45 insertions(+), 21 deletions(-)

diff --git a/dlls/winegstreamer/unix_private.h b/dlls/winegstreamer/unix_private.h
index e9f472986ae..2bfdc6f9f5b 100644
--- a/dlls/winegstreamer/unix_private.h
+++ b/dlls/winegstreamer/unix_private.h
@@ -44,5 +44,7 @@ extern GstAllocator *wg_allocator_create(wg_allocator_request_sample_cb request_
 extern void wg_allocator_destroy(GstAllocator *allocator) DECLSPEC_HIDDEN;
 extern void wg_allocator_release_sample(GstAllocator *allocator, struct wg_sample *sample,
         bool discard_data) DECLSPEC_HIDDEN;
+extern void wg_allocator_set_next_sample(GstAllocator *allocator,
+        struct wg_sample *sample) DECLSPEC_HIDDEN;
 
 #endif /* __WINE_WINEGSTREAMER_UNIX_PRIVATE_H */
diff --git a/dlls/winegstreamer/wg_allocator.c b/dlls/winegstreamer/wg_allocator.c
index 16e961a57d4..53ea5d08c8e 100644
--- a/dlls/winegstreamer/wg_allocator.c
+++ b/dlls/winegstreamer/wg_allocator.c
@@ -54,6 +54,7 @@ typedef struct
 {
     GstAllocator parent;
 
+    struct wg_sample *next_sample;
     wg_allocator_request_sample_cb request_sample;
     void *request_sample_context;
 
@@ -68,6 +69,23 @@ typedef struct
 
 G_DEFINE_TYPE(WgAllocator, wg_allocator, GST_TYPE_ALLOCATOR);
 
+static struct wg_sample *default_request_sample(gsize size, void *context)
+{
+    WgAllocator *allocator = context;
+    struct wg_sample *sample;
+
+    GST_LOG("size %#zx, context %p", size, context);
+
+    if (!(sample = allocator->next_sample))
+        return NULL;
+    allocator->next_sample = NULL;
+
+    if (sample->max_size < size)
+        return NULL;
+
+    return sample;
+}
+
 static gpointer wg_allocator_map(GstMemory *gst_memory, GstMapInfo *info, gsize maxsize)
 {
     WgAllocator *allocator = (WgAllocator *)gst_memory->allocator;
@@ -210,8 +228,14 @@ GstAllocator *wg_allocator_create(wg_allocator_request_sample_cb request_sample,
     if (!(allocator = g_object_new(wg_allocator_get_type(), NULL)))
         return NULL;
 
-    allocator->request_sample = request_sample;
-    allocator->request_sample_context = request_sample_context;
+    if ((allocator->request_sample = request_sample))
+        allocator->request_sample_context = request_sample_context;
+    else
+    {
+        allocator->request_sample = default_request_sample;
+        allocator->request_sample_context = allocator;
+    }
+
     return GST_ALLOCATOR(allocator);
 }
 
@@ -282,3 +306,17 @@ void wg_allocator_release_sample(GstAllocator *gst_allocator, struct wg_sample *
         GST_ERROR("Couldn't find memory for sample %p", sample);
     GST_OBJECT_UNLOCK(allocator);
 }
+
+void wg_allocator_set_next_sample(GstAllocator *gst_allocator, struct wg_sample *sample)
+{
+    WgAllocator *allocator = (WgAllocator *)gst_allocator;
+
+    GST_LOG("allocator %p, sample %p", allocator, sample);
+
+    GST_OBJECT_LOCK(allocator);
+    if (allocator->next_sample)
+        InterlockedDecrement(&allocator->next_sample->refcount);
+    if ((allocator->next_sample = sample))
+        InterlockedIncrement(&allocator->next_sample->refcount);
+    GST_OBJECT_UNLOCK(allocator);
+}
diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c
index e05432f6ac7..73c3c6d42b0 100644
--- a/dlls/winegstreamer/wg_transform.c
+++ b/dlls/winegstreamer/wg_transform.c
@@ -307,20 +307,6 @@ static bool transform_append_element(struct wg_transform *transform, GstElement
     return success;
 }
 
-static struct wg_sample *transform_request_sample(gsize size, void *context)
-{
-    struct wg_transform *transform = context;
-    struct wg_sample *sample;
-
-    GST_LOG("size %#zx, context %p", size, transform);
-
-    sample = InterlockedExchangePointer((void **)&transform->output_wg_sample, NULL);
-    if (!sample || sample->max_size < size)
-        return NULL;
-
-    return sample;
-}
-
 NTSTATUS wg_transform_create(void *args)
 {
     struct wg_transform_create_params *params = args;
@@ -345,7 +331,7 @@ NTSTATUS wg_transform_create(void *args)
         goto out;
     if (!(transform->output_queue = gst_atomic_queue_new(8)))
         goto out;
-    if (!(transform->allocator = wg_allocator_create(transform_request_sample, transform)))
+    if (!(transform->allocator = wg_allocator_create(NULL, NULL)))
         goto out;
     transform->input_max_length = 1;
     transform->output_plane_align = 0;
@@ -724,8 +710,7 @@ NTSTATUS wg_transform_read_data(void *args)
     NTSTATUS status;
 
     /* Provide the sample for transform_request_sample to pick it up */
-    InterlockedIncrement(&sample->refcount);
-    InterlockedExchangePointer((void **)&transform->output_wg_sample, sample);
+    wg_allocator_set_next_sample(transform->allocator, sample);
 
     if (!gst_buffer_list_length(transform->input))
         GST_DEBUG("Not input buffer queued");
@@ -741,8 +726,7 @@ NTSTATUS wg_transform_read_data(void *args)
     }
 
     /* Remove the sample so transform_request_sample cannot use it */
-    if (InterlockedExchangePointer((void **)&transform->output_wg_sample, NULL))
-        InterlockedDecrement(&sample->refcount);
+    wg_allocator_set_next_sample(transform->allocator, NULL);
 
     if (ret)
     {
-- 
GitLab


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



More information about the wine-devel mailing list