buffer: allow building into custom memory

Make it possible to pass custom memory to the builder so that it can
construct packets directly into specified memory and avoid allocs.
Remove GError and GSocketControlMessage in the buffer API to make it
possible to use other (rt-safe) API later.
This commit is contained in:
Wim Taymans 2016-05-09 18:48:18 +02:00
parent 91385a782e
commit c67d3d7f04
9 changed files with 240 additions and 175 deletions

View file

@ -142,7 +142,7 @@ release_fds (GstPinosDepay *this, GstBuffer *buffer)
pinos_buffer_builder_end (&b, &pbuf);
g_array_unref (fdids);
data = pinos_buffer_steal (&pbuf, &size, NULL);
data = pinos_buffer_steal_data (&pbuf, &size);
outbuf = gst_buffer_new_wrapped (data, size);
ev = gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM,
@ -164,20 +164,20 @@ gst_pinos_depay_chain (GstPad *pad, GstObject * parent, GstBuffer * buffer)
PinosBuffer pbuf;
PinosBufferIter it;
GstNetControlMessageMeta * meta;
GSocketControlMessage *msg = NULL;
GError *err = NULL;
GArray *fdids = NULL;
GUnixFDList *fds = NULL;
meta = ((GstNetControlMessageMeta*) gst_buffer_get_meta (
buffer, GST_NET_CONTROL_MESSAGE_META_API_TYPE));
if (meta) {
msg = g_object_ref (meta->message);
gst_buffer_remove_meta (buffer, (GstMeta *) meta);
meta = NULL;
if (G_IS_UNIX_FD_MESSAGE (meta->message)) {
fds = g_unix_fd_message_get_fd_list (G_UNIX_FD_MESSAGE (meta->message));
}
}
gst_buffer_map (buffer, &info, GST_MAP_READ);
pinos_buffer_init_data (&pbuf, info.data, info.size, msg);
pinos_buffer_init_data (&pbuf, info.data, info.size, NULL, 0);
pinos_buffer_iter_init (&it, &pbuf);
while (pinos_buffer_iter_next (&it)) {
@ -212,7 +212,7 @@ gst_pinos_depay_chain (GstPad *pad, GstObject * parent, GstBuffer * buffer)
if (!pinos_buffer_iter_parse_fd_payload (&it, &p))
goto error;
fd = pinos_buffer_get_fd (&pbuf, p.fd_index, &err);
fd = g_unix_fd_list_get (fds, p.fd_index, &err);
if (fd == -1)
goto error;

View file

@ -214,7 +214,7 @@ client_buffer_received (GstPinosPay *pay, GstBuffer *buffer,
}
gst_buffer_map (buffer, &info, GST_MAP_READ);
pinos_buffer_init_data (&pbuf, info.data, info.size, NULL);
pinos_buffer_init_data (&pbuf, info.data, info.size, NULL, 0);
pinos_buffer_iter_init (&it, &pbuf);
while (pinos_buffer_iter_next (&it)) {
switch (pinos_buffer_iter_get_type (&it)) {
@ -266,7 +266,7 @@ client_buffer_received (GstPinosPay *pay, GstBuffer *buffer,
if (have_out) {
pinos_buffer_builder_end (&b, &pbuf);
data = pinos_buffer_steal (&pbuf, &size, NULL);
data = pinos_buffer_steal_data (&pbuf, &size);
outbuf = gst_buffer_new_wrapped (data, size);
ev = gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM,
@ -379,7 +379,7 @@ release_fds (GstPinosPay *pay, GstBuffer *buffer)
pinos_buffer_builder_end (&b, &pbuf);
g_array_unref (fdids);
data = pinos_buffer_steal (&pbuf, &size, NULL);
data = pinos_buffer_steal_data (&pbuf, &size);
outbuf = gst_buffer_new_wrapped (data, size);
ev = gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM,
@ -401,7 +401,7 @@ gst_pinos_pay_chain_pinos (GstPinosPay *pay, GstBuffer * buffer)
GArray *fdids = NULL;
gst_buffer_map (buffer, &info, GST_MAP_READ);
pinos_buffer_init_data (&pbuf, info.data, info.size, NULL);
pinos_buffer_init_data (&pbuf, info.data, info.size, NULL, 0);
pinos_buffer_iter_init (&it, &pbuf);
while (pinos_buffer_iter_next (&it)) {
switch (pinos_buffer_iter_get_type (&it)) {
@ -467,6 +467,7 @@ gst_pinos_pay_chain_other (GstPinosPay *pay, GstBuffer * buffer)
gpointer data;
GSocketControlMessage *msg;
gboolean tmpfile = TRUE;
gint *fds, n_fds, i;
hdr.flags = 0;
hdr.seq = GST_BUFFER_OFFSET (buffer);
@ -476,20 +477,19 @@ gst_pinos_pay_chain_other (GstPinosPay *pay, GstBuffer * buffer)
pinos_buffer_builder_init (&builder);
pinos_buffer_builder_add_header (&builder, &hdr);
msg = g_unix_fd_message_new ();
fdmem = gst_pinos_pay_get_fd_memory (pay, buffer, &tmpfile);
p.fd_index = pinos_buffer_builder_add_fd (&builder, gst_fd_memory_get_fd (fdmem), &err);
if (p.fd_index == -1)
goto add_fd_failed;
p.fd_index = pinos_buffer_builder_add_fd (&builder, gst_fd_memory_get_fd (fdmem));
p.id = pinos_fd_manager_get_id (pay->fdmanager);
p.offset = fdmem->offset;
p.size = fdmem->size;
pinos_buffer_builder_add_fd_payload (&builder, &p);
pinos_buffer_builder_end (&builder, &pbuf);
gst_memory_unref(fdmem);
fdmem = NULL;
data = pinos_buffer_steal (&pbuf, &size, &msg);
data = pinos_buffer_steal_data (&pbuf, &size);
fds = pinos_buffer_steal_fds (&pbuf, &n_fds);
outbuf = gst_buffer_new_wrapped (data, size);
GST_BUFFER_PTS (outbuf) = GST_BUFFER_PTS (buffer);
@ -498,6 +498,18 @@ gst_pinos_pay_chain_other (GstPinosPay *pay, GstBuffer * buffer)
GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET (buffer);
GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET_END (buffer);
msg = g_unix_fd_message_new ();
for (i = 0; i < n_fds; i++) {
if (!g_unix_fd_message_append_fd (G_UNIX_FD_MESSAGE (msg), fds[i], &err))
goto add_fd_failed;
}
gst_buffer_add_net_control_message_meta (outbuf, msg);
g_object_unref (msg);
g_free (fds);
gst_memory_unref(fdmem);
fdmem = NULL;
if (!tmpfile) {
GArray *fdids;
/* we are using the original buffer fd in the control message, we need
@ -516,16 +528,13 @@ gst_pinos_pay_chain_other (GstPinosPay *pay, GstBuffer * buffer)
gst_buffer_unref (buffer);
}
gst_buffer_add_net_control_message_meta (outbuf, msg);
g_object_unref (msg);
return gst_pad_push (pay->srcpad, outbuf);
/* ERRORS */
add_fd_failed:
{
GST_WARNING_OBJECT (pay, "Adding fd failed: %s", err->message);
gst_memory_unref(fdmem);
gst_object_unref(msg);
g_clear_error (&err);
return GST_FLOW_ERROR;

View file

@ -507,7 +507,6 @@ gst_pinos_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
PinosPacketHeader hdr;
PinosPacketFDPayload p;
gsize size;
GError *err = NULL;
gboolean tmpfile, res;
pinossink = GST_PINOS_SINK (bsink);
@ -552,17 +551,13 @@ gst_pinos_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
pinos_buffer_builder_init (&builder);
pinos_buffer_builder_add_header (&builder, &hdr);
p.fd_index = pinos_buffer_builder_add_fd (&builder, gst_fd_memory_get_fd (mem), &err);
if (p.fd_index == -1)
goto add_fd_failed;
p.fd_index = pinos_buffer_builder_add_fd (&builder, gst_fd_memory_get_fd (mem));
p.id = pinossink->id_counter++;
p.offset = 0;
p.size = size;
pinos_buffer_builder_add_fd_payload (&builder, &p);
pinos_buffer_builder_end (&builder, &pbuf);
gst_memory_unref (mem);
GST_LOG ("sending fd index %d", p.id);
pinos_main_loop_lock (pinossink->loop);
@ -572,6 +567,8 @@ gst_pinos_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
pinos_buffer_clear (&pbuf);
pinos_main_loop_unlock (pinossink->loop);
gst_memory_unref (mem);
if (res && !tmpfile) {
/* keep the buffer around until we get the release fd message */
g_hash_table_insert (pinossink->fdids, GINT_TO_POINTER (p.id), gst_buffer_ref (buffer));
@ -586,18 +583,13 @@ map_error:
{
GST_ELEMENT_ERROR (pinossink, RESOURCE, FAILED,
("failed to map buffer"), (NULL));
return GST_FLOW_ERROR;
}
add_fd_failed:
{
GST_ELEMENT_ERROR (pinossink, RESOURCE, FAILED,
("failed to add fd: %s", err->message), (NULL));
pinos_buffer_builder_clear (&builder);
gst_memory_unref (mem);
return GST_FLOW_ERROR;
}
streaming_error:
{
pinos_main_loop_unlock (pinossink->loop);
gst_memory_unref (mem);
return GST_FLOW_ERROR;
}
}

View file

@ -201,7 +201,7 @@ release_fds (GstPinosSocketSink *this, GstBuffer *buffer)
pinos_buffer_builder_end (&b, &pbuf);
g_array_unref (fdids);
data = pinos_buffer_steal (&pbuf, &size, NULL);
data = pinos_buffer_steal_data (&pbuf, &size);
outbuf = gst_buffer_new_wrapped (data, size);
ev = gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM,
@ -223,7 +223,7 @@ gst_pinos_socket_sink_render_pinos (GstPinosSocketSink * this, GstBuffer * buffe
GArray *fdids = NULL;
gst_buffer_map (buffer, &info, GST_MAP_READ);
pinos_buffer_init_data (&pbuf, info.data, info.size, NULL);
pinos_buffer_init_data (&pbuf, info.data, info.size, NULL, 0);
pinos_buffer_iter_init (&it, &pbuf);
while (pinos_buffer_iter_next (&it)) {
switch (pinos_buffer_iter_get_type (&it)) {
@ -314,6 +314,7 @@ gst_pinos_socket_sink_render_other (GstPinosSocketSink * this, GstBuffer * buffe
gpointer data;
GSocketControlMessage *msg;
gboolean tmpfile = TRUE;
gint *fds, n_fds, i;
hdr.flags = 0;
hdr.seq = GST_BUFFER_OFFSET (buffer);
@ -324,9 +325,7 @@ gst_pinos_socket_sink_render_other (GstPinosSocketSink * this, GstBuffer * buffe
pinos_buffer_builder_add_header (&builder, &hdr);
fdmem = gst_pinos_socket_sink_get_fd_memory (this, buffer, &tmpfile);
p.fd_index = pinos_buffer_builder_add_fd (&builder, gst_fd_memory_get_fd (fdmem), &err);
if (p.fd_index == -1)
goto add_fd_failed;
p.fd_index = pinos_buffer_builder_add_fd (&builder, gst_fd_memory_get_fd (fdmem));
p.id = pinos_fd_manager_get_id (this->fdmanager);
p.offset = fdmem->offset;
p.size = fdmem->size;
@ -336,10 +335,9 @@ gst_pinos_socket_sink_render_other (GstPinosSocketSink * this, GstBuffer * buffe
p.id, hdr.pts, GST_BUFFER_PTS (buffer), GST_ELEMENT_CAST (this)->base_time);
pinos_buffer_builder_end (&builder, &pbuf);
gst_memory_unref(fdmem);
fdmem = NULL;
data = pinos_buffer_steal (&pbuf, &size, &msg);
data = pinos_buffer_steal_data (&pbuf, &size);
fds = pinos_buffer_steal_fds (&pbuf, &n_fds);
outbuf = gst_buffer_new_wrapped (data, size);
GST_BUFFER_PTS (outbuf) = GST_BUFFER_PTS (buffer);
@ -348,6 +346,18 @@ gst_pinos_socket_sink_render_other (GstPinosSocketSink * this, GstBuffer * buffe
GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET (buffer);
GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET_END (buffer);
msg = g_unix_fd_message_new ();
for (i = 0; i < n_fds; i++) {
if (!g_unix_fd_message_append_fd (G_UNIX_FD_MESSAGE (msg), fds[i], &err))
goto add_fd_failed;
}
gst_buffer_add_net_control_message_meta (outbuf, msg);
g_object_unref (msg);
g_free (fds);
gst_memory_unref(fdmem);
fdmem = NULL;
if (!tmpfile) {
GArray *fdids;
/* we are using the original buffer fd in the control message, we need
@ -363,8 +373,6 @@ gst_pinos_socket_sink_render_other (GstPinosSocketSink * this, GstBuffer * buffe
gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (outbuf),
orig_buffer_quark, gst_buffer_ref (buffer), (GDestroyNotify) gst_buffer_unref);
}
gst_buffer_add_net_control_message_meta (outbuf, msg);
g_object_unref (msg);
gst_burst_cache_queue_buffer (this->cache, outbuf);
@ -534,7 +542,7 @@ myreader_receive_buffer (GstPinosSocketSink *this, MyReader *myreader)
pinos_buffer_builder_init (&b);
}
pinos_buffer_init_data (&pbuf, mem, maxmem, NULL);
pinos_buffer_init_data (&pbuf, mem, maxmem, NULL, 0);
pinos_buffer_iter_init (&it, &pbuf);
while (pinos_buffer_iter_next (&it)) {
switch (pinos_buffer_iter_get_type (&it)) {
@ -585,7 +593,7 @@ myreader_receive_buffer (GstPinosSocketSink *this, MyReader *myreader)
if (have_out) {
pinos_buffer_builder_end (&b, &pbuf);
data = pinos_buffer_steal (&pbuf, &size, NULL);
data = pinos_buffer_steal_data (&pbuf, &size);
outbuf = gst_buffer_new_wrapped (data, size);
ev = gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM,

View file

@ -358,7 +358,6 @@ on_new_buffer (GObject *gobject,
PinosBuffer *pbuf;
PinosBufferIter it;
GstBuffer *buf = NULL;
GError *error = NULL;
GST_LOG_OBJECT (pinossrc, "got new buffer");
if (!pinos_stream_peek_buffer (pinossrc->stream, &pbuf)) {
@ -397,8 +396,9 @@ on_new_buffer (GObject *gobject,
if (!pinos_buffer_iter_parse_fd_payload (&it, &data.p))
goto parse_failed;
GST_DEBUG ("got fd payload id %d", data.p.id);
fd = pinos_buffer_get_fd (pbuf, data.p.fd_index, &error);
fd = pinos_buffer_get_fd (pbuf, data.p.fd_index);
if (fd == -1)
goto no_fds;
@ -453,8 +453,7 @@ parse_failed:
no_fds:
{
gst_buffer_unref (buf);
GST_ELEMENT_ERROR (pinossrc, RESOURCE, FAILED,
("buffer error: %s", error->message), (NULL));
GST_ELEMENT_ERROR (pinossrc, RESOURCE, FAILED, ("fd not found in buffer"), (NULL));
pinos_main_loop_signal (pinossrc->loop, FALSE);
return;
}