gst/rtp/: Added very simplistic amr payloader. depayloader does not work yet.
authorWim Taymans <wim.taymans@gmail.com>
Thu, 18 Aug 2005 17:39:17 +0000 (17:39 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Thu, 18 Aug 2005 17:39:17 +0000 (17:39 +0000)
Original commit message from CVS:
* gst/rtp/Makefile.am:
* gst/rtp/gstrtp.c: (plugin_init):
* gst/rtp/gstrtpamrdec.c: (gst_rtpamrdec_get_type),
(gst_rtpamrdec_base_init), (gst_rtpamrdec_class_init),
(gst_rtpamrdec_init), (gst_rtpamrdec_chain),
(gst_rtpamrdec_set_property), (gst_rtpamrdec_get_property),
(gst_rtpamrdec_change_state), (gst_rtpamrdec_plugin_init):
* gst/rtp/gstrtpamrdec.h:
* gst/rtp/gstrtpamrenc.c: (gst_rtpamrenc_get_type),
(gst_rtpamrenc_base_init), (gst_rtpamrenc_class_init),
(gst_rtpamrenc_init), (gst_rtpamrenc_chain),
(gst_rtpamrenc_set_property), (gst_rtpamrenc_get_property),
(gst_rtpamrenc_change_state), (gst_rtpamrenc_plugin_init):
* gst/rtp/gstrtpamrenc.h:
* gst/rtp/gstrtpmpaenc.c: (gst_rtpmpaenc_class_init),
(gst_rtpmpaenc_flush), (gst_rtpmpaenc_chain):
Added very simplistic amr payloader. depayloader does not
work yet.

13 files changed:
ChangeLog
gst/rtp/Makefile.am
gst/rtp/gstrtp.c
gst/rtp/gstrtpamrdec.c [new file with mode: 0644]
gst/rtp/gstrtpamrdec.h [new file with mode: 0644]
gst/rtp/gstrtpamrdepay.c [new file with mode: 0644]
gst/rtp/gstrtpamrdepay.h [new file with mode: 0644]
gst/rtp/gstrtpamrenc.c [new file with mode: 0644]
gst/rtp/gstrtpamrenc.h [new file with mode: 0644]
gst/rtp/gstrtpamrpay.c [new file with mode: 0644]
gst/rtp/gstrtpamrpay.h [new file with mode: 0644]
gst/rtp/gstrtpmpaenc.c
gst/rtp/gstrtpmpapay.c

index f9ff82ea71f93c78f31951a6d3252c9a9bea767f..8fd7253c55092c4df910a7a80847a9cd931aa13d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2005-08-18  Wim Taymans  <wim@fluendo.com>
+
+       * gst/rtp/Makefile.am:
+       * gst/rtp/gstrtp.c: (plugin_init):
+       * gst/rtp/gstrtpamrdec.c: (gst_rtpamrdec_get_type),
+       (gst_rtpamrdec_base_init), (gst_rtpamrdec_class_init),
+       (gst_rtpamrdec_init), (gst_rtpamrdec_chain),
+       (gst_rtpamrdec_set_property), (gst_rtpamrdec_get_property),
+       (gst_rtpamrdec_change_state), (gst_rtpamrdec_plugin_init):
+       * gst/rtp/gstrtpamrdec.h:
+       * gst/rtp/gstrtpamrenc.c: (gst_rtpamrenc_get_type),
+       (gst_rtpamrenc_base_init), (gst_rtpamrenc_class_init),
+       (gst_rtpamrenc_init), (gst_rtpamrenc_chain),
+       (gst_rtpamrenc_set_property), (gst_rtpamrenc_get_property),
+       (gst_rtpamrenc_change_state), (gst_rtpamrenc_plugin_init):
+       * gst/rtp/gstrtpamrenc.h:
+       * gst/rtp/gstrtpmpaenc.c: (gst_rtpmpaenc_class_init),
+       (gst_rtpmpaenc_flush), (gst_rtpmpaenc_chain):
+       Added very simplistic amr payloader. depayloader does not
+       work yet.
+
 2005-08-18  Wim Taymans  <wim@fluendo.com>
 
        * gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_send), (gst_rtspsrc_open),
index b08df858aa4f9735646791b75162c478a1c93863..4f1f3d6c59abb3564dc219fe2502973bba18f4b2 100644 (file)
@@ -4,6 +4,8 @@ libgstrtp_la_SOURCES = gstrtp.c \
                       gstrtpdec.c \
                       gstrtpmpadec.c \
                       gstrtpmpaenc.c \
+                      gstrtpamrdec.c \
+                      gstrtpamrenc.c \
                       gstrtph263pdec.c \
                       gstrtph263penc.c 
 
@@ -16,6 +18,8 @@ libgstrtp_la_LIBADD = $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) \
 
 noinst_HEADERS = gstrtpL16enc.h        \
                 gstrtpL16parse.h       \
+                gstrtpamrdec.h         \
+                gstrtpamrenc.h         \
                 gstrtpgsmenc.h         \
                 gstrtpgsmparse.h       \
                 gstrtpmpadec.h         \
index 9715e9a83aaa4a4f27259356381f4d7d6074b18e..02205d236207e56268b1622d30b867b70ff2d365 100644 (file)
@@ -22,6 +22,8 @@
 #endif
 
 #include "gstrtpdec.h"
+#include "gstrtpamrenc.h"
+#include "gstrtpamrdec.h"
 #include "gstrtpmpaenc.h"
 #include "gstrtpmpadec.h"
 #include "gstrtph263pdec.h"
@@ -33,6 +35,12 @@ plugin_init (GstPlugin * plugin)
   if (!gst_rtpdec_plugin_init (plugin))
     return FALSE;
 
+  if (!gst_rtpamrdec_plugin_init (plugin))
+    return FALSE;
+
+  if (!gst_rtpamrenc_plugin_init (plugin))
+    return FALSE;
+
   if (!gst_rtpmpadec_plugin_init (plugin))
     return FALSE;
 
diff --git a/gst/rtp/gstrtpamrdec.c b/gst/rtp/gstrtpamrdec.c
new file mode 100644 (file)
index 0000000..61827cb
--- /dev/null
@@ -0,0 +1,261 @@
+/* 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 
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <gst/rtp/gstrtpbuffer.h>
+
+#include <string.h>
+#include "gstrtpamrdec.h"
+
+/* elementfactory information */
+static GstElementDetails gst_rtp_amrdec_details = {
+  "RTP packet parser",
+  "Codec/Parser/Network",
+  "Extracts MPEG audio from RTP packets",
+  "Wim Taymans <wim@fluendo.com>"
+};
+
+/* RtpAMRDec signals and args */
+enum
+{
+  /* FILL ME */
+  LAST_SIGNAL
+};
+
+enum
+{
+  ARG_0,
+  ARG_FREQUENCY
+};
+
+static GstStaticPadTemplate gst_rtpamrdec_src_template =
+GST_STATIC_PAD_TEMPLATE ("src",
+    GST_PAD_SRC,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS ("audio/mpeg")
+    );
+
+static GstStaticPadTemplate gst_rtpamrdec_sink_template =
+GST_STATIC_PAD_TEMPLATE ("sink",
+    GST_PAD_SINK,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS ("application/x-rtp")
+    );
+
+
+static void gst_rtpamrdec_class_init (GstRtpAMRDecClass * klass);
+static void gst_rtpamrdec_base_init (GstRtpAMRDecClass * klass);
+static void gst_rtpamrdec_init (GstRtpAMRDec * rtpamrdec);
+
+static GstFlowReturn gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buffer);
+
+static void gst_rtpamrdec_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_rtpamrdec_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
+
+static GstElementStateReturn gst_rtpamrdec_change_state (GstElement * element);
+
+static GstElementClass *parent_class = NULL;
+
+static GType
+gst_rtpamrdec_get_type (void)
+{
+  static GType rtpamrdec_type = 0;
+
+  if (!rtpamrdec_type) {
+    static const GTypeInfo rtpamrdec_info = {
+      sizeof (GstRtpAMRDecClass),
+      (GBaseInitFunc) gst_rtpamrdec_base_init,
+      NULL,
+      (GClassInitFunc) gst_rtpamrdec_class_init,
+      NULL,
+      NULL,
+      sizeof (GstRtpAMRDec),
+      0,
+      (GInstanceInitFunc) gst_rtpamrdec_init,
+    };
+
+    rtpamrdec_type =
+        g_type_register_static (GST_TYPE_ELEMENT, "GstRtpAMRDec",
+        &rtpamrdec_info, 0);
+  }
+  return rtpamrdec_type;
+}
+
+static void
+gst_rtpamrdec_base_init (GstRtpAMRDecClass * klass)
+{
+  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&gst_rtpamrdec_src_template));
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&gst_rtpamrdec_sink_template));
+
+  gst_element_class_set_details (element_class, &gst_rtp_amrdec_details);
+}
+
+static void
+gst_rtpamrdec_class_init (GstRtpAMRDecClass * klass)
+{
+  GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
+
+  gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
+
+  parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+
+  gobject_class->set_property = gst_rtpamrdec_set_property;
+  gobject_class->get_property = gst_rtpamrdec_get_property;
+
+  gstelement_class->change_state = gst_rtpamrdec_change_state;
+}
+
+static void
+gst_rtpamrdec_init (GstRtpAMRDec * rtpamrdec)
+{
+  rtpamrdec->srcpad =
+      gst_pad_new_from_template (gst_static_pad_template_get
+      (&gst_rtpamrdec_src_template), "src");
+  gst_element_add_pad (GST_ELEMENT (rtpamrdec), rtpamrdec->srcpad);
+
+  rtpamrdec->sinkpad =
+      gst_pad_new_from_template (gst_static_pad_template_get
+      (&gst_rtpamrdec_sink_template), "sink");
+  gst_pad_set_chain_function (rtpamrdec->sinkpad, gst_rtpamrdec_chain);
+  gst_element_add_pad (GST_ELEMENT (rtpamrdec), rtpamrdec->sinkpad);
+}
+
+static GstFlowReturn
+gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buf)
+{
+  GstRtpAMRDec *rtpamrdec;
+  GstBuffer *outbuf;
+  GstFlowReturn ret;
+
+  rtpamrdec = GST_RTP_AMR_DEC (GST_OBJECT_PARENT (pad));
+
+  if (!gst_rtpbuffer_validate (buf))
+    goto bad_packet;
+
+  {
+    gint payload_len;
+    guint8 *payload;
+    guint16 frag_offset;
+    guint32 timestamp;
+
+    payload_len = gst_rtpbuffer_get_payload_len (buf);
+    payload = gst_rtpbuffer_get_payload (buf);
+
+    frag_offset = (payload[2] << 8) | payload[3];
+
+    /* strip off header */
+    payload_len -= 4;
+    payload += 4;
+
+    timestamp = gst_rtpbuffer_get_timestamp (buf);
+
+    outbuf = gst_buffer_new_and_alloc (payload_len);
+
+    //GST_BUFFER_TIMESTAMP (outbuf) = timestamp * GST_SECOND / 90000;
+
+    memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len);
+
+    GST_DEBUG ("gst_rtpamrdec_chain: pushing buffer of size %d",
+        GST_BUFFER_SIZE (outbuf));
+
+    gst_buffer_unref (buf);
+
+    ret = gst_pad_push (rtpamrdec->srcpad, outbuf);
+  }
+
+  return ret;
+
+bad_packet:
+  {
+    GST_DEBUG ("Packet did not validate");
+    gst_buffer_unref (buf);
+    return GST_FLOW_ERROR;
+  }
+}
+
+static void
+gst_rtpamrdec_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstRtpAMRDec *rtpamrdec;
+
+  rtpamrdec = GST_RTP_AMR_DEC (object);
+
+  switch (prop_id) {
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_rtpamrdec_get_property (GObject * object, guint prop_id, GValue * value,
+    GParamSpec * pspec)
+{
+  GstRtpAMRDec *rtpamrdec;
+
+  rtpamrdec = GST_RTP_AMR_DEC (object);
+
+  switch (prop_id) {
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static GstElementStateReturn
+gst_rtpamrdec_change_state (GstElement * element)
+{
+  GstRtpAMRDec *rtpamrdec;
+  gint transition;
+  GstElementStateReturn ret;
+
+  rtpamrdec = GST_RTP_AMR_DEC (element);
+  transition = GST_STATE_TRANSITION (element);
+
+  switch (transition) {
+    case GST_STATE_NULL_TO_READY:
+      break;
+    default:
+      break;
+  }
+
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
+  switch (transition) {
+    case GST_STATE_READY_TO_NULL:
+      break;
+    default:
+      break;
+  }
+  return ret;
+}
+
+gboolean
+gst_rtpamrdec_plugin_init (GstPlugin * plugin)
+{
+  return gst_element_register (plugin, "rtpamrdec",
+      GST_RANK_NONE, GST_TYPE_RTP_AMR_DEC);
+}
diff --git a/gst/rtp/gstrtpamrdec.h b/gst/rtp/gstrtpamrdec.h
new file mode 100644 (file)
index 0000000..dd14792
--- /dev/null
@@ -0,0 +1,60 @@
+/* Gnome-Streamer
+ * 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_RTP_AMR_DEC_H__
+#define __GST_RTP_AMR_DEC_H__
+
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_RTP_AMR_DEC \
+  (gst_rtpamrdec_get_type())
+#define GST_RTP_AMR_DEC(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_AMR_DEC,GstRtpAMRDec))
+#define GST_RTP_AMR_DEC_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_AMR_DEC,GstRtpAMRDec))
+#define GST_IS_RTP_AMR_DEC(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_AMR_DEC))
+#define GST_IS_RTP_AMR_DEC_CLASS(obj) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_AMR_DEC))
+
+typedef struct _GstRtpAMRDec GstRtpAMRDec;
+typedef struct _GstRtpAMRDecClass GstRtpAMRDecClass;
+
+struct _GstRtpAMRDec
+{
+  GstElement element;
+
+  GstPad *sinkpad;
+  GstPad *srcpad;
+
+  guint frequency;
+};
+
+struct _GstRtpAMRDecClass
+{
+  GstElementClass parent_class;
+};
+
+gboolean gst_rtpamrdec_plugin_init (GstPlugin * plugin);
+
+G_END_DECLS
+
+#endif /* __GST_RTP_AMR_DEC_H__ */
diff --git a/gst/rtp/gstrtpamrdepay.c b/gst/rtp/gstrtpamrdepay.c
new file mode 100644 (file)
index 0000000..61827cb
--- /dev/null
@@ -0,0 +1,261 @@
+/* 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 
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <gst/rtp/gstrtpbuffer.h>
+
+#include <string.h>
+#include "gstrtpamrdec.h"
+
+/* elementfactory information */
+static GstElementDetails gst_rtp_amrdec_details = {
+  "RTP packet parser",
+  "Codec/Parser/Network",
+  "Extracts MPEG audio from RTP packets",
+  "Wim Taymans <wim@fluendo.com>"
+};
+
+/* RtpAMRDec signals and args */
+enum
+{
+  /* FILL ME */
+  LAST_SIGNAL
+};
+
+enum
+{
+  ARG_0,
+  ARG_FREQUENCY
+};
+
+static GstStaticPadTemplate gst_rtpamrdec_src_template =
+GST_STATIC_PAD_TEMPLATE ("src",
+    GST_PAD_SRC,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS ("audio/mpeg")
+    );
+
+static GstStaticPadTemplate gst_rtpamrdec_sink_template =
+GST_STATIC_PAD_TEMPLATE ("sink",
+    GST_PAD_SINK,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS ("application/x-rtp")
+    );
+
+
+static void gst_rtpamrdec_class_init (GstRtpAMRDecClass * klass);
+static void gst_rtpamrdec_base_init (GstRtpAMRDecClass * klass);
+static void gst_rtpamrdec_init (GstRtpAMRDec * rtpamrdec);
+
+static GstFlowReturn gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buffer);
+
+static void gst_rtpamrdec_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_rtpamrdec_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
+
+static GstElementStateReturn gst_rtpamrdec_change_state (GstElement * element);
+
+static GstElementClass *parent_class = NULL;
+
+static GType
+gst_rtpamrdec_get_type (void)
+{
+  static GType rtpamrdec_type = 0;
+
+  if (!rtpamrdec_type) {
+    static const GTypeInfo rtpamrdec_info = {
+      sizeof (GstRtpAMRDecClass),
+      (GBaseInitFunc) gst_rtpamrdec_base_init,
+      NULL,
+      (GClassInitFunc) gst_rtpamrdec_class_init,
+      NULL,
+      NULL,
+      sizeof (GstRtpAMRDec),
+      0,
+      (GInstanceInitFunc) gst_rtpamrdec_init,
+    };
+
+    rtpamrdec_type =
+        g_type_register_static (GST_TYPE_ELEMENT, "GstRtpAMRDec",
+        &rtpamrdec_info, 0);
+  }
+  return rtpamrdec_type;
+}
+
+static void
+gst_rtpamrdec_base_init (GstRtpAMRDecClass * klass)
+{
+  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&gst_rtpamrdec_src_template));
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&gst_rtpamrdec_sink_template));
+
+  gst_element_class_set_details (element_class, &gst_rtp_amrdec_details);
+}
+
+static void
+gst_rtpamrdec_class_init (GstRtpAMRDecClass * klass)
+{
+  GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
+
+  gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
+
+  parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+
+  gobject_class->set_property = gst_rtpamrdec_set_property;
+  gobject_class->get_property = gst_rtpamrdec_get_property;
+
+  gstelement_class->change_state = gst_rtpamrdec_change_state;
+}
+
+static void
+gst_rtpamrdec_init (GstRtpAMRDec * rtpamrdec)
+{
+  rtpamrdec->srcpad =
+      gst_pad_new_from_template (gst_static_pad_template_get
+      (&gst_rtpamrdec_src_template), "src");
+  gst_element_add_pad (GST_ELEMENT (rtpamrdec), rtpamrdec->srcpad);
+
+  rtpamrdec->sinkpad =
+      gst_pad_new_from_template (gst_static_pad_template_get
+      (&gst_rtpamrdec_sink_template), "sink");
+  gst_pad_set_chain_function (rtpamrdec->sinkpad, gst_rtpamrdec_chain);
+  gst_element_add_pad (GST_ELEMENT (rtpamrdec), rtpamrdec->sinkpad);
+}
+
+static GstFlowReturn
+gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buf)
+{
+  GstRtpAMRDec *rtpamrdec;
+  GstBuffer *outbuf;
+  GstFlowReturn ret;
+
+  rtpamrdec = GST_RTP_AMR_DEC (GST_OBJECT_PARENT (pad));
+
+  if (!gst_rtpbuffer_validate (buf))
+    goto bad_packet;
+
+  {
+    gint payload_len;
+    guint8 *payload;
+    guint16 frag_offset;
+    guint32 timestamp;
+
+    payload_len = gst_rtpbuffer_get_payload_len (buf);
+    payload = gst_rtpbuffer_get_payload (buf);
+
+    frag_offset = (payload[2] << 8) | payload[3];
+
+    /* strip off header */
+    payload_len -= 4;
+    payload += 4;
+
+    timestamp = gst_rtpbuffer_get_timestamp (buf);
+
+    outbuf = gst_buffer_new_and_alloc (payload_len);
+
+    //GST_BUFFER_TIMESTAMP (outbuf) = timestamp * GST_SECOND / 90000;
+
+    memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len);
+
+    GST_DEBUG ("gst_rtpamrdec_chain: pushing buffer of size %d",
+        GST_BUFFER_SIZE (outbuf));
+
+    gst_buffer_unref (buf);
+
+    ret = gst_pad_push (rtpamrdec->srcpad, outbuf);
+  }
+
+  return ret;
+
+bad_packet:
+  {
+    GST_DEBUG ("Packet did not validate");
+    gst_buffer_unref (buf);
+    return GST_FLOW_ERROR;
+  }
+}
+
+static void
+gst_rtpamrdec_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstRtpAMRDec *rtpamrdec;
+
+  rtpamrdec = GST_RTP_AMR_DEC (object);
+
+  switch (prop_id) {
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_rtpamrdec_get_property (GObject * object, guint prop_id, GValue * value,
+    GParamSpec * pspec)
+{
+  GstRtpAMRDec *rtpamrdec;
+
+  rtpamrdec = GST_RTP_AMR_DEC (object);
+
+  switch (prop_id) {
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static GstElementStateReturn
+gst_rtpamrdec_change_state (GstElement * element)
+{
+  GstRtpAMRDec *rtpamrdec;
+  gint transition;
+  GstElementStateReturn ret;
+
+  rtpamrdec = GST_RTP_AMR_DEC (element);
+  transition = GST_STATE_TRANSITION (element);
+
+  switch (transition) {
+    case GST_STATE_NULL_TO_READY:
+      break;
+    default:
+      break;
+  }
+
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
+  switch (transition) {
+    case GST_STATE_READY_TO_NULL:
+      break;
+    default:
+      break;
+  }
+  return ret;
+}
+
+gboolean
+gst_rtpamrdec_plugin_init (GstPlugin * plugin)
+{
+  return gst_element_register (plugin, "rtpamrdec",
+      GST_RANK_NONE, GST_TYPE_RTP_AMR_DEC);
+}
diff --git a/gst/rtp/gstrtpamrdepay.h b/gst/rtp/gstrtpamrdepay.h
new file mode 100644 (file)
index 0000000..dd14792
--- /dev/null
@@ -0,0 +1,60 @@
+/* Gnome-Streamer
+ * 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_RTP_AMR_DEC_H__
+#define __GST_RTP_AMR_DEC_H__
+
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_RTP_AMR_DEC \
+  (gst_rtpamrdec_get_type())
+#define GST_RTP_AMR_DEC(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_AMR_DEC,GstRtpAMRDec))
+#define GST_RTP_AMR_DEC_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_AMR_DEC,GstRtpAMRDec))
+#define GST_IS_RTP_AMR_DEC(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_AMR_DEC))
+#define GST_IS_RTP_AMR_DEC_CLASS(obj) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_AMR_DEC))
+
+typedef struct _GstRtpAMRDec GstRtpAMRDec;
+typedef struct _GstRtpAMRDecClass GstRtpAMRDecClass;
+
+struct _GstRtpAMRDec
+{
+  GstElement element;
+
+  GstPad *sinkpad;
+  GstPad *srcpad;
+
+  guint frequency;
+};
+
+struct _GstRtpAMRDecClass
+{
+  GstElementClass parent_class;
+};
+
+gboolean gst_rtpamrdec_plugin_init (GstPlugin * plugin);
+
+G_END_DECLS
+
+#endif /* __GST_RTP_AMR_DEC_H__ */
diff --git a/gst/rtp/gstrtpamrenc.c b/gst/rtp/gstrtpamrenc.c
new file mode 100644 (file)
index 0000000..de368ec
--- /dev/null
@@ -0,0 +1,285 @@
+/* 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 
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <string.h>
+
+#include <gst/rtp/gstrtpbuffer.h>
+
+#include "gstrtpamrenc.h"
+
+/* elementfactory information */
+static GstElementDetails gst_rtp_amrenc_details = {
+  "RTP packet parser",
+  "Codec/Parser/Network",
+  "Encode AMR audio into RTP packets",
+  "Wim Taymans <wim@fluendo.com>"
+};
+
+/* RtpAMREnc signals and args */
+enum
+{
+  /* FILL ME */
+  LAST_SIGNAL
+};
+
+#define DEFAULT_MTU    1024
+
+enum
+{
+  PROP_0,
+  PROP_MTU
+};
+
+static GstStaticPadTemplate gst_rtpamrenc_sink_template =
+GST_STATIC_PAD_TEMPLATE ("sink",
+    GST_PAD_SINK,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS ("audio/x-amr-nb, channels=(int)1, rate=(int)8000")
+    );
+
+static GstStaticPadTemplate gst_rtpamrenc_src_template =
+GST_STATIC_PAD_TEMPLATE ("src",
+    GST_PAD_SRC,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS ("application/x-rtp")
+    );
+
+
+static void gst_rtpamrenc_class_init (GstRtpAMREncClass * klass);
+static void gst_rtpamrenc_base_init (GstRtpAMREncClass * klass);
+static void gst_rtpamrenc_init (GstRtpAMREnc * rtpamrenc);
+
+static GstFlowReturn gst_rtpamrenc_chain (GstPad * pad, GstBuffer * buffer);
+
+static void gst_rtpamrenc_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_rtpamrenc_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
+
+static GstElementStateReturn gst_rtpamrenc_change_state (GstElement * element);
+
+static GstElementClass *parent_class = NULL;
+
+static GType
+gst_rtpamrenc_get_type (void)
+{
+  static GType rtpamrenc_type = 0;
+
+  if (!rtpamrenc_type) {
+    static const GTypeInfo rtpamrenc_info = {
+      sizeof (GstRtpAMREncClass),
+      (GBaseInitFunc) gst_rtpamrenc_base_init,
+      NULL,
+      (GClassInitFunc) gst_rtpamrenc_class_init,
+      NULL,
+      NULL,
+      sizeof (GstRtpAMREnc),
+      0,
+      (GInstanceInitFunc) gst_rtpamrenc_init,
+    };
+
+    rtpamrenc_type =
+        g_type_register_static (GST_TYPE_ELEMENT, "GstRtpAMREnc",
+        &rtpamrenc_info, 0);
+  }
+  return rtpamrenc_type;
+}
+
+static void
+gst_rtpamrenc_base_init (GstRtpAMREncClass * klass)
+{
+  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&gst_rtpamrenc_src_template));
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&gst_rtpamrenc_sink_template));
+
+  gst_element_class_set_details (element_class, &gst_rtp_amrenc_details);
+}
+
+static void
+gst_rtpamrenc_class_init (GstRtpAMREncClass * klass)
+{
+  GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
+
+  gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
+
+  parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+
+  gobject_class->set_property = gst_rtpamrenc_set_property;
+  gobject_class->get_property = gst_rtpamrenc_get_property;
+
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_MTU,
+      g_param_spec_uint ("mtu", "MTU",
+          "Maximum size of one packet",
+          28, G_MAXUINT, DEFAULT_MTU, G_PARAM_READWRITE));
+
+  gstelement_class->change_state = gst_rtpamrenc_change_state;
+}
+
+static void
+gst_rtpamrenc_init (GstRtpAMREnc * rtpamrenc)
+{
+  rtpamrenc->srcpad =
+      gst_pad_new_from_template (gst_static_pad_template_get
+      (&gst_rtpamrenc_src_template), "src");
+  gst_element_add_pad (GST_ELEMENT (rtpamrenc), rtpamrenc->srcpad);
+
+  rtpamrenc->sinkpad =
+      gst_pad_new_from_template (gst_static_pad_template_get
+      (&gst_rtpamrenc_sink_template), "sink");
+  gst_pad_set_chain_function (rtpamrenc->sinkpad, gst_rtpamrenc_chain);
+  gst_element_add_pad (GST_ELEMENT (rtpamrenc), rtpamrenc->sinkpad);
+
+  rtpamrenc->mtu = DEFAULT_MTU;
+}
+
+static GstFlowReturn
+gst_rtpamrenc_chain (GstPad * pad, GstBuffer * buffer)
+{
+  GstRtpAMREnc *rtpamrenc;
+  GstFlowReturn ret;
+  guint size, payload_len;
+  GstBuffer *outbuf;
+  guint8 *payload;
+  GstClockTime timestamp;
+
+  rtpamrenc = GST_RTP_AMR_ENC (gst_pad_get_parent (pad));
+
+  size = GST_BUFFER_SIZE (buffer);
+  timestamp = GST_BUFFER_TIMESTAMP (buffer);
+
+  /* FIXME, only one AMR frame per RTP packet for now, 
+   * octet aligned, no interleaving, single channel, no CRC,
+   * no robust-sorting. */
+  payload_len = size + 2;
+
+  outbuf = gst_rtpbuffer_new_allocate (payload_len, 0, 0);
+  /* FIXME, assert for now */
+  g_assert (GST_BUFFER_SIZE (outbuf) < rtpamrenc->mtu);
+
+  gst_rtpbuffer_set_seq (outbuf, rtpamrenc->seqnum++);
+  gst_rtpbuffer_set_timestamp (outbuf, timestamp * 8000 / GST_SECOND);
+
+  /* copy timestamp */
+  GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
+
+  /* get payload */
+  payload = gst_rtpbuffer_get_payload (outbuf);
+
+  /*   0 1 2 3 4 5 6 7 
+   *  +-+-+-+-+-+-+-+-+
+   *  |  CMR  |R|R|R|R|
+   *  +-+-+-+-+-+-+-+-+
+   */
+  payload[0] = 0xF0;            /* CMR, no specific mode requested */
+  /*   0 1 2 3 4 5 6 7
+   *  +-+-+-+-+-+-+-+-+
+   *  |F|  FT   |Q|P|P|
+   *  +-+-+-+-+-+-+-+-+
+   */
+  payload[1] = 0x04;            /* ToC, no damage (Q=1) */
+
+  /* copy data in payload */
+  memcpy (&payload[2], GST_BUFFER_DATA (buffer), size);
+
+  gst_buffer_unref (buffer);
+
+  ret = gst_pad_push (rtpamrenc->srcpad, outbuf);
+
+  gst_object_unref (rtpamrenc);
+
+  return ret;
+}
+
+static void
+gst_rtpamrenc_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstRtpAMREnc *rtpamrenc;
+
+  rtpamrenc = GST_RTP_AMR_ENC (object);
+
+  switch (prop_id) {
+    case PROP_MTU:
+      rtpamrenc->mtu = g_value_get_uint (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_rtpamrenc_get_property (GObject * object, guint prop_id, GValue * value,
+    GParamSpec * pspec)
+{
+  GstRtpAMREnc *rtpamrenc;
+
+  rtpamrenc = GST_RTP_AMR_ENC (object);
+
+  switch (prop_id) {
+    case PROP_MTU:
+      g_value_set_uint (value, rtpamrenc->mtu);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static GstElementStateReturn
+gst_rtpamrenc_change_state (GstElement * element)
+{
+  GstRtpAMREnc *rtpamrenc;
+  gint transition;
+  GstElementStateReturn ret;
+
+  rtpamrenc = GST_RTP_AMR_ENC (element);
+  transition = GST_STATE_TRANSITION (element);
+
+  switch (transition) {
+    case GST_STATE_NULL_TO_READY:
+      break;
+    case GST_STATE_READY_TO_PAUSED:
+      rtpamrenc->seqnum = 0;
+      break;
+    default:
+      break;
+  }
+
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
+  switch (transition) {
+    case GST_STATE_READY_TO_NULL:
+      break;
+    default:
+      break;
+  }
+  return ret;
+}
+
+gboolean
+gst_rtpamrenc_plugin_init (GstPlugin * plugin)
+{
+  return gst_element_register (plugin, "rtpamrenc",
+      GST_RANK_NONE, GST_TYPE_RTP_AMR_ENC);
+}
diff --git a/gst/rtp/gstrtpamrenc.h b/gst/rtp/gstrtpamrenc.h
new file mode 100644 (file)
index 0000000..3da7f96
--- /dev/null
@@ -0,0 +1,63 @@
+/* Gnome-Streamer
+ * 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_RTP_AMR_ENC_H__
+#define __GST_RTP_AMR_ENC_H__
+
+#include <gst/gst.h>
+#include <gst/base/gstadapter.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_RTP_AMR_ENC \
+  (gst_rtpamrenc_get_type())
+#define GST_RTP_AMR_ENC(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_AMR_ENC,GstRtpAMREnc))
+#define GST_RTP_AMR_ENC_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_AMR_ENC,GstRtpAMREnc))
+#define GST_IS_RTP_AMR_ENC(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_AMR_ENC))
+#define GST_IS_RTP_AMR_ENC_CLASS(obj) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_AMR_ENC))
+
+typedef struct _GstRtpAMREnc GstRtpAMREnc;
+typedef struct _GstRtpAMREncClass GstRtpAMREncClass;
+
+struct _GstRtpAMREnc
+{
+  GstElement element;
+
+  GstPad *sinkpad;
+  GstPad *srcpad;
+
+  guint16 seqnum;
+
+  guint mtu;
+};
+
+struct _GstRtpAMREncClass
+{
+  GstElementClass parent_class;
+};
+
+gboolean gst_rtpamrenc_plugin_init (GstPlugin * plugin);
+
+G_END_DECLS
+
+#endif /* __GST_RTP_AMR_ENC_H__ */
diff --git a/gst/rtp/gstrtpamrpay.c b/gst/rtp/gstrtpamrpay.c
new file mode 100644 (file)
index 0000000..de368ec
--- /dev/null
@@ -0,0 +1,285 @@
+/* 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 
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <string.h>
+
+#include <gst/rtp/gstrtpbuffer.h>
+
+#include "gstrtpamrenc.h"
+
+/* elementfactory information */
+static GstElementDetails gst_rtp_amrenc_details = {
+  "RTP packet parser",
+  "Codec/Parser/Network",
+  "Encode AMR audio into RTP packets",
+  "Wim Taymans <wim@fluendo.com>"
+};
+
+/* RtpAMREnc signals and args */
+enum
+{
+  /* FILL ME */
+  LAST_SIGNAL
+};
+
+#define DEFAULT_MTU    1024
+
+enum
+{
+  PROP_0,
+  PROP_MTU
+};
+
+static GstStaticPadTemplate gst_rtpamrenc_sink_template =
+GST_STATIC_PAD_TEMPLATE ("sink",
+    GST_PAD_SINK,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS ("audio/x-amr-nb, channels=(int)1, rate=(int)8000")
+    );
+
+static GstStaticPadTemplate gst_rtpamrenc_src_template =
+GST_STATIC_PAD_TEMPLATE ("src",
+    GST_PAD_SRC,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS ("application/x-rtp")
+    );
+
+
+static void gst_rtpamrenc_class_init (GstRtpAMREncClass * klass);
+static void gst_rtpamrenc_base_init (GstRtpAMREncClass * klass);
+static void gst_rtpamrenc_init (GstRtpAMREnc * rtpamrenc);
+
+static GstFlowReturn gst_rtpamrenc_chain (GstPad * pad, GstBuffer * buffer);
+
+static void gst_rtpamrenc_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_rtpamrenc_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
+
+static GstElementStateReturn gst_rtpamrenc_change_state (GstElement * element);
+
+static GstElementClass *parent_class = NULL;
+
+static GType
+gst_rtpamrenc_get_type (void)
+{
+  static GType rtpamrenc_type = 0;
+
+  if (!rtpamrenc_type) {
+    static const GTypeInfo rtpamrenc_info = {
+      sizeof (GstRtpAMREncClass),
+      (GBaseInitFunc) gst_rtpamrenc_base_init,
+      NULL,
+      (GClassInitFunc) gst_rtpamrenc_class_init,
+      NULL,
+      NULL,
+      sizeof (GstRtpAMREnc),
+      0,
+      (GInstanceInitFunc) gst_rtpamrenc_init,
+    };
+
+    rtpamrenc_type =
+        g_type_register_static (GST_TYPE_ELEMENT, "GstRtpAMREnc",
+        &rtpamrenc_info, 0);
+  }
+  return rtpamrenc_type;
+}
+
+static void
+gst_rtpamrenc_base_init (GstRtpAMREncClass * klass)
+{
+  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&gst_rtpamrenc_src_template));
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&gst_rtpamrenc_sink_template));
+
+  gst_element_class_set_details (element_class, &gst_rtp_amrenc_details);
+}
+
+static void
+gst_rtpamrenc_class_init (GstRtpAMREncClass * klass)
+{
+  GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
+
+  gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
+
+  parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+
+  gobject_class->set_property = gst_rtpamrenc_set_property;
+  gobject_class->get_property = gst_rtpamrenc_get_property;
+
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_MTU,
+      g_param_spec_uint ("mtu", "MTU",
+          "Maximum size of one packet",
+          28, G_MAXUINT, DEFAULT_MTU, G_PARAM_READWRITE));
+
+  gstelement_class->change_state = gst_rtpamrenc_change_state;
+}
+
+static void
+gst_rtpamrenc_init (GstRtpAMREnc * rtpamrenc)
+{
+  rtpamrenc->srcpad =
+      gst_pad_new_from_template (gst_static_pad_template_get
+      (&gst_rtpamrenc_src_template), "src");
+  gst_element_add_pad (GST_ELEMENT (rtpamrenc), rtpamrenc->srcpad);
+
+  rtpamrenc->sinkpad =
+      gst_pad_new_from_template (gst_static_pad_template_get
+      (&gst_rtpamrenc_sink_template), "sink");
+  gst_pad_set_chain_function (rtpamrenc->sinkpad, gst_rtpamrenc_chain);
+  gst_element_add_pad (GST_ELEMENT (rtpamrenc), rtpamrenc->sinkpad);
+
+  rtpamrenc->mtu = DEFAULT_MTU;
+}
+
+static GstFlowReturn
+gst_rtpamrenc_chain (GstPad * pad, GstBuffer * buffer)
+{
+  GstRtpAMREnc *rtpamrenc;
+  GstFlowReturn ret;
+  guint size, payload_len;
+  GstBuffer *outbuf;
+  guint8 *payload;
+  GstClockTime timestamp;
+
+  rtpamrenc = GST_RTP_AMR_ENC (gst_pad_get_parent (pad));
+
+  size = GST_BUFFER_SIZE (buffer);
+  timestamp = GST_BUFFER_TIMESTAMP (buffer);
+
+  /* FIXME, only one AMR frame per RTP packet for now, 
+   * octet aligned, no interleaving, single channel, no CRC,
+   * no robust-sorting. */
+  payload_len = size + 2;
+
+  outbuf = gst_rtpbuffer_new_allocate (payload_len, 0, 0);
+  /* FIXME, assert for now */
+  g_assert (GST_BUFFER_SIZE (outbuf) < rtpamrenc->mtu);
+
+  gst_rtpbuffer_set_seq (outbuf, rtpamrenc->seqnum++);
+  gst_rtpbuffer_set_timestamp (outbuf, timestamp * 8000 / GST_SECOND);
+
+  /* copy timestamp */
+  GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
+
+  /* get payload */
+  payload = gst_rtpbuffer_get_payload (outbuf);
+
+  /*   0 1 2 3 4 5 6 7 
+   *  +-+-+-+-+-+-+-+-+
+   *  |  CMR  |R|R|R|R|
+   *  +-+-+-+-+-+-+-+-+
+   */
+  payload[0] = 0xF0;            /* CMR, no specific mode requested */
+  /*   0 1 2 3 4 5 6 7
+   *  +-+-+-+-+-+-+-+-+
+   *  |F|  FT   |Q|P|P|
+   *  +-+-+-+-+-+-+-+-+
+   */
+  payload[1] = 0x04;            /* ToC, no damage (Q=1) */
+
+  /* copy data in payload */
+  memcpy (&payload[2], GST_BUFFER_DATA (buffer), size);
+
+  gst_buffer_unref (buffer);
+
+  ret = gst_pad_push (rtpamrenc->srcpad, outbuf);
+
+  gst_object_unref (rtpamrenc);
+
+  return ret;
+}
+
+static void
+gst_rtpamrenc_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstRtpAMREnc *rtpamrenc;
+
+  rtpamrenc = GST_RTP_AMR_ENC (object);
+
+  switch (prop_id) {
+    case PROP_MTU:
+      rtpamrenc->mtu = g_value_get_uint (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_rtpamrenc_get_property (GObject * object, guint prop_id, GValue * value,
+    GParamSpec * pspec)
+{
+  GstRtpAMREnc *rtpamrenc;
+
+  rtpamrenc = GST_RTP_AMR_ENC (object);
+
+  switch (prop_id) {
+    case PROP_MTU:
+      g_value_set_uint (value, rtpamrenc->mtu);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static GstElementStateReturn
+gst_rtpamrenc_change_state (GstElement * element)
+{
+  GstRtpAMREnc *rtpamrenc;
+  gint transition;
+  GstElementStateReturn ret;
+
+  rtpamrenc = GST_RTP_AMR_ENC (element);
+  transition = GST_STATE_TRANSITION (element);
+
+  switch (transition) {
+    case GST_STATE_NULL_TO_READY:
+      break;
+    case GST_STATE_READY_TO_PAUSED:
+      rtpamrenc->seqnum = 0;
+      break;
+    default:
+      break;
+  }
+
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
+  switch (transition) {
+    case GST_STATE_READY_TO_NULL:
+      break;
+    default:
+      break;
+  }
+  return ret;
+}
+
+gboolean
+gst_rtpamrenc_plugin_init (GstPlugin * plugin)
+{
+  return gst_element_register (plugin, "rtpamrenc",
+      GST_RANK_NONE, GST_TYPE_RTP_AMR_ENC);
+}
diff --git a/gst/rtp/gstrtpamrpay.h b/gst/rtp/gstrtpamrpay.h
new file mode 100644 (file)
index 0000000..3da7f96
--- /dev/null
@@ -0,0 +1,63 @@
+/* Gnome-Streamer
+ * 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_RTP_AMR_ENC_H__
+#define __GST_RTP_AMR_ENC_H__
+
+#include <gst/gst.h>
+#include <gst/base/gstadapter.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_RTP_AMR_ENC \
+  (gst_rtpamrenc_get_type())
+#define GST_RTP_AMR_ENC(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_AMR_ENC,GstRtpAMREnc))
+#define GST_RTP_AMR_ENC_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_AMR_ENC,GstRtpAMREnc))
+#define GST_IS_RTP_AMR_ENC(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_AMR_ENC))
+#define GST_IS_RTP_AMR_ENC_CLASS(obj) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_AMR_ENC))
+
+typedef struct _GstRtpAMREnc GstRtpAMREnc;
+typedef struct _GstRtpAMREncClass GstRtpAMREncClass;
+
+struct _GstRtpAMREnc
+{
+  GstElement element;
+
+  GstPad *sinkpad;
+  GstPad *srcpad;
+
+  guint16 seqnum;
+
+  guint mtu;
+};
+
+struct _GstRtpAMREncClass
+{
+  GstElementClass parent_class;
+};
+
+gboolean gst_rtpamrenc_plugin_init (GstPlugin * plugin);
+
+G_END_DECLS
+
+#endif /* __GST_RTP_AMR_ENC_H__ */
index 6c77291f2695f97ea5f82c319b183d5bb368c5bb..991b09dc34015ec102dce4d7e05837b3af8f5272 100644 (file)
@@ -26,7 +26,7 @@
 static GstElementDetails gst_rtp_mpaenc_details = {
   "RTP packet parser",
   "Codec/Parser/Network",
-  "Extracts MPEG audio from RTP packets",
+  "Encode MPEG audio as RTP packets",
   "Wim Taymans <wim@fluendo.com>"
 };
 
index 6c77291f2695f97ea5f82c319b183d5bb368c5bb..991b09dc34015ec102dce4d7e05837b3af8f5272 100644 (file)
@@ -26,7 +26,7 @@
 static GstElementDetails gst_rtp_mpaenc_details = {
   "RTP packet parser",
   "Codec/Parser/Network",
-  "Extracts MPEG audio from RTP packets",
+  "Encode MPEG audio as RTP packets",
   "Wim Taymans <wim@fluendo.com>"
 };