2 * Copyright (C) <2007> Wim Taymans <wim@fluendo.com>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
27 #include <gst/audio/audio.h>
28 #include <gst/audio/multichannel.h>
30 #include "gstrtpL16depay.h"
31 #include "gstrtpchannels.h"
33 GST_DEBUG_CATEGORY_STATIC (rtpL16depay_debug);
34 #define GST_CAT_DEFAULT (rtpL16depay_debug)
36 /* elementfactory information */
37 static const GstElementDetails gst_rtp_L16_depay_details =
38 GST_ELEMENT_DETAILS ("RTP packet depayloader",
39 "Codec/Depayloader/Network",
40 "Extracts raw audio from RTP packets",
41 "Zeeshan Ali <zak147@yahoo.com>," "Wim Taymans <wim@fluendo.com>");
43 static GstStaticPadTemplate gst_rtp_L16_depay_src_template =
44 GST_STATIC_PAD_TEMPLATE ("src",
47 GST_STATIC_CAPS ("audio/x-raw-int, "
48 "endianness = (int) BIG_ENDIAN, "
49 "signed = (boolean) true, "
52 "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, MAX ]")
55 static GstStaticPadTemplate gst_rtp_L16_depay_sink_template =
56 GST_STATIC_PAD_TEMPLATE ("sink",
59 GST_STATIC_CAPS ("application/x-rtp, "
60 "media = (string) \"audio\", "
61 "payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
62 "clock-rate = (int) [ 1, MAX ], "
63 /* "channels = (int) [1, MAX]" */
64 /* "emphasis = (string) ANY" */
65 /* "channel-order = (string) ANY" */
66 "encoding-name = (string) \"L16\";"
68 "media = (string) \"audio\", "
69 "payload = (int) { " GST_RTP_PAYLOAD_L16_STEREO_STRING ", "
70 GST_RTP_PAYLOAD_L16_MONO_STRING " }," "clock-rate = (int) [ 1, MAX ]"
71 /* "channels = (int) [1, MAX]" */
72 /* "emphasis = (string) ANY" */
73 /* "channel-order = (string) ANY" */
77 GST_BOILERPLATE (GstRtpL16Depay, gst_rtp_L16_depay, GstBaseRTPDepayload,
78 GST_TYPE_BASE_RTP_DEPAYLOAD);
80 static gboolean gst_rtp_L16_depay_setcaps (GstBaseRTPDepayload * depayload,
82 static GstBuffer *gst_rtp_L16_depay_process (GstBaseRTPDepayload * depayload,
85 static GstStateChangeReturn gst_rtp_L16_depay_change_state (GstElement *
86 element, GstStateChange transition);
89 gst_rtp_L16_depay_base_init (gpointer klass)
91 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
93 gst_element_class_add_pad_template (element_class,
94 gst_static_pad_template_get (&gst_rtp_L16_depay_src_template));
95 gst_element_class_add_pad_template (element_class,
96 gst_static_pad_template_get (&gst_rtp_L16_depay_sink_template));
98 gst_element_class_set_details (element_class, &gst_rtp_L16_depay_details);
102 gst_rtp_L16_depay_class_init (GstRtpL16DepayClass * klass)
104 GstElementClass *gstelement_class;
105 GstBaseRTPDepayloadClass *gstbasertpdepayload_class;
107 gstelement_class = (GstElementClass *) klass;
108 gstbasertpdepayload_class = (GstBaseRTPDepayloadClass *) klass;
110 parent_class = g_type_class_peek_parent (klass);
112 gstelement_class->change_state = gst_rtp_L16_depay_change_state;
114 gstbasertpdepayload_class->set_caps = gst_rtp_L16_depay_setcaps;
115 gstbasertpdepayload_class->process = gst_rtp_L16_depay_process;
117 GST_DEBUG_CATEGORY_INIT (rtpL16depay_debug, "rtpL16depay", 0,
118 "Raw Audio RTP Depayloader");
122 gst_rtp_L16_depay_init (GstRtpL16Depay * rtpL16depay,
123 GstRtpL16DepayClass * klass)
125 /* needed because of GST_BOILERPLATE */
129 gst_rtp_L16_depay_parse_int (GstStructure * structure, const gchar * field,
135 if ((str = gst_structure_get_string (structure, field)))
138 if (gst_structure_get_int (structure, field, &res))
145 gst_rtp_L16_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
147 GstStructure *structure;
148 GstRtpL16Depay *rtpL16depay;
149 gint clock_rate, payload;
153 const gchar *channel_order;
154 const GstRTPChannelOrder *order;
156 rtpL16depay = GST_RTP_L16_DEPAY (depayload);
158 structure = gst_caps_get_structure (caps, 0);
161 gst_structure_get_int (structure, "payload", &payload);
163 case GST_RTP_PAYLOAD_L16_STEREO:
167 case GST_RTP_PAYLOAD_L16_MONO:
172 /* no fixed mapping, we need channels and clock-rate */
178 /* caps can overwrite defaults */
180 gst_rtp_L16_depay_parse_int (structure, "clock-rate", clock_rate);
184 channels = gst_rtp_L16_depay_parse_int (structure, "channels", channels);
188 depayload->clock_rate = clock_rate;
189 rtpL16depay->rate = clock_rate;
190 rtpL16depay->channels = channels;
192 srccaps = gst_caps_new_simple ("audio/x-raw-int",
193 "endianness", G_TYPE_INT, G_BIG_ENDIAN,
194 "signed", G_TYPE_BOOLEAN, TRUE,
195 "width", G_TYPE_INT, 16,
196 "depth", G_TYPE_INT, 16,
197 "rate", G_TYPE_INT, clock_rate, "channels", G_TYPE_INT, channels, NULL);
199 /* add channel positions */
200 channel_order = gst_structure_get_string (structure, "channel-order");
202 order = gst_rtp_channels_get_by_order (channels, channel_order);
204 gst_audio_set_channel_positions (gst_caps_get_structure (srccaps, 0),
207 GstAudioChannelPosition *pos;
209 GST_ELEMENT_WARNING (rtpL16depay, STREAM, DECODE,
210 (NULL), ("Unknown channel order '%s' for %d channels",
211 GST_STR_NULL (channel_order), channels));
212 /* create default NONE layout */
213 pos = gst_rtp_channels_create_default (channels);
214 gst_audio_set_channel_positions (gst_caps_get_structure (srccaps, 0), pos);
218 res = gst_pad_set_caps (depayload->srcpad, srccaps);
219 gst_caps_unref (srccaps);
226 GST_ERROR_OBJECT (depayload, "no clock-rate specified");
231 GST_ERROR_OBJECT (depayload, "no channels specified");
237 gst_rtp_L16_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
239 GstRtpL16Depay *rtpL16depay;
244 rtpL16depay = GST_RTP_L16_DEPAY (depayload);
246 payload_len = gst_rtp_buffer_get_payload_len (buf);
248 if (payload_len <= 0)
251 GST_DEBUG_OBJECT (rtpL16depay, "got payload of %d bytes", payload_len);
253 outbuf = gst_rtp_buffer_get_payload_buffer (buf);
254 marker = gst_rtp_buffer_get_marker (buf);
257 /* mark talk spurt with DISCONT */
258 GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
266 GST_ELEMENT_WARNING (rtpL16depay, STREAM, DECODE,
267 ("Empty Payload."), (NULL));
272 static GstStateChangeReturn
273 gst_rtp_L16_depay_change_state (GstElement * element, GstStateChange transition)
275 GstRtpL16Depay *rtpL16depay;
276 GstStateChangeReturn ret;
278 rtpL16depay = GST_RTP_L16_DEPAY (element);
281 switch (transition) {
282 case GST_STATE_CHANGE_NULL_TO_READY:
289 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
292 switch (transition) {
293 case GST_STATE_CHANGE_READY_TO_NULL:
303 gst_rtp_L16_depay_plugin_init (GstPlugin * plugin)
305 return gst_element_register (plugin, "rtpL16depay",
306 GST_RANK_MARGINAL, GST_TYPE_RTP_L16_DEPAY);