diff options
-rw-r--r-- | ChangeLog | 16 | ||||
-rw-r--r-- | gst/rtp/Makefile.am | 4 | ||||
-rw-r--r-- | gst/rtp/gstrtp.c | 8 | ||||
-rw-r--r-- | gst/rtp/gstrtpilbcdepay.c | 222 | ||||
-rw-r--r-- | gst/rtp/gstrtpilbcdepay.h | 63 | ||||
-rw-r--r-- | gst/rtp/gstrtpilbcpay.c | 161 | ||||
-rw-r--r-- | gst/rtp/gstrtpilbcpay.h | 58 | ||||
-rw-r--r-- | gst/rtp/gstrtppcmapay.c | 130 | ||||
-rw-r--r-- | gst/rtp/gstrtppcmapay.h | 11 | ||||
-rw-r--r-- | gst/rtp/gstrtppcmupay.c | 130 | ||||
-rw-r--r-- | gst/rtp/gstrtppcmupay.h | 11 |
11 files changed, 556 insertions, 258 deletions
@@ -1,3 +1,19 @@ +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), diff --git a/gst/rtp/Makefile.am b/gst/rtp/Makefile.am index 82648b51..0dd25e5d 100644 --- a/gst/rtp/Makefile.am +++ b/gst/rtp/Makefile.am @@ -16,6 +16,8 @@ libgstrtp_la_SOURCES = \ gstrtph263pdepay.c \ gstrtph263ppay.c \ gstrtph263pay.c \ + gstrtpilbcpay.c \ + gstrtpilbcdepay.c \ gstasteriskh263.c \ gstrtpmp4vdepay.c \ gstrtpmp4vpay.c \ @@ -52,6 +54,8 @@ noinst_HEADERS = \ gstrtph263pdepay.h \ gstrtph263ppay.h \ gstrtph263pay.h \ + gstrtpilbcpay.h \ + gstrtpilbcdepay.h \ gstrtpmp4vdepay.h \ gstrtpmp4vpay.h \ gstrtpmp4gpay.h \ diff --git a/gst/rtp/gstrtp.c b/gst/rtp/gstrtp.c index e80d4d6d..d5cd86ae 100644 --- a/gst/rtp/gstrtp.c +++ b/gst/rtp/gstrtp.c @@ -35,6 +35,8 @@ #include "gstrtph263pdepay.h" #include "gstrtph263ppay.h" #include "gstrtph263pay.h" +#include "gstrtpilbcpay.h" +#include "gstrtpilbcdepay.h" #include "gstasteriskh263.h" #include "gstrtpmp4vpay.h" #include "gstrtpmp4gpay.h" @@ -87,6 +89,12 @@ plugin_init (GstPlugin * plugin) 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; diff --git a/gst/rtp/gstrtpilbcdepay.c b/gst/rtp/gstrtpilbcdepay.c new file mode 100644 index 00000000..1dd5bdef --- /dev/null +++ b/gst/rtp/gstrtpilbcdepay.c @@ -0,0 +1,222 @@ +/* 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); +} diff --git a/gst/rtp/gstrtpilbcdepay.h b/gst/rtp/gstrtpilbcdepay.h new file mode 100644 index 00000000..646fcafd --- /dev/null +++ b/gst/rtp/gstrtpilbcdepay.h @@ -0,0 +1,63 @@ +/* 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__ */ diff --git a/gst/rtp/gstrtpilbcpay.c b/gst/rtp/gstrtpilbcpay.c new file mode 100644 index 00000000..7dbac86c --- /dev/null +++ b/gst/rtp/gstrtpilbcpay.c @@ -0,0 +1,161 @@ +/* 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); +} diff --git a/gst/rtp/gstrtpilbcpay.h b/gst/rtp/gstrtpilbcpay.h new file mode 100644 index 00000000..3b527d11 --- /dev/null +++ b/gst/rtp/gstrtpilbcpay.h @@ -0,0 +1,58 @@ +/* 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__ */ diff --git a/gst/rtp/gstrtppcmapay.c b/gst/rtp/gstrtppcmapay.c index 439efaa9..940e6caa 100644 --- a/gst/rtp/gstrtppcmapay.c +++ b/gst/rtp/gstrtppcmapay.c @@ -50,17 +50,9 @@ GST_STATIC_PAD_TEMPLATE ("src", 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) @@ -86,30 +78,24 @@ gst_rtp_pcma_pay_class_init (GstRtpPmcaPayClass * 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 @@ -123,104 +109,6 @@ gst_rtp_pcma_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps) 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) { diff --git a/gst/rtp/gstrtppcmapay.h b/gst/rtp/gstrtppcmapay.h index 0d498544..9c8557e2 100644 --- a/gst/rtp/gstrtppcmapay.h +++ b/gst/rtp/gstrtppcmapay.h @@ -17,8 +17,7 @@ #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 @@ -38,16 +37,12 @@ typedef struct _GstRtpPmcaPayClass GstRtpPmcaPayClass; 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); diff --git a/gst/rtp/gstrtppcmupay.c b/gst/rtp/gstrtppcmupay.c index ffb220b5..02ba1f84 100644 --- a/gst/rtp/gstrtppcmupay.c +++ b/gst/rtp/gstrtppcmupay.c @@ -50,17 +50,9 @@ GST_STATIC_PAD_TEMPLATE ("src", 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) @@ -86,30 +78,24 @@ gst_rtp_pcmu_pay_class_init (GstRtpPcmuPayClass * 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 @@ -123,104 +109,6 @@ gst_rtp_pcmu_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps) 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) { diff --git a/gst/rtp/gstrtppcmupay.h b/gst/rtp/gstrtppcmupay.h index 046071bd..7b736054 100644 --- a/gst/rtp/gstrtppcmupay.h +++ b/gst/rtp/gstrtppcmupay.h @@ -17,8 +17,7 @@ #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 @@ -38,16 +37,12 @@ typedef struct _GstRtpPcmuPayClass GstRtpPcmuPayClass; 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); |