put the same mail for Zaheer Merali everywhere
[platform/upstream/gst-plugins-good.git] / gst / law / mulaw-encode.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
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 #include <gst/gst.h>
24 #include "mulaw-encode.h"
25 #include "mulaw-conversion.h"
26
27 extern GstPadTemplate *mulawenc_src_template, *mulawenc_sink_template;
28
29 /* Stereo signals and args */
30 enum
31 {
32   /* FILL ME */
33   LAST_SIGNAL
34 };
35
36 enum
37 {
38   ARG_0
39 };
40
41 static void gst_mulawenc_class_init (GstMuLawEncClass * klass);
42 static void gst_mulawenc_base_init (GstMuLawEncClass * klass);
43 static void gst_mulawenc_init (GstMuLawEnc * mulawenc);
44
45 static void gst_mulawenc_chain (GstPad * pad, GstData * _data);
46
47 static GstElementClass *parent_class = NULL;
48
49 /*static guint gst_stereo_signals[LAST_SIGNAL] = { 0 }; */
50
51 static GstCaps *
52 mulawenc_getcaps (GstPad * pad)
53 {
54   GstMuLawEnc *mulawenc = GST_MULAWENC (gst_pad_get_parent (pad));
55   GstPad *otherpad;
56   GstCaps *base_caps, *othercaps;
57   GstStructure *structure;
58   const GValue *rate, *chans;
59
60   if (pad == mulawenc->srcpad) {
61     otherpad = mulawenc->sinkpad;
62     base_caps = gst_caps_new_simple ("audio/x-mulaw", NULL);
63   } else {
64     otherpad = mulawenc->srcpad;
65     base_caps = gst_caps_new_simple ("audio/x-raw-int",
66         "width", G_TYPE_INT, 16, "depth", G_TYPE_INT, 16,
67         "endianness", G_TYPE_INT, G_BYTE_ORDER,
68         "signed", G_TYPE_BOOLEAN, TRUE, NULL);
69   }
70   othercaps = gst_pad_get_allowed_caps (otherpad);
71
72   /* Not fully correct, but usually, all structures in a caps have
73    * the same samplerate and channels range. */
74   structure = gst_caps_get_structure (othercaps, 0);
75   rate = gst_structure_get_value (structure, "rate");
76   chans = gst_structure_get_value (structure, "channels");
77   if (!rate || !chans)
78     return gst_caps_new_empty ();
79
80   /* Set the samplerate/channels on the to-be-returned caps */
81   structure = gst_caps_get_structure (base_caps, 0);
82   gst_structure_set_value (structure, "rate", rate);
83   gst_structure_set_value (structure, "channels", chans);
84   gst_caps_free (othercaps);
85
86   return base_caps;
87 }
88
89 static GstPadLinkReturn
90 mulawenc_link (GstPad * pad, const GstCaps * caps)
91 {
92   GstMuLawEnc *mulawenc = GST_MULAWENC (gst_pad_get_parent (pad));
93   GstPad *otherpad;
94   GstStructure *structure;
95   const GValue *rate, *chans;
96   GstCaps *base_caps;
97
98   structure = gst_caps_get_structure (caps, 0);
99   rate = gst_structure_get_value (structure, "rate");
100   chans = gst_structure_get_value (structure, "channels");
101   if (!rate || !chans)
102     return GST_PAD_LINK_REFUSED;
103
104   if (pad == mulawenc->sinkpad) {
105     otherpad = mulawenc->srcpad;
106     base_caps = gst_caps_new_simple ("audio/x-mulaw", NULL);
107   } else {
108     otherpad = mulawenc->sinkpad;
109     base_caps = gst_caps_new_simple ("audio/x-raw-int",
110         "width", G_TYPE_INT, 16, "depth", G_TYPE_INT, 16,
111         "endianness", G_TYPE_INT, G_BYTE_ORDER,
112         "signed", G_TYPE_BOOLEAN, TRUE, NULL);
113   }
114
115   structure = gst_caps_get_structure (base_caps, 0);
116   gst_structure_set_value (structure, "rate", rate);
117   gst_structure_set_value (structure, "channels", chans);
118
119   return gst_pad_try_set_caps (otherpad, base_caps);
120 }
121
122 GType
123 gst_mulawenc_get_type (void)
124 {
125   static GType mulawenc_type = 0;
126
127   if (!mulawenc_type) {
128     static const GTypeInfo mulawenc_info = {
129       sizeof (GstMuLawEncClass),
130       (GBaseInitFunc) gst_mulawenc_base_init,
131       NULL,
132       (GClassInitFunc) gst_mulawenc_class_init,
133       NULL,
134       NULL,
135       sizeof (GstMuLawEnc),
136       0,
137       (GInstanceInitFunc) gst_mulawenc_init,
138     };
139
140     mulawenc_type =
141         g_type_register_static (GST_TYPE_ELEMENT, "GstMuLawEnc", &mulawenc_info,
142         0);
143   }
144   return mulawenc_type;
145 }
146
147 static void
148 gst_mulawenc_base_init (GstMuLawEncClass * klass)
149 {
150   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
151   GstElementDetails mulawenc_details = {
152     "PCM to Mu Law conversion",
153     "Codec/Encoder/Audio",
154     "Convert 16bit PCM to 8bit mu law",
155     "Zaheer Abbas Merali <zaheerabbas at merali dot org>"
156   };
157
158   gst_element_class_add_pad_template (element_class, mulawenc_src_template);
159   gst_element_class_add_pad_template (element_class, mulawenc_sink_template);
160   gst_element_class_set_details (element_class, &mulawenc_details);
161 }
162
163 static void
164 gst_mulawenc_class_init (GstMuLawEncClass * klass)
165 {
166   parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
167 }
168
169 static void
170 gst_mulawenc_init (GstMuLawEnc * mulawenc)
171 {
172   mulawenc->sinkpad =
173       gst_pad_new_from_template (mulawenc_sink_template, "sink");
174   gst_pad_set_link_function (mulawenc->sinkpad, mulawenc_link);
175   gst_pad_set_getcaps_function (mulawenc->sinkpad, mulawenc_getcaps);
176   gst_pad_set_chain_function (mulawenc->sinkpad, gst_mulawenc_chain);
177   gst_element_add_pad (GST_ELEMENT (mulawenc), mulawenc->sinkpad);
178
179   mulawenc->srcpad = gst_pad_new_from_template (mulawenc_src_template, "src");
180   gst_pad_set_link_function (mulawenc->srcpad, mulawenc_link);
181   gst_pad_set_getcaps_function (mulawenc->srcpad, mulawenc_getcaps);
182   gst_element_add_pad (GST_ELEMENT (mulawenc), mulawenc->srcpad);
183 }
184
185 static void
186 gst_mulawenc_chain (GstPad * pad, GstData * _data)
187 {
188   GstBuffer *buf = GST_BUFFER (_data);
189   GstMuLawEnc *mulawenc;
190   gint16 *linear_data;
191   guint8 *mulaw_data;
192   GstBuffer *outbuf;
193
194   g_return_if_fail (pad != NULL);
195   g_return_if_fail (GST_IS_PAD (pad));
196   g_return_if_fail (buf != NULL);
197
198   mulawenc = GST_MULAWENC (GST_OBJECT_PARENT (pad));
199   g_return_if_fail (mulawenc != NULL);
200   g_return_if_fail (GST_IS_MULAWENC (mulawenc));
201
202   linear_data = (gint16 *) GST_BUFFER_DATA (buf);
203   outbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (buf) / 2);
204   GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
205   GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buf);
206   mulaw_data = (gint8 *) GST_BUFFER_DATA (outbuf);
207   mulaw_encode (linear_data, mulaw_data, GST_BUFFER_SIZE (outbuf));
208
209   gst_buffer_unref (buf);
210   gst_pad_push (mulawenc->srcpad, GST_DATA (outbuf));
211 }