2 * Copyright (C) <2005> 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
19 #include <gst/rtp/gstrtpbuffer.h>
22 #include "gstrtpamrdec.h"
24 /* elementfactory information */
25 static GstElementDetails gst_rtp_amrdec_details = {
27 "Codec/Parser/Network",
28 "Extracts MPEG audio from RTP packets",
29 "Wim Taymans <wim@fluendo.com>"
32 /* RtpAMRDec signals and args */
45 static GstStaticPadTemplate gst_rtpamrdec_src_template =
46 GST_STATIC_PAD_TEMPLATE ("src",
49 GST_STATIC_CAPS ("audio/x-amr-nb")
52 static GstStaticPadTemplate gst_rtpamrdec_sink_template =
53 GST_STATIC_PAD_TEMPLATE ("sink",
56 GST_STATIC_CAPS ("application/x-rtp")
60 static void gst_rtpamrdec_class_init (GstRtpAMRDecClass * klass);
61 static void gst_rtpamrdec_base_init (GstRtpAMRDecClass * klass);
62 static void gst_rtpamrdec_init (GstRtpAMRDec * rtpamrdec);
64 static GstFlowReturn gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buffer);
66 static void gst_rtpamrdec_set_property (GObject * object, guint prop_id,
67 const GValue * value, GParamSpec * pspec);
68 static void gst_rtpamrdec_get_property (GObject * object, guint prop_id,
69 GValue * value, GParamSpec * pspec);
71 static GstElementStateReturn gst_rtpamrdec_change_state (GstElement * element);
73 static GstElementClass *parent_class = NULL;
76 gst_rtpamrdec_get_type (void)
78 static GType rtpamrdec_type = 0;
80 if (!rtpamrdec_type) {
81 static const GTypeInfo rtpamrdec_info = {
82 sizeof (GstRtpAMRDecClass),
83 (GBaseInitFunc) gst_rtpamrdec_base_init,
85 (GClassInitFunc) gst_rtpamrdec_class_init,
88 sizeof (GstRtpAMRDec),
90 (GInstanceInitFunc) gst_rtpamrdec_init,
94 g_type_register_static (GST_TYPE_ELEMENT, "GstRtpAMRDec",
97 return rtpamrdec_type;
101 gst_rtpamrdec_base_init (GstRtpAMRDecClass * klass)
103 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
105 gst_element_class_add_pad_template (element_class,
106 gst_static_pad_template_get (&gst_rtpamrdec_src_template));
107 gst_element_class_add_pad_template (element_class,
108 gst_static_pad_template_get (&gst_rtpamrdec_sink_template));
110 gst_element_class_set_details (element_class, &gst_rtp_amrdec_details);
114 gst_rtpamrdec_class_init (GstRtpAMRDecClass * klass)
116 GObjectClass *gobject_class;
117 GstElementClass *gstelement_class;
119 gobject_class = (GObjectClass *) klass;
120 gstelement_class = (GstElementClass *) klass;
122 parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
124 gobject_class->set_property = gst_rtpamrdec_set_property;
125 gobject_class->get_property = gst_rtpamrdec_get_property;
127 gstelement_class->change_state = gst_rtpamrdec_change_state;
131 gst_rtpamrdec_init (GstRtpAMRDec * rtpamrdec)
136 gst_pad_new_from_template (gst_static_pad_template_get
137 (&gst_rtpamrdec_src_template), "src");
138 gst_element_add_pad (GST_ELEMENT (rtpamrdec), rtpamrdec->srcpad);
140 caps = gst_caps_new_simple ("audio/x-amr-nb",
141 "channels", G_TYPE_INT, 1, "rate", G_TYPE_INT, 8000, NULL);
143 gst_pad_set_caps (rtpamrdec->srcpad, caps);
146 gst_pad_new_from_template (gst_static_pad_template_get
147 (&gst_rtpamrdec_sink_template), "sink");
148 gst_pad_set_chain_function (rtpamrdec->sinkpad, gst_rtpamrdec_chain);
149 gst_element_add_pad (GST_ELEMENT (rtpamrdec), rtpamrdec->sinkpad);
153 gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buf)
155 GstRtpAMRDec *rtpamrdec;
159 rtpamrdec = GST_RTP_AMR_DEC (GST_OBJECT_PARENT (pad));
161 if (!gst_rtpbuffer_validate (buf))
169 payload_len = gst_rtpbuffer_get_payload_len (buf);
170 payload = gst_rtpbuffer_get_payload (buf);
172 /* strip off header */
176 timestamp = gst_rtpbuffer_get_timestamp (buf);
178 outbuf = gst_buffer_new_and_alloc (payload_len);
180 //GST_BUFFER_TIMESTAMP (outbuf) = timestamp * GST_SECOND / 90000;
182 memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len);
184 gst_buffer_set_caps (outbuf, GST_PAD_CAPS (rtpamrdec->srcpad));
186 GST_DEBUG ("gst_rtpamrdec_chain: pushing buffer of size %d",
187 GST_BUFFER_SIZE (outbuf));
189 gst_buffer_unref (buf);
191 ret = gst_pad_push (rtpamrdec->srcpad, outbuf);
198 GST_DEBUG ("Packet did not validate");
199 gst_buffer_unref (buf);
200 return GST_FLOW_ERROR;
205 gst_rtpamrdec_set_property (GObject * object, guint prop_id,
206 const GValue * value, GParamSpec * pspec)
208 GstRtpAMRDec *rtpamrdec;
210 rtpamrdec = GST_RTP_AMR_DEC (object);
214 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
220 gst_rtpamrdec_get_property (GObject * object, guint prop_id, GValue * value,
223 GstRtpAMRDec *rtpamrdec;
225 rtpamrdec = GST_RTP_AMR_DEC (object);
229 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
234 static GstElementStateReturn
235 gst_rtpamrdec_change_state (GstElement * element)
237 GstRtpAMRDec *rtpamrdec;
239 GstElementStateReturn ret;
241 rtpamrdec = GST_RTP_AMR_DEC (element);
242 transition = GST_STATE_TRANSITION (element);
244 switch (transition) {
245 case GST_STATE_NULL_TO_READY:
251 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element);
253 switch (transition) {
254 case GST_STATE_READY_TO_NULL:
263 gst_rtpamrdec_plugin_init (GstPlugin * plugin)
265 return gst_element_register (plugin, "rtpamrdec",
266 GST_RANK_NONE, GST_TYPE_RTP_AMR_DEC);