2 * Copyright (C) 2007-2009 Nokia Corporation.
4 * Author: Felipe Contreras <felipe.contreras@nokia.com>
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.
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.
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
22 #include "gstomx_mpeg4dec.h"
25 GSTOMX_BOILERPLATE (GstOmxMpeg4Dec, gst_omx_mpeg4dec, GstOmxBaseVideoDec,
26 GST_OMX_BASE_VIDEODEC_TYPE);
29 static void instance_init (GstElement * element);
30 static void instance_deinit (GstElement * element);
32 #ifdef DIVX_DRM /* we do not support divx now */
33 static gboolean init_divx_symbol (GstOmxMpeg4Dec * self)
35 GST_LOG_OBJECT (self, "mpeg4dec load_divx_symbol enter");
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());
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());
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());
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());
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());
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());
73 if (self->divx_handle) {
74 dlclose(self->divx_handle);
75 self->divx_handle = NULL;
82 init_divx_drm (GstOmxMpeg4Dec * self)
86 GST_LOG_OBJECT (self, "mpeg4dec init_divx_drm enter");
88 if (init_divx_symbol(self) == FALSE) {
89 GST_ERROR_OBJECT (self, "loading symbol failed....");
93 self->drmContext = self->divx_sym_table.init_decrypt (&error);
95 if (self->drmContext) {
96 GST_DEBUG_OBJECT (self, "%s init success: drmContext = %p\n", __func__, self->drmContext);
98 GST_ERROR_OBJECT (self, "%s failed to init... error code = %d \n", __func__, error);
102 error = self->divx_sym_table.commit (self->drmContext);
104 if (error == DRM_SUCCESS) {
105 GST_DEBUG_OBJECT (self, "%s commit success: drmContext = %p\n", __func__, self->drmContext);
107 GST_ERROR_OBJECT (self, "%s failed to commit... error code = %d \n", __func__, error);
115 if (self->drmContext)
117 self->divx_sym_table.finalize (self->drmContext);
118 free(self->drmContext);
119 self->drmContext = NULL;
126 process_input_buf (GstOmxBaseFilter * omx_base_filter, GstBuffer **buf)
128 GstOmxMpeg4Dec *self;
130 self = GST_OMX_MPEG4DEC (omx_base_filter);
132 GST_LOG_OBJECT (self, "mpeg4dec process_input_buf enter");
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));
139 GST_ERROR_OBJECT (self, "##### DivX DRM Mode ##### decrypt video failed : buffer = %d", GST_BUFFER_SIZE(*buf));
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); */
146 return GSTOMX_RETURN_OK;
150 print_tag (const GstTagList * list, const gchar * tag, gpointer data)
153 GstOmxMpeg4Dec *self;
154 GstOmxBaseFilter *omx_base_filter;
156 self = GST_OMX_MPEG4DEC (data);
157 omx_base_filter = GST_OMX_BASE_FILTER (data);
159 count = gst_tag_list_get_tag_size (list, tag);
161 for (i = 0; i < count; i++) {
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) {
170 img = gst_value_get_buffer (gst_tag_list_get_value_index (list, tag, i));
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);
180 str = g_strdup ("NULL buffer");
183 str = g_strdup_value_contents (gst_tag_list_get_value_index (list, tag, i));
187 GST_LOG_OBJECT(self, "%16s: %s", gst_tag_get_nick (tag), str);
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");
196 GST_ERROR_OBJECT(self, "omx_printtag_init_divx_drm() failed");
199 GST_LOG_OBJECT(self, "Init divx drm is DONE before. so do nothing [%s]", str);
203 GST_LOG_OBJECT(self, "tag is not DRM Divx");
209 GST_LOG_OBJECT(self, "print_tag End");
213 mpeg4_pad_event (GstPad * pad, GstEvent * event)
215 GstOmxMpeg4Dec *self;
218 self = GST_OMX_MPEG4DEC (GST_OBJECT_PARENT (pad));
220 GST_LOG_OBJECT (self, "begin");
222 GST_INFO_OBJECT (self, "event: %s", GST_EVENT_TYPE_NAME (event));
224 switch (GST_EVENT_TYPE (event)) {
227 GstTagList *taglist = NULL;
229 GST_LOG_OBJECT (self, "GST_EVENT_TAG");
231 gst_event_parse_tag (event, &taglist);
232 gst_tag_list_foreach (taglist, print_tag, self);
233 gst_event_unref (event);
243 #endif /* we do not support divx now */
246 instance_deinit (GstElement * element)
248 GstOmxMpeg4Dec *self;
249 self = GST_OMX_MPEG4DEC (element);
251 GST_WARNING_OBJECT (self, "mpeg4 dec deinit");
254 if (self->drmContext)
256 self->divx_sym_table.finalize (self->drmContext);
257 free(self->drmContext);
258 self->drmContext = NULL;
261 if (self->divx_handle)
263 dlclose(self->divx_handle);
264 self->divx_handle = NULL;
268 GST_OMX_BASE_FILTER_CLASS (parent_class)->instance_deinit(element);
269 GST_WARNING_OBJECT (self, "mpeg4 dec end");
273 finalize (GObject * obj)
275 GstOmxMpeg4Dec *self;
277 self = GST_OMX_MPEG4DEC (obj);
279 GST_LOG_OBJECT (self, "mpeg4dec finalize enter");
281 G_OBJECT_CLASS (parent_class)->finalize (obj);
285 type_base_init (gpointer g_class)
287 GstElementClass *element_class;
289 element_class = GST_ELEMENT_CLASS (g_class);
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");
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")));
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")));
306 type_class_init (gpointer g_class, gpointer class_data)
308 GObjectClass *gobject_class;
309 GstOmxBaseFilterClass *basefilter_class;
311 gobject_class = G_OBJECT_CLASS (g_class);
312 basefilter_class = GST_OMX_BASE_FILTER_CLASS (g_class);
314 gobject_class->finalize = finalize;
316 basefilter_class->process_input_buf = process_input_buf;
318 basefilter_class->instance_init = instance_init;
319 basefilter_class->instance_deinit = instance_deinit;
323 instance_private_value_init(GstElement * element)
325 GstOmxBaseVideoDec *omx_base;
326 GstOmxBaseFilter *omx_base_filter;
328 omx_base_filter = GST_OMX_BASE_FILTER (element);
329 omx_base = GST_OMX_BASE_VIDEODEC (element);
331 omx_base_filter->pad_event = mpeg4_pad_event;
333 omx_base->compression_format = OMX_VIDEO_CodingMPEG4;
334 omx_base_filter->gomx->compression_format = OMX_VIDEO_CodingMPEG4;
338 instance_init (GstElement * element)
340 GST_OMX_BASE_FILTER_CLASS (parent_class)->instance_init(element);
342 instance_private_value_init(element);
346 type_instance_init (GTypeInstance * instance, gpointer g_class)
348 instance_private_value_init(GST_ELEMENT(instance));