From: "Rémi Bernon" Subject: [PATCH v5 3/5] winegstreamer: Introduce a new wg_allocator_set_next_sample helper. Message-Id: Date: Thu, 30 Jun 2022 12:33:43 +0000 In-Reply-To: References: From: Rémi Bernon Using the allocator lock and replacing the transform_request_sample callback with a default wg_allocator callback. Signed-off-by: Rémi Bernon --- dlls/winegstreamer/unix_private.h | 2 ++ dlls/winegstreamer/wg_allocator.c | 42 +++++++++++++++++++++++++++++-- dlls/winegstreamer/wg_transform.c | 24 +++--------------- 3 files changed, 46 insertions(+), 22 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..557e085ea31 100644 --- a/dlls/winegstreamer/wg_transform.c +++ b/dlls/winegstreamer/wg_transform.c @@ -53,8 +53,8 @@ struct wg_transform GstSegment segment; GstBufferList *input; guint input_max_length; + guint output_plane_align; - struct wg_sample *output_wg_sample; GstAtomicQueue *output_queue; GstSample *output_sample; bool output_caps_changed; @@ -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