r23699 - /packages/unstable/gnome-dvb-daemon/debian/patches/01_vala-0.8.0.patch
slomo at users.alioth.debian.org
slomo at users.alioth.debian.org
Sun Apr 11 09:48:19 UTC 2010
Author: slomo
Date: Sun Apr 11 09:48:19 2010
New Revision: 23699
URL: http://svn.debian.org/wsvn/pkg-gnome/?sc=1&rev=23699
Log:
* fix patch
Modified:
packages/unstable/gnome-dvb-daemon/debian/patches/01_vala-0.8.0.patch
Modified: packages/unstable/gnome-dvb-daemon/debian/patches/01_vala-0.8.0.patch
URL: http://svn.debian.org/wsvn/pkg-gnome/packages/unstable/gnome-dvb-daemon/debian/patches/01_vala-0.8.0.patch?rev=23699&op=diff
==============================================================================
--- packages/unstable/gnome-dvb-daemon/debian/patches/01_vala-0.8.0.patch [utf-8] (original)
+++ packages/unstable/gnome-dvb-daemon/debian/patches/01_vala-0.8.0.patch [utf-8] Sun Apr 11 09:48:19 2010
@@ -1,140 +1,6 @@
-=== modified file 'src/Recorder.vala'
---- a/src/Recorder.vala 2010-03-23 22:07:57 +0000
-+++ b/src/Recorder.vala 2010-04-08 13:49:40 +0000
-@@ -167,8 +167,12 @@
-
- if (!has_conflict) {
- this.timers.set (new_timer.Id, new_timer);
-- Factory.get_timers_store ().add_timer_to_device_group (new_timer,
-- this.DeviceGroup);
-+ try {
-+ Factory.get_timers_store ().add_timer_to_device_group (new_timer,
-+ this.DeviceGroup);
-+ } catch (SqlError e) {
-+ critical ("%s", e.message);
-+ }
- this.changed (new_timer.Id, ChangeType.ADDED);
-
- if (this.timers.size == 1 && !this.have_check_timers_timeout) {
-@@ -233,8 +237,12 @@
- this.stop_recording (timer);
- }
- this.timers.remove (timer_id);
-- Factory.get_timers_store ().remove_timer_from_device_group (
-- timer_id, this.DeviceGroup);
-+ try {
-+ Factory.get_timers_store ().remove_timer_from_device_group (
-+ timer_id, this.DeviceGroup);
-+ } catch (SqlError e) {
-+ critical ("%s", e.message);
-+ }
- this.changed (timer_id, ChangeType.DELETED);
- val = true;
- } else {
-
-=== modified file 'src/Schedule.vala'
---- a/src/Schedule.vala 2009-11-17 14:17:18 +0000
-+++ b/src/Schedule.vala 2010-04-08 13:49:40 +0000
-@@ -111,8 +111,12 @@
-
- this.event_id_map.remove (element.id);
- this.events.remove (iter);
-- this.epgstore.remove_event (
-- element.id, this.channel.Sid, this.channel.GroupId);
-+ try {
-+ this.epgstore.remove_event (element.id,
-+ this.channel.Sid, this.channel.GroupId);
-+ } catch (SqlError e) {
-+ critical ("%s", e.message);
-+ }
- }
- }
- }
-@@ -138,8 +142,12 @@
- this.create_and_add_event_element (event);
- }
-
-- this.epgstore.add_or_update_event (event, this.channel.Sid,
-- this.channel.GroupId);
-+ try {
-+ this.epgstore.add_or_update_event (event, this.channel.Sid,
-+ this.channel.GroupId);
-+ } catch (SqlError e) {
-+ critical ("%s", e.message);
-+ }
- }
- }
-
-
-=== modified file 'src/Manager.vala'
---- a/src/Manager.vala 2010-03-22 11:32:56 +0000
-+++ b/src/Manager.vala 2010-04-08 13:58:06 +0000
-@@ -66,7 +66,7 @@
- lock (m.scanners) {
- foreach (Scanner scanner in m.scanners.values) {
- debug ("Stopping scanner");
-- scanner.Destroy ();
-+ scanner.do_destroy ();
- }
- m.scanners.clear ();
- }
-
-=== modified file 'src/Recorder.vala'
---- a/src/Recorder.vala 2010-04-08 13:49:40 +0000
-+++ b/src/Recorder.vala 2010-04-08 13:58:06 +0000
-@@ -228,10 +228,14 @@
- * active timer recording is aborted.
- */
- public bool DeleteTimer (uint32 timer_id) throws DBus.Error {
-+ return this.delete_timer (timer_id);
-+ }
-+
-+ protected bool delete_timer (uint32 timer_id) {
- bool val;
- lock (this.timers) {
- if (this.timers.contains (timer_id)) {
-- if (this.IsTimerActive (timer_id)) {
-+ if (this.is_timer_active (timer_id)) {
- // Abort recording
- Timer timer = this.timers.get (timer_id);
- this.stop_recording (timer);
-@@ -492,6 +496,10 @@
- * @returns: TRUE if timer is currently active
- */
- public bool IsTimerActive (uint32 timer_id) throws DBus.Error {
-+ return this.is_timer_active (timer_id);
-+ }
-+
-+ protected bool is_timer_active (uint32 timer_id) {
- return this.active_timers.contains (timer_id);
- }
-
-@@ -790,7 +798,7 @@
-
- // Delete items from this.timers using this.DeleteTimer
- for (int i=0; i<deleteable_items.length(); i++) {
-- this.DeleteTimer (deleteable_items.nth_data (i));
-+ this.delete_timer (deleteable_items.nth_data (i));
- }
-
- if (this.timers.size == 0 && this.active_timers.size == 0) {
-
-=== modified file 'src/Scanner.vala'
---- a/src/Scanner.vala 2010-04-02 15:19:18 +0000
-+++ b/src/Scanner.vala 2010-04-08 13:58:06 +0000
-@@ -183,7 +183,7 @@
- this.do_destroy ();
- }
-
-- protected void do_destroy () {
-+ public void do_destroy () {
- this.remove_check_for_lock_timeout ();
- this.remove_wait_for_tables_timeout ();
- this.clear_and_reset_all ();
-
-=== modified file 'src/ChannelFactory.vala'
---- a/src/ChannelFactory.vala 2010-02-05 17:52:07 +0000
-+++ b/src/ChannelFactory.vala 2010-04-08 14:13:46 +0000
+diff -Naur gnome-dvb-daemon-0.1.16.old/src/ChannelFactory.vala gnome-dvb-daemon-0.1.16/src/ChannelFactory.vala
+--- gnome-dvb-daemon-0.1.16.old/src/ChannelFactory.vala 2010-02-07 17:11:57.000000000 +0100
++++ gnome-dvb-daemon-0.1.16/src/ChannelFactory.vala 2010-04-11 10:55:19.665601099 +0200
@@ -201,24 +201,24 @@
create_channel = false;
}
@@ -174,4 +40,911 @@
}
private Gst.Element add_sink_bin (Gst.Element sink_element) {
-
+diff -Naur gnome-dvb-daemon-0.1.16.old/src/Manager.vala gnome-dvb-daemon-0.1.16/src/Manager.vala
+--- gnome-dvb-daemon-0.1.16.old/src/Manager.vala 2010-02-07 17:11:57.000000000 +0100
++++ gnome-dvb-daemon-0.1.16/src/Manager.vala 2010-04-11 10:55:19.661592349 +0200
+@@ -66,7 +66,7 @@
+ lock (m.scanners) {
+ foreach (Scanner scanner in m.scanners.values) {
+ debug ("Stopping scanner");
+- scanner.Destroy ();
++ scanner.do_destroy ();
+ }
+ m.scanners.clear ();
+ }
+diff -Naur gnome-dvb-daemon-0.1.16.old/src/Recorder.vala gnome-dvb-daemon-0.1.16/src/Recorder.vala
+--- gnome-dvb-daemon-0.1.16.old/src/Recorder.vala 2010-02-07 17:11:57.000000000 +0100
++++ gnome-dvb-daemon-0.1.16/src/Recorder.vala 2010-04-11 10:55:19.665601099 +0200
+@@ -167,8 +167,12 @@
+
+ if (!has_conflict) {
+ this.timers.set (new_timer.Id, new_timer);
+- Factory.get_timers_store ().add_timer_to_device_group (new_timer,
+- this.DeviceGroup);
++ try {
++ Factory.get_timers_store ().add_timer_to_device_group (new_timer,
++ this.DeviceGroup);
++ } catch (SqlError e) {
++ critical ("%s", e.message);
++ }
+ this.changed (new_timer.Id, ChangeType.ADDED);
+
+ if (this.timers.size == 1 && !this.have_check_timers_timeout) {
+@@ -224,17 +228,25 @@
+ * active timer recording is aborted.
+ */
+ public bool DeleteTimer (uint32 timer_id) throws DBus.Error {
++ return this.delete_timer (timer_id);
++ }
++
++ protected bool delete_timer (uint32 timer_id) {
+ bool val;
+ lock (this.timers) {
+ if (this.timers.contains (timer_id)) {
+- if (this.IsTimerActive (timer_id)) {
++ if (this.is_timer_active (timer_id)) {
+ // Abort recording
+ Timer timer = this.timers.get (timer_id);
+ this.stop_recording (timer);
+ }
+ this.timers.remove (timer_id);
+- Factory.get_timers_store ().remove_timer_from_device_group (
+- timer_id, this.DeviceGroup);
++ try {
++ Factory.get_timers_store ().remove_timer_from_device_group (
++ timer_id, this.DeviceGroup);
++ } catch (SqlError e) {
++ critical ("%s", e.message);
++ }
+ this.changed (timer_id, ChangeType.DELETED);
+ val = true;
+ } else {
+@@ -484,6 +496,10 @@
+ * @returns: TRUE if timer is currently active
+ */
+ public bool IsTimerActive (uint32 timer_id) throws DBus.Error {
++ return this.is_timer_active (timer_id);
++ }
++
++ protected bool is_timer_active (uint32 timer_id) {
+ return this.active_timers.contains (timer_id);
+ }
+
+@@ -782,7 +798,7 @@
+
+ // Delete items from this.timers using this.DeleteTimer
+ for (int i=0; i<deleteable_items.length(); i++) {
+- this.DeleteTimer (deleteable_items.nth_data (i));
++ this.delete_timer (deleteable_items.nth_data (i));
+ }
+
+ if (this.timers.size == 0 && this.active_timers.size == 0) {
+diff -Naur gnome-dvb-daemon-0.1.16.old/src/Scanner.vala gnome-dvb-daemon-0.1.16/src/Scanner.vala
+--- gnome-dvb-daemon-0.1.16.old/src/Scanner.vala 2010-03-17 20:06:52.000000000 +0100
++++ gnome-dvb-daemon-0.1.16/src/Scanner.vala 2010-04-11 10:55:19.665601099 +0200
+@@ -184,7 +184,7 @@
+ this.do_destroy ();
+ }
+
+- protected void do_destroy () {
++ public void do_destroy () {
+ this.remove_check_for_lock_timeout ();
+ this.remove_wait_for_tables_timeout ();
+ this.clear_and_reset_all ();
+diff -Naur gnome-dvb-daemon-0.1.16.old/src/Scanner.vala.orig gnome-dvb-daemon-0.1.16/src/Scanner.vala.orig
+--- gnome-dvb-daemon-0.1.16.old/src/Scanner.vala.orig 1970-01-01 01:00:00.000000000 +0100
++++ gnome-dvb-daemon-0.1.16/src/Scanner.vala.orig 2010-03-17 20:06:52.000000000 +0100
+@@ -0,0 +1,780 @@
++/*
++ * Copyright (C) 2008,2009 Sebastian Pölsterl
++ *
++ * This file is part of GNOME DVB Daemon.
++ *
++ * GNOME DVB Daemon is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation, either version 3 of the License, or
++ * (at your option) any later version.
++ *
++ * GNOME DVB Daemon 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 General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with GNOME DVB Daemon. If not, see <http://www.gnu.org/licenses/>.
++ */
++
++using GLib;
++using Gee;
++
++namespace DVB {
++
++ /**
++ * An abstract class responsible for scanning for new channels
++ */
++ public abstract class Scanner : GLib.Object {
++
++ /**
++ * Emitted when the Destroy () method is called
++ */
++ public signal void destroyed ();
++
++ /**
++ * Emitted when a frequency has been scanned.
++ * Whether a new channel has been found on that frequency or not.
++ */
++ public signal void frequency_scanned (uint frequency, uint freq_left);
++
++ /**
++ * @frequency: Frequency of the channel
++ * @sid: SID of the channel
++ * @name: Name of the channel
++ * @network: Name of network the channel is part of
++ * @type: What type of channel this is (Radio or TV)
++ * @scrambled: Whether the channel is scrambled
++ *
++ * Emitted when a new channel has been found
++ */
++ public signal void channel_added (uint frequency, uint sid,
++ string name, string network, string type, bool scrambled);
++
++ /**
++ * Emitted when all frequencies have been scanned
++ */
++ public signal void finished ();
++
++ /**
++ * The DVB device the scanner should use
++ */
++ [DBus (visible = false)]
++ public DVB.Device Device { get; construct; }
++
++ [DBus (visible = false)]
++ public ChannelList Channels {
++ get { return this.channels; }
++ }
++
++ protected ChannelList channels;
++
++ /**
++ * The Gst pipeline used for scanning
++ */
++ protected Gst.Element pipeline;
++
++ /**
++ * Contains the tuning parameters we use for scanning
++ */
++ protected GLib.Queue<Gst.Structure> frequencies;
++
++ /**
++ * The tuning paramters we're currently using
++ */
++ protected Gst.Structure? current_tuning_params;
++
++ /**
++ * All the frequencies that have been scanned already
++ */
++ protected HashSet<ScannedItem> scanned_frequencies;
++
++ protected HashMap<uint, Gst.Structure> transport_streams;
++
++ private static const string BASE_PIDS = "16:17:18";
++ private static const string PIPELINE_TEMPLATE = "dvbsrc name=dvbsrc adapter=%u frontend=%u pids=%s stats-reporting-interval=0 ! mpegtsparse ! fakesink silent=true";
++
++ // Contains SIDs
++ private ArrayList<uint> new_channels;
++ private Source check_for_lock_source;
++ private Source wait_for_tables_source;
++ private bool nit_arrived;
++ private bool sdt_arrived;
++ private bool pat_arrived;
++ private bool pmt_arrived;
++ private bool locked;
++ private MainContext context;
++ private MainLoop loop;
++ private unowned Thread worker_thread;
++ private bool running;
++ private uint bus_watch_id;
++
++ construct {
++ this.scanned_frequencies =
++ new HashSet<ScannedItem> (ScannedItem.hash, ScannedItem.equal);
++ this.new_channels = new ArrayList<uint> ();
++ this.frequencies = new GLib.Queue<Gst.Structure> ();
++ this.transport_streams = new HashMap<uint, Gst.Structure> ();
++ this.context = new MainContext ();
++ this.running = false;
++ }
++
++ /**
++ * Setup the pipeline correctly
++ */
++ protected abstract void prepare();
++
++ /**
++ * Use the frequency and possibly other data to
++ * mark the tuning paramters as already used
++ */
++ protected abstract ScannedItem get_scanned_item (Gst.Structure structure);
++
++ /**
++ * Return a new empty channel
++ */
++ protected abstract Channel get_new_channel ();
++
++ /**
++ * Retrieve the data from structure and add it to the Channel
++ */
++ protected abstract void add_values_from_structure_to_channel (Gst.Structure delivery, Channel channel);
++
++ /**
++ * Start the scanner
++ */
++ public void Run () throws DBus.Error {
++ if (this.running) return;
++ this.running = true;
++
++ this.loop = new MainLoop (this.context, false);
++ try {
++ this.worker_thread = Thread.create (this.worker, true);
++ } catch (Error e) {
++ critical ("Could not create thread: %s", e.message);
++ return;
++ }
++
++ this.channels = new ChannelList ();
++ // pids: 0=pat, 16=nit, 17=sdt, 18=eit
++ try {
++ this.pipeline = Gst.parse_launch(
++ PIPELINE_TEMPLATE.printf (this.Device.Adapter,
++ this.Device.Frontend, BASE_PIDS));
++ } catch (Error e) {
++ error ("Could not create pipeline: %s", e.message);
++ return;
++ }
++
++ Gst.Bus bus = this.pipeline.get_bus();
++ this.bus_watch_id = cUtils.gst_bus_add_watch_context (bus,
++ this.bus_watch_func, this.context);
++
++ this.pipeline.set_state(Gst.State.READY);
++
++ var source = new IdleSource ();
++ source.set_callback (this.start_scan);
++ source.attach (this.context);
++ }
++
++ /**
++ * Abort scanning and cleanup
++ */
++ public void Destroy () throws DBus.Error {
++ this.do_destroy ();
++ }
++
++ protected void do_destroy () {
++ this.remove_check_for_lock_timeout ();
++ this.remove_wait_for_tables_timeout ();
++ this.clear_and_reset_all ();
++ this.channels.clear ();
++ this.channels = null;
++
++ if (this.loop != null) {
++ this.loop.quit ();
++ this.loop = null;
++ this.worker_thread.join ();
++ this.worker_thread = null;
++ }
++ this.destroyed ();
++ }
++
++ /**
++ * @path: Location where the file will be stored
++ *
++ * Write all the channels stored in this.Channels to file
++ */
++ public bool WriteAllChannelsToFile (string path) throws DBus.Error {
++ bool success = true;
++ var writer = new ChannelListWriter (File.new_for_path (path));
++ foreach (DVB.Channel c in this.channels) {
++ try {
++ writer.write (c);
++ } catch (Error e) {
++ critical ("Could not write to file: %s", e.message);
++ success = false;
++ }
++ }
++
++ try {
++ writer.close ();
++ } catch (Error e) {
++ critical ("Could not close file handle: %s", e.message);
++ success = false;
++ }
++
++ return success;
++ }
++
++ /**
++ * @channel_sids: A list of channels' SIDs
++ * @path: Location where the file will be stored
++ *
++ * Write the channels with the given SIDs to file @path
++ */
++ public bool WriteChannelsToFile (uint[] channel_sids, string path)
++ throws DBus.Error
++ {
++ bool success = true;
++ var writer = new ChannelListWriter (File.new_for_path (path));
++ foreach (uint sid in channel_sids) {
++ DVB.Channel? c = this.channels.get_channel (sid);
++ if (c == null) {
++ warning ("Channel with SID %u does not exist", sid);
++ continue;
++ }
++ try {
++ writer.write (c);
++ } catch (Error e) {
++ critical ("Could not write to file: %s", e.message);
++ success = false;
++ }
++ }
++
++ try {
++ writer.close ();
++ } catch (Error e) {
++ critical ("Could not close file handle: %s", e.message);
++ success = false;
++ }
++
++ return success;
++ }
++
++ /* Main Thread */
++ private void* worker () {
++ this.loop.run ();
++
++ return null;
++ }
++
++ protected void clear_and_reset_all () {
++ if (this.pipeline != null) {
++ Source bus_watch_source = this.context.find_source_by_id (
++ this.bus_watch_id);
++ if (bus_watch_source != null) {
++ bus_watch_source.destroy ();
++ this.bus_watch_id = 0;
++ }
++ this.pipeline.set_state (Gst.State.NULL);
++ // Free pipeline
++ this.pipeline = null;
++ }
++
++ this.transport_streams.clear ();
++ this.scanned_frequencies.clear ();
++ this.clear_frequencies ();
++ this.current_tuning_params = null;
++ this.new_channels.clear ();
++ this.running = false;
++ }
++
++ protected void clear_frequencies () {
++ while (!this.frequencies.is_empty ()) {
++ Gst.Structure? s = this.frequencies.pop_head ();
++ // Force that gst_structure_free is called
++ s = null;
++ }
++ this.frequencies.clear ();
++ }
++
++ protected void add_structure_to_scan (owned Gst.Structure structure) {
++ if (structure == null) return;
++
++ ScannedItem item = this.get_scanned_item (structure);
++
++ if (!this.scanned_frequencies.contains (item)) {
++ debug ("Queueing new frequency %u", item.Frequency);
++ this.frequencies.push_tail (structure);
++ this.scanned_frequencies.add (item);
++ }
++ }
++
++ /**
++ * Pick up the next tuning paramters from the queue
++ * and start scanning with them
++ */
++ protected bool start_scan () {
++ bool all_tables = (this.sdt_arrived && this.nit_arrived
++ && this.pat_arrived && this.pmt_arrived);
++ debug ("Received all tables: %s (pat: %s, sdt: %s, nit: %s, pmt: %s)",
++ all_tables.to_string (), this.pat_arrived.to_string (),
++ this.sdt_arrived.to_string (), this.nit_arrived.to_string (),
++ this.pmt_arrived.to_string ());
++
++ this.nit_arrived = false;
++ this.sdt_arrived = false;
++ this.pat_arrived = false;
++ this.pmt_arrived = false;
++ this.locked = false;
++
++ if (this.current_tuning_params != null) {
++ uint old_freq;
++ this.current_tuning_params.get_uint ("frequency", out old_freq);
++ this.frequency_scanned (old_freq, this.frequencies.length);
++ }
++
++ if (this.frequencies.is_empty()) {
++ message("Finished scanning");
++ // We don't have all the information for those channels
++ // remove them
++ lock (this.new_channels) {
++ debug ("%u channels still have missing or invalid information",
++ this.new_channels.size);
++ foreach (uint sid in this.new_channels) {
++ this.channels.remove (sid);
++ }
++ }
++ this.clear_and_reset_all ();
++ this.finished ();
++ return false;
++ }
++
++ this.current_tuning_params = this.frequencies.pop_head();
++
++ // Remember that we already scanned this frequency
++ uint freq;
++ this.current_tuning_params.get_uint ("frequency", out freq);
++
++ debug("Starting scanning frequency %u (%u left)", freq,
++ this.frequencies.get_length ());
++
++ this.pipeline.set_state (Gst.State.READY);
++
++ this.prepare ();
++
++ // Reset PIDs
++ Gst.Element dvbsrc = ((Gst.Bin)this.pipeline).get_by_name ("dvbsrc");
++ dvbsrc.set ("pids", BASE_PIDS);
++
++ this.check_for_lock_source =
++ new TimeoutSource.seconds (5);
++ this.check_for_lock_source.set_callback (this.check_for_lock);
++ this.check_for_lock_source.attach (this.context);
++
++ this.pipeline.set_state (Gst.State.PLAYING);
++
++ return false;
++ }
++
++ /**
++ * Check if we received a lock with the currently
++ * used tuning parameters
++ */
++ protected bool check_for_lock () {
++ if (!this.locked) {
++ this.pipeline.set_state (Gst.State.READY);
++ this.queue_start_scan ();
++ }
++ return false;
++ }
++
++ protected bool wait_for_tables () {
++ if (!(this.sdt_arrived && this.nit_arrived && this.pat_arrived
++ && this.pmt_arrived)) {
++ this.pipeline.set_state (Gst.State.READY);
++ this.queue_start_scan ();
++ }
++ return false;
++ }
++
++ protected void remove_check_for_lock_timeout () {
++ if (this.check_for_lock_source != null) {
++ this.check_for_lock_source.destroy ();
++ this.check_for_lock_source = null;
++ }
++ }
++
++ protected void remove_wait_for_tables_timeout () {
++ if (this.wait_for_tables_source != null) {
++ this.wait_for_tables_source.destroy ();
++ this.wait_for_tables_source = null;
++ }
++ }
++
++ protected void queue_start_scan () {
++ var source = new IdleSource ();
++ source.set_callback (this.start_scan);
++ source.attach (this.context);
++ }
++
++ protected static void set_uint_property (Gst.Element src,
++ Gst.Structure params, string key) {
++ uint val;
++ params.get_uint (key, out val);
++ src.set (key, val);
++ }
++
++ protected void on_dvb_frontend_stats_structure (Gst.Structure structure) {
++ bool has_lock;
++ structure.get_boolean ("lock", out has_lock);
++ if (has_lock && !this.locked) {
++ debug("Got lock");
++ this.remove_check_for_lock_timeout ();
++ this.wait_for_tables_source =
++ new TimeoutSource.seconds (10);
++ this.wait_for_tables_source.set_callback (this.wait_for_tables);
++ this.wait_for_tables_source.attach (this.context);
++ }
++ }
++
++ protected void on_dvb_read_failure_structure () {
++ warning ("Read failure");
++ /*
++ this.Destroy ();
++ */
++ }
++
++ protected void on_pat_structure (Gst.Structure structure) {
++ debug("Received PAT");
++
++ Set<uint> pid_set = new HashSet<uint> ();
++ // add BASE_PIDS
++ pid_set.add (16);
++ pid_set.add (17);
++ pid_set.add (18);
++
++ Gst.Value programs = structure.get_value ("programs");
++ uint size = programs.list_get_size ();
++ Gst.Value val;
++ weak Gst.Structure program;
++ // Iterate over programs
++ for (uint i=0; i<size; i++) {
++ val = programs.list_get_value (i);
++ program = val.get_structure ();
++
++ uint sid;
++ program.get_uint ("program-number", out sid);
++
++ uint pmt;
++ program.get_uint ("pid", out pmt);
++
++ pid_set.add (pmt);
++ }
++
++ StringBuilder new_pids = new StringBuilder ();
++ int i = 0;
++ foreach (uint pid in pid_set) {
++ if (i+1 == pid_set.size)
++ new_pids.append ("%u".printf (pid));
++ else
++ new_pids.append ("%u:".printf (pid));
++ i++;
++ }
++
++ debug ("Setting %d pids: %s", pid_set.size, new_pids.str);
++ // We want to parse the pmt as well
++ Gst.Element dvbsrc = ((Gst.Bin)this.pipeline).get_by_name ("dvbsrc");
++ dvbsrc.set ("pids", new_pids.str);
++
++ this.pat_arrived = true;
++ }
++
++ protected void on_sdt_structure (Gst.Structure structure) {
++ debug("Received SDT");
++
++ uint tsid;
++ structure.get_uint ("transport-stream-id", out tsid);
++
++ Gst.Value services = structure.get_value ("services");
++ uint size = services.list_get_size ();
++
++ Gst.Value val;
++ weak Gst.Structure service;
++ // Iterate over services
++ for (uint i=0; i<size; i++) {
++ val = services.list_get_value (i);
++ service = val.get_structure ();
++
++ // Returns "service-%d"
++ string name = service.get_name ();
++ // Get the number at the end
++ int sid = name.substring (8, name.len() - 8).to_int ();
++
++ if (service.has_field ("name"))
++ name = service.get_string ("name");
++
++ if (!this.channels.contains (sid)) {
++ this.add_new_channel (sid);
++ }
++
++ Channel channel = this.channels.get_channel (sid);
++
++ if (service.has_field ("scrambled")) {
++ bool scrambled;
++ service.get_boolean ("scrambled", out scrambled);
++ channel.Scrambled = scrambled;
++ } else {
++ channel.Scrambled = false;
++ }
++
++ if (name.validate ()) {
++ channel.Name = name.replace ("\\s", " ");
++ }
++
++ channel.TransportStreamId = tsid;
++ string provider = service.get_string ("provider-name");
++ if (provider != null && provider.validate ()) {
++ channel.Network = provider;
++ } else {
++ channel.Network = "";
++ }
++ }
++
++ this.sdt_arrived = true;
++ }
++
++ protected void on_nit_structure (Gst.Structure structure) {
++ debug("Received NIT");
++
++ string name;
++ if (structure.has_field ("network-name")) {
++ name = structure.get_string ("network-name");
++ } else {
++ uint nid;
++ structure.get_uint ("network-id", out nid);
++ name = "%u".printf (nid);
++ }
++ debug ("Network name '%s'", name);
++
++ Gst.Value transports = structure.get_value ("transports");
++ uint size = transports.list_get_size ();
++ Gst.Value val;
++ weak Gst.Structure transport;
++ // Iterate over transports
++ for (uint i=0; i<size; i++) {
++ val = transports.list_get_value (i);
++ transport = val.get_structure ();
++
++ uint tsid;
++ transport.get_uint ("transport-stream-id", out tsid);
++
++ if (transport.has_field ("delivery")) {
++ Gst.Value delivery_val = transport.get_value ("delivery");
++ weak Gst.Structure delivery =
++ delivery_val.get_structure ();
++
++ debug ("Received TS %u", tsid);
++ this.transport_streams.set (tsid, delivery);
++
++ uint freq;
++ delivery.get_uint ("frequency", out freq);
++ // Takes care of duplicates
++ this.add_structure_to_scan (delivery);
++ }
++
++ if (transport.has_field ("channels")) {
++ Gst.Value channels = transport.get_value ("channels");
++ uint channels_size = channels.list_get_size ();
++
++ Gst.Value channel_val;
++ weak Gst.Structure channel_struct;
++ // Iterate over channels
++ for (int j=0; j<channels_size; j++) {
++ channel_val = channels.list_get_value (j);
++ channel_struct = channel_val.get_structure ();
++
++ uint sid;
++ channel_struct.get_uint ("service-id", out sid);
++
++ if (!this.channels.contains (sid)) {
++ this.add_new_channel (sid);
++ }
++
++ Channel dvb_channel = this.channels.get_channel (sid);
++
++ if (name.validate ()) {
++ dvb_channel.Network = name;
++ } else {
++ dvb_channel.Network = "";
++ }
++
++ uint lcnumber;
++ channel_struct.get_uint ("logical-channel-number", out lcnumber);
++ dvb_channel.LogicalChannelNumber = lcnumber;
++ }
++ }
++ }
++
++ this.nit_arrived = true;
++ }
++
++ protected void on_pmt_structure (Gst.Structure structure) {
++ debug ("Received PMT");
++
++ uint program_number;
++ structure.get_uint ("program-number", out program_number);
++
++ if (!this.channels.contains (program_number)) {
++ this.add_new_channel (program_number);
++ }
++
++ Channel dvb_channel = this.channels.get_channel (program_number);
++
++ Gst.Value streams = structure.get_value ("streams");
++ uint size = streams.list_get_size ();
++
++ Gst.Value stream_val;
++ weak Gst.Structure stream;
++ // Iterate over streams
++ for (int i=0; i<size; i++) {
++ stream_val = streams.list_get_value (i);
++ stream = stream_val.get_structure ();
++
++ uint pid;
++ stream.get_uint ("pid", out pid);
++
++ // See ISO/IEC 13818-1 Table 2-29
++ uint stream_type;
++ stream.get_uint ("stream-type", out stream_type);
++
++ switch (stream_type) {
++ case 0x01:
++ case 0x02:
++ case 0x1b: /* H.264 video stream */
++ debug ("Found video PID %u for channel %u",
++ pid, program_number);
++ dvb_channel.VideoPID = pid;
++ break;
++ case 0x03:
++ case 0x04:
++ case 0x0f:
++ case 0x11:
++ debug ("Found audio PID %u for channel %u",
++ pid, program_number);
++ dvb_channel.AudioPIDs.add (pid);
++ break;
++ default:
++ debug ("Other stream type: 0x%02x", stream_type);
++ break;
++ }
++ }
++
++ this.pmt_arrived = true;
++ }
++
++ protected bool bus_watch_func (Gst.Bus bus, Gst.Message message) {
++ switch (message.type) {
++ case Gst.MessageType.ELEMENT: {
++ if (message.structure.get_name() == "dvb-frontend-stats")
++ this.on_dvb_frontend_stats_structure (message.structure);
++ else if (message.structure.get_name() == "dvb-read-failure")
++ this.on_dvb_read_failure_structure ();
++ else if (message.structure.get_name() == "sdt")
++ this.on_sdt_structure (message.structure);
++ else if (message.structure.get_name() == "nit")
++ this.on_nit_structure (message.structure);
++ else if (message.structure.get_name() == "pat")
++ this.on_pat_structure (message.structure);
++ else if (message.structure.get_name() == "pmt")
++ this.on_pmt_structure (message.structure);
++ break;
++ }
++ case Gst.MessageType.ERROR: {
++ Error gerror;
++ string debug;
++ message.parse_error (out gerror, out debug);
++ critical ("%s %s", gerror.message, debug);
++ this.do_destroy ();
++ return false;
++ }
++ }
++
++ // NIT gives us the transport stream, SDT links SID and TS ID
++ if (this.nit_arrived && this.sdt_arrived) {
++ lock (this.new_channels) {
++ foreach (uint sid in this.new_channels) {
++ DVB.Channel channel = this.channels.get_channel (sid);
++
++ uint tsid = channel.TransportStreamId;
++ // Check if already came across the transport stream
++ if (this.transport_streams.contains (tsid)) {
++ // add values from Gst.Structure to Channel
++ this.add_values_from_structure_to_channel (
++ this.transport_streams.get (tsid),
++ channel);
++ } else {
++ debug ("TS %u for channel %u does not exist", tsid,
++ sid);
++ // We haven't seen the transport stream, yet
++ // Maybe it comes with a later bus message
++ this.nit_arrived = false;
++ }
++ }
++
++ // We received all tables at least once. Add valid channels.
++ if (this.pat_arrived) {
++ ArrayList<uint> del_channels = new ArrayList<uint> ();
++ foreach (uint sid in this.new_channels) {
++ DVB.Channel channel = this.channels.get_channel (sid);
++
++ // If this fails we may miss video or audio pid,
++ // because we didn't came across the sdt or pmt, yet
++ if (channel.is_valid ()) {
++ string type = (channel.is_radio ()) ? "Radio" : "TV";
++ debug ("Channel added: %s", channel.to_string ());
++ this.channel_added (channel.Frequency, sid,
++ channel.Name, channel.Network, type,
++ channel.Scrambled);
++ // Mark channel for deletion of this.new_channels
++ del_channels.add (sid);
++ } else {
++ debug ("Channel %u is not valid: %s", sid,
++ channel.to_string ());
++ this.pmt_arrived = false;
++ }
++ }
++
++ // Only remove those channels we have all the information for
++ foreach (uint sid in del_channels) {
++ this.new_channels.remove (sid);
++ }
++ }
++ }
++ }
++
++ // If we collect all information we can continue scanning
++ // the next frequency
++ if (this.sdt_arrived && this.nit_arrived && this.pat_arrived
++ && this.pmt_arrived) {
++ this.remove_wait_for_tables_timeout ();
++
++ this.queue_start_scan ();
++ }
++
++ return true;
++ }
++
++ protected void add_new_channel (uint sid) {
++ debug ("Adding new channel with SID %u", sid);
++ Channel new_channel = this.get_new_channel ();
++ new_channel.Sid = sid;
++ this.channels.add (new_channel);
++ lock (this.new_channels) {
++ this.new_channels.add (sid);
++ }
++ }
++ }
++
++}
+diff -Naur gnome-dvb-daemon-0.1.16.old/src/Schedule.vala gnome-dvb-daemon-0.1.16/src/Schedule.vala
+--- gnome-dvb-daemon-0.1.16.old/src/Schedule.vala 2009-11-28 02:09:02.000000000 +0100
++++ gnome-dvb-daemon-0.1.16/src/Schedule.vala 2010-04-11 10:55:19.661592349 +0200
+@@ -111,8 +111,12 @@
+
+ this.event_id_map.remove (element.id);
+ this.events.remove (iter);
+- this.epgstore.remove_event (
+- element.id, this.channel.Sid, this.channel.GroupId);
++ try {
++ this.epgstore.remove_event (element.id,
++ this.channel.Sid, this.channel.GroupId);
++ } catch (SqlError e) {
++ critical ("%s", e.message);
++ }
+ }
+ }
+ }
+@@ -138,8 +142,12 @@
+ this.create_and_add_event_element (event);
+ }
+
+- this.epgstore.add_or_update_event (event, this.channel.Sid,
+- this.channel.GroupId);
++ try {
++ this.epgstore.add_or_update_event (event, this.channel.Sid,
++ this.channel.GroupId);
++ } catch (SqlError e) {
++ critical ("%s", e.message);
++ }
+ }
+ }
+
More information about the pkg-gnome-commits
mailing list