unixfd: Use DMABuf allocator when needed

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5328>
This commit is contained in:
Xavier Claessens 2023-09-28 13:34:32 -04:00 committed by GStreamer Marge Bot
parent 1f928c6c1a
commit d44aa71f24
3 changed files with 36 additions and 6 deletions

View file

@ -35,6 +35,13 @@ typedef enum
COMMAND_TYPE_EOS = 3,
} CommandType;
typedef enum
{
MEMORY_TYPE_DEFAULT = 0,
MEMORY_TYPE_DMABUF = 1,
MEMORY_TYPE_LAST,
} MemoryType;
typedef struct {
guint64 size;
guint64 offset;
@ -48,9 +55,9 @@ typedef struct {
guint64 offset;
guint64 offset_end;
guint32 flags;
guint8 type;
guint8 n_memory;
guint8 padding8;
guint16 padding16;
guint16 padding;
MemoryPayload memories[];
} NewBufferPayload;

View file

@ -461,8 +461,10 @@ gst_unix_fd_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
new_buffer->offset = GST_BUFFER_OFFSET (buffer);
new_buffer->offset_end = GST_BUFFER_OFFSET_END (buffer);
new_buffer->flags = GST_BUFFER_FLAGS (buffer);
new_buffer->type = MEMORY_TYPE_DEFAULT;
new_buffer->n_memory = n_memory;
gboolean dmabuf_count = 0;
GUnixFDList *fds = g_unix_fd_list_new ();
for (int i = 0; i < n_memory; i++) {
GstMemory *mem = gst_buffer_peek_memory (buffer, i);
@ -472,6 +474,9 @@ gst_unix_fd_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
goto out;
}
if (gst_is_dmabuf_memory (mem))
dmabuf_count++;
if (g_unix_fd_list_append (fds, gst_fd_memory_get_fd (mem), &error) < 0) {
GST_ERROR_OBJECT (self, "Failed to append FD: %s", error->message);
ret = GST_FLOW_ERROR;
@ -483,6 +488,15 @@ gst_unix_fd_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
new_buffer->memories[i].offset = offset;
}
if (dmabuf_count > 0 && dmabuf_count != n_memory) {
GST_ERROR_OBJECT (self, "Some but not all memories are DMABuf");
ret = GST_FLOW_ERROR;
goto out;
}
if (dmabuf_count > 0)
new_buffer->type = MEMORY_TYPE_DMABUF;
GST_OBJECT_LOCK (self);
send_command_to_all (self, COMMAND_TYPE_NEW_BUFFER, fds, payload,
payload_size, buffer);

View file

@ -65,7 +65,7 @@ struct _GstUnixFdSrc
GSocket *socket;
GCancellable *cancellable;
GstAllocator *allocator;
GstAllocator *allocators[MEMORY_TYPE_LAST];
GHashTable *memories;
gboolean uses_monotonic_clock;
};
@ -121,7 +121,8 @@ gst_unix_fd_src_init (GstUnixFdSrc * self)
self->cancellable = g_cancellable_new ();
self->memories = g_hash_table_new (NULL, NULL);
self->allocator = gst_fd_allocator_new ();
self->allocators[0] = gst_fd_allocator_new ();
self->allocators[1] = gst_dmabuf_allocator_new ();
gst_base_src_set_live (GST_BASE_SRC (self), TRUE);
}
@ -133,7 +134,8 @@ gst_unix_fd_src_finalize (GObject * object)
g_free (self->socket_path);
g_object_unref (self->cancellable);
g_hash_table_unref (self->memories);
gst_object_unref (self->allocator);
for (int i = 0; i < MEMORY_TYPE_LAST; i++)
gst_object_unref (self->allocators[i]);
G_OBJECT_CLASS (gst_unix_fd_src_parent_class)->finalize (object);
}
@ -339,6 +341,13 @@ again:
goto on_error;
}
if (new_buffer->type >= MEMORY_TYPE_LAST) {
GST_ERROR_OBJECT (self, "Unknown buffer type %d", new_buffer->type);
ret = GST_FLOW_ERROR;
goto on_error;
}
GstAllocator *allocator = self->allocators[new_buffer->type];
gint *fds_arr = g_unix_fd_list_steal_fds (fds, NULL);
BufferContext *ctx = g_new0 (BufferContext, 1);
@ -366,7 +375,7 @@ again:
GST_OBJECT_LOCK (self);
for (int i = 0; i < new_buffer->n_memory; i++) {
GstMemory *mem = gst_fd_allocator_alloc (self->allocator, fds_arr[i],
GstMemory *mem = gst_fd_allocator_alloc (allocator, fds_arr[i],
new_buffer->memories[i].size, GST_FD_MEMORY_FLAG_NONE);
gst_memory_resize (mem, new_buffer->memories[i].offset,
new_buffer->memories[i].size);