tizen 2.0 init
[framework/multimedia/gst-plugins-good0.10.git] / gst / rtp / gstrtpg722pay.c
1 /* GStreamer
2  * Copyright (C) <2010> Wim Taymans <wim.taymans@gmail.com>
3  *
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.
8  *
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.
13  *
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.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #  include "config.h"
22 #endif
23
24 #include <string.h>
25
26 #include <gst/audio/audio.h>
27 #include <gst/audio/multichannel.h>
28 #include <gst/rtp/gstrtpbuffer.h>
29
30 #include "gstrtpg722pay.h"
31 #include "gstrtpchannels.h"
32
33 GST_DEBUG_CATEGORY_STATIC (rtpg722pay_debug);
34 #define GST_CAT_DEFAULT (rtpg722pay_debug)
35
36 static GstStaticPadTemplate gst_rtp_g722_pay_sink_template =
37 GST_STATIC_PAD_TEMPLATE ("sink",
38     GST_PAD_SINK,
39     GST_PAD_ALWAYS,
40     GST_STATIC_CAPS ("audio/G722, " "rate = (int) 16000, " "channels = (int) 1")
41     );
42
43 static GstStaticPadTemplate gst_rtp_g722_pay_src_template =
44 GST_STATIC_PAD_TEMPLATE ("src",
45     GST_PAD_SRC,
46     GST_PAD_ALWAYS,
47     GST_STATIC_CAPS ("application/x-rtp, "
48         "media = (string) \"audio\", "
49         "encoding-name = (string) \"G722\", "
50         "payload = (int) " GST_RTP_PAYLOAD_G722_STRING ", "
51         "clock-rate = (int) 8000")
52     );
53
54 static gboolean gst_rtp_g722_pay_setcaps (GstBaseRTPPayload * basepayload,
55     GstCaps * caps);
56 static GstCaps *gst_rtp_g722_pay_getcaps (GstBaseRTPPayload * rtppayload,
57     GstPad * pad);
58
59 GST_BOILERPLATE (GstRtpG722Pay, gst_rtp_g722_pay, GstBaseRTPAudioPayload,
60     GST_TYPE_BASE_RTP_AUDIO_PAYLOAD);
61
62 static void
63 gst_rtp_g722_pay_base_init (gpointer klass)
64 {
65   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
66
67   gst_element_class_add_static_pad_template (element_class,
68       &gst_rtp_g722_pay_src_template);
69   gst_element_class_add_static_pad_template (element_class,
70       &gst_rtp_g722_pay_sink_template);
71
72   gst_element_class_set_details_simple (element_class, "RTP audio payloader",
73       "Codec/Payloader/Network/RTP",
74       "Payload-encode Raw audio into RTP packets (RFC 3551)",
75       "Wim Taymans <wim.taymans@gmail.com>");
76 }
77
78 static void
79 gst_rtp_g722_pay_class_init (GstRtpG722PayClass * klass)
80 {
81   GstBaseRTPPayloadClass *gstbasertppayload_class;
82
83   gstbasertppayload_class = (GstBaseRTPPayloadClass *) klass;
84
85   gstbasertppayload_class->set_caps = gst_rtp_g722_pay_setcaps;
86   gstbasertppayload_class->get_caps = gst_rtp_g722_pay_getcaps;
87
88   GST_DEBUG_CATEGORY_INIT (rtpg722pay_debug, "rtpg722pay", 0,
89       "G722 RTP Payloader");
90 }
91
92 static void
93 gst_rtp_g722_pay_init (GstRtpG722Pay * rtpg722pay, GstRtpG722PayClass * klass)
94 {
95   GstBaseRTPAudioPayload *basertpaudiopayload;
96
97   basertpaudiopayload = GST_BASE_RTP_AUDIO_PAYLOAD (rtpg722pay);
98
99   /* tell basertpaudiopayload that this is a sample based codec */
100   gst_base_rtp_audio_payload_set_sample_based (basertpaudiopayload);
101 }
102
103 static gboolean
104 gst_rtp_g722_pay_setcaps (GstBaseRTPPayload * basepayload, GstCaps * caps)
105 {
106   GstRtpG722Pay *rtpg722pay;
107   GstStructure *structure;
108   gint rate, channels, clock_rate;
109   gboolean res;
110   gchar *params;
111   GstAudioChannelPosition *pos;
112   const GstRTPChannelOrder *order;
113   GstBaseRTPAudioPayload *basertpaudiopayload;
114
115   basertpaudiopayload = GST_BASE_RTP_AUDIO_PAYLOAD (basepayload);
116   rtpg722pay = GST_RTP_G722_PAY (basepayload);
117
118   structure = gst_caps_get_structure (caps, 0);
119
120   /* first parse input caps */
121   if (!gst_structure_get_int (structure, "rate", &rate))
122     goto no_rate;
123
124   if (!gst_structure_get_int (structure, "channels", &channels))
125     goto no_channels;
126
127   /* get the channel order */
128   pos = gst_audio_get_channel_positions (structure);
129   if (pos)
130     order = gst_rtp_channels_get_by_pos (channels, pos);
131   else
132     order = NULL;
133
134   /* Clock rate is always 8000 Hz for G722 according to
135    * RFC 3551 although the sampling rate is 16000 Hz */
136   clock_rate = 8000;
137
138   gst_basertppayload_set_options (basepayload, "audio", TRUE, "G722",
139       clock_rate);
140   params = g_strdup_printf ("%d", channels);
141
142   if (!order && channels > 2) {
143     GST_ELEMENT_WARNING (rtpg722pay, STREAM, DECODE,
144         (NULL), ("Unknown channel order for %d channels", channels));
145   }
146
147   if (order && order->name) {
148     res = gst_basertppayload_set_outcaps (basepayload,
149         "encoding-params", G_TYPE_STRING, params, "channels", G_TYPE_INT,
150         channels, "channel-order", G_TYPE_STRING, order->name, NULL);
151   } else {
152     res = gst_basertppayload_set_outcaps (basepayload,
153         "encoding-params", G_TYPE_STRING, params, "channels", G_TYPE_INT,
154         channels, NULL);
155   }
156
157   g_free (params);
158   g_free (pos);
159
160   rtpg722pay->rate = rate;
161   rtpg722pay->channels = channels;
162
163   /* bits-per-sample is 4 * channels for G722, but as the RTP clock runs at
164    * half speed (8 instead of 16 khz), pretend it's 8 bits per sample
165    * channels. */
166   gst_base_rtp_audio_payload_set_samplebits_options (basertpaudiopayload,
167       8 * rtpg722pay->channels);
168
169   return res;
170
171   /* ERRORS */
172 no_rate:
173   {
174     GST_DEBUG_OBJECT (rtpg722pay, "no rate given");
175     return FALSE;
176   }
177 no_channels:
178   {
179     GST_DEBUG_OBJECT (rtpg722pay, "no channels given");
180     return FALSE;
181   }
182 }
183
184 static GstCaps *
185 gst_rtp_g722_pay_getcaps (GstBaseRTPPayload * rtppayload, GstPad * pad)
186 {
187   GstCaps *otherpadcaps;
188   GstCaps *caps;
189
190   otherpadcaps = gst_pad_get_allowed_caps (rtppayload->srcpad);
191   caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
192
193   if (otherpadcaps) {
194     if (!gst_caps_is_empty (otherpadcaps)) {
195       gst_caps_set_simple (caps, "channels", G_TYPE_INT, 1, NULL);
196       gst_caps_set_simple (caps, "rate", G_TYPE_INT, 16000, NULL);
197     }
198     gst_caps_unref (otherpadcaps);
199   }
200   return caps;
201 }
202
203 gboolean
204 gst_rtp_g722_pay_plugin_init (GstPlugin * plugin)
205 {
206   return gst_element_register (plugin, "rtpg722pay",
207       GST_RANK_SECONDARY, GST_TYPE_RTP_G722_PAY);
208 }