diff --git a/subprojects/gst-plugins-bad/gst/unixfd/gstunixfd.h b/subprojects/gst-plugins-bad/gst/unixfd/gstunixfd.h index 0eab2b46f7..6a675fc5bd 100644 --- a/subprojects/gst-plugins-bad/gst/unixfd/gstunixfd.h +++ b/subprojects/gst-plugins-bad/gst/unixfd/gstunixfd.h @@ -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; diff --git a/subprojects/gst-plugins-bad/gst/unixfd/gstunixfdsink.c b/subprojects/gst-plugins-bad/gst/unixfd/gstunixfdsink.c index b35d1c1314..e7dd1b6b45 100644 --- a/subprojects/gst-plugins-bad/gst/unixfd/gstunixfdsink.c +++ b/subprojects/gst-plugins-bad/gst/unixfd/gstunixfdsink.c @@ -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); diff --git a/subprojects/gst-plugins-bad/gst/unixfd/gstunixfdsrc.c b/subprojects/gst-plugins-bad/gst/unixfd/gstunixfdsrc.c index 7d41cdf0ff..766d716ed9 100644 --- a/subprojects/gst-plugins-bad/gst/unixfd/gstunixfdsrc.c +++ b/subprojects/gst-plugins-bad/gst/unixfd/gstunixfdsrc.c @@ -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);