Initialize Tizen 2.3
[framework/multimedia/gst-openmax.git] / wearable / omx / gstomx_mpeg4dec.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_mpeg4dec.h"
23 #include "gstomx.h"
24
25 GSTOMX_BOILERPLATE (GstOmxMpeg4Dec, gst_omx_mpeg4dec, GstOmxBaseVideoDec,
26     GST_OMX_BASE_VIDEODEC_TYPE);
27
28
29 static void instance_init (GstElement * element);
30 static void instance_deinit (GstElement * element);
31
32 #ifdef DIVX_DRM /* we do not support divx now */
33 static gboolean init_divx_symbol (GstOmxMpeg4Dec * self)
34 {
35   GST_LOG_OBJECT (self, "mpeg4dec load_divx_symbol enter");
36
37   self->divx_handle = dlopen (DIVX_SDK_PLUGIN_NAME, RTLD_LAZY);
38   if (!self->divx_handle) {
39     GST_ERROR_OBJECT (self, "dlopen failed [%s]", dlerror());
40     goto error_exit;
41   }
42
43   self->divx_sym_table.init_decrypt = dlsym (self->divx_handle, "divx_init_decrypt");
44   if (!self->divx_sym_table.init_decrypt) {
45     GST_ERROR_OBJECT (self, "loading divx_init_decrypt failed : %s", dlerror());
46     goto error_exit;
47   }
48   self->divx_sym_table.commit = dlsym (self->divx_handle, "divx_commit");
49   if (!self->divx_sym_table.commit) {
50     GST_ERROR_OBJECT (self, "loading divx_commit failed : %s", dlerror());
51     goto error_exit;
52   }
53   self->divx_sym_table.decrypt_video = dlsym (self->divx_handle, "divx_decrypt_video");
54   if (!self->divx_sym_table.decrypt_video) {
55     GST_ERROR_OBJECT (self, "loading divx_decrypt_video failed : %s", dlerror());
56     goto error_exit;
57   }
58   self->divx_sym_table.prepare_video_bitstream = dlsym (self->divx_handle, "divx_prepare_video_bitstream");
59   if (!self->divx_sym_table.prepare_video_bitstream) {
60     GST_ERROR_OBJECT (self, "loading divx_prepare_video_bitstream failed : %s", dlerror());
61     goto error_exit;
62   }
63   self->divx_sym_table.finalize = dlsym (self->divx_handle, "divx_finalize");
64   if (!self->divx_sym_table.finalize) {
65     GST_ERROR_OBJECT (self, "loading divx_finalize failed : %s", dlerror());
66     goto error_exit;
67   }
68
69   return TRUE;
70
71 error_exit:
72
73   if (self->divx_handle) {
74     dlclose(self->divx_handle);
75     self->divx_handle = NULL;
76   }
77
78   return FALSE;
79 }
80
81 static gboolean
82 init_divx_drm (GstOmxMpeg4Dec * self)
83 {
84   int error = 0;
85
86   GST_LOG_OBJECT (self, "mpeg4dec init_divx_drm enter");
87
88   if (init_divx_symbol(self) == FALSE) {
89     GST_ERROR_OBJECT (self, "loading symbol failed....");
90     goto error_exit;
91   }
92
93   self->drmContext = self->divx_sym_table.init_decrypt (&error);
94
95   if (self->drmContext) {
96     GST_DEBUG_OBJECT (self, "%s  init success: drmContext = %p\n", __func__, self->drmContext);
97   } else {
98     GST_ERROR_OBJECT (self, "%s  failed to init... error code = %d \n", __func__, error);
99     goto error_exit;
100   }
101
102   error = self->divx_sym_table.commit (self->drmContext);
103
104   if (error == DRM_SUCCESS) {
105     GST_DEBUG_OBJECT (self, "%s  commit success: drmContext = %p\n", __func__, self->drmContext);
106   } else {
107     GST_ERROR_OBJECT (self, "%s  failed to commit... error code = %d \n", __func__, error);
108     goto error_exit;
109   }
110
111   return TRUE;
112
113 error_exit:
114
115   if (self->drmContext)
116   {
117     self->divx_sym_table.finalize (self->drmContext);
118     free(self->drmContext);
119     self->drmContext = NULL;
120   }
121
122   return FALSE;
123 }
124
125 static GstOmxReturn
126 process_input_buf (GstOmxBaseFilter * omx_base_filter, GstBuffer **buf)
127 {
128   GstOmxMpeg4Dec *self;
129
130   self = GST_OMX_MPEG4DEC (omx_base_filter);
131
132   GST_LOG_OBJECT (self, "mpeg4dec process_input_buf enter");
133
134   /* decrypt DivX DRM buffer if this is DRM */
135   if (self->drmContext) {
136     if (DRM_SUCCESS == self->divx_sym_table.decrypt_video (self->drmContext, GST_BUFFER_DATA(*buf), GST_BUFFER_SIZE(*buf))) {
137       GST_DEBUG_OBJECT (self, "##### DivX DRM Mode ##### decrypt video success : buffer = %d", GST_BUFFER_SIZE(*buf));
138     } else {
139       GST_ERROR_OBJECT (self, "##### DivX DRM Mode ##### decrypt video failed : buffer = %d", GST_BUFFER_SIZE(*buf));
140     }
141   }
142
143 /* if you want to use commonly for videodec input, use this */
144 /*  GST_OMX_BASE_FILTER_CLASS (parent_class)->process_input_buf (omx_base_filter, buf); */
145
146   return GSTOMX_RETURN_OK;
147 }
148
149 static void
150 print_tag (const GstTagList * list, const gchar * tag, gpointer data)
151 {
152   gint i, count;
153   GstOmxMpeg4Dec *self;
154   GstOmxBaseFilter *omx_base_filter;
155
156   self = GST_OMX_MPEG4DEC (data);
157   omx_base_filter = GST_OMX_BASE_FILTER (data);
158
159   count = gst_tag_list_get_tag_size (list, tag);
160
161   for (i = 0; i < count; i++) {
162     gchar *str;
163
164     if (gst_tag_get_type (tag) == G_TYPE_STRING) {
165       if (!gst_tag_list_get_string_index (list, tag, i, &str))
166         g_assert_not_reached ();
167     } else if (gst_tag_get_type (tag) == GST_TYPE_BUFFER) {
168       GstBuffer *img;
169
170       img = gst_value_get_buffer (gst_tag_list_get_value_index (list, tag, i));
171       if (img) {
172         gchar *caps_str;
173
174         caps_str = GST_BUFFER_CAPS (img) ?
175             gst_caps_to_string (GST_BUFFER_CAPS (img)) : g_strdup ("unknown");
176         str = g_strdup_printf ("buffer of %u bytes, type: %s",
177             GST_BUFFER_SIZE (img), caps_str);
178         g_free (caps_str);
179       } else {
180         str = g_strdup ("NULL buffer");
181       }
182     } else {
183       str = g_strdup_value_contents (gst_tag_list_get_value_index (list, tag, i));
184     }
185
186     if (i == 0) {
187       GST_LOG_OBJECT(self, "%16s: %s", gst_tag_get_nick (tag), str);
188
189       if (strcmp (gst_tag_get_nick(tag), "DRM DivX") == 0) {
190         if (self->drmContext == NULL) {
191           GST_LOG_OBJECT(self, "Init divx drm !!!!!!!!!!!!!!!!!!!! [%s]", str);
192           if (init_divx_drm (self)) {
193             omx_base_filter->is_divx_drm = TRUE;
194             GST_LOG_OBJECT(self, "omx_printtag_init_divx_drm() success");
195           } else {
196             GST_ERROR_OBJECT(self, "omx_printtag_init_divx_drm() failed");
197           }
198         } else {
199           GST_LOG_OBJECT(self, "Init divx drm is DONE before. so do nothing [%s]", str);
200         }
201       }
202     } else {
203       GST_LOG_OBJECT(self, "tag is not DRM Divx");
204     }
205
206     g_free (str);
207   }
208
209   GST_LOG_OBJECT(self, "print_tag End");
210 }
211
212 static gboolean
213 mpeg4_pad_event (GstPad * pad, GstEvent * event)
214 {
215   GstOmxMpeg4Dec *self;
216   gboolean ret = TRUE;
217
218   self = GST_OMX_MPEG4DEC (GST_OBJECT_PARENT (pad));
219
220   GST_LOG_OBJECT (self, "begin");
221
222   GST_INFO_OBJECT (self, "event: %s", GST_EVENT_TYPE_NAME (event));
223
224   switch (GST_EVENT_TYPE (event)) {
225     case GST_EVENT_TAG:
226     {
227       GstTagList *taglist = NULL;
228
229       GST_LOG_OBJECT (self, "GST_EVENT_TAG");
230
231       gst_event_parse_tag (event, &taglist);
232       gst_tag_list_foreach (taglist, print_tag, self);
233       gst_event_unref (event);
234       ret= FALSE;
235       break;
236     }
237     default:
238       ret = TRUE;
239       break;
240   }
241   return ret;
242 }
243 #endif /* we do not support divx now */
244
245 static void
246 instance_deinit (GstElement * element)
247 {
248   GstOmxMpeg4Dec *self;
249   self = GST_OMX_MPEG4DEC (element);
250
251   GST_WARNING_OBJECT (self, "mpeg4 dec deinit");
252
253 #ifdef DIVX_DRM
254   if (self->drmContext)
255   {
256     self->divx_sym_table.finalize (self->drmContext);
257     free(self->drmContext);
258     self->drmContext = NULL;
259   }
260
261   if (self->divx_handle)
262   {
263     dlclose(self->divx_handle);
264     self->divx_handle = NULL;
265   }
266 #endif
267
268   GST_OMX_BASE_FILTER_CLASS (parent_class)->instance_deinit(element);
269   GST_WARNING_OBJECT (self, "mpeg4 dec end");
270 }
271
272 static void
273 finalize (GObject * obj)
274 {
275   GstOmxMpeg4Dec *self;
276
277   self = GST_OMX_MPEG4DEC (obj);
278
279   GST_LOG_OBJECT (self, "mpeg4dec finalize enter");
280
281   G_OBJECT_CLASS (parent_class)->finalize (obj);
282 }
283
284 static void
285 type_base_init (gpointer g_class)
286 {
287   GstElementClass *element_class;
288
289   element_class = GST_ELEMENT_CLASS (g_class);
290
291   gst_element_class_set_details_simple (element_class,
292       "OpenMAX IL MPEG-4 video decoder",
293       "Codec/Decoder/Video",
294       "Decodes video in MPEG-4 format with OpenMAX IL", "Felipe Contreras");
295
296   gst_element_class_add_pad_template (element_class,
297       gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
298           gstomx_template_caps (G_TYPE_FROM_CLASS (g_class), "sink")));
299
300   gst_element_class_add_pad_template (element_class,
301       gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
302           gstomx_template_caps (G_TYPE_FROM_CLASS (g_class), "src")));
303 }
304
305 static void
306 type_class_init (gpointer g_class, gpointer class_data)
307 {
308   GObjectClass *gobject_class;
309   GstOmxBaseFilterClass *basefilter_class;
310
311   gobject_class = G_OBJECT_CLASS (g_class);
312   basefilter_class = GST_OMX_BASE_FILTER_CLASS (g_class);
313
314   gobject_class->finalize = finalize;
315 #ifdef DIVX_DRM
316   basefilter_class->process_input_buf = process_input_buf;
317 #endif
318   basefilter_class->instance_init = instance_init;
319   basefilter_class->instance_deinit = instance_deinit;
320 }
321
322 static void
323 instance_private_value_init(GstElement * element)
324 {
325   GstOmxBaseVideoDec *omx_base;
326   GstOmxBaseFilter *omx_base_filter;
327
328   omx_base_filter = GST_OMX_BASE_FILTER (element);
329   omx_base = GST_OMX_BASE_VIDEODEC (element);
330 #ifdef DIVX_DRM
331   omx_base_filter->pad_event = mpeg4_pad_event;
332 #endif
333   omx_base->compression_format = OMX_VIDEO_CodingMPEG4;
334   omx_base_filter->gomx->compression_format = OMX_VIDEO_CodingMPEG4;
335 }
336
337 static void
338 instance_init (GstElement * element)
339 {
340   GST_OMX_BASE_FILTER_CLASS (parent_class)->instance_init(element);
341
342   instance_private_value_init(element);
343 }
344
345 static void
346 type_instance_init (GTypeInstance * instance, gpointer g_class)
347 {
348   instance_private_value_init(GST_ELEMENT(instance));
349 }