mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-10 13:30:05 -05:00
More work on wire protocol
Make separate payload for the header. Make release-fd payloads capture_buffer -> peek_buffer to avoid a copy remove release-buffer, we really need to release each fd in the buffer separately. provide_buffer -> send_buffer so that we can also use this to send the release-fd messages. in pinossrc, send back release-fd messages when the fd is no longer in use.
This commit is contained in:
parent
c2cf359076
commit
8d1ad2ea63
10 changed files with 351 additions and 155 deletions
|
|
@ -86,17 +86,21 @@ gst_pinos_depay_chain (GstPad *pad, GstObject * parent, GstBuffer * buffer)
|
|||
PinosBufferIter it;
|
||||
GstNetControlMessageMeta * meta;
|
||||
GSocketControlMessage *msg = NULL;
|
||||
const PinosBufferHeader *hdr;
|
||||
GError *err = NULL;
|
||||
|
||||
meta = ((GstNetControlMessageMeta*) gst_buffer_get_meta (
|
||||
buffer, GST_NET_CONTROL_MESSAGE_META_API_TYPE));
|
||||
if (meta) {
|
||||
msg = meta->message;
|
||||
msg = g_object_ref (meta->message);
|
||||
gst_buffer_remove_meta (buffer, (GstMeta *) meta);
|
||||
meta = NULL;
|
||||
}
|
||||
|
||||
if (msg == NULL) {
|
||||
gst_buffer_unref (buffer);
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
outbuf = gst_buffer_new ();
|
||||
|
||||
gst_buffer_map (buffer, &info, GST_MAP_READ);
|
||||
|
|
@ -105,13 +109,24 @@ gst_pinos_depay_chain (GstPad *pad, GstObject * parent, GstBuffer * buffer)
|
|||
pinos_buffer_iter_init (&it, &pbuf);
|
||||
while (pinos_buffer_iter_next (&it)) {
|
||||
switch (pinos_buffer_iter_get_type (&it)) {
|
||||
case PINOS_PACKET_TYPE_HEADER:
|
||||
{
|
||||
PinosPacketHeader hdr;
|
||||
|
||||
if (!pinos_buffer_iter_parse_header (&it, &hdr))
|
||||
goto error;
|
||||
|
||||
GST_BUFFER_OFFSET (outbuf) = hdr.seq;
|
||||
break;
|
||||
}
|
||||
case PINOS_PACKET_TYPE_FD_PAYLOAD:
|
||||
{
|
||||
GstMemory *fdmem = NULL;
|
||||
PinosPacketFDPayload p;
|
||||
int fd;
|
||||
|
||||
pinos_buffer_iter_parse_fd_payload (&it, &p);
|
||||
if (!pinos_buffer_iter_parse_fd_payload (&it, &p))
|
||||
goto error;
|
||||
fd = pinos_buffer_get_fd (&pbuf, p.fd_index, &err);
|
||||
if (fd == -1)
|
||||
goto error;
|
||||
|
|
@ -126,8 +141,6 @@ gst_pinos_depay_chain (GstPad *pad, GstObject * parent, GstBuffer * buffer)
|
|||
break;
|
||||
}
|
||||
}
|
||||
hdr = pinos_buffer_get_header (&pbuf, NULL);
|
||||
GST_BUFFER_OFFSET (buffer) = hdr->seq;
|
||||
pinos_buffer_clear (&pbuf);
|
||||
gst_buffer_unmap (buffer, &info);
|
||||
gst_buffer_unref (buffer);
|
||||
|
|
@ -139,6 +152,7 @@ error:
|
|||
GST_ELEMENT_ERROR (depay, RESOURCE, SETTINGS, (NULL),
|
||||
("can't get fd: %s", err->message));
|
||||
g_clear_error (&err);
|
||||
gst_buffer_unref (outbuf);
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ gst_pinos_pay_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
|
|||
GstBuffer *outbuf;
|
||||
PinosBuffer pbuf;
|
||||
PinosBufferBuilder builder;
|
||||
PinosBufferHeader hdr;
|
||||
PinosPacketHeader hdr;
|
||||
PinosPacketFDPayload p;
|
||||
gsize size;
|
||||
gpointer data;
|
||||
|
|
@ -167,7 +167,7 @@ gst_pinos_pay_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
|
|||
hdr.dts_offset = 0;
|
||||
|
||||
pinos_buffer_builder_init (&builder);
|
||||
pinos_buffer_builder_set_header (&builder, &hdr);
|
||||
pinos_buffer_builder_add_header (&builder, &hdr);
|
||||
|
||||
fdmem = gst_pinos_pay_get_fd_memory (pay, buffer);
|
||||
p.fd_index = pinos_buffer_builder_add_fd (&builder, gst_fd_memory_get_fd (fdmem), &err);
|
||||
|
|
|
|||
|
|
@ -333,7 +333,7 @@ gst_pinos_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
|
|||
PinosBufferBuilder builder;
|
||||
GstMemory *mem = NULL;
|
||||
GstClockTime pts, dts, base;
|
||||
PinosBufferHeader hdr;
|
||||
PinosPacketHeader hdr;
|
||||
PinosPacketFDPayload p;
|
||||
gsize size;
|
||||
GError *err = NULL;
|
||||
|
|
@ -376,7 +376,7 @@ gst_pinos_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
|
|||
}
|
||||
|
||||
pinos_buffer_builder_init (&builder);
|
||||
pinos_buffer_builder_set_header (&builder, &hdr);
|
||||
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)
|
||||
|
|
@ -393,7 +393,7 @@ gst_pinos_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
|
|||
pinos_main_loop_lock (pinossink->loop);
|
||||
if (pinos_stream_get_state (pinossink->stream) != PINOS_STREAM_STATE_STREAMING)
|
||||
goto streaming_error;
|
||||
pinos_stream_provide_buffer (pinossink->stream, &pbuf);
|
||||
pinos_stream_send_buffer (pinossink->stream, &pbuf);
|
||||
pinos_buffer_clear (&pbuf);
|
||||
pinos_main_loop_unlock (pinossink->loop);
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
#include <gst/allocators/gstfdmemory.h>
|
||||
|
||||
|
||||
static GQuark fdpayload_data_quark;
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (pinos_src_debug);
|
||||
#define GST_CAT_DEFAULT pinos_src_debug
|
||||
|
|
@ -190,6 +191,8 @@ gst_pinos_src_class_init (GstPinosSrcClass * klass)
|
|||
|
||||
GST_DEBUG_CATEGORY_INIT (pinos_src_debug, "pinossrc", 0,
|
||||
"Pinos Source");
|
||||
|
||||
fdpayload_data_quark = g_quark_from_static_string ("GstPinosSrcFDPayloadQuark");
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -246,55 +249,100 @@ gst_pinos_src_src_fixate (GstBaseSrc * bsrc, GstCaps * caps)
|
|||
return caps;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GstPinosSrc *src;
|
||||
PinosPacketFDPayload p;
|
||||
} FDPayloadData;
|
||||
|
||||
static void
|
||||
fdpayload_data_destroy (gpointer user_data)
|
||||
{
|
||||
FDPayloadData *data = user_data;
|
||||
GstPinosSrc *pinossrc = data->src;
|
||||
PinosBufferBuilder b;
|
||||
PinosPacketReleaseFDPayload r;
|
||||
PinosBuffer pbuf;
|
||||
|
||||
r.id = data->p.id;
|
||||
|
||||
GST_DEBUG_OBJECT (pinossrc, "destroy %d", r.id);
|
||||
|
||||
pinos_buffer_builder_init (&b);
|
||||
pinos_buffer_builder_add_release_fd_payload (&b, &r);
|
||||
pinos_buffer_builder_end (&b, &pbuf);
|
||||
|
||||
GST_OBJECT_LOCK (pinossrc);
|
||||
if (pinossrc->stream)
|
||||
pinos_stream_send_buffer (pinossrc->stream, &pbuf);
|
||||
GST_OBJECT_UNLOCK (pinossrc);
|
||||
|
||||
pinos_buffer_clear (&pbuf);
|
||||
|
||||
gst_object_unref (pinossrc);
|
||||
g_slice_free (FDPayloadData, data);
|
||||
}
|
||||
|
||||
static void
|
||||
on_new_buffer (GObject *gobject,
|
||||
gpointer user_data)
|
||||
{
|
||||
GstPinosSrc *pinossrc = user_data;
|
||||
PinosBuffer pbuf;
|
||||
const PinosBufferHeader *hdr;
|
||||
PinosBuffer *pbuf;
|
||||
PinosBufferIter it;
|
||||
GstBuffer *buf;
|
||||
GError *error = NULL;
|
||||
|
||||
GST_LOG_OBJECT (pinossrc, "got new buffer");
|
||||
if (!pinos_stream_capture_buffer (pinossrc->stream, &pbuf)) {
|
||||
if (!pinos_stream_peek_buffer (pinossrc->stream, &pbuf)) {
|
||||
g_warning ("failed to capture buffer");
|
||||
return;
|
||||
}
|
||||
|
||||
buf = gst_buffer_new ();
|
||||
|
||||
hdr = pinos_buffer_get_header (&pbuf, NULL);
|
||||
|
||||
if (GST_CLOCK_TIME_IS_VALID (hdr->pts)) {
|
||||
if (hdr->pts > GST_ELEMENT_CAST (pinossrc)->base_time)
|
||||
GST_BUFFER_PTS (buf) = hdr->pts - GST_ELEMENT_CAST (pinossrc)->base_time;
|
||||
|
||||
if (GST_BUFFER_PTS (buf) + hdr->dts_offset > 0)
|
||||
GST_BUFFER_DTS (buf) = GST_BUFFER_PTS (buf) + hdr->dts_offset;
|
||||
}
|
||||
GST_BUFFER_OFFSET (buf) = hdr->seq;
|
||||
|
||||
pinos_buffer_iter_init (&it, &pbuf);
|
||||
pinos_buffer_iter_init (&it, pbuf);
|
||||
while (pinos_buffer_iter_next (&it)) {
|
||||
switch (pinos_buffer_iter_get_type (&it)) {
|
||||
case PINOS_PACKET_TYPE_HEADER:
|
||||
{
|
||||
PinosPacketHeader hdr;
|
||||
|
||||
if (!pinos_buffer_iter_parse_header (&it, &hdr))
|
||||
goto no_fds;
|
||||
|
||||
if (GST_CLOCK_TIME_IS_VALID (hdr.pts)) {
|
||||
if (hdr.pts > GST_ELEMENT_CAST (pinossrc)->base_time)
|
||||
GST_BUFFER_PTS (buf) = hdr.pts - GST_ELEMENT_CAST (pinossrc)->base_time;
|
||||
|
||||
if (GST_BUFFER_PTS (buf) + hdr.dts_offset > 0)
|
||||
GST_BUFFER_DTS (buf) = GST_BUFFER_PTS (buf) + hdr.dts_offset;
|
||||
}
|
||||
GST_BUFFER_OFFSET (buf) = hdr.seq;
|
||||
break;
|
||||
}
|
||||
case PINOS_PACKET_TYPE_FD_PAYLOAD:
|
||||
{
|
||||
GstMemory *fdmem = NULL;
|
||||
PinosPacketFDPayload p;
|
||||
FDPayloadData data;
|
||||
int fd;
|
||||
|
||||
GST_DEBUG ("got fd payload");
|
||||
pinos_buffer_iter_parse_fd_payload (&it, &p);
|
||||
fd = pinos_buffer_get_fd (&pbuf, p.fd_index, &error);
|
||||
if (!pinos_buffer_iter_parse_fd_payload (&it, &data.p))
|
||||
goto no_fds;
|
||||
fd = pinos_buffer_get_fd (pbuf, data.p.fd_index, &error);
|
||||
if (fd == -1)
|
||||
goto no_fds;
|
||||
|
||||
fdmem = gst_fd_allocator_alloc (pinossrc->fd_allocator, fd,
|
||||
p.offset + p.size, GST_FD_MEMORY_FLAG_NONE);
|
||||
gst_memory_resize (fdmem, p.offset, p.size);
|
||||
data.p.offset + data.p.size, GST_FD_MEMORY_FLAG_NONE);
|
||||
gst_memory_resize (fdmem, data.p.offset, data.p.size);
|
||||
gst_buffer_append_memory (buf, fdmem);
|
||||
|
||||
data.src = gst_object_ref (pinossrc);
|
||||
gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (fdmem),
|
||||
fdpayload_data_quark,
|
||||
g_slice_dup (FDPayloadData, &data),
|
||||
fdpayload_data_destroy);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
@ -305,8 +353,6 @@ on_new_buffer (GObject *gobject,
|
|||
gst_buffer_unref (pinossrc->current);
|
||||
pinossrc->current = buf;
|
||||
|
||||
pinos_stream_release_buffer (pinossrc->stream, &pbuf);
|
||||
|
||||
pinos_main_loop_signal (pinossrc->loop, FALSE);
|
||||
|
||||
return;
|
||||
|
|
@ -678,7 +724,9 @@ gst_pinos_src_close (GstPinosSrc * pinossrc)
|
|||
g_clear_object (&pinossrc->loop);
|
||||
g_clear_object (&pinossrc->ctx);
|
||||
g_main_context_unref (pinossrc->context);
|
||||
GST_OBJECT_LOCK (pinossrc);
|
||||
g_clear_object (&pinossrc->stream);
|
||||
GST_OBJECT_UNLOCK (pinossrc);
|
||||
|
||||
if (pinossrc->current)
|
||||
gst_buffer_unref (pinossrc->current);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue