diff options
author | Wim Taymans <wim.taymans@gmail.com> | 2007-01-24 18:20:14 +0000 |
---|---|---|
committer | Wim Taymans <wim.taymans@gmail.com> | 2007-01-24 18:20:14 +0000 |
commit | 85420195b22b54f306833be2d4ba66fd2ff6b6e8 (patch) | |
tree | a6100c8b69d0291ae4e2e694121b34cab2fc37a0 /gst/rtp/gstrtpL16depay.c | |
parent | a6a9207c4298081d2af237edd04e337e5d175e0d (diff) | |
download | gstreamer-plugins-good-85420195b22b54f306833be2d4ba66fd2ff6b6e8.tar.gz |
gst/rtp/: Port and enable raw audio payloader/depayloader. Needs a bit more work on the payloader side.
Original commit message from CVS:
* gst/rtp/Makefile.am:
* gst/rtp/gstrtp.c: (plugin_init):
* gst/rtp/gstrtpL16depay.c: (gst_rtp_L16_depay_base_init),
(gst_rtp_L16_depay_class_init), (gst_rtp_L16_depay_init),
(gst_rtp_L16_depay_parse_int), (gst_rtp_L16_depay_setcaps),
(gst_rtp_L16_depay_process), (gst_rtp_L16_depay_set_property),
(gst_rtp_L16_depay_get_property), (gst_rtp_L16_depay_change_state),
(gst_rtp_L16_depay_plugin_init):
* gst/rtp/gstrtpL16depay.h:
* gst/rtp/gstrtpL16pay.c: (gst_rtp_L16_pay_get_type),
(gst_rtp_L16_pay_base_init), (gst_rtp_L16_pay_class_init),
(gst_rtp_L16_pay_init), (gst_rtp_L16_pay_finalize),
(gst_rtp_L16_pay_setcaps), (gst_rtp_L16_pay_handle_buffer),
(gst_rtp_L16_pay_plugin_init):
* gst/rtp/gstrtpL16pay.h:
Port and enable raw audio payloader/depayloader. Needs a bit more work
on the payloader side.
Diffstat (limited to 'gst/rtp/gstrtpL16depay.c')
-rw-r--r-- | gst/rtp/gstrtpL16depay.c | 321 |
1 files changed, 141 insertions, 180 deletions
diff --git a/gst/rtp/gstrtpL16depay.c b/gst/rtp/gstrtpL16depay.c index bffbcbd4a..1f37a22f3 100644 --- a/gst/rtp/gstrtpL16depay.c +++ b/gst/rtp/gstrtpL16depay.c @@ -1,5 +1,5 @@ /* GStreamer - * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> + * Copyright (C) <2007> 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 @@ -21,293 +21,258 @@ #include "config.h" #endif #include <string.h> + #include "gstrtpL16depay.h" -#include "gstrtp-common.h" + +GST_DEBUG_CATEGORY_STATIC (rtpL16depay_debug); +#define GST_CAT_DEFAULT (rtpL16depay_debug) /* elementfactory information */ -static const GstElementDetails gst_rtp_L16depay_details = +static const GstElementDetails gst_rtp_L16_depay_details = GST_ELEMENT_DETAILS ("RTP packet depayloader", "Codec/Depayloader/Network", "Extracts raw audio from RTP packets", - "Zeeshan Ali <zak147@yahoo.com>"); + "Zeeshan Ali <zak147@yahoo.com>," "Wim Taymans <wim@fluendo.com>"); /* RtpL16Depay signals and args */ enum { - /* FILL ME */ LAST_SIGNAL }; enum { ARG_0, - ARG_FREQUENCY, - ARG_PAYLOAD_TYPE }; -static GstStaticPadTemplate gst_rtp_L16depay_src_template = +static GstStaticPadTemplate gst_rtp_L16_depay_src_template = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS ("audio/x-raw-int, " - "endianness = (int) BYTE_ORDER, " + "endianness = (int) BIG_ENDIAN, " "signed = (boolean) true, " "width = (int) 16, " "depth = (int) 16, " - "rate = (int) [ 1000, 48000 ], " "channels = (int) [ 1, 2 ]") + "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, MAX ]") ); -static GstStaticPadTemplate gst_rtp_L16depay_sink_template = -GST_STATIC_PAD_TEMPLATE ("sink", +static GstStaticPadTemplate gst_rtp_L16_depay_sink_template = + GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS ("application/x-rtp") + GST_STATIC_CAPS ("application/x-rtp, " + "media = (string) \"audio\", " + "payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", " + "clock-rate = (int) [ 1, MAX ], " + /* "channels = (int) [1, MAX]" */ + /* "emphasis = (string) ANY" */ + /* "channel-order = (string) ANY" */ + "encoding-name = (string) \"L16\";" + "application/x-rtp, " + "media = (string) \"audio\", " + "payload = (int) { " GST_RTP_PAYLOAD_L16_STEREO_STRING ", " + GST_RTP_PAYLOAD_L16_MONO_STRING " }," "clock-rate = (int) [ 1, MAX ]" + /* "channels = (int) [1, MAX]" */ + /* "emphasis = (string) ANY" */ + /* "channel-order = (string) ANY" */ + ) ); -static void gst_rtp_L16depay_class_init (GstRtpL16DepayClass * klass); -static void gst_rtp_L16depay_base_init (GstRtpL16DepayClass * klass); -static void gst_rtp_L16depay_init (GstRtpL16Depay * rtpL16depay); +GST_BOILERPLATE (GstRtpL16Depay, gst_rtp_L16_depay, GstBaseRTPDepayload, + GST_TYPE_BASE_RTP_DEPAYLOAD); -static void gst_rtp_L16depay_chain (GstPad * pad, GstData * _data); +static gboolean gst_rtp_L16_depay_setcaps (GstBaseRTPDepayload * depayload, + GstCaps * caps); +static GstBuffer *gst_rtp_L16_depay_process (GstBaseRTPDepayload * depayload, + GstBuffer * buf); -static void gst_rtp_L16depay_set_property (GObject * object, guint prop_id, +static void gst_rtp_L16_depay_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); -static void gst_rtp_L16depay_get_property (GObject * object, guint prop_id, +static void gst_rtp_L16_depay_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -static GstStateChangeReturn gst_rtp_L16depay_change_state (GstElement * - element); - -static GstElementClass *parent_class = NULL; -static GType -gst_rtp_L16depay_get_type (void) -{ - static GType rtpL16depay_type = 0; - - if (!rtpL16depay_type) { - static const GTypeInfo rtpL16depay_info = { - sizeof (GstRtpL16DepayClass), - (GBaseInitFunc) gst_rtp_L16depay_base_init, - NULL, - (GClassInitFunc) gst_rtp_L16depay_class_init, - NULL, - NULL, - sizeof (GstRtpL16Depay), - 0, - (GInstanceInitFunc) gst_rtp_L16depay_init, - }; - - rtpL16depay_type = - g_type_register_static (GST_TYPE_ELEMENT, "GstRtpL16Depay", - &rtpL16depay_info, 0); - } - return rtpL16depay_type; -} +static GstStateChangeReturn gst_rtp_L16_depay_change_state (GstElement * + element, GstStateChange transition); static void -gst_rtp_L16depay_base_init (GstRtpL16DepayClass * klass) +gst_rtp_L16_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_L16depay_src_template)); + gst_static_pad_template_get (&gst_rtp_L16_depay_src_template)); gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_rtp_L16depay_sink_template)); - gst_element_class_set_details (element_class, &gst_rtp_L16depay_details); + gst_static_pad_template_get (&gst_rtp_L16_depay_sink_template)); + + gst_element_class_set_details (element_class, &gst_rtp_L16_depay_details); } static void -gst_rtp_L16depay_class_init (GstRtpL16DepayClass * klass) +gst_rtp_L16_depay_class_init (GstRtpL16DepayClass * klass) { GObjectClass *gobject_class; GstElementClass *gstelement_class; + GstBaseRTPDepayloadClass *gstbasertpdepayload_class; gobject_class = (GObjectClass *) klass; gstelement_class = (GstElementClass *) klass; + gstbasertpdepayload_class = (GstBaseRTPDepayloadClass *) klass; parent_class = g_type_class_peek_parent (klass); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PAYLOAD_TYPE, - g_param_spec_int ("payload_type", "payload_type", "payload type", - G_MININT, G_MAXINT, PAYLOAD_L16_STEREO, G_PARAM_READABLE)); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FREQUENCY, - g_param_spec_int ("frequency", "frequency", "frequency", - G_MININT, G_MAXINT, 44100, G_PARAM_READWRITE)); + gobject_class->set_property = gst_rtp_L16_depay_set_property; + gobject_class->get_property = gst_rtp_L16_depay_get_property; + + gstelement_class->change_state = gst_rtp_L16_depay_change_state; - gobject_class->set_property = gst_rtp_L16depay_set_property; - gobject_class->get_property = gst_rtp_L16depay_get_property; + gstbasertpdepayload_class->set_caps = gst_rtp_L16_depay_setcaps; + gstbasertpdepayload_class->process = gst_rtp_L16_depay_process; - gstelement_class->change_state = gst_rtp_L16depay_change_state; + GST_DEBUG_CATEGORY_INIT (rtpL16depay_debug, "rtpL16depay", 0, + "Raw Audio RTP Depayloader"); } static void -gst_rtp_L16depay_init (GstRtpL16Depay * rtpL16depay) +gst_rtp_L16_depay_init (GstRtpL16Depay * rtpL16depay, + GstRtpL16DepayClass * klass) { - rtpL16depay->srcpad = - gst_pad_new_from_static_template (&gst_rtp_L16depay_src_template, "src"); - rtpL16depay->sinkpad = - gst_pad_new_from_static_template (&gst_rtp_L16depay_sink_template, - "sink"); - gst_element_add_pad (GST_ELEMENT (rtpL16depay), rtpL16depay->srcpad); - gst_element_add_pad (GST_ELEMENT (rtpL16depay), rtpL16depay->sinkpad); - gst_pad_set_chain_function (rtpL16depay->sinkpad, gst_rtp_L16depay_chain); - - rtpL16depay->frequency = 44100; - rtpL16depay->channels = 2; - - rtpL16depay->payload_type = PAYLOAD_L16_STEREO; } -void -gst_rtp_L16depay_ntohs (GstBuffer * buf) +static gint +gst_rtp_L16_depay_parse_int (GstStructure * structure, const gchar * field, + gint def) { - gint16 *i, *len; + const gchar *str; + gint res; - /* FIXME: is this code correct or even sane at all? */ - i = (gint16 *) GST_BUFFER_DATA (buf); - len = i + GST_BUFFER_SIZE (buf) / sizeof (gint16 *); + if ((str = gst_structure_get_string (structure, field))) + return atoi (str); - for (; i < len; i++) { - *i = g_ntohs (*i); - } + if (gst_structure_get_int (structure, field, &res)) + return res; + + return def; } -void -gst_rtp_L16_caps_nego (GstRtpL16Depay * rtpL16depay) +static gboolean +gst_rtp_L16_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps) { - GstCaps *caps; - - caps = - gst_caps_copy (gst_static_caps_get (&gst_rtp_L16depay_src_template. - static_caps)); + GstStructure *structure; + GstRtpL16Depay *rtpL16depay; + gint clock_rate, payload; + gint channels; + GstCaps *srccaps; - gst_caps_set_simple (caps, - "rate", G_TYPE_INT, rtpL16depay->frequency, - "channel", G_TYPE_INT, rtpL16depay->channels, NULL); + rtpL16depay = GST_RTP_L16_DEPAY (depayload); - gst_pad_try_set_caps (rtpL16depay->srcpad, caps); -} + structure = gst_caps_get_structure (caps, 0); -void -gst_rtp_L16depay_payloadtype_change (GstRtpL16Depay * rtpL16depay, - rtp_payload_t pt) -{ - rtpL16depay->payload_type = pt; - - switch (pt) { - case PAYLOAD_L16_MONO: - rtpL16depay->channels = 1; + payload = 96; + gst_structure_get_int (structure, "payload", &payload); + switch (payload) { + case GST_RTP_PAYLOAD_L16_STEREO: + channels = 2; + clock_rate = 44100; break; - case PAYLOAD_L16_STEREO: - rtpL16depay->channels = 2; + case GST_RTP_PAYLOAD_L16_MONO: + channels = 1; + clock_rate = 44100; break; default: - g_warning ("unknown payload_t %d\n", pt); + channels = 0; + clock_rate = 0; + break; } - gst_rtp_L16_caps_nego (rtpL16depay); + /* caps can overwrite defaults */ + clock_rate = + gst_rtp_L16_depay_parse_int (structure, "clock-rate", clock_rate); + channels = gst_rtp_L16_depay_parse_int (structure, "channels", channels); + + depayload->clock_rate = clock_rate; + rtpL16depay->rate = clock_rate; + rtpL16depay->channels = channels; + + srccaps = gst_caps_new_simple ("audio/x-raw-int", + "endianness", G_TYPE_INT, G_BIG_ENDIAN, + "signed", G_TYPE_BOOLEAN, TRUE, + "width", G_TYPE_INT, 16, + "depth", G_TYPE_INT, 16, + "rate", G_TYPE_INT, clock_rate, "channels", G_TYPE_INT, channels, NULL); + + gst_pad_set_caps (depayload->srcpad, srccaps); + gst_caps_unref (srccaps); + + return TRUE; } -static void -gst_rtp_L16depay_chain (GstPad * pad, GstData * _data) +static GstBuffer * +gst_rtp_L16_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf) { - GstBuffer *buf = GST_BUFFER (_data); GstRtpL16Depay *rtpL16depay; GstBuffer *outbuf; - Rtp_Packet packet; - rtp_payload_t pt; - g_return_if_fail (pad != NULL); - g_return_if_fail (GST_IS_PAD (pad)); - g_return_if_fail (buf != NULL); + rtpL16depay = GST_RTP_L16_DEPAY (depayload); - rtpL16depay = GST_RTP_L16_DEPAY (GST_OBJECT_PARENT (pad)); + if (!gst_rtp_buffer_validate (buf)) + goto bad_packet; - g_return_if_fail (rtpL16depay != NULL); - g_return_if_fail (GST_IS_RTP_L16_DEPAY (rtpL16depay)); + { + gint payload_len; + guint8 *payload; - if (GST_IS_EVENT (buf)) { - GstEvent *event = GST_EVENT (buf); + payload_len = gst_rtp_buffer_get_payload_len (buf); + payload = gst_rtp_buffer_get_payload (buf); - gst_pad_event_default (pad, event); + if (payload_len <= 0) + goto empty_packet; - return; - } - - if (GST_PAD_CAPS (rtpL16depay->srcpad) == NULL) { - gst_rtp_L16_caps_nego (rtpL16depay); - } + GST_DEBUG_OBJECT (rtpL16depay, "got payload of %d bytes", payload_len); - packet = - rtp_packet_new_copy_data (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); + outbuf = gst_rtp_buffer_get_payload_buffer (buf); - pt = rtp_packet_get_payload_type (packet); - - if (pt != rtpL16depay->payload_type) { - gst_rtp_L16depay_payloadtype_change (rtpL16depay, pt); + return outbuf; } + return NULL; - outbuf = gst_buffer_new (); - GST_BUFFER_SIZE (outbuf) = rtp_packet_get_payload_len (packet); - GST_BUFFER_DATA (outbuf) = g_malloc (GST_BUFFER_SIZE (outbuf)); - GST_BUFFER_TIMESTAMP (outbuf) = - g_ntohl (rtp_packet_get_timestamp (packet)) * GST_SECOND; - - memcpy (GST_BUFFER_DATA (outbuf), rtp_packet_get_payload (packet), - GST_BUFFER_SIZE (outbuf)); - - GST_DEBUG ("gst_rtp_L16depay_chain: pushing buffer of size %d", - GST_BUFFER_SIZE (outbuf)); - - /* FIXME: According to RFC 1890, this is required, right? */ -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - gst_rtp_L16depay_ntohs (outbuf); -#endif - - gst_pad_push (rtpL16depay->srcpad, GST_DATA (outbuf)); - - rtp_packet_free (packet); - gst_buffer_unref (buf); +bad_packet: + { + GST_ELEMENT_WARNING (rtpL16depay, STREAM, DECODE, + ("Packet did not validate."), (NULL)); + return NULL; + } +empty_packet: + { + GST_ELEMENT_WARNING (rtpL16depay, STREAM, DECODE, + ("Empty Payload."), (NULL)); + return NULL; + } } static void -gst_rtp_L16depay_set_property (GObject * object, guint prop_id, +gst_rtp_L16_depay_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstRtpL16Depay *rtpL16depay; - g_return_if_fail (GST_IS_RTP_L16_DEPAY (object)); rtpL16depay = GST_RTP_L16_DEPAY (object); switch (prop_id) { - case ARG_PAYLOAD_TYPE: - gst_rtp_L16depay_payloadtype_change (rtpL16depay, - g_value_get_int (value)); - break; - case ARG_FREQUENCY: - rtpL16depay->frequency = g_value_get_int (value); - break; default: break; } } static void -gst_rtp_L16depay_get_property (GObject * object, guint prop_id, GValue * value, +gst_rtp_L16_depay_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstRtpL16Depay *rtpL16depay; - g_return_if_fail (GST_IS_RTP_L16_DEPAY (object)); rtpL16depay = GST_RTP_L16_DEPAY (object); switch (prop_id) { - case ARG_PAYLOAD_TYPE: - g_value_set_int (value, rtpL16depay->payload_type); - break; - case ARG_FREQUENCY: - g_value_set_int (value, rtpL16depay->frequency); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -315,23 +280,20 @@ gst_rtp_L16depay_get_property (GObject * object, guint prop_id, GValue * value, } static GstStateChangeReturn -gst_rtp_L16depay_change_state (GstElement * element, GstStateChange transition) +gst_rtp_L16_depay_change_state (GstElement * element, GstStateChange transition) { GstRtpL16Depay *rtpL16depay; GstStateChangeReturn ret; rtpL16depay = GST_RTP_L16_DEPAY (element); - GST_DEBUG ("state pending %d\n", GST_STATE_PENDING (element)); - - switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: break; default: break; } - /* if we haven't failed already, give the parent class a chance to ;-) */ + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); switch (transition) { @@ -340,12 +302,11 @@ gst_rtp_L16depay_change_state (GstElement * element, GstStateChange transition) default: break; } - return ret; } gboolean -gst_rtp_L16depay_plugin_init (GstPlugin * plugin) +gst_rtp_L16_depay_plugin_init (GstPlugin * plugin) { return gst_element_register (plugin, "rtpL16depay", GST_RANK_MARGINAL, GST_TYPE_RTP_L16_DEPAY); |