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
26 #include <gst/gststructure.h>
29 #include "gstomx_dummy.h"
30 #include "gstomx_mpeg4dec.h"
31 #include "gstomx_h263dec.h"
32 #include "gstomx_h264dec.h"
33 #include "gstomx_wmvdec.h"
34 #include "gstomx_mpeg4enc.h"
35 #include "gstomx_h264enc.h"
36 #include "gstomx_h263enc.h"
37 #include "gstomx_vorbisdec.h"
38 #include "gstomx_mp3dec.h"
40 #include "gstomx_mp3dec_alp.h"
42 #include "gstomx_mp2dec.h"
43 #include "gstomx_aacdec.h"
44 #include "gstomx_aacenc.h"
45 #include "gstomx_amrnbdec.h"
46 #include "gstomx_amrnbenc.h"
47 #include "gstomx_amrwbdec.h"
48 #include "gstomx_amrwbenc.h"
49 #include "gstomx_adpcmdec.h"
50 #include "gstomx_adpcmenc.h"
51 #include "gstomx_g711dec.h"
52 #include "gstomx_g711enc.h"
53 #include "gstomx_g729dec.h"
54 #include "gstomx_g729enc.h"
55 #include "gstomx_ilbcdec.h"
56 #include "gstomx_ilbcenc.h"
57 #include "gstomx_jpegenc.h"
58 #endif /* EXPERIMENTAL */
59 #include "gstomx_audiosink.h"
61 #include "gstomx_videosink.h"
62 #include "gstomx_filereadersrc.h"
63 #endif /* EXPERIMENTAL */
64 #include "gstomx_volume.h"
66 GST_DEBUG_CATEGORY (gstomx_debug);
68 static const GstStructure *element_table;
69 static GQuark element_name_quark;
71 extern const gchar *default_config;
73 static GType (*get_type[]) (void) = {
74 gst_omx_dummy_get_type,
75 gst_omx_mpeg4dec_get_type,
76 gst_omx_h264dec_get_type,
77 gst_omx_h263dec_get_type,
78 gst_omx_wmvdec_get_type,
79 gst_omx_mpeg4enc_get_type,
80 gst_omx_h264enc_get_type,
81 gst_omx_h263enc_get_type,
82 gst_omx_vorbisdec_get_type, gst_omx_mp3dec_get_type,
84 gst_omx_mp3dec_alp_get_type,
86 gst_omx_mp2dec_get_type,
87 gst_omx_amrnbdec_get_type,
88 gst_omx_amrnbenc_get_type,
89 gst_omx_amrwbdec_get_type,
90 gst_omx_amrwbenc_get_type,
91 gst_omx_aacdec_get_type,
92 gst_omx_aacenc_get_type,
93 gst_omx_adpcmdec_get_type,
94 gst_omx_adpcmenc_get_type,
95 gst_omx_g711dec_get_type,
96 gst_omx_g711enc_get_type,
97 gst_omx_g729dec_get_type,
98 gst_omx_g729enc_get_type,
99 gst_omx_ilbcdec_get_type,
100 gst_omx_ilbcenc_get_type, gst_omx_jpegenc_get_type,
101 #endif /* EXPERIMENTAL */
102 gst_omx_audiosink_get_type,
104 gst_omx_videosink_get_type, gst_omx_filereadersrc_get_type,
105 #endif /* EXPERIMENTAL */
106 gst_omx_volume_get_type,};
109 get_config_path (void)
112 #if 1 /* Fix_config_path */
113 return g_build_filename (OMX_CONFIG_DIRPATH, OMX_CONFIG_FILENAME, NULL);
116 const gchar *const *dirs;
119 path = g_strdup (g_getenv ("OMX_CONFIG"));
124 dirs = g_get_system_config_dirs ();
125 for (i = 0; dirs[i]; i++) {
127 g_build_filename (dirs[i], "gstreamer-0.10", "gst-openmax.conf", NULL);
128 if (g_file_test (path, G_FILE_TEST_IS_REGULAR))
133 return g_build_filename (g_get_user_config_dir (), "gst-openmax.conf", NULL);
138 fetch_element_table (GstPlugin * plugin)
142 GstStructure *tmp, *element;
144 element_table = gst_plugin_get_cache_data (plugin);
149 path = get_config_path ();
151 if (!g_file_get_contents (path, &config, NULL, NULL)) {
152 g_warning ("could not find config file '%s'.. using defaults!", path);
153 config = (gchar *) default_config;
156 gst_plugin_add_dependency_simple (plugin, "ONX_CONFIG", path, NULL,
157 GST_PLUGIN_DEPENDENCY_FLAG_NONE);
161 GST_DEBUG ("parsing config:\n%s", config);
163 tmp = gst_structure_empty_new ("element_table");
167 while ((element = gst_structure_from_string (s, &s))) {
168 const gchar *element_name = gst_structure_get_name (element);
169 gst_structure_set (tmp, element_name, GST_TYPE_STRUCTURE, element, NULL);
172 if (config != default_config)
175 GST_DEBUG ("element_table=%" GST_PTR_FORMAT, tmp);
177 gst_plugin_set_cache_data (plugin, tmp);
182 static GstStructure *
183 get_element_entry (const gchar * element_name)
185 GstStructure *element;
187 if (!gst_structure_get ((GstStructure *) element_table, element_name,
188 GST_TYPE_STRUCTURE, &element, NULL)) {
192 /* This assert should never fail, because plugin elements are registered
193 * based on the entries in this table. Someone would have to manually
194 * override the type qdata for this to fail.
201 /* register a new dynamic sub-class with the name 'type_name'.. this gives us
202 * a way to use the same (for example) GstOmxMp3Dec element mapping to
203 * multiple different element names with different OMX library implementations
204 * and/or component names
207 create_subtype (GType parent_type, const gchar * type_name)
210 GTypeInfo i = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
215 g_type_query (parent_type, &q);
217 i.class_size = q.class_size;
218 i.instance_size = q.instance_size;
220 return g_type_register_static (parent_type, type_name, &i, 0);
224 plugin_init (GstPlugin * plugin)
228 GST_DEBUG_CATEGORY_INIT (gstomx_debug, "omx", 0, "gst-openmax");
229 GST_DEBUG_CATEGORY_INIT (gstomx_util_debug, "omx_util", 0,
230 "gst-openmax utility");
232 element_name_quark = g_quark_from_static_string ("element-name");
235 * First, call all the _get_type() functions to ensure the types are
238 for (i = 0; i < G_N_ELEMENTS (get_type); i++)
241 fetch_element_table (plugin);
245 cnt = gst_structure_n_fields (element_table);
246 for (i = 0; i < cnt; i++) {
247 const gchar *element_name = gst_structure_nth_field_name (element_table, i);
248 GstStructure *element = get_element_entry (element_name);
249 const gchar *type_name, *parent_type_name;
250 const gchar *component_name, *library_name;
254 GST_DEBUG ("element_name=%s, element=%" GST_PTR_FORMAT, element_name,
257 parent_type_name = gst_structure_get_string (element, "parent-type");
258 type_name = gst_structure_get_string (element, "type");
259 component_name = gst_structure_get_string (element, "component-name");
260 library_name = gst_structure_get_string (element, "library-name");
262 if (!type_name || !component_name || !library_name) {
263 g_warning ("malformed config file: missing required fields for %s",
265 gst_structure_free(element);
269 if (parent_type_name) {
270 type = g_type_from_name (parent_type_name);
272 type = create_subtype (type, type_name);
274 g_warning ("malformed config file: invalid parent-type '%s' for %s",
275 parent_type_name, element_name);
276 gst_structure_free(element);
280 type = g_type_from_name (type_name);
284 g_warning ("malformed config file: invalid type '%s' for %s",
285 type_name, element_name);
286 gst_structure_free(element);
290 g_type_set_qdata (type, element_name_quark, (gpointer) element_name);
292 if (!gst_structure_get_int (element, "rank", &rank)) {
293 /* use default rank: */
294 rank = GST_RANK_NONE;
297 if (!gst_element_register (plugin, element_name, rank, type)) {
298 g_warning ("failed registering '%s'", element_name);
299 gst_structure_free(element);
303 gst_structure_free(element);
310 gstomx_get_component_info (void *core, GType type)
312 GOmxCore *rcore = core;
313 const gchar *element_name;
314 GstStructure *element;
317 element_name = g_type_get_qdata (type, element_name_quark);
318 element = get_element_entry (element_name);
323 str = gst_structure_get_string (element, "library-name");
324 rcore->library_name = g_strdup (str);
326 str = gst_structure_get_string (element, "component-name");
327 rcore->component_name = g_strdup (str);
329 str = gst_structure_get_string (element, "component-role");
330 rcore->component_role = g_strdup (str);
332 gst_structure_free(element);
337 gstomx_core_new (void *object, GType type)
339 GOmxCore *core = g_omx_core_new (object);
340 gstomx_get_component_info (core, type);
341 g_omx_core_init (core);
346 gstomx_template_caps (GType type, const gchar * pad_name)
348 const gchar *element_name;
349 GstStructure *element;
350 const gchar *caps_str;
351 GstCaps *caps = NULL;
353 element_name = g_type_get_qdata (type, element_name_quark);
354 element = get_element_entry (element_name);
357 /* this shouldn't really happen.. */
361 caps_str = gst_structure_get_string (element, pad_name);
363 GST_DEBUG ("%s: %s", element_name, caps_str);
365 /* default to ANY.. at least for now.. maybe when everything is converted
366 * over, we should treat missing caps as a more serious condition?
369 g_warning ("%s is missing required field: %s", element_name, pad_name);
370 gst_structure_free(element);
374 caps = gst_caps_from_string (caps_str);
375 gst_structure_free(element);
381 gstomx_install_property_helper (GObjectClass * gobject_class)
384 g_object_class_install_property (gobject_class, ARG_COMPONENT_NAME,
385 g_param_spec_string ("component-name", "Component name",
386 "Name of the OpenMAX IL component to use",
387 NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
389 g_object_class_install_property (gobject_class, ARG_COMPONENT_ROLE,
390 g_param_spec_string ("component-role", "Component role",
391 "Role of the OpenMAX IL component",
392 NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
394 g_object_class_install_property (gobject_class, ARG_LIBRARY_NAME,
395 g_param_spec_string ("library-name", "Library name",
396 "Name of the OpenMAX IL implementation library to use",
397 NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
401 gstomx_get_property_helper (void *core, guint prop_id, GValue * value)
403 GOmxCore *gomx = core;
405 case ARG_COMPONENT_NAME:
406 g_value_set_string (value, gomx->component_name);
408 case ARG_COMPONENT_ROLE:
409 g_value_set_string (value, gomx->component_role);
411 case ARG_LIBRARY_NAME:
412 g_value_set_string (value, gomx->library_name);
419 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
424 PACKAGE_VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)