summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Clark <rob@ti.com>2010-03-02 23:57:13 +0200
committerFelipe Contreras <felipe.contreras@nokia.com>2010-03-05 17:15:00 +0200
commit35c941a92cc798cef70c5226a585b67ae4406c2c (patch)
tree31f72246e1ca0af68e724bc937bbe7aaf0883cd6
parentddee035746083677491d38f07b402a5467dff90e (diff)
Initial support for configuration file
Configurable mapping between gst-openmax elements and OMX library-name and component-name via config file. The config file may even create multiple different elements with unique names using the same gst-openmax class but different OMX library-name and/or component-name. In the simple case, of one OMX component per gst-openmax class, specify the gst-openmax class as the 'type', and the 'library-name' and 'compnent-name' of the OMX component, and optionally the 'rank' (defaults to 0 or GST_RANK_NONE): ---- omx_h264dec, type=GstOmxH264Dec, library-name=libomxil-bellagio.so.0, component-name=OMX.st.video_decoder.avc, rank=256; ---- Or in the advanced case of multiple OMX components per gst-openmax class, specify the gst-openmax class as the 'parent-type' and a dynamically created sub-class for the 'type': ---- omx_mp3dec_ti, parent-type=GstOmxMp3Dec, type=GstOmxMp3DecTi library-name=libOMX_Core.so.0, component-name=OMX.TI.AUDIO.DECODE, component-role=audio_decode.dsp.mp3, rank=256; omx_mp3dec_nokia, parent-type=GstOmxMp3Dec, type=GstOmxMp3DecNokia library-name=libomxil_bellagio.so.0, component-name=OMX.nokia.audio_decode.mp3, rank=128; ---- By default, the config file is stored in $HOME/.config/gst-openmax.conf, although if none is found a default config will be created. Modified by Felipe Contreras to keep using the library and component names through qdata. Plus a bunch of cleanups and reorganization. Signed-off-by: Felipe Contreras <felipe.contreras@nokia.com> Signed-off-by: Rob Clark <rob@ti.com>
-rw-r--r--omx/gstomx.c264
1 files changed, 211 insertions, 53 deletions
diff --git a/omx/gstomx.c b/omx/gstomx.c
index 6756f54..914e64f 100644
--- a/omx/gstomx.c
+++ b/omx/gstomx.c
@@ -21,6 +21,10 @@
#include "config.h"
+#include <string.h>
+
+#include <gst/gststructure.h>
+
#include "gstomx.h"
#include "gstomx_dummy.h"
#include "gstomx_mpeg4dec.h"
@@ -59,85 +63,239 @@
GST_DEBUG_CATEGORY (gstomx_debug);
-typedef struct TableItem
-{
- const gchar *name;
- const gchar *library_name;
- const gchar *component_name;
- guint rank;
- GType (*get_type) (void);
-} TableItem;
-
-static TableItem element_table[] =
-{
- { "omx_dummy", "libomxil-bellagio.so.0", "OMX.st.dummy", GST_RANK_NONE, gst_omx_dummy_get_type },
- { "omx_mpeg4dec", "libomxil-bellagio.so.0", "OMX.st.video_decoder.mpeg4", GST_RANK_PRIMARY, gst_omx_mpeg4dec_get_type },
- { "omx_h264dec", "libomxil-bellagio.so.0", "OMX.st.video_decoder.avc", GST_RANK_PRIMARY, gst_omx_h264dec_get_type },
- { "omx_h263dec", "libomxil-bellagio.so.0", "OMX.st.video_decoder.h263", GST_RANK_PRIMARY, gst_omx_h263dec_get_type },
- { "omx_wmvdec", "libomxil-bellagio.so.0", "OMX.st.video_decoder.wmv", GST_RANK_PRIMARY, gst_omx_wmvdec_get_type },
- { "omx_mpeg4enc", "libomxil-bellagio.so.0", "OMX.st.video_encoder.mpeg4", GST_RANK_PRIMARY, gst_omx_mpeg4enc_get_type },
- { "omx_h264enc", "libomxil-bellagio.so.0", "OMX.st.video_encoder.avc", GST_RANK_PRIMARY, gst_omx_h264enc_get_type },
- { "omx_h263enc", "libomxil-bellagio.so.0", "OMX.st.video_encoder.h263", GST_RANK_PRIMARY, gst_omx_h263enc_get_type },
- { "omx_vorbisdec", "libomxil-bellagio.so.0", "OMX.st.audio_decoder.ogg.single", GST_RANK_SECONDARY, gst_omx_vorbisdec_get_type },
- { "omx_mp3dec", "libomxil-bellagio.so.0", "OMX.st.audio_decoder.mp3.mad", GST_RANK_PRIMARY, gst_omx_mp3dec_get_type },
+static GstStructure *element_table = NULL;
+static GQuark element_name_quark;
+
+const gchar *default_config = NULL;
+
+static GType (*get_type[]) (void) = {
+ gst_omx_dummy_get_type,
+ gst_omx_mpeg4dec_get_type,
+ gst_omx_h264dec_get_type,
+ gst_omx_h263dec_get_type,
+ gst_omx_wmvdec_get_type,
+ gst_omx_mpeg4enc_get_type,
+ gst_omx_h264enc_get_type,
+ gst_omx_h263enc_get_type,
+ gst_omx_vorbisdec_get_type,
+ gst_omx_mp3dec_get_type,
#ifdef EXPERIMENTAL
- { "omx_mp2dec", "libomxil-bellagio.so.0", "OMX.st.audio_decoder.mp3.mad", GST_RANK_PRIMARY, gst_omx_mp2dec_get_type },
- { "omx_amrnbdec", "libomxil-bellagio.so.0", "OMX.st.audio_decoder.amrnb", GST_RANK_PRIMARY, gst_omx_amrnbdec_get_type },
- { "omx_amrnbenc", "libomxil-bellagio.so.0", "OMX.st.audio_encoder.amrnb", GST_RANK_PRIMARY, gst_omx_amrnbenc_get_type },
- { "omx_amrwbdec", "libomxil-bellagio.so.0", "OMX.st.audio_decoder.amrwb", GST_RANK_PRIMARY, gst_omx_amrwbdec_get_type },
- { "omx_amrwbenc", "libomxil-bellagio.so.0", "OMX.st.audio_encoder.amrwb", GST_RANK_PRIMARY, gst_omx_amrwbenc_get_type },
- { "omx_aacdec", "libomxil-bellagio.so.0", "OMX.st.audio_decoder.aac", GST_RANK_PRIMARY, gst_omx_aacdec_get_type },
- { "omx_aacenc", "libomxil-bellagio.so.0", "OMX.st.audio_encoder.aac", GST_RANK_PRIMARY, gst_omx_aacenc_get_type },
- { "omx_adpcmdec", "libomxil-bellagio.so.0", "OMX.st.audio_decoder.adpcm", GST_RANK_PRIMARY, gst_omx_adpcmdec_get_type },
- { "omx_adpcmenc", "libomxil-bellagio.so.0", "OMX.st.audio_encoder.adpcm", GST_RANK_PRIMARY, gst_omx_adpcmenc_get_type },
- { "omx_g711dec", "libomxil-bellagio.so.0", "OMX.st.audio_decoder.g711", GST_RANK_PRIMARY, gst_omx_g711dec_get_type },
- { "omx_g711enc", "libomxil-bellagio.so.0", "OMX.st.audio_encoder.g711", GST_RANK_PRIMARY, gst_omx_g711enc_get_type },
- { "omx_g729dec", "libomxil-bellagio.so.0", "OMX.st.audio_decoder.g729", GST_RANK_PRIMARY, gst_omx_g729dec_get_type },
- { "omx_g729enc", "libomxil-bellagio.so.0", "OMX.st.audio_encoder.g729", GST_RANK_PRIMARY, gst_omx_g729enc_get_type },
- { "omx_ilbcdec", "libomxil-bellagio.so.0", "OMX.st.audio_decoder.ilbc", GST_RANK_PRIMARY, gst_omx_ilbcdec_get_type },
- { "omx_ilbcenc", "libomxil-bellagio.so.0", "OMX.st.audio_encoder.ilbc", GST_RANK_PRIMARY, gst_omx_ilbcenc_get_type },
- { "omx_jpegenc", "libomxil-bellagio.so.0", "OMX.st.image_encoder.jpeg", GST_RANK_PRIMARY, gst_omx_jpegenc_get_type },
+ gst_omx_mp2dec_get_type,
+ gst_omx_amrnbdec_get_type,
+ gst_omx_amrnbenc_get_type,
+ gst_omx_amrwbdec_get_type,
+ gst_omx_amrwbenc_get_type,
+ gst_omx_aacdec_get_type,
+ gst_omx_aacenc_get_type,
+ gst_omx_adpcmdec_get_type,
+ gst_omx_adpcmenc_get_type,
+ gst_omx_g711dec_get_type,
+ gst_omx_g711enc_get_type,
+ gst_omx_g729dec_get_type,
+ gst_omx_g729enc_get_type,
+ gst_omx_ilbcdec_get_type,
+ gst_omx_ilbcenc_get_type,
+ gst_omx_jpegenc_get_type,
#endif /* EXPERIMENTAL */
- { "omx_audiosink", "libomxil-bellagio.so.0", "OMX.st.alsa.alsasink", GST_RANK_NONE, gst_omx_audiosink_get_type },
+ gst_omx_audiosink_get_type,
#ifdef EXPERIMENTAL
- { "omx_videosink", "libomxil-bellagio.so.0", "OMX.st.videosink", GST_RANK_NONE, gst_omx_videosink_get_type },
- { "omx_filereadersrc", "libomxil-bellagio.so.0", "OMX.st.audio_filereader", GST_RANK_NONE, gst_omx_filereadersrc_get_type },
+ gst_omx_videosink_get_type,
+ gst_omx_filereadersrc_get_type,
#endif /* EXPERIMENTAL */
- { "omx_volume", "libomxil-bellagio.so.0", "OMX.st.volume.component", GST_RANK_NONE, gst_omx_volume_get_type },
- { NULL, NULL, NULL, 0, NULL },
+ gst_omx_volume_get_type,
};
+/**
+ * @todo find a way to call plugin_init() when the config file changes
+ * @todo support a system-wide config file
+ * @todo provide a recommended system-wide config file
+ */
+
+/* TODO: we can cache table w/ gst_plugin_{get,set}_cache_data..
+ */
+static GstStructure *
+get_element_table (void)
+{
+ static volatile gsize gonce_data = 0;
+ if (g_once_init_enter (&gonce_data))
+ {
+ gchar *path;
+ gchar *config, *s;
+ GstStructure *element;
+
+ path = g_strdup (g_getenv ("OMX_CONFIG"));
+ if (!path)
+ {
+ path = g_build_filename (g_get_user_config_dir (),
+ "gst-openmax.conf", NULL);
+ }
+
+ if (!g_file_get_contents (path, &config, NULL, NULL))
+ {
+ g_warning ("could not find config file '%s'.. using defaults!", path);
+ config = (gchar *) default_config;
+ }
+
+ g_free (path);
+
+ GST_DEBUG ("parsing config:\n%s", config);
+
+ element_table = gst_structure_empty_new ("element_table");
+
+ s = config;
+
+ while ((element = gst_structure_from_string (s, &s)))
+ {
+ const gchar *element_name = gst_structure_get_name (element);
+ gst_structure_set (element_table,
+ element_name, GST_TYPE_STRUCTURE, element, NULL);
+ }
+
+ if (config != default_config)
+ g_free (config);
+
+ GST_DEBUG ("element_table=%" GST_PTR_FORMAT, element_table);
+
+ g_once_init_leave (&gonce_data, 1);
+ }
+
+ return element_table;
+}
+
+static GstStructure *
+get_element_entry (const gchar *element_name)
+{
+ GstStructure *element_table = get_element_table ();
+ GstStructure *element;
+
+ if (!gst_structure_get (element_table, element_name,
+ GST_TYPE_STRUCTURE, &element, NULL))
+ {
+ element = NULL;
+ }
+
+ /* This assert should never fail, because plugin elements are registered
+ * based on the entries in this table. Someone would have to manually
+ * override the type qdata for this to fail.
+ */
+ g_assert (element);
+
+ return element;
+}
+
+/* register a new dynamic sub-class with the name 'type_name'.. this gives us
+ * a way to use the same (for example) GstOmxMp3Dec element mapping to
+ * multiple different element names with different OMX library implementations
+ * and/or component names
+ */
+static GType
+create_subtype (GType parent_type, const gchar *type_name)
+{
+ GTypeQuery q;
+ GTypeInfo i = {0};
+
+ if (!type_name)
+ return 0;
+
+ g_type_query (parent_type, &q);
+
+ i.class_size = q.class_size;
+ i.instance_size = q.instance_size;
+
+ return g_type_register_static (parent_type, type_name, &i, 0);
+}
+
static gboolean
plugin_init (GstPlugin *plugin)
{
GQuark library_name_quark;
GQuark component_name_quark;
+ gint i, cnt;
+ GstStructure *element_table;
+
GST_DEBUG_CATEGORY_INIT (gstomx_debug, "omx", 0, "gst-openmax");
GST_DEBUG_CATEGORY_INIT (gstomx_util_debug, "omx_util", 0, "gst-openmax utility");
library_name_quark = g_quark_from_static_string ("library-name");
component_name_quark = g_quark_from_static_string ("component-name");
+ element_name_quark = g_quark_from_static_string ("element-name");
+
+ /*
+ * First, call all the _get_type() functions to ensure the types are
+ * registered.
+ */
+ for (i = 0; i < G_N_ELEMENTS (get_type); i++)
+ get_type[i] ();
+
+ element_table = get_element_table ();
g_omx_init ();
+ cnt = gst_structure_n_fields (element_table);
+ for (i = 0; i < cnt; i++)
{
- guint i;
- for (i = 0; element_table[i].name; i++)
- {
- TableItem *element;
- GType type;
+ const gchar *element_name = gst_structure_nth_field_name (element_table, i);
+ GstStructure *element = get_element_entry (element_name);
+ const gchar *type_name, *parent_type_name;
+ const gchar *component_name, *library_name;
+ GType type;
+ gint rank;
- element = &element_table[i];
- type = element->get_type ();
- g_type_set_qdata (type, library_name_quark, (gpointer) element->library_name);
- g_type_set_qdata (type, component_name_quark, (gpointer) element->component_name);
+ GST_DEBUG ("element_name=%s, element=%" GST_PTR_FORMAT, element_name, element);
- if (!gst_element_register (plugin, element->name, element->rank, type))
+ parent_type_name = gst_structure_get_string (element, "parent-type");
+ type_name = gst_structure_get_string (element, "type");
+ component_name = gst_structure_get_string (element, "component-name");
+ library_name = gst_structure_get_string (element, "library-name");
+
+ if (!type_name || !component_name || !library_name)
+ {
+ g_warning ("malformed config file: missing required fields for %s",
+ element_name);
+ return FALSE;
+ }
+
+ if (parent_type_name)
+ {
+ type = g_type_from_name (parent_type_name);
+ if (type)
+ {
+ type = create_subtype (type, type_name);
+ }
+ else
{
- g_warning ("failed registering '%s'", element->name);
+ g_warning ("malformed config file: invalid parent-type '%s' for %s",
+ parent_type_name, element_name);
return FALSE;
}
}
+ else
+ {
+ type = g_type_from_name (type_name);
+ }
+
+ if (!type)
+ {
+ g_warning ("malformed config file: invalid type '%s' for %s",
+ type_name, element_name);
+ return FALSE;
+ }
+
+ g_type_set_qdata (type, library_name_quark, (gpointer) library_name);
+ g_type_set_qdata (type, component_name_quark, (gpointer) component_name);
+ g_type_set_qdata (type, element_name_quark, (gpointer) element_name);
+
+ if (!gst_structure_get_int (element, "rank", &rank))
+ {
+ /* use default rank: */
+ rank = GST_RANK_NONE;
+ }
+
+ if (!gst_element_register (plugin, element_name, rank, type))
+ {
+ g_warning ("failed registering '%s'", element_name);
+ return FALSE;
+ }
}
return TRUE;