+2006-04-12 Philippe Kalaf <philippe.kalaf@collabora.co.uk>
+
+ * gst/rtp/gstrtppcmapay.c:
+ * gst/rtp/gstrtppcmapay.h:
+ * gst/rtp/gstrtppcmupay.c:
+ * gst/rtp/gstrtppcmupay.h:
+ Ported mulaw and alaw payloaders to use new base class
+ * gst/rtp/Makefile.am:
+ * gst/rtp/gstrtp.c:
+ * gst/rtp/gstrtpilbcpay.c:
+ * gst/rtp/gstrtpilbcpay.h:
+ * gst/rtp/gstrtpilbcdepay.c:
+ * gst/rtp/gstrtpilbcdepay.h:
+ Added new iLBC payloader/depayloader. Payloader uses new audio payload base
+ class.
+
2006-04-12 Wim Taymans <wim@fluendo.com>
* ext/gdk_pixbuf/gstgdkpixbuf.c: (gst_gdk_pixbuf_sink_setcaps),
gstrtph263pdepay.c \
gstrtph263ppay.c \
gstrtph263pay.c \
+ gstrtpilbcpay.c \
+ gstrtpilbcdepay.c \
gstasteriskh263.c \
gstrtpmp4vdepay.c \
gstrtpmp4vpay.c \
gstrtph263pdepay.h \
gstrtph263ppay.h \
gstrtph263pay.h \
+ gstrtpilbcpay.h \
+ gstrtpilbcdepay.h \
gstrtpmp4vdepay.h \
gstrtpmp4vpay.h \
gstrtpmp4gpay.h \
#include "gstrtph263pdepay.h"
#include "gstrtph263ppay.h"
#include "gstrtph263pay.h"
+#include "gstrtpilbcpay.h"
+#include "gstrtpilbcdepay.h"
#include "gstasteriskh263.h"
#include "gstrtpmp4vpay.h"
#include "gstrtpmp4gpay.h"
if (!gst_rtp_h263_pay_plugin_init (plugin))
return FALSE;
+ if (!gst_rtp_ilbc_pay_plugin_init (plugin))
+ return FALSE;
+
+ if (!gst_rtp_ilbc_depay_plugin_init (plugin))
+ return FALSE;
+
if (!gst_asteriskh263_plugin_init (plugin))
return FALSE;
--- /dev/null
+/* GStreamer
+ * Copyright (C) <2006> Philippe Khalaf <burger@speedy.org>
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <string.h>
+#include <gst/rtp/gstrtpbuffer.h>
+#include "gstrtpilbcdepay.h"
+
+/* elementfactory information */
+static GstElementDetails gst_rtp_ilbc_depay_details =
+GST_ELEMENT_DETAILS ("RTP iLBC packet depayloader",
+ "Codec/Depayr/Network",
+ "Extracts iLBC audio from RTP packets",
+ "Philippe Kalaf <philippe.kalaf@collabora.co.uk>");
+
+/* RtpiLBCDepay signals and args */
+enum
+{
+ /* FILL ME */
+ LAST_SIGNAL
+};
+
+enum
+{
+ ARG_0,
+ ARG_MODE
+};
+
+static GstStaticPadTemplate gst_rtp_ilbc_depay_sink_template =
+GST_STATIC_PAD_TEMPLATE ("sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS ("application/x-rtp, "
+ "media = (string) \"audio\", "
+ "clock-rate = (int) 8000, "
+ "encoding-name = (string) \"iLBC\", " "mode = (int) { 20, 30 }")
+ );
+
+static GstStaticPadTemplate gst_rtp_ilbc_depay_src_template =
+GST_STATIC_PAD_TEMPLATE ("src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS ("audio/x-iLBC, " "mode = (int) { 20, 30 }")
+ );
+
+static void gst_ilbc_depay_set_property (GObject * object,
+ guint prop_id, const GValue * value, GParamSpec * pspec);
+static void gst_ilbc_depay_get_property (GObject * object,
+ guint prop_id, GValue * value, GParamSpec * pspec);
+
+static GstBuffer *gst_rtp_ilbc_depay_process (GstBaseRTPDepayload * depayload,
+ GstBuffer * buf);
+static gboolean gst_rtp_ilbc_depay_setcaps (GstBaseRTPDepayload * depayload,
+ GstCaps * caps);
+
+GST_BOILERPLATE (GstRTPiLBCDepay, gst_rtp_ilbc_depay, GstBaseRTPDepayload,
+ GST_TYPE_BASE_RTP_DEPAYLOAD);
+
+#define GST_TYPE_ILBC_MODE (gst_ilbc_mode_get_type())
+static GType
+gst_ilbc_mode_get_type (void)
+{
+ static GType ilbc_mode_type = 0;
+ static GEnumValue ilbc_modes[] = {
+ {GST_ILBC_MODE_20, "20ms frames", "20ms"},
+ {GST_ILBC_MODE_30, "30ms frames", "30ms"},
+ {0, NULL, NULL},
+ };
+
+ if (!ilbc_mode_type) {
+ ilbc_mode_type = g_enum_register_static ("iLBCMode", ilbc_modes);
+ }
+ return ilbc_mode_type;
+}
+
+static void
+gst_rtp_ilbc_depay_base_init (gpointer klass)
+{
+ GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_rtp_ilbc_depay_src_template));
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_rtp_ilbc_depay_sink_template));
+ gst_element_class_set_details (element_class, &gst_rtp_ilbc_depay_details);
+}
+
+static void
+gst_rtp_ilbc_depay_class_init (GstRTPiLBCDepayClass * klass)
+{
+ GObjectClass *gobject_class;
+ GstElementClass *gstelement_class;
+ GstBaseRTPDepayloadClass *gstbasertpdepayload_class;
+
+ gobject_class = (GObjectClass *) klass;
+ gstelement_class = (GstElementClass *) klass;
+ gstbasertpdepayload_class = (GstBaseRTPDepayloadClass *) klass;
+
+ gobject_class->set_property = gst_ilbc_depay_set_property;
+ gobject_class->get_property = gst_ilbc_depay_get_property;
+
+ g_object_class_install_property (gobject_class, ARG_MODE, g_param_spec_enum ("mode", "Mode", "iLBC frame mode", GST_TYPE_ILBC_MODE, /* enum type */
+ GST_ILBC_MODE_30, /* default value */
+ G_PARAM_READWRITE));
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ gstbasertpdepayload_class->process = gst_rtp_ilbc_depay_process;
+ gstbasertpdepayload_class->set_caps = gst_rtp_ilbc_depay_setcaps;
+}
+
+static void
+gst_rtp_ilbc_depay_init (GstRTPiLBCDepay * rtpilbcdepay,
+ GstRTPiLBCDepayClass * klass)
+{
+ GstBaseRTPDepayload *depayload;
+
+ depayload = GST_BASE_RTP_DEPAYLOAD (rtpilbcdepay);
+
+ depayload->clock_rate = 8000;
+
+ /* Set default mode to 30 */
+ rtpilbcdepay->mode = GST_ILBC_MODE_30;
+}
+
+static gboolean
+gst_rtp_ilbc_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
+{
+ GstRTPiLBCDepay *rtpilbcdepay = GST_RTP_ILBC_DEPAY (depayload);
+ GstCaps *srccaps;
+ GstStructure *structure;
+ gboolean ret;
+
+ srccaps = gst_caps_copy (gst_static_pad_template_get_caps
+ (&gst_rtp_ilbc_depay_src_template));
+ structure = gst_caps_get_structure (srccaps, 0);
+ gst_structure_set (structure, "mode", G_TYPE_INT,
+ rtpilbcdepay->mode == GST_ILBC_MODE_30 ? 30 : 20, NULL);
+ ret = gst_pad_set_caps (GST_BASE_RTP_DEPAYLOAD_SRCPAD (depayload), srccaps);
+ GST_DEBUG ("caps set on source are %s", gst_caps_to_string (srccaps));
+
+ gst_caps_unref (srccaps);
+ return ret;
+}
+
+static GstBuffer *
+gst_rtp_ilbc_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
+{
+ GstBuffer *outbuf = NULL;
+ gint payload_len;
+ gint header_len;
+
+ GST_DEBUG ("process : got %d bytes, mark %d ts %u seqn %d",
+ GST_BUFFER_SIZE (buf),
+ gst_rtp_buffer_get_marker (buf),
+ gst_rtp_buffer_get_timestamp (buf), gst_rtp_buffer_get_seq (buf));
+
+ payload_len = gst_rtp_buffer_get_payload_len (buf);
+ header_len = gst_rtp_buffer_calc_header_len (0);
+
+ outbuf = gst_buffer_create_sub (buf, header_len, payload_len);
+
+ return outbuf;
+}
+
+static void
+gst_ilbc_depay_set_property (GObject * object,
+ guint prop_id, const GValue * value, GParamSpec * pspec)
+{
+ GstRTPiLBCDepay *rtpilbcdepay = GST_RTP_ILBC_DEPAY (object);
+
+ switch (prop_id) {
+ case ARG_MODE:
+ rtpilbcdepay->mode = g_value_get_enum (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_ilbc_depay_get_property (GObject * object,
+ guint prop_id, GValue * value, GParamSpec * pspec)
+{
+ GstRTPiLBCDepay *rtpilbcdepay = GST_RTP_ILBC_DEPAY (object);
+
+ switch (prop_id) {
+ case ARG_MODE:
+ g_value_set_enum (value, rtpilbcdepay->mode);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+gboolean
+gst_rtp_ilbc_depay_plugin_init (GstPlugin * plugin)
+{
+ return gst_element_register (plugin, "rtpilbcdepay",
+ GST_RANK_NONE, GST_TYPE_RTP_ILBC_DEPAY);
+}
--- /dev/null
+/* GStreamer
+ * Copyright (C) <2006> Philippe Khalaf <burger@speedy.org>
+ *
+ * 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_ILBC_DEPAY_H__
+#define __GST_RTP_ILBC_DEPAY_H__
+
+#include <gst/gst.h>
+#include <gst/rtp/gstbasertpdepayload.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GstRTPiLBCDepay GstRTPiLBCDepay;
+typedef struct _GstRTPiLBCDepayClass GstRTPiLBCDepayClass;
+
+#define GST_TYPE_RTP_ILBC_DEPAY \
+ (gst_rtp_ilbc_depay_get_type())
+#define GST_RTP_ILBC_DEPAY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_ILBC_DEPAY,GstRTPiLBCDepay))
+#define GST_RTP_ILBC_DEPAY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_ILBC_DEPAY,GstRTPiLBCDepay))
+#define GST_IS_RTP_ILBC_DEPAY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_ILBC_DEPAY))
+#define GST_IS_RTP_ILBC_DEPAY_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_ILBC_DEPAY))
+
+typedef enum {
+ GST_ILBC_MODE_20,
+ GST_ILBC_MODE_30
+} GstiLBCMode;
+
+struct _GstRTPiLBCDepay
+{
+ GstBaseRTPDepayload depayload;
+
+ GstiLBCMode mode;
+};
+
+struct _GstRTPiLBCDepayClass
+{
+ GstBaseRTPDepayloadClass parent_class;
+};
+
+gboolean gst_rtp_ilbc_depay_plugin_init (GstPlugin * plugin);
+
+G_END_DECLS
+
+#endif /* __GST_RTP_ILBC_DEPAY_H__ */
--- /dev/null
+/* GStreamer
+ * Copyright (C) <2006> Philippe Khalaf <burger@speedy.org>
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gstrtpilbcpay.h"
+#include <gst/rtp/gstrtpbuffer.h>
+
+/* elementfactory information */
+static GstElementDetails gst_rtpilbcpay_details = {
+ "RTP Payloader for iLBC Audio",
+ "Codec/Payloader/Network",
+ "Packetize iLBC audio streams into RTP packets",
+ "Philippe Kalaf <philippe.kalaf@collabora.co.uk>"
+};
+
+GST_DEBUG_CATEGORY (rtpilbcpay_debug);
+#define GST_CAT_DEFAULT (rtpilbcpay_debug)
+
+static GstStaticPadTemplate gst_rtpilbcpay_sink_template =
+GST_STATIC_PAD_TEMPLATE ("sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS ("audio/x-iLBC, " "mode = (int) {20, 30}")
+ );
+
+static GstStaticPadTemplate gst_rtpilbcpay_src_template =
+GST_STATIC_PAD_TEMPLATE ("src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS ("application/x-rtp, "
+ "media = (string) \"audio\", "
+ "payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
+ "clock-rate = (int) 8000, "
+ "encoding-name = (string) \"iLBC\", " "mode = (int) {20, 30}")
+ );
+
+static gboolean gst_rtpilbcpay_setcaps (GstBaseRTPPayload * payload,
+ GstCaps * caps);
+
+GST_BOILERPLATE (GstRTPILBCPay, gst_rtpilbcpay, GstBaseRTPAudioPayload,
+ GST_TYPE_BASE_RTP_AUDIO_PAYLOAD);
+
+static void
+gst_rtpilbcpay_base_init (gpointer klass)
+{
+ GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_rtpilbcpay_sink_template));
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_rtpilbcpay_src_template));
+ gst_element_class_set_details (element_class, &gst_rtpilbcpay_details);
+}
+
+static void
+gst_rtpilbcpay_class_init (GstRTPILBCPayClass * klass)
+{
+ GObjectClass *gobject_class;
+ GstElementClass *gstelement_class;
+ GstBaseRTPPayloadClass *gstbasertppayload_class;
+
+ gobject_class = (GObjectClass *) klass;
+ gstelement_class = (GstElementClass *) klass;
+ gstbasertppayload_class = (GstBaseRTPPayloadClass *) klass;
+
+ parent_class = g_type_class_ref (GST_TYPE_BASE_RTP_PAYLOAD);
+
+ gstbasertppayload_class->set_caps = gst_rtpilbcpay_setcaps;
+
+ GST_DEBUG_CATEGORY_INIT (rtpilbcpay_debug, "rtpilbcpay", 0,
+ "iLBC audio RTP payloader");
+}
+
+static void
+gst_rtpilbcpay_init (GstRTPILBCPay * rtpilbcpay, GstRTPILBCPayClass * klass)
+{
+ GstBaseRTPPayload *basertppayload;
+ GstBaseRTPAudioPayload *basertpaudiopayload;
+
+ basertppayload = GST_BASE_RTP_PAYLOAD (rtpilbcpay);
+ basertpaudiopayload = GST_BASE_RTP_AUDIO_PAYLOAD (rtpilbcpay);
+
+ /* we don't set the payload type, it should be set by the application using
+ * the pt property or the default 96 will be used */
+ basertppayload->clock_rate = 8000;
+
+ rtpilbcpay->mode = -1;
+
+ /* tell basertpaudiopayload that this is a frame based codec */
+ gst_basertpaudiopayload_set_frame_based (basertpaudiopayload);
+}
+
+static gboolean
+gst_rtpilbcpay_setcaps (GstBaseRTPPayload * basertppayload, GstCaps * caps)
+{
+ GstRTPILBCPay *rtpilbcpay;
+ GstBaseRTPAudioPayload *basertpaudiopayload;
+ gboolean ret;
+ gint mode;
+ GstStructure *structure;
+ const char *payload_name;
+
+ rtpilbcpay = GST_RTP_ILBC_PAY (basertppayload);
+ basertpaudiopayload = GST_BASE_RTP_AUDIO_PAYLOAD (basertppayload);
+
+ structure = gst_caps_get_structure (caps, 0);
+
+ gst_structure_get_int (structure, "mode", &mode);
+ if (mode != 20 && mode != 30) {
+ return FALSE;
+ }
+
+ payload_name = gst_structure_get_name (structure);
+ if (g_strcasecmp ("audio/x-iLBC", payload_name) == 0) {
+ gst_basertppayload_set_options (basertppayload, "audio", TRUE, "iLBC",
+ 8000);
+ /* set options for this frame based audio codec */
+ gst_basertpaudiopayload_set_frame_options (basertpaudiopayload,
+ mode, mode == 30 ? 50 : 38);
+ } else {
+ return FALSE;
+ }
+
+ ret =
+ gst_basertppayload_set_outcaps (basertppayload, "mode", G_TYPE_INT, mode,
+ NULL);
+ if (mode != rtpilbcpay->mode && rtpilbcpay->mode != -1) {
+ GST_ERROR_OBJECT (rtpilbcpay, "Mode has changed from %d to %d! \
+ Mode cannot change while streaming", rtpilbcpay->mode, mode);
+ return FALSE;
+ }
+ rtpilbcpay->mode = mode;
+
+ return ret;
+}
+
+gboolean
+gst_rtp_ilbc_pay_plugin_init (GstPlugin * plugin)
+{
+ return gst_element_register (plugin, "rtpilbcpay",
+ GST_RANK_NONE, GST_TYPE_RTP_ILBC_PAY);
+}
--- /dev/null
+/* GStreamer
+ * Copyright (C) <2006> Philippe Khalaf <burger@speedy.org>
+ *
+ * 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_ILBC_PAY_H__
+#define __GST_RTP_ILBC_PAY_H__
+
+#include <gst/gst.h>
+#include <gst/rtp/gstbasertpaudiopayload.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_RTP_ILBC_PAY \
+ (gst_rtpilbcpay_get_type())
+#define GST_RTP_ILBC_PAY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_ILBC_PAY,GstRTPILBCPay))
+#define GST_RTP_ILBC_PAY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_ILBC_PAY,GstRTPILBCPay))
+#define GST_IS_RTP_ILBC_PAY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_ILBC_PAY))
+#define GST_IS_RTP_ILBC_PAY_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_ILBC_PAY))
+
+typedef struct _GstRTPILBCPay GstRTPILBCPay;
+typedef struct _GstRTPILBCPayClass GstRTPILBCPayClass;
+
+struct _GstRTPILBCPay
+{
+ GstBaseRTPAudioPayload audiopayload;
+
+ gint mode;
+};
+
+struct _GstRTPILBCPayClass
+{
+ GstBaseRTPAudioPayloadClass parent_class;
+};
+
+gboolean gst_rtp_ilbc_pay_plugin_init (GstPlugin * plugin);
+
+G_END_DECLS
+
+#endif /* __GST_RTP_ILBC_PAY_H__ */
static gboolean gst_rtp_pcma_pay_setcaps (GstBaseRTPPayload * payload,
GstCaps * caps);
-static GstFlowReturn gst_rtp_pcma_pay_handle_buffer (GstBaseRTPPayload *
- payload, GstBuffer * buffer);
-static void gst_rtp_pcma_pay_finalize (GObject * object);
-GST_BOILERPLATE (GstRtpPmcaPay, gst_rtp_pcma_pay, GstBaseRTPPayload,
- GST_TYPE_BASE_RTP_PAYLOAD);
-
-/* The lower limit for number of octet to put in one packet
- * (clock-rate=8000, octet-per-sample=1). The default 80 is equal
- * to to 10msec (see RFC3551) */
-#define GST_RTP_PCMA_MIN_PTIME_OCTETS 80
+GST_BOILERPLATE (GstRtpPmcaPay, gst_rtp_pcma_pay, GstBaseRTPAudioPayload,
+ GST_TYPE_BASE_RTP_AUDIO_PAYLOAD);
static void
gst_rtp_pcma_pay_base_init (gpointer klass)
gstbasertppayload_class = (GstBaseRTPPayloadClass *) klass;
parent_class = g_type_class_peek_parent (klass);
- gobject_class->finalize = gst_rtp_pcma_pay_finalize;
gstbasertppayload_class->set_caps = gst_rtp_pcma_pay_setcaps;
- gstbasertppayload_class->handle_buffer = gst_rtp_pcma_pay_handle_buffer;
}
static void
gst_rtp_pcma_pay_init (GstRtpPmcaPay * rtppcmapay, GstRtpPmcaPayClass * klass)
{
- rtppcmapay->adapter = gst_adapter_new ();
- GST_BASE_RTP_PAYLOAD (rtppcmapay)->clock_rate = 8000;
-}
+ GstBaseRTPAudioPayload *basertpaudiopayload;
-static void
-gst_rtp_pcma_pay_finalize (GObject * object)
-{
- GstRtpPmcaPay *rtppcmapay;
+ basertpaudiopayload = GST_BASE_RTP_AUDIO_PAYLOAD (rtppcmapay);
- rtppcmapay = GST_RTP_PCMA_PAY (object);
+ GST_BASE_RTP_PAYLOAD (rtppcmapay)->clock_rate = 8000;
- g_object_unref (rtppcmapay->adapter);
- rtppcmapay->adapter = NULL;
+ /* tell basertpaudiopayload that this is a sample based codec */
+ gst_basertpaudiopayload_set_sample_based (basertpaudiopayload);
- G_OBJECT_CLASS (parent_class)->finalize (object);
+ /* octet-per-sample is 1 for PCM */
+ gst_basertpaudiopayload_set_sample_options (basertpaudiopayload, 1);
}
static gboolean
return TRUE;
}
-static GstFlowReturn
-gst_rtp_pcma_pay_flush (GstRtpPmcaPay * rtppcmapay)
-{
- guint avail;
- GstBuffer *outbuf;
- GstFlowReturn ret;
- guint maxptime_octets = G_MAXUINT;
- guint minptime_octets = GST_RTP_PCMA_MIN_PTIME_OCTETS;
-
- if (GST_BASE_RTP_PAYLOAD (rtppcmapay)->max_ptime > 0) {
- /* calculate octet count with:
- maxptime-nsec * samples-per-sec / nsecs-per-sec * octets-per-sample */
- maxptime_octets =
- GST_BASE_RTP_PAYLOAD (rtppcmapay)->max_ptime *
- GST_BASE_RTP_PAYLOAD (rtppcmapay)->clock_rate / GST_SECOND;
- }
-
- /* the data available in the adapter is either smaller
- * than the MTU or bigger. In the case it is smaller, the complete
- * adapter contents can be put in one packet. */
- avail = gst_adapter_available (rtppcmapay->adapter);
-
- ret = GST_FLOW_OK;
-
- while (avail >= minptime_octets) {
- guint8 *payload;
- guint8 *data;
- guint payload_len;
- guint packet_len;
-
- /* fill one MTU or all available bytes */
- payload_len =
- MIN (MIN (GST_BASE_RTP_PAYLOAD_MTU (rtppcmapay), maxptime_octets),
- avail);
-
- /* this will be the total lenght of the packet */
- packet_len = gst_rtp_buffer_calc_packet_len (payload_len, 0, 0);
-
- /* create buffer to hold the payload */
- outbuf = gst_rtp_buffer_new_allocate (payload_len, 0, 0);
-
- /* copy payload */
- gst_rtp_buffer_set_payload_type (outbuf,
- GST_BASE_RTP_PAYLOAD_PT (rtppcmapay));
- payload = gst_rtp_buffer_get_payload (outbuf);
- data = (guint8 *) gst_adapter_peek (rtppcmapay->adapter, payload_len);
- memcpy (payload, data, payload_len);
- gst_adapter_flush (rtppcmapay->adapter, payload_len);
-
- avail -= payload_len;
-
- GST_BUFFER_TIMESTAMP (outbuf) = rtppcmapay->first_ts;
- ret = gst_basertppayload_push (GST_BASE_RTP_PAYLOAD (rtppcmapay), outbuf);
- }
-
- return ret;
-}
-
-static GstFlowReturn
-gst_rtp_pcma_pay_handle_buffer (GstBaseRTPPayload * basepayload,
- GstBuffer * buffer)
-{
- GstRtpPmcaPay *rtppcmapay;
- guint size, packet_len, avail;
- GstFlowReturn ret;
- GstClockTime duration;
-
- rtppcmapay = GST_RTP_PCMA_PAY (basepayload);
-
- size = GST_BUFFER_SIZE (buffer);
- duration = GST_BUFFER_TIMESTAMP (buffer);
-
- avail = gst_adapter_available (rtppcmapay->adapter);
- if (avail == 0) {
- rtppcmapay->first_ts = GST_BUFFER_TIMESTAMP (buffer);
- rtppcmapay->duration = 0;
- }
-
- /* get packet length of data and see if we exceeded MTU. */
- packet_len = gst_rtp_buffer_calc_packet_len (avail + size, 0, 0);
-
- /* if this buffer is going to overflow the packet, flush what we
- * have. */
- if (gst_basertppayload_is_filled (basepayload,
- packet_len, rtppcmapay->duration + duration)) {
- ret = gst_rtp_pcma_pay_flush (rtppcmapay);
- rtppcmapay->first_ts = GST_BUFFER_TIMESTAMP (buffer);
- rtppcmapay->duration = 0;
- } else {
- ret = GST_FLOW_OK;
- }
-
- gst_adapter_push (rtppcmapay->adapter, buffer);
- rtppcmapay->duration += duration;
-
- return ret;
-}
-
gboolean
gst_rtp_pcma_pay_plugin_init (GstPlugin * plugin)
{
#define __GST_RTP_PCMA_PAY_H__
#include <gst/gst.h>
-#include <gst/rtp/gstbasertppayload.h>
-#include <gst/base/gstadapter.h>
+#include <gst/rtp/gstbasertpaudiopayload.h>
G_BEGIN_DECLS
struct _GstRtpPmcaPay
{
- GstBaseRTPPayload payload;
- GstAdapter *adapter;
-
- GstClockTime first_ts;
- GstClockTime duration;
+ GstBaseRTPAudioPayload audiopayload;
};
struct _GstRtpPmcaPayClass
{
- GstBaseRTPPayloadClass parent_class;
+ GstBaseRTPAudioPayloadClass parent_class;
};
gboolean gst_rtp_pcma_pay_plugin_init (GstPlugin * plugin);
static gboolean gst_rtp_pcmu_pay_setcaps (GstBaseRTPPayload * payload,
GstCaps * caps);
-static GstFlowReturn gst_rtp_pcmu_pay_handle_buffer (GstBaseRTPPayload *
- payload, GstBuffer * buffer);
-static void gst_rtp_pcmu_pay_finalize (GObject * object);
-GST_BOILERPLATE (GstRtpPcmuPay, gst_rtp_pcmu_pay, GstBaseRTPPayload,
- GST_TYPE_BASE_RTP_PAYLOAD);
-
-/* The lower limit for number of octet to put in one packet
- * (clock-rate=8000, octet-per-sample=1). The default 80 is equal
- * to to 10msec (see RFC3551) */
-#define GST_RTP_PCMU_MIN_PTIME_OCTETS 80
+GST_BOILERPLATE (GstRtpPcmuPay, gst_rtp_pcmu_pay, GstBaseRTPAudioPayload,
+ GST_TYPE_BASE_RTP_AUDIO_PAYLOAD);
static void
gst_rtp_pcmu_pay_base_init (gpointer klass)
gstbasertppayload_class = (GstBaseRTPPayloadClass *) klass;
parent_class = g_type_class_peek_parent (klass);
- gobject_class->finalize = gst_rtp_pcmu_pay_finalize;
gstbasertppayload_class->set_caps = gst_rtp_pcmu_pay_setcaps;
- gstbasertppayload_class->handle_buffer = gst_rtp_pcmu_pay_handle_buffer;
}
static void
gst_rtp_pcmu_pay_init (GstRtpPcmuPay * rtppcmupay, GstRtpPcmuPayClass * klass)
{
- rtppcmupay->adapter = gst_adapter_new ();
- GST_BASE_RTP_PAYLOAD (rtppcmupay)->clock_rate = 8000;
-}
+ GstBaseRTPAudioPayload *basertpaudiopayload;
-static void
-gst_rtp_pcmu_pay_finalize (GObject * object)
-{
- GstRtpPcmuPay *rtppcmupay;
+ basertpaudiopayload = GST_BASE_RTP_AUDIO_PAYLOAD (rtppcmupay);
- rtppcmupay = GST_RTP_PCMU_PAY (object);
+ GST_BASE_RTP_PAYLOAD (rtppcmupay)->clock_rate = 8000;
- g_object_unref (rtppcmupay->adapter);
- rtppcmupay->adapter = NULL;
+ /* tell basertpaudiopayload that this is a sample based codec */
+ gst_basertpaudiopayload_set_sample_based (basertpaudiopayload);
- G_OBJECT_CLASS (parent_class)->finalize (object);
+ /* octet-per-sample is 1 for PCM */
+ gst_basertpaudiopayload_set_sample_options (basertpaudiopayload, 1);
}
static gboolean
return TRUE;
}
-static GstFlowReturn
-gst_rtp_pcmu_pay_flush (GstRtpPcmuPay * rtppcmupay)
-{
- guint avail;
- GstBuffer *outbuf;
- GstFlowReturn ret;
- guint maxptime_octets = G_MAXUINT;
- guint minptime_octets = GST_RTP_PCMU_MIN_PTIME_OCTETS;
-
- if (GST_BASE_RTP_PAYLOAD (rtppcmupay)->max_ptime > 0) {
- /* calculate octet count with:
- maxptime-nsec * samples-per-sec / nsecs-per-sec * octets-per-sample */
- maxptime_octets =
- GST_BASE_RTP_PAYLOAD (rtppcmupay)->max_ptime *
- GST_BASE_RTP_PAYLOAD (rtppcmupay)->clock_rate / GST_SECOND;
- }
-
- /* the data available in the adapter is either smaller
- * than the MTU or bigger. In the case it is smaller, the complete
- * adapter contents can be put in one packet. */
- avail = gst_adapter_available (rtppcmupay->adapter);
-
- ret = GST_FLOW_OK;
-
- while (avail >= minptime_octets) {
- guint8 *payload;
- guint8 *data;
- guint payload_len;
- guint packet_len;
-
- /* fill one MTU or all available bytes */
- payload_len =
- MIN (MIN (GST_BASE_RTP_PAYLOAD_MTU (rtppcmupay), maxptime_octets),
- avail);
-
- /* this will be the total lenght of the packet */
- packet_len = gst_rtp_buffer_calc_packet_len (payload_len, 0, 0);
-
- /* create buffer to hold the payload */
- outbuf = gst_rtp_buffer_new_allocate (payload_len, 0, 0);
-
- /* copy payload */
- gst_rtp_buffer_set_payload_type (outbuf,
- GST_BASE_RTP_PAYLOAD_PT (rtppcmupay));
- payload = gst_rtp_buffer_get_payload (outbuf);
- data = (guint8 *) gst_adapter_peek (rtppcmupay->adapter, payload_len);
- memcpy (payload, data, payload_len);
- gst_adapter_flush (rtppcmupay->adapter, payload_len);
-
- avail -= payload_len;
-
- GST_BUFFER_TIMESTAMP (outbuf) = rtppcmupay->first_ts;
- ret = gst_basertppayload_push (GST_BASE_RTP_PAYLOAD (rtppcmupay), outbuf);
- }
-
- return ret;
-}
-
-static GstFlowReturn
-gst_rtp_pcmu_pay_handle_buffer (GstBaseRTPPayload * basepayload,
- GstBuffer * buffer)
-{
- GstRtpPcmuPay *rtppcmupay;
- guint size, packet_len, avail;
- GstFlowReturn ret;
- GstClockTime duration;
-
- rtppcmupay = GST_RTP_PCMU_PAY (basepayload);
-
- size = GST_BUFFER_SIZE (buffer);
- duration = GST_BUFFER_TIMESTAMP (buffer);
-
- avail = gst_adapter_available (rtppcmupay->adapter);
- if (avail == 0) {
- rtppcmupay->first_ts = GST_BUFFER_TIMESTAMP (buffer);
- rtppcmupay->duration = 0;
- }
-
- /* get packet length of data and see if we exceeded MTU. */
- packet_len = gst_rtp_buffer_calc_packet_len (avail + size, 0, 0);
-
- /* if this buffer is going to overflow the packet, flush what we
- * have. */
- if (gst_basertppayload_is_filled (basepayload,
- packet_len, rtppcmupay->duration + duration)) {
- ret = gst_rtp_pcmu_pay_flush (rtppcmupay);
- rtppcmupay->first_ts = GST_BUFFER_TIMESTAMP (buffer);
- rtppcmupay->duration = 0;
- } else {
- ret = GST_FLOW_OK;
- }
-
- gst_adapter_push (rtppcmupay->adapter, buffer);
- rtppcmupay->duration += duration;
-
- return ret;
-}
-
gboolean
gst_rtp_pcmu_pay_plugin_init (GstPlugin * plugin)
{
#define __GST_RTP_PCMU_PAY_H__
#include <gst/gst.h>
-#include <gst/rtp/gstbasertppayload.h>
-#include <gst/base/gstadapter.h>
+#include <gst/rtp/gstbasertpaudiopayload.h>
G_BEGIN_DECLS
struct _GstRtpPcmuPay
{
- GstBaseRTPPayload payload;
- GstAdapter *adapter;
-
- GstClockTime first_ts;
- GstClockTime duration;
+ GstBaseRTPAudioPayload audiopayload;
};
struct _GstRtpPcmuPayClass
{
- GstBaseRTPPayloadClass parent_class;
+ GstBaseRTPAudioPayloadClass parent_class;
};
gboolean gst_rtp_pcmu_pay_plugin_init (GstPlugin * plugin);