aacparse: fix wrong offset of adts channel
[platform/upstream/gst-plugins-good.git] / gst / law / mulaw-decode.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., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 /**
20  * SECTION:element-mulawdec
21  *
22  * This element decodes mulaw audio. Mulaw coding is also known as G.711.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28 #include <gst/gst.h>
29
30 #include "mulaw-decode.h"
31 #include "mulaw-conversion.h"
32
33 extern GstStaticPadTemplate mulaw_dec_src_factory;
34 extern GstStaticPadTemplate mulaw_dec_sink_factory;
35
36 static gboolean gst_mulawdec_set_format (GstAudioDecoder * dec, GstCaps * caps);
37 static GstFlowReturn gst_mulawdec_handle_frame (GstAudioDecoder * dec,
38     GstBuffer * buffer);
39
40
41 /* Stereo signals and args */
42 enum
43 {
44   /* FILL ME */
45   LAST_SIGNAL
46 };
47
48 enum
49 {
50   PROP_0
51 };
52
53 #define gst_mulawdec_parent_class parent_class
54 G_DEFINE_TYPE (GstMuLawDec, gst_mulawdec, GST_TYPE_AUDIO_DECODER);
55
56 static gboolean
57 gst_mulawdec_set_format (GstAudioDecoder * dec, GstCaps * caps)
58 {
59   GstMuLawDec *mulawdec = GST_MULAWDEC (dec);
60   GstStructure *structure;
61   int rate, channels;
62   GstAudioInfo info;
63
64   structure = gst_caps_get_structure (caps, 0);
65   if (!structure) {
66     GST_ERROR ("failed to get structure from caps");
67     goto error_failed_get_structure;
68   }
69
70   if (!gst_structure_get_int (structure, "rate", &rate)) {
71     GST_ERROR ("failed to find field rate in input caps");
72     goto error_failed_find_rate;
73   }
74
75   if (!gst_structure_get_int (structure, "channels", &channels)) {
76     GST_ERROR ("failed to find field channels in input caps");
77     goto error_failed_find_channel;
78   }
79
80   gst_audio_info_init (&info);
81   gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_S16, rate, channels, NULL);
82
83   GST_DEBUG_OBJECT (mulawdec, "rate=%d, channels=%d", rate, channels);
84
85   return gst_audio_decoder_set_output_format (dec, &info);
86
87 error_failed_find_channel:
88 error_failed_find_rate:
89 error_failed_get_structure:
90   return FALSE;
91 }
92
93 static GstFlowReturn
94 gst_mulawdec_handle_frame (GstAudioDecoder * dec, GstBuffer * buffer)
95 {
96   GstMapInfo inmap, outmap;
97   gint16 *linear_data;
98   guint8 *mulaw_data;
99   gsize mulaw_size, linear_size;
100   GstBuffer *outbuf;
101
102   if (!buffer) {
103     return GST_FLOW_OK;
104   }
105
106   if (!gst_buffer_map (buffer, &inmap, GST_MAP_READ)) {
107     GST_ERROR ("failed to map input buffer");
108     goto error_failed_map_input_buffer;
109   }
110
111   mulaw_data = inmap.data;
112   mulaw_size = inmap.size;
113
114   linear_size = mulaw_size * 2;
115
116   outbuf = gst_audio_decoder_allocate_output_buffer (dec, linear_size);
117   if (!gst_buffer_map (outbuf, &outmap, GST_MAP_WRITE)) {
118     GST_ERROR ("failed to map input buffer");
119     goto error_failed_map_output_buffer;
120   }
121
122   linear_data = (gint16 *) outmap.data;
123
124   mulaw_decode (mulaw_data, linear_data, mulaw_size);
125
126   gst_buffer_unmap (outbuf, &outmap);
127   gst_buffer_unmap (buffer, &inmap);
128
129   return gst_audio_decoder_finish_frame (dec, outbuf, -1);
130
131 error_failed_map_output_buffer:
132   gst_buffer_unref (outbuf);
133   gst_buffer_unmap (buffer, &inmap);
134
135 error_failed_map_input_buffer:
136   return GST_FLOW_ERROR;
137 }
138
139 static gboolean
140 gst_mulawdec_start (GstAudioDecoder * dec)
141 {
142   gst_audio_decoder_set_estimate_rate (dec, TRUE);
143
144   return TRUE;
145 }
146
147 static void
148 gst_mulawdec_class_init (GstMuLawDecClass * klass)
149 {
150   GstElementClass *element_class = (GstElementClass *) klass;
151   GstAudioDecoderClass *audiodec_class = GST_AUDIO_DECODER_CLASS (klass);
152
153   gst_element_class_add_static_pad_template (element_class,
154       &mulaw_dec_src_factory);
155   gst_element_class_add_static_pad_template (element_class,
156       &mulaw_dec_sink_factory);
157
158
159   audiodec_class->start = GST_DEBUG_FUNCPTR (gst_mulawdec_start);
160   audiodec_class->set_format = GST_DEBUG_FUNCPTR (gst_mulawdec_set_format);
161   audiodec_class->handle_frame = GST_DEBUG_FUNCPTR (gst_mulawdec_handle_frame);
162
163   gst_element_class_set_static_metadata (element_class, "Mu Law audio decoder",
164       "Codec/Decoder/Audio",
165       "Convert 8bit mu law to 16bit PCM",
166       "Zaheer Abbas Merali <zaheerabbas at merali dot org>");
167 }
168
169 static void
170 gst_mulawdec_init (GstMuLawDec * mulawdec)
171 {
172   gst_audio_decoder_set_needs_format (GST_AUDIO_DECODER (mulawdec), TRUE);
173   gst_audio_decoder_set_use_default_pad_acceptcaps (GST_AUDIO_DECODER_CAST
174       (mulawdec), TRUE);
175   GST_PAD_SET_ACCEPT_TEMPLATE (GST_AUDIO_DECODER_SINK_PAD (mulawdec));
176 }