[PATCH v5 3/5] winegstreamer: Introduce a new wg_allocator_set_next_sample helper.
Rémi Bernon
wine at gitlab.winehq.org
Thu Jun 30 07:33:43 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 | 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
More information about the wine-devel
mailing list