Initialize Tizen 2.3
[framework/multimedia/gst-openmax.git] / wearable / omx / gstomx_mp3dec_alp.c
1 /*
2  * Copyright (C) 2007-2009 Nokia Corporation.
3  *
4  * Author: Felipe Contreras <felipe.contreras@nokia.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation
9  * version 2.1 of the License.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #include "gstomx_mp3dec_alp.h"
23 #include "gstomx.h"
24
25 #define OMX_MP3DEC_OUTBUF_ALP
26 #define OMX_MP3DEC_INBUF_ALP
27 #ifdef OMX_MP3DEC_INBUF_ALP
28   #define SRP_INPUT_SIZE 0
29 #else
30   #define SRP_INPUT_SIZE 32768
31 #endif
32
33 #define SRP_MP3_FRAME_SIZE 1152
34 #define SRP_MP3_SAMPLE_SIZE 2
35
36 GSTOMX_BOILERPLATE (GstOmxMp3DecAlp, gst_omx_mp3dec_alp, GstOmxBaseAudioDec,
37     GST_OMX_BASE_AUDIODEC_TYPE);
38
39 static void instance_init (GstElement * element);
40 static void instance_deinit (GstElement * element);
41
42
43 #ifdef SRP_ENABLE_DUMP
44 static void init_dump_config(GstOmxMp3DecAlp *self)
45 {
46   dictionary * dict = NULL;
47
48   dict = iniparser_load (SRP_DUMP_INI_DEFAULT_PATH);
49   if (!dict) {
50     GST_INFO ("%s load failed. Use temporary file", SRP_DUMP_INI_DEFAULT_PATH);
51     dict = iniparser_load (SRP_DUMP_INI_TEMP_PATH);
52     if (!dict) {
53       GST_WARNING ("%s load failed", SRP_DUMP_INI_TEMP_PATH);
54       return;
55     }
56   }
57
58   if (iniparser_getboolean (dict, "pcm_dump:codec", 0) == TRUE) {
59     char *suffix, *dump_path;
60     GDateTime *time = g_date_time_new_now_local ();
61
62     suffix = g_date_time_format (time, "%Y%m%d_%H%M%S.pcm");
63     dump_path = g_strjoin (NULL, SRP_DUMP_INPUT_PATH_PREFIX, suffix, NULL);
64     self->pcmFd = fopen (dump_path, "w+");
65     g_free (dump_path);
66     g_free (suffix);
67     g_date_time_unref (time);
68     if(!self->pcmFd) {
69       GST_ERROR ("Can not create debug dump file");
70     }
71   }
72
73   iniparser_freedict (dict);
74 }
75 #endif
76
77 #if 0
78 static GstOmxReturn
79 process_output_buf(GstOmxBaseFilter * omx_base, GstBuffer **buf, OMX_BUFFERHEADERTYPE *omx_buffer)
80 {
81   GstFlowReturn ret = GST_FLOW_OK;
82   GstOmxMp3DecAlp *self;
83   GstCaps *caps = NULL;
84   GstStructure *structure;
85   gint samplerate = 0;
86   gint channels = 0;
87   GstBuffer *push_buf;
88   guint offset = 0, output_size;
89   GstClockTime timestamp = 0, duration = 0;
90
91   self = GST_OMX_MP3DEC_ALP (omx_base);
92   caps = gst_pad_get_negotiated_caps (omx_base->srcpad);
93   caps = gst_caps_make_writable (caps);
94   structure = gst_caps_get_structure (caps, 0);
95   gst_structure_get_int (structure, "rate", &samplerate);
96   gst_structure_get_int (structure, "channels", &channels);
97   output_size = SRP_MP3_FRAME_SIZE * SRP_MP3_SAMPLE_SIZE * channels;
98   timestamp = GST_BUFFER_TIMESTAMP (*buf);
99   duration = GST_SECOND * SRP_MP3_FRAME_SIZE / samplerate;
100   gst_caps_unref (caps);
101   do {
102     /* merge remained data */
103     if (self->remain_buffer) {
104       if (GST_BUFFER_SIZE(self->remain_buffer) +GST_BUFFER_SIZE(*buf) < output_size) {
105         GST_DEBUG_OBJECT (self, "remain_buf (%d) + current_buf (%d) < output_size (%d). change output_size.",
106           GST_BUFFER_SIZE(self->remain_buffer), GST_BUFFER_SIZE(*buf), output_size);
107         output_size = GST_BUFFER_SIZE(self->remain_buffer) +GST_BUFFER_SIZE(*buf);
108       }
109       push_buf = gst_buffer_span (self->remain_buffer, 0, *buf, output_size);
110       gst_buffer_copy_metadata (push_buf, *buf,
111           GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_CAPS);
112       GST_BUFFER_DURATION (push_buf) = duration;
113
114       GST_LOG_OBJECT (self, "OUT_BUFFER: remained = %lu size = %lu",
115           GST_BUFFER_SIZE (self->remain_buffer), GST_BUFFER_SIZE (push_buf));
116
117       offset += output_size - GST_BUFFER_SIZE (self->remain_buffer);
118       gst_buffer_unref (self->remain_buffer);
119       self->remain_buffer = NULL;
120       ret = gst_pad_push (omx_base->srcpad, push_buf);
121       GST_LOG_OBJECT (self, "gst_pad_push end. ret = %d", ret);
122     }
123
124     /* separate data by frame size */
125     if (GST_BUFFER_SIZE (*buf) - offset >= output_size) {
126       push_buf = gst_buffer_create_sub (*buf, offset, output_size);
127       gst_buffer_copy_metadata (push_buf, *buf,
128           GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_CAPS);
129       GST_BUFFER_TIMESTAMP (push_buf) = timestamp
130           + (GST_SECOND * offset / (SRP_MP3_SAMPLE_SIZE * channels * samplerate));
131       GST_BUFFER_DURATION (push_buf) = duration;
132
133       GST_LOG_OBJECT (self, "OUT_BUFFER: offset = %lu size = %lu",
134           offset, GST_BUFFER_SIZE (push_buf));
135
136       offset += output_size;
137       ret = gst_pad_push (omx_base->srcpad, push_buf);
138       GST_LOG_OBJECT (self, "gst_pad_push end. ret = %d", ret);
139     } else {
140       /* store remained data */
141       if (GST_BUFFER_SIZE (*buf) - offset > 0) {
142         self->remain_buffer = gst_buffer_create_sub (*buf, offset,
143             GST_BUFFER_SIZE (*buf) - offset);
144         GST_BUFFER_TIMESTAMP (self->remain_buffer) = timestamp
145             + (GST_SECOND * offset / (SRP_MP3_SAMPLE_SIZE * channels * samplerate));
146       }
147       break;
148     }
149   } while (1);
150
151 #ifdef SRP_ENABLE_DUMP
152   if (self->pcmFd) {
153     fwrite (GST_BUFFER_DATA (*buf), 1, GST_BUFFER_SIZE (*buf), self->pcmFd);
154   }
155 #endif
156
157   return GSTOMX_RETURN_SKIP;
158 }
159 #endif
160
161 static gboolean
162 pad_event (GstPad * pad, GstEvent * event)
163 {
164   GstOmxBaseFilter *omx_base;
165   GstOmxMp3DecAlp *self;
166   gboolean ret = TRUE;
167
168   omx_base = GST_OMX_BASE_FILTER (GST_OBJECT_PARENT (pad));
169   self = GST_OMX_MP3DEC_ALP (omx_base);
170
171   GST_LOG_OBJECT (self, "begin");
172
173   GST_INFO_OBJECT (self, "event: %s", GST_EVENT_TYPE_NAME (event));
174
175   switch (GST_EVENT_TYPE (event)) {
176     case GST_EVENT_FLUSH_STOP:
177       if (self->remain_buffer) {
178         gst_buffer_unref (self->remain_buffer);
179         self->remain_buffer = NULL;
180       }
181       break;
182
183     default:
184       break;
185   }
186   return ret;
187 }
188
189 static void
190 instance_deinit (GstElement * element)
191 {
192   GstOmxMp3DecAlp *self;
193   self = GST_OMX_MP3DEC_ALP (element);
194
195   GST_WARNING_OBJECT (self, "mp3 alp deinit");
196
197   if (self->remain_buffer) {
198     gst_buffer_unref (self->remain_buffer);
199     self->remain_buffer = NULL;
200   }
201
202 #ifdef SRP_ENABLE_DUMP
203   if (self->pcmFd) {
204     fclose (self->pcmFd);
205     self->pcmFd = NULL;
206   }
207 #endif
208
209   GST_OMX_BASE_FILTER_CLASS (parent_class)->instance_deinit(element);
210 }
211
212 static void
213 finalize (GObject * obj)
214 {
215   G_OBJECT_CLASS (parent_class)->finalize (obj);
216 }
217
218 static void
219 type_base_init (gpointer g_class)
220 {
221   GstElementClass *element_class;
222
223   element_class = GST_ELEMENT_CLASS (g_class);
224
225   gst_element_class_set_details_simple (element_class,
226       "OpenMAX IL ALP MP3 audio decoder",
227       "Codec/Decoder/Audio/ALP",
228       "Decodes audio in MP3 format with OpenMAX IL", "Felipe Contreras");
229
230   gst_element_class_add_pad_template (element_class,
231       gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
232           gstomx_template_caps (G_TYPE_FROM_CLASS (g_class), "sink")));
233
234   gst_element_class_add_pad_template (element_class,
235       gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
236           gstomx_template_caps (G_TYPE_FROM_CLASS (g_class), "src")));
237 }
238
239 static void
240 type_class_init (gpointer g_class, gpointer class_data)
241 {
242   GObjectClass *gobject_class;
243   GstOmxBaseFilterClass *basefilter_class;
244
245   gobject_class = G_OBJECT_CLASS (g_class);
246   gobject_class->finalize = finalize;
247
248   basefilter_class = GST_OMX_BASE_FILTER_CLASS (g_class);
249   basefilter_class->instance_init = instance_init;
250   basefilter_class->instance_deinit = instance_deinit;
251 }
252
253 static void
254 instance_private_value_init(GstElement * element)
255 {
256   GstOmxBaseFilter *base_filter;
257 #ifdef SRP_ENABLE_DUMP
258   GstOmxMp3DecAlp *self;
259 #endif
260
261   base_filter = GST_OMX_BASE_FILTER (element);
262 #ifdef SRP_ENABLE_DUMP
263   self = GST_OMX_MP3DEC_ALP (element);
264 #endif
265
266   /* ALP audio use adapter */
267   base_filter->adapter_size = SRP_INPUT_SIZE;
268
269   GST_INFO_OBJECT (base_filter, "mp3dec ALP. adapter_size=%d", base_filter ->adapter_size);
270
271   self->remain_buffer = NULL;
272 #ifdef SRP_ENABLE_DUMP
273   init_dump_config (self);
274 #endif
275 }
276
277 static void
278 instance_init (GstElement * element)
279 {
280   GST_OMX_BASE_FILTER_CLASS (parent_class)->instance_init(element);
281
282   instance_private_value_init(element);
283 }
284
285 static void
286 type_instance_init (GTypeInstance * instance, gpointer g_class)
287 {
288   GstOmxBaseFilter *base_filter;
289
290   base_filter = GST_OMX_BASE_FILTER (instance);
291   base_filter->pad_event = pad_event;
292
293   instance_private_value_init(GST_ELEMENT(instance));
294
295 }