diff --git a/src/Makefile.am b/src/Makefile.am index 081d720b8..b1d923b7d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -150,8 +150,8 @@ pinos_monitor_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) # Client library # ################################### -pinosgstsource = gst/gstfdpay.h gst/gstfdpay.c \ - gst/gstfddepay.h gst/gstfddepay.c \ +pinosgstsource = gst/gstpinospay.h gst/gstpinospay.c \ + gst/gstpinosdepay.h gst/gstpinosdepay.c \ gst/gsttmpfileallocator.h gst/gsttmpfileallocator.c \ wire-protocol.h @@ -219,8 +219,8 @@ plugin_LTLIBRARIES = libgstpinos.la libgstpinos_la_SOURCES = \ gst/gstpinos.c \ - gst/gstfdpay.c \ - gst/gstfddepay.c \ + gst/gstpinospay.c \ + gst/gstpinosdepay.c \ gst/gstpinosdeviceprovider.c \ gst/gstpinossrc.c \ gst/gstpinossink.c @@ -231,7 +231,7 @@ libgstpinos_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS) $(GLIB_LIBS) $(LIBM) -lgst libpinos-@PINOS_MAJORMINOR@.la libpinoscore-@PINOS_MAJORMINOR@.la libgstpinos_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS) -noinst_HEADERS = gst/gstpinossrc.h gst/gstpinossink.h gst/gstfdpay.h gst/gstfddepay.h gst/gstpinosdeviceprovider.h +noinst_HEADERS = gst/gstpinossrc.h gst/gstpinossink.h gst/gstpinospay.h gst/gstpinosdepay.h gst/gstpinosdeviceprovider.h ################################### # Some minor stuff # diff --git a/src/client/buffer.c b/src/client/buffer.c index 4015554f8..76a43b662 100644 --- a/src/client/buffer.c +++ b/src/client/buffer.c @@ -30,18 +30,30 @@ G_STATIC_ASSERT (sizeof (PinosStackBuffer) <= sizeof (PinosBuffer)); +/** + * pinos_buffer_init_data: + * @buffer: a #PinosBuffer + * @data: data + * @size: size of @data + * @message: (transfer full): a #GSocketControlMessage + * + * Initialize @buffer with @data and @size and @message. @data and size + * must not be modified until pinos_buffer_clear() is called. + * + * Ownership is taken of @message. + */ void -pinos_buffer_init_take_data (PinosBuffer *buffer, - gpointer data, - gsize size, - GSocketControlMessage *message) +pinos_buffer_init_data (PinosBuffer *buffer, + gpointer data, + gsize size, + GSocketControlMessage *message) { PinosStackBuffer *sb = PSB (buffer); sb->magic = PSB_MAGIC; sb->data = data; sb->size = size; - sb->allocated_size = size; + sb->allocated_size = 0; sb->message = message; } @@ -52,7 +64,9 @@ pinos_buffer_clear (PinosBuffer *buffer) g_return_val_if_fail (is_valid_buffer (buffer), -1); - g_free (sb->data); + sb->magic = 0; + if (sb->allocated_size) + g_free (sb->data); sb->size = 0; sb->allocated_size = 0; g_clear_object (&sb->message); @@ -120,59 +134,39 @@ not_found: } /** - * pinos_buffer_get_socket_control_message: + * pinos_buffer_steal_data: * @buffer: a #PinosBuffer + * @size: output size + * @message: output #GSocketControlMessage * - * Get the #GSocketControlMessage of @buffer + * Take the data and control message from @buffer. * - * Returns: the #GSocketControlMessage it remains valid as long as @buffer - * is valid + * Returns: the data of @buffer. */ -GSocketControlMessage * -pinos_buffer_get_socket_control_message (PinosBuffer *buffer) -{ - PinosStackBuffer *sb = PSB (buffer); - - g_return_val_if_fail (is_valid_buffer (buffer), NULL); - - return sb->message; -} - -/** - * pinos_buffer_get_size: - * @buffer: a #PinosBuffer - * - * Get the total size needed to store @buffer with pinos_buffer_store(). - * - * Returns: the serialized size of @buffer. - */ -gsize -pinos_buffer_get_size (PinosBuffer *buffer) +gpointer +pinos_buffer_steal (PinosBuffer *buffer, + gsize *size, + GSocketControlMessage **message) { PinosStackBuffer *sb = PSB (buffer); + gpointer data; g_return_val_if_fail (is_valid_buffer (buffer), 0); - return sizeof (PinosStackHeader) + sb->size; -} + if (size) + *size = sb->size; + if (message) + *message = sb->message; -/** - * pinos_buffer_store: - * @buffer: a #PinosBuffer - * @data: destination - * - * Store the contents of @buffer in @data. @data must be large enough, see - * pinos_buffer_get_size(). - */ -void -pinos_buffer_store (PinosBuffer *buffer, - gpointer data) -{ - PinosStackBuffer *sb = PSB (buffer); + data = sb->data; - g_return_val_if_fail (is_valid_buffer (buffer), 0); + sb->magic = 0; + sb->data = NULL; + sb->size = 0; + sb->allocated_size = 0; + sb->message = NULL; - memcpy (data, sb->data, sizeof (PinosStackHeader) + sb->size); + return data; } /** diff --git a/src/client/buffer.h b/src/client/buffer.h index d3e126eb1..b980d3cc7 100644 --- a/src/client/buffer.h +++ b/src/client/buffer.h @@ -44,7 +44,7 @@ struct _PinosBuffer { gsize x[16]; }; -void pinos_buffer_init_take_data (PinosBuffer *buffer, +void pinos_buffer_init_data (PinosBuffer *buffer, gpointer data, gsize size, GSocketControlMessage *message); @@ -57,12 +57,10 @@ const PinosBufferHeader * int pinos_buffer_get_fd (PinosBuffer *buffer, gint index, GError **error); -GSocketControlMessage * - pinos_buffer_get_socket_control_message (PinosBuffer *buffer); -gsize pinos_buffer_get_size (PinosBuffer *buffer); -void pinos_buffer_store (PinosBuffer *buffer, - gpointer data); +gpointer pinos_buffer_steal (PinosBuffer *buffer, + gsize *size, + GSocketControlMessage **message); typedef enum { diff --git a/src/gst/gstfddepay.c b/src/gst/gstfddepay.c deleted file mode 100644 index 675b5f31b..000000000 --- a/src/gst/gstfddepay.c +++ /dev/null @@ -1,233 +0,0 @@ -/* GStreamer - * Copyright (C) 2014 William Manley - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Suite 500, - * Boston, MA 02110-1335, USA. - */ -/** - * SECTION:element-gstfddepay - * - * The fddepay element does FIXME stuff. - * - * - * Example launch line - * |[ - * gst-launch -v fakesrc ! fddepay ! FIXME ! fakesink - * ]| - * FIXME Describe what the pipeline does. - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "gstfddepay.h" -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -GST_DEBUG_CATEGORY_STATIC (gst_fddepay_debug_category); -#define GST_CAT_DEFAULT gst_fddepay_debug_category - -/* prototypes */ - - -static GstCaps *gst_fddepay_transform_caps (GstBaseTransform * trans, - GstPadDirection direction, GstCaps * caps, GstCaps * filter); -static void gst_fddepay_dispose (GObject * object); - -static GstFlowReturn gst_fddepay_transform_ip (GstBaseTransform * trans, - GstBuffer * buf); - -/* pad templates */ - -static GstStaticCaps fd_caps = GST_STATIC_CAPS ("application/x-fd"); - -static GstStaticPadTemplate gst_fddepay_src_template = -GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); - -static GstStaticPadTemplate gst_fddepay_sink_template = -GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("application/x-fd")); - - -/* class initialization */ - -G_DEFINE_TYPE_WITH_CODE (GstFddepay, gst_fddepay, GST_TYPE_BASE_TRANSFORM, - GST_DEBUG_CATEGORY_INIT (gst_fddepay_debug_category, "fddepay", 0, - "debug category for fddepay element")); - -static void -gst_fddepay_class_init (GstFddepayClass * klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GstBaseTransformClass *base_transform_class = - GST_BASE_TRANSFORM_CLASS (klass); - - /* Setting up pads and setting metadata should be moved to - base_class_init if you intend to subclass this class. */ - gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass), - gst_static_pad_template_get (&gst_fddepay_src_template)); - gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass), - gst_static_pad_template_get (&gst_fddepay_sink_template)); - - gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass), - "Simple FD Deplayloder", "Generic", - "Simple File-descriptor Depayloader for zero-copy video IPC", - "William Manley "); - - gobject_class->dispose = gst_fddepay_dispose; - base_transform_class->transform_caps = - GST_DEBUG_FUNCPTR (gst_fddepay_transform_caps); - base_transform_class->transform_ip = - GST_DEBUG_FUNCPTR (gst_fddepay_transform_ip); - -} - -static void -gst_fddepay_init (GstFddepay * fddepay) -{ - fddepay->fd_allocator = gst_fd_allocator_new (); -} - -void -gst_fddepay_dispose (GObject * object) -{ - GstFddepay *fddepay = GST_FDDEPAY (object); - - GST_DEBUG_OBJECT (fddepay, "dispose"); - - /* clean up as possible. may be called multiple times */ - if (fddepay->fd_allocator != NULL) { - g_object_unref (G_OBJECT (fddepay->fd_allocator)); - fddepay->fd_allocator = NULL; - } - - G_OBJECT_CLASS (gst_fddepay_parent_class)->dispose (object); -} - -static GstCaps * -gst_fddepay_transform_caps (GstBaseTransform * trans, GstPadDirection direction, - GstCaps * caps, GstCaps * filter) -{ - GstFddepay *fddepay = GST_FDDEPAY (trans); - GstCaps *othercaps; - - GST_DEBUG_OBJECT (fddepay, "transform_caps"); - - - if (direction == GST_PAD_SRC) { - /* transform caps going upstream */ - othercaps = gst_static_caps_get (&fd_caps); - } else { - /* transform caps going downstream */ - othercaps = gst_caps_new_any (); - } - - if (filter) { - GstCaps *intersect; - - intersect = gst_caps_intersect (othercaps, filter); - gst_caps_unref (othercaps); - - return intersect; - } else { - return othercaps; - } -} - -static GstFlowReturn -gst_fddepay_transform_ip (GstBaseTransform * trans, GstBuffer * buf) -{ - GstFddepay *fddepay = GST_FDDEPAY (trans); - PinosBuffer pbuf; - PinosBufferIter it; - GstNetControlMessageMeta * meta; - GSocketControlMessage *msg = NULL; - const PinosBufferHeader *hdr; - gpointer data; - gsize size; - GError *err = NULL; - - GST_DEBUG_OBJECT (fddepay, "transform_ip"); - - gst_buffer_extract_dup (buf, 0, gst_buffer_get_size (buf), &data, &size); - - meta = ((GstNetControlMessageMeta*) gst_buffer_get_meta ( - buf, GST_NET_CONTROL_MESSAGE_META_API_TYPE)); - - if (meta) { - msg = meta->message; - gst_buffer_remove_meta (buf, (GstMeta *) meta); - meta = NULL; - } - - pinos_buffer_init_take_data (&pbuf, data, size, msg); - - gst_buffer_remove_all_memory (buf); - - pinos_buffer_iter_init (&it, &pbuf); - while (pinos_buffer_iter_next (&it)) { - switch (pinos_buffer_iter_get_type (&it)) { - case PINOS_PACKET_TYPE_FD_PAYLOAD: - { - GstMemory *fdmem = NULL; - PinosPacketFDPayload p; - int fd; - - pinos_buffer_iter_parse_fd_payload (&it, &p); - fd = pinos_buffer_get_fd (&pbuf, p.fd_index, &err); - if (fd == -1) - goto error; - - fdmem = gst_fd_allocator_alloc (fddepay->fd_allocator, fd, - p.offset + p.size, GST_FD_MEMORY_FLAG_NONE); - gst_memory_resize (fdmem, p.offset, p.size); - gst_buffer_append_memory (buf, fdmem); - break; - } - default: - break; - } - } - hdr = pinos_buffer_get_header (&pbuf, NULL); - GST_BUFFER_OFFSET (buf) = hdr->seq; - - return GST_FLOW_OK; - -error: - { - GST_ELEMENT_ERROR (fddepay, RESOURCE, SETTINGS, (NULL), - ("can't get fd: %s", err->message)); - g_clear_error (&err); - return GST_FLOW_ERROR; - } -} diff --git a/src/gst/gstfdpay.c b/src/gst/gstfdpay.c deleted file mode 100644 index 5bc981f77..000000000 --- a/src/gst/gstfdpay.c +++ /dev/null @@ -1,297 +0,0 @@ -/* GStreamer - * Copyright (C) 2014 William Manley - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Suite 500, - * Boston, MA 02110-1335, USA. - */ -/** - * SECTION:element-gstfdpay - * - * The tmpfilepay element enables zero-copy passing of buffers between - * processes by allocating memory in a temporary file. This is a proof of - * concept example. - * - * - * Example launch line - * |[ - * gst-launch-1.0 -v videotestsrc ! video/x-raw,format=RGB,width=1920,height=1080 \ - * ! fdpay ! fdsink fd=1 \ - * | gst-launch-1.0 fdsrc fd=0 ! fddepay \ - * ! video/x-raw,format=RGB,width=1920,height=1080 ! autovideosink - * ]| - * Video frames are created in the first gst-launch-1.0 process and displayed - * by the second with no copying. - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include "gstfdpay.h" -#include "gsttmpfileallocator.h" - -#include -#include - -#include -#include -#include - -#include - -GST_DEBUG_CATEGORY_STATIC (gst_fdpay_debug_category); -#define GST_CAT_DEFAULT gst_fdpay_debug_category - -#define GST_UNREF(x) \ - do { \ - if ( x ) \ - gst_object_unref ( x ); \ - x = NULL; \ - } while (0); - - -/* prototypes */ - -static void gst_fdpay_dispose (GObject * object); - -static GstCaps *gst_fdpay_transform_caps (GstBaseTransform * trans, - GstPadDirection direction, GstCaps * caps, GstCaps * filter); -static gboolean gst_fdpay_transform_size (GstBaseTransform *trans, - GstPadDirection direction, GstCaps *caps, gsize size, GstCaps *othercaps, - gsize *othersize); -static gboolean gst_fdpay_propose_allocation (GstBaseTransform * trans, - GstQuery * decide_query, GstQuery * query); -static GstFlowReturn gst_fdpay_transform (GstBaseTransform * trans, - GstBuffer * inbuf, GstBuffer * outbuf); - -/* pad templates */ - -static GstStaticCaps fd_caps = GST_STATIC_CAPS ("application/x-fd"); - -static GstStaticPadTemplate gst_fdpay_src_template = -GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("application/x-fd")); - -static GstStaticPadTemplate gst_fdpay_sink_template = -GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); - - -/* class initialization */ - -G_DEFINE_TYPE_WITH_CODE (GstFdpay, gst_fdpay, GST_TYPE_BASE_TRANSFORM, - GST_DEBUG_CATEGORY_INIT (gst_fdpay_debug_category, "fdpay", 0, - "debug category for fdpay element")); - -static void -gst_fdpay_class_init (GstFdpayClass * klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GstBaseTransformClass *base_transform_class = - GST_BASE_TRANSFORM_CLASS (klass); - - /* Setting up pads and setting metadata should be moved to - base_class_init if you intend to subclass this class. */ - gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass), - gst_static_pad_template_get (&gst_fdpay_src_template)); - gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass), - gst_static_pad_template_get (&gst_fdpay_sink_template)); - - gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass), - "Simple FD Payloader", "Generic", - "Simple File-descriptor Payloader for zero-copy video IPC", - "William Manley "); - - gobject_class->dispose = gst_fdpay_dispose; - base_transform_class->transform_caps = - GST_DEBUG_FUNCPTR (gst_fdpay_transform_caps); - base_transform_class->propose_allocation = - GST_DEBUG_FUNCPTR (gst_fdpay_propose_allocation); - base_transform_class->transform = - GST_DEBUG_FUNCPTR (gst_fdpay_transform); - base_transform_class->transform_size = - GST_DEBUG_FUNCPTR (gst_fdpay_transform_size); -} - -static void -gst_fdpay_init (GstFdpay * fdpay) -{ - fdpay->allocator = gst_tmpfile_allocator_new (); -} - -void -gst_fdpay_dispose (GObject * object) -{ - GstFdpay *fdpay = GST_FDPAY (object); - - GST_DEBUG_OBJECT (fdpay, "dispose"); - - /* clean up as possible. may be called multiple times */ - GST_UNREF(fdpay->allocator); - - G_OBJECT_CLASS (gst_fdpay_parent_class)->dispose (object); -} - -static GstCaps * -gst_fdpay_transform_caps (GstBaseTransform * trans, GstPadDirection direction, - GstCaps * caps, GstCaps * filter) -{ - GstFdpay *fdpay = GST_FDPAY (trans); - GstCaps *othercaps; - - GST_DEBUG_OBJECT (fdpay, "transform_caps"); - - - if (direction == GST_PAD_SRC) { - /* transform caps going upstream */ - othercaps = gst_caps_new_any (); - } else { - /* transform caps going downstream */ - othercaps = gst_static_caps_get (&fd_caps); - } - - if (filter) { - GstCaps *intersect; - - intersect = gst_caps_intersect (othercaps, filter); - gst_caps_unref (othercaps); - - return intersect; - } else { - return othercaps; - } -} - -static gboolean -gst_fdpay_transform_size (GstBaseTransform *trans, GstPadDirection direction, - GstCaps *caps, gsize size, GstCaps *othercaps, gsize *othersize) -{ - if (direction == GST_PAD_SRC) { - /* transform size going upstream - don't know how to do this */ - return FALSE; - } else { - /* transform size going downstream */ - *othersize = sizeof (PinosBuffer) + 30; - } - - return TRUE; -} - -/* propose allocation query parameters for input buffers */ -static gboolean -gst_fdpay_propose_allocation (GstBaseTransform * trans, - GstQuery * decide_query, GstQuery * query) -{ - GstFdpay *fdpay = GST_FDPAY (trans); - - GST_DEBUG_OBJECT (fdpay, "propose_allocation"); - - gst_query_add_allocation_param (query, fdpay->allocator, NULL); - - return TRUE; -} - -static GstMemory * -gst_fdpay_get_fd_memory (GstFdpay * tmpfilepay, GstBuffer * buffer) -{ - GstMemory *mem = NULL; - - if (gst_buffer_n_memory (buffer) == 1 - && gst_is_fd_memory (gst_buffer_peek_memory (buffer, 0))) - mem = gst_buffer_get_memory (buffer, 0); - else { - GstMapInfo info; - GstAllocationParams params = {0, 0, 0, 0, { NULL, }}; - gsize size = gst_buffer_get_size (buffer); - GST_INFO_OBJECT (tmpfilepay, "Buffer cannot be payloaded without copying"); - mem = gst_allocator_alloc (tmpfilepay->allocator, size, ¶ms); - if (!gst_memory_map (mem, &info, GST_MAP_WRITE)) - return NULL; - gst_buffer_extract (buffer, 0, info.data, size); - gst_memory_unmap (mem, &info); - } - return mem; -} - -static GstFlowReturn -gst_fdpay_transform (GstBaseTransform * trans, GstBuffer * inbuf, - GstBuffer * outbuf) -{ - GstFdpay *fdpay = GST_FDPAY (trans); - GstMemory *fdmem = NULL; - GstMapInfo info; - GError *err = NULL; - PinosBuffer pbuf; - PinosBufferBuilder builder; - PinosBufferHeader hdr; - PinosPacketFDPayload p; - gsize size; - - GST_DEBUG_OBJECT (fdpay, "transform_ip"); - - fdmem = gst_fdpay_get_fd_memory (fdpay, inbuf); - - hdr.flags = 0; - hdr.seq = GST_BUFFER_OFFSET (inbuf); - hdr.pts = GST_BUFFER_TIMESTAMP (inbuf) + GST_ELEMENT_CAST (trans)->base_time; - hdr.dts_offset = 0; - - pinos_buffer_builder_init (&builder); - pinos_buffer_builder_set_header (&builder, &hdr); - - 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.id = 0; - 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; - - gst_buffer_add_net_control_message_meta (outbuf, - pinos_buffer_get_socket_control_message (&pbuf)); - - size = pinos_buffer_get_size (&pbuf); - - gst_buffer_map (outbuf, &info, GST_MAP_WRITE); - pinos_buffer_store (&pbuf, info.data); - gst_buffer_unmap (outbuf, &info); - gst_buffer_resize (outbuf, 0, size); - - pinos_buffer_clear (&pbuf); - - return GST_FLOW_OK; - - /* ERRORS */ -add_fd_failed: - { - GST_WARNING_OBJECT (trans, "Adding fd failed: %s", err->message); - gst_memory_unref(fdmem); - g_clear_error (&err); - - return GST_FLOW_ERROR; - } -} diff --git a/src/gst/gstfdpay.h b/src/gst/gstfdpay.h deleted file mode 100644 index f506ac57c..000000000 --- a/src/gst/gstfdpay.h +++ /dev/null @@ -1,49 +0,0 @@ -/* GStreamer - * Copyright (C) 2014 William Manley - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef _GST_FDPAY_H_ -#define _GST_FDPAY_H_ - -#include - -G_BEGIN_DECLS -#define GST_TYPE_FDPAY (gst_fdpay_get_type()) -#define GST_FDPAY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FDPAY,GstFdpay)) -#define GST_FDPAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FDPAY,GstFdpayClass)) -#define GST_IS_FDPAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FDPAY)) -#define GST_IS_FDPAY_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FDPAY)) -typedef struct _GstFdpay GstFdpay; -typedef struct _GstFdpayClass GstFdpayClass; - -struct _GstFdpay -{ - GstBaseTransform base_fdpay; - GstAllocator * allocator; - -}; - -struct _GstFdpayClass -{ - GstBaseTransformClass base_fdpay_class; -}; - -GType gst_fdpay_get_type (void); - -G_END_DECLS -#endif diff --git a/src/gst/gstpinos.c b/src/gst/gstpinos.c index 37fa2b895..8bf1ca327 100644 --- a/src/gst/gstpinos.c +++ b/src/gst/gstpinos.c @@ -35,18 +35,18 @@ #include "gstpinossrc.h" #include "gstpinossink.h" #include "gstpinosdeviceprovider.h" -#include "gstfdpay.h" -#include "gstfddepay.h" +#include "gstpinospay.h" +#include "gstpinosdepay.h" GST_DEBUG_CATEGORY (pinos_debug); static gboolean plugin_init (GstPlugin * plugin) { - gst_element_register (plugin, "pinosfdpay", GST_RANK_NONE, - GST_TYPE_FDPAY); - gst_element_register (plugin, "pinosfddepay", GST_RANK_NONE, - GST_TYPE_FDDEPAY); + gst_element_register (plugin, "pinospay", GST_RANK_NONE, + GST_TYPE_PINOS_PAY); + gst_element_register (plugin, "pinosdepay", GST_RANK_NONE, + GST_TYPE_PINOS_DEPAY); gst_element_register (plugin, "pinossrc", GST_RANK_PRIMARY + 1, GST_TYPE_PINOS_SRC); gst_element_register (plugin, "pinossink", GST_RANK_NONE, diff --git a/src/gst/gstpinosdepay.c b/src/gst/gstpinosdepay.c new file mode 100644 index 000000000..757df8735 --- /dev/null +++ b/src/gst/gstpinosdepay.c @@ -0,0 +1,192 @@ +/* GStreamer + * Copyright (C) 2014 William Manley + * (C) 2015 Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Suite 500, + * Boston, MA 02110-1335, USA. + */ +/** + * SECTION:element-gstpinosdepay + * + * The pinosdepay element does FIXME stuff. + * + * + * Example launch line + * |[ + * gst-launch -v fakesrc ! pinosdepay ! FIXME ! fakesink + * ]| + * FIXME Describe what the pipeline does. + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstpinosdepay.h" +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +GST_DEBUG_CATEGORY_STATIC (gst_pinos_depay_debug_category); +#define GST_CAT_DEFAULT gst_pinos_depay_debug_category + +/* prototypes */ + + +/* pad templates */ +static GstStaticPadTemplate gst_pinos_depay_src_template = +GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS_ANY); + +static GstStaticPadTemplate gst_pinos_depay_sink_template = +GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("application/x-pinos")); + + +/* class initialization */ + +G_DEFINE_TYPE_WITH_CODE (GstPinosDepay, gst_pinos_depay, GST_TYPE_ELEMENT, + GST_DEBUG_CATEGORY_INIT (gst_pinos_depay_debug_category, "pinosdepay", 0, + "debug category for pinosdepay element")); + +static GstFlowReturn +gst_pinos_depay_chain (GstPad *pad, GstObject * parent, GstBuffer * buffer) +{ + GstPinosDepay *depay = GST_PINOS_DEPAY (parent); + GstBuffer *outbuf; + GstMapInfo info; + PinosBuffer pbuf; + 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; + gst_buffer_remove_meta (buffer, (GstMeta *) meta); + meta = NULL; + } + + outbuf = gst_buffer_new (); + + gst_buffer_map (buffer, &info, GST_MAP_READ); + pinos_buffer_init_data (&pbuf, info.data, info.size, msg); + + pinos_buffer_iter_init (&it, &pbuf); + while (pinos_buffer_iter_next (&it)) { + switch (pinos_buffer_iter_get_type (&it)) { + case PINOS_PACKET_TYPE_FD_PAYLOAD: + { + GstMemory *fdmem = NULL; + PinosPacketFDPayload p; + int fd; + + pinos_buffer_iter_parse_fd_payload (&it, &p); + fd = pinos_buffer_get_fd (&pbuf, p.fd_index, &err); + if (fd == -1) + goto error; + + fdmem = gst_fd_allocator_alloc (depay->fd_allocator, fd, + p.offset + p.size, GST_FD_MEMORY_FLAG_NONE); + gst_memory_resize (fdmem, p.offset, p.size); + gst_buffer_append_memory (outbuf, fdmem); + break; + } + default: + 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); + + return gst_pad_push (depay->srcpad, outbuf); + +error: + { + GST_ELEMENT_ERROR (depay, RESOURCE, SETTINGS, (NULL), + ("can't get fd: %s", err->message)); + g_clear_error (&err); + return GST_FLOW_ERROR; + } +} + +static void +gst_pinos_depay_finalize (GObject * object) +{ + GstPinosDepay *depay = GST_PINOS_DEPAY (object); + + GST_DEBUG_OBJECT (depay, "finalize"); + + g_object_unref (depay->fd_allocator); + + G_OBJECT_CLASS (gst_pinos_depay_parent_class)->finalize (object); +} + +static void +gst_pinos_depay_class_init (GstPinosDepayClass * klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GstElementClass *element_class = + GST_ELEMENT_CLASS (klass); + + /* Setting up pads and setting metadata should be moved to + base_class_init if you intend to subclass this class. */ + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_pinos_depay_src_template)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_pinos_depay_sink_template)); + + gst_element_class_set_static_metadata (element_class, + "Pinos Deplayloder", "Generic", + "Pinos Depayloader for zero-copy IPC via Pinos", + "Wim Taymans "); + + gobject_class->finalize = gst_pinos_depay_finalize; +} + +static void +gst_pinos_depay_init (GstPinosDepay * depay) +{ + depay->srcpad = gst_pad_new_from_static_template (&gst_pinos_depay_src_template, "src"); + gst_element_add_pad (GST_ELEMENT (depay), depay->srcpad); + + depay->sinkpad = gst_pad_new_from_static_template (&gst_pinos_depay_sink_template, "sink"); + gst_pad_set_chain_function (depay->sinkpad, gst_pinos_depay_chain); + gst_element_add_pad (GST_ELEMENT (depay), depay->sinkpad); + + depay->fd_allocator = gst_fd_allocator_new (); +} + diff --git a/src/gst/gstfddepay.h b/src/gst/gstpinosdepay.h similarity index 50% rename from src/gst/gstfddepay.h rename to src/gst/gstpinosdepay.h index d74ed6998..a5af71138 100644 --- a/src/gst/gstfddepay.h +++ b/src/gst/gstpinosdepay.h @@ -1,5 +1,6 @@ /* GStreamer * Copyright (C) 2014 William Manley + * Copyright (C) 2015 Wim Taymans * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -17,32 +18,37 @@ * Boston, MA 02110-1301, USA. */ -#ifndef _GST_FDDEPAY_H_ -#define _GST_FDDEPAY_H_ +#ifndef _GST_PINOS_DEPAY_H_ +#define _GST_PINOS_DEPAY_H_ -#include +#include G_BEGIN_DECLS -#define GST_TYPE_FDDEPAY (gst_fddepay_get_type()) -#define GST_FDDEPAY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FDDEPAY,GstFddepay)) -#define GST_FDDEPAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FDDEPAY,GstFddepayClass)) -#define GST_IS_FDDEPAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FDDEPAY)) -#define GST_IS_FDDEPAY_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FDDEPAY)) -typedef struct _GstFddepay GstFddepay; -typedef struct _GstFddepayClass GstFddepayClass; -struct _GstFddepay +#define GST_TYPE_PINOS_DEPAY (gst_pinos_depay_get_type()) +#define GST_PINOS_DEPAY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PINOS_DEPAY,GstPinosDepay)) +#define GST_PINOS_DEPAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_PINOS_DEPAY,GstPinosDepayClass)) +#define GST_IS_PINOS_DEPAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PINOS_DEPAY)) +#define GST_IS_PINOS_DEPAY_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PINOS_DEPAY)) + +typedef struct _GstPinosDepay GstPinosDepay; +typedef struct _GstPinosDepayClass GstPinosDepayClass; + +struct _GstPinosDepay { - GstBaseTransform base_fddepay; + GstElement parent; + + GstPad *srcpad, *sinkpad; GstAllocator *fd_allocator; }; -struct _GstFddepayClass +struct _GstPinosDepayClass { - GstBaseTransformClass base_fddepay_class; + GstElementClass parent_class; }; -GType gst_fddepay_get_type (void); +GType gst_pinos_depay_get_type (void); G_END_DECLS + #endif diff --git a/src/gst/gstpinospay.c b/src/gst/gstpinospay.c new file mode 100644 index 000000000..9c016d548 --- /dev/null +++ b/src/gst/gstpinospay.c @@ -0,0 +1,254 @@ +/* GStreamer + * Copyright (C) 2014 William Manley + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Suite 500, + * Boston, MA 02110-1335, USA. + */ +/** + * SECTION:element-gstpinospay + * + * The pinospay element converts regular GStreamer buffers into the format + * expected by Pinos. + * + * + * Example launch line + * |[ + * gst-launch-1.0 -v videotestsrc ! video/x-raw,format=RGB,width=1920,height=1080 \ + * ! pinospay ! fdsink fd=1 \ + * | gst-launch-1.0 fdsrc fd=0 ! fddepay \ + * ! video/x-raw,format=RGB,width=1920,height=1080 ! autovideosink + * ]| + * Video frames are created in the first gst-launch-1.0 process and displayed + * by the second with no copying. + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include "gstpinospay.h" +#include "gsttmpfileallocator.h" + +#include +#include + +#include +#include +#include + +#include + +GST_DEBUG_CATEGORY_STATIC (gst_pinos_pay_debug_category); +#define GST_CAT_DEFAULT gst_pinos_pay_debug_category + +/* prototypes */ + +/* pad templates */ +static GstStaticPadTemplate gst_pinos_pay_src_template = +GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("application/x-pinos")); + +static GstStaticPadTemplate gst_pinos_pay_sink_template = +GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS_ANY); + +/* class initialization */ + +G_DEFINE_TYPE_WITH_CODE (GstPinosPay, gst_pinos_pay, GST_TYPE_ELEMENT, + GST_DEBUG_CATEGORY_INIT (gst_pinos_pay_debug_category, "pinospay", 0, + "debug category for pinospay element")); + +/* propose allocation query parameters for input buffers */ +static gboolean +gst_pinos_pay_query (GstPad * pad, GstObject * parent, GstQuery * query) +{ + GstPinosPay *pay = GST_PINOS_PAY (parent); + gboolean res = FALSE; + + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_ALLOCATION: + { + GST_DEBUG_OBJECT (pay, "propose_allocation"); + gst_query_add_allocation_param (query, pay->allocator, NULL); + res = TRUE; + break; + } + default: + res = gst_pad_query_default (pad, parent, query); + break; + } + return res; +} + +static gboolean +gst_pinos_pay_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) +{ + GstPinosPay *pay = GST_PINOS_PAY (parent); + gboolean res = FALSE; + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_CAPS: + { + GstCaps *caps; + + caps = gst_caps_new_empty_simple ("application/x-pinos"); + res = gst_pad_push_event (pay->srcpad, gst_event_new_caps (caps)); + gst_caps_unref (caps); + gst_event_unref (event); + break; + } + default: + res = gst_pad_event_default (pad, parent, event); + break; + } + return res; +} + +static GstMemory * +gst_pinos_pay_get_fd_memory (GstPinosPay * tmpfilepay, GstBuffer * buffer) +{ + GstMemory *mem = NULL; + + if (gst_buffer_n_memory (buffer) == 1 + && gst_is_fd_memory (gst_buffer_peek_memory (buffer, 0))) + mem = gst_buffer_get_memory (buffer, 0); + else { + GstMapInfo info; + GstAllocationParams params = {0, 0, 0, 0, { NULL, }}; + gsize size = gst_buffer_get_size (buffer); + GST_INFO_OBJECT (tmpfilepay, "Buffer cannot be payloaded without copying"); + mem = gst_allocator_alloc (tmpfilepay->allocator, size, ¶ms); + if (!gst_memory_map (mem, &info, GST_MAP_WRITE)) + return NULL; + gst_buffer_extract (buffer, 0, info.data, size); + gst_memory_unmap (mem, &info); + } + return mem; +} + +static GstFlowReturn +gst_pinos_pay_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer) +{ + GstPinosPay *pay = GST_PINOS_PAY (parent); + GstMemory *fdmem = NULL; + GError *err = NULL; + GstBuffer *outbuf; + PinosBuffer pbuf; + PinosBufferBuilder builder; + PinosBufferHeader hdr; + PinosPacketFDPayload p; + gsize size; + gpointer data; + GSocketControlMessage *msg; + + hdr.flags = 0; + hdr.seq = GST_BUFFER_OFFSET (buffer); + hdr.pts = GST_BUFFER_PTS (buffer) + GST_ELEMENT_CAST (pay)->base_time; + hdr.dts_offset = 0; + + pinos_buffer_builder_init (&builder); + pinos_buffer_builder_set_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); + if (p.fd_index == -1) + goto add_fd_failed; + p.id = 0; + 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); + + outbuf = gst_buffer_new_wrapped (data, size); + GST_BUFFER_PTS (outbuf) = GST_BUFFER_PTS (buffer); + GST_BUFFER_DTS (outbuf) = GST_BUFFER_DTS (buffer); + GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buffer); + GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET (buffer); + GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET_END (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); + g_clear_error (&err); + + return GST_FLOW_ERROR; + } +} +static void +gst_pinos_pay_finalize (GObject * object) +{ + GstPinosPay *pay = GST_PINOS_PAY (object); + + GST_DEBUG_OBJECT (pay, "finalize"); + + g_object_unref (pay->allocator); + + G_OBJECT_CLASS (gst_pinos_pay_parent_class)->finalize (object); +} + +static void +gst_pinos_pay_init (GstPinosPay * pay) +{ + pay->srcpad = gst_pad_new_from_static_template (&gst_pinos_pay_src_template, "src"); + gst_element_add_pad (GST_ELEMENT (pay), pay->srcpad); + + pay->sinkpad = gst_pad_new_from_static_template (&gst_pinos_pay_sink_template, "sink"); + gst_pad_set_chain_function (pay->sinkpad, gst_pinos_pay_chain); + gst_pad_set_event_function (pay->sinkpad, gst_pinos_pay_sink_event); + gst_pad_set_query_function (pay->sinkpad, gst_pinos_pay_query); + gst_element_add_pad (GST_ELEMENT (pay), pay->sinkpad); + + pay->allocator = gst_tmpfile_allocator_new (); +} + +static void +gst_pinos_pay_class_init (GstPinosPayClass * klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_pinos_pay_src_template)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_pinos_pay_sink_template)); + + gst_element_class_set_static_metadata (element_class, + "Pinos Payloader", "Generic", + "Pinos Payloader for zero-copy IPC with Pinos", + "Wim Taymans "); + + gobject_class->finalize = gst_pinos_pay_finalize; +} diff --git a/src/gst/gstpinospay.h b/src/gst/gstpinospay.h new file mode 100644 index 000000000..e1c27c9f4 --- /dev/null +++ b/src/gst/gstpinospay.h @@ -0,0 +1,57 @@ +/* GStreamer + * Copyright (C) 2014 William Manley + * (C) 2015 Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _GST_PINOS_PAY_H_ +#define _GST_PINOS_PAY_H_ + +#include + +G_BEGIN_DECLS + +#define GST_TYPE_PINOS_PAY (gst_pinos_pay_get_type()) +#define GST_PINOS_PAY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PINOS_PAY,GstPinosPay)) +#define GST_PINOS_PAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_PINOS_PAY,GstPinosPayClass)) +#define GST_IS_PINOS_PAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PINOS_PAY)) +#define GST_IS_PINOS_PAY_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PINOS_PAY)) + +typedef struct _GstPinosPay GstPinosPay; +typedef struct _GstPinosPayClass GstPinosPayClass; + +struct _GstPinosPay +{ + GstElement parent; + + gboolean negotiated; + GstPad *srcpad, *sinkpad; + + GstAllocator *allocator; + +}; + +struct _GstPinosPayClass +{ + GstElementClass parent_class; +}; + +GType gst_pinos_pay_get_type (void); + +G_END_DECLS + +#endif diff --git a/src/modules/gst/gst-source.c b/src/modules/gst/gst-source.c index e9623e48f..1dd55d196 100644 --- a/src/modules/gst/gst-source.c +++ b/src/modules/gst/gst-source.c @@ -126,7 +126,7 @@ setup_pipeline (PinosGstSource *source, GError **error) gst_bin_add (GST_BIN (priv->pipeline), priv->filter); gst_element_link (priv->element, priv->filter); - elem = gst_element_factory_make ("pinosfdpay", NULL); + elem = gst_element_factory_make ("pinospay", NULL); gst_bin_add (GST_BIN (priv->pipeline), elem); gst_element_link (priv->filter, elem); diff --git a/src/tests/test-client.c b/src/tests/test-client.c index 49ef5035b..b959b9c50 100644 --- a/src/tests/test-client.c +++ b/src/tests/test-client.c @@ -38,7 +38,7 @@ on_socket_notify (GObject *gobject, GstCaps *caps; GError *error = NULL; - pipeline = gst_parse_launch ("socketsrc name=src ! pinosfddepay ! capsfilter name=filter ! videoconvert ! xvimagesink", &error); + pipeline = gst_parse_launch ("socketsrc name=src ! pinosdepay ! capsfilter name=filter ! videoconvert ! xvimagesink", &error); if (error != NULL) { g_warning ("error creating pipeline: %s", error->message); g_clear_error (&error);