gst/: UDP fixes, added uri handler.
authorWim Taymans <wim.taymans@gmail.com>
Wed, 11 May 2005 07:31:22 +0000 (07:31 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Wed, 11 May 2005 07:31:22 +0000 (07:31 +0000)
Original commit message from CVS:
* gst/rtp/Makefile.am:
* gst/rtp/gstrtp.c: (plugin_init):
* gst/rtp/gstrtpdec.c: (gst_rtpdec_get_type),
(gst_rtpdec_class_init), (gst_rtpdec_init), (gst_rtpdec_chain_rtp),
(gst_rtpdec_chain_rtcp), (gst_rtpdec_set_property),
(gst_rtpdec_get_property), (gst_rtpdec_change_state),
(gst_rtpdec_plugin_init):
* gst/rtp/gstrtpdec.h:
* gst/udp/gstudpsink.c: (gst_udpsink_base_init),
(gst_udpsink_get_times), (gst_udpsink_render),
(gst_udpsink_change_state):
* gst/udp/gstudpsrc.c: (gst_udpsrc_get_type),
(gst_udpsrc_base_init), (gst_udpsrc_class_init), (gst_udpsrc_init),
(gst_udpsrc_loop), (gst_udpsrc_set_uri), (gst_udpsrc_set_property),
(gst_udpsrc_get_property), (gst_udpsrc_init_receive),
(gst_udpsrc_activate), (gst_udpsrc_change_state),
(gst_udpsrc_uri_get_type), (gst_udpsrc_uri_get_protocols),
(gst_udpsrc_uri_get_uri), (gst_udpsrc_uri_set_uri),
(gst_udpsrc_uri_handler_init):
* gst/udp/gstudpsrc.h:
UDP fixes, added uri handler.
Added rtpdec that will manage the RTP session in the future.

ChangeLog
gst/rtp/Makefile.am
gst/rtp/gstrtp.c
gst/rtp/gstrtpdec.c [new file with mode: 0644]
gst/rtp/gstrtpdec.h [new file with mode: 0644]
gst/rtp/gstrtpdepay.c [new file with mode: 0644]
gst/rtp/gstrtpdepay.h [new file with mode: 0644]
gst/udp/gstudpsink.c
gst/udp/gstudpsrc.c
gst/udp/gstudpsrc.h

index 22dabd9..a67e3d5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+2005-05-11  Wim Taymans  <wim@fluendo.com>
+
+       * gst/rtp/Makefile.am:
+       * gst/rtp/gstrtp.c: (plugin_init):
+       * gst/rtp/gstrtpdec.c: (gst_rtpdec_get_type),
+       (gst_rtpdec_class_init), (gst_rtpdec_init), (gst_rtpdec_chain_rtp),
+       (gst_rtpdec_chain_rtcp), (gst_rtpdec_set_property),
+       (gst_rtpdec_get_property), (gst_rtpdec_change_state),
+       (gst_rtpdec_plugin_init):
+       * gst/rtp/gstrtpdec.h:
+       * gst/udp/gstudpsink.c: (gst_udpsink_base_init),
+       (gst_udpsink_get_times), (gst_udpsink_render),
+       (gst_udpsink_change_state):
+       * gst/udp/gstudpsrc.c: (gst_udpsrc_get_type),
+       (gst_udpsrc_base_init), (gst_udpsrc_class_init), (gst_udpsrc_init),
+       (gst_udpsrc_loop), (gst_udpsrc_set_uri), (gst_udpsrc_set_property),
+       (gst_udpsrc_get_property), (gst_udpsrc_init_receive),
+       (gst_udpsrc_activate), (gst_udpsrc_change_state),
+       (gst_udpsrc_uri_get_type), (gst_udpsrc_uri_get_protocols),
+       (gst_udpsrc_uri_get_uri), (gst_udpsrc_uri_set_uri),
+       (gst_udpsrc_uri_handler_init):
+       * gst/udp/gstudpsrc.h:
+       UDP fixes, added uri handler.
+       Added rtpdec that will manage the RTP session in the future.
+
 2005-05-10  Arwed v. Merkatz  <v.merkatz@gmx.net>>
 
        * PORTED_09:
index b705d6b..f23cea2 100644 (file)
@@ -1,7 +1,9 @@
 
 plugin_LTLIBRARIES = libgstrtp.la
 
-libgstrtp_la_SOURCES = gstrtp.c gstrtpL16enc.c gstrtpL16parse.c gstrtpgsmenc.c gstrtpgsmparse.c rtp-packet.c
+libgstrtp_la_SOURCES = gstrtp.c gstrtpdec.c
+
+#gstrtpL16enc.c gstrtpL16parse.c gstrtpgsmenc.c gstrtpgsmparse.c rtp-packet.c
 
 libgstrtp_la_CFLAGS = $(GST_CFLAGS)
 libgstrtp_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
index e16d2e9..8ea85ae 100644 (file)
@@ -1,4 +1,4 @@
-/* Gnome-Streamer
+/* GStreamer
  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
  *
  * This library is free software; you can redistribute it and/or
 #include "config.h"
 #endif
 
-#include "gstrtpL16enc.h"
-#include "gstrtpL16parse.h"
-#include "gstrtpgsmenc.h"
-#include "gstrtpgsmparse.h"
+#include "gstrtpdec.h"
 
 static gboolean
 plugin_init (GstPlugin * plugin)
 {
-  if (!gst_rtpL16enc_plugin_init (plugin) ||
-      !gst_rtpL16parse_plugin_init (plugin) ||
-      !gst_rtpgsmenc_plugin_init (plugin) ||
-      !gst_rtpgsmparse_plugin_init (plugin))
+  if (!gst_rtpdec_plugin_init (plugin))
     return FALSE;
 
   return TRUE;
diff --git a/gst/rtp/gstrtpdec.c b/gst/rtp/gstrtpdec.c
new file mode 100644 (file)
index 0000000..6e7906e
--- /dev/null
@@ -0,0 +1,256 @@
+/* GStreamer
+ * Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/* Element-Checklist-Version: 5 */
+
+#include "gstrtpdec.h"
+
+/* elementfactory information */
+static GstElementDetails rtpdec_details = GST_ELEMENT_DETAILS ("RTP Decoder",
+    "Codec/Parser/Network",
+    "Accepts raw RTP and RTCP packets and sends them forward",
+    "Wim Taymans <wim@fluendo.com>");
+
+/* GstRTPDec signals and args */
+enum
+{
+  /* FILL ME */
+  LAST_SIGNAL
+};
+
+enum
+{
+  ARG_0,
+  ARG_SKIP
+      /* FILL ME */
+};
+
+static GstStaticPadTemplate gst_rtpdec_src_rtp_template =
+GST_STATIC_PAD_TEMPLATE ("srcrtp",
+    GST_PAD_SRC,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS ("application/x-rtp")
+    );
+
+static GstStaticPadTemplate gst_rtpdec_src_rtcp_template =
+GST_STATIC_PAD_TEMPLATE ("srcrtcp",
+    GST_PAD_SRC,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS ("application/x-rtcp")
+    );
+
+static GstStaticPadTemplate gst_rtpdec_sink_rtp_template =
+GST_STATIC_PAD_TEMPLATE ("sinkrtp",
+    GST_PAD_SINK,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS ("application/x-rtp")
+    );
+
+static GstStaticPadTemplate gst_rtpdec_sink_rtcp_template =
+GST_STATIC_PAD_TEMPLATE ("sinkrtcp",
+    GST_PAD_SINK,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS ("application/x-rtcp")
+    );
+
+static void gst_rtpdec_class_init (gpointer g_class);
+static void gst_rtpdec_init (GstRTPDec * rtpdec);
+
+static GstFlowReturn gst_rtpdec_chain_rtp (GstPad * pad, GstBuffer * buffer);
+static GstFlowReturn gst_rtpdec_chain_rtcp (GstPad * pad, GstBuffer * buffer);
+
+static void gst_rtpdec_set_property (GObject * object,
+    guint prop_id, const GValue * value, GParamSpec * pspec);
+static void gst_rtpdec_get_property (GObject * object,
+    guint prop_id, GValue * value, GParamSpec * pspec);
+
+static GstElementStateReturn gst_rtpdec_change_state (GstElement * element);
+
+static GstElementClass *parent_class = NULL;
+
+/*static guint gst_rtpdec_signals[LAST_SIGNAL] = { 0 };*/
+
+GType
+gst_rtpdec_get_type (void)
+{
+  static GType rtpdec_type = 0;
+
+  if (!rtpdec_type) {
+    static const GTypeInfo rtpdec_info = {
+      sizeof (GstRTPDecClass), NULL,
+      NULL,
+      (GClassInitFunc) gst_rtpdec_class_init,
+      NULL,
+      NULL,
+      sizeof (GstRTPDec),
+      0,
+      (GInstanceInitFunc) gst_rtpdec_init,
+    };
+
+    rtpdec_type =
+        g_type_register_static (GST_TYPE_ELEMENT, "GstRTPDec", &rtpdec_info, 0);
+  }
+  return rtpdec_type;
+}
+
+static void
+gst_rtpdec_class_init (gpointer g_class)
+{
+  GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
+  GstRTPDecClass *klass;
+
+  klass = (GstRTPDecClass *) g_class;
+  gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
+
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&gst_rtpdec_src_rtp_template));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&gst_rtpdec_src_rtcp_template));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&gst_rtpdec_sink_rtp_template));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&gst_rtpdec_sink_rtcp_template));
+  gst_element_class_set_details (gstelement_class, &rtpdec_details);
+
+  gobject_class->set_property = gst_rtpdec_set_property;
+  gobject_class->get_property = gst_rtpdec_get_property;
+
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SKIP, g_param_spec_int ("skip", "skip", "skip", G_MININT, G_MAXINT, 0, G_PARAM_READWRITE));      /* CHECKME */
+
+  parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+
+  gstelement_class->change_state = gst_rtpdec_change_state;
+}
+
+static void
+gst_rtpdec_init (GstRTPDec * rtpdec)
+{
+  /* the input rtp pad */
+  rtpdec->sink_rtp =
+      gst_pad_new_from_template (gst_static_pad_template_get
+      (&gst_rtpdec_sink_rtp_template), "sinkrtp");
+  gst_element_add_pad (GST_ELEMENT (rtpdec), rtpdec->sink_rtp);
+  gst_pad_set_chain_function (rtpdec->sink_rtp, gst_rtpdec_chain_rtp);
+
+  /* the input rtcp pad */
+  rtpdec->sink_rtcp =
+      gst_pad_new_from_template (gst_static_pad_template_get
+      (&gst_rtpdec_sink_rtcp_template), "sinkrtcp");
+  gst_element_add_pad (GST_ELEMENT (rtpdec), rtpdec->sink_rtcp);
+  gst_pad_set_chain_function (rtpdec->sink_rtcp, gst_rtpdec_chain_rtcp);
+
+  /* the output rtp pad */
+  rtpdec->src_rtp =
+      gst_pad_new_from_template (gst_static_pad_template_get
+      (&gst_rtpdec_src_rtp_template), "srcrtp");
+  gst_element_add_pad (GST_ELEMENT (rtpdec), rtpdec->src_rtp);
+
+  /* the output rtcp pad */
+  rtpdec->src_rtcp =
+      gst_pad_new_from_template (gst_static_pad_template_get
+      (&gst_rtpdec_src_rtcp_template), "srcrtcp");
+  gst_element_add_pad (GST_ELEMENT (rtpdec), rtpdec->src_rtcp);
+}
+
+static GstFlowReturn
+gst_rtpdec_chain_rtp (GstPad * pad, GstBuffer * buffer)
+{
+  GstRTPDec *src;
+
+  src = GST_RTPDEC (GST_PAD_PARENT (pad));
+
+  g_print ("got rtp packet\n");
+  return gst_pad_push (src->src_rtp, buffer);
+}
+
+static GstFlowReturn
+gst_rtpdec_chain_rtcp (GstPad * pad, GstBuffer * buffer)
+{
+  g_print ("got rtcp packet\n");
+  return GST_FLOW_OK;
+}
+
+static void
+gst_rtpdec_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstRTPDec *src;
+
+  src = GST_RTPDEC (object);
+
+  switch (prop_id) {
+    case ARG_SKIP:
+      break;
+    default:
+      break;
+  }
+}
+
+static void
+gst_rtpdec_get_property (GObject * object, guint prop_id, GValue * value,
+    GParamSpec * pspec)
+{
+  GstRTPDec *src;
+
+  src = GST_RTPDEC (object);
+
+  switch (prop_id) {
+    case ARG_SKIP:
+      break;
+    default:
+      break;
+  }
+}
+
+static GstElementStateReturn
+gst_rtpdec_change_state (GstElement * element)
+{
+  GstElementStateReturn ret;
+  GstRTPDec *rtpdec;
+  gint transition;
+
+  rtpdec = GST_RTPDEC (element);
+  transition = GST_STATE_TRANSITION (element);
+
+  switch (transition) {
+    case GST_STATE_PAUSED_TO_READY:
+      break;
+    default:
+      break;
+  }
+
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
+  switch (transition) {
+    case GST_STATE_PAUSED_TO_READY:
+      break;
+    default:
+      break;
+  }
+
+  return ret;
+}
+
+gboolean
+gst_rtpdec_plugin_init (GstPlugin * plugin)
+{
+  return gst_element_register (plugin, "rtpdec",
+      GST_RANK_NONE, GST_TYPE_RTPDEC);
+}
diff --git a/gst/rtp/gstrtpdec.h b/gst/rtp/gstrtpdec.h
new file mode 100644 (file)
index 0000000..5d75e46
--- /dev/null
@@ -0,0 +1,55 @@
+/* GStreamer
+ * Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GST_RTPDEC_H__
+#define __GST_RTPDEC_H__
+
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_RTPDEC                (gst_rtpdec_get_type())
+#define GST_IS_RTPDEC(obj)             (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTPDEC))
+#define GST_IS_RTPDEC_CLASS(obj)       (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTPDEC))
+#define GST_RTPDEC(obj)                (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTPDEC, GstRTPDec))
+#define GST_RTPDEC_CLASS(klass)        (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTPDEC, GstRTPDecClass))
+
+typedef struct _GstRTPDec GstRTPDec;
+typedef struct _GstRTPDecClass GstRTPDecClass;
+
+struct _GstRTPDec {
+  GstElement element;
+
+  GstPad *sink_rtp;
+  GstPad *sink_rtcp;
+  GstPad *src_rtp;
+  GstPad *src_rtcp;
+};
+
+struct _GstRTPDecClass {
+  GstElementClass parent_class;
+};
+
+gboolean gst_rtpdec_plugin_init (GstPlugin * plugin);
+
+GType gst_rtpdec_get_type(void);
+
+G_END_DECLS
+
+#endif /* __GST_RTPDEC_H__ */
diff --git a/gst/rtp/gstrtpdepay.c b/gst/rtp/gstrtpdepay.c
new file mode 100644 (file)
index 0000000..6e7906e
--- /dev/null
@@ -0,0 +1,256 @@
+/* GStreamer
+ * Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/* Element-Checklist-Version: 5 */
+
+#include "gstrtpdec.h"
+
+/* elementfactory information */
+static GstElementDetails rtpdec_details = GST_ELEMENT_DETAILS ("RTP Decoder",
+    "Codec/Parser/Network",
+    "Accepts raw RTP and RTCP packets and sends them forward",
+    "Wim Taymans <wim@fluendo.com>");
+
+/* GstRTPDec signals and args */
+enum
+{
+  /* FILL ME */
+  LAST_SIGNAL
+};
+
+enum
+{
+  ARG_0,
+  ARG_SKIP
+      /* FILL ME */
+};
+
+static GstStaticPadTemplate gst_rtpdec_src_rtp_template =
+GST_STATIC_PAD_TEMPLATE ("srcrtp",
+    GST_PAD_SRC,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS ("application/x-rtp")
+    );
+
+static GstStaticPadTemplate gst_rtpdec_src_rtcp_template =
+GST_STATIC_PAD_TEMPLATE ("srcrtcp",
+    GST_PAD_SRC,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS ("application/x-rtcp")
+    );
+
+static GstStaticPadTemplate gst_rtpdec_sink_rtp_template =
+GST_STATIC_PAD_TEMPLATE ("sinkrtp",
+    GST_PAD_SINK,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS ("application/x-rtp")
+    );
+
+static GstStaticPadTemplate gst_rtpdec_sink_rtcp_template =
+GST_STATIC_PAD_TEMPLATE ("sinkrtcp",
+    GST_PAD_SINK,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS ("application/x-rtcp")
+    );
+
+static void gst_rtpdec_class_init (gpointer g_class);
+static void gst_rtpdec_init (GstRTPDec * rtpdec);
+
+static GstFlowReturn gst_rtpdec_chain_rtp (GstPad * pad, GstBuffer * buffer);
+static GstFlowReturn gst_rtpdec_chain_rtcp (GstPad * pad, GstBuffer * buffer);
+
+static void gst_rtpdec_set_property (GObject * object,
+    guint prop_id, const GValue * value, GParamSpec * pspec);
+static void gst_rtpdec_get_property (GObject * object,
+    guint prop_id, GValue * value, GParamSpec * pspec);
+
+static GstElementStateReturn gst_rtpdec_change_state (GstElement * element);
+
+static GstElementClass *parent_class = NULL;
+
+/*static guint gst_rtpdec_signals[LAST_SIGNAL] = { 0 };*/
+
+GType
+gst_rtpdec_get_type (void)
+{
+  static GType rtpdec_type = 0;
+
+  if (!rtpdec_type) {
+    static const GTypeInfo rtpdec_info = {
+      sizeof (GstRTPDecClass), NULL,
+      NULL,
+      (GClassInitFunc) gst_rtpdec_class_init,
+      NULL,
+      NULL,
+      sizeof (GstRTPDec),
+      0,
+      (GInstanceInitFunc) gst_rtpdec_init,
+    };
+
+    rtpdec_type =
+        g_type_register_static (GST_TYPE_ELEMENT, "GstRTPDec", &rtpdec_info, 0);
+  }
+  return rtpdec_type;
+}
+
+static void
+gst_rtpdec_class_init (gpointer g_class)
+{
+  GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
+  GstRTPDecClass *klass;
+
+  klass = (GstRTPDecClass *) g_class;
+  gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
+
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&gst_rtpdec_src_rtp_template));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&gst_rtpdec_src_rtcp_template));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&gst_rtpdec_sink_rtp_template));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&gst_rtpdec_sink_rtcp_template));
+  gst_element_class_set_details (gstelement_class, &rtpdec_details);
+
+  gobject_class->set_property = gst_rtpdec_set_property;
+  gobject_class->get_property = gst_rtpdec_get_property;
+
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SKIP, g_param_spec_int ("skip", "skip", "skip", G_MININT, G_MAXINT, 0, G_PARAM_READWRITE));      /* CHECKME */
+
+  parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+
+  gstelement_class->change_state = gst_rtpdec_change_state;
+}
+
+static void
+gst_rtpdec_init (GstRTPDec * rtpdec)
+{
+  /* the input rtp pad */
+  rtpdec->sink_rtp =
+      gst_pad_new_from_template (gst_static_pad_template_get
+      (&gst_rtpdec_sink_rtp_template), "sinkrtp");
+  gst_element_add_pad (GST_ELEMENT (rtpdec), rtpdec->sink_rtp);
+  gst_pad_set_chain_function (rtpdec->sink_rtp, gst_rtpdec_chain_rtp);
+
+  /* the input rtcp pad */
+  rtpdec->sink_rtcp =
+      gst_pad_new_from_template (gst_static_pad_template_get
+      (&gst_rtpdec_sink_rtcp_template), "sinkrtcp");
+  gst_element_add_pad (GST_ELEMENT (rtpdec), rtpdec->sink_rtcp);
+  gst_pad_set_chain_function (rtpdec->sink_rtcp, gst_rtpdec_chain_rtcp);
+
+  /* the output rtp pad */
+  rtpdec->src_rtp =
+      gst_pad_new_from_template (gst_static_pad_template_get
+      (&gst_rtpdec_src_rtp_template), "srcrtp");
+  gst_element_add_pad (GST_ELEMENT (rtpdec), rtpdec->src_rtp);
+
+  /* the output rtcp pad */
+  rtpdec->src_rtcp =
+      gst_pad_new_from_template (gst_static_pad_template_get
+      (&gst_rtpdec_src_rtcp_template), "srcrtcp");
+  gst_element_add_pad (GST_ELEMENT (rtpdec), rtpdec->src_rtcp);
+}
+
+static GstFlowReturn
+gst_rtpdec_chain_rtp (GstPad * pad, GstBuffer * buffer)
+{
+  GstRTPDec *src;
+
+  src = GST_RTPDEC (GST_PAD_PARENT (pad));
+
+  g_print ("got rtp packet\n");
+  return gst_pad_push (src->src_rtp, buffer);
+}
+
+static GstFlowReturn
+gst_rtpdec_chain_rtcp (GstPad * pad, GstBuffer * buffer)
+{
+  g_print ("got rtcp packet\n");
+  return GST_FLOW_OK;
+}
+
+static void
+gst_rtpdec_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstRTPDec *src;
+
+  src = GST_RTPDEC (object);
+
+  switch (prop_id) {
+    case ARG_SKIP:
+      break;
+    default:
+      break;
+  }
+}
+
+static void
+gst_rtpdec_get_property (GObject * object, guint prop_id, GValue * value,
+    GParamSpec * pspec)
+{
+  GstRTPDec *src;
+
+  src = GST_RTPDEC (object);
+
+  switch (prop_id) {
+    case ARG_SKIP:
+      break;
+    default:
+      break;
+  }
+}
+
+static GstElementStateReturn
+gst_rtpdec_change_state (GstElement * element)
+{
+  GstElementStateReturn ret;
+  GstRTPDec *rtpdec;
+  gint transition;
+
+  rtpdec = GST_RTPDEC (element);
+  transition = GST_STATE_TRANSITION (element);
+
+  switch (transition) {
+    case GST_STATE_PAUSED_TO_READY:
+      break;
+    default:
+      break;
+  }
+
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
+  switch (transition) {
+    case GST_STATE_PAUSED_TO_READY:
+      break;
+    default:
+      break;
+  }
+
+  return ret;
+}
+
+gboolean
+gst_rtpdec_plugin_init (GstPlugin * plugin)
+{
+  return gst_element_register (plugin, "rtpdec",
+      GST_RANK_NONE, GST_TYPE_RTPDEC);
+}
diff --git a/gst/rtp/gstrtpdepay.h b/gst/rtp/gstrtpdepay.h
new file mode 100644 (file)
index 0000000..5d75e46
--- /dev/null
@@ -0,0 +1,55 @@
+/* GStreamer
+ * Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GST_RTPDEC_H__
+#define __GST_RTPDEC_H__
+
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_RTPDEC                (gst_rtpdec_get_type())
+#define GST_IS_RTPDEC(obj)             (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTPDEC))
+#define GST_IS_RTPDEC_CLASS(obj)       (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTPDEC))
+#define GST_RTPDEC(obj)                (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTPDEC, GstRTPDec))
+#define GST_RTPDEC_CLASS(klass)        (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTPDEC, GstRTPDecClass))
+
+typedef struct _GstRTPDec GstRTPDec;
+typedef struct _GstRTPDecClass GstRTPDecClass;
+
+struct _GstRTPDec {
+  GstElement element;
+
+  GstPad *sink_rtp;
+  GstPad *sink_rtcp;
+  GstPad *src_rtp;
+  GstPad *src_rtcp;
+};
+
+struct _GstRTPDecClass {
+  GstElementClass parent_class;
+};
+
+gboolean gst_rtpdec_plugin_init (GstPlugin * plugin);
+
+GType gst_rtpdec_get_type(void);
+
+G_END_DECLS
+
+#endif /* __GST_RTPDEC_H__ */
index 7f9206f..93fb654 100644 (file)
@@ -161,26 +161,27 @@ static GstFlowReturn
 gst_udpsink_render (GstBaseSink * sink, GstBuffer * buffer)
 {
   GstUDPSink *udpsink;
-  guint tolen, i;
   gint tosend;
   guint8 *data;
 
   udpsink = GST_UDPSINK (sink);
 
-  tolen = sizeof (udpsink->theiraddr);
-
   tosend = GST_BUFFER_SIZE (buffer);
   data = GST_BUFFER_DATA (buffer);
 
   /* send in chunks of MTU */
   while (tosend > 0) {
-    if (sendto (udpsink->sock, data, udpsink->mtu,
-            0, (struct sockaddr *) &udpsink->theiraddr, tolen) == -1) {
+    gint psize;
+
+    psize = MIN (udpsink->mtu, tosend);
+    if (sendto (udpsink->sock, data, psize, 0,
+            (struct sockaddr *) &udpsink->theiraddr,
+            sizeof (udpsink->theiraddr)) == -1) {
       perror ("sending");
     }
 
-    data += udpsink->mtu;
-    tosend -= udpsink->mtu;
+    data += psize;
+    tosend -= psize;
   }
 
   return GST_FLOW_OK;
index f6901a3..120d0c5 100644 (file)
@@ -25,9 +25,6 @@
 #include "gstudpsrc.h"
 #include <unistd.h>
 
-#define UDP_DEFAULT_PORT               4951
-#define UDP_DEFAULT_MULTICAST_GROUP    "0.0.0.0"
-
 static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
@@ -47,18 +44,25 @@ enum
   LAST_SIGNAL
 };
 
+#define UDP_DEFAULT_PORT               4951
+#define UDP_DEFAULT_MULTICAST_GROUP    "0.0.0.0"
+#define UDP_DEFAULT_URI                        "udp://0.0.0.0:4951"
+
 enum
 {
-  ARG_0,
-  ARG_PORT,
-  ARG_MULTICAST_GROUP
-      /* FILL ME */
+  PROP_0,
+  PROP_PORT,
+  PROP_MULTICAST_GROUP,
+  PROP_URI,
+  /* FILL ME */
 };
 
 static void gst_udpsrc_base_init (gpointer g_class);
 static void gst_udpsrc_class_init (GstUDPSrc * klass);
 static void gst_udpsrc_init (GstUDPSrc * udpsrc);
 
+static void gst_udpsrc_uri_handler_init (gpointer g_iface, gpointer iface_data);
+
 static void gst_udpsrc_loop (GstPad * pad);
 static GstElementStateReturn gst_udpsrc_change_state (GstElement * element);
 static gboolean gst_udpsrc_activate (GstPad * pad, GstActivateMode mode);
@@ -90,9 +94,17 @@ gst_udpsrc_get_type (void)
       (GInstanceInitFunc) gst_udpsrc_init,
       NULL
     };
+    static const GInterfaceInfo urihandler_info = {
+      gst_udpsrc_uri_handler_init,
+      NULL,
+      NULL
+    };
 
     udpsrc_type =
         g_type_register_static (GST_TYPE_ELEMENT, "GstUDPSrc", &udpsrc_info, 0);
+
+    g_type_add_interface_static (udpsrc_type, GST_TYPE_URI_HANDLER,
+        &urihandler_info);
   }
   return udpsrc_type;
 }
@@ -122,13 +134,18 @@ gst_udpsrc_class_init (GstUDPSrc * klass)
   gobject_class->set_property = gst_udpsrc_set_property;
   gobject_class->get_property = gst_udpsrc_get_property;
 
-  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PORT,
-      g_param_spec_int ("port", "port", "The port to receive the packets from",
-          0, 32768, UDP_DEFAULT_PORT, G_PARAM_READWRITE));
-  g_object_class_install_property (gobject_class, ARG_MULTICAST_GROUP,
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PORT,
+      g_param_spec_int ("port", "port",
+          "The port to receive the packets from, 0=allocate", 0, 32768,
+          UDP_DEFAULT_PORT, G_PARAM_READWRITE));
+  g_object_class_install_property (gobject_class, PROP_MULTICAST_GROUP,
       g_param_spec_string ("multicast_group", "multicast_group",
-          "The Address of multicast group to join",
-          UDP_DEFAULT_MULTICAST_GROUP, G_PARAM_READWRITE));
+          "The Address of multicast group to join", UDP_DEFAULT_MULTICAST_GROUP,
+          G_PARAM_READWRITE));
+  g_object_class_install_property (gobject_class, PROP_URI,
+      g_param_spec_string ("uri", "URI",
+          "URI in the form of udp://hostname:port", UDP_DEFAULT_URI,
+          G_PARAM_READWRITE));
 
   gstelement_class->change_state = gst_udpsrc_change_state;
 }
@@ -146,6 +163,7 @@ gst_udpsrc_init (GstUDPSrc * udpsrc)
   udpsrc->port = UDP_DEFAULT_PORT;
   udpsrc->sock = -1;
   udpsrc->multi_group = g_strdup (UDP_DEFAULT_MULTICAST_GROUP);
+  udpsrc->uri = g_strdup (UDP_DEFAULT_URI);
 }
 
 static void
@@ -165,6 +183,9 @@ gst_udpsrc_loop (GstPad * pad)
   FD_SET (udpsrc->sock, &read_fds);
   max_sock = udpsrc->sock;
 
+  GST_STREAM_LOCK (pad);
+
+  /* FIXME, add another socket to unblock */
   if (select (max_sock + 1, &read_fds, NULL, NULL, NULL) < 0)
     goto select_error;
 
@@ -179,21 +200,64 @@ gst_udpsrc_loop (GstPad * pad)
     goto receive_error;
 
   GST_BUFFER_SIZE (outbuf) = numbytes;
-  gst_pad_push (udpsrc->srcpad, outbuf);
+  if (gst_pad_push (udpsrc->srcpad, outbuf) != GST_FLOW_OK)
+    goto need_pause;
+
+  GST_STREAM_UNLOCK (pad);
 
   return;
 
 select_error:
   {
+    GST_STREAM_UNLOCK (pad);
     GST_DEBUG ("got select error");
     return;
   }
 receive_error:
   {
+    GST_STREAM_UNLOCK (pad);
     gst_buffer_unref (outbuf);
     GST_DEBUG ("got receive error");
     return;
   }
+need_pause:
+  {
+    gst_task_pause (GST_RPAD_TASK (pad));
+    GST_STREAM_UNLOCK (pad);
+    return;
+  }
+}
+
+static gboolean
+gst_udpsrc_set_uri (GstUDPSrc * src, const gchar * uri)
+{
+  gchar *protocol;
+  gchar *location;
+  gchar *colptr;
+
+  protocol = gst_uri_get_protocol (uri);
+  if (strcmp (protocol, "udp") != 0)
+    goto wrong_protocol;
+  g_free (protocol);
+
+  location = gst_uri_get_location (uri);
+  colptr = strstr (location, ":");
+  if (colptr != NULL) {
+    src->port = atoi (colptr + 1);
+  }
+  g_free (location);
+  g_free (src->uri);
+
+  src->uri = g_strdup (uri);
+
+  return TRUE;
+
+wrong_protocol:
+  {
+    g_free (protocol);
+    GST_DEBUG ("error parsing uri %s", uri);
+    return FALSE;
+  }
 }
 
 static void
@@ -205,10 +269,10 @@ gst_udpsrc_set_property (GObject * object, guint prop_id, const GValue * value,
   udpsrc = GST_UDPSRC (object);
 
   switch (prop_id) {
-    case ARG_PORT:
+    case PROP_PORT:
       udpsrc->port = g_value_get_int (value);
       break;
-    case ARG_MULTICAST_GROUP:
+    case PROP_MULTICAST_GROUP:
       g_free (udpsrc->multi_group);
 
       if (g_value_get_string (value) == NULL)
@@ -217,6 +281,9 @@ gst_udpsrc_set_property (GObject * object, guint prop_id, const GValue * value,
         udpsrc->multi_group = g_strdup (g_value_get_string (value));
 
       break;
+    case PROP_URI:
+      gst_udpsrc_set_uri (udpsrc, g_value_get_string (value));
+      break;
     default:
       break;
   }
@@ -231,12 +298,15 @@ gst_udpsrc_get_property (GObject * object, guint prop_id, GValue * value,
   udpsrc = GST_UDPSRC (object);
 
   switch (prop_id) {
-    case ARG_PORT:
+    case PROP_PORT:
       g_value_set_int (value, udpsrc->port);
       break;
-    case ARG_MULTICAST_GROUP:
+    case PROP_MULTICAST_GROUP:
       g_value_set_string (value, udpsrc->multi_group);
       break;
+    case PROP_URI:
+      g_value_set_string (value, udpsrc->uri);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -249,28 +319,24 @@ gst_udpsrc_init_receive (GstUDPSrc * src)
 {
   guint bc_val;
   gint reuse = 1;
+  struct sockaddr_in my_addr;
+  int len, port;
 
   memset (&src->myaddr, 0, sizeof (src->myaddr));
   src->myaddr.sin_family = AF_INET;     /* host byte order */
   src->myaddr.sin_port = htons (src->port);     /* short, network byte order */
   src->myaddr.sin_addr.s_addr = INADDR_ANY;
 
-  if ((src->sock = socket (AF_INET, SOCK_DGRAM, 0)) == -1) {
-    perror ("socket");
-    return FALSE;
-  }
+  if ((src->sock = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
+    goto error;
 
   if (setsockopt (src->sock, SOL_SOCKET, SO_REUSEADDR, &reuse,
-          sizeof (reuse)) == -1) {
-    perror ("setsockopt");
-    return FALSE;
-  }
+          sizeof (reuse)) < 0)
+    goto error;
 
   if (bind (src->sock, (struct sockaddr *) &src->myaddr,
-          sizeof (src->myaddr)) == -1) {
-    perror ("bind");
-    return FALSE;
-  }
+          sizeof (src->myaddr)) < 0)
+    goto error;
 
   if (inet_aton (src->multi_group, &(src->multi_addr.imr_multiaddr))) {
     if (src->multi_addr.imr_multiaddr.s_addr) {
@@ -280,11 +346,25 @@ gst_udpsrc_init_receive (GstUDPSrc * src)
     }
   }
 
+  len = sizeof (my_addr);
+  getsockname (src->sock, (struct sockaddr *) &my_addr, &len);
+  port = ntohs (my_addr.sin_port);
+  if (port != src->port) {
+    src->port = port;
+    g_object_notify (G_OBJECT (src), "port");
+  }
+
   bc_val = 1;
   setsockopt (src->sock, SOL_SOCKET, SO_BROADCAST, &bc_val, sizeof (bc_val));
   src->myaddr.sin_port = htons (src->port + 1);
 
   return TRUE;
+
+error:
+  {
+    perror ("open");
+    return FALSE;
+  }
 }
 
 static void
@@ -326,6 +406,8 @@ gst_udpsrc_activate (GstPad * pad, GstActivateMode mode)
 
       /* step 2, make sure streaming finishes */
       GST_STREAM_LOCK (pad);
+      gst_udpsrc_close (udpsrc);
+
       /* step 3, stop the task */
       if (GST_RPAD_TASK (pad)) {
         gst_task_stop (GST_RPAD_TASK (pad));
@@ -363,9 +445,6 @@ gst_udpsrc_change_state (GstElement * element)
   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element);
 
   switch (transition) {
-    case GST_STATE_PAUSED_TO_READY:
-      gst_udpsrc_close (src);
-      break;
     default:
       break;
   }
@@ -374,6 +453,52 @@ gst_udpsrc_change_state (GstElement * element)
 
 no_init:
   {
+    GST_DEBUG ("could not init udp socket");
     return GST_STATE_FAILURE;
   }
 }
+
+/*** GSTURIHANDLER INTERFACE *************************************************/
+
+static guint
+gst_udpsrc_uri_get_type (void)
+{
+  return GST_URI_SRC;
+}
+static gchar **
+gst_udpsrc_uri_get_protocols (void)
+{
+  static gchar *protocols[] = { "udp", NULL };
+
+  return protocols;
+}
+
+static const gchar *
+gst_udpsrc_uri_get_uri (GstURIHandler * handler)
+{
+  GstUDPSrc *src = GST_UDPSRC (handler);
+
+  return g_strdup (src->uri);
+}
+
+static gboolean
+gst_udpsrc_uri_set_uri (GstURIHandler * handler, const gchar * uri)
+{
+  gboolean ret;
+  GstUDPSrc *src = GST_UDPSRC (handler);
+
+  ret = gst_udpsrc_set_uri (src, uri);
+
+  return ret;
+}
+
+static void
+gst_udpsrc_uri_handler_init (gpointer g_iface, gpointer iface_data)
+{
+  GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
+
+  iface->get_type = gst_udpsrc_uri_get_type;
+  iface->get_protocols = gst_udpsrc_uri_get_protocols;
+  iface->get_uri = gst_udpsrc_uri_get_uri;
+  iface->set_uri = gst_udpsrc_uri_set_uri;
+}
index a2cfb2e..a347eb2 100644 (file)
@@ -56,11 +56,18 @@ struct _GstUDPSrc {
   GstElement element;
 
   /* pads */
-  GstPad *sinkpad,*srcpad;
+  GstPad *sinkpad,
+        *srcpad;
+
+  gchar *uri;
 
   int port;
   int sock;
   gchar *multi_group;
+  gboolean multicast;
+  gint ttl;
+
+  int control;
 
   struct sockaddr_in myaddr;
   struct ip_mreq multi_addr;