diff --git a/pinos/Makefile.am b/pinos/Makefile.am
index b1f1200e2..6c9eca56f 100644
--- a/pinos/Makefile.am
+++ b/pinos/Makefile.am
@@ -208,6 +208,7 @@ libpinoscore_@PINOS_MAJORMINOR@_la_SOURCES = \
server/channel.c server/channel.h \
server/client.c server/client.h \
server/daemon.c server/daemon.h \
+ server/link.c server/link.h \
server/node.c server/node.h \
server/port.c server/port.h \
server/node-factory.c server/node-factory.h \
diff --git a/pinos/client/buffer.c b/pinos/client/buffer.c
index 63f54f79d..ec7f088f8 100644
--- a/pinos/client/buffer.c
+++ b/pinos/client/buffer.c
@@ -459,8 +459,8 @@ pinos_buffer_builder_init_full (PinosBufferBuilder *builder,
sb->buf.max_size = sizeof (PinosStackHeader) + 128;
sb->buf.data = g_malloc (sb->buf.max_size);
sb->buf.free_data = sb->buf.data;
-// g_warning ("builder %p: realloc buffer memory %"G_GSIZE_FORMAT" -> %"G_GSIZE_FORMAT,
-// builder, max_data, sb->buf.max_size);
+ g_warning ("builder %p: realloc buffer memory %"G_GSIZE_FORMAT" -> %"G_GSIZE_FORMAT,
+ builder, max_data, sb->buf.max_size);
} else {
sb->buf.max_size = max_data;
sb->buf.data = data;
@@ -581,8 +581,8 @@ pinos_buffer_builder_add_fd (PinosBufferBuilder *builder,
if (sb->buf.n_fds >= sb->buf.max_fds) {
gint new_size = sb->buf.max_fds + 8;
-// g_warning ("builder %p: realloc buffer fds %d -> %d",
-// builder, sb->buf.max_fds, new_size);
+ g_warning ("builder %p: realloc buffer fds %d -> %d",
+ builder, sb->buf.max_fds, new_size);
sb->buf.max_fds = new_size;
sb->buf.free_fds = g_realloc (sb->buf.free_fds, new_size * sizeof (int));
sb->buf.fds = sb->buf.free_fds;
@@ -599,8 +599,8 @@ builder_ensure_size (struct stack_builder *sb, gsize size)
{
if (sb->buf.size + size > sb->buf.max_size) {
gsize new_size = sb->buf.size + MAX (size, 1024);
-// g_warning ("builder %p: realloc buffer memory %"G_GSIZE_FORMAT" -> %"G_GSIZE_FORMAT,
-// sb, sb->buf.max_size, new_size);
+ g_warning ("builder %p: realloc buffer memory %"G_GSIZE_FORMAT" -> %"G_GSIZE_FORMAT,
+ sb, sb->buf.max_size, new_size);
sb->buf.max_size = new_size;
sb->buf.free_data = g_realloc (sb->buf.free_data, new_size);
sb->sh = sb->buf.data = sb->buf.free_data;
@@ -634,20 +634,144 @@ builder_add_packet (struct stack_builder *sb, PinosPacketType type, gsize size)
return p;
}
+/**
+ * pinos_buffer_builder_add_empty:
+ * @builder: a #PinosBufferBuilder
+ * @type: a #PinosPacketType
+ *
+ * Add an empty packet of @type.
+ *
+ * Returns: %TRUE on success.
+ */
+gboolean
+pinos_buffer_builder_add_empty (PinosBufferBuilder *builder,
+ PinosPacketType type)
+{
+ struct stack_builder *sb = PPSB (builder);
+
+ g_return_val_if_fail (is_valid_builder (builder), FALSE);
+
+ builder_add_packet (sb, type, 0);
+
+ return TRUE;
+}
+
+/**
+ * pinos_buffer_iter_parse_add_mem:
+ * @iter: a #PinosBufferIter
+ * @payload: a #PinosPacketAddMem
+ *
+ * Get the #PinosPacketAddMem. @iter must be positioned on a packet of
+ * type #PINOS_PACKET_TYPE_ADD_MEM
+ *
+ * Returns: %TRUE if @payload contains valid data.
+ */
+gboolean
+pinos_buffer_iter_parse_add_mem (PinosBufferIter *iter,
+ PinosPacketAddMem *payload)
+{
+ struct stack_iter *si = PPSI (iter);
+
+ g_return_val_if_fail (is_valid_iter (iter), FALSE);
+ g_return_val_if_fail (si->type == PINOS_PACKET_TYPE_ADD_MEM, FALSE);
+
+ if (si->size < sizeof (PinosPacketAddMem))
+ return FALSE;
+
+ memcpy (payload, si->data, sizeof (*payload));
+
+ return TRUE;
+}
+
+/**
+ * pinos_buffer_builder_add_add_mem:
+ * @builder: a #PinosBufferBuilder
+ * @payload: a #PinosPacketAddMem
+ *
+ * Add a #PINOS_PACKET_TYPE_ADD_MEM to @builder with data from @payload.
+ *
+ * Returns: %TRUE on success.
+ */
+gboolean
+pinos_buffer_builder_add_add_mem (PinosBufferBuilder *builder,
+ PinosPacketAddMem *payload)
+{
+ struct stack_builder *sb = PPSB (builder);
+ PinosPacketAddMem *p;
+
+ g_return_val_if_fail (is_valid_builder (builder), FALSE);
+
+ p = builder_add_packet (sb, PINOS_PACKET_TYPE_ADD_MEM, sizeof (PinosPacketAddMem));
+ memcpy (p, payload, sizeof (*payload));
+
+ return TRUE;
+}
+
+/**
+ * pinos_buffer_iter_parse_remove_mem:
+ * @iter: a #PinosBufferIter
+ * @payload: a #PinosPacketRemoveMem
+ *
+ * Get the #PinosPacketRemoveMem. @iter must be positioned on a packet of
+ * type #PINOS_PACKET_TYPE_REMOVE_MEM
+ *
+ * Returns: %TRUE if @payload contains valid data.
+ */
+gboolean
+pinos_buffer_iter_parse_remove_mem (PinosBufferIter *iter,
+ PinosPacketRemoveMem *payload)
+{
+ struct stack_iter *si = PPSI (iter);
+
+ g_return_val_if_fail (is_valid_iter (iter), FALSE);
+ g_return_val_if_fail (si->type == PINOS_PACKET_TYPE_REMOVE_MEM, FALSE);
+
+ if (si->size < sizeof (PinosPacketRemoveMem))
+ return FALSE;
+
+ memcpy (payload, si->data, sizeof (*payload));
+
+ return TRUE;
+}
+
+/**
+ * pinos_buffer_builder_add_remove_mem:
+ * @builder: a #PinosBufferBuilder
+ * @payload: a #PinosPacketRemoveMem
+ *
+ * Add a #PINOS_PACKET_TYPE_REMOVE_MEM to @builder with data from @payload.
+ *
+ * Returns: %TRUE on success.
+ */
+gboolean
+pinos_buffer_builder_add_remove_mem (PinosBufferBuilder *builder,
+ PinosPacketRemoveMem *payload)
+{
+ struct stack_builder *sb = PPSB (builder);
+ PinosPacketRemoveMem *p;
+
+ g_return_val_if_fail (is_valid_builder (builder), FALSE);
+
+ p = builder_add_packet (sb, PINOS_PACKET_TYPE_REMOVE_MEM, sizeof (PinosPacketRemoveMem));
+ memcpy (p, payload, sizeof (*payload));
+
+ return TRUE;
+}
+
/* header packets */
/**
- * pinos_buffer_iter_get_header:
+ * pinos_buffer_iter_parse_header:
* @iter: a #PinosBufferIter
- * @header: a #PinosPacketHeader
+ * @payload: a #PinosPacketHeader
*
* Get the #PinosPacketHeader. @iter must be positioned on a packet of
* type #PINOS_PACKET_TYPE_HEADER
*
- * Returns: %TRUE if @header contains valid data.
+ * Returns: %TRUE if @payload contains valid data.
*/
gboolean
pinos_buffer_iter_parse_header (PinosBufferIter *iter,
- PinosPacketHeader *header)
+ PinosPacketHeader *payload)
{
struct stack_iter *si = PPSI (iter);
@@ -657,7 +781,7 @@ pinos_buffer_iter_parse_header (PinosBufferIter *iter,
if (si->size < sizeof (PinosPacketHeader))
return FALSE;
- memcpy (header, si->data, sizeof (*header));
+ memcpy (payload, si->data, sizeof (*payload));
return TRUE;
}
@@ -665,48 +789,48 @@ pinos_buffer_iter_parse_header (PinosBufferIter *iter,
/**
* pinos_buffer_builder_add_header:
* @builder: a #PinosBufferBuilder
- * @header: a #PinosPacketHeader
+ * @payload: a #PinosPacketHeader
*
- * Add a #PINOS_PACKET_TYPE_HEADER to @builder with data from @header.
+ * Add a #PINOS_PACKET_TYPE_HEADER to @builder with data from @payload.
*
* Returns: %TRUE on success.
*/
gboolean
pinos_buffer_builder_add_header (PinosBufferBuilder *builder,
- PinosPacketHeader *header)
+ PinosPacketHeader *payload)
{
struct stack_builder *sb = PPSB (builder);
- PinosPacketHeader *h;
+ PinosPacketHeader *p;
g_return_val_if_fail (is_valid_builder (builder), FALSE);
- h = builder_add_packet (sb, PINOS_PACKET_TYPE_HEADER, sizeof (PinosPacketHeader));
- memcpy (h, header, sizeof (*header));
+ p = builder_add_packet (sb, PINOS_PACKET_TYPE_HEADER, sizeof (PinosPacketHeader));
+ memcpy (p, payload, sizeof (*payload));
return TRUE;
}
-/* fd-payload packets */
+/* process-mem packets */
/**
- * pinos_buffer_iter_get_fd_payload:
+ * pinos_buffer_iter_parse_process_mem:
* @iter: a #PinosBufferIter
- * @payload: a #PinosPacketFDPayload
+ * @payload: a #PinosPacketProcessMem
*
- * Get the #PinosPacketFDPayload. @iter must be positioned on a packet of
- * type #PINOS_PACKET_TYPE_FD_PAYLOAD
+ * Get the #PinosPacketProcessMem. @iter must be positioned on a packet of
+ * type #PINOS_PACKET_TYPE_PROCESS_MEM
*
* Returns: %TRUE if @payload contains valid data.
*/
gboolean
-pinos_buffer_iter_parse_fd_payload (PinosBufferIter *iter,
- PinosPacketFDPayload *payload)
+pinos_buffer_iter_parse_process_mem (PinosBufferIter *iter,
+ PinosPacketProcessMem *payload)
{
struct stack_iter *si = PPSI (iter);
g_return_val_if_fail (is_valid_iter (iter), FALSE);
- g_return_val_if_fail (si->type == PINOS_PACKET_TYPE_FD_PAYLOAD, FALSE);
+ g_return_val_if_fail (si->type == PINOS_PACKET_TYPE_PROCESS_MEM, FALSE);
- if (si->size < sizeof (PinosPacketFDPayload))
+ if (si->size < sizeof (PinosPacketProcessMem))
return FALSE;
memcpy (payload, si->data, sizeof (*payload));
@@ -715,49 +839,49 @@ pinos_buffer_iter_parse_fd_payload (PinosBufferIter *iter,
}
/**
- * pinos_buffer_builder_add_fd_payload:
+ * pinos_buffer_builder_add_process_mem:
* @builder: a #PinosBufferBuilder
- * @payload: a #PinosPacketFDPayload
+ * @payload: a #PinosPacketProcessMem
*
- * Add a #PINOS_PACKET_TYPE_FD_PAYLOAD to @builder with data from @payload.
+ * Add a #PINOS_PACKET_TYPE_PROCESS_MEM to @builder with data from @payload.
*
* Returns: %TRUE on success.
*/
gboolean
-pinos_buffer_builder_add_fd_payload (PinosBufferBuilder *builder,
- PinosPacketFDPayload *payload)
+pinos_buffer_builder_add_process_mem (PinosBufferBuilder *builder,
+ PinosPacketProcessMem *payload)
{
struct stack_builder *sb = PPSB (builder);
- PinosPacketFDPayload *p;
+ PinosPacketProcessMem *p;
g_return_val_if_fail (is_valid_builder (builder), FALSE);
g_return_val_if_fail (payload->size > 0, FALSE);
- p = builder_add_packet (sb, PINOS_PACKET_TYPE_FD_PAYLOAD, sizeof (PinosPacketFDPayload));
+ p = builder_add_packet (sb, PINOS_PACKET_TYPE_PROCESS_MEM, sizeof (PinosPacketProcessMem));
memcpy (p, payload, sizeof (*payload));
return TRUE;
}
/**
- * pinos_buffer_iter_parse_release_fd_payload:
+ * pinos_buffer_iter_parse_reuse_mem:
* @iter: a #PinosBufferIter
- * @payload: a #PinosPacketReleaseFDPayload
+ * @payload: a #PinosPacketReuseMem
*
- * Parse a #PINOS_PACKET_TYPE_RELEASE_FD_PAYLOAD packet from @iter into @payload.
+ * Parse a #PINOS_PACKET_TYPE_REUSE_MEM packet from @iter into @payload.
*
* Returns: %TRUE on success
*/
gboolean
-pinos_buffer_iter_parse_release_fd_payload (PinosBufferIter *iter,
- PinosPacketReleaseFDPayload *payload)
+pinos_buffer_iter_parse_reuse_mem (PinosBufferIter *iter,
+ PinosPacketReuseMem *payload)
{
struct stack_iter *si = PPSI (iter);
g_return_val_if_fail (is_valid_iter (iter), FALSE);
- g_return_val_if_fail (si->type == PINOS_PACKET_TYPE_RELEASE_FD_PAYLOAD, FALSE);
+ g_return_val_if_fail (si->type == PINOS_PACKET_TYPE_REUSE_MEM, FALSE);
- if (si->size < sizeof (PinosPacketReleaseFDPayload))
+ if (si->size < sizeof (PinosPacketReuseMem))
return FALSE;
memcpy (payload, si->data, sizeof (*payload));
@@ -766,26 +890,26 @@ pinos_buffer_iter_parse_release_fd_payload (PinosBufferIter *iter,
}
/**
- * pinos_buffer_builder_add_release_fd_payload:
+ * pinos_buffer_builder_add_reuse_mem:
* @builder: a #PinosBufferBuilder
- * @payload: a #PinosPacketReleaseFDPayload
+ * @payload: a #PinosPacketReuseMem
*
- * Add a #PINOS_PACKET_TYPE_RELEASE_FD_PAYLOAD payload in @payload to @builder.
+ * Add a #PINOS_PACKET_TYPE_REUSE_MEM payload in @payload to @builder.
*
* Returns: %TRUE on success
*/
gboolean
-pinos_buffer_builder_add_release_fd_payload (PinosBufferBuilder *builder,
- PinosPacketReleaseFDPayload *payload)
+pinos_buffer_builder_add_reuse_mem (PinosBufferBuilder *builder,
+ PinosPacketReuseMem *payload)
{
struct stack_builder *sb = PPSB (builder);
- PinosPacketReleaseFDPayload *p;
+ PinosPacketReuseMem *p;
g_return_val_if_fail (is_valid_builder (builder), FALSE);
p = builder_add_packet (sb,
- PINOS_PACKET_TYPE_RELEASE_FD_PAYLOAD,
- sizeof (PinosPacketReleaseFDPayload));
+ PINOS_PACKET_TYPE_REUSE_MEM,
+ sizeof (PinosPacketReuseMem));
memcpy (p, payload, sizeof (*payload));
return TRUE;
diff --git a/pinos/client/buffer.h b/pinos/client/buffer.h
index 3750c780e..b035d305f 100644
--- a/pinos/client/buffer.h
+++ b/pinos/client/buffer.h
@@ -75,11 +75,16 @@ gint * pinos_buffer_steal_fds (PinosBuffer *buffer,
* @PINOS_PACKET_TYPE_INVALID: invalid packet type, ignore
* @PINOS_PACKET_TYPE_CONTINUATION: continuation packet, used internally to send
* commands using a shared memory region.
+ * @PINOS_PACKET_TYPE_REGISTER_MEM: register memory region
+ * @PINOS_PACKET_TYPE_RELEASE_MEM: release memory region
+ * @PINOS_PACKET_TYPE_START: start transfer
+ * @PINOS_PACKET_TYPE_STOP: stop transfer
+ *
* @PINOS_PACKET_TYPE_HEADER: common packet header
- * @PINOS_PACKET_TYPE_FD_PAYLOAD: packet contains fd-payload. An fd-payload contains
- * the media data as a file descriptor
- * @PINOS_PACKET_TYPE_RELEASE_FD_PAYLOAD: packet contains release fd-payload. Notifies
- * that a previously received fd-payload is no longer in use.
+ * @PINOS_PACKET_TYPE_PROCESS_MEM: packet contains mem-payload. An mem-payload contains
+ * the media data as the index of a shared memory region
+ * @PINOS_PACKET_TYPE_REUSE_MEM: when a memory region has been consumed and is ready to
+ * be reused.
* @PINOS_PACKET_TYPE_FORMAT_CHANGE: a format change.
* @PINOS_PACKET_TYPE_PROPERTY_CHANGE: one or more property changes.
* @PINOS_PACKET_TYPE_REFRESH_REQUEST: ask for a new keyframe
@@ -89,13 +94,21 @@ gint * pinos_buffer_steal_fds (PinosBuffer *buffer,
typedef enum {
PINOS_PACKET_TYPE_INVALID = 0,
- PINOS_PACKET_TYPE_CONTINUATION = 1,
- PINOS_PACKET_TYPE_HEADER = 2,
- PINOS_PACKET_TYPE_FD_PAYLOAD = 3,
- PINOS_PACKET_TYPE_RELEASE_FD_PAYLOAD = 4,
- PINOS_PACKET_TYPE_FORMAT_CHANGE = 5,
- PINOS_PACKET_TYPE_PROPERTY_CHANGE = 6,
- PINOS_PACKET_TYPE_REFRESH_REQUEST = 7,
+ PINOS_PACKET_TYPE_CONTINUATION,
+ PINOS_PACKET_TYPE_ADD_MEM,
+ PINOS_PACKET_TYPE_REMOVE_MEM,
+ PINOS_PACKET_TYPE_START,
+ PINOS_PACKET_TYPE_STREAMING,
+ PINOS_PACKET_TYPE_STOP,
+ PINOS_PACKET_TYPE_STOPPED,
+ PINOS_PACKET_TYPE_DRAIN,
+ PINOS_PACKET_TYPE_DRAINED,
+ PINOS_PACKET_TYPE_HEADER,
+ PINOS_PACKET_TYPE_PROCESS_MEM,
+ PINOS_PACKET_TYPE_REUSE_MEM,
+ PINOS_PACKET_TYPE_FORMAT_CHANGE,
+ PINOS_PACKET_TYPE_PROPERTY_CHANGE,
+ PINOS_PACKET_TYPE_REFRESH_REQUEST,
} PinosPacketType;
@@ -139,8 +152,51 @@ void pinos_buffer_builder_clear (PinosBufferBuilder *builder)
void pinos_buffer_builder_end (PinosBufferBuilder *builder,
PinosBuffer *buffer);
+gboolean pinos_buffer_builder_add_empty (PinosBufferBuilder *builder,
+ PinosPacketType type);
+
gint pinos_buffer_builder_add_fd (PinosBufferBuilder *builder,
int fd);
+/* add-mem packets */
+/**
+ * PinosPacketAddMem:
+ * @id: the unique id of this memory block
+ * @type: the memory block type
+ * @fd_index: the index of the fd with the data
+ * @offset: the offset of the data
+ * @size: the size of the data
+ *
+ * A Packet that contains a memory block used for data transfer.
+ */
+typedef struct {
+ guint32 id;
+ guint32 type;
+ gint32 fd_index;
+ guint64 offset;
+ guint64 size;
+} PinosPacketAddMem;
+
+gboolean pinos_buffer_iter_parse_add_mem (PinosBufferIter *iter,
+ PinosPacketAddMem *payload);
+gboolean pinos_buffer_builder_add_add_mem (PinosBufferBuilder *builder,
+ PinosPacketAddMem *payload);
+
+/* remove-mem packets */
+/**
+ * PinosPacketRemoveMem:
+ * @id: the unique id of the memory block
+ *
+ * Remove a memory block.
+ */
+typedef struct {
+ guint32 id;
+} PinosPacketRemoveMem;
+
+gboolean pinos_buffer_iter_parse_remove_mem (PinosBufferIter *iter,
+ PinosPacketRemoveMem *payload);
+gboolean pinos_buffer_builder_add_remove_mem (PinosBufferBuilder *builder,
+ PinosPacketRemoveMem *payload);
+
/* header packets */
/**
* PinosPacketHeader
@@ -159,15 +215,15 @@ typedef struct {
} PinosPacketHeader;
gboolean pinos_buffer_iter_parse_header (PinosBufferIter *iter,
- PinosPacketHeader *header);
+ PinosPacketHeader *payload);
gboolean pinos_buffer_builder_add_header (PinosBufferBuilder *builder,
- PinosPacketHeader *header);
+ PinosPacketHeader *payload);
-/* fd-payload packets */
+
+/* process-mem packets */
/**
- * PinosPacketFDPayload:
- * @id: the unique id of this payload
- * @fd_index: the index of the fd with the data
+ * PinosPacketProcessMem:
+ * @id: the mem index to process
* @offset: the offset of the data
* @size: the size of the data
*
@@ -176,31 +232,32 @@ gboolean pinos_buffer_builder_add_header (PinosBufferBuilder *buil
*/
typedef struct {
guint32 id;
- gint32 fd_index;
guint64 offset;
guint64 size;
-} PinosPacketFDPayload;
+} PinosPacketProcessMem;
-gboolean pinos_buffer_iter_parse_fd_payload (PinosBufferIter *iter,
- PinosPacketFDPayload *payload);
-gboolean pinos_buffer_builder_add_fd_payload (PinosBufferBuilder *builder,
- PinosPacketFDPayload *payload);
+gboolean pinos_buffer_iter_parse_process_mem (PinosBufferIter *iter,
+ PinosPacketProcessMem *payload);
+gboolean pinos_buffer_builder_add_process_mem (PinosBufferBuilder *builder,
+ PinosPacketProcessMem *payload);
-/* release fd-payload packets */
+/* reuse-mem packets */
/**
- * PinosPacketReleaseFDPayload:
- * @id: the unique id of the fd-payload to release
+ * PinosPacketReuseMem:
+ * @id: the unique id of the memory block to reuse
*
* Release the payload with @id
*/
typedef struct {
guint32 id;
-} PinosPacketReleaseFDPayload;
+ guint64 offset;
+ guint64 size;
+} PinosPacketReuseMem;
-gboolean pinos_buffer_iter_parse_release_fd_payload (PinosBufferIter *iter,
- PinosPacketReleaseFDPayload *payload);
-gboolean pinos_buffer_builder_add_release_fd_payload (PinosBufferBuilder *builder,
- PinosPacketReleaseFDPayload *payload);
+gboolean pinos_buffer_iter_parse_reuse_mem (PinosBufferIter *iter,
+ PinosPacketReuseMem *payload);
+gboolean pinos_buffer_builder_add_reuse_mem (PinosBufferBuilder *builder,
+ PinosPacketReuseMem *payload);
/* format change packets */
@@ -216,9 +273,9 @@ typedef struct {
const gchar *format;
} PinosPacketFormatChange;
-gboolean pinos_buffer_iter_parse_format_change (PinosBufferIter *iter,
+gboolean pinos_buffer_iter_parse_format_change (PinosBufferIter *iter,
PinosPacketFormatChange *payload);
-gboolean pinos_buffer_builder_add_format_change (PinosBufferBuilder *builder,
+gboolean pinos_buffer_builder_add_format_change (PinosBufferBuilder *builder,
PinosPacketFormatChange *payload);
@@ -235,10 +292,10 @@ typedef struct {
const gchar *value;
} PinosPacketPropertyChange;
-gboolean pinos_buffer_iter_parse_property_change (PinosBufferIter *iter,
- guint idx,
+gboolean pinos_buffer_iter_parse_property_change (PinosBufferIter *iter,
+ guint idx,
PinosPacketPropertyChange *payload);
-gboolean pinos_buffer_builder_add_property_change (PinosBufferBuilder *builder,
+gboolean pinos_buffer_builder_add_property_change (PinosBufferBuilder *builder,
PinosPacketPropertyChange *payload);
/* refresh request packets */
diff --git a/pinos/client/fdmanager.c b/pinos/client/fdmanager.c
index 3175d780c..b7d67afa7 100644
--- a/pinos/client/fdmanager.c
+++ b/pinos/client/fdmanager.c
@@ -202,6 +202,43 @@ wrong_object:
return FALSE;
}
}
+/**
+ * pinos_fd_manager_find:
+ * @manager: a #PinosFdManager
+ * @client: a client id
+ * @id: an id
+ *
+ * find the object associated with the id and client from @manager.
+ *
+ * Returns: the object or %NULL
+ */
+gpointer
+pinos_fd_manager_find (PinosFdManager *manager,
+ const gchar *client, guint32 id)
+{
+ PinosFdManagerPrivate *priv;
+ ObjectId *oid;
+ ClientIds *cids;
+
+ g_return_val_if_fail (PINOS_IS_FD_MANAGER (manager), FALSE);
+ g_return_val_if_fail (client != NULL, FALSE);
+
+ priv = manager->priv;
+
+ g_mutex_lock (&priv->lock);
+ oid = g_hash_table_lookup (priv->object_ids, GINT_TO_POINTER (id));
+ if (oid) {
+ cids = g_hash_table_lookup (priv->client_ids, client);
+ if (cids) {
+ GList *find = g_list_find (cids->ids, oid);
+ if (find)
+ return oid->obj;
+ }
+ }
+ g_mutex_unlock (&priv->lock);
+
+ return NULL;
+}
/**
* pinos_fd_manager_remove:
diff --git a/pinos/client/fdmanager.h b/pinos/client/fdmanager.h
index 25730701b..5332bfece 100644
--- a/pinos/client/fdmanager.h
+++ b/pinos/client/fdmanager.h
@@ -67,6 +67,9 @@ gboolean pinos_fd_manager_add (PinosFdManager *manager,
gboolean pinos_fd_manager_remove (PinosFdManager *manager,
const gchar *client,
guint32 id);
+gpointer pinos_fd_manager_find (PinosFdManager *manager,
+ const gchar *client,
+ guint32 id);
gboolean pinos_fd_manager_remove_all (PinosFdManager *manager,
const gchar *client);
diff --git a/pinos/client/pinos.h b/pinos/client/pinos.h
index f0a3c52cd..00ed54b38 100644
--- a/pinos/client/pinos.h
+++ b/pinos/client/pinos.h
@@ -35,6 +35,7 @@
#define PINOS_DBUS_OBJECT_SERVER PINOS_DBUS_OBJECT_PREFIX "/server"
#define PINOS_DBUS_OBJECT_CLIENT PINOS_DBUS_OBJECT_PREFIX "/client"
#define PINOS_DBUS_OBJECT_NODE PINOS_DBUS_OBJECT_PREFIX "/node"
+#define PINOS_DBUS_OBJECT_LINK PINOS_DBUS_OBJECT_PREFIX "/link"
void pinos_init (int *argc, char **argv[]);
diff --git a/pinos/client/stream.c b/pinos/client/stream.c
index 3031a827e..7dc130636 100644
--- a/pinos/client/stream.c
+++ b/pinos/client/stream.c
@@ -65,6 +65,11 @@ struct _PinosStreamPrivate
PinosBuffer recv_buffer;
guint8 recv_data[MAX_BUFFER_SIZE];
int recv_fds[MAX_FDS];
+
+ guint8 send_data[MAX_BUFFER_SIZE];
+ int send_fds[MAX_FDS];
+
+ GHashTable *mem_ids;
};
#define PINOS_STREAM_GET_PRIVATE(obj) \
@@ -91,6 +96,8 @@ enum
static guint signals[LAST_SIGNAL] = { 0 };
+static void unhandle_socket (PinosStream *stream);
+
static void
pinos_stream_get_property (GObject *_object,
guint prop_id,
@@ -546,6 +553,89 @@ channel_failed:
}
}
+static gboolean
+parse_buffer (PinosStream *stream,
+ PinosBuffer *pbuf)
+{
+ PinosBufferIter it;
+ PinosStreamPrivate *priv = stream->priv;
+
+ pinos_buffer_iter_init (&it, pbuf);
+ while (pinos_buffer_iter_next (&it)) {
+ PinosPacketType type = pinos_buffer_iter_get_type (&it);
+
+ switch (type) {
+ case PINOS_PACKET_TYPE_ADD_MEM:
+ {
+ PinosPacketAddMem p;
+ int fd;
+
+ if (!pinos_buffer_iter_parse_add_mem (&it, &p))
+ break;
+
+ fd = pinos_buffer_get_fd (pbuf, p.fd_index);
+ if (fd == -1)
+ break;
+
+// g_hash_table_insert (priv->mem_ids, GINT_TO_POINTER (p.id), NULL);
+ break;
+ }
+ case PINOS_PACKET_TYPE_REMOVE_MEM:
+ {
+ PinosPacketRemoveMem p;
+
+ if (!pinos_buffer_iter_parse_remove_mem (&it, &p))
+ break;
+
+// g_hash_table_remove (priv->mem_ids, GINT_TO_POINTER (p.id));
+ break;
+ }
+ case PINOS_PACKET_TYPE_FORMAT_CHANGE:
+ {
+ PinosPacketFormatChange p;
+
+ if (!pinos_buffer_iter_parse_format_change (&it, &p))
+ break;
+
+ if (priv->format)
+ g_bytes_unref (priv->format);
+ priv->format = g_bytes_new (p.format, strlen (p.format) + 1);
+ g_object_notify (G_OBJECT (stream), "format");
+ break;
+ }
+ case PINOS_PACKET_TYPE_STREAMING:
+ {
+ stream_set_state (stream, PINOS_STREAM_STATE_STREAMING, NULL);
+ break;
+ }
+ case PINOS_PACKET_TYPE_STOPPED:
+ {
+ unhandle_socket (stream);
+
+ g_clear_pointer (&priv->format, g_bytes_unref);
+ g_object_notify (G_OBJECT (stream), "format");
+
+ stream_set_state (stream, PINOS_STREAM_STATE_READY, NULL);
+ break;
+ }
+ case PINOS_PACKET_TYPE_HEADER:
+ {
+ break;
+ }
+ case PINOS_PACKET_TYPE_PROCESS_MEM:
+ {
+ break;
+ }
+ default:
+ g_warning ("unhandled packet %d", type);
+ break;
+ }
+ }
+ pinos_buffer_iter_end (&it);
+
+ return TRUE;
+}
+
static gboolean
on_socket_condition (GSocket *socket,
GIOCondition condition,
@@ -572,6 +662,8 @@ on_socket_condition (GSocket *socket,
return TRUE;
}
+ parse_buffer (stream, buffer);
+
priv->buffer = buffer;
g_signal_emit (stream, signals[SIGNAL_NEW_BUFFER], 0, NULL);
priv->buffer = NULL;
@@ -841,18 +933,25 @@ static gboolean
do_start (PinosStream *stream)
{
PinosStreamPrivate *priv = stream->priv;
+ PinosBufferBuilder builder;
+ PinosPacketFormatChange fc;
+ PinosBuffer pbuf;
+ GError *error = NULL;
handle_socket (stream, priv->fd);
- g_dbus_proxy_call (priv->channel,
- "Start",
- g_variant_new ("(s)",
- priv->format ? g_bytes_get_data (priv->format, NULL) : "ANY"),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL, /* GCancellable *cancellable */
- on_stream_started,
- stream);
+ pinos_stream_buffer_builder_init (stream, &builder);
+ fc.id = 0;
+ fc.format = priv->format ? g_bytes_get_data (priv->format, NULL) : "ANY";
+ pinos_buffer_builder_add_format_change (&builder, &fc);
+ pinos_buffer_builder_add_empty (&builder, PINOS_PACKET_TYPE_START);
+ pinos_buffer_builder_end (&builder, &pbuf);
+
+ if (!pinos_io_write_buffer (priv->fd, &pbuf, &error)) {
+ g_warning ("stream %p: failed to read buffer: %s", stream, error->message);
+ g_clear_error (&error);
+ }
+ g_object_unref (stream);
return FALSE;
}
@@ -936,16 +1035,11 @@ call_failed:
static gboolean
do_stop (PinosStream *stream)
{
- PinosStreamPrivate *priv = stream->priv;
+ PinosBufferBuilder builder;
- g_dbus_proxy_call (priv->channel,
- "Stop",
- g_variant_new ("()"),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL, /* GCancellable *cancellable */
- on_stream_stopped,
- stream);
+ pinos_stream_buffer_builder_init (stream, &builder);
+ pinos_buffer_builder_add_empty (&builder, PINOS_PACKET_TYPE_STOP);
+ g_object_unref (stream);
return FALSE;
}
@@ -1091,9 +1185,16 @@ pinos_stream_peek_buffer (PinosStream *stream)
void
pinos_stream_buffer_builder_init (PinosStream *stream, PinosBufferBuilder *builder)
{
- g_return_if_fail (PINOS_IS_STREAM (stream));
+ PinosStreamPrivate *priv;
- pinos_buffer_builder_init (builder);
+ g_return_if_fail (PINOS_IS_STREAM (stream));
+ priv = stream->priv;
+
+ pinos_buffer_builder_init_into (builder,
+ priv->send_data,
+ MAX_BUFFER_SIZE,
+ priv->send_fds,
+ MAX_FDS);
}
/**
diff --git a/pinos/dbus/org.pinos.xml b/pinos/dbus/org.pinos.xml
index b1ab9b9d5..0d9633b8a 100644
--- a/pinos/dbus/org.pinos.xml
+++ b/pinos/dbus/org.pinos.xml
@@ -62,6 +62,7 @@
+
@@ -114,23 +115,6 @@
-
-
-
-
-
-
-
-