From: Rob C. <ro...@ti...> - 2010-02-25 02:01:51
|
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. For example: ---- omx_mp3dec_ti, type=GstOmxMp3Dec, library-name=libOMX_Core.so.0, component-name=OMX.TI.AUDIO.DECODE, component-role=audio_decode.dsp.mp3, rank=256; omx_mp3dec_nokia, type=GstOmxMp3Dec, library-name=libomxil_bellagio.so.0, component-name=OMX.nokia.audio_decode.mp3, rank=128; ---- by default, the config file is stored in $HOME/.gstreamer-0.10/gst-openmax.conf, although if none is found a default config will be created. --- configure.ac | 3 + omx/Makefile.am | 9 +- omx/gstomx.c | 353 ++++++++++++++++++++++++++++++++++++++-------- omx/gstomx.conf | 216 ++++++++++++++++++++++++++++ omx/gstomx.h | 12 ++ omx/gstomx_base_filter.c | 31 +---- omx/gstomx_base_filter.h | 2 - omx/gstomx_base_sink.c | 31 +---- omx/gstomx_base_sink.h | 3 - omx/gstomx_base_src.c | 38 +----- omx/gstomx_base_src.h | 2 - omx/gstomx_util.c | 9 +- omx/gstomx_util.h | 2 +- 13 files changed, 553 insertions(+), 158 deletions(-) create mode 100644 omx/gstomx.conf diff --git a/configure.ac b/configure.ac index 22dcf7d..3d7df3f 100644 --- a/configure.ac +++ b/configure.ac @@ -11,6 +11,9 @@ dnl versions of GStreamer GST_MAJORMINOR=0.10 GST_REQUIRED=0.10.0 +AC_DEFINE_UNQUOTED(GST_MAJORMINOR, "$GST_MAJORMINOR", + [library major.minor version]) + dnl AM_MAINTAINER_MODE provides the option to enable maintainer mode AM_MAINTAINER_MODE diff --git a/omx/Makefile.am b/omx/Makefile.am index 4a3fbf9..1bb9901 100644 --- a/omx/Makefile.am +++ b/omx/Makefile.am @@ -18,7 +18,8 @@ libgstomx_la_SOURCES = gstomx.c gstomx.h \ gstomx_vorbisdec.c gstomx_vorbisdec.h \ gstomx_mp3dec.c gstomx_mp3dec.h \ gstomx_base_sink.c gstomx_base_sink.h \ - gstomx_audiosink.c gstomx_audiosink.h + gstomx_audiosink.c gstomx_audiosink.h \ + gstomx_conf.c if EXPERIMENTAL libgstomx_la_SOURCES += gstomx_amrnbdec.c gstomx_amrnbdec.h \ @@ -47,3 +48,9 @@ libgstomx_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) $(top_builddir)/util/libutil. libgstomx_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) EXTRA_DIST = headers + +gstomx_conf.c: gstomx.conf + echo "const char * default_config =" > $@ + cat $^ | $(CPP) $(CFLAGS) $(libgstomx_la_CFLAGS) $(DEFAULT_INCLUDES) $(INCLUDES) - | grep -v "^#" | sed 's/^.*/\"&\\\n"/' >> $@ + echo ";" >> $@ + diff --git a/omx/gstomx.c b/omx/gstomx.c index 6756f54..ae80813 100644 --- a/omx/gstomx.c +++ b/omx/gstomx.c @@ -19,8 +19,12 @@ * */ +#include <string.h> + #include "config.h" +#include <gst/gststructure.h> + #include "gstomx.h" #include "gstomx_dummy.h" #include "gstomx_mpeg4dec.h" @@ -59,90 +63,317 @@ 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; + +extern const gchar *default_config; + +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: 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_REGISTRY")); + if (!path) + { + path = g_build_filename (g_get_home_dir (), + ".gstreamer-" GST_MAJORMINOR, "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_file_set_contents (path, config, -1, NULL); + } + + 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); + } + + g_free (path); + + 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; + + g_assert (gst_structure_get (element_table, + element_name, GST_TYPE_STRUCTURE, &element, NULL)); + + return element; +} + +static const gchar * +get_element_name (gpointer object) +{ + return g_type_name (G_OBJECT_TYPE (object)); +} + + +/* register a new dynamic sub-class with the omx element as it's 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 type, const gchar *element_name) +{ + GTypeQuery q; + GTypeInfo i; + + g_type_query (type, &q); + + bzero (&i, sizeof (i)); + + i.class_size = q.class_size; + i.instance_size = q.instance_size; + + return g_type_register_static (type, element_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"); + /* first, call all the _get_type() functions to ensure the types are + * registered: + */ + for (i = 0; i < DIM (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++) + const gchar *element_name = gst_structure_nth_field_name (element_table, i); + GstStructure *element = get_element_entry (element_name); + const gchar *type_name; + GType type; + gint rank; + + GST_DEBUG ("element=%"GST_PTR_FORMAT, element); + + type_name = gst_structure_get_string (element, "type"); + if (!type_name) + { + g_warning ("malformed config file: missing 'type' for %s", element_name); + return FALSE; + } + + 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; + } + + type = create_subtype (type, element_name); + + if (!gst_structure_get_int (element, "rank", &rank)) { - TableItem *element; - GType type; - - 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); - - if (!gst_element_register (plugin, element->name, element->rank, type)) - { - g_warning ("failed registering '%s'", element->name); - return FALSE; - } + /* 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; } +/** + * g_omx_get_component_info: + * @object: the GstOmx object (ie. GstOmxBaseFilter, GstOmxBaseSrc, or + * GstOmxBaseSink). + * @library_name: library-name, returned by reference (or NULL) + * @component_name: component-name, returned by reference (or NULL) + * + * Get library-name and component-name for an element. + * + * note: this function will gain another parameter later when component-role + * is added + */ +gboolean +g_omx_get_component_info (gpointer object, + gchar **library_name, + gchar **component_name) +{ + gboolean ret = TRUE; + const gchar *element_name = get_element_name (object); + GstStructure *element = get_element_entry (element_name); + + g_assert (gst_structure_get (element_table, + element_name, GST_TYPE_STRUCTURE, &element, NULL)); + + /* initialize ptrs to NULL so that in error cases we can tell what needs + * to be freed: + */ + if (library_name) *library_name = NULL; + if (component_name) *component_name = NULL; + + if (library_name) + { + const gchar *str = gst_structure_get_string (element, "library-name"); + if (!str) + { + g_warning ("malformed config file: missing 'library-name' for %s", element_name); + ret = FALSE; + goto beach; + } + *library_name = g_strdup (str); + } + + if (component_name) + { + const gchar *str = gst_structure_get_string (element, "component-name"); + if (!str) + { + g_warning ("malformed config file: missing 'component-name' for %s", element_name); + ret = FALSE; + goto beach; + } + *component_name = g_strdup (str); + } + +beach: + + /* if we failed, free any memory that might have been allocated: + */ + if (!ret) + { + if (library_name) g_free (*library_name); + if (component_name) g_free (*component_name); + } + + + return ret; +} + +static gboolean +set_value_helper (GValue *value, gchar *str) +{ + g_value_set_string (value, str); + return TRUE; +} + +/** + * g_omx_get_library_name_value: + * @object: the GstOmx object (ie. GstOmxBaseFilter, GstOmxBaseSrc, or + * GstOmxBaseSink). + * @val: the GValue to return the value through + * + * A helper to access the "library-name" as a GValue, mainly for + * get_property methods. + */ +gboolean +g_omx_get_library_name_value (gpointer object, GValue *val) +{ + gchar *str; + return g_omx_get_component_info (object, &str, NULL) && + set_value_helper (val, str); +} + +/** + * g_omx_get_component_name_value: + * @object: the GstOmx object (ie. GstOmxBaseFilter, GstOmxBaseSrc, or + * GstOmxBaseSink). + * @val: the GValue to return the value through + * + * A helper to access the "component-name" as a GValue, mainly for + * get_property methods. + */ +gboolean +g_omx_get_component_name_value (gpointer object, GValue *val) +{ + gchar *str; + return g_omx_get_component_info (object, NULL, &str) && + set_value_helper (val, str); +} + + GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, "omx", diff --git a/omx/gstomx.conf b/omx/gstomx.conf new file mode 100644 index 0000000..6a88dc1 --- /dev/null +++ b/omx/gstomx.conf @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2010 Texas Instruments, Incorporated + * Copyright (C) 2007-2010 Nokia Corporation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "config.h" + +omx_dummy, + type=GstOmxDummy, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.dummy, + rank=0; + +/* for testing: */ +omx_dummy_2, + type=GstOmxDummy, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.dummy2, + rank=256; + +omx_mpeg4dec, + type=GstOmxMpeg4Dec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.video_decoder.mpeg4, + rank=256; + +omx_h264dec, + type=GstOmxH264Dec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.video_decoder.avc, + rank=256; + +omx_h263dec, + type=GstOmxH263Dec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.video_decoder.h263, + rank=256; + +omx_wmvdec, + type=GstOmxWmvDec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.video_decoder.wmv, + rank=256; + +omx_mpeg4enc, + type=GstOmxMpeg4Enc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.video_encoder.mpeg4, + rank=256; + +omx_h264enc, + type=GstOmxH264Enc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.video_encoder.avc, + rank=256; + +omx_h263enc, + type=GstOmxH263Enc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.video_encoder.h263, + rank=256; + +omx_vorbisdec, + type=GstOmxVorbisDec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.ogg.single, + rank=128; + +omx_mp3dec, + type=GstOmxMp3Dec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.mp3.mad, + rank=256; + +#ifdef EXPERIMENTAL + +omx_mp2dec, + type=GstOmxMp2Dec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.mp3.mad, + rank=256; + +omx_amrnbdec, + type=GstOmxAmrNbDec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.amrnb, + rank=256; + +omx_amrnbenc, + type=GstOmxAmrNbEnc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_encoder.amrnb, + rank=256; + +omx_amrwbdec, + type=GstOmxAmrWbDec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.amrwb, + rank=256; + +omx_amrwbenc, + type=GstOmxAmrWbEnc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_encoder.amrwb, + rank=256; + +omx_aacdec, + type=GstOmxAacDec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.aac, + rank=256; + +omx_aacenc, + type=GstOmxAacEnc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_encoder.aac, + rank=256; + +omx_adpcmdec, + type=GstOmxAdpcmDec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.adpcm, + rank=256; + +omx_adpcmenc, + type=GstOmxAdpcmEnc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_encoder.adpcm, + rank=256; + +omx_g711dec, + type=GstOmxG711Dec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.g711, + rank=256; + +omx_g711enc, + type=GstOmxG711Enc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_encoder.g711, + rank=256; + +omx_g729dec, + type=GstOmxG729Dec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.g729, + rank=256; + +omx_g729enc, + type=GstOmxG729Enc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_encoder.g729, + rank=256; + +omx_ilbcdec, + type=GstOmxIlbcDec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.ilbc, + rank=256; + +omx_ilbcenc, + type=GstOmxIlbcEnc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_encoder.ilbc, + rank=256; + +omx_jpegenc, + type=GstOmxJpegEnc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.image_encoder.jpeg, + rank=256; + +#endif /* EXPERIMENTAL */ + +omx_audiosink, + type=GstOmxAudioSink, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.alsa.alsasink, + rank=0; + +#ifdef EXPERIMENTAL + +omx_videosink, + type=GstOmxVideoSink, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.videosink, + rank=0; + +omx_filereadersrc, + type=GstOmxFilereaderSrc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_filereader, + rank=0; + +#endif /* EXPERIMENTAL */ + +omx_volume, + type=GstOmxVolume, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.volume.component, + rank=0; diff --git a/omx/gstomx.h b/omx/gstomx.h index 7d5fa04..0d362d7 100644 --- a/omx/gstomx.h +++ b/omx/gstomx.h @@ -30,6 +30,18 @@ GST_DEBUG_CATEGORY_EXTERN (gstomx_debug); GST_DEBUG_CATEGORY_EXTERN (gstomx_util_debug); #define GST_CAT_DEFAULT gstomx_debug +#ifndef DIM /* XXX is there a better alternative available? */ +# define DIM(x) (sizeof(x)/sizeof((x)[0])) +#endif + + +gboolean g_omx_get_component_info (gpointer object, + gchar **library_name, + gchar **component_name); +gboolean g_omx_get_library_name_value (gpointer object, GValue *val); +gboolean g_omx_get_component_name_value (gpointer object, GValue *val); + + G_END_DECLS #endif /* GSTOMX_H */ diff --git a/omx/gstomx_base_filter.c b/omx/gstomx_base_filter.c index b0353cb..2a30502 100644 --- a/omx/gstomx_base_filter.c +++ b/omx/gstomx_base_filter.c @@ -115,7 +115,7 @@ change_state (GstElement *element, switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: - g_omx_core_init (core, self->omx_library, self->omx_component); + g_omx_core_init (core); if (core->omx_state != OMX_StateLoaded) { ret = GST_STATE_CHANGE_FAILURE; @@ -184,9 +184,6 @@ finalize (GObject *obj) g_omx_core_free (self->gomx); - g_free (self->omx_component); - g_free (self->omx_library); - g_mutex_free (self->ready_lock); G_OBJECT_CLASS (parent_class)->finalize (obj); @@ -204,14 +201,6 @@ set_property (GObject *obj, switch (prop_id) { - case ARG_COMPONENT_NAME: - g_free (self->omx_component); - self->omx_component = g_value_dup_string (value); - break; - case ARG_LIBRARY_NAME: - g_free (self->omx_library); - self->omx_library = g_value_dup_string (value); - break; case ARG_USE_TIMESTAMPS: self->use_timestamps = g_value_get_boolean (value); break; @@ -234,10 +223,10 @@ get_property (GObject *obj, switch (prop_id) { case ARG_COMPONENT_NAME: - g_value_set_string (value, self->omx_component); + g_omx_get_component_name_value (self, value); break; case ARG_LIBRARY_NAME: - g_value_set_string (value, self->omx_library); + g_omx_get_library_name_value (self, value); break; case ARG_USE_TIMESTAMPS: g_value_set_boolean (value, self->use_timestamps); @@ -271,12 +260,12 @@ type_class_init (gpointer g_class, g_object_class_install_property (gobject_class, ARG_COMPONENT_NAME, g_param_spec_string ("component-name", "Component name", "Name of the OpenMAX IL component to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); g_object_class_install_property (gobject_class, ARG_LIBRARY_NAME, g_param_spec_string ("library-name", "Library name", "Name of the OpenMAX IL implementation library to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); g_object_class_install_property (gobject_class, ARG_USE_TIMESTAMPS, g_param_spec_boolean ("use-timestamps", "Use timestamps", @@ -922,16 +911,6 @@ type_instance_init (GTypeInstance *instance, gst_element_add_pad (GST_ELEMENT (self), self->sinkpad); gst_element_add_pad (GST_ELEMENT (self), self->srcpad); - { - const char *tmp; - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("library-name")); - self->omx_library = g_strdup (tmp); - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("component-name")); - self->omx_component = g_strdup (tmp); - } - GST_LOG_OBJECT (self, "end"); } diff --git a/omx/gstomx_base_filter.h b/omx/gstomx_base_filter.h index 4baf181..99b5d72 100644 --- a/omx/gstomx_base_filter.h +++ b/omx/gstomx_base_filter.h @@ -48,8 +48,6 @@ struct GstOmxBaseFilter GOmxPort *in_port; GOmxPort *out_port; - char *omx_component; - char *omx_library; gboolean use_timestamps; /** @todo remove; timestamps should always be used */ gboolean ready; GMutex *ready_lock; diff --git a/omx/gstomx_base_sink.c b/omx/gstomx_base_sink.c index c1a2076..7911167 100644 --- a/omx/gstomx_base_sink.c +++ b/omx/gstomx_base_sink.c @@ -141,9 +141,6 @@ finalize (GObject *obj) g_omx_core_free (self->gomx); - g_free (self->omx_component); - g_free (self->omx_library); - G_OBJECT_CLASS (parent_class)->finalize (obj); } @@ -298,14 +295,6 @@ set_property (GObject *obj, switch (prop_id) { - case ARG_COMPONENT_NAME: - g_free (self->omx_component); - self->omx_component = g_value_dup_string (value); - break; - case ARG_LIBRARY_NAME: - g_free (self->omx_library); - self->omx_library = g_value_dup_string (value); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); break; @@ -325,10 +314,10 @@ get_property (GObject *obj, switch (prop_id) { case ARG_COMPONENT_NAME: - g_value_set_string (value, self->omx_component); + g_omx_get_component_name_value (self, value); break; case ARG_LIBRARY_NAME: - g_value_set_string (value, self->omx_library); + g_omx_get_library_name_value (self, value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); @@ -366,12 +355,12 @@ type_class_init (gpointer g_class, g_object_class_install_property (gobject_class, ARG_COMPONENT_NAME, g_param_spec_string ("component-name", "Component name", "Name of the OpenMAX IL component to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); g_object_class_install_property (gobject_class, ARG_LIBRARY_NAME, g_param_spec_string ("library-name", "Library name", "Name of the OpenMAX IL implementation library to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); } } @@ -420,7 +409,7 @@ activate_push (GstPad *pad, static inline gboolean omx_init (GstOmxBaseSink *self) { - g_omx_core_init (self->gomx, self->omx_library, self->omx_component); + g_omx_core_init (self->gomx); if (self->gomx->omx_error) return FALSE; @@ -468,16 +457,6 @@ type_instance_init (GTypeInstance *instance, } { - const char *tmp; - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("library-name")); - self->omx_library = g_strdup (tmp); - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("component-name")); - self->omx_component = g_strdup (tmp); - } - - { GstPad *sinkpad; self->sinkpad = sinkpad = GST_BASE_SINK_PAD (self); self->base_activatepush = GST_PAD_ACTIVATEPUSHFUNC (sinkpad); diff --git a/omx/gstomx_base_sink.h b/omx/gstomx_base_sink.h index 681e939..589c441 100644 --- a/omx/gstomx_base_sink.h +++ b/omx/gstomx_base_sink.h @@ -46,9 +46,6 @@ struct GstOmxBaseSink GOmxCore *gomx; GOmxPort *in_port; - char *omx_component; - char *omx_library; - gboolean ready; GstPadActivateModeFunction base_activatepush; gboolean initialized; diff --git a/omx/gstomx_base_src.c b/omx/gstomx_base_src.c index 9b02b22..dd9767e 100644 --- a/omx/gstomx_base_src.c +++ b/omx/gstomx_base_src.c @@ -67,7 +67,7 @@ start (GstBaseSrc *gst_base) GST_LOG_OBJECT (self, "begin"); - g_omx_core_init (self->gomx, self->omx_library, self->omx_component); + g_omx_core_init (self->gomx); if (self->gomx->omx_error) return GST_STATE_CHANGE_FAILURE; @@ -106,9 +106,6 @@ finalize (GObject *obj) g_omx_core_free (self->gomx); - g_free (self->omx_component); - g_free (self->omx_library); - G_OBJECT_CLASS (parent_class)->finalize (obj); } @@ -362,20 +359,6 @@ set_property (GObject *obj, switch (prop_id) { - case ARG_COMPONENT_NAME: - if (self->omx_component) - { - g_free (self->omx_component); - } - self->omx_component = g_value_dup_string (value); - break; - case ARG_LIBRARY_NAME: - if (self->omx_library) - { - g_free (self->omx_library); - } - self->omx_library = g_value_dup_string (value); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); break; @@ -395,10 +378,10 @@ get_property (GObject *obj, switch (prop_id) { case ARG_COMPONENT_NAME: - g_value_set_string (value, self->omx_component); + g_omx_get_component_name_value (self, value); break; case ARG_LIBRARY_NAME: - g_value_set_string (value, self->omx_library); + g_omx_get_library_name_value (self, value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); @@ -433,12 +416,12 @@ type_class_init (gpointer g_class, g_object_class_install_property (gobject_class, ARG_COMPONENT_NAME, g_param_spec_string ("component-name", "Component name", "Name of the OpenMAX IL component to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); g_object_class_install_property (gobject_class, ARG_LIBRARY_NAME, g_param_spec_string ("library-name", "Library name", "Name of the OpenMAX IL implementation library to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); } } @@ -459,17 +442,6 @@ type_instance_init (GTypeInstance *instance, gomx->object = self; } - { - const char *tmp; - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("library-name")); - self->omx_library = g_strdup (tmp); - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("component-name")); - self->omx_component = g_strdup (tmp); - } - - GST_LOG_OBJECT (self, "end"); } diff --git a/omx/gstomx_base_src.h b/omx/gstomx_base_src.h index 85e4c13..adab894 100644 --- a/omx/gstomx_base_src.h +++ b/omx/gstomx_base_src.h @@ -44,8 +44,6 @@ struct GstOmxBaseSrc GOmxCore *gomx; GOmxPort *out_port; - char *omx_component; - char *omx_library; GstOmxBaseSrcCb setup_ports; }; diff --git a/omx/gstomx_util.c b/omx/gstomx_util.c index 39d900b..c429738 100644 --- a/omx/gstomx_util.c +++ b/omx/gstomx_util.c @@ -301,10 +301,13 @@ g_omx_core_free (GOmxCore *core) } void -g_omx_core_init (GOmxCore *core, - const gchar *library_name, - const gchar *component_name) +g_omx_core_init (GOmxCore *core) { + gchar *library_name, *component_name; + + g_assert (g_omx_get_component_info (core->object, + &library_name, &component_name)); + core->imp = request_imp (library_name); if (!core->imp) diff --git a/omx/gstomx_util.h b/omx/gstomx_util.h index f0cf045..c3ac441 100644 --- a/omx/gstomx_util.h +++ b/omx/gstomx_util.h @@ -116,7 +116,7 @@ void g_omx_deinit (void); GOmxCore *g_omx_core_new (void); void g_omx_core_free (GOmxCore *core); -void g_omx_core_init (GOmxCore *core, const gchar *library_name, const gchar *component_name); +void g_omx_core_init (GOmxCore *core); void g_omx_core_deinit (GOmxCore *core); void g_omx_core_prepare (GOmxCore *core); void g_omx_core_start (GOmxCore *core); -- 1.6.3.2 |
From: Rob C. <ro...@ti...> - 2010-02-26 18:31:29
|
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. For example: ---- omx_mp3dec_ti, type=GstOmxMp3Dec, library-name=libOMX_Core.so.0, component-name=OMX.TI.AUDIO.DECODE, component-role=audio_decode.dsp.mp3, rank=256; omx_mp3dec_nokia, type=GstOmxMp3Dec, library-name=libomxil_bellagio.so.0, component-name=OMX.nokia.audio_decode.mp3, rank=128; ---- by default, the config file is stored in $HOME/.gstreamer-0.10/gst-openmax.conf, although if none is found a default config will be created. --- omx/Makefile.am | 3 +- omx/gstomx.c | 348 ++++++++++++++++++++++++++++++++++++++-------- omx/gstomx.h | 6 + omx/gstomx_base_filter.c | 31 +---- omx/gstomx_base_filter.h | 2 - omx/gstomx_base_sink.c | 31 +---- omx/gstomx_base_sink.h | 3 - omx/gstomx_base_src.c | 38 +----- omx/gstomx_base_src.h | 2 - omx/gstomx_conf.c | 217 +++++++++++++++++++++++++++++ omx/gstomx_util.c | 9 +- omx/gstomx_util.h | 2 +- 12 files changed, 534 insertions(+), 158 deletions(-) create mode 100644 omx/gstomx_conf.c diff --git a/omx/Makefile.am b/omx/Makefile.am index 4a3fbf9..6ea9cf5 100644 --- a/omx/Makefile.am +++ b/omx/Makefile.am @@ -18,7 +18,8 @@ libgstomx_la_SOURCES = gstomx.c gstomx.h \ gstomx_vorbisdec.c gstomx_vorbisdec.h \ gstomx_mp3dec.c gstomx_mp3dec.h \ gstomx_base_sink.c gstomx_base_sink.h \ - gstomx_audiosink.c gstomx_audiosink.h + gstomx_audiosink.c gstomx_audiosink.h \ + gstomx_conf.c if EXPERIMENTAL libgstomx_la_SOURCES += gstomx_amrnbdec.c gstomx_amrnbdec.h \ diff --git a/omx/gstomx.c b/omx/gstomx.c index 6756f54..6a53eda 100644 --- a/omx/gstomx.c +++ b/omx/gstomx.c @@ -19,8 +19,12 @@ * */ +#include <string.h> + #include "config.h" +#include <gst/gststructure.h> + #include "gstomx.h" #include "gstomx_dummy.h" #include "gstomx_mpeg4dec.h" @@ -59,90 +63,312 @@ 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; + +extern const gchar *default_config; + +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: 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_REGISTRY")); + 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_file_set_contents (path, config, -1, NULL); + } + + 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); + } + + g_free (path); + + 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; + + g_assert (gst_structure_get (element_table, + element_name, GST_TYPE_STRUCTURE, &element, NULL)); + + return element; +} + +static const gchar * +get_element_name (gpointer object) +{ + return g_type_name (G_OBJECT_TYPE (object)); +} + +/* register a new dynamic sub-class with the omx element as it's 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 type, const gchar *element_name) +{ + GTypeQuery q; + GTypeInfo i = {0}; + + g_type_query (type, &q); + + i.class_size = q.class_size; + i.instance_size = q.instance_size; + + return g_type_register_static (type, element_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"); + /* 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++) + const gchar *element_name = gst_structure_nth_field_name (element_table, i); + GstStructure *element = get_element_entry (element_name); + const gchar *type_name; + GType type; + gint rank; + + GST_DEBUG ("element=%"GST_PTR_FORMAT, element); + + type_name = gst_structure_get_string (element, "type"); + if (!type_name) { - TableItem *element; - GType type; - - 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); - - if (!gst_element_register (plugin, element->name, element->rank, type)) - { - g_warning ("failed registering '%s'", element->name); - return FALSE; - } + g_warning ("malformed config file: missing 'type' for %s", element_name); + return FALSE; + } + + 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; + } + + type = create_subtype (type, 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; } +/** + * g_omx_get_component_info: + * @object: the GstOmx object (ie. GstOmxBaseFilter, GstOmxBaseSrc, or + * GstOmxBaseSink). + * @library_name: library-name, returned by reference (or NULL) + * @component_name: component-name, returned by reference (or NULL) + * + * Get library-name and component-name for an element. + * + * note: this function will gain another parameter later when component-role + * is added + */ +gboolean +g_omx_get_component_info (gpointer object, + gchar **library_name, + gchar **component_name) +{ + gboolean ret = TRUE; + const gchar *element_name = get_element_name (object); + GstStructure *element = get_element_entry (element_name); + + g_assert (gst_structure_get (element_table, + element_name, GST_TYPE_STRUCTURE, &element, NULL)); + + /* initialize ptrs to NULL so that in error cases we can tell what needs + * to be freed: + */ + if (library_name) *library_name = NULL; + if (component_name) *component_name = NULL; + + if (library_name) + { + const gchar *str = gst_structure_get_string (element, "library-name"); + if (!str) + { + g_warning ("malformed config file: missing 'library-name' for %s", element_name); + ret = FALSE; + goto exit; + } + *library_name = g_strdup (str); + } + + if (component_name) + { + const gchar *str = gst_structure_get_string (element, "component-name"); + if (!str) + { + g_warning ("malformed config file: missing 'component-name' for %s", element_name); + ret = FALSE; + goto exit; + } + *component_name = g_strdup (str); + } + +exit: + + /* if we failed, free any memory that might have been allocated: + */ + if (!ret) + { + if (library_name) g_free (*library_name); + if (component_name) g_free (*component_name); + } + + + return ret; +} + +static gboolean +set_value_helper (GValue *value, gchar *str) +{ + g_value_set_string (value, str); + return TRUE; +} + +/** + * g_omx_get_library_name_value: + * @object: the GstOmx object (ie. GstOmxBaseFilter, GstOmxBaseSrc, or + * GstOmxBaseSink). + * @val: the GValue to return the value through + * + * A helper to access the "library-name" as a GValue, mainly for + * get_property methods. + */ +gboolean +g_omx_get_library_name_value (gpointer object, GValue *val) +{ + gchar *str; + return g_omx_get_component_info (object, &str, NULL) && + set_value_helper (val, str); +} + +/** + * g_omx_get_component_name_value: + * @object: the GstOmx object (ie. GstOmxBaseFilter, GstOmxBaseSrc, or + * GstOmxBaseSink). + * @val: the GValue to return the value through + * + * A helper to access the "component-name" as a GValue, mainly for + * get_property methods. + */ +gboolean +g_omx_get_component_name_value (gpointer object, GValue *val) +{ + gchar *str; + return g_omx_get_component_info (object, NULL, &str) && + set_value_helper (val, str); +} + GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, "omx", diff --git a/omx/gstomx.h b/omx/gstomx.h index 7d5fa04..063437d 100644 --- a/omx/gstomx.h +++ b/omx/gstomx.h @@ -30,6 +30,12 @@ GST_DEBUG_CATEGORY_EXTERN (gstomx_debug); GST_DEBUG_CATEGORY_EXTERN (gstomx_util_debug); #define GST_CAT_DEFAULT gstomx_debug +gboolean g_omx_get_component_info (gpointer object, + gchar **library_name, + gchar **component_name); +gboolean g_omx_get_library_name_value (gpointer object, GValue *val); +gboolean g_omx_get_component_name_value (gpointer object, GValue *val); + G_END_DECLS #endif /* GSTOMX_H */ diff --git a/omx/gstomx_base_filter.c b/omx/gstomx_base_filter.c index b0353cb..2a30502 100644 --- a/omx/gstomx_base_filter.c +++ b/omx/gstomx_base_filter.c @@ -115,7 +115,7 @@ change_state (GstElement *element, switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: - g_omx_core_init (core, self->omx_library, self->omx_component); + g_omx_core_init (core); if (core->omx_state != OMX_StateLoaded) { ret = GST_STATE_CHANGE_FAILURE; @@ -184,9 +184,6 @@ finalize (GObject *obj) g_omx_core_free (self->gomx); - g_free (self->omx_component); - g_free (self->omx_library); - g_mutex_free (self->ready_lock); G_OBJECT_CLASS (parent_class)->finalize (obj); @@ -204,14 +201,6 @@ set_property (GObject *obj, switch (prop_id) { - case ARG_COMPONENT_NAME: - g_free (self->omx_component); - self->omx_component = g_value_dup_string (value); - break; - case ARG_LIBRARY_NAME: - g_free (self->omx_library); - self->omx_library = g_value_dup_string (value); - break; case ARG_USE_TIMESTAMPS: self->use_timestamps = g_value_get_boolean (value); break; @@ -234,10 +223,10 @@ get_property (GObject *obj, switch (prop_id) { case ARG_COMPONENT_NAME: - g_value_set_string (value, self->omx_component); + g_omx_get_component_name_value (self, value); break; case ARG_LIBRARY_NAME: - g_value_set_string (value, self->omx_library); + g_omx_get_library_name_value (self, value); break; case ARG_USE_TIMESTAMPS: g_value_set_boolean (value, self->use_timestamps); @@ -271,12 +260,12 @@ type_class_init (gpointer g_class, g_object_class_install_property (gobject_class, ARG_COMPONENT_NAME, g_param_spec_string ("component-name", "Component name", "Name of the OpenMAX IL component to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); g_object_class_install_property (gobject_class, ARG_LIBRARY_NAME, g_param_spec_string ("library-name", "Library name", "Name of the OpenMAX IL implementation library to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); g_object_class_install_property (gobject_class, ARG_USE_TIMESTAMPS, g_param_spec_boolean ("use-timestamps", "Use timestamps", @@ -922,16 +911,6 @@ type_instance_init (GTypeInstance *instance, gst_element_add_pad (GST_ELEMENT (self), self->sinkpad); gst_element_add_pad (GST_ELEMENT (self), self->srcpad); - { - const char *tmp; - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("library-name")); - self->omx_library = g_strdup (tmp); - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("component-name")); - self->omx_component = g_strdup (tmp); - } - GST_LOG_OBJECT (self, "end"); } diff --git a/omx/gstomx_base_filter.h b/omx/gstomx_base_filter.h index 4baf181..99b5d72 100644 --- a/omx/gstomx_base_filter.h +++ b/omx/gstomx_base_filter.h @@ -48,8 +48,6 @@ struct GstOmxBaseFilter GOmxPort *in_port; GOmxPort *out_port; - char *omx_component; - char *omx_library; gboolean use_timestamps; /** @todo remove; timestamps should always be used */ gboolean ready; GMutex *ready_lock; diff --git a/omx/gstomx_base_sink.c b/omx/gstomx_base_sink.c index c1a2076..7911167 100644 --- a/omx/gstomx_base_sink.c +++ b/omx/gstomx_base_sink.c @@ -141,9 +141,6 @@ finalize (GObject *obj) g_omx_core_free (self->gomx); - g_free (self->omx_component); - g_free (self->omx_library); - G_OBJECT_CLASS (parent_class)->finalize (obj); } @@ -298,14 +295,6 @@ set_property (GObject *obj, switch (prop_id) { - case ARG_COMPONENT_NAME: - g_free (self->omx_component); - self->omx_component = g_value_dup_string (value); - break; - case ARG_LIBRARY_NAME: - g_free (self->omx_library); - self->omx_library = g_value_dup_string (value); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); break; @@ -325,10 +314,10 @@ get_property (GObject *obj, switch (prop_id) { case ARG_COMPONENT_NAME: - g_value_set_string (value, self->omx_component); + g_omx_get_component_name_value (self, value); break; case ARG_LIBRARY_NAME: - g_value_set_string (value, self->omx_library); + g_omx_get_library_name_value (self, value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); @@ -366,12 +355,12 @@ type_class_init (gpointer g_class, g_object_class_install_property (gobject_class, ARG_COMPONENT_NAME, g_param_spec_string ("component-name", "Component name", "Name of the OpenMAX IL component to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); g_object_class_install_property (gobject_class, ARG_LIBRARY_NAME, g_param_spec_string ("library-name", "Library name", "Name of the OpenMAX IL implementation library to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); } } @@ -420,7 +409,7 @@ activate_push (GstPad *pad, static inline gboolean omx_init (GstOmxBaseSink *self) { - g_omx_core_init (self->gomx, self->omx_library, self->omx_component); + g_omx_core_init (self->gomx); if (self->gomx->omx_error) return FALSE; @@ -468,16 +457,6 @@ type_instance_init (GTypeInstance *instance, } { - const char *tmp; - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("library-name")); - self->omx_library = g_strdup (tmp); - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("component-name")); - self->omx_component = g_strdup (tmp); - } - - { GstPad *sinkpad; self->sinkpad = sinkpad = GST_BASE_SINK_PAD (self); self->base_activatepush = GST_PAD_ACTIVATEPUSHFUNC (sinkpad); diff --git a/omx/gstomx_base_sink.h b/omx/gstomx_base_sink.h index 681e939..589c441 100644 --- a/omx/gstomx_base_sink.h +++ b/omx/gstomx_base_sink.h @@ -46,9 +46,6 @@ struct GstOmxBaseSink GOmxCore *gomx; GOmxPort *in_port; - char *omx_component; - char *omx_library; - gboolean ready; GstPadActivateModeFunction base_activatepush; gboolean initialized; diff --git a/omx/gstomx_base_src.c b/omx/gstomx_base_src.c index 9b02b22..dd9767e 100644 --- a/omx/gstomx_base_src.c +++ b/omx/gstomx_base_src.c @@ -67,7 +67,7 @@ start (GstBaseSrc *gst_base) GST_LOG_OBJECT (self, "begin"); - g_omx_core_init (self->gomx, self->omx_library, self->omx_component); + g_omx_core_init (self->gomx); if (self->gomx->omx_error) return GST_STATE_CHANGE_FAILURE; @@ -106,9 +106,6 @@ finalize (GObject *obj) g_omx_core_free (self->gomx); - g_free (self->omx_component); - g_free (self->omx_library); - G_OBJECT_CLASS (parent_class)->finalize (obj); } @@ -362,20 +359,6 @@ set_property (GObject *obj, switch (prop_id) { - case ARG_COMPONENT_NAME: - if (self->omx_component) - { - g_free (self->omx_component); - } - self->omx_component = g_value_dup_string (value); - break; - case ARG_LIBRARY_NAME: - if (self->omx_library) - { - g_free (self->omx_library); - } - self->omx_library = g_value_dup_string (value); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); break; @@ -395,10 +378,10 @@ get_property (GObject *obj, switch (prop_id) { case ARG_COMPONENT_NAME: - g_value_set_string (value, self->omx_component); + g_omx_get_component_name_value (self, value); break; case ARG_LIBRARY_NAME: - g_value_set_string (value, self->omx_library); + g_omx_get_library_name_value (self, value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); @@ -433,12 +416,12 @@ type_class_init (gpointer g_class, g_object_class_install_property (gobject_class, ARG_COMPONENT_NAME, g_param_spec_string ("component-name", "Component name", "Name of the OpenMAX IL component to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); g_object_class_install_property (gobject_class, ARG_LIBRARY_NAME, g_param_spec_string ("library-name", "Library name", "Name of the OpenMAX IL implementation library to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); } } @@ -459,17 +442,6 @@ type_instance_init (GTypeInstance *instance, gomx->object = self; } - { - const char *tmp; - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("library-name")); - self->omx_library = g_strdup (tmp); - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("component-name")); - self->omx_component = g_strdup (tmp); - } - - GST_LOG_OBJECT (self, "end"); } diff --git a/omx/gstomx_base_src.h b/omx/gstomx_base_src.h index 85e4c13..adab894 100644 --- a/omx/gstomx_base_src.h +++ b/omx/gstomx_base_src.h @@ -44,8 +44,6 @@ struct GstOmxBaseSrc GOmxCore *gomx; GOmxPort *out_port; - char *omx_component; - char *omx_library; GstOmxBaseSrcCb setup_ports; }; diff --git a/omx/gstomx_conf.c b/omx/gstomx_conf.c new file mode 100644 index 0000000..d25c173 --- /dev/null +++ b/omx/gstomx_conf.c @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2010 Texas Instruments, Incorporated + * Copyright (C) 2007-2010 Nokia Corporation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include <glib.h> + +#include "config.h" + +const gchar * default_config = +"\n" +"omx_dummy,\n" +" type=GstOmxDummy,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.dummy,\n" +" rank=0;\n" +"\n" +/* for testing: */ +"omx_dummy_2,\n" +" type=GstOmxDummy,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.dummy2,\n" +" rank=256;\n" +"\n" +"omx_mpeg4dec,\n" +" type=GstOmxMpeg4Dec,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.video_decoder.mpeg4,\n" +" rank=256;\n" +"\n" +"omx_h264dec,\n" +" type=GstOmxH264Dec,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.video_decoder.avc,\n" +" rank=256;\n" +"\n" +"omx_h263dec,\n" +" type=GstOmxH263Dec,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.video_decoder.h263,\n" +" rank=256;\n" +"\n" +"omx_wmvdec,\n" +" type=GstOmxWmvDec,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.video_decoder.wmv,\n" +" rank=256;\n" +"\n" +"omx_mpeg4enc,\n" +" type=GstOmxMpeg4Enc,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.video_encoder.mpeg4,\n" +" rank=256;\n" +"\n" +"omx_h264enc,\n" +" type=GstOmxH264Enc,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.video_encoder.avc,\n" +" rank=256;\n" +"\n" +"omx_h263enc,\n" +" type=GstOmxH263Enc,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.video_encoder.h263,\n" +" rank=256;\n" +"\n" +"omx_vorbisdec,\n" +" type=GstOmxVorbisDec,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_decoder.ogg.single,\n" +" rank=128;\n" +"\n" +"omx_mp3dec,\n" +" type=GstOmxMp3Dec,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_decoder.mp3.mad,\n" +" rank=256;\n" +"\n" +#ifdef EXPERIMENTAL +"omx_mp2dec,\n" +" type=GstOmxMp2Dec,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_decoder.mp3.mad,\n" +" rank=256;\n" +"\n" +"omx_amrnbdec,\n" +" type=GstOmxAmrNbDec,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_decoder.amrnb,\n" +" rank=256;\n" +"\n" +"omx_amrnbenc,\n" +" type=GstOmxAmrNbEnc,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_encoder.amrnb,\n" +" rank=256;\n" +"\n" +"omx_amrwbdec,\n" +" type=GstOmxAmrWbDec,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_decoder.amrwb,\n" +" rank=256;\n" +"\n" +"omx_amrwbenc,\n" +" type=GstOmxAmrWbEnc,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_encoder.amrwb,\n" +" rank=256;\n" +"\n" +"omx_aacdec,\n" +" type=GstOmxAacDec,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_decoder.aac,\n" +" rank=256;\n" +"\n" +"omx_aacenc,\n" +" type=GstOmxAacEnc,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_encoder.aac,\n" +" rank=256;\n" +"\n" +"omx_adpcmdec,\n" +" type=GstOmxAdpcmDec,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_decoder.adpcm,\n" +" rank=256;\n" +"\n" +"omx_adpcmenc,\n" +" type=GstOmxAdpcmEnc,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_encoder.adpcm,\n" +" rank=256;\n" +"\n" +"omx_g711dec,\n" +" type=GstOmxG711Dec,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_decoder.g711,\n" +" rank=256;\n" +"\n" +"omx_g711enc,\n" +" type=GstOmxG711Enc,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_encoder.g711,\n" +" rank=256;\n" +"\n" +"omx_g729dec,\n" +" type=GstOmxG729Dec,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_decoder.g729,\n" +" rank=256;\n" +"\n" +"omx_g729enc,\n" +" type=GstOmxG729Enc,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_encoder.g729,\n" +" rank=256;\n" +"\n" +"omx_ilbcdec,\n" +" type=GstOmxIlbcDec,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_decoder.ilbc,\n" +" rank=256;\n" +"\n" +"omx_ilbcenc,\n" +" type=GstOmxIlbcEnc,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_encoder.ilbc,\n" +" rank=256;\n" +"\n" +"omx_jpegenc,\n" +" type=GstOmxJpegEnc,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.image_encoder.jpeg,\n" +" rank=256;\n" +"\n" +#endif /* EXPERIMENTAL */ +"omx_audiosink,\n" +" type=GstOmxAudioSink,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.alsa.alsasink,\n" +" rank=0;\n" +"\n" +#ifdef EXPERIMENTAL +"omx_videosink,\n" +" type=GstOmxVideoSink,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.videosink,\n" +" rank=0;\n" +"\n" +"omx_filereadersrc,\n" +" type=GstOmxFilereaderSrc,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_filereader,\n" +" rank=0;\n" +"\n" +#endif /* EXPERIMENTAL */ +"omx_volume,\n" +" type=GstOmxVolume,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.volume.component,\n" +" rank=0;\n" +; diff --git a/omx/gstomx_util.c b/omx/gstomx_util.c index 39d900b..c429738 100644 --- a/omx/gstomx_util.c +++ b/omx/gstomx_util.c @@ -301,10 +301,13 @@ g_omx_core_free (GOmxCore *core) } void -g_omx_core_init (GOmxCore *core, - const gchar *library_name, - const gchar *component_name) +g_omx_core_init (GOmxCore *core) { + gchar *library_name, *component_name; + + g_assert (g_omx_get_component_info (core->object, + &library_name, &component_name)); + core->imp = request_imp (library_name); if (!core->imp) diff --git a/omx/gstomx_util.h b/omx/gstomx_util.h index f0cf045..c3ac441 100644 --- a/omx/gstomx_util.h +++ b/omx/gstomx_util.h @@ -116,7 +116,7 @@ void g_omx_deinit (void); GOmxCore *g_omx_core_new (void); void g_omx_core_free (GOmxCore *core); -void g_omx_core_init (GOmxCore *core, const gchar *library_name, const gchar *component_name); +void g_omx_core_init (GOmxCore *core); void g_omx_core_deinit (GOmxCore *core); void g_omx_core_prepare (GOmxCore *core); void g_omx_core_start (GOmxCore *core); -- 1.6.3.2 |
From: Stefan K. <en...@ho...> - 2010-02-26 20:38:24
|
hi rob, thanks for the new patch. Am 26.02.2010 20:31, schrieb Rob Clark: > 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. For example: > > ---- > omx_mp3dec_ti, > type=GstOmxMp3Dec, > library-name=libOMX_Core.so.0, > component-name=OMX.TI.AUDIO.DECODE, > component-role=audio_decode.dsp.mp3, > rank=256; > > omx_mp3dec_nokia, > type=GstOmxMp3Dec, > library-name=libomxil_bellagio.so.0, > component-name=OMX.nokia.audio_decode.mp3, > rank=128; > ---- > > by default, the config file is stored in $HOME/.gstreamer-0.10/gst-openmax.conf, although if none is found a default config will be created. > --- Minor nitpick - this is not true anymore. > omx/Makefile.am | 3 +- > omx/gstomx.c | 348 ++++++++++++++++++++++++++++++++++++++-------- > omx/gstomx.h | 6 + > omx/gstomx_base_filter.c | 31 +---- > omx/gstomx_base_filter.h | 2 - > omx/gstomx_base_sink.c | 31 +---- > omx/gstomx_base_sink.h | 3 - > omx/gstomx_base_src.c | 38 +----- > omx/gstomx_base_src.h | 2 - > omx/gstomx_conf.c | 217 +++++++++++++++++++++++++++++ > omx/gstomx_util.c | 9 +- > omx/gstomx_util.h | 2 +- > 12 files changed, 534 insertions(+), 158 deletions(-) > create mode 100644 omx/gstomx_conf.c > > diff --git a/omx/Makefile.am b/omx/Makefile.am > index 4a3fbf9..6ea9cf5 100644 > --- a/omx/Makefile.am > +++ b/omx/Makefile.am > @@ -18,7 +18,8 @@ libgstomx_la_SOURCES = gstomx.c gstomx.h \ > gstomx_vorbisdec.c gstomx_vorbisdec.h \ > gstomx_mp3dec.c gstomx_mp3dec.h \ > gstomx_base_sink.c gstomx_base_sink.h \ > - gstomx_audiosink.c gstomx_audiosink.h > + gstomx_audiosink.c gstomx_audiosink.h \ > + gstomx_conf.c > > if EXPERIMENTAL > libgstomx_la_SOURCES += gstomx_amrnbdec.c gstomx_amrnbdec.h \ > diff --git a/omx/gstomx.c b/omx/gstomx.c > index 6756f54..6a53eda 100644 > --- a/omx/gstomx.c > +++ b/omx/gstomx.c > @@ -19,8 +19,12 @@ > * > */ > > +#include <string.h> > + > #include "config.h" please keep "config.h" first. > > +#include <gst/gststructure.h> > + > #include "gstomx.h" > #include "gstomx_dummy.h" > #include "gstomx_mpeg4dec.h" > @@ -59,90 +63,312 @@ > > 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; > + > +extern const gchar *default_config; > + > +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: 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_REGISTRY")); > + 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_file_set_contents (path, config, -1, NULL); > + } > + > + 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); > + } > + > + g_free (path); > + > + 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; > + > + g_assert (gst_structure_get (element_table, > + element_name, GST_TYPE_STRUCTURE, &element, NULL)); > + asserts can be disabled. gboolean have_field; have_field = gst_structure_get (element_table, element_name, GST_TYPE_STRUCTURE, &element, NULL); g_assert (have_field); > + return element; > +} > + > +static const gchar * > +get_element_name (gpointer object) > +{ > + return g_type_name (G_OBJECT_TYPE (object)); > +} => G_OBJECT_TYPE_NAME(obj); > + > +/* register a new dynamic sub-class with the omx element as it's 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 type, const gchar *element_name) > +{ > + GTypeQuery q; > + GTypeInfo i = {0}; > + > + g_type_query (type, &q); > + > + i.class_size = q.class_size; > + i.instance_size = q.instance_size; > + > + return g_type_register_static (type, element_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"); > + /* 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++) > + const gchar *element_name = gst_structure_nth_field_name (element_table, i); > + GstStructure *element = get_element_entry (element_name); > + const gchar *type_name; > + GType type; > + gint rank; > + > + GST_DEBUG ("element=%"GST_PTR_FORMAT, element); > + > + type_name = gst_structure_get_string (element, "type"); > + if (!type_name) > { > - TableItem *element; > - GType type; > - > - 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); > - > - if (!gst_element_register (plugin, element->name, element->rank, type)) > - { > - g_warning ("failed registering '%s'", element->name); > - return FALSE; > - } > + g_warning ("malformed config file: missing 'type' for %s", element_name); > + return FALSE; > + } > + > + 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; > + } > + > + type = create_subtype (type, 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; > } > > +/** > + * g_omx_get_component_info: > + * @object: the GstOmx object (ie. GstOmxBaseFilter, GstOmxBaseSrc, or > + * GstOmxBaseSink). > + * @library_name: library-name, returned by reference (or NULL) > + * @component_name: component-name, returned by reference (or NULL) > + * > + * Get library-name and component-name for an element. > + * > + * note: this function will gain another parameter later when component-role > + * is added > + */ > +gboolean > +g_omx_get_component_info (gpointer object, > + gchar **library_name, > + gchar **component_name) > +{ > + gboolean ret = TRUE; > + const gchar *element_name = get_element_name (object); > + GstStructure *element = get_element_entry (element_name); > + > + g_assert (gst_structure_get (element_table, > + element_name, GST_TYPE_STRUCTURE, &element, NULL)); > + see above and more below (not commented specificaly). > + /* initialize ptrs to NULL so that in error cases we can tell what needs > + * to be freed: > + */ > + if (library_name) *library_name = NULL; > + if (component_name) *component_name = NULL; > + > + if (library_name) > + { > + const gchar *str = gst_structure_get_string (element, "library-name"); > + if (!str) > + { > + g_warning ("malformed config file: missing 'library-name' for %s", element_name); > + ret = FALSE; > + goto exit; > + } > + *library_name = g_strdup (str); > + } > + > + if (component_name) > + { > + const gchar *str = gst_structure_get_string (element, "component-name"); > + if (!str) > + { > + g_warning ("malformed config file: missing 'component-name' for %s", element_name); > + ret = FALSE; > + goto exit; > + } > + *component_name = g_strdup (str); > + } > + > +exit: > + > + /* if we failed, free any memory that might have been allocated: > + */ > + if (!ret) > + { > + if (library_name) g_free (*library_name); > + if (component_name) g_free (*component_name); > + } > + > + > + return ret; > +} > + > +static gboolean > +set_value_helper (GValue *value, gchar *str) > +{ > + g_value_set_string (value, str); > + return TRUE; > +} > + > +/** > + * g_omx_get_library_name_value: > + * @object: the GstOmx object (ie. GstOmxBaseFilter, GstOmxBaseSrc, or > + * GstOmxBaseSink). > + * @val: the GValue to return the value through > + * > + * A helper to access the "library-name" as a GValue, mainly for > + * get_property methods. > + */ > +gboolean > +g_omx_get_library_name_value (gpointer object, GValue *val) > +{ > + gchar *str; > + return g_omx_get_component_info (object, &str, NULL) && > + set_value_helper (val, str); > +} > + > +/** > + * g_omx_get_component_name_value: > + * @object: the GstOmx object (ie. GstOmxBaseFilter, GstOmxBaseSrc, or > + * GstOmxBaseSink). > + * @val: the GValue to return the value through > + * > + * A helper to access the "component-name" as a GValue, mainly for > + * get_property methods. > + */ > +gboolean > +g_omx_get_component_name_value (gpointer object, GValue *val) > +{ > + gchar *str; > + return g_omx_get_component_info (object, NULL, &str) && > + set_value_helper (val, str); > +} > + > GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, > GST_VERSION_MINOR, > "omx", > diff --git a/omx/gstomx.h b/omx/gstomx.h > index 7d5fa04..063437d 100644 > --- a/omx/gstomx.h > +++ b/omx/gstomx.h > @@ -30,6 +30,12 @@ GST_DEBUG_CATEGORY_EXTERN (gstomx_debug); > GST_DEBUG_CATEGORY_EXTERN (gstomx_util_debug); > #define GST_CAT_DEFAULT gstomx_debug > > +gboolean g_omx_get_component_info (gpointer object, > + gchar **library_name, > + gchar **component_name); > +gboolean g_omx_get_library_name_value (gpointer object, GValue *val); > +gboolean g_omx_get_component_name_value (gpointer object, GValue *val); > + > G_END_DECLS > > #endif /* GSTOMX_H */ > diff --git a/omx/gstomx_base_filter.c b/omx/gstomx_base_filter.c > index b0353cb..2a30502 100644 > --- a/omx/gstomx_base_filter.c > +++ b/omx/gstomx_base_filter.c > @@ -115,7 +115,7 @@ change_state (GstElement *element, > switch (transition) > { > case GST_STATE_CHANGE_NULL_TO_READY: > - g_omx_core_init (core, self->omx_library, self->omx_component); > + g_omx_core_init (core); > if (core->omx_state != OMX_StateLoaded) > { > ret = GST_STATE_CHANGE_FAILURE; > @@ -184,9 +184,6 @@ finalize (GObject *obj) > > g_omx_core_free (self->gomx); > > - g_free (self->omx_component); > - g_free (self->omx_library); > - > g_mutex_free (self->ready_lock); > > G_OBJECT_CLASS (parent_class)->finalize (obj); > @@ -204,14 +201,6 @@ set_property (GObject *obj, > > switch (prop_id) > { > - case ARG_COMPONENT_NAME: > - g_free (self->omx_component); > - self->omx_component = g_value_dup_string (value); > - break; > - case ARG_LIBRARY_NAME: > - g_free (self->omx_library); > - self->omx_library = g_value_dup_string (value); > - break; > case ARG_USE_TIMESTAMPS: > self->use_timestamps = g_value_get_boolean (value); > break; > @@ -234,10 +223,10 @@ get_property (GObject *obj, > switch (prop_id) > { > case ARG_COMPONENT_NAME: > - g_value_set_string (value, self->omx_component); > + g_omx_get_component_name_value (self, value); > break; > case ARG_LIBRARY_NAME: > - g_value_set_string (value, self->omx_library); > + g_omx_get_library_name_value (self, value); > break; > case ARG_USE_TIMESTAMPS: > g_value_set_boolean (value, self->use_timestamps); > @@ -271,12 +260,12 @@ type_class_init (gpointer g_class, > g_object_class_install_property (gobject_class, ARG_COMPONENT_NAME, > g_param_spec_string ("component-name", "Component name", > "Name of the OpenMAX IL component to use", > - NULL, G_PARAM_READWRITE)); > + NULL, G_PARAM_READABLE)); > > g_object_class_install_property (gobject_class, ARG_LIBRARY_NAME, > g_param_spec_string ("library-name", "Library name", > "Name of the OpenMAX IL implementation library to use", > - NULL, G_PARAM_READWRITE)); > + NULL, G_PARAM_READABLE)); > > g_object_class_install_property (gobject_class, ARG_USE_TIMESTAMPS, > g_param_spec_boolean ("use-timestamps", "Use timestamps", > @@ -922,16 +911,6 @@ type_instance_init (GTypeInstance *instance, > gst_element_add_pad (GST_ELEMENT (self), self->sinkpad); > gst_element_add_pad (GST_ELEMENT (self), self->srcpad); > > - { > - const char *tmp; > - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), > - g_quark_from_static_string ("library-name")); > - self->omx_library = g_strdup (tmp); > - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), > - g_quark_from_static_string ("component-name")); > - self->omx_component = g_strdup (tmp); > - } > - > GST_LOG_OBJECT (self, "end"); > } > > diff --git a/omx/gstomx_base_filter.h b/omx/gstomx_base_filter.h > index 4baf181..99b5d72 100644 > --- a/omx/gstomx_base_filter.h > +++ b/omx/gstomx_base_filter.h > @@ -48,8 +48,6 @@ struct GstOmxBaseFilter > GOmxPort *in_port; > GOmxPort *out_port; > > - char *omx_component; > - char *omx_library; > gboolean use_timestamps; /** @todo remove; timestamps should always be used */ > gboolean ready; > GMutex *ready_lock; > diff --git a/omx/gstomx_base_sink.c b/omx/gstomx_base_sink.c > index c1a2076..7911167 100644 > --- a/omx/gstomx_base_sink.c > +++ b/omx/gstomx_base_sink.c > @@ -141,9 +141,6 @@ finalize (GObject *obj) > > g_omx_core_free (self->gomx); > > - g_free (self->omx_component); > - g_free (self->omx_library); > - > G_OBJECT_CLASS (parent_class)->finalize (obj); > } > > @@ -298,14 +295,6 @@ set_property (GObject *obj, > > switch (prop_id) > { > - case ARG_COMPONENT_NAME: > - g_free (self->omx_component); > - self->omx_component = g_value_dup_string (value); > - break; > - case ARG_LIBRARY_NAME: > - g_free (self->omx_library); > - self->omx_library = g_value_dup_string (value); > - break; > default: > G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); > break; > @@ -325,10 +314,10 @@ get_property (GObject *obj, > switch (prop_id) > { > case ARG_COMPONENT_NAME: > - g_value_set_string (value, self->omx_component); > + g_omx_get_component_name_value (self, value); > break; > case ARG_LIBRARY_NAME: > - g_value_set_string (value, self->omx_library); > + g_omx_get_library_name_value (self, value); > break; > default: > G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); > @@ -366,12 +355,12 @@ type_class_init (gpointer g_class, > g_object_class_install_property (gobject_class, ARG_COMPONENT_NAME, > g_param_spec_string ("component-name", "Component name", > "Name of the OpenMAX IL component to use", > - NULL, G_PARAM_READWRITE)); > + NULL, G_PARAM_READABLE)); > > g_object_class_install_property (gobject_class, ARG_LIBRARY_NAME, > g_param_spec_string ("library-name", "Library name", > "Name of the OpenMAX IL implementation library to use", > - NULL, G_PARAM_READWRITE)); > + NULL, G_PARAM_READABLE)); > } > } > > @@ -420,7 +409,7 @@ activate_push (GstPad *pad, > static inline gboolean > omx_init (GstOmxBaseSink *self) > { > - g_omx_core_init (self->gomx, self->omx_library, self->omx_component); > + g_omx_core_init (self->gomx); > > if (self->gomx->omx_error) > return FALSE; > @@ -468,16 +457,6 @@ type_instance_init (GTypeInstance *instance, > } > > { > - const char *tmp; > - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), > - g_quark_from_static_string ("library-name")); > - self->omx_library = g_strdup (tmp); > - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), > - g_quark_from_static_string ("component-name")); > - self->omx_component = g_strdup (tmp); > - } > - > - { > GstPad *sinkpad; > self->sinkpad = sinkpad = GST_BASE_SINK_PAD (self); > self->base_activatepush = GST_PAD_ACTIVATEPUSHFUNC (sinkpad); > diff --git a/omx/gstomx_base_sink.h b/omx/gstomx_base_sink.h > index 681e939..589c441 100644 > --- a/omx/gstomx_base_sink.h > +++ b/omx/gstomx_base_sink.h > @@ -46,9 +46,6 @@ struct GstOmxBaseSink > GOmxCore *gomx; > GOmxPort *in_port; > > - char *omx_component; > - char *omx_library; > - > gboolean ready; > GstPadActivateModeFunction base_activatepush; > gboolean initialized; > diff --git a/omx/gstomx_base_src.c b/omx/gstomx_base_src.c > index 9b02b22..dd9767e 100644 > --- a/omx/gstomx_base_src.c > +++ b/omx/gstomx_base_src.c > @@ -67,7 +67,7 @@ start (GstBaseSrc *gst_base) > > GST_LOG_OBJECT (self, "begin"); > > - g_omx_core_init (self->gomx, self->omx_library, self->omx_component); > + g_omx_core_init (self->gomx); > if (self->gomx->omx_error) > return GST_STATE_CHANGE_FAILURE; > > @@ -106,9 +106,6 @@ finalize (GObject *obj) > > g_omx_core_free (self->gomx); > > - g_free (self->omx_component); > - g_free (self->omx_library); > - > G_OBJECT_CLASS (parent_class)->finalize (obj); > } > > @@ -362,20 +359,6 @@ set_property (GObject *obj, > > switch (prop_id) > { > - case ARG_COMPONENT_NAME: > - if (self->omx_component) > - { > - g_free (self->omx_component); > - } > - self->omx_component = g_value_dup_string (value); > - break; > - case ARG_LIBRARY_NAME: > - if (self->omx_library) > - { > - g_free (self->omx_library); > - } > - self->omx_library = g_value_dup_string (value); > - break; > default: > G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); > break; > @@ -395,10 +378,10 @@ get_property (GObject *obj, > switch (prop_id) > { > case ARG_COMPONENT_NAME: > - g_value_set_string (value, self->omx_component); > + g_omx_get_component_name_value (self, value); > break; > case ARG_LIBRARY_NAME: > - g_value_set_string (value, self->omx_library); > + g_omx_get_library_name_value (self, value); > break; > default: > G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); > @@ -433,12 +416,12 @@ type_class_init (gpointer g_class, > g_object_class_install_property (gobject_class, ARG_COMPONENT_NAME, > g_param_spec_string ("component-name", "Component name", > "Name of the OpenMAX IL component to use", > - NULL, G_PARAM_READWRITE)); > + NULL, G_PARAM_READABLE)); > > g_object_class_install_property (gobject_class, ARG_LIBRARY_NAME, > g_param_spec_string ("library-name", "Library name", > "Name of the OpenMAX IL implementation library to use", > - NULL, G_PARAM_READWRITE)); > + NULL, G_PARAM_READABLE)); > } > } > > @@ -459,17 +442,6 @@ type_instance_init (GTypeInstance *instance, > gomx->object = self; > } > > - { > - const char *tmp; > - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), > - g_quark_from_static_string ("library-name")); > - self->omx_library = g_strdup (tmp); > - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), > - g_quark_from_static_string ("component-name")); > - self->omx_component = g_strdup (tmp); > - } > - > - > GST_LOG_OBJECT (self, "end"); > } > > diff --git a/omx/gstomx_base_src.h b/omx/gstomx_base_src.h > index 85e4c13..adab894 100644 > --- a/omx/gstomx_base_src.h > +++ b/omx/gstomx_base_src.h > @@ -44,8 +44,6 @@ struct GstOmxBaseSrc > GOmxCore *gomx; > GOmxPort *out_port; > > - char *omx_component; > - char *omx_library; > GstOmxBaseSrcCb setup_ports; > }; > > diff --git a/omx/gstomx_conf.c b/omx/gstomx_conf.c > new file mode 100644 > index 0000000..d25c173 > --- /dev/null > +++ b/omx/gstomx_conf.c > @@ -0,0 +1,217 @@ > +/* > + * Copyright (C) 2010 Texas Instruments, Incorporated > + * Copyright (C) 2007-2010 Nokia Corporation. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + * > + */ > + > +#include <glib.h> > + > +#include "config.h" > + > +const gchar * default_config = > +"\n" > +"omx_dummy,\n" > +" type=GstOmxDummy,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.dummy,\n" > +" rank=0;\n" > +"\n" > +/* for testing: */ > +"omx_dummy_2,\n" > +" type=GstOmxDummy,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.dummy2,\n" > +" rank=256;\n" > +"\n" > +"omx_mpeg4dec,\n" > +" type=GstOmxMpeg4Dec,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.video_decoder.mpeg4,\n" > +" rank=256;\n" > +"\n" > +"omx_h264dec,\n" > +" type=GstOmxH264Dec,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.video_decoder.avc,\n" > +" rank=256;\n" > +"\n" > +"omx_h263dec,\n" > +" type=GstOmxH263Dec,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.video_decoder.h263,\n" > +" rank=256;\n" > +"\n" > +"omx_wmvdec,\n" > +" type=GstOmxWmvDec,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.video_decoder.wmv,\n" > +" rank=256;\n" > +"\n" > +"omx_mpeg4enc,\n" > +" type=GstOmxMpeg4Enc,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.video_encoder.mpeg4,\n" > +" rank=256;\n" > +"\n" > +"omx_h264enc,\n" > +" type=GstOmxH264Enc,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.video_encoder.avc,\n" > +" rank=256;\n" > +"\n" > +"omx_h263enc,\n" > +" type=GstOmxH263Enc,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.video_encoder.h263,\n" > +" rank=256;\n" > +"\n" > +"omx_vorbisdec,\n" > +" type=GstOmxVorbisDec,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.audio_decoder.ogg.single,\n" > +" rank=128;\n" > +"\n" > +"omx_mp3dec,\n" > +" type=GstOmxMp3Dec,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.audio_decoder.mp3.mad,\n" > +" rank=256;\n" > +"\n" > +#ifdef EXPERIMENTAL > +"omx_mp2dec,\n" > +" type=GstOmxMp2Dec,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.audio_decoder.mp3.mad,\n" > +" rank=256;\n" > +"\n" > +"omx_amrnbdec,\n" > +" type=GstOmxAmrNbDec,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.audio_decoder.amrnb,\n" > +" rank=256;\n" > +"\n" > +"omx_amrnbenc,\n" > +" type=GstOmxAmrNbEnc,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.audio_encoder.amrnb,\n" > +" rank=256;\n" > +"\n" > +"omx_amrwbdec,\n" > +" type=GstOmxAmrWbDec,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.audio_decoder.amrwb,\n" > +" rank=256;\n" > +"\n" > +"omx_amrwbenc,\n" > +" type=GstOmxAmrWbEnc,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.audio_encoder.amrwb,\n" > +" rank=256;\n" > +"\n" > +"omx_aacdec,\n" > +" type=GstOmxAacDec,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.audio_decoder.aac,\n" > +" rank=256;\n" > +"\n" > +"omx_aacenc,\n" > +" type=GstOmxAacEnc,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.audio_encoder.aac,\n" > +" rank=256;\n" > +"\n" > +"omx_adpcmdec,\n" > +" type=GstOmxAdpcmDec,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.audio_decoder.adpcm,\n" > +" rank=256;\n" > +"\n" > +"omx_adpcmenc,\n" > +" type=GstOmxAdpcmEnc,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.audio_encoder.adpcm,\n" > +" rank=256;\n" > +"\n" > +"omx_g711dec,\n" > +" type=GstOmxG711Dec,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.audio_decoder.g711,\n" > +" rank=256;\n" > +"\n" > +"omx_g711enc,\n" > +" type=GstOmxG711Enc,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.audio_encoder.g711,\n" > +" rank=256;\n" > +"\n" > +"omx_g729dec,\n" > +" type=GstOmxG729Dec,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.audio_decoder.g729,\n" > +" rank=256;\n" > +"\n" > +"omx_g729enc,\n" > +" type=GstOmxG729Enc,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.audio_encoder.g729,\n" > +" rank=256;\n" > +"\n" > +"omx_ilbcdec,\n" > +" type=GstOmxIlbcDec,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.audio_decoder.ilbc,\n" > +" rank=256;\n" > +"\n" > +"omx_ilbcenc,\n" > +" type=GstOmxIlbcEnc,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.audio_encoder.ilbc,\n" > +" rank=256;\n" > +"\n" > +"omx_jpegenc,\n" > +" type=GstOmxJpegEnc,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.image_encoder.jpeg,\n" > +" rank=256;\n" > +"\n" > +#endif /* EXPERIMENTAL */ > +"omx_audiosink,\n" > +" type=GstOmxAudioSink,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.alsa.alsasink,\n" > +" rank=0;\n" > +"\n" > +#ifdef EXPERIMENTAL > +"omx_videosink,\n" > +" type=GstOmxVideoSink,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.videosink,\n" > +" rank=0;\n" > +"\n" > +"omx_filereadersrc,\n" > +" type=GstOmxFilereaderSrc,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.audio_filereader,\n" > +" rank=0;\n" > +"\n" > +#endif /* EXPERIMENTAL */ > +"omx_volume,\n" > +" type=GstOmxVolume,\n" > +" library-name=libomxil-bellagio.so.0,\n" > +" component-name=OMX.st.volume.component,\n" > +" rank=0;\n" > +; > diff --git a/omx/gstomx_util.c b/omx/gstomx_util.c > index 39d900b..c429738 100644 > --- a/omx/gstomx_util.c > +++ b/omx/gstomx_util.c > @@ -301,10 +301,13 @@ g_omx_core_free (GOmxCore *core) > } > > void > -g_omx_core_init (GOmxCore *core, > - const gchar *library_name, > - const gchar *component_name) > +g_omx_core_init (GOmxCore *core) > { > + gchar *library_name, *component_name; > + > + g_assert (g_omx_get_component_info (core->object, > + &library_name, &component_name)); > + > core->imp = request_imp (library_name); > > if (!core->imp) > diff --git a/omx/gstomx_util.h b/omx/gstomx_util.h > index f0cf045..c3ac441 100644 > --- a/omx/gstomx_util.h > +++ b/omx/gstomx_util.h > @@ -116,7 +116,7 @@ void g_omx_deinit (void); > > GOmxCore *g_omx_core_new (void); > void g_omx_core_free (GOmxCore *core); > -void g_omx_core_init (GOmxCore *core, const gchar *library_name, const gchar *component_name); > +void g_omx_core_init (GOmxCore *core); > void g_omx_core_deinit (GOmxCore *core); > void g_omx_core_prepare (GOmxCore *core); > void g_omx_core_start (GOmxCore *core); |
From: Rob C. <ro...@ti...> - 2010-02-26 21:44:19
|
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. For example: ---- omx_mp3dec_ti, type=GstOmxMp3Dec, library-name=libOMX_Core.so.0, component-name=OMX.TI.AUDIO.DECODE, component-role=audio_decode.dsp.mp3, rank=256; omx_mp3dec_nokia, type=GstOmxMp3Dec, 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. --- omx/Makefile.am | 3 +- omx/gstomx.c | 351 ++++++++++++++++++++++++++++++++++++++-------- omx/gstomx.h | 6 + omx/gstomx_base_filter.c | 31 +---- omx/gstomx_base_filter.h | 2 - omx/gstomx_base_sink.c | 31 +---- omx/gstomx_base_sink.h | 3 - omx/gstomx_base_src.c | 38 +----- omx/gstomx_base_src.h | 2 - omx/gstomx_conf.c | 217 ++++++++++++++++++++++++++++ omx/gstomx_util.c | 9 +- omx/gstomx_util.h | 2 +- 12 files changed, 537 insertions(+), 158 deletions(-) create mode 100644 omx/gstomx_conf.c diff --git a/omx/Makefile.am b/omx/Makefile.am index 4a3fbf9..6ea9cf5 100644 --- a/omx/Makefile.am +++ b/omx/Makefile.am @@ -18,7 +18,8 @@ libgstomx_la_SOURCES = gstomx.c gstomx.h \ gstomx_vorbisdec.c gstomx_vorbisdec.h \ gstomx_mp3dec.c gstomx_mp3dec.h \ gstomx_base_sink.c gstomx_base_sink.h \ - gstomx_audiosink.c gstomx_audiosink.h + gstomx_audiosink.c gstomx_audiosink.h \ + gstomx_conf.c if EXPERIMENTAL libgstomx_la_SOURCES += gstomx_amrnbdec.c gstomx_amrnbdec.h \ diff --git a/omx/gstomx.c b/omx/gstomx.c index 6756f54..f882f64 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,90 +63,315 @@ 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; + +extern const gchar *default_config; + +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: 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_REGISTRY")); + 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_file_set_contents (path, config, -1, NULL); + } + + 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); + } + + g_free (path); + + 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; + + g_assert (element); + + return element; +} + +static const gchar * +get_element_name (gpointer object) +{ + return G_OBJECT_TYPE_NAME (object); +} + +/* register a new dynamic sub-class with the omx element as it's 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 type, const gchar *element_name) +{ + GTypeQuery q; + GTypeInfo i = {0}; + + g_type_query (type, &q); + + i.class_size = q.class_size; + i.instance_size = q.instance_size; + + return g_type_register_static (type, element_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"); + /* 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++) + const gchar *element_name = gst_structure_nth_field_name (element_table, i); + GstStructure *element = get_element_entry (element_name); + const gchar *type_name; + GType type; + gint rank; + + GST_DEBUG ("element=%"GST_PTR_FORMAT, element); + + type_name = gst_structure_get_string (element, "type"); + if (!type_name) { - TableItem *element; - GType type; - - 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); - - if (!gst_element_register (plugin, element->name, element->rank, type)) - { - g_warning ("failed registering '%s'", element->name); - return FALSE; - } + g_warning ("malformed config file: missing 'type' for %s", element_name); + return FALSE; + } + + 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; + } + + type = create_subtype (type, 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; } +/** + * g_omx_get_component_info: + * @object: the GstOmx object (ie. GstOmxBaseFilter, GstOmxBaseSrc, or + * GstOmxBaseSink). + * @library_name: library-name, returned by reference (or NULL) + * @component_name: component-name, returned by reference (or NULL) + * + * Get library-name and component-name for an element. + * + * note: this function will gain another parameter later when component-role + * is added + */ +gboolean +g_omx_get_component_info (gpointer object, + gchar **library_name, + gchar **component_name) +{ + gboolean ret = TRUE; + const gchar *element_name = get_element_name (object); + GstStructure *element = get_element_entry (element_name); + + if (!element) + return FALSE; + + /* initialize ptrs to NULL so that in error cases we can tell what needs + * to be freed: + */ + if (library_name) *library_name = NULL; + if (component_name) *component_name = NULL; + + if (library_name) + { + const gchar *str = gst_structure_get_string (element, "library-name"); + if (!str) + { + g_warning ("malformed config file: missing 'library-name' for %s", element_name); + ret = FALSE; + goto exit; + } + *library_name = g_strdup (str); + } + + if (component_name) + { + const gchar *str = gst_structure_get_string (element, "component-name"); + if (!str) + { + g_warning ("malformed config file: missing 'component-name' for %s", element_name); + ret = FALSE; + goto exit; + } + *component_name = g_strdup (str); + } + +exit: + + /* if we failed, free any memory that might have been allocated: + */ + if (!ret) + { + if (library_name) g_free (*library_name); + if (component_name) g_free (*component_name); + } + + + return ret; +} + +static gboolean +set_value_helper (GValue *value, gchar *str) +{ + g_value_set_string (value, str); + return TRUE; +} + +/** + * g_omx_get_library_name_value: + * @object: the GstOmx object (ie. GstOmxBaseFilter, GstOmxBaseSrc, or + * GstOmxBaseSink). + * @val: the GValue to return the value through + * + * A helper to access the "library-name" as a GValue, mainly for + * get_property methods. + */ +gboolean +g_omx_get_library_name_value (gpointer object, GValue *val) +{ + gchar *str; + return g_omx_get_component_info (object, &str, NULL) && + set_value_helper (val, str); +} + +/** + * g_omx_get_component_name_value: + * @object: the GstOmx object (ie. GstOmxBaseFilter, GstOmxBaseSrc, or + * GstOmxBaseSink). + * @val: the GValue to return the value through + * + * A helper to access the "component-name" as a GValue, mainly for + * get_property methods. + */ +gboolean +g_omx_get_component_name_value (gpointer object, GValue *val) +{ + gchar *str; + return g_omx_get_component_info (object, NULL, &str) && + set_value_helper (val, str); +} + GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, "omx", diff --git a/omx/gstomx.h b/omx/gstomx.h index 7d5fa04..063437d 100644 --- a/omx/gstomx.h +++ b/omx/gstomx.h @@ -30,6 +30,12 @@ GST_DEBUG_CATEGORY_EXTERN (gstomx_debug); GST_DEBUG_CATEGORY_EXTERN (gstomx_util_debug); #define GST_CAT_DEFAULT gstomx_debug +gboolean g_omx_get_component_info (gpointer object, + gchar **library_name, + gchar **component_name); +gboolean g_omx_get_library_name_value (gpointer object, GValue *val); +gboolean g_omx_get_component_name_value (gpointer object, GValue *val); + G_END_DECLS #endif /* GSTOMX_H */ diff --git a/omx/gstomx_base_filter.c b/omx/gstomx_base_filter.c index b0353cb..2a30502 100644 --- a/omx/gstomx_base_filter.c +++ b/omx/gstomx_base_filter.c @@ -115,7 +115,7 @@ change_state (GstElement *element, switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: - g_omx_core_init (core, self->omx_library, self->omx_component); + g_omx_core_init (core); if (core->omx_state != OMX_StateLoaded) { ret = GST_STATE_CHANGE_FAILURE; @@ -184,9 +184,6 @@ finalize (GObject *obj) g_omx_core_free (self->gomx); - g_free (self->omx_component); - g_free (self->omx_library); - g_mutex_free (self->ready_lock); G_OBJECT_CLASS (parent_class)->finalize (obj); @@ -204,14 +201,6 @@ set_property (GObject *obj, switch (prop_id) { - case ARG_COMPONENT_NAME: - g_free (self->omx_component); - self->omx_component = g_value_dup_string (value); - break; - case ARG_LIBRARY_NAME: - g_free (self->omx_library); - self->omx_library = g_value_dup_string (value); - break; case ARG_USE_TIMESTAMPS: self->use_timestamps = g_value_get_boolean (value); break; @@ -234,10 +223,10 @@ get_property (GObject *obj, switch (prop_id) { case ARG_COMPONENT_NAME: - g_value_set_string (value, self->omx_component); + g_omx_get_component_name_value (self, value); break; case ARG_LIBRARY_NAME: - g_value_set_string (value, self->omx_library); + g_omx_get_library_name_value (self, value); break; case ARG_USE_TIMESTAMPS: g_value_set_boolean (value, self->use_timestamps); @@ -271,12 +260,12 @@ type_class_init (gpointer g_class, g_object_class_install_property (gobject_class, ARG_COMPONENT_NAME, g_param_spec_string ("component-name", "Component name", "Name of the OpenMAX IL component to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); g_object_class_install_property (gobject_class, ARG_LIBRARY_NAME, g_param_spec_string ("library-name", "Library name", "Name of the OpenMAX IL implementation library to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); g_object_class_install_property (gobject_class, ARG_USE_TIMESTAMPS, g_param_spec_boolean ("use-timestamps", "Use timestamps", @@ -922,16 +911,6 @@ type_instance_init (GTypeInstance *instance, gst_element_add_pad (GST_ELEMENT (self), self->sinkpad); gst_element_add_pad (GST_ELEMENT (self), self->srcpad); - { - const char *tmp; - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("library-name")); - self->omx_library = g_strdup (tmp); - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("component-name")); - self->omx_component = g_strdup (tmp); - } - GST_LOG_OBJECT (self, "end"); } diff --git a/omx/gstomx_base_filter.h b/omx/gstomx_base_filter.h index 4baf181..99b5d72 100644 --- a/omx/gstomx_base_filter.h +++ b/omx/gstomx_base_filter.h @@ -48,8 +48,6 @@ struct GstOmxBaseFilter GOmxPort *in_port; GOmxPort *out_port; - char *omx_component; - char *omx_library; gboolean use_timestamps; /** @todo remove; timestamps should always be used */ gboolean ready; GMutex *ready_lock; diff --git a/omx/gstomx_base_sink.c b/omx/gstomx_base_sink.c index c1a2076..7911167 100644 --- a/omx/gstomx_base_sink.c +++ b/omx/gstomx_base_sink.c @@ -141,9 +141,6 @@ finalize (GObject *obj) g_omx_core_free (self->gomx); - g_free (self->omx_component); - g_free (self->omx_library); - G_OBJECT_CLASS (parent_class)->finalize (obj); } @@ -298,14 +295,6 @@ set_property (GObject *obj, switch (prop_id) { - case ARG_COMPONENT_NAME: - g_free (self->omx_component); - self->omx_component = g_value_dup_string (value); - break; - case ARG_LIBRARY_NAME: - g_free (self->omx_library); - self->omx_library = g_value_dup_string (value); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); break; @@ -325,10 +314,10 @@ get_property (GObject *obj, switch (prop_id) { case ARG_COMPONENT_NAME: - g_value_set_string (value, self->omx_component); + g_omx_get_component_name_value (self, value); break; case ARG_LIBRARY_NAME: - g_value_set_string (value, self->omx_library); + g_omx_get_library_name_value (self, value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); @@ -366,12 +355,12 @@ type_class_init (gpointer g_class, g_object_class_install_property (gobject_class, ARG_COMPONENT_NAME, g_param_spec_string ("component-name", "Component name", "Name of the OpenMAX IL component to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); g_object_class_install_property (gobject_class, ARG_LIBRARY_NAME, g_param_spec_string ("library-name", "Library name", "Name of the OpenMAX IL implementation library to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); } } @@ -420,7 +409,7 @@ activate_push (GstPad *pad, static inline gboolean omx_init (GstOmxBaseSink *self) { - g_omx_core_init (self->gomx, self->omx_library, self->omx_component); + g_omx_core_init (self->gomx); if (self->gomx->omx_error) return FALSE; @@ -468,16 +457,6 @@ type_instance_init (GTypeInstance *instance, } { - const char *tmp; - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("library-name")); - self->omx_library = g_strdup (tmp); - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("component-name")); - self->omx_component = g_strdup (tmp); - } - - { GstPad *sinkpad; self->sinkpad = sinkpad = GST_BASE_SINK_PAD (self); self->base_activatepush = GST_PAD_ACTIVATEPUSHFUNC (sinkpad); diff --git a/omx/gstomx_base_sink.h b/omx/gstomx_base_sink.h index 681e939..589c441 100644 --- a/omx/gstomx_base_sink.h +++ b/omx/gstomx_base_sink.h @@ -46,9 +46,6 @@ struct GstOmxBaseSink GOmxCore *gomx; GOmxPort *in_port; - char *omx_component; - char *omx_library; - gboolean ready; GstPadActivateModeFunction base_activatepush; gboolean initialized; diff --git a/omx/gstomx_base_src.c b/omx/gstomx_base_src.c index 9b02b22..dd9767e 100644 --- a/omx/gstomx_base_src.c +++ b/omx/gstomx_base_src.c @@ -67,7 +67,7 @@ start (GstBaseSrc *gst_base) GST_LOG_OBJECT (self, "begin"); - g_omx_core_init (self->gomx, self->omx_library, self->omx_component); + g_omx_core_init (self->gomx); if (self->gomx->omx_error) return GST_STATE_CHANGE_FAILURE; @@ -106,9 +106,6 @@ finalize (GObject *obj) g_omx_core_free (self->gomx); - g_free (self->omx_component); - g_free (self->omx_library); - G_OBJECT_CLASS (parent_class)->finalize (obj); } @@ -362,20 +359,6 @@ set_property (GObject *obj, switch (prop_id) { - case ARG_COMPONENT_NAME: - if (self->omx_component) - { - g_free (self->omx_component); - } - self->omx_component = g_value_dup_string (value); - break; - case ARG_LIBRARY_NAME: - if (self->omx_library) - { - g_free (self->omx_library); - } - self->omx_library = g_value_dup_string (value); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); break; @@ -395,10 +378,10 @@ get_property (GObject *obj, switch (prop_id) { case ARG_COMPONENT_NAME: - g_value_set_string (value, self->omx_component); + g_omx_get_component_name_value (self, value); break; case ARG_LIBRARY_NAME: - g_value_set_string (value, self->omx_library); + g_omx_get_library_name_value (self, value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); @@ -433,12 +416,12 @@ type_class_init (gpointer g_class, g_object_class_install_property (gobject_class, ARG_COMPONENT_NAME, g_param_spec_string ("component-name", "Component name", "Name of the OpenMAX IL component to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); g_object_class_install_property (gobject_class, ARG_LIBRARY_NAME, g_param_spec_string ("library-name", "Library name", "Name of the OpenMAX IL implementation library to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); } } @@ -459,17 +442,6 @@ type_instance_init (GTypeInstance *instance, gomx->object = self; } - { - const char *tmp; - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("library-name")); - self->omx_library = g_strdup (tmp); - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("component-name")); - self->omx_component = g_strdup (tmp); - } - - GST_LOG_OBJECT (self, "end"); } diff --git a/omx/gstomx_base_src.h b/omx/gstomx_base_src.h index 85e4c13..adab894 100644 --- a/omx/gstomx_base_src.h +++ b/omx/gstomx_base_src.h @@ -44,8 +44,6 @@ struct GstOmxBaseSrc GOmxCore *gomx; GOmxPort *out_port; - char *omx_component; - char *omx_library; GstOmxBaseSrcCb setup_ports; }; diff --git a/omx/gstomx_conf.c b/omx/gstomx_conf.c new file mode 100644 index 0000000..d25c173 --- /dev/null +++ b/omx/gstomx_conf.c @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2010 Texas Instruments, Incorporated + * Copyright (C) 2007-2010 Nokia Corporation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include <glib.h> + +#include "config.h" + +const gchar * default_config = +"\n" +"omx_dummy,\n" +" type=GstOmxDummy,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.dummy,\n" +" rank=0;\n" +"\n" +/* for testing: */ +"omx_dummy_2,\n" +" type=GstOmxDummy,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.dummy2,\n" +" rank=256;\n" +"\n" +"omx_mpeg4dec,\n" +" type=GstOmxMpeg4Dec,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.video_decoder.mpeg4,\n" +" rank=256;\n" +"\n" +"omx_h264dec,\n" +" type=GstOmxH264Dec,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.video_decoder.avc,\n" +" rank=256;\n" +"\n" +"omx_h263dec,\n" +" type=GstOmxH263Dec,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.video_decoder.h263,\n" +" rank=256;\n" +"\n" +"omx_wmvdec,\n" +" type=GstOmxWmvDec,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.video_decoder.wmv,\n" +" rank=256;\n" +"\n" +"omx_mpeg4enc,\n" +" type=GstOmxMpeg4Enc,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.video_encoder.mpeg4,\n" +" rank=256;\n" +"\n" +"omx_h264enc,\n" +" type=GstOmxH264Enc,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.video_encoder.avc,\n" +" rank=256;\n" +"\n" +"omx_h263enc,\n" +" type=GstOmxH263Enc,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.video_encoder.h263,\n" +" rank=256;\n" +"\n" +"omx_vorbisdec,\n" +" type=GstOmxVorbisDec,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_decoder.ogg.single,\n" +" rank=128;\n" +"\n" +"omx_mp3dec,\n" +" type=GstOmxMp3Dec,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_decoder.mp3.mad,\n" +" rank=256;\n" +"\n" +#ifdef EXPERIMENTAL +"omx_mp2dec,\n" +" type=GstOmxMp2Dec,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_decoder.mp3.mad,\n" +" rank=256;\n" +"\n" +"omx_amrnbdec,\n" +" type=GstOmxAmrNbDec,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_decoder.amrnb,\n" +" rank=256;\n" +"\n" +"omx_amrnbenc,\n" +" type=GstOmxAmrNbEnc,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_encoder.amrnb,\n" +" rank=256;\n" +"\n" +"omx_amrwbdec,\n" +" type=GstOmxAmrWbDec,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_decoder.amrwb,\n" +" rank=256;\n" +"\n" +"omx_amrwbenc,\n" +" type=GstOmxAmrWbEnc,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_encoder.amrwb,\n" +" rank=256;\n" +"\n" +"omx_aacdec,\n" +" type=GstOmxAacDec,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_decoder.aac,\n" +" rank=256;\n" +"\n" +"omx_aacenc,\n" +" type=GstOmxAacEnc,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_encoder.aac,\n" +" rank=256;\n" +"\n" +"omx_adpcmdec,\n" +" type=GstOmxAdpcmDec,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_decoder.adpcm,\n" +" rank=256;\n" +"\n" +"omx_adpcmenc,\n" +" type=GstOmxAdpcmEnc,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_encoder.adpcm,\n" +" rank=256;\n" +"\n" +"omx_g711dec,\n" +" type=GstOmxG711Dec,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_decoder.g711,\n" +" rank=256;\n" +"\n" +"omx_g711enc,\n" +" type=GstOmxG711Enc,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_encoder.g711,\n" +" rank=256;\n" +"\n" +"omx_g729dec,\n" +" type=GstOmxG729Dec,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_decoder.g729,\n" +" rank=256;\n" +"\n" +"omx_g729enc,\n" +" type=GstOmxG729Enc,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_encoder.g729,\n" +" rank=256;\n" +"\n" +"omx_ilbcdec,\n" +" type=GstOmxIlbcDec,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_decoder.ilbc,\n" +" rank=256;\n" +"\n" +"omx_ilbcenc,\n" +" type=GstOmxIlbcEnc,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_encoder.ilbc,\n" +" rank=256;\n" +"\n" +"omx_jpegenc,\n" +" type=GstOmxJpegEnc,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.image_encoder.jpeg,\n" +" rank=256;\n" +"\n" +#endif /* EXPERIMENTAL */ +"omx_audiosink,\n" +" type=GstOmxAudioSink,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.alsa.alsasink,\n" +" rank=0;\n" +"\n" +#ifdef EXPERIMENTAL +"omx_videosink,\n" +" type=GstOmxVideoSink,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.videosink,\n" +" rank=0;\n" +"\n" +"omx_filereadersrc,\n" +" type=GstOmxFilereaderSrc,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.audio_filereader,\n" +" rank=0;\n" +"\n" +#endif /* EXPERIMENTAL */ +"omx_volume,\n" +" type=GstOmxVolume,\n" +" library-name=libomxil-bellagio.so.0,\n" +" component-name=OMX.st.volume.component,\n" +" rank=0;\n" +; diff --git a/omx/gstomx_util.c b/omx/gstomx_util.c index 39d900b..ac94953 100644 --- a/omx/gstomx_util.c +++ b/omx/gstomx_util.c @@ -301,10 +301,13 @@ g_omx_core_free (GOmxCore *core) } void -g_omx_core_init (GOmxCore *core, - const gchar *library_name, - const gchar *component_name) +g_omx_core_init (GOmxCore *core) { + gchar *library_name, *component_name; + + g_return_if_fail (g_omx_get_component_info (core->object, + &library_name, &component_name)); + core->imp = request_imp (library_name); if (!core->imp) diff --git a/omx/gstomx_util.h b/omx/gstomx_util.h index f0cf045..c3ac441 100644 --- a/omx/gstomx_util.h +++ b/omx/gstomx_util.h @@ -116,7 +116,7 @@ void g_omx_deinit (void); GOmxCore *g_omx_core_new (void); void g_omx_core_free (GOmxCore *core); -void g_omx_core_init (GOmxCore *core, const gchar *library_name, const gchar *component_name); +void g_omx_core_init (GOmxCore *core); void g_omx_core_deinit (GOmxCore *core); void g_omx_core_prepare (GOmxCore *core); void g_omx_core_start (GOmxCore *core); -- 1.6.3.2 |
From: Rob C. <ro...@ti...> - 2010-02-27 03:25:12
|
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. For example: ---- omx_mp3dec_ti, type=GstOmxMp3Dec, library-name=libOMX_Core.so.0, component-name=OMX.TI.AUDIO.DECODE, component-role=audio_decode.dsp.mp3, rank=256; omx_mp3dec_nokia, type=GstOmxMp3Dec, 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. --- omx/Makefile.am | 8 +- omx/gstomx.c | 372 +++++++++++++++++++++++++++++++++++++++------- omx/gstomx.conf | 203 +++++++++++++++++++++++++ omx/gstomx.h | 6 + omx/gstomx_base_filter.c | 31 +---- omx/gstomx_base_filter.h | 2 - omx/gstomx_base_sink.c | 31 +---- omx/gstomx_base_sink.h | 3 - omx/gstomx_base_src.c | 38 +---- omx/gstomx_base_src.h | 2 - omx/gstomx_util.c | 9 +- omx/gstomx_util.h | 2 +- 12 files changed, 553 insertions(+), 154 deletions(-) create mode 100644 omx/gstomx.conf diff --git a/omx/Makefile.am b/omx/Makefile.am index 4a3fbf9..01243ff 100644 --- a/omx/Makefile.am +++ b/omx/Makefile.am @@ -18,7 +18,8 @@ libgstomx_la_SOURCES = gstomx.c gstomx.h \ gstomx_vorbisdec.c gstomx_vorbisdec.h \ gstomx_mp3dec.c gstomx_mp3dec.h \ gstomx_base_sink.c gstomx_base_sink.h \ - gstomx_audiosink.c gstomx_audiosink.h + gstomx_audiosink.c gstomx_audiosink.h \ + gstomx_conf.c if EXPERIMENTAL libgstomx_la_SOURCES += gstomx_amrnbdec.c gstomx_amrnbdec.h \ @@ -47,3 +48,8 @@ libgstomx_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) $(top_builddir)/util/libutil. libgstomx_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) EXTRA_DIST = headers + +gstomx_conf.c: gstomx.conf + echo "const char * default_config =" > $@ + cat $^ | $(CPP) $(CFLAGS) $(libgstomx_la_CFLAGS) $(DEFAULT_INCLUDES) $(INCLUDES) - | grep -v "^#" | sed 's/^.*/\"&\\\n"/' >> $@ + echo ";" >> $@ diff --git a/omx/gstomx.c b/omx/gstomx.c index 6756f54..7049f41 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,90 +63,344 @@ 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; + + +extern const gchar *default_config; + +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: 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_REGISTRY")); + 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_file_set_contents (path, config, -1, NULL); + } + + 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); + } + + g_free (path); + + 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; + + g_assert (element); + + return element; +} + +static const gchar * +get_element_name (gpointer object) +{ + return g_type_get_qdata (G_OBJECT_TYPE (object), element_name_quark); +} + +/* 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; + GType type; + gint rank; + + GST_DEBUG ("element_name=%s, element=%"GST_PTR_FORMAT, element_name, element); - 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); + parent_type_name = gst_structure_get_string (element, "parent-type"); + type_name = gst_structure_get_string (element, "type"); - if (!gst_element_register (plugin, element->name, element->rank, type)) + 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 if (type_name) + { + type = g_type_from_name (type_name); + } + + if (!type_name) + { + g_warning ("malformed config file: missing 'type' for %s", + element_name); + return FALSE; + } + + if (!type) + { + g_warning ("malformed config file: invalid type '%s' for %s", + type_name, element_name); + return FALSE; + } + + 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; } +/** + * g_omx_get_component_info: + * @object: the GstOmx object (ie. GstOmxBaseFilter, GstOmxBaseSrc, or + * GstOmxBaseSink). + * @library_name: library-name, returned by reference (or NULL) + * @component_name: component-name, returned by reference (or NULL) + * + * Get library-name and component-name for an element. + * + * note: this function will gain another parameter later when component-role + * is added + */ +gboolean +g_omx_get_component_info (gpointer object, + gchar **library_name, + gchar **component_name) +{ + gboolean ret = TRUE; + const gchar *element_name = get_element_name (object); + GstStructure *element = get_element_entry (element_name); + + if (!element) + return FALSE; + + /* initialize ptrs to NULL so that in error cases we can tell what needs + * to be freed: + */ + if (library_name) *library_name = NULL; + if (component_name) *component_name = NULL; + + if (library_name) + { + const gchar *str = gst_structure_get_string (element, "library-name"); + if (!str) + { + g_warning ("malformed config file: missing 'library-name' for %s", element_name); + ret = FALSE; + goto exit; + } + *library_name = g_strdup (str); + } + + if (component_name) + { + const gchar *str = gst_structure_get_string (element, "component-name"); + if (!str) + { + g_warning ("malformed config file: missing 'component-name' for %s", element_name); + ret = FALSE; + goto exit; + } + *component_name = g_strdup (str); + } + +exit: + + /* if we failed, free any memory that might have been allocated: + */ + if (!ret) + { + if (library_name) g_free (*library_name); + if (component_name) g_free (*component_name); + } + + + return ret; +} + +static gboolean +set_value_helper (GValue *value, gchar *str) +{ + g_value_set_string (value, str); + return TRUE; +} + +/** + * g_omx_get_library_name_value: + * @object: the GstOmx object (ie. GstOmxBaseFilter, GstOmxBaseSrc, or + * GstOmxBaseSink). + * @val: the GValue to return the value through + * + * A helper to access the "library-name" as a GValue, mainly for + * get_property methods. + */ +gboolean +g_omx_get_library_name_value (gpointer object, GValue *val) +{ + gchar *str; + return g_omx_get_component_info (object, &str, NULL) && + set_value_helper (val, str); +} + +/** + * g_omx_get_component_name_value: + * @object: the GstOmx object (ie. GstOmxBaseFilter, GstOmxBaseSrc, or + * GstOmxBaseSink). + * @val: the GValue to return the value through + * + * A helper to access the "component-name" as a GValue, mainly for + * get_property methods. + */ +gboolean +g_omx_get_component_name_value (gpointer object, GValue *val) +{ + gchar *str; + return g_omx_get_component_info (object, NULL, &str) && + set_value_helper (val, str); +} + GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, "omx", diff --git a/omx/gstomx.conf b/omx/gstomx.conf new file mode 100644 index 0000000..c22c6d6 --- /dev/null +++ b/omx/gstomx.conf @@ -0,0 +1,203 @@ +#include "config.h" + +/* in case of multiple OMX components mapping to a single gst-openmax element + * class, a dynamic subclass can be created by specifying the gst-openmax + * type as the 'parent-type' and specifying a new unique type name as the + * 'type' parameter: + */ +omx_dummy, + parent-type=GstOmxDummy, + type=GstOmxDummyOne, + library-name=libomxil-bellagio.so.0, + component-name=OMX.bellagio.dummy, + rank=0; + +/* for testing: */ +omx_dummy_2, + parent-type=GstOmxDummy, + type=GstOmxDummyTwo, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.dummy2, + rank=256; + +omx_mpeg4dec, + type=GstOmxMpeg4Dec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.video_decoder.mpeg4, + rank=256; + +omx_h264dec, + type=GstOmxH264Dec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.video_decoder.avc, + rank=256; + +omx_h263dec, + type=GstOmxH263Dec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.video_decoder.h263, + rank=256; + +omx_wmvdec, + type=GstOmxWmvDec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.video_decoder.wmv, + rank=256; + +omx_mpeg4enc, + type=GstOmxMpeg4Enc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.video_encoder.mpeg4, + rank=256; + +omx_h264enc, + type=GstOmxH264Enc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.video_encoder.avc, + rank=256; + +omx_h263enc, + type=GstOmxH263Enc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.video_encoder.h263, + rank=256; + +omx_vorbisdec, + type=GstOmxVorbisDec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.ogg.single, + rank=128; + +omx_mp3dec, + type=GstOmxMp3Dec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.mp3.mad, + rank=256; + +#ifdef EXPERIMENTAL + +omx_mp2dec, + type=GstOmxMp2Dec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.mp3.mad, + rank=256; + +omx_amrnbdec, + type=GstOmxAmrNbDec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.amrnb, + rank=256; + +omx_amrnbenc, + type=GstOmxAmrNbEnc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_encoder.amrnb, + rank=256; + +omx_amrwbdec, + type=GstOmxAmrWbDec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.amrwb, + rank=256; + +omx_amrwbenc, + type=GstOmxAmrWbEnc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_encoder.amrwb, + rank=256; + +omx_aacdec, + type=GstOmxAacDec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.aac, + rank=256; + +omx_aacenc, + type=GstOmxAacEnc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_encoder.aac, + rank=256; + +omx_adpcmdec, + type=GstOmxAdpcmDec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.adpcm, + rank=256; + +omx_adpcmenc, + type=GstOmxAdpcmEnc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_encoder.adpcm, + rank=256; + +omx_g711dec, + type=GstOmxG711Dec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.g711, + rank=256; + +omx_g711enc, + type=GstOmxG711Enc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_encoder.g711, + rank=256; + +omx_g729dec, + type=GstOmxG729Dec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.g729, + rank=256; + +omx_g729enc, + type=GstOmxG729Enc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_encoder.g729, + rank=256; + +omx_ilbcdec, + type=GstOmxIlbcDec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.ilbc, + rank=256; + +omx_ilbcenc, + type=GstOmxIlbcEnc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_encoder.ilbc, + rank=256; + +omx_jpegenc, + type=GstOmxJpegEnc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.image_encoder.jpeg, + rank=256; + +#endif /* EXPERIMENTAL */ + +omx_audiosink, + type=GstOmxAudioSink, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.alsa.alsasink, + rank=0; + +#ifdef EXPERIMENTAL + +omx_videosink, + type=GstOmxVideoSink, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.videosink, + rank=0; + +omx_filereadersrc, + type=GstOmxFilereaderSrc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_filereader, + rank=0; + +#endif /* EXPERIMENTAL */ + +omx_volume, + type=GstOmxVolume, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.volume.component, + rank=0; diff --git a/omx/gstomx.h b/omx/gstomx.h index 7d5fa04..063437d 100644 --- a/omx/gstomx.h +++ b/omx/gstomx.h @@ -30,6 +30,12 @@ GST_DEBUG_CATEGORY_EXTERN (gstomx_debug); GST_DEBUG_CATEGORY_EXTERN (gstomx_util_debug); #define GST_CAT_DEFAULT gstomx_debug +gboolean g_omx_get_component_info (gpointer object, + gchar **library_name, + gchar **component_name); +gboolean g_omx_get_library_name_value (gpointer object, GValue *val); +gboolean g_omx_get_component_name_value (gpointer object, GValue *val); + G_END_DECLS #endif /* GSTOMX_H */ diff --git a/omx/gstomx_base_filter.c b/omx/gstomx_base_filter.c index b0353cb..2a30502 100644 --- a/omx/gstomx_base_filter.c +++ b/omx/gstomx_base_filter.c @@ -115,7 +115,7 @@ change_state (GstElement *element, switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: - g_omx_core_init (core, self->omx_library, self->omx_component); + g_omx_core_init (core); if (core->omx_state != OMX_StateLoaded) { ret = GST_STATE_CHANGE_FAILURE; @@ -184,9 +184,6 @@ finalize (GObject *obj) g_omx_core_free (self->gomx); - g_free (self->omx_component); - g_free (self->omx_library); - g_mutex_free (self->ready_lock); G_OBJECT_CLASS (parent_class)->finalize (obj); @@ -204,14 +201,6 @@ set_property (GObject *obj, switch (prop_id) { - case ARG_COMPONENT_NAME: - g_free (self->omx_component); - self->omx_component = g_value_dup_string (value); - break; - case ARG_LIBRARY_NAME: - g_free (self->omx_library); - self->omx_library = g_value_dup_string (value); - break; case ARG_USE_TIMESTAMPS: self->use_timestamps = g_value_get_boolean (value); break; @@ -234,10 +223,10 @@ get_property (GObject *obj, switch (prop_id) { case ARG_COMPONENT_NAME: - g_value_set_string (value, self->omx_component); + g_omx_get_component_name_value (self, value); break; case ARG_LIBRARY_NAME: - g_value_set_string (value, self->omx_library); + g_omx_get_library_name_value (self, value); break; case ARG_USE_TIMESTAMPS: g_value_set_boolean (value, self->use_timestamps); @@ -271,12 +260,12 @@ type_class_init (gpointer g_class, g_object_class_install_property (gobject_class, ARG_COMPONENT_NAME, g_param_spec_string ("component-name", "Component name", "Name of the OpenMAX IL component to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); g_object_class_install_property (gobject_class, ARG_LIBRARY_NAME, g_param_spec_string ("library-name", "Library name", "Name of the OpenMAX IL implementation library to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); g_object_class_install_property (gobject_class, ARG_USE_TIMESTAMPS, g_param_spec_boolean ("use-timestamps", "Use timestamps", @@ -922,16 +911,6 @@ type_instance_init (GTypeInstance *instance, gst_element_add_pad (GST_ELEMENT (self), self->sinkpad); gst_element_add_pad (GST_ELEMENT (self), self->srcpad); - { - const char *tmp; - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("library-name")); - self->omx_library = g_strdup (tmp); - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("component-name")); - self->omx_component = g_strdup (tmp); - } - GST_LOG_OBJECT (self, "end"); } diff --git a/omx/gstomx_base_filter.h b/omx/gstomx_base_filter.h index 4baf181..99b5d72 100644 --- a/omx/gstomx_base_filter.h +++ b/omx/gstomx_base_filter.h @@ -48,8 +48,6 @@ struct GstOmxBaseFilter GOmxPort *in_port; GOmxPort *out_port; - char *omx_component; - char *omx_library; gboolean use_timestamps; /** @todo remove; timestamps should always be used */ gboolean ready; GMutex *ready_lock; diff --git a/omx/gstomx_base_sink.c b/omx/gstomx_base_sink.c index c1a2076..7911167 100644 --- a/omx/gstomx_base_sink.c +++ b/omx/gstomx_base_sink.c @@ -141,9 +141,6 @@ finalize (GObject *obj) g_omx_core_free (self->gomx); - g_free (self->omx_component); - g_free (self->omx_library); - G_OBJECT_CLASS (parent_class)->finalize (obj); } @@ -298,14 +295,6 @@ set_property (GObject *obj, switch (prop_id) { - case ARG_COMPONENT_NAME: - g_free (self->omx_component); - self->omx_component = g_value_dup_string (value); - break; - case ARG_LIBRARY_NAME: - g_free (self->omx_library); - self->omx_library = g_value_dup_string (value); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); break; @@ -325,10 +314,10 @@ get_property (GObject *obj, switch (prop_id) { case ARG_COMPONENT_NAME: - g_value_set_string (value, self->omx_component); + g_omx_get_component_name_value (self, value); break; case ARG_LIBRARY_NAME: - g_value_set_string (value, self->omx_library); + g_omx_get_library_name_value (self, value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); @@ -366,12 +355,12 @@ type_class_init (gpointer g_class, g_object_class_install_property (gobject_class, ARG_COMPONENT_NAME, g_param_spec_string ("component-name", "Component name", "Name of the OpenMAX IL component to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); g_object_class_install_property (gobject_class, ARG_LIBRARY_NAME, g_param_spec_string ("library-name", "Library name", "Name of the OpenMAX IL implementation library to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); } } @@ -420,7 +409,7 @@ activate_push (GstPad *pad, static inline gboolean omx_init (GstOmxBaseSink *self) { - g_omx_core_init (self->gomx, self->omx_library, self->omx_component); + g_omx_core_init (self->gomx); if (self->gomx->omx_error) return FALSE; @@ -468,16 +457,6 @@ type_instance_init (GTypeInstance *instance, } { - const char *tmp; - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("library-name")); - self->omx_library = g_strdup (tmp); - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("component-name")); - self->omx_component = g_strdup (tmp); - } - - { GstPad *sinkpad; self->sinkpad = sinkpad = GST_BASE_SINK_PAD (self); self->base_activatepush = GST_PAD_ACTIVATEPUSHFUNC (sinkpad); diff --git a/omx/gstomx_base_sink.h b/omx/gstomx_base_sink.h index 681e939..589c441 100644 --- a/omx/gstomx_base_sink.h +++ b/omx/gstomx_base_sink.h @@ -46,9 +46,6 @@ struct GstOmxBaseSink GOmxCore *gomx; GOmxPort *in_port; - char *omx_component; - char *omx_library; - gboolean ready; GstPadActivateModeFunction base_activatepush; gboolean initialized; diff --git a/omx/gstomx_base_src.c b/omx/gstomx_base_src.c index 9b02b22..dd9767e 100644 --- a/omx/gstomx_base_src.c +++ b/omx/gstomx_base_src.c @@ -67,7 +67,7 @@ start (GstBaseSrc *gst_base) GST_LOG_OBJECT (self, "begin"); - g_omx_core_init (self->gomx, self->omx_library, self->omx_component); + g_omx_core_init (self->gomx); if (self->gomx->omx_error) return GST_STATE_CHANGE_FAILURE; @@ -106,9 +106,6 @@ finalize (GObject *obj) g_omx_core_free (self->gomx); - g_free (self->omx_component); - g_free (self->omx_library); - G_OBJECT_CLASS (parent_class)->finalize (obj); } @@ -362,20 +359,6 @@ set_property (GObject *obj, switch (prop_id) { - case ARG_COMPONENT_NAME: - if (self->omx_component) - { - g_free (self->omx_component); - } - self->omx_component = g_value_dup_string (value); - break; - case ARG_LIBRARY_NAME: - if (self->omx_library) - { - g_free (self->omx_library); - } - self->omx_library = g_value_dup_string (value); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); break; @@ -395,10 +378,10 @@ get_property (GObject *obj, switch (prop_id) { case ARG_COMPONENT_NAME: - g_value_set_string (value, self->omx_component); + g_omx_get_component_name_value (self, value); break; case ARG_LIBRARY_NAME: - g_value_set_string (value, self->omx_library); + g_omx_get_library_name_value (self, value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); @@ -433,12 +416,12 @@ type_class_init (gpointer g_class, g_object_class_install_property (gobject_class, ARG_COMPONENT_NAME, g_param_spec_string ("component-name", "Component name", "Name of the OpenMAX IL component to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); g_object_class_install_property (gobject_class, ARG_LIBRARY_NAME, g_param_spec_string ("library-name", "Library name", "Name of the OpenMAX IL implementation library to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); } } @@ -459,17 +442,6 @@ type_instance_init (GTypeInstance *instance, gomx->object = self; } - { - const char *tmp; - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("library-name")); - self->omx_library = g_strdup (tmp); - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("component-name")); - self->omx_component = g_strdup (tmp); - } - - GST_LOG_OBJECT (self, "end"); } diff --git a/omx/gstomx_base_src.h b/omx/gstomx_base_src.h index 85e4c13..adab894 100644 --- a/omx/gstomx_base_src.h +++ b/omx/gstomx_base_src.h @@ -44,8 +44,6 @@ struct GstOmxBaseSrc GOmxCore *gomx; GOmxPort *out_port; - char *omx_component; - char *omx_library; GstOmxBaseSrcCb setup_ports; }; diff --git a/omx/gstomx_util.c b/omx/gstomx_util.c index 39d900b..ac94953 100644 --- a/omx/gstomx_util.c +++ b/omx/gstomx_util.c @@ -301,10 +301,13 @@ g_omx_core_free (GOmxCore *core) } void -g_omx_core_init (GOmxCore *core, - const gchar *library_name, - const gchar *component_name) +g_omx_core_init (GOmxCore *core) { + gchar *library_name, *component_name; + + g_return_if_fail (g_omx_get_component_info (core->object, + &library_name, &component_name)); + core->imp = request_imp (library_name); if (!core->imp) diff --git a/omx/gstomx_util.h b/omx/gstomx_util.h index f0cf045..c3ac441 100644 --- a/omx/gstomx_util.h +++ b/omx/gstomx_util.h @@ -116,7 +116,7 @@ void g_omx_deinit (void); GOmxCore *g_omx_core_new (void); void g_omx_core_free (GOmxCore *core); -void g_omx_core_init (GOmxCore *core, const gchar *library_name, const gchar *component_name); +void g_omx_core_init (GOmxCore *core); void g_omx_core_deinit (GOmxCore *core); void g_omx_core_prepare (GOmxCore *core); void g_omx_core_start (GOmxCore *core); -- 1.6.3.2 |
From: Felipe C. <fel...@gm...> - 2010-02-27 11:13:36
|
On Sat, Feb 27, 2010 at 5:25 AM, Rob Clark <ro...@ti...> wrote: > 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. For example: Looks fine by me. There are some minor styling issues but there's no point in burdening you with that since the style is going to change anyway. I'll make the minor modifications, test, and commit this. Cheers. -- Felipe Contreras |
From: Rob C. <ro...@ti...> - 2010-02-28 17:02:41
|
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. --- Latest version of patch updates the commit msg for more detail about usage of 'type' and 'parent-type' in config file, and also makes some minor changes in error handling to work properly if G_DISABLE_CHECKS is defined omx/Makefile.am | 8 +- omx/gstomx.c | 376 +++++++++++++++++++++++++++++++++++++++------- omx/gstomx.conf | 203 +++++++++++++++++++++++++ omx/gstomx.h | 6 + omx/gstomx_base_filter.c | 31 +---- omx/gstomx_base_filter.h | 2 - omx/gstomx_base_sink.c | 31 +---- omx/gstomx_base_sink.h | 3 - omx/gstomx_base_src.c | 38 +---- omx/gstomx_base_src.h | 2 - omx/gstomx_util.c | 13 ++- omx/gstomx_util.h | 2 +- 12 files changed, 561 insertions(+), 154 deletions(-) create mode 100644 omx/gstomx.conf diff --git a/omx/Makefile.am b/omx/Makefile.am index 4a3fbf9..01243ff 100644 --- a/omx/Makefile.am +++ b/omx/Makefile.am @@ -18,7 +18,8 @@ libgstomx_la_SOURCES = gstomx.c gstomx.h \ gstomx_vorbisdec.c gstomx_vorbisdec.h \ gstomx_mp3dec.c gstomx_mp3dec.h \ gstomx_base_sink.c gstomx_base_sink.h \ - gstomx_audiosink.c gstomx_audiosink.h + gstomx_audiosink.c gstomx_audiosink.h \ + gstomx_conf.c if EXPERIMENTAL libgstomx_la_SOURCES += gstomx_amrnbdec.c gstomx_amrnbdec.h \ @@ -47,3 +48,8 @@ libgstomx_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) $(top_builddir)/util/libutil. libgstomx_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) EXTRA_DIST = headers + +gstomx_conf.c: gstomx.conf + echo "const char * default_config =" > $@ + cat $^ | $(CPP) $(CFLAGS) $(libgstomx_la_CFLAGS) $(DEFAULT_INCLUDES) $(INCLUDES) - | grep -v "^#" | sed 's/^.*/\"&\\\n"/' >> $@ + echo ";" >> $@ diff --git a/omx/gstomx.c b/omx/gstomx.c index 6756f54..4e3a168 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,90 +63,348 @@ 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; + + +extern const gchar *default_config; + +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: 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_REGISTRY")); + 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_file_set_contents (path, config, -1, NULL); + } + + 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); + } + + g_free (path); + + 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; +} + +static const gchar * +get_element_name (gpointer object) +{ + return g_type_get_qdata (G_OBJECT_TYPE (object), element_name_quark); +} + +/* 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; + GType type; + gint rank; + + GST_DEBUG ("element_name=%s, element=%"GST_PTR_FORMAT, element_name, element); - 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); + parent_type_name = gst_structure_get_string (element, "parent-type"); + type_name = gst_structure_get_string (element, "type"); - if (!gst_element_register (plugin, element->name, element->rank, type)) + 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 if (type_name) + { + type = g_type_from_name (type_name); + } + + if (!type_name) + { + g_warning ("malformed config file: missing 'type' for %s", + element_name); + return FALSE; + } + + if (!type) + { + g_warning ("malformed config file: invalid type '%s' for %s", + type_name, element_name); + return FALSE; + } + + 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; } +/** + * g_omx_get_component_info: + * @object: the GstOmx object (ie. GstOmxBaseFilter, GstOmxBaseSrc, or + * GstOmxBaseSink). + * @library_name: library-name, returned by reference (or NULL) + * @component_name: component-name, returned by reference (or NULL) + * + * Get library-name and component-name for an element. + * + * note: this function will gain another parameter later when component-role + * is added + */ +gboolean +g_omx_get_component_info (gpointer object, + gchar **library_name, + gchar **component_name) +{ + gboolean ret = TRUE; + const gchar *element_name = get_element_name (object); + GstStructure *element = get_element_entry (element_name); + + if (!element) + return FALSE; + + /* initialize ptrs to NULL so that in error cases we can tell what needs + * to be freed: + */ + if (library_name) *library_name = NULL; + if (component_name) *component_name = NULL; + + if (library_name) + { + const gchar *str = gst_structure_get_string (element, "library-name"); + if (!str) + { + g_warning ("malformed config file: missing 'library-name' for %s", element_name); + ret = FALSE; + goto exit; + } + *library_name = g_strdup (str); + } + + if (component_name) + { + const gchar *str = gst_structure_get_string (element, "component-name"); + if (!str) + { + g_warning ("malformed config file: missing 'component-name' for %s", element_name); + ret = FALSE; + goto exit; + } + *component_name = g_strdup (str); + } + +exit: + + /* if we failed, free any memory that might have been allocated: + */ + if (!ret) + { + if (library_name) g_free (*library_name); + if (component_name) g_free (*component_name); + } + + + return ret; +} + +static gboolean +set_value_helper (GValue *value, gchar *str) +{ + g_value_set_string (value, str); + return TRUE; +} + +/** + * g_omx_get_library_name_value: + * @object: the GstOmx object (ie. GstOmxBaseFilter, GstOmxBaseSrc, or + * GstOmxBaseSink). + * @val: the GValue to return the value through + * + * A helper to access the "library-name" as a GValue, mainly for + * get_property methods. + */ +gboolean +g_omx_get_library_name_value (gpointer object, GValue *val) +{ + gchar *str; + return g_omx_get_component_info (object, &str, NULL) && + set_value_helper (val, str); +} + +/** + * g_omx_get_component_name_value: + * @object: the GstOmx object (ie. GstOmxBaseFilter, GstOmxBaseSrc, or + * GstOmxBaseSink). + * @val: the GValue to return the value through + * + * A helper to access the "component-name" as a GValue, mainly for + * get_property methods. + */ +gboolean +g_omx_get_component_name_value (gpointer object, GValue *val) +{ + gchar *str; + return g_omx_get_component_info (object, NULL, &str) && + set_value_helper (val, str); +} + GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, "omx", diff --git a/omx/gstomx.conf b/omx/gstomx.conf new file mode 100644 index 0000000..c22c6d6 --- /dev/null +++ b/omx/gstomx.conf @@ -0,0 +1,203 @@ +#include "config.h" + +/* in case of multiple OMX components mapping to a single gst-openmax element + * class, a dynamic subclass can be created by specifying the gst-openmax + * type as the 'parent-type' and specifying a new unique type name as the + * 'type' parameter: + */ +omx_dummy, + parent-type=GstOmxDummy, + type=GstOmxDummyOne, + library-name=libomxil-bellagio.so.0, + component-name=OMX.bellagio.dummy, + rank=0; + +/* for testing: */ +omx_dummy_2, + parent-type=GstOmxDummy, + type=GstOmxDummyTwo, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.dummy2, + rank=256; + +omx_mpeg4dec, + type=GstOmxMpeg4Dec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.video_decoder.mpeg4, + rank=256; + +omx_h264dec, + type=GstOmxH264Dec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.video_decoder.avc, + rank=256; + +omx_h263dec, + type=GstOmxH263Dec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.video_decoder.h263, + rank=256; + +omx_wmvdec, + type=GstOmxWmvDec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.video_decoder.wmv, + rank=256; + +omx_mpeg4enc, + type=GstOmxMpeg4Enc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.video_encoder.mpeg4, + rank=256; + +omx_h264enc, + type=GstOmxH264Enc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.video_encoder.avc, + rank=256; + +omx_h263enc, + type=GstOmxH263Enc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.video_encoder.h263, + rank=256; + +omx_vorbisdec, + type=GstOmxVorbisDec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.ogg.single, + rank=128; + +omx_mp3dec, + type=GstOmxMp3Dec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.mp3.mad, + rank=256; + +#ifdef EXPERIMENTAL + +omx_mp2dec, + type=GstOmxMp2Dec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.mp3.mad, + rank=256; + +omx_amrnbdec, + type=GstOmxAmrNbDec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.amrnb, + rank=256; + +omx_amrnbenc, + type=GstOmxAmrNbEnc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_encoder.amrnb, + rank=256; + +omx_amrwbdec, + type=GstOmxAmrWbDec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.amrwb, + rank=256; + +omx_amrwbenc, + type=GstOmxAmrWbEnc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_encoder.amrwb, + rank=256; + +omx_aacdec, + type=GstOmxAacDec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.aac, + rank=256; + +omx_aacenc, + type=GstOmxAacEnc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_encoder.aac, + rank=256; + +omx_adpcmdec, + type=GstOmxAdpcmDec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.adpcm, + rank=256; + +omx_adpcmenc, + type=GstOmxAdpcmEnc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_encoder.adpcm, + rank=256; + +omx_g711dec, + type=GstOmxG711Dec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.g711, + rank=256; + +omx_g711enc, + type=GstOmxG711Enc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_encoder.g711, + rank=256; + +omx_g729dec, + type=GstOmxG729Dec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.g729, + rank=256; + +omx_g729enc, + type=GstOmxG729Enc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_encoder.g729, + rank=256; + +omx_ilbcdec, + type=GstOmxIlbcDec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.ilbc, + rank=256; + +omx_ilbcenc, + type=GstOmxIlbcEnc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_encoder.ilbc, + rank=256; + +omx_jpegenc, + type=GstOmxJpegEnc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.image_encoder.jpeg, + rank=256; + +#endif /* EXPERIMENTAL */ + +omx_audiosink, + type=GstOmxAudioSink, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.alsa.alsasink, + rank=0; + +#ifdef EXPERIMENTAL + +omx_videosink, + type=GstOmxVideoSink, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.videosink, + rank=0; + +omx_filereadersrc, + type=GstOmxFilereaderSrc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_filereader, + rank=0; + +#endif /* EXPERIMENTAL */ + +omx_volume, + type=GstOmxVolume, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.volume.component, + rank=0; diff --git a/omx/gstomx.h b/omx/gstomx.h index 7d5fa04..063437d 100644 --- a/omx/gstomx.h +++ b/omx/gstomx.h @@ -30,6 +30,12 @@ GST_DEBUG_CATEGORY_EXTERN (gstomx_debug); GST_DEBUG_CATEGORY_EXTERN (gstomx_util_debug); #define GST_CAT_DEFAULT gstomx_debug +gboolean g_omx_get_component_info (gpointer object, + gchar **library_name, + gchar **component_name); +gboolean g_omx_get_library_name_value (gpointer object, GValue *val); +gboolean g_omx_get_component_name_value (gpointer object, GValue *val); + G_END_DECLS #endif /* GSTOMX_H */ diff --git a/omx/gstomx_base_filter.c b/omx/gstomx_base_filter.c index b0353cb..2a30502 100644 --- a/omx/gstomx_base_filter.c +++ b/omx/gstomx_base_filter.c @@ -115,7 +115,7 @@ change_state (GstElement *element, switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: - g_omx_core_init (core, self->omx_library, self->omx_component); + g_omx_core_init (core); if (core->omx_state != OMX_StateLoaded) { ret = GST_STATE_CHANGE_FAILURE; @@ -184,9 +184,6 @@ finalize (GObject *obj) g_omx_core_free (self->gomx); - g_free (self->omx_component); - g_free (self->omx_library); - g_mutex_free (self->ready_lock); G_OBJECT_CLASS (parent_class)->finalize (obj); @@ -204,14 +201,6 @@ set_property (GObject *obj, switch (prop_id) { - case ARG_COMPONENT_NAME: - g_free (self->omx_component); - self->omx_component = g_value_dup_string (value); - break; - case ARG_LIBRARY_NAME: - g_free (self->omx_library); - self->omx_library = g_value_dup_string (value); - break; case ARG_USE_TIMESTAMPS: self->use_timestamps = g_value_get_boolean (value); break; @@ -234,10 +223,10 @@ get_property (GObject *obj, switch (prop_id) { case ARG_COMPONENT_NAME: - g_value_set_string (value, self->omx_component); + g_omx_get_component_name_value (self, value); break; case ARG_LIBRARY_NAME: - g_value_set_string (value, self->omx_library); + g_omx_get_library_name_value (self, value); break; case ARG_USE_TIMESTAMPS: g_value_set_boolean (value, self->use_timestamps); @@ -271,12 +260,12 @@ type_class_init (gpointer g_class, g_object_class_install_property (gobject_class, ARG_COMPONENT_NAME, g_param_spec_string ("component-name", "Component name", "Name of the OpenMAX IL component to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); g_object_class_install_property (gobject_class, ARG_LIBRARY_NAME, g_param_spec_string ("library-name", "Library name", "Name of the OpenMAX IL implementation library to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); g_object_class_install_property (gobject_class, ARG_USE_TIMESTAMPS, g_param_spec_boolean ("use-timestamps", "Use timestamps", @@ -922,16 +911,6 @@ type_instance_init (GTypeInstance *instance, gst_element_add_pad (GST_ELEMENT (self), self->sinkpad); gst_element_add_pad (GST_ELEMENT (self), self->srcpad); - { - const char *tmp; - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("library-name")); - self->omx_library = g_strdup (tmp); - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("component-name")); - self->omx_component = g_strdup (tmp); - } - GST_LOG_OBJECT (self, "end"); } diff --git a/omx/gstomx_base_filter.h b/omx/gstomx_base_filter.h index 4baf181..99b5d72 100644 --- a/omx/gstomx_base_filter.h +++ b/omx/gstomx_base_filter.h @@ -48,8 +48,6 @@ struct GstOmxBaseFilter GOmxPort *in_port; GOmxPort *out_port; - char *omx_component; - char *omx_library; gboolean use_timestamps; /** @todo remove; timestamps should always be used */ gboolean ready; GMutex *ready_lock; diff --git a/omx/gstomx_base_sink.c b/omx/gstomx_base_sink.c index c1a2076..7911167 100644 --- a/omx/gstomx_base_sink.c +++ b/omx/gstomx_base_sink.c @@ -141,9 +141,6 @@ finalize (GObject *obj) g_omx_core_free (self->gomx); - g_free (self->omx_component); - g_free (self->omx_library); - G_OBJECT_CLASS (parent_class)->finalize (obj); } @@ -298,14 +295,6 @@ set_property (GObject *obj, switch (prop_id) { - case ARG_COMPONENT_NAME: - g_free (self->omx_component); - self->omx_component = g_value_dup_string (value); - break; - case ARG_LIBRARY_NAME: - g_free (self->omx_library); - self->omx_library = g_value_dup_string (value); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); break; @@ -325,10 +314,10 @@ get_property (GObject *obj, switch (prop_id) { case ARG_COMPONENT_NAME: - g_value_set_string (value, self->omx_component); + g_omx_get_component_name_value (self, value); break; case ARG_LIBRARY_NAME: - g_value_set_string (value, self->omx_library); + g_omx_get_library_name_value (self, value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); @@ -366,12 +355,12 @@ type_class_init (gpointer g_class, g_object_class_install_property (gobject_class, ARG_COMPONENT_NAME, g_param_spec_string ("component-name", "Component name", "Name of the OpenMAX IL component to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); g_object_class_install_property (gobject_class, ARG_LIBRARY_NAME, g_param_spec_string ("library-name", "Library name", "Name of the OpenMAX IL implementation library to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); } } @@ -420,7 +409,7 @@ activate_push (GstPad *pad, static inline gboolean omx_init (GstOmxBaseSink *self) { - g_omx_core_init (self->gomx, self->omx_library, self->omx_component); + g_omx_core_init (self->gomx); if (self->gomx->omx_error) return FALSE; @@ -468,16 +457,6 @@ type_instance_init (GTypeInstance *instance, } { - const char *tmp; - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("library-name")); - self->omx_library = g_strdup (tmp); - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("component-name")); - self->omx_component = g_strdup (tmp); - } - - { GstPad *sinkpad; self->sinkpad = sinkpad = GST_BASE_SINK_PAD (self); self->base_activatepush = GST_PAD_ACTIVATEPUSHFUNC (sinkpad); diff --git a/omx/gstomx_base_sink.h b/omx/gstomx_base_sink.h index 681e939..589c441 100644 --- a/omx/gstomx_base_sink.h +++ b/omx/gstomx_base_sink.h @@ -46,9 +46,6 @@ struct GstOmxBaseSink GOmxCore *gomx; GOmxPort *in_port; - char *omx_component; - char *omx_library; - gboolean ready; GstPadActivateModeFunction base_activatepush; gboolean initialized; diff --git a/omx/gstomx_base_src.c b/omx/gstomx_base_src.c index 9b02b22..dd9767e 100644 --- a/omx/gstomx_base_src.c +++ b/omx/gstomx_base_src.c @@ -67,7 +67,7 @@ start (GstBaseSrc *gst_base) GST_LOG_OBJECT (self, "begin"); - g_omx_core_init (self->gomx, self->omx_library, self->omx_component); + g_omx_core_init (self->gomx); if (self->gomx->omx_error) return GST_STATE_CHANGE_FAILURE; @@ -106,9 +106,6 @@ finalize (GObject *obj) g_omx_core_free (self->gomx); - g_free (self->omx_component); - g_free (self->omx_library); - G_OBJECT_CLASS (parent_class)->finalize (obj); } @@ -362,20 +359,6 @@ set_property (GObject *obj, switch (prop_id) { - case ARG_COMPONENT_NAME: - if (self->omx_component) - { - g_free (self->omx_component); - } - self->omx_component = g_value_dup_string (value); - break; - case ARG_LIBRARY_NAME: - if (self->omx_library) - { - g_free (self->omx_library); - } - self->omx_library = g_value_dup_string (value); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); break; @@ -395,10 +378,10 @@ get_property (GObject *obj, switch (prop_id) { case ARG_COMPONENT_NAME: - g_value_set_string (value, self->omx_component); + g_omx_get_component_name_value (self, value); break; case ARG_LIBRARY_NAME: - g_value_set_string (value, self->omx_library); + g_omx_get_library_name_value (self, value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); @@ -433,12 +416,12 @@ type_class_init (gpointer g_class, g_object_class_install_property (gobject_class, ARG_COMPONENT_NAME, g_param_spec_string ("component-name", "Component name", "Name of the OpenMAX IL component to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); g_object_class_install_property (gobject_class, ARG_LIBRARY_NAME, g_param_spec_string ("library-name", "Library name", "Name of the OpenMAX IL implementation library to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); } } @@ -459,17 +442,6 @@ type_instance_init (GTypeInstance *instance, gomx->object = self; } - { - const char *tmp; - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("library-name")); - self->omx_library = g_strdup (tmp); - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("component-name")); - self->omx_component = g_strdup (tmp); - } - - GST_LOG_OBJECT (self, "end"); } diff --git a/omx/gstomx_base_src.h b/omx/gstomx_base_src.h index 85e4c13..adab894 100644 --- a/omx/gstomx_base_src.h +++ b/omx/gstomx_base_src.h @@ -44,8 +44,6 @@ struct GstOmxBaseSrc GOmxCore *gomx; GOmxPort *out_port; - char *omx_component; - char *omx_library; GstOmxBaseSrcCb setup_ports; }; diff --git a/omx/gstomx_util.c b/omx/gstomx_util.c index 39d900b..6701628 100644 --- a/omx/gstomx_util.c +++ b/omx/gstomx_util.c @@ -301,10 +301,17 @@ g_omx_core_free (GOmxCore *core) } void -g_omx_core_init (GOmxCore *core, - const gchar *library_name, - const gchar *component_name) +g_omx_core_init (GOmxCore *core) { + gchar *library_name, *component_name; + + if (!g_omx_get_component_info (core->object, + &library_name, &component_name)) + { + GST_ERROR_OBJECT (core->object, "missing component info"); + return; + } + core->imp = request_imp (library_name); if (!core->imp) diff --git a/omx/gstomx_util.h b/omx/gstomx_util.h index f0cf045..c3ac441 100644 --- a/omx/gstomx_util.h +++ b/omx/gstomx_util.h @@ -116,7 +116,7 @@ void g_omx_deinit (void); GOmxCore *g_omx_core_new (void); void g_omx_core_free (GOmxCore *core); -void g_omx_core_init (GOmxCore *core, const gchar *library_name, const gchar *component_name); +void g_omx_core_init (GOmxCore *core); void g_omx_core_deinit (GOmxCore *core); void g_omx_core_prepare (GOmxCore *core); void g_omx_core_start (GOmxCore *core); -- 1.6.3.2 |
From: Rob C. <ro...@ti...> - 2010-02-28 23:36:56
|
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. --- Latest (and hopefully final) version of patch fixes small memory leak omx/Makefile.am | 8 +- omx/gstomx.c | 376 +++++++++++++++++++++++++++++++++++++++------- omx/gstomx.conf | 203 +++++++++++++++++++++++++ omx/gstomx.h | 6 + omx/gstomx_base_filter.c | 31 +---- omx/gstomx_base_filter.h | 2 - omx/gstomx_base_sink.c | 31 +---- omx/gstomx_base_sink.h | 3 - omx/gstomx_base_src.c | 38 +---- omx/gstomx_base_src.h | 2 - omx/gstomx_util.c | 16 ++- omx/gstomx_util.h | 2 +- 12 files changed, 564 insertions(+), 154 deletions(-) create mode 100644 omx/gstomx.conf diff --git a/omx/Makefile.am b/omx/Makefile.am index 4a3fbf9..01243ff 100644 --- a/omx/Makefile.am +++ b/omx/Makefile.am @@ -18,7 +18,8 @@ libgstomx_la_SOURCES = gstomx.c gstomx.h \ gstomx_vorbisdec.c gstomx_vorbisdec.h \ gstomx_mp3dec.c gstomx_mp3dec.h \ gstomx_base_sink.c gstomx_base_sink.h \ - gstomx_audiosink.c gstomx_audiosink.h + gstomx_audiosink.c gstomx_audiosink.h \ + gstomx_conf.c if EXPERIMENTAL libgstomx_la_SOURCES += gstomx_amrnbdec.c gstomx_amrnbdec.h \ @@ -47,3 +48,8 @@ libgstomx_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) $(top_builddir)/util/libutil. libgstomx_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) EXTRA_DIST = headers + +gstomx_conf.c: gstomx.conf + echo "const char * default_config =" > $@ + cat $^ | $(CPP) $(CFLAGS) $(libgstomx_la_CFLAGS) $(DEFAULT_INCLUDES) $(INCLUDES) - | grep -v "^#" | sed 's/^.*/\"&\\\n"/' >> $@ + echo ";" >> $@ diff --git a/omx/gstomx.c b/omx/gstomx.c index 6756f54..6fa9b09 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,90 +63,348 @@ 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; + + +extern const gchar *default_config; + +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: 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_REGISTRY")); + 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_file_set_contents (path, config, -1, NULL); + } + + 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); + } + + g_free (path); + + 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; +} + +static const gchar * +get_element_name (gpointer object) +{ + return g_type_get_qdata (G_OBJECT_TYPE (object), element_name_quark); +} + +/* 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; + GType type; + gint rank; + + GST_DEBUG ("element_name=%s, element=%"GST_PTR_FORMAT, element_name, element); - 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); + parent_type_name = gst_structure_get_string (element, "parent-type"); + type_name = gst_structure_get_string (element, "type"); - if (!gst_element_register (plugin, element->name, element->rank, type)) + 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 if (type_name) + { + type = g_type_from_name (type_name); + } + + if (!type_name) + { + g_warning ("malformed config file: missing 'type' for %s", + element_name); + return FALSE; + } + + if (!type) + { + g_warning ("malformed config file: invalid type '%s' for %s", + type_name, element_name); + return FALSE; + } + + 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; } +/** + * g_omx_get_component_info: + * @object: the GstOmx object (ie. GstOmxBaseFilter, GstOmxBaseSrc, or + * GstOmxBaseSink). + * @library_name: library-name, returned by reference (or NULL) + * @component_name: component-name, returned by reference (or NULL) + * + * Get library-name and component-name for an element. + * + * note: this function will gain another parameter later when component-role + * is added + */ +gboolean +g_omx_get_component_info (gpointer object, + gchar **library_name, + gchar **component_name) +{ + gboolean ret = TRUE; + const gchar *element_name = get_element_name (object); + GstStructure *element = get_element_entry (element_name); + + if (!element) + return FALSE; + + /* initialize ptrs to NULL so that in error cases we can tell what needs + * to be freed: + */ + if (library_name) *library_name = NULL; + if (component_name) *component_name = NULL; + + if (library_name) + { + const gchar *str = gst_structure_get_string (element, "library-name"); + if (!str) + { + g_warning ("malformed config file: missing 'library-name' for %s", element_name); + ret = FALSE; + goto exit; + } + *library_name = g_strdup (str); + } + + if (component_name) + { + const gchar *str = gst_structure_get_string (element, "component-name"); + if (!str) + { + g_warning ("malformed config file: missing 'component-name' for %s", element_name); + ret = FALSE; + goto exit; + } + *component_name = g_strdup (str); + } + +exit: + + /* if we failed, free any memory that might have been allocated: + */ + if (!ret) + { + if (library_name) g_free (*library_name); + if (component_name) g_free (*component_name); + } + + + return ret; +} + +static gboolean +set_value_helper (GValue *value, gchar *str) +{ + g_value_take_string (value, str); + return TRUE; +} + +/** + * g_omx_get_library_name_value: + * @object: the GstOmx object (ie. GstOmxBaseFilter, GstOmxBaseSrc, or + * GstOmxBaseSink). + * @val: the GValue to return the value through + * + * A helper to access the "library-name" as a GValue, mainly for + * get_property methods. + */ +gboolean +g_omx_get_library_name_value (gpointer object, GValue *val) +{ + gchar *str; + return g_omx_get_component_info (object, &str, NULL) && + set_value_helper (val, str); +} + +/** + * g_omx_get_component_name_value: + * @object: the GstOmx object (ie. GstOmxBaseFilter, GstOmxBaseSrc, or + * GstOmxBaseSink). + * @val: the GValue to return the value through + * + * A helper to access the "component-name" as a GValue, mainly for + * get_property methods. + */ +gboolean +g_omx_get_component_name_value (gpointer object, GValue *val) +{ + gchar *str; + return g_omx_get_component_info (object, NULL, &str) && + set_value_helper (val, str); +} + GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, "omx", diff --git a/omx/gstomx.conf b/omx/gstomx.conf new file mode 100644 index 0000000..c22c6d6 --- /dev/null +++ b/omx/gstomx.conf @@ -0,0 +1,203 @@ +#include "config.h" + +/* in case of multiple OMX components mapping to a single gst-openmax element + * class, a dynamic subclass can be created by specifying the gst-openmax + * type as the 'parent-type' and specifying a new unique type name as the + * 'type' parameter: + */ +omx_dummy, + parent-type=GstOmxDummy, + type=GstOmxDummyOne, + library-name=libomxil-bellagio.so.0, + component-name=OMX.bellagio.dummy, + rank=0; + +/* for testing: */ +omx_dummy_2, + parent-type=GstOmxDummy, + type=GstOmxDummyTwo, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.dummy2, + rank=256; + +omx_mpeg4dec, + type=GstOmxMpeg4Dec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.video_decoder.mpeg4, + rank=256; + +omx_h264dec, + type=GstOmxH264Dec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.video_decoder.avc, + rank=256; + +omx_h263dec, + type=GstOmxH263Dec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.video_decoder.h263, + rank=256; + +omx_wmvdec, + type=GstOmxWmvDec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.video_decoder.wmv, + rank=256; + +omx_mpeg4enc, + type=GstOmxMpeg4Enc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.video_encoder.mpeg4, + rank=256; + +omx_h264enc, + type=GstOmxH264Enc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.video_encoder.avc, + rank=256; + +omx_h263enc, + type=GstOmxH263Enc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.video_encoder.h263, + rank=256; + +omx_vorbisdec, + type=GstOmxVorbisDec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.ogg.single, + rank=128; + +omx_mp3dec, + type=GstOmxMp3Dec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.mp3.mad, + rank=256; + +#ifdef EXPERIMENTAL + +omx_mp2dec, + type=GstOmxMp2Dec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.mp3.mad, + rank=256; + +omx_amrnbdec, + type=GstOmxAmrNbDec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.amrnb, + rank=256; + +omx_amrnbenc, + type=GstOmxAmrNbEnc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_encoder.amrnb, + rank=256; + +omx_amrwbdec, + type=GstOmxAmrWbDec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.amrwb, + rank=256; + +omx_amrwbenc, + type=GstOmxAmrWbEnc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_encoder.amrwb, + rank=256; + +omx_aacdec, + type=GstOmxAacDec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.aac, + rank=256; + +omx_aacenc, + type=GstOmxAacEnc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_encoder.aac, + rank=256; + +omx_adpcmdec, + type=GstOmxAdpcmDec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.adpcm, + rank=256; + +omx_adpcmenc, + type=GstOmxAdpcmEnc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_encoder.adpcm, + rank=256; + +omx_g711dec, + type=GstOmxG711Dec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.g711, + rank=256; + +omx_g711enc, + type=GstOmxG711Enc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_encoder.g711, + rank=256; + +omx_g729dec, + type=GstOmxG729Dec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.g729, + rank=256; + +omx_g729enc, + type=GstOmxG729Enc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_encoder.g729, + rank=256; + +omx_ilbcdec, + type=GstOmxIlbcDec, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_decoder.ilbc, + rank=256; + +omx_ilbcenc, + type=GstOmxIlbcEnc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_encoder.ilbc, + rank=256; + +omx_jpegenc, + type=GstOmxJpegEnc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.image_encoder.jpeg, + rank=256; + +#endif /* EXPERIMENTAL */ + +omx_audiosink, + type=GstOmxAudioSink, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.alsa.alsasink, + rank=0; + +#ifdef EXPERIMENTAL + +omx_videosink, + type=GstOmxVideoSink, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.videosink, + rank=0; + +omx_filereadersrc, + type=GstOmxFilereaderSrc, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.audio_filereader, + rank=0; + +#endif /* EXPERIMENTAL */ + +omx_volume, + type=GstOmxVolume, + library-name=libomxil-bellagio.so.0, + component-name=OMX.st.volume.component, + rank=0; diff --git a/omx/gstomx.h b/omx/gstomx.h index 7d5fa04..063437d 100644 --- a/omx/gstomx.h +++ b/omx/gstomx.h @@ -30,6 +30,12 @@ GST_DEBUG_CATEGORY_EXTERN (gstomx_debug); GST_DEBUG_CATEGORY_EXTERN (gstomx_util_debug); #define GST_CAT_DEFAULT gstomx_debug +gboolean g_omx_get_component_info (gpointer object, + gchar **library_name, + gchar **component_name); +gboolean g_omx_get_library_name_value (gpointer object, GValue *val); +gboolean g_omx_get_component_name_value (gpointer object, GValue *val); + G_END_DECLS #endif /* GSTOMX_H */ diff --git a/omx/gstomx_base_filter.c b/omx/gstomx_base_filter.c index b0353cb..2a30502 100644 --- a/omx/gstomx_base_filter.c +++ b/omx/gstomx_base_filter.c @@ -115,7 +115,7 @@ change_state (GstElement *element, switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: - g_omx_core_init (core, self->omx_library, self->omx_component); + g_omx_core_init (core); if (core->omx_state != OMX_StateLoaded) { ret = GST_STATE_CHANGE_FAILURE; @@ -184,9 +184,6 @@ finalize (GObject *obj) g_omx_core_free (self->gomx); - g_free (self->omx_component); - g_free (self->omx_library); - g_mutex_free (self->ready_lock); G_OBJECT_CLASS (parent_class)->finalize (obj); @@ -204,14 +201,6 @@ set_property (GObject *obj, switch (prop_id) { - case ARG_COMPONENT_NAME: - g_free (self->omx_component); - self->omx_component = g_value_dup_string (value); - break; - case ARG_LIBRARY_NAME: - g_free (self->omx_library); - self->omx_library = g_value_dup_string (value); - break; case ARG_USE_TIMESTAMPS: self->use_timestamps = g_value_get_boolean (value); break; @@ -234,10 +223,10 @@ get_property (GObject *obj, switch (prop_id) { case ARG_COMPONENT_NAME: - g_value_set_string (value, self->omx_component); + g_omx_get_component_name_value (self, value); break; case ARG_LIBRARY_NAME: - g_value_set_string (value, self->omx_library); + g_omx_get_library_name_value (self, value); break; case ARG_USE_TIMESTAMPS: g_value_set_boolean (value, self->use_timestamps); @@ -271,12 +260,12 @@ type_class_init (gpointer g_class, g_object_class_install_property (gobject_class, ARG_COMPONENT_NAME, g_param_spec_string ("component-name", "Component name", "Name of the OpenMAX IL component to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); g_object_class_install_property (gobject_class, ARG_LIBRARY_NAME, g_param_spec_string ("library-name", "Library name", "Name of the OpenMAX IL implementation library to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); g_object_class_install_property (gobject_class, ARG_USE_TIMESTAMPS, g_param_spec_boolean ("use-timestamps", "Use timestamps", @@ -922,16 +911,6 @@ type_instance_init (GTypeInstance *instance, gst_element_add_pad (GST_ELEMENT (self), self->sinkpad); gst_element_add_pad (GST_ELEMENT (self), self->srcpad); - { - const char *tmp; - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("library-name")); - self->omx_library = g_strdup (tmp); - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("component-name")); - self->omx_component = g_strdup (tmp); - } - GST_LOG_OBJECT (self, "end"); } diff --git a/omx/gstomx_base_filter.h b/omx/gstomx_base_filter.h index 4baf181..99b5d72 100644 --- a/omx/gstomx_base_filter.h +++ b/omx/gstomx_base_filter.h @@ -48,8 +48,6 @@ struct GstOmxBaseFilter GOmxPort *in_port; GOmxPort *out_port; - char *omx_component; - char *omx_library; gboolean use_timestamps; /** @todo remove; timestamps should always be used */ gboolean ready; GMutex *ready_lock; diff --git a/omx/gstomx_base_sink.c b/omx/gstomx_base_sink.c index c1a2076..7911167 100644 --- a/omx/gstomx_base_sink.c +++ b/omx/gstomx_base_sink.c @@ -141,9 +141,6 @@ finalize (GObject *obj) g_omx_core_free (self->gomx); - g_free (self->omx_component); - g_free (self->omx_library); - G_OBJECT_CLASS (parent_class)->finalize (obj); } @@ -298,14 +295,6 @@ set_property (GObject *obj, switch (prop_id) { - case ARG_COMPONENT_NAME: - g_free (self->omx_component); - self->omx_component = g_value_dup_string (value); - break; - case ARG_LIBRARY_NAME: - g_free (self->omx_library); - self->omx_library = g_value_dup_string (value); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); break; @@ -325,10 +314,10 @@ get_property (GObject *obj, switch (prop_id) { case ARG_COMPONENT_NAME: - g_value_set_string (value, self->omx_component); + g_omx_get_component_name_value (self, value); break; case ARG_LIBRARY_NAME: - g_value_set_string (value, self->omx_library); + g_omx_get_library_name_value (self, value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); @@ -366,12 +355,12 @@ type_class_init (gpointer g_class, g_object_class_install_property (gobject_class, ARG_COMPONENT_NAME, g_param_spec_string ("component-name", "Component name", "Name of the OpenMAX IL component to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); g_object_class_install_property (gobject_class, ARG_LIBRARY_NAME, g_param_spec_string ("library-name", "Library name", "Name of the OpenMAX IL implementation library to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); } } @@ -420,7 +409,7 @@ activate_push (GstPad *pad, static inline gboolean omx_init (GstOmxBaseSink *self) { - g_omx_core_init (self->gomx, self->omx_library, self->omx_component); + g_omx_core_init (self->gomx); if (self->gomx->omx_error) return FALSE; @@ -468,16 +457,6 @@ type_instance_init (GTypeInstance *instance, } { - const char *tmp; - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("library-name")); - self->omx_library = g_strdup (tmp); - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("component-name")); - self->omx_component = g_strdup (tmp); - } - - { GstPad *sinkpad; self->sinkpad = sinkpad = GST_BASE_SINK_PAD (self); self->base_activatepush = GST_PAD_ACTIVATEPUSHFUNC (sinkpad); diff --git a/omx/gstomx_base_sink.h b/omx/gstomx_base_sink.h index 681e939..589c441 100644 --- a/omx/gstomx_base_sink.h +++ b/omx/gstomx_base_sink.h @@ -46,9 +46,6 @@ struct GstOmxBaseSink GOmxCore *gomx; GOmxPort *in_port; - char *omx_component; - char *omx_library; - gboolean ready; GstPadActivateModeFunction base_activatepush; gboolean initialized; diff --git a/omx/gstomx_base_src.c b/omx/gstomx_base_src.c index 9b02b22..dd9767e 100644 --- a/omx/gstomx_base_src.c +++ b/omx/gstomx_base_src.c @@ -67,7 +67,7 @@ start (GstBaseSrc *gst_base) GST_LOG_OBJECT (self, "begin"); - g_omx_core_init (self->gomx, self->omx_library, self->omx_component); + g_omx_core_init (self->gomx); if (self->gomx->omx_error) return GST_STATE_CHANGE_FAILURE; @@ -106,9 +106,6 @@ finalize (GObject *obj) g_omx_core_free (self->gomx); - g_free (self->omx_component); - g_free (self->omx_library); - G_OBJECT_CLASS (parent_class)->finalize (obj); } @@ -362,20 +359,6 @@ set_property (GObject *obj, switch (prop_id) { - case ARG_COMPONENT_NAME: - if (self->omx_component) - { - g_free (self->omx_component); - } - self->omx_component = g_value_dup_string (value); - break; - case ARG_LIBRARY_NAME: - if (self->omx_library) - { - g_free (self->omx_library); - } - self->omx_library = g_value_dup_string (value); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); break; @@ -395,10 +378,10 @@ get_property (GObject *obj, switch (prop_id) { case ARG_COMPONENT_NAME: - g_value_set_string (value, self->omx_component); + g_omx_get_component_name_value (self, value); break; case ARG_LIBRARY_NAME: - g_value_set_string (value, self->omx_library); + g_omx_get_library_name_value (self, value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); @@ -433,12 +416,12 @@ type_class_init (gpointer g_class, g_object_class_install_property (gobject_class, ARG_COMPONENT_NAME, g_param_spec_string ("component-name", "Component name", "Name of the OpenMAX IL component to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); g_object_class_install_property (gobject_class, ARG_LIBRARY_NAME, g_param_spec_string ("library-name", "Library name", "Name of the OpenMAX IL implementation library to use", - NULL, G_PARAM_READWRITE)); + NULL, G_PARAM_READABLE)); } } @@ -459,17 +442,6 @@ type_instance_init (GTypeInstance *instance, gomx->object = self; } - { - const char *tmp; - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("library-name")); - self->omx_library = g_strdup (tmp); - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), - g_quark_from_static_string ("component-name")); - self->omx_component = g_strdup (tmp); - } - - GST_LOG_OBJECT (self, "end"); } diff --git a/omx/gstomx_base_src.h b/omx/gstomx_base_src.h index 85e4c13..adab894 100644 --- a/omx/gstomx_base_src.h +++ b/omx/gstomx_base_src.h @@ -44,8 +44,6 @@ struct GstOmxBaseSrc GOmxCore *gomx; GOmxPort *out_port; - char *omx_component; - char *omx_library; GstOmxBaseSrcCb setup_ports; }; diff --git a/omx/gstomx_util.c b/omx/gstomx_util.c index 39d900b..dae3f67 100644 --- a/omx/gstomx_util.c +++ b/omx/gstomx_util.c @@ -301,10 +301,17 @@ g_omx_core_free (GOmxCore *core) } void -g_omx_core_init (GOmxCore *core, - const gchar *library_name, - const gchar *component_name) +g_omx_core_init (GOmxCore *core) { + gchar *library_name, *component_name; + + if (!g_omx_get_component_info (core->object, + &library_name, &component_name)) + { + GST_ERROR_OBJECT (core->object, "missing component info"); + return; + } + core->imp = request_imp (library_name); if (!core->imp) @@ -316,6 +323,9 @@ g_omx_core_init (GOmxCore *core, &callbacks); if (!core->omx_error) core->omx_state = OMX_StateLoaded; + + g_free (library_name); + g_free (component_name); } void diff --git a/omx/gstomx_util.h b/omx/gstomx_util.h index f0cf045..c3ac441 100644 --- a/omx/gstomx_util.h +++ b/omx/gstomx_util.h @@ -116,7 +116,7 @@ void g_omx_deinit (void); GOmxCore *g_omx_core_new (void); void g_omx_core_free (GOmxCore *core); -void g_omx_core_init (GOmxCore *core, const gchar *library_name, const gchar *component_name); +void g_omx_core_init (GOmxCore *core); void g_omx_core_deinit (GOmxCore *core); void g_omx_core_prepare (GOmxCore *core); void g_omx_core_start (GOmxCore *core); -- 1.6.3.2 |
From: Felipe C. <fel...@gm...> - 2010-03-01 15:29:25
|
On Mon, Mar 1, 2010 at 1:36 AM, Rob Clark <ro...@ti...> wrote: > Latest (and hopefully final) version of patch fixes small memory leak You should specify the version of your patch (v6?), you can do that with easily with format-patch --subject-prefix="PATCH v6". Otherwise it's hard to keep track of them. Stefan, can I get your ACK for this? Cheers. -- Felipe Contreras |
From: Felipe C. <fel...@no...> - 2010-03-03 00:07:26
|
On Mon, Mar 01, 2010 at 12:36:13AM +0100, Rob Clark wrote: > 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. > --- > Latest (and hopefully final) version of patch fixes small memory leak I was about to commit this when I recalled to run 'make check', which is broken by this commit. One modification lead to another and I ended up making huge modifications. Please see the following patch (I'll call it v2 because the previous ones were not versioned). First, it's not necessary to make read-only the 'library-name' and 'component-name' properties. I acomplished this by moving both fienls from the bases clases to GOmxCore, and then, in g_omx_core_init(), only update them if they haven't been set before. This fixes 'make check'. I have the patch if you are interested. It might be possible to update 'make check' to use a temporary configuration file instead, but I didn't want to go that way yet. The problem with this approach is that the fields will not be updated from the config file until g_omx_core_init() is called, so they'll not show in gst-launch. I solved this by calling g_omx_get_component_info() when the instance is created and using the type of the class instead of the element name. For some reason get_element_name() was returning NULL. I think it might be possible to keep using the element name as the primary field, by using the "element-name" qdata of the GType but I only though of it just now. The resulting patch is much simpler. This is the format of the config: (I'm not entirely happy with it) --- GstOmxMpeg4Dec, name=omx_mpeg4dec, library-name=libOMX_Core, component-name=OMX.TI.Video.Decoder, rank=256; --- Cheers. -- Felipe Contreras |
From: Felipe C. <fel...@no...> - 2010-03-03 00:15:55
|
From: Rob Clark <ro...@ti...> Modified by Felipe Contreras to use element 'type' instead of 'name' as primary field, and keep using the library and component names through qdata. Plus a bunch of cleanups and reorganization. Signed-off-by: Felipe Contreras <fel...@no...> --- omx/gstomx.c | 254 ++++++++++++++++++++++++++++++++++++++++++++++------------ 1 files changed, 201 insertions(+), 53 deletions(-) diff --git a/omx/gstomx.c b/omx/gstomx.c index 6756f54..6d50f68 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,229 @@ 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; + +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: 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_REGISTRY")); + 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_type = gst_structure_get_name (element); + gst_structure_set (element_table, + element_type, 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_type) +{ + GstStructure *element_table = get_element_table (); + GstStructure *element; + + if (!gst_structure_get (element_table, element_type, + 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"); + /* + * 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_type = gst_structure_nth_field_name (element_table, i); + GstStructure *element = get_element_entry (element_type); + const gchar *name, *parent_type_name; + const gchar *component_name, *library_name; + GType type; + gint rank; + + GST_DEBUG ("element_type=%s, element=%" GST_PTR_FORMAT, element_type, element); + + name = gst_structure_get_string (element, "name"); + component_name = gst_structure_get_string (element, "component-name"); + library_name = gst_structure_get_string (element, "library-name"); - 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); + parent_type_name = gst_structure_get_string (element, "parent-type"); - if (!gst_element_register (plugin, element->name, element->rank, type)) + if (!name || !component_name || !library_name) + { + g_warning ("malformed config file: missing required fields for %s", + element_type); + return FALSE; + } + + if (parent_type_name) + { + type = g_type_from_name (parent_type_name); + if (type) { - g_warning ("failed registering '%s'", element->name); + type = create_subtype (type, element_type); + } + else + { + g_warning ("malformed config file: invalid parent-type '%s' for %s", + parent_type_name, element_type); return FALSE; } } + else + type = g_type_from_name (element_type); + + if (!type) + { + g_warning ("malformed config file: invalid type '%s'", + element_type); + return FALSE; + } + + g_type_set_qdata (type, library_name_quark, (gpointer) library_name); + g_type_set_qdata (type, component_name_quark, (gpointer) component_name); + + if (!gst_structure_get_int (element, "rank", &rank)) + { + /* use default rank: */ + rank = GST_RANK_NONE; + } + + if (!gst_element_register (plugin, name, rank, type)) + { + g_warning ("failed registering '%s'", name); + return FALSE; + } } return TRUE; -- 1.7.0.1 |
From: Felipe C. <fel...@no...> - 2010-03-03 00:20:36
|
On Wed, Mar 03, 2010 at 01:15:24AM +0100, To gst-openmax wrote: > From: Rob Clark <ro...@ti...> > > Modified by Felipe Contreras to use element 'type' instead of 'name' as > primary field, and keep using the library and component names through > qdata. Plus a bunch of cleanups and reorganization. > > Signed-off-by: Felipe Contreras <fel...@no...> Damn it, I forgot to include your commit message. Anyway, this is more like RFC. Cheers. -- Felipe Contreras |
From: Felipe C. <fel...@gm...> - 2010-03-03 00:35:50
|
On Wed, Mar 3, 2010 at 2:15 AM, Felipe Contreras <fel...@no...> wrote: > diff --git a/omx/gstomx.c b/omx/gstomx.c [...] > +static GstStructure *element_table = NULL; > + > +const gchar *default_config = NULL; Note that the default_config is NULL, but will be updated by a subsequent patch to use the extern one. [...] > +/* 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_REGISTRY")); > + 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; Note that here I'm not creating a file with the default_config. I think it's a bad idea; the conf file wouldn't be human readable, and in case gst-omx is updated with a new default_config it will not be used because the old one is already stored. [...] Cheers. -- Felipe Contreras |
From: Clark, R. <ro...@ti...> - 2010-03-03 02:18:37
|
On Mar 2, 2010, at 6:35 PM, Felipe Contreras wrote: > On Wed, Mar 3, 2010 at 2:15 AM, Felipe Contreras > <fel...@no...> wrote: >> diff --git a/omx/gstomx.c b/omx/gstomx.c > > [...] > >> +static GstStructure *element_table = NULL; >> + >> +const gchar *default_config = NULL; > > Note that the default_config is NULL, but will be updated by a > subsequent patch to use the extern one. > > [...] > >> +/* 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_REGISTRY")); >> + 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; > > Note that here I'm not creating a file with the default_config. > > I think it's a bad idea; the conf file wouldn't be human readable, and > in case gst-omx is updated with a new default_config it will not be > used because the old one is already stored. re: human-readable: as long as you aren't using gst_structure_to_string(), it should be readable.. re: writing default config: I was debating back and forth on this.. it would be nice to make it easier for someone to take the current config, and make a few tweaks. Maybe the better approach would be to write out gst-openmax.conf-example which the user could modify and rename if desired.. (other note.. current patch I sent was not handling case where .config directory does not exist yet) BR, -R > > [...] > > Cheers. > > -- > Felipe Contreras > > ------------------------------------------------------------------------------ > Download Intel® Parallel Studio Eval > Try the new software tools for yourself. Speed compiling, find bugs > proactively, and fine-tune applications for parallel performance. > See why Intel Parallel Studio got high marks during beta. > http://p.sf.net/sfu/intel-sw-dev > _______________________________________________ > Gstreamer-openmax mailing list > Gst...@li... > https://lists.sourceforge.net/lists/listinfo/gstreamer-openmax |
From: Felipe C. <fel...@no...> - 2010-03-03 09:59:42
|
On Wed, Mar 03, 2010 at 03:06:24AM +0100, Rob Clark wrote: > On Mar 2, 2010, at 6:35 PM, Felipe Contreras wrote: > > Note that here I'm not creating a file with the default_config. > > > > I think it's a bad idea; the conf file wouldn't be human readable, and > > in case gst-omx is updated with a new default_config it will not be > > used because the old one is already stored. > > re: human-readable: as long as you aren't using > gst_structure_to_string(), it should be readable.. Well, when I took a look at the file (which I scratched my head for quite some time trying to figure out how it got there) everything was on one line. So that's not readable to me. > re: writing default config: I was debating back and forth on this.. > it would be nice to make it easier for someone to take the current > config, and make a few tweaks. Maybe the better approach would be to > write out gst-openmax.conf-example which the user could modify and > rename if desired.. Yeah, in some kind of documentation, but we shouldn't polute the user's config directory. Most people wouldn't care about this, and if every project out there does this, it would be chaos. I don't recall any project doing something like this. The other option is to provide a system-wide config file instead, so the user can copy it to ~/.config, and then modify it. But in that case I'm against having an internal 'default_config'. In fact, now that I think again... most systems would rather have a system-wide config file. Cheers. -- Felipe Contreras |
From: Felipe C. <fel...@gm...> - 2010-02-26 12:06:04
|
On Thu, Feb 25, 2010 at 3:56 AM, Rob Clark <ro...@ti...> wrote: > 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. For example: In general the patch looks ok, but: 1) I don't like this new class creation, probably the only reason it's needed is because the library-name and component-name are set in the GType, which is not needed. We can set these into the element itself without modifying the original GType. 2) gstomx_conf.c looks a bit tricky, I was thinking on a plain text file, just like gst-openmax.conf. I guess the .c file is ok for now, but I don't like this tricky Makefile rule, let's just have a gstomx_conf.c instead. 3) The configuration location should be obtained with g_get_user_config_dir() ($HOME/.config) Also, a few minor comments below. > ---- > omx_mp3dec_ti, > type=GstOmxMp3Dec, > library-name=libOMX_Core.so.0, > component-name=OMX.TI.AUDIO.DECODE, > component-role=audio_decode.dsp.mp3, > rank=256; > > omx_mp3dec_nokia, > type=GstOmxMp3Dec, > library-name=libomxil_bellagio.so.0, > component-name=OMX.nokia.audio_decode.mp3, > rank=128; > ---- > > by default, the config file is stored in $HOME/.gstreamer-0.10/gst-openmax.conf, although if none is found a default config will be created. > --- > configure.ac | 3 + > omx/Makefile.am | 9 +- > omx/gstomx.c | 353 ++++++++++++++++++++++++++++++++++++++-------- > omx/gstomx.conf | 216 ++++++++++++++++++++++++++++ > omx/gstomx.h | 12 ++ > omx/gstomx_base_filter.c | 31 +---- > omx/gstomx_base_filter.h | 2 - > omx/gstomx_base_sink.c | 31 +---- > omx/gstomx_base_sink.h | 3 - > omx/gstomx_base_src.c | 38 +----- > omx/gstomx_base_src.h | 2 - > omx/gstomx_util.c | 9 +- > omx/gstomx_util.h | 2 +- > 13 files changed, 553 insertions(+), 158 deletions(-) > create mode 100644 omx/gstomx.conf > > diff --git a/configure.ac b/configure.ac > index 22dcf7d..3d7df3f 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -11,6 +11,9 @@ dnl versions of GStreamer > GST_MAJORMINOR=0.10 > GST_REQUIRED=0.10.0 > > +AC_DEFINE_UNQUOTED(GST_MAJORMINOR, "$GST_MAJORMINOR", > + [library major.minor version]) > + > dnl AM_MAINTAINER_MODE provides the option to enable maintainer mode > AM_MAINTAINER_MODE > > diff --git a/omx/Makefile.am b/omx/Makefile.am > index 4a3fbf9..1bb9901 100644 > --- a/omx/Makefile.am > +++ b/omx/Makefile.am > @@ -18,7 +18,8 @@ libgstomx_la_SOURCES = gstomx.c gstomx.h \ > gstomx_vorbisdec.c gstomx_vorbisdec.h \ > gstomx_mp3dec.c gstomx_mp3dec.h \ > gstomx_base_sink.c gstomx_base_sink.h \ > - gstomx_audiosink.c gstomx_audiosink.h > + gstomx_audiosink.c gstomx_audiosink.h \ > + gstomx_conf.c > > if EXPERIMENTAL > libgstomx_la_SOURCES += gstomx_amrnbdec.c gstomx_amrnbdec.h \ > @@ -47,3 +48,9 @@ libgstomx_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) $(top_builddir)/util/libutil. > libgstomx_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) > > EXTRA_DIST = headers > + > +gstomx_conf.c: gstomx.conf > + echo "const char * default_config =" > $@ > + cat $^ | $(CPP) $(CFLAGS) $(libgstomx_la_CFLAGS) $(DEFAULT_INCLUDES) $(INCLUDES) - | grep -v "^#" | sed 's/^.*/\"&\\\n"/' >> $@ > + echo ";" >> $@ > + > diff --git a/omx/gstomx.c b/omx/gstomx.c > index 6756f54..ae80813 100644 > --- a/omx/gstomx.c > +++ b/omx/gstomx.c > @@ -19,8 +19,12 @@ > * > */ > > +#include <string.h> > + > #include "config.h" > > +#include <gst/gststructure.h> > + > #include "gstomx.h" > #include "gstomx_dummy.h" > #include "gstomx_mpeg4dec.h" > @@ -59,90 +63,317 @@ > > 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; > + > +extern const gchar *default_config; > + > +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, > }; > > + Unnecessary extra space. > +/* 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_REGISTRY")); > + if (!path) > + { > + path = g_build_filename (g_get_home_dir (), > + ".gstreamer-" GST_MAJORMINOR, "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_file_set_contents (path, config, -1, NULL); > + } > + > + 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); > + } > + > + g_free (path); > + > + 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; > + > + g_assert (gst_structure_get (element_table, > + element_name, GST_TYPE_STRUCTURE, &element, NULL)); > + > + return element; > +} > + > +static const gchar * > +get_element_name (gpointer object) > +{ > + return g_type_name (G_OBJECT_TYPE (object)); > +} > + > + Unnecessary extra space. > +/* register a new dynamic sub-class with the omx element as it's 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 type, const gchar *element_name) > +{ > + GTypeQuery q; > + GTypeInfo i; > + > + g_type_query (type, &q); > + > + bzero (&i, sizeof (i)); bzero is deprecated in POSIX; memset should be used instead. Even better would be to set any field of i, the compiler would then zero the rest of the structure (C spec). > + i.class_size = q.class_size; > + i.instance_size = q.instance_size; > + > + return g_type_register_static (type, element_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"); > + /* first, call all the _get_type() functions to ensure the types are > + * registered: > + */ > + for (i = 0; i < DIM (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++) > + const gchar *element_name = gst_structure_nth_field_name (element_table, i); > + GstStructure *element = get_element_entry (element_name); > + const gchar *type_name; > + GType type; > + gint rank; > + > + GST_DEBUG ("element=%"GST_PTR_FORMAT, element); > + > + type_name = gst_structure_get_string (element, "type"); > + if (!type_name) > + { > + g_warning ("malformed config file: missing 'type' for %s", element_name); > + return FALSE; > + } > + > + 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; > + } > + > + type = create_subtype (type, element_name); > + > + if (!gst_structure_get_int (element, "rank", &rank)) > { > - TableItem *element; > - GType type; > - > - 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); > - > - if (!gst_element_register (plugin, element->name, element->rank, type)) > - { > - g_warning ("failed registering '%s'", element->name); > - return FALSE; > - } > + /* 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; > } > > +/** > + * g_omx_get_component_info: > + * @object: the GstOmx object (ie. GstOmxBaseFilter, GstOmxBaseSrc, or > + * GstOmxBaseSink). > + * @library_name: library-name, returned by reference (or NULL) > + * @component_name: component-name, returned by reference (or NULL) > + * > + * Get library-name and component-name for an element. > + * > + * note: this function will gain another parameter later when component-role > + * is added > + */ > +gboolean > +g_omx_get_component_info (gpointer object, > + gchar **library_name, > + gchar **component_name) > +{ > + gboolean ret = TRUE; > + const gchar *element_name = get_element_name (object); > + GstStructure *element = get_element_entry (element_name); > + > + g_assert (gst_structure_get (element_table, > + element_name, GST_TYPE_STRUCTURE, &element, NULL)); > + > + /* initialize ptrs to NULL so that in error cases we can tell what needs > + * to be freed: > + */ > + if (library_name) *library_name = NULL; > + if (component_name) *component_name = NULL; > + > + if (library_name) > + { > + const gchar *str = gst_structure_get_string (element, "library-name"); > + if (!str) > + { > + g_warning ("malformed config file: missing 'library-name' for %s", element_name); > + ret = FALSE; > + goto beach; > + } > + *library_name = g_strdup (str); > + } > + > + if (component_name) > + { > + const gchar *str = gst_structure_get_string (element, "component-name"); > + if (!str) > + { > + g_warning ("malformed config file: missing 'component-name' for %s", element_name); > + ret = FALSE; > + goto beach; > + } > + *component_name = g_strdup (str); > + } > + > +beach: Let's not follow bad gst practiced :) let's call this "leave", or something meaningful. > + > + /* if we failed, free any memory that might have been allocated: > + */ > + if (!ret) > + { > + if (library_name) g_free (*library_name); > + if (component_name) g_free (*component_name); > + } > + > + > + return ret; > +} > + > +static gboolean > +set_value_helper (GValue *value, gchar *str) > +{ > + g_value_set_string (value, str); > + return TRUE; > +} > + > +/** > + * g_omx_get_library_name_value: > + * @object: the GstOmx object (ie. GstOmxBaseFilter, GstOmxBaseSrc, or > + * GstOmxBaseSink). > + * @val: the GValue to return the value through > + * > + * A helper to access the "library-name" as a GValue, mainly for > + * get_property methods. > + */ > +gboolean > +g_omx_get_library_name_value (gpointer object, GValue *val) > +{ > + gchar *str; > + return g_omx_get_component_info (object, &str, NULL) && > + set_value_helper (val, str); > +} > + > +/** > + * g_omx_get_component_name_value: > + * @object: the GstOmx object (ie. GstOmxBaseFilter, GstOmxBaseSrc, or > + * GstOmxBaseSink). > + * @val: the GValue to return the value through > + * > + * A helper to access the "component-name" as a GValue, mainly for > + * get_property methods. > + */ > +gboolean > +g_omx_get_component_name_value (gpointer object, GValue *val) > +{ > + gchar *str; > + return g_omx_get_component_info (object, NULL, &str) && > + set_value_helper (val, str); > +} > + > + Unnecessary extra space. This is done in a bunch of other places =/ > GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, > GST_VERSION_MINOR, > "omx", > diff --git a/omx/gstomx.conf b/omx/gstomx.conf > new file mode 100644 > index 0000000..6a88dc1 > --- /dev/null > +++ b/omx/gstomx.conf > @@ -0,0 +1,216 @@ > +/* > + * Copyright (C) 2010 Texas Instruments, Incorporated > + * Copyright (C) 2007-2010 Nokia Corporation. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + * > + */ > + > +#include "config.h" > + > +omx_dummy, > + type=GstOmxDummy, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.dummy, > + rank=0; > + > +/* for testing: */ > +omx_dummy_2, > + type=GstOmxDummy, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.dummy2, > + rank=256; > + > +omx_mpeg4dec, > + type=GstOmxMpeg4Dec, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.video_decoder.mpeg4, > + rank=256; > + > +omx_h264dec, > + type=GstOmxH264Dec, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.video_decoder.avc, > + rank=256; > + > +omx_h263dec, > + type=GstOmxH263Dec, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.video_decoder.h263, > + rank=256; > + > +omx_wmvdec, > + type=GstOmxWmvDec, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.video_decoder.wmv, > + rank=256; > + > +omx_mpeg4enc, > + type=GstOmxMpeg4Enc, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.video_encoder.mpeg4, > + rank=256; > + > +omx_h264enc, > + type=GstOmxH264Enc, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.video_encoder.avc, > + rank=256; > + > +omx_h263enc, > + type=GstOmxH263Enc, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.video_encoder.h263, > + rank=256; > + > +omx_vorbisdec, > + type=GstOmxVorbisDec, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.audio_decoder.ogg.single, > + rank=128; > + > +omx_mp3dec, > + type=GstOmxMp3Dec, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.audio_decoder.mp3.mad, > + rank=256; > + > +#ifdef EXPERIMENTAL > + > +omx_mp2dec, > + type=GstOmxMp2Dec, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.audio_decoder.mp3.mad, > + rank=256; > + > +omx_amrnbdec, > + type=GstOmxAmrNbDec, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.audio_decoder.amrnb, > + rank=256; > + > +omx_amrnbenc, > + type=GstOmxAmrNbEnc, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.audio_encoder.amrnb, > + rank=256; > + > +omx_amrwbdec, > + type=GstOmxAmrWbDec, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.audio_decoder.amrwb, > + rank=256; > + > +omx_amrwbenc, > + type=GstOmxAmrWbEnc, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.audio_encoder.amrwb, > + rank=256; > + > +omx_aacdec, > + type=GstOmxAacDec, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.audio_decoder.aac, > + rank=256; > + > +omx_aacenc, > + type=GstOmxAacEnc, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.audio_encoder.aac, > + rank=256; > + > +omx_adpcmdec, > + type=GstOmxAdpcmDec, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.audio_decoder.adpcm, > + rank=256; > + > +omx_adpcmenc, > + type=GstOmxAdpcmEnc, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.audio_encoder.adpcm, > + rank=256; > + > +omx_g711dec, > + type=GstOmxG711Dec, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.audio_decoder.g711, > + rank=256; > + > +omx_g711enc, > + type=GstOmxG711Enc, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.audio_encoder.g711, > + rank=256; > + > +omx_g729dec, > + type=GstOmxG729Dec, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.audio_decoder.g729, > + rank=256; > + > +omx_g729enc, > + type=GstOmxG729Enc, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.audio_encoder.g729, > + rank=256; > + > +omx_ilbcdec, > + type=GstOmxIlbcDec, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.audio_decoder.ilbc, > + rank=256; > + > +omx_ilbcenc, > + type=GstOmxIlbcEnc, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.audio_encoder.ilbc, > + rank=256; > + > +omx_jpegenc, > + type=GstOmxJpegEnc, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.image_encoder.jpeg, > + rank=256; > + > +#endif /* EXPERIMENTAL */ > + > +omx_audiosink, > + type=GstOmxAudioSink, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.alsa.alsasink, > + rank=0; > + > +#ifdef EXPERIMENTAL > + > +omx_videosink, > + type=GstOmxVideoSink, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.videosink, > + rank=0; > + > +omx_filereadersrc, > + type=GstOmxFilereaderSrc, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.audio_filereader, > + rank=0; > + > +#endif /* EXPERIMENTAL */ > + > +omx_volume, > + type=GstOmxVolume, > + library-name=libomxil-bellagio.so.0, > + component-name=OMX.st.volume.component, > + rank=0; > diff --git a/omx/gstomx.h b/omx/gstomx.h > index 7d5fa04..0d362d7 100644 > --- a/omx/gstomx.h > +++ b/omx/gstomx.h > @@ -30,6 +30,18 @@ GST_DEBUG_CATEGORY_EXTERN (gstomx_debug); > GST_DEBUG_CATEGORY_EXTERN (gstomx_util_debug); > #define GST_CAT_DEFAULT gstomx_debug > > +#ifndef DIM /* XXX is there a better alternative available? */ > +# define DIM(x) (sizeof(x)/sizeof((x)[0])) > +#endif Let's call it ARRAY_SIZE (just like in the kernel). Maybe there's something in GLib for that (can't recall though), but I like ARRAY_SIZE :) > + > + > +gboolean g_omx_get_component_info (gpointer object, > + gchar **library_name, > + gchar **component_name); > +gboolean g_omx_get_library_name_value (gpointer object, GValue *val); > +gboolean g_omx_get_component_name_value (gpointer object, GValue *val); > + > + > G_END_DECLS > > #endif /* GSTOMX_H */ > diff --git a/omx/gstomx_base_filter.c b/omx/gstomx_base_filter.c > index b0353cb..2a30502 100644 > --- a/omx/gstomx_base_filter.c > +++ b/omx/gstomx_base_filter.c > @@ -115,7 +115,7 @@ change_state (GstElement *element, > switch (transition) > { > case GST_STATE_CHANGE_NULL_TO_READY: > - g_omx_core_init (core, self->omx_library, self->omx_component); > + g_omx_core_init (core); > if (core->omx_state != OMX_StateLoaded) > { > ret = GST_STATE_CHANGE_FAILURE; > @@ -184,9 +184,6 @@ finalize (GObject *obj) > > g_omx_core_free (self->gomx); > > - g_free (self->omx_component); > - g_free (self->omx_library); > - > g_mutex_free (self->ready_lock); > > G_OBJECT_CLASS (parent_class)->finalize (obj); > @@ -204,14 +201,6 @@ set_property (GObject *obj, > > switch (prop_id) > { > - case ARG_COMPONENT_NAME: > - g_free (self->omx_component); > - self->omx_component = g_value_dup_string (value); > - break; > - case ARG_LIBRARY_NAME: > - g_free (self->omx_library); > - self->omx_library = g_value_dup_string (value); > - break; > case ARG_USE_TIMESTAMPS: > self->use_timestamps = g_value_get_boolean (value); > break; > @@ -234,10 +223,10 @@ get_property (GObject *obj, > switch (prop_id) > { > case ARG_COMPONENT_NAME: > - g_value_set_string (value, self->omx_component); > + g_omx_get_component_name_value (self, value); > break; > case ARG_LIBRARY_NAME: > - g_value_set_string (value, self->omx_library); > + g_omx_get_library_name_value (self, value); > break; > case ARG_USE_TIMESTAMPS: > g_value_set_boolean (value, self->use_timestamps); > @@ -271,12 +260,12 @@ type_class_init (gpointer g_class, > g_object_class_install_property (gobject_class, ARG_COMPONENT_NAME, > g_param_spec_string ("component-name", "Component name", > "Name of the OpenMAX IL component to use", > - NULL, G_PARAM_READWRITE)); > + NULL, G_PARAM_READABLE)); > > g_object_class_install_property (gobject_class, ARG_LIBRARY_NAME, > g_param_spec_string ("library-name", "Library name", > "Name of the OpenMAX IL implementation library to use", > - NULL, G_PARAM_READWRITE)); > + NULL, G_PARAM_READABLE)); > > g_object_class_install_property (gobject_class, ARG_USE_TIMESTAMPS, > g_param_spec_boolean ("use-timestamps", "Use timestamps", > @@ -922,16 +911,6 @@ type_instance_init (GTypeInstance *instance, > gst_element_add_pad (GST_ELEMENT (self), self->sinkpad); > gst_element_add_pad (GST_ELEMENT (self), self->srcpad); > > - { > - const char *tmp; > - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), > - g_quark_from_static_string ("library-name")); > - self->omx_library = g_strdup (tmp); > - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), > - g_quark_from_static_string ("component-name")); > - self->omx_component = g_strdup (tmp); > - } > - > GST_LOG_OBJECT (self, "end"); > } > > diff --git a/omx/gstomx_base_filter.h b/omx/gstomx_base_filter.h > index 4baf181..99b5d72 100644 > --- a/omx/gstomx_base_filter.h > +++ b/omx/gstomx_base_filter.h > @@ -48,8 +48,6 @@ struct GstOmxBaseFilter > GOmxPort *in_port; > GOmxPort *out_port; > > - char *omx_component; > - char *omx_library; > gboolean use_timestamps; /** @todo remove; timestamps should always be used */ > gboolean ready; > GMutex *ready_lock; > diff --git a/omx/gstomx_base_sink.c b/omx/gstomx_base_sink.c > index c1a2076..7911167 100644 > --- a/omx/gstomx_base_sink.c > +++ b/omx/gstomx_base_sink.c > @@ -141,9 +141,6 @@ finalize (GObject *obj) > > g_omx_core_free (self->gomx); > > - g_free (self->omx_component); > - g_free (self->omx_library); > - > G_OBJECT_CLASS (parent_class)->finalize (obj); > } > > @@ -298,14 +295,6 @@ set_property (GObject *obj, > > switch (prop_id) > { > - case ARG_COMPONENT_NAME: > - g_free (self->omx_component); > - self->omx_component = g_value_dup_string (value); > - break; > - case ARG_LIBRARY_NAME: > - g_free (self->omx_library); > - self->omx_library = g_value_dup_string (value); > - break; > default: > G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); > break; > @@ -325,10 +314,10 @@ get_property (GObject *obj, > switch (prop_id) > { > case ARG_COMPONENT_NAME: > - g_value_set_string (value, self->omx_component); > + g_omx_get_component_name_value (self, value); > break; > case ARG_LIBRARY_NAME: > - g_value_set_string (value, self->omx_library); > + g_omx_get_library_name_value (self, value); > break; > default: > G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); > @@ -366,12 +355,12 @@ type_class_init (gpointer g_class, > g_object_class_install_property (gobject_class, ARG_COMPONENT_NAME, > g_param_spec_string ("component-name", "Component name", > "Name of the OpenMAX IL component to use", > - NULL, G_PARAM_READWRITE)); > + NULL, G_PARAM_READABLE)); > > g_object_class_install_property (gobject_class, ARG_LIBRARY_NAME, > g_param_spec_string ("library-name", "Library name", > "Name of the OpenMAX IL implementation library to use", > - NULL, G_PARAM_READWRITE)); > + NULL, G_PARAM_READABLE)); > } > } > > @@ -420,7 +409,7 @@ activate_push (GstPad *pad, > static inline gboolean > omx_init (GstOmxBaseSink *self) > { > - g_omx_core_init (self->gomx, self->omx_library, self->omx_component); > + g_omx_core_init (self->gomx); > > if (self->gomx->omx_error) > return FALSE; > @@ -468,16 +457,6 @@ type_instance_init (GTypeInstance *instance, > } > > { > - const char *tmp; > - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), > - g_quark_from_static_string ("library-name")); > - self->omx_library = g_strdup (tmp); > - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), > - g_quark_from_static_string ("component-name")); > - self->omx_component = g_strdup (tmp); > - } > - > - { > GstPad *sinkpad; > self->sinkpad = sinkpad = GST_BASE_SINK_PAD (self); > self->base_activatepush = GST_PAD_ACTIVATEPUSHFUNC (sinkpad); > diff --git a/omx/gstomx_base_sink.h b/omx/gstomx_base_sink.h > index 681e939..589c441 100644 > --- a/omx/gstomx_base_sink.h > +++ b/omx/gstomx_base_sink.h > @@ -46,9 +46,6 @@ struct GstOmxBaseSink > GOmxCore *gomx; > GOmxPort *in_port; > > - char *omx_component; > - char *omx_library; > - > gboolean ready; > GstPadActivateModeFunction base_activatepush; > gboolean initialized; > diff --git a/omx/gstomx_base_src.c b/omx/gstomx_base_src.c > index 9b02b22..dd9767e 100644 > --- a/omx/gstomx_base_src.c > +++ b/omx/gstomx_base_src.c > @@ -67,7 +67,7 @@ start (GstBaseSrc *gst_base) > > GST_LOG_OBJECT (self, "begin"); > > - g_omx_core_init (self->gomx, self->omx_library, self->omx_component); > + g_omx_core_init (self->gomx); > if (self->gomx->omx_error) > return GST_STATE_CHANGE_FAILURE; > > @@ -106,9 +106,6 @@ finalize (GObject *obj) > > g_omx_core_free (self->gomx); > > - g_free (self->omx_component); > - g_free (self->omx_library); > - > G_OBJECT_CLASS (parent_class)->finalize (obj); > } > > @@ -362,20 +359,6 @@ set_property (GObject *obj, > > switch (prop_id) > { > - case ARG_COMPONENT_NAME: > - if (self->omx_component) > - { > - g_free (self->omx_component); > - } > - self->omx_component = g_value_dup_string (value); > - break; > - case ARG_LIBRARY_NAME: > - if (self->omx_library) > - { > - g_free (self->omx_library); > - } > - self->omx_library = g_value_dup_string (value); > - break; > default: > G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); > break; > @@ -395,10 +378,10 @@ get_property (GObject *obj, > switch (prop_id) > { > case ARG_COMPONENT_NAME: > - g_value_set_string (value, self->omx_component); > + g_omx_get_component_name_value (self, value); > break; > case ARG_LIBRARY_NAME: > - g_value_set_string (value, self->omx_library); > + g_omx_get_library_name_value (self, value); > break; > default: > G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); > @@ -433,12 +416,12 @@ type_class_init (gpointer g_class, > g_object_class_install_property (gobject_class, ARG_COMPONENT_NAME, > g_param_spec_string ("component-name", "Component name", > "Name of the OpenMAX IL component to use", > - NULL, G_PARAM_READWRITE)); > + NULL, G_PARAM_READABLE)); > > g_object_class_install_property (gobject_class, ARG_LIBRARY_NAME, > g_param_spec_string ("library-name", "Library name", > "Name of the OpenMAX IL implementation library to use", > - NULL, G_PARAM_READWRITE)); > + NULL, G_PARAM_READABLE)); > } > } > > @@ -459,17 +442,6 @@ type_instance_init (GTypeInstance *instance, > gomx->object = self; > } > > - { > - const char *tmp; > - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), > - g_quark_from_static_string ("library-name")); > - self->omx_library = g_strdup (tmp); > - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), > - g_quark_from_static_string ("component-name")); > - self->omx_component = g_strdup (tmp); > - } > - > - > GST_LOG_OBJECT (self, "end"); > } > > diff --git a/omx/gstomx_base_src.h b/omx/gstomx_base_src.h > index 85e4c13..adab894 100644 > --- a/omx/gstomx_base_src.h > +++ b/omx/gstomx_base_src.h > @@ -44,8 +44,6 @@ struct GstOmxBaseSrc > GOmxCore *gomx; > GOmxPort *out_port; > > - char *omx_component; > - char *omx_library; > GstOmxBaseSrcCb setup_ports; > }; > > diff --git a/omx/gstomx_util.c b/omx/gstomx_util.c > index 39d900b..c429738 100644 > --- a/omx/gstomx_util.c > +++ b/omx/gstomx_util.c > @@ -301,10 +301,13 @@ g_omx_core_free (GOmxCore *core) > } > > void > -g_omx_core_init (GOmxCore *core, > - const gchar *library_name, > - const gchar *component_name) > +g_omx_core_init (GOmxCore *core) > { > + gchar *library_name, *component_name; > + > + g_assert (g_omx_get_component_info (core->object, > + &library_name, &component_name)); > + > core->imp = request_imp (library_name); > > if (!core->imp) > diff --git a/omx/gstomx_util.h b/omx/gstomx_util.h > index f0cf045..c3ac441 100644 > --- a/omx/gstomx_util.h > +++ b/omx/gstomx_util.h > @@ -116,7 +116,7 @@ void g_omx_deinit (void); > > GOmxCore *g_omx_core_new (void); > void g_omx_core_free (GOmxCore *core); > -void g_omx_core_init (GOmxCore *core, const gchar *library_name, const gchar *component_name); > +void g_omx_core_init (GOmxCore *core); > void g_omx_core_deinit (GOmxCore *core); > void g_omx_core_prepare (GOmxCore *core); > void g_omx_core_start (GOmxCore *core); > -- > 1.6.3.2 Cheers. -- Felipe Contreras |
From: Clark, R. <ro...@ti...> - 2010-02-26 14:14:17
|
On Feb 26, 2010, at 6:05 AM, Felipe Contreras wrote: > 3) The configuration location should be obtained with > g_get_user_config_dir() ($HOME/.config) What do you think about leaving this as-is, but submitting a patch to gstreamer to add API to get the gst registry directory (gst_get_registry_dir() or something like that?), and later changing to using that? I'm wondering if the config file makes more sense to be located along side gst registry.. Thoughts? BR, -R |
From: Felipe C. <fel...@gm...> - 2010-02-26 22:01:06
|
On Fri, Feb 26, 2010 at 4:14 PM, Clark, Rob <ro...@ti...> wrote: > > On Feb 26, 2010, at 6:05 AM, Felipe Contreras wrote: > >> 3) The configuration location should be obtained with >> g_get_user_config_dir() ($HOME/.config) > > > What do you think about leaving this as-is, but submitting a patch to gstreamer to add API to get the gst registry directory (gst_get_registry_dir() or something like that?), and later changing to using that? > > I'm wondering if the config file makes more sense to be located along side gst registry.. The problem I have with this approach is that GStreamer registry is fundamentally different; it's not something the user is supposed to change. In fact, the proper location of the registry should probably be ~/.cache/gstreamer-0.10 (through g_get_user_cache_dir()). So if we use use gst_get_registry_dir() the conf might end up in ~/.cache, and I don't think that's good. In fact, I think the user should be able to configure the rank of gstreamer elements (not gst-omx). And if such thing gets ever implemented the configuration would probably be in ~/.config. Until there's a gst_get_config_dir(), I think it's best to follow my proposal. Cheers. -- Felipe Contreras |
From: Stefan K. <en...@ho...> - 2010-02-27 19:39:31
|
Am 27.02.2010 00:00, schrieb Felipe Contreras: > On Fri, Feb 26, 2010 at 4:14 PM, Clark, Rob <ro...@ti...> wrote: >> >> On Feb 26, 2010, at 6:05 AM, Felipe Contreras wrote: >> >>> 3) The configuration location should be obtained with >>> g_get_user_config_dir() ($HOME/.config) >> >> >> What do you think about leaving this as-is, but submitting a patch to gstreamer to add API to get the gst registry directory (gst_get_registry_dir() or something like that?), and later changing to using that? >> >> I'm wondering if the config file makes more sense to be located along side gst registry.. > > The problem I have with this approach is that GStreamer registry is > fundamentally different; it's not something the user is supposed to > change. > > In fact, the proper location of the registry should probably be > ~/.cache/gstreamer-0.10 (through g_get_user_cache_dir()). So if we use > use gst_get_registry_dir() the conf might end up in ~/.cache, and I > don't think that's good. regarding the xdg use in gst: https://bugzilla.gnome.org/show_bug.cgi?id=518597 but +1 regarding your comment, just use g_get_user_config_dir() > > In fact, I think the user should be able to configure the rank of > gstreamer elements (not gst-omx). And if such thing gets ever > implemented the configuration would probably be in ~/.config. Until > there's a gst_get_config_dir(), I think it's best to follow my > proposal. Yep, that would be nice to have and it could probably be done simillar to this patch. Then some one could write a UI for that. That could work better than the gconf elements. Stefan > > Cheers. > |
From: Tim-Philipp M. <t....@ze...> - 2010-02-26 13:13:08
|
On Fri, 2010-02-26 at 14:05 +0200, Felipe Contreras wrote: > > +#ifndef DIM /* XXX is there a better alternative available? */ > > +# define DIM(x) (sizeof(x)/sizeof((x)[0])) > > +#endif > > Let's call it ARRAY_SIZE (just like in the kernel). Maybe there's > something in GLib for that (can't recall though), but I like > ARRAY_SIZE :) GLib macro is G_N_ELEMENTS, fwiw. Cheers -Tim |
From: Clark, R. <ro...@ti...> - 2010-02-26 13:15:06
|
On Feb 26, 2010, at 6:05 AM, Felipe Contreras wrote: > On Thu, Feb 25, 2010 at 3:56 AM, Rob Clark <ro...@ti...> wrote: >> 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. For example: > > In general the patch looks ok, but: > > 1) I don't like this new class creation, probably the only reason it's > needed is because the library-name and component-name are set in the > GType, which is not needed. We can set these into the element itself > without modifying the original GType. We can set them as properties on the GstElement, but we still need some way to differentiate when the same element is used for two different OMX components in order to set the correct property values.. we can use the name property on the element, because this can be set to anything by the user (and at a minimum, would end up something like "omx_dummy0") I originally tried without creating new classes, but ran into this problem in the case that we had two different elements with same GType but different OMX components. So I don't see any better solution. > > 2) gstomx_conf.c looks a bit tricky, I was thinking on a plain text > file, just like gst-openmax.conf. I guess the .c file is ok for now, > but I don't like this tricky Makefile rule, let's just have a > gstomx_conf.c instead. I think we need something that ends up as a .c file, for the #ifndef EXPERIMENTAL stuff.. and also so we have some default config embedded in libgstomx.so. That said, it could be a plain gstomx_conf.c file.. I just thought the plain text .conf file generating the .c file was easier to edit. But I can change it back to plain .c file if you don't like my clever makefile rule ;-) > > 3) The configuration location should be obtained with > g_get_user_config_dir() ($HOME/.config) ok, I can change this, and address the other minor comments and re-submit BR, -R > > Also, a few minor comments below. > >> ---- >> omx_mp3dec_ti, >> type=GstOmxMp3Dec, >> library-name=libOMX_Core.so.0, >> component-name=OMX.TI.AUDIO.DECODE, >> component-role=audio_decode.dsp.mp3, >> rank=256; >> >> omx_mp3dec_nokia, >> type=GstOmxMp3Dec, >> library-name=libomxil_bellagio.so.0, >> component-name=OMX.nokia.audio_decode.mp3, >> rank=128; >> ---- >> >> by default, the config file is stored in $HOME/.gstreamer-0.10/gst-openmax.conf, although if none is found a default config will be created. >> --- >> configure.ac | 3 + >> omx/Makefile.am | 9 +- >> omx/gstomx.c | 353 ++++++++++++++++++++++++++++++++++++++-------- >> omx/gstomx.conf | 216 ++++++++++++++++++++++++++++ >> omx/gstomx.h | 12 ++ >> omx/gstomx_base_filter.c | 31 +---- >> omx/gstomx_base_filter.h | 2 - >> omx/gstomx_base_sink.c | 31 +---- >> omx/gstomx_base_sink.h | 3 - >> omx/gstomx_base_src.c | 38 +----- >> omx/gstomx_base_src.h | 2 - >> omx/gstomx_util.c | 9 +- >> omx/gstomx_util.h | 2 +- >> 13 files changed, 553 insertions(+), 158 deletions(-) >> create mode 100644 omx/gstomx.conf >> >> diff --git a/configure.ac b/configure.ac >> index 22dcf7d..3d7df3f 100644 >> --- a/configure.ac >> +++ b/configure.ac >> @@ -11,6 +11,9 @@ dnl versions of GStreamer >> GST_MAJORMINOR=0.10 >> GST_REQUIRED=0.10.0 >> >> +AC_DEFINE_UNQUOTED(GST_MAJORMINOR, "$GST_MAJORMINOR", >> + [library major.minor version]) >> + >> dnl AM_MAINTAINER_MODE provides the option to enable maintainer mode >> AM_MAINTAINER_MODE >> >> diff --git a/omx/Makefile.am b/omx/Makefile.am >> index 4a3fbf9..1bb9901 100644 >> --- a/omx/Makefile.am >> +++ b/omx/Makefile.am >> @@ -18,7 +18,8 @@ libgstomx_la_SOURCES = gstomx.c gstomx.h \ >> gstomx_vorbisdec.c gstomx_vorbisdec.h \ >> gstomx_mp3dec.c gstomx_mp3dec.h \ >> gstomx_base_sink.c gstomx_base_sink.h \ >> - gstomx_audiosink.c gstomx_audiosink.h >> + gstomx_audiosink.c gstomx_audiosink.h \ >> + gstomx_conf.c >> >> if EXPERIMENTAL >> libgstomx_la_SOURCES += gstomx_amrnbdec.c gstomx_amrnbdec.h \ >> @@ -47,3 +48,9 @@ libgstomx_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) $(top_builddir)/util/libutil. >> libgstomx_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) >> >> EXTRA_DIST = headers >> + >> +gstomx_conf.c: gstomx.conf >> + echo "const char * default_config =" > $@ >> + cat $^ | $(CPP) $(CFLAGS) $(libgstomx_la_CFLAGS) $(DEFAULT_INCLUDES) $(INCLUDES) - | grep -v "^#" | sed 's/^.*/\"&\\\n"/' >> $@ >> + echo ";" >> $@ >> + >> diff --git a/omx/gstomx.c b/omx/gstomx.c >> index 6756f54..ae80813 100644 >> --- a/omx/gstomx.c >> +++ b/omx/gstomx.c >> @@ -19,8 +19,12 @@ >> * >> */ >> >> +#include <string.h> >> + >> #include "config.h" >> >> +#include <gst/gststructure.h> >> + >> #include "gstomx.h" >> #include "gstomx_dummy.h" >> #include "gstomx_mpeg4dec.h" >> @@ -59,90 +63,317 @@ >> >> 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; >> + >> +extern const gchar *default_config; >> + >> +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, >> }; >> >> + > > Unnecessary extra space. > >> +/* 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_REGISTRY")); >> + if (!path) >> + { >> + path = g_build_filename (g_get_home_dir (), >> + ".gstreamer-" GST_MAJORMINOR, "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_file_set_contents (path, config, -1, NULL); >> + } >> + >> + 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); >> + } >> + >> + g_free (path); >> + >> + 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; >> + >> + g_assert (gst_structure_get (element_table, >> + element_name, GST_TYPE_STRUCTURE, &element, NULL)); >> + >> + return element; >> +} >> + >> +static const gchar * >> +get_element_name (gpointer object) >> +{ >> + return g_type_name (G_OBJECT_TYPE (object)); >> +} >> + >> + > > Unnecessary extra space. > >> +/* register a new dynamic sub-class with the omx element as it's 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 type, const gchar *element_name) >> +{ >> + GTypeQuery q; >> + GTypeInfo i; >> + >> + g_type_query (type, &q); >> + >> + bzero (&i, sizeof (i)); > > bzero is deprecated in POSIX; memset should be used instead. > > Even better would be to set any field of i, the compiler would then > zero the rest of the structure (C spec). > >> + i.class_size = q.class_size; >> + i.instance_size = q.instance_size; >> + >> + return g_type_register_static (type, element_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"); >> + /* first, call all the _get_type() functions to ensure the types are >> + * registered: >> + */ >> + for (i = 0; i < DIM (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++) >> + const gchar *element_name = gst_structure_nth_field_name (element_table, i); >> + GstStructure *element = get_element_entry (element_name); >> + const gchar *type_name; >> + GType type; >> + gint rank; >> + >> + GST_DEBUG ("element=%"GST_PTR_FORMAT, element); >> + >> + type_name = gst_structure_get_string (element, "type"); >> + if (!type_name) >> + { >> + g_warning ("malformed config file: missing 'type' for %s", element_name); >> + return FALSE; >> + } >> + >> + 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; >> + } >> + >> + type = create_subtype (type, element_name); >> + >> + if (!gst_structure_get_int (element, "rank", &rank)) >> { >> - TableItem *element; >> - GType type; >> - >> - 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); >> - >> - if (!gst_element_register (plugin, element->name, element->rank, type)) >> - { >> - g_warning ("failed registering '%s'", element->name); >> - return FALSE; >> - } >> + /* 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; >> } >> >> +/** >> + * g_omx_get_component_info: >> + * @object: the GstOmx object (ie. GstOmxBaseFilter, GstOmxBaseSrc, or >> + * GstOmxBaseSink). >> + * @library_name: library-name, returned by reference (or NULL) >> + * @component_name: component-name, returned by reference (or NULL) >> + * >> + * Get library-name and component-name for an element. >> + * >> + * note: this function will gain another parameter later when component-role >> + * is added >> + */ >> +gboolean >> +g_omx_get_component_info (gpointer object, >> + gchar **library_name, >> + gchar **component_name) >> +{ >> + gboolean ret = TRUE; >> + const gchar *element_name = get_element_name (object); >> + GstStructure *element = get_element_entry (element_name); >> + >> + g_assert (gst_structure_get (element_table, >> + element_name, GST_TYPE_STRUCTURE, &element, NULL)); >> + >> + /* initialize ptrs to NULL so that in error cases we can tell what needs >> + * to be freed: >> + */ >> + if (library_name) *library_name = NULL; >> + if (component_name) *component_name = NULL; >> + >> + if (library_name) >> + { >> + const gchar *str = gst_structure_get_string (element, "library-name"); >> + if (!str) >> + { >> + g_warning ("malformed config file: missing 'library-name' for %s", element_name); >> + ret = FALSE; >> + goto beach; >> + } >> + *library_name = g_strdup (str); >> + } >> + >> + if (component_name) >> + { >> + const gchar *str = gst_structure_get_string (element, "component-name"); >> + if (!str) >> + { >> + g_warning ("malformed config file: missing 'component-name' for %s", element_name); >> + ret = FALSE; >> + goto beach; >> + } >> + *component_name = g_strdup (str); >> + } >> + >> +beach: > > Let's not follow bad gst practiced :) let's call this "leave", or > something meaningful. > >> + >> + /* if we failed, free any memory that might have been allocated: >> + */ >> + if (!ret) >> + { >> + if (library_name) g_free (*library_name); >> + if (component_name) g_free (*component_name); >> + } >> + >> + >> + return ret; >> +} >> + >> +static gboolean >> +set_value_helper (GValue *value, gchar *str) >> +{ >> + g_value_set_string (value, str); >> + return TRUE; >> +} >> + >> +/** >> + * g_omx_get_library_name_value: >> + * @object: the GstOmx object (ie. GstOmxBaseFilter, GstOmxBaseSrc, or >> + * GstOmxBaseSink). >> + * @val: the GValue to return the value through >> + * >> + * A helper to access the "library-name" as a GValue, mainly for >> + * get_property methods. >> + */ >> +gboolean >> +g_omx_get_library_name_value (gpointer object, GValue *val) >> +{ >> + gchar *str; >> + return g_omx_get_component_info (object, &str, NULL) && >> + set_value_helper (val, str); >> +} >> + >> +/** >> + * g_omx_get_component_name_value: >> + * @object: the GstOmx object (ie. GstOmxBaseFilter, GstOmxBaseSrc, or >> + * GstOmxBaseSink). >> + * @val: the GValue to return the value through >> + * >> + * A helper to access the "component-name" as a GValue, mainly for >> + * get_property methods. >> + */ >> +gboolean >> +g_omx_get_component_name_value (gpointer object, GValue *val) >> +{ >> + gchar *str; >> + return g_omx_get_component_info (object, NULL, &str) && >> + set_value_helper (val, str); >> +} >> + >> + > > Unnecessary extra space. This is done in a bunch of other places =/ > >> GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, >> GST_VERSION_MINOR, >> "omx", >> diff --git a/omx/gstomx.conf b/omx/gstomx.conf >> new file mode 100644 >> index 0000000..6a88dc1 >> --- /dev/null >> +++ b/omx/gstomx.conf >> @@ -0,0 +1,216 @@ >> +/* >> + * Copyright (C) 2010 Texas Instruments, Incorporated >> + * Copyright (C) 2007-2010 Nokia Corporation. >> + * >> + * This library is free software; you can redistribute it and/or >> + * modify it under the terms of the GNU Lesser General Public >> + * License as published by the Free Software Foundation >> + * version 2.1 of the License. >> + * >> + * This library is distributed in the hope that it will be useful, >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> + * Lesser General Public License for more details. >> + * >> + * You should have received a copy of the GNU Lesser General Public >> + * License along with this library; if not, write to the Free Software >> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA >> + * >> + */ >> + >> +#include "config.h" >> + >> +omx_dummy, >> + type=GstOmxDummy, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.dummy, >> + rank=0; >> + >> +/* for testing: */ >> +omx_dummy_2, >> + type=GstOmxDummy, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.dummy2, >> + rank=256; >> + >> +omx_mpeg4dec, >> + type=GstOmxMpeg4Dec, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.video_decoder.mpeg4, >> + rank=256; >> + >> +omx_h264dec, >> + type=GstOmxH264Dec, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.video_decoder.avc, >> + rank=256; >> + >> +omx_h263dec, >> + type=GstOmxH263Dec, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.video_decoder.h263, >> + rank=256; >> + >> +omx_wmvdec, >> + type=GstOmxWmvDec, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.video_decoder.wmv, >> + rank=256; >> + >> +omx_mpeg4enc, >> + type=GstOmxMpeg4Enc, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.video_encoder.mpeg4, >> + rank=256; >> + >> +omx_h264enc, >> + type=GstOmxH264Enc, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.video_encoder.avc, >> + rank=256; >> + >> +omx_h263enc, >> + type=GstOmxH263Enc, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.video_encoder.h263, >> + rank=256; >> + >> +omx_vorbisdec, >> + type=GstOmxVorbisDec, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.audio_decoder.ogg.single, >> + rank=128; >> + >> +omx_mp3dec, >> + type=GstOmxMp3Dec, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.audio_decoder.mp3.mad, >> + rank=256; >> + >> +#ifdef EXPERIMENTAL >> + >> +omx_mp2dec, >> + type=GstOmxMp2Dec, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.audio_decoder.mp3.mad, >> + rank=256; >> + >> +omx_amrnbdec, >> + type=GstOmxAmrNbDec, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.audio_decoder.amrnb, >> + rank=256; >> + >> +omx_amrnbenc, >> + type=GstOmxAmrNbEnc, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.audio_encoder.amrnb, >> + rank=256; >> + >> +omx_amrwbdec, >> + type=GstOmxAmrWbDec, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.audio_decoder.amrwb, >> + rank=256; >> + >> +omx_amrwbenc, >> + type=GstOmxAmrWbEnc, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.audio_encoder.amrwb, >> + rank=256; >> + >> +omx_aacdec, >> + type=GstOmxAacDec, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.audio_decoder.aac, >> + rank=256; >> + >> +omx_aacenc, >> + type=GstOmxAacEnc, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.audio_encoder.aac, >> + rank=256; >> + >> +omx_adpcmdec, >> + type=GstOmxAdpcmDec, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.audio_decoder.adpcm, >> + rank=256; >> + >> +omx_adpcmenc, >> + type=GstOmxAdpcmEnc, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.audio_encoder.adpcm, >> + rank=256; >> + >> +omx_g711dec, >> + type=GstOmxG711Dec, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.audio_decoder.g711, >> + rank=256; >> + >> +omx_g711enc, >> + type=GstOmxG711Enc, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.audio_encoder.g711, >> + rank=256; >> + >> +omx_g729dec, >> + type=GstOmxG729Dec, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.audio_decoder.g729, >> + rank=256; >> + >> +omx_g729enc, >> + type=GstOmxG729Enc, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.audio_encoder.g729, >> + rank=256; >> + >> +omx_ilbcdec, >> + type=GstOmxIlbcDec, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.audio_decoder.ilbc, >> + rank=256; >> + >> +omx_ilbcenc, >> + type=GstOmxIlbcEnc, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.audio_encoder.ilbc, >> + rank=256; >> + >> +omx_jpegenc, >> + type=GstOmxJpegEnc, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.image_encoder.jpeg, >> + rank=256; >> + >> +#endif /* EXPERIMENTAL */ >> + >> +omx_audiosink, >> + type=GstOmxAudioSink, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.alsa.alsasink, >> + rank=0; >> + >> +#ifdef EXPERIMENTAL >> + >> +omx_videosink, >> + type=GstOmxVideoSink, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.videosink, >> + rank=0; >> + >> +omx_filereadersrc, >> + type=GstOmxFilereaderSrc, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.audio_filereader, >> + rank=0; >> + >> +#endif /* EXPERIMENTAL */ >> + >> +omx_volume, >> + type=GstOmxVolume, >> + library-name=libomxil-bellagio.so.0, >> + component-name=OMX.st.volume.component, >> + rank=0; >> diff --git a/omx/gstomx.h b/omx/gstomx.h >> index 7d5fa04..0d362d7 100644 >> --- a/omx/gstomx.h >> +++ b/omx/gstomx.h >> @@ -30,6 +30,18 @@ GST_DEBUG_CATEGORY_EXTERN (gstomx_debug); >> GST_DEBUG_CATEGORY_EXTERN (gstomx_util_debug); >> #define GST_CAT_DEFAULT gstomx_debug >> >> +#ifndef DIM /* XXX is there a better alternative available? */ >> +# define DIM(x) (sizeof(x)/sizeof((x)[0])) >> +#endif > > Let's call it ARRAY_SIZE (just like in the kernel). Maybe there's > something in GLib for that (can't recall though), but I like > ARRAY_SIZE :) > >> + >> + >> +gboolean g_omx_get_component_info (gpointer object, >> + gchar **library_name, >> + gchar **component_name); >> +gboolean g_omx_get_library_name_value (gpointer object, GValue *val); >> +gboolean g_omx_get_component_name_value (gpointer object, GValue *val); >> + >> + >> G_END_DECLS >> >> #endif /* GSTOMX_H */ >> diff --git a/omx/gstomx_base_filter.c b/omx/gstomx_base_filter.c >> index b0353cb..2a30502 100644 >> --- a/omx/gstomx_base_filter.c >> +++ b/omx/gstomx_base_filter.c >> @@ -115,7 +115,7 @@ change_state (GstElement *element, >> switch (transition) >> { >> case GST_STATE_CHANGE_NULL_TO_READY: >> - g_omx_core_init (core, self->omx_library, self->omx_component); >> + g_omx_core_init (core); >> if (core->omx_state != OMX_StateLoaded) >> { >> ret = GST_STATE_CHANGE_FAILURE; >> @@ -184,9 +184,6 @@ finalize (GObject *obj) >> >> g_omx_core_free (self->gomx); >> >> - g_free (self->omx_component); >> - g_free (self->omx_library); >> - >> g_mutex_free (self->ready_lock); >> >> G_OBJECT_CLASS (parent_class)->finalize (obj); >> @@ -204,14 +201,6 @@ set_property (GObject *obj, >> >> switch (prop_id) >> { >> - case ARG_COMPONENT_NAME: >> - g_free (self->omx_component); >> - self->omx_component = g_value_dup_string (value); >> - break; >> - case ARG_LIBRARY_NAME: >> - g_free (self->omx_library); >> - self->omx_library = g_value_dup_string (value); >> - break; >> case ARG_USE_TIMESTAMPS: >> self->use_timestamps = g_value_get_boolean (value); >> break; >> @@ -234,10 +223,10 @@ get_property (GObject *obj, >> switch (prop_id) >> { >> case ARG_COMPONENT_NAME: >> - g_value_set_string (value, self->omx_component); >> + g_omx_get_component_name_value (self, value); >> break; >> case ARG_LIBRARY_NAME: >> - g_value_set_string (value, self->omx_library); >> + g_omx_get_library_name_value (self, value); >> break; >> case ARG_USE_TIMESTAMPS: >> g_value_set_boolean (value, self->use_timestamps); >> @@ -271,12 +260,12 @@ type_class_init (gpointer g_class, >> g_object_class_install_property (gobject_class, ARG_COMPONENT_NAME, >> g_param_spec_string ("component-name", "Component name", >> "Name of the OpenMAX IL component to use", >> - NULL, G_PARAM_READWRITE)); >> + NULL, G_PARAM_READABLE)); >> >> g_object_class_install_property (gobject_class, ARG_LIBRARY_NAME, >> g_param_spec_string ("library-name", "Library name", >> "Name of the OpenMAX IL implementation library to use", >> - NULL, G_PARAM_READWRITE)); >> + NULL, G_PARAM_READABLE)); >> >> g_object_class_install_property (gobject_class, ARG_USE_TIMESTAMPS, >> g_param_spec_boolean ("use-timestamps", "Use timestamps", >> @@ -922,16 +911,6 @@ type_instance_init (GTypeInstance *instance, >> gst_element_add_pad (GST_ELEMENT (self), self->sinkpad); >> gst_element_add_pad (GST_ELEMENT (self), self->srcpad); >> >> - { >> - const char *tmp; >> - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), >> - g_quark_from_static_string ("library-name")); >> - self->omx_library = g_strdup (tmp); >> - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), >> - g_quark_from_static_string ("component-name")); >> - self->omx_component = g_strdup (tmp); >> - } >> - >> GST_LOG_OBJECT (self, "end"); >> } >> >> diff --git a/omx/gstomx_base_filter.h b/omx/gstomx_base_filter.h >> index 4baf181..99b5d72 100644 >> --- a/omx/gstomx_base_filter.h >> +++ b/omx/gstomx_base_filter.h >> @@ -48,8 +48,6 @@ struct GstOmxBaseFilter >> GOmxPort *in_port; >> GOmxPort *out_port; >> >> - char *omx_component; >> - char *omx_library; >> gboolean use_timestamps; /** @todo remove; timestamps should always be used */ >> gboolean ready; >> GMutex *ready_lock; >> diff --git a/omx/gstomx_base_sink.c b/omx/gstomx_base_sink.c >> index c1a2076..7911167 100644 >> --- a/omx/gstomx_base_sink.c >> +++ b/omx/gstomx_base_sink.c >> @@ -141,9 +141,6 @@ finalize (GObject *obj) >> >> g_omx_core_free (self->gomx); >> >> - g_free (self->omx_component); >> - g_free (self->omx_library); >> - >> G_OBJECT_CLASS (parent_class)->finalize (obj); >> } >> >> @@ -298,14 +295,6 @@ set_property (GObject *obj, >> >> switch (prop_id) >> { >> - case ARG_COMPONENT_NAME: >> - g_free (self->omx_component); >> - self->omx_component = g_value_dup_string (value); >> - break; >> - case ARG_LIBRARY_NAME: >> - g_free (self->omx_library); >> - self->omx_library = g_value_dup_string (value); >> - break; >> default: >> G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); >> break; >> @@ -325,10 +314,10 @@ get_property (GObject *obj, >> switch (prop_id) >> { >> case ARG_COMPONENT_NAME: >> - g_value_set_string (value, self->omx_component); >> + g_omx_get_component_name_value (self, value); >> break; >> case ARG_LIBRARY_NAME: >> - g_value_set_string (value, self->omx_library); >> + g_omx_get_library_name_value (self, value); >> break; >> default: >> G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); >> @@ -366,12 +355,12 @@ type_class_init (gpointer g_class, >> g_object_class_install_property (gobject_class, ARG_COMPONENT_NAME, >> g_param_spec_string ("component-name", "Component name", >> "Name of the OpenMAX IL component to use", >> - NULL, G_PARAM_READWRITE)); >> + NULL, G_PARAM_READABLE)); >> >> g_object_class_install_property (gobject_class, ARG_LIBRARY_NAME, >> g_param_spec_string ("library-name", "Library name", >> "Name of the OpenMAX IL implementation library to use", >> - NULL, G_PARAM_READWRITE)); >> + NULL, G_PARAM_READABLE)); >> } >> } >> >> @@ -420,7 +409,7 @@ activate_push (GstPad *pad, >> static inline gboolean >> omx_init (GstOmxBaseSink *self) >> { >> - g_omx_core_init (self->gomx, self->omx_library, self->omx_component); >> + g_omx_core_init (self->gomx); >> >> if (self->gomx->omx_error) >> return FALSE; >> @@ -468,16 +457,6 @@ type_instance_init (GTypeInstance *instance, >> } >> >> { >> - const char *tmp; >> - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), >> - g_quark_from_static_string ("library-name")); >> - self->omx_library = g_strdup (tmp); >> - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), >> - g_quark_from_static_string ("component-name")); >> - self->omx_component = g_strdup (tmp); >> - } >> - >> - { >> GstPad *sinkpad; >> self->sinkpad = sinkpad = GST_BASE_SINK_PAD (self); >> self->base_activatepush = GST_PAD_ACTIVATEPUSHFUNC (sinkpad); >> diff --git a/omx/gstomx_base_sink.h b/omx/gstomx_base_sink.h >> index 681e939..589c441 100644 >> --- a/omx/gstomx_base_sink.h >> +++ b/omx/gstomx_base_sink.h >> @@ -46,9 +46,6 @@ struct GstOmxBaseSink >> GOmxCore *gomx; >> GOmxPort *in_port; >> >> - char *omx_component; >> - char *omx_library; >> - >> gboolean ready; >> GstPadActivateModeFunction base_activatepush; >> gboolean initialized; >> diff --git a/omx/gstomx_base_src.c b/omx/gstomx_base_src.c >> index 9b02b22..dd9767e 100644 >> --- a/omx/gstomx_base_src.c >> +++ b/omx/gstomx_base_src.c >> @@ -67,7 +67,7 @@ start (GstBaseSrc *gst_base) >> >> GST_LOG_OBJECT (self, "begin"); >> >> - g_omx_core_init (self->gomx, self->omx_library, self->omx_component); >> + g_omx_core_init (self->gomx); >> if (self->gomx->omx_error) >> return GST_STATE_CHANGE_FAILURE; >> >> @@ -106,9 +106,6 @@ finalize (GObject *obj) >> >> g_omx_core_free (self->gomx); >> >> - g_free (self->omx_component); >> - g_free (self->omx_library); >> - >> G_OBJECT_CLASS (parent_class)->finalize (obj); >> } >> >> @@ -362,20 +359,6 @@ set_property (GObject *obj, >> >> switch (prop_id) >> { >> - case ARG_COMPONENT_NAME: >> - if (self->omx_component) >> - { >> - g_free (self->omx_component); >> - } >> - self->omx_component = g_value_dup_string (value); >> - break; >> - case ARG_LIBRARY_NAME: >> - if (self->omx_library) >> - { >> - g_free (self->omx_library); >> - } >> - self->omx_library = g_value_dup_string (value); >> - break; >> default: >> G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); >> break; >> @@ -395,10 +378,10 @@ get_property (GObject *obj, >> switch (prop_id) >> { >> case ARG_COMPONENT_NAME: >> - g_value_set_string (value, self->omx_component); >> + g_omx_get_component_name_value (self, value); >> break; >> case ARG_LIBRARY_NAME: >> - g_value_set_string (value, self->omx_library); >> + g_omx_get_library_name_value (self, value); >> break; >> default: >> G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); >> @@ -433,12 +416,12 @@ type_class_init (gpointer g_class, >> g_object_class_install_property (gobject_class, ARG_COMPONENT_NAME, >> g_param_spec_string ("component-name", "Component name", >> "Name of the OpenMAX IL component to use", >> - NULL, G_PARAM_READWRITE)); >> + NULL, G_PARAM_READABLE)); >> >> g_object_class_install_property (gobject_class, ARG_LIBRARY_NAME, >> g_param_spec_string ("library-name", "Library name", >> "Name of the OpenMAX IL implementation library to use", >> - NULL, G_PARAM_READWRITE)); >> + NULL, G_PARAM_READABLE)); >> } >> } >> >> @@ -459,17 +442,6 @@ type_instance_init (GTypeInstance *instance, >> gomx->object = self; >> } >> >> - { >> - const char *tmp; >> - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), >> - g_quark_from_static_string ("library-name")); >> - self->omx_library = g_strdup (tmp); >> - tmp = g_type_get_qdata (G_OBJECT_CLASS_TYPE (g_class), >> - g_quark_from_static_string ("component-name")); >> - self->omx_component = g_strdup (tmp); >> - } >> - >> - >> GST_LOG_OBJECT (self, "end"); >> } >> >> diff --git a/omx/gstomx_base_src.h b/omx/gstomx_base_src.h >> index 85e4c13..adab894 100644 >> --- a/omx/gstomx_base_src.h >> +++ b/omx/gstomx_base_src.h >> @@ -44,8 +44,6 @@ struct GstOmxBaseSrc >> GOmxCore *gomx; >> GOmxPort *out_port; >> >> - char *omx_component; >> - char *omx_library; >> GstOmxBaseSrcCb setup_ports; >> }; >> >> diff --git a/omx/gstomx_util.c b/omx/gstomx_util.c >> index 39d900b..c429738 100644 >> --- a/omx/gstomx_util.c >> +++ b/omx/gstomx_util.c >> @@ -301,10 +301,13 @@ g_omx_core_free (GOmxCore *core) >> } >> >> void >> -g_omx_core_init (GOmxCore *core, >> - const gchar *library_name, >> - const gchar *component_name) >> +g_omx_core_init (GOmxCore *core) >> { >> + gchar *library_name, *component_name; >> + >> + g_assert (g_omx_get_component_info (core->object, >> + &library_name, &component_name)); >> + >> core->imp = request_imp (library_name); >> >> if (!core->imp) >> diff --git a/omx/gstomx_util.h b/omx/gstomx_util.h >> index f0cf045..c3ac441 100644 >> --- a/omx/gstomx_util.h >> +++ b/omx/gstomx_util.h >> @@ -116,7 +116,7 @@ void g_omx_deinit (void); >> >> GOmxCore *g_omx_core_new (void); >> void g_omx_core_free (GOmxCore *core); >> -void g_omx_core_init (GOmxCore *core, const gchar *library_name, const gchar *component_name); >> +void g_omx_core_init (GOmxCore *core); >> void g_omx_core_deinit (GOmxCore *core); >> void g_omx_core_prepare (GOmxCore *core); >> void g_omx_core_start (GOmxCore *core); >> -- >> 1.6.3.2 > > Cheers. > > -- > Felipe Contreras |
From: Clark, R. <ro...@ti...> - 2010-02-26 14:01:16
|
On Feb 26, 2010, at 6:36 AM, Tim-Philipp Müller wrote: > On Fri, 2010-02-26 at 14:05 +0200, Felipe Contreras wrote: > >>> +#ifndef DIM /* XXX is there a better alternative available? */ >>> +# define DIM(x) (sizeof(x)/sizeof((x)[0])) >>> +#endif >> >> Let's call it ARRAY_SIZE (just like in the kernel). Maybe there's >> something in GLib for that (can't recall though), but I like >> ARRAY_SIZE :) > > GLib macro is G_N_ELEMENTS, fwiw. > ahh, brilliant.. I couldn't figure out what macro name to look for, and was hoping for someone to clue me in :-) BR, -R > Cheers > -Tim > > > > ------------------------------------------------------------------------------ > Download Intel® Parallel Studio Eval > Try the new software tools for yourself. Speed compiling, find bugs > proactively, and fine-tune applications for parallel performance. > See why Intel Parallel Studio got high marks during beta. > http://p.sf.net/sfu/intel-sw-dev > _______________________________________________ > Gstreamer-openmax mailing list > Gst...@li... > https://lists.sourceforge.net/lists/listinfo/gstreamer-openmax |
From: Felipe C. <fel...@gm...> - 2010-02-26 21:53:55
|
On Fri, Feb 26, 2010 at 3:33 PM, Clark, Rob <ro...@ti...> wrote: > On Feb 26, 2010, at 6:36 AM, Tim-Philipp Müller wrote: >> GLib macro is G_N_ELEMENTS, fwiw. > > ahh, brilliant.. I couldn't figure out what macro name to look for, and was hoping for someone to clue me in :-) Let's use that instead then. -- Felipe Contreras |
From: Felipe C. <fel...@gm...> - 2010-02-26 21:53:08
|
On Fri, Feb 26, 2010 at 3:15 PM, Clark, Rob <ro...@ti...> wrote: > > On Feb 26, 2010, at 6:05 AM, Felipe Contreras wrote: > >> On Thu, Feb 25, 2010 at 3:56 AM, Rob Clark <ro...@ti...> wrote: >>> 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. For example: >> >> In general the patch looks ok, but: >> >> 1) I don't like this new class creation, probably the only reason it's >> needed is because the library-name and component-name are set in the >> GType, which is not needed. We can set these into the element itself >> without modifying the original GType. > > > We can set them as properties on the GstElement, but we still need some way to differentiate when the same element is used for two different OMX components in order to set the correct property values.. we can use the name property on the element, because this can be set to anything by the user (and at a minimum, would end up something like "omx_dummy0") > > I originally tried without creating new classes, but ran into this problem in the case that we had two different elements with same GType but different OMX components. So I don't see any better solution. Yeah, now I see that it can be problematic. But I still don't like omx_dummy as a GType, I think the proper GType should also be specified on the config: GstOmxDummy. >> 2) gstomx_conf.c looks a bit tricky, I was thinking on a plain text >> file, just like gst-openmax.conf. I guess the .c file is ok for now, >> but I don't like this tricky Makefile rule, let's just have a >> gstomx_conf.c instead. > > I think we need something that ends up as a .c file, for the #ifndef EXPERIMENTAL stuff.. and also so we have some default config embedded in libgstomx.so. > > That said, it could be a plain gstomx_conf.c file.. I just thought the plain text .conf file generating the .c file was easier to edit. But I can change it back to plain .c file if you don't like my clever makefile rule ;-) Now that you show the plain .c file I understand why it's not nice to use that. I feel there must be a better way to handle this, but for now I think you original proposal is ok (except the license notice, which I think is overkill). -- Felipe Contreras |
From: Clark, R. <ro...@ti...> - 2010-02-26 22:03:33
|
On Feb 26, 2010, at 3:52 PM, Felipe Contreras wrote: > On Fri, Feb 26, 2010 at 3:15 PM, Clark, Rob <ro...@ti...> wrote: >> >> On Feb 26, 2010, at 6:05 AM, Felipe Contreras wrote: >> >>> On Thu, Feb 25, 2010 at 3:56 AM, Rob Clark <ro...@ti...> wrote: >>>> 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. For example: >>> >>> In general the patch looks ok, but: >>> >>> 1) I don't like this new class creation, probably the only reason it's >>> needed is because the library-name and component-name are set in the >>> GType, which is not needed. We can set these into the element itself >>> without modifying the original GType. >> >> >> We can set them as properties on the GstElement, but we still need some way to differentiate when the same element is used for two different OMX components in order to set the correct property values.. we can use the name property on the element, because this can be set to anything by the user (and at a minimum, would end up something like "omx_dummy0") >> >> I originally tried without creating new classes, but ran into this problem in the case that we had two different elements with same GType but different OMX components. So I don't see any better solution. > > Yeah, now I see that it can be problematic. But I still don't like > omx_dummy as a GType, I think the proper GType should also be > specified on the config: GstOmxDummy. so something like: ----- omx_dummy, type=GstOmxDummy, derived-type=GstOmxDummyOne, library-name=libomxil-bellagio.so, component-name=OMX.st.dummy, rank=0; omx_dummy_2, type=GstOmxDummy, derived-type=GstOmxDummyTwo, library-name=libomxil-bellagio.so, component-name=OMX.bellagio.dummy, rank=256; ----- it does make the config file more complex (one more thing to misconfigure), and then we need a bit more error handling, in case user specifies a type name that already exists.. so I'm not super-excited about that. Also, then we need an additional hash-table to map back to element name (or something like g_type_set_qdata()).. both is possible, but it makes the code slightly less simple. using the element name as the type name seems a simple solution to both. > >>> 2) gstomx_conf.c looks a bit tricky, I was thinking on a plain text >>> file, just like gst-openmax.conf. I guess the .c file is ok for now, >>> but I don't like this tricky Makefile rule, let's just have a >>> gstomx_conf.c instead. >> >> I think we need something that ends up as a .c file, for the #ifndef EXPERIMENTAL stuff.. and also so we have some default config embedded in libgstomx.so. >> >> That said, it could be a plain gstomx_conf.c file.. I just thought the plain text .conf file generating the .c file was easier to edit. But I can change it back to plain .c file if you don't like my clever makefile rule ;-) > > Now that you show the plain .c file I understand why it's not nice to > use that. I feel there must be a better way to handle this, but for > now I think you original proposal is ok (except the license notice, > which I think is overkill). ok, I can go back to original version of default config .conf file BR, -R > > -- > Felipe Contreras |