From 1316ad4d71faff4f878c304b06c80a3bccbf47e9 Mon Sep 17 00:00:00 2001 From: Zaheer Abbas Merali Date: Fri, 8 Feb 2008 18:22:08 +0000 Subject: sys/dvb/: Add URI Handler for dvb. Original commit message from CVS: * sys/dvb/Makefile.am: * sys/dvb/dvbbasebin.c: Add URI Handler for dvb. Re-order pad templates to workaround a bug in playbasebin. * sys/dvb/parsechannels.c: * sys/dvb/parsechannels.h: Add code to parse channels from zap-style channels.conf files. --- sys/dvb/Makefile.am | 6 +- sys/dvb/dvbbasebin.c | 77 ++++++++++++- sys/dvb/parsechannels.c | 297 ++++++++++++++++++++++++++++++++++++++++++++++++ sys/dvb/parsechannels.h | 31 +++++ 4 files changed, 405 insertions(+), 6 deletions(-) create mode 100644 sys/dvb/parsechannels.c create mode 100644 sys/dvb/parsechannels.h (limited to 'sys') diff --git a/sys/dvb/Makefile.am b/sys/dvb/Makefile.am index 1bcb099f..9453d446 100644 --- a/sys/dvb/Makefile.am +++ b/sys/dvb/Makefile.am @@ -14,7 +14,8 @@ libgstdvb_la_SOURCES = \ camapplication.c \ camresourcemanager.c \ camapplicationinfo.c \ - camconditionalaccess.c + camconditionalaccess.c \ + parsechannels.c libgstdvb_la_CFLAGS = $(GST_CFLAGS) libgstdvb_la_LIBADD = $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) @@ -32,5 +33,6 @@ noinst_HEADERS = \ camapplication.h \ camresourcemanager.h \ camapplicationinfo.h \ - camconditionalaccess.h + camconditionalaccess.h \ + parsechannels.h diff --git a/sys/dvb/dvbbasebin.c b/sys/dvb/dvbbasebin.c index 8f633e66..bc13eddb 100644 --- a/sys/dvb/dvbbasebin.c +++ b/sys/dvb/dvbbasebin.c @@ -28,6 +28,7 @@ #include #include #include "dvbbasebin.h" +#include "parsechannels.h" GST_DEBUG_CATEGORY_STATIC (dvb_base_bin_debug); #define GST_CAT_DEFAULT dvb_base_bin_debug @@ -121,6 +122,21 @@ static GstPad *dvb_base_bin_request_new_pad (GstElement * element, static void dvb_base_bin_release_pad (GstElement * element, GstPad * pad); static void dvb_base_bin_rebuild_filter (DvbBaseBin * dvbbasebin); +static void dvb_base_bin_uri_handler_init (gpointer g_iface, + gpointer iface_data); + +static void +dvb_base_bin_setup_interfaces (GType type) +{ + static const GInterfaceInfo urihandler_info = { + dvb_base_bin_uri_handler_init, + NULL, + NULL, + }; + + g_type_add_interface_static (type, GST_TYPE_URI_HANDLER, &urihandler_info); +} + static DvbBaseBinStream * dvb_base_bin_add_stream (DvbBaseBin * dvbbasebin, guint16 pid) { @@ -174,7 +190,8 @@ dvb_base_bin_get_program (DvbBaseBin * dvbbasebin, gint program_number) static guint signals [LAST_SIGNAL] = { 0 }; */ -GST_BOILERPLATE (DvbBaseBin, dvb_base_bin, GstBin, GST_TYPE_BIN); +GST_BOILERPLATE_FULL (DvbBaseBin, dvb_base_bin, GstBin, GST_TYPE_BIN, + dvb_base_bin_setup_interfaces); static void dvb_base_bin_base_init (gpointer klass) @@ -184,10 +201,10 @@ dvb_base_bin_base_init (gpointer klass) element_class->request_new_pad = dvb_base_bin_request_new_pad; element_class->release_pad = dvb_base_bin_release_pad; - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&src_template)); gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&program_template)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&src_template)); gst_element_class_set_details (element_class, &dvb_base_bin_details); } @@ -919,7 +936,6 @@ dvb_base_bin_pad_added_cb (GstElement * mpegtsparse, program->ghost = gst_ghost_pad_new (gst_pad_get_name (pad), pad); gst_pad_set_active (program->ghost, TRUE); gst_element_add_pad (GST_ELEMENT (dvbbasebin), program->ghost); - /* if the program has a pmt, activate it now, otherwise it will get activated * when there's a PMT */ if (!program->active && program->pmt_pid != G_MAXUINT16) @@ -944,6 +960,59 @@ dvb_base_bin_pad_removed_cb (GstElement * mpegtsparse, program->ghost = NULL; } +static guint +dvb_base_bin_uri_get_type (void) +{ + return GST_URI_SRC; +} + +static gchar ** +dvb_base_bin_uri_get_protocols (void) +{ + static gchar *protocols[] = { "dvb", NULL }; + + return protocols; +} + +static const gchar * +dvb_base_bin_uri_get_uri (GstURIHandler * handler) +{ + return "dvb://"; +} + +static gboolean +dvb_base_bin_uri_set_uri (GstURIHandler * handler, const gchar * uri) +{ + gboolean ret; + gchar *protocol; + DvbBaseBin *dvbbasebin = GST_DVB_BASE_BIN (handler); + + protocol = gst_uri_get_protocol (uri); + + if (strcmp (protocol, "dvb") != 0) { + ret = FALSE; + } else { + ret = set_properties_for_channel (G_OBJECT (dvbbasebin), + gst_uri_get_location (uri)); + } + + /* here is where we parse channels.conf */ + g_free (protocol); + + return ret; +} + +static void +dvb_base_bin_uri_handler_init (gpointer g_iface, gpointer iface_data) +{ + GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface; + + iface->get_type = dvb_base_bin_uri_get_type; + iface->get_protocols = dvb_base_bin_uri_get_protocols; + iface->get_uri = dvb_base_bin_uri_get_uri; + iface->set_uri = dvb_base_bin_uri_set_uri; +} + gboolean gst_dvb_base_bin_plugin_init (GstPlugin * plugin) { diff --git a/sys/dvb/parsechannels.c b/sys/dvb/parsechannels.c new file mode 100644 index 00000000..a813d43b --- /dev/null +++ b/sys/dvb/parsechannels.c @@ -0,0 +1,297 @@ +/* + * parsechannels.c - + * Copyright (C) 2008 Zaheer Abbas Merali + * + * Authors: + * Zaheer Abbas Merali + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include + +/* this will do zap style channels.conf only for the moment*/ +GHashTable * +parse_channels_conf_from_file (const gchar * filename) +{ + gchar *contents; + gchar **lines; + gchar *line; + gchar **fields; + gchar *terrestrial[] = { "inversion", "bandwidth", + "code-rate-hp", "code-rate-lp", "modulation", "transmission-mode", + "guard", "hierarchy" + }; + gchar *satellite[] = { "polarity", "diseqc-source", + "symbol-rate" + }; + int i; + GHashTable *res = NULL; + + if (g_file_get_contents (filename, &contents, NULL, NULL)) { + lines = g_strsplit (contents, "\n", 0); + res = g_hash_table_new (g_str_hash, g_str_equal); + + i = 0; + line = lines[0]; + while (line != NULL) { + if (line[0] != '#') { + int numfields; + gboolean parsed = FALSE; + GHashTable *params = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, g_free); + + fields = g_strsplit (line, ":", 0); + numfields = g_strv_length (fields); + if (numfields == 8) { + /* satellite */ + int j; + + g_hash_table_insert (params, g_strdup ("type"), + g_strdup ("satellite")); + for (j = 2; j <= 4; j++) { + g_hash_table_insert (params, g_strdup (satellite[j - 2]), + g_strdup (fields[j])); + } + g_hash_table_insert (params, g_strdup ("frequency"), + g_strdup_printf ("%d", atoi (fields[1]) * 1000)); + parsed = TRUE; + } else if (numfields == 13) { + /* terrestrial */ + int j; + + g_hash_table_insert (params, g_strdup ("type"), + g_strdup ("terrestrial")); + for (j = 2; j <= 9; j++) { + g_hash_table_insert (params, g_strdup (terrestrial[j - 2]), + g_strdup (fields[j])); + } + g_hash_table_insert (params, g_strdup ("frequency"), + g_strdup (fields[1])); + parsed = TRUE; + } + if (parsed) { + g_hash_table_insert (params, g_strdup ("sid"), + g_strdup (fields[numfields - 1])); + g_hash_table_insert (res, g_strdup (fields[0]), params); + } + g_strfreev (fields); + } + line = lines[++i]; + } + g_strfreev (lines); + g_free (contents); + } + return res; +} + +static gboolean +remove_channel_from_hash (gpointer key, gpointer value, gpointer user_data) +{ + if (key) + g_free (key); + if (value) + g_hash_table_destroy ((GHashTable *) value); + return TRUE; +} + +static void +destroy_channels_hash (GHashTable * channels) +{ + g_hash_table_foreach_remove (channels, remove_channel_from_hash, NULL); +} + +gboolean +set_properties_for_channel (GObject * dvbbasebin, const gchar * channel_name) +{ + gboolean ret = FALSE; + GHashTable *channels; + gchar *filename; + + filename = g_strdup (g_getenv ("GST_DVB_CHANNELS_CONF")); + if (filename == NULL) { + guint major, minor, micro, nano; + + gst_version (&major, &minor, µ, &nano); + filename = g_strdup_printf ("%s/.gstreamer-%d.%d/dvb-channels.conf", + g_get_home_dir (), major, minor); + } + channels = parse_channels_conf_from_file (filename); + g_free (filename); + + if (channels) { + GHashTable *params = g_hash_table_lookup (channels, + channel_name); + + if (params) { + gchar *type; + const gchar *adapter; + + g_object_set (dvbbasebin, "program-numbers", + g_hash_table_lookup (params, "sid"), NULL); + /* check if it is terrestrial or satellite */ + adapter = g_getenv ("GST_DVB_ADAPTER"); + if (adapter) + g_object_set (dvbbasebin, "adapter", atoi (adapter), NULL); + g_object_set (dvbbasebin, "frequency", + atoi (g_hash_table_lookup (params, "frequency")), NULL); + type = g_hash_table_lookup (params, "type"); + if (strcmp (type, "terrestrial") == 0) { + gchar *val; + + val = g_hash_table_lookup (params, "inversion"); + if (strcmp (val, "INVERSION_OFF") == 0) + g_object_set (dvbbasebin, "inversion", 0, NULL); + else if (strcmp (val, "INVERSION_ON") == 0) + g_object_set (dvbbasebin, "inversion", 1, NULL); + else + g_object_set (dvbbasebin, "inversion", 2, NULL); + + val = g_hash_table_lookup (params, "bandwidth"); + if (strcmp (val, "BANDWIDTH_8_MHZ") == 0) + g_object_set (dvbbasebin, "bandwidth", 0, NULL); + else if (strcmp (val, "BANDWIDTH_7_MHZ") == 0) + g_object_set (dvbbasebin, "bandwidth", 1, NULL); + else if (strcmp (val, "BANDWIDTH_6_MHZ") == 0) + g_object_set (dvbbasebin, "bandwidth", 2, NULL); + else + g_object_set (dvbbasebin, "bandwidth", 3, NULL); + + val = g_hash_table_lookup (params, "code-rate-hp"); + if (strcmp (val, "FEC_NONE") == 0) + g_object_set (dvbbasebin, "code-rate-hp", 0, NULL); + else if (strcmp (val, "FEC_1_2") == 0) + g_object_set (dvbbasebin, "code-rate-hp", 1, NULL); + else if (strcmp (val, "FEC_2_3") == 0) + g_object_set (dvbbasebin, "code-rate-hp", 2, NULL); + else if (strcmp (val, "FEC_3_4") == 0) + g_object_set (dvbbasebin, "code-rate-hp", 3, NULL); + else if (strcmp (val, "FEC_4_5") == 0) + g_object_set (dvbbasebin, "code-rate-hp", 4, NULL); + else if (strcmp (val, "FEC_5_6") == 0) + g_object_set (dvbbasebin, "code-rate-hp", 5, NULL); + else if (strcmp (val, "FEC_6_7") == 0) + g_object_set (dvbbasebin, "code-rate-hp", 6, NULL); + else if (strcmp (val, "FEC_7_8") == 0) + g_object_set (dvbbasebin, "code-rate-hp", 7, NULL); + else if (strcmp (val, "FEC_8_9") == 0) + g_object_set (dvbbasebin, "code-rate-hp", 8, NULL); + else + g_object_set (dvbbasebin, "code-rate-hp", 9, NULL); + + val = g_hash_table_lookup (params, "code-rate-lp"); + if (strcmp (val, "FEC_NONE") == 0) + g_object_set (dvbbasebin, "code-rate-lp", 0, NULL); + else if (strcmp (val, "FEC_1_2") == 0) + g_object_set (dvbbasebin, "code-rate-lp", 1, NULL); + else if (strcmp (val, "FEC_2_3") == 0) + g_object_set (dvbbasebin, "code-rate-lp", 2, NULL); + else if (strcmp (val, "FEC_3_4") == 0) + g_object_set (dvbbasebin, "code-rate-lp", 3, NULL); + else if (strcmp (val, "FEC_4_5") == 0) + g_object_set (dvbbasebin, "code-rate-lp", 4, NULL); + else if (strcmp (val, "FEC_5_6") == 0) + g_object_set (dvbbasebin, "code-rate-lp", 5, NULL); + else if (strcmp (val, "FEC_6_7") == 0) + g_object_set (dvbbasebin, "code-rate-lp", 6, NULL); + else if (strcmp (val, "FEC_7_8") == 0) + g_object_set (dvbbasebin, "code-rate-lp", 7, NULL); + else if (strcmp (val, "FEC_8_9") == 0) + g_object_set (dvbbasebin, "code-rate-lp", 8, NULL); + else + g_object_set (dvbbasebin, "code-rate-lp", 9, NULL); + + val = g_hash_table_lookup (params, "modulation"); + if (strcmp (val, "QPSK") == 0) + g_object_set (dvbbasebin, "modulation", 0, NULL); + else if (strcmp (val, "QAM_16") == 0) + g_object_set (dvbbasebin, "modulation", 1, NULL); + else if (strcmp (val, "QAM_32") == 0) + g_object_set (dvbbasebin, "modulation", 2, NULL); + else if (strcmp (val, "QAM_64") == 0) + g_object_set (dvbbasebin, "modulation", 3, NULL); + else if (strcmp (val, "QAM_128") == 0) + g_object_set (dvbbasebin, "modulation", 4, NULL); + else if (strcmp (val, "QAM_256") == 0) + g_object_set (dvbbasebin, "modulation", 5, NULL); + else + g_object_set (dvbbasebin, "modulation", 6, NULL); + + val = g_hash_table_lookup (params, "transmission-mode"); + if (strcmp (val, "TRANSMISSION_MODE_2K") == 0) + g_object_set (dvbbasebin, "trans-mode", 0, NULL); + else if (strcmp (val, "TRANSMISSION_MODE_8K") == 0) + g_object_set (dvbbasebin, "trans-mode", 1, NULL); + else + g_object_set (dvbbasebin, "trans-mode", 2, NULL); + + val = g_hash_table_lookup (params, "guard"); + if (strcmp (val, "GUARD_INTERVAL_1_32") == 0) + g_object_set (dvbbasebin, "guard", 0, NULL); + else if (strcmp (val, "GUARD_INTERVAL_1_16") == 0) + g_object_set (dvbbasebin, "guard", 1, NULL); + else if (strcmp (val, "GUARD_INTERVAL_1_8") == 0) + g_object_set (dvbbasebin, "guard", 2, NULL); + else if (strcmp (val, "GUARD_INTERVAL_1_4") == 0) + g_object_set (dvbbasebin, "guard", 3, NULL); + else + g_object_set (dvbbasebin, "guard", 4, NULL); + + val = g_hash_table_lookup (params, "hierarchy"); + if (strcmp (val, "HIERARCHY_NONE") == 0) + g_object_set (dvbbasebin, "hierarchy", 0, NULL); + else if (strcmp (val, "HIERARCHY_1") == 0) + g_object_set (dvbbasebin, "hierarchy", 1, NULL); + else if (strcmp (val, "HIERARCHY_2") == 0) + g_object_set (dvbbasebin, "hierarchy", 2, NULL); + else if (strcmp (val, "HIERARCHY_4") == 0) + g_object_set (dvbbasebin, "hierarchy", 3, NULL); + else + g_object_set (dvbbasebin, "hierarchy", 4, NULL); + + ret = TRUE; + } else if (strcmp (type, "satellite") == 0) { + gchar *val; + + ret = TRUE; + + val = g_hash_table_lookup (params, "polarity"); + if (val) + g_object_set (dvbbasebin, "polarity", val, NULL); + else + ret = FALSE; + + val = g_hash_table_lookup (params, "diseqc-source"); + if (val) + g_object_set (dvbbasebin, "diseqc-source", atoi (val), NULL); + + val = g_hash_table_lookup (params, "symbol-rate"); + if (val) + g_object_set (dvbbasebin, "symbol-rate", atoi (val), NULL); + else + ret = FALSE; + } + + } + destroy_channels_hash (channels); + } + + return ret; +} diff --git a/sys/dvb/parsechannels.h b/sys/dvb/parsechannels.h new file mode 100644 index 00000000..727419b1 --- /dev/null +++ b/sys/dvb/parsechannels.h @@ -0,0 +1,31 @@ +/* + * parsechannels.h - Parse channels.conf + * Copyright (C) 2007 Alessandro Decina + * + * Authors: + * Zaheer Abbas Merali + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef PARSE_CHANNELS_H +#define PARSE_CHANNELS_H + +GHashTable* parse_channels_conf_from_file(const gchar* filename); +gboolean set_properties_for_channel(GObject *dvbbasebin, + const gchar* channel_name); + +#endif -- cgit v1.2.1