Author: duncan
Date: Wed Oct  4 04:36:19 2006
New Revision: 8314

Modified:
   branches/rel-1-5/freevo/src/tv/ivtv_xine_tv.py

Log:
[ 1568856 ] Pygame error: traceback with ivtv_xine_tv and directfb
Reverted patch to old version.


Modified: branches/rel-1-5/freevo/src/tv/ivtv_xine_tv.py
==============================================================================
--- branches/rel-1-5/freevo/src/tv/ivtv_xine_tv.py      (original)
+++ branches/rel-1-5/freevo/src/tv/ivtv_xine_tv.py      Wed Oct  4 04:36:19 2006
@@ -1,6 +1,3 @@
-
-# [EMAIL PROTECTED]
-
 import config
 
 import time, os
@@ -8,26 +5,33 @@
 import signal
 import skin
 
-import rc
-import util
-import plugin
-import childapp
-import tv.ivtv as ivtv
-import tv.epg_xmltv as epg
 
+import util    # Various utilities
 from event import *
-from gui.AlertBox import AlertBox
+import osd     # The OSD class, used to communicate with the OSD daemon
+import rc      # The RemoteControl class.
+import childapp # Handle child applications
+import tv.epg_xmltv as epg # The Electronic Program Guide
+import tv.ivtv as ivtv
+import plugin
+
+#import event as em 
 from tv.channels import FreevoChannels
 
+
+from event import *
+
+import plugin
+
+# Set to 1 for debug output
 DEBUG = config.DEBUG
 
 TRUE = 1
 FALSE = 0
 
-if not config.XINE_TV_VO_DEV:
-       config.XINE_TV_VO_DEV = config.XINE_VO_DEV
-if not config.XINE_TV_AO_DEV:
-       config.XINE_TV_AO_DEV = config.XINE_AO_DEV
+
+# Create the OSD object
+osd = osd.get_singleton()
 
 class PluginInterface(plugin.Plugin):
     """
@@ -35,397 +39,361 @@
     """
     def __init__(self):
         plugin.Plugin.__init__(self)
-        plugin.register(IVTV_XINE_TV(), plugin.TV)
+
+        plugin.register(IVTV_TV(), plugin.TV)
 
 
-class IVTV_XINE_TV:
+class IVTV_TV:
 
+    __muted    = 0
+    __igainvol = 0
+    
     def __init__(self):
+        self.thread = Xine_Thread()
+        self.thread.setDaemon(1)
+        self.thread.start()
+        self.tuner_chidx = 0    # Current channel, index into 
config.TV_CHANNELS
+        self.app_mode = 'tv'
+       self.app       = None
+        self.videodev = None
+       self.fc = FreevoChannels() 
+        self.current_vg = None 
 
-        self.xine = XineThread()
-        self.xine.setDaemon(1)
-        self.xine.start()
 
-        self.tuner = TunerControl()
-        self.mixer = MixerControl()
+       
+    def TunerSetChannel(self, tuner_channel):
+        for pos in range(len(config.TV_CHANNELS)):
+            channel = config.TV_CHANNELS[pos]
+            if channel[2] == tuner_channel:
+                self.tuner_chidx = pos
+                return
+        print 'ERROR: Cannot find tuner channel "%s" in the TV channel 
listing' % tuner_channel
+        self.tuner_chidx = 0
 
-        self.app_mode = 'tv'
-        self.app = None
-        self.videodev = None
+
+    def TunerGetChannelInfo(self):
+        '''Get program info for the current channel'''
+        
+        tuner_id = config.TV_CHANNELS[self.tuner_chidx][2]
+        chan_name = config.TV_CHANNELS[self.tuner_chidx][1]
+        chan_id = config.TV_CHANNELS[self.tuner_chidx][0]
+
+        channels = epg.get_guide().GetPrograms(start=time.time(),
+                                               stop=time.time(), 
chanids=[chan_id])
+
+        if channels and channels[0] and channels[0].programs:
+            start_s = time.strftime('%H:%M', 
time.localtime(channels[0].programs[0].start))
+            stop_s = time.strftime('%H:%M', 
time.localtime(channels[0].programs[0].stop))
+            ts = '(%s-%s)' % (start_s, stop_s)
+            prog_info = '%s %s' % (ts, channels[0].programs[0].title)
+        else:
+            prog_info = 'No info'
+            
+        return tuner_id, chan_name, prog_info
 
 
+    def TunerGetChannel(self):
+        return config.TV_CHANNELS[self.tuner_chidx][2]
+        
+
+    def TunerNextChannel(self):
+        self.tuner_chidx = (self.tuner_chidx+1) % len(config.TV_CHANNELS)
+
+
+    def TunerPrevChannel(self):
+        self.tuner_chidx = (self.tuner_chidx-1) % len(config.TV_CHANNELS)
+
+        
     def Play(self, mode, tuner_channel=None, channel_change=0):
 
-        _debug_('PLAY CHAN: %s' % tuner_channel)
+       print 'PLAY CHAN: %s' % tuner_channel
+
+        if tuner_channel != None:
+            
+            try:
+                self.TunerSetChannel(tuner_channel)
+            except ValueError:
+                pass
+
+       if not tuner_channel: 
+            tuner_channel = self.fc.getChannel()
+           print 'PLAY CHAN: %s' % tuner_channel
+
+       vg = self.current_vg = self.fc.getVideoGroup(tuner_channel) 
+       print 'PLAY GROUP: %s' % vg.desc
+
+        if mode == 'tv':               
+        if vg.group_type == 'ivtv':
+            ivtv_dev = ivtv.IVTV(vg.vdev)
+            ivtv_dev.init_settings()
+            ivtv_dev.setinput(vg.input_num)
+# CO by JM           ivtv_dev.print_settings()
+            self.fc.chanSet(tuner_channel)
+
+#            command = '%s -V --no-splash --no-lirc --stdctl pvr://' % 
config.XINE_COMMAND
+            command = '%s -V --no-splash --no-lirc --stdctl %s 
pvr:///home/livetv' % (config.XINE_COMMAND, config.XINE_ARGS_DEF)
+        else:
+            print 'Mode "%s" is not implemented' % mode  # XXX ui.message()
+            return
+
 
         self.mode = mode
 
+        # XXX Mixer manipulation code.
+        # TV is on line in
+        # VCR is mic in
+        # btaudio (different dsp device) will be added later
+        mixer = plugin.getbyname('MIXER')
+        
+        if mixer and config.MAJOR_AUDIO_CTRL == 'VOL':
+            mixer_vol = mixer.getMainVolume()
+            mixer.setMainVolume(0)
+        elif mixer and config.MAJOR_AUDIO_CTRL == 'PCM':
+            mixer_vol = mixer.getPcmVolume()
+            mixer.setPcmVolume(0)
+
+        # Start up the TV task
+        self.thread.mode = 'play'
+        self.thread.command = command
+        self.thread.mode_flag.set()
+        
         self.prev_app = rc.app()
         rc.app(self)
 
-        self.tuner.SetChannel(mode, tuner_channel)
-        self.mixer.prepare()
-        self.xine.play()
+        if osd.focused_app():
+            osd.focused_app().hide()
 
         # Suppress annoying audio clicks
         time.sleep(0.4)
-        self.mixer.start(mode)
-
-        _debug_('%s: started %s app' % (time.time(), self.mode))
-
-
-    def Pause(self):
-
-        self.xine.pause()
+        # XXX Hm.. This is hardcoded and very unflexible.
+        if mixer and mode == 'vcr':
+            mixer.setMicVolume(config.VCR_IN_VOLUME)
+        elif mixer:
+            mixer.setLineinVolume(config.TV_IN_VOLUME)
+            mixer.setIgainVolume(config.TV_IN_VOLUME)
+            
+        if mixer and config.MAJOR_AUDIO_CTRL == 'VOL':
+            mixer.setMainVolume(mixer_vol)
+        elif mixer and config.MAJOR_AUDIO_CTRL == 'PCM':
+            mixer.setPcmVolume(mixer_vol)
 
+        if DEBUG: print '%s: started %s app' % (time.time(), self.mode)
 
+        
     def Stop(self):
+        mixer = plugin.getbyname('MIXER')
+        mixer.setLineinVolume(0)
+        mixer.setMicVolume(0)
+        mixer.setIgainVolume(0) # Input on emu10k cards.
+
+        self.thread.mode = 'stop'
+        self.thread.mode_flag.set()
 
-        self.mixer.stop()
-        self.xine.stop()
         rc.app(self.prev_app)
-        rc.post_event(PLAY_END)
+       #JM +PLAY_END
+       rc.post_event(PLAY_END)
+        if osd.focused_app():
+           osd.focused_app().show() 
+           
+        while self.thread.mode == 'stop':
+            time.sleep(0.05)
+        print 'stopped %s app' % self.mode
 
-        _debug_('stopped %s app' % self.mode)
 
 
     def eventhandler(self, event, menuw=None):
+        print '%s: %s app got %s event' % (time.time(), self.mode, event)
+       s_event = '%s' % event
+
+# The following events need to be defined in events.py (check that) first
 
-        _debug_('%s: %s app got %s event' % (time.time(), self.mode, event))
-        s_event = '%s' % event
+#        if event == FASTFORWARD:
+#            self.thread.app.write('SpeedFaster\n')
+#            return True
+
+#        if event == REWIND:
+#            self.thread.app.write('SpeedSlower\n')
+#            return True
+  
+        if event == MIXER_VOLUP:
+            self.thread.app.write('Volume+\n')
+            return True
 
+        if event == MIXER_VOLDOWN:
+            self.thread.app.write('Volume-\n')
+            return True
+    
         if event == STOP or event == PLAY_END:
             self.Stop()
+            rc.post_event(PLAY_END)
+            return TRUE
+        
+       if event == PAUSE or event == PLAY:
+            self.thread.app.write('pause\n')
             return True
 
-        if event == PAUSE or event == PLAY:
-            self.Pause()
-            return True
+#        if event == UP:
+#            self.thread.app.write('EventUp\n')
+#          return True
 
-        if event in [ TV_CHANNEL_UP, TV_CHANNEL_DOWN] or 
s_event.startswith('INPUT_'):
+#        if event == DOWN:
+#            self.thread.app.write('EventDown\n')
+#            return True
 
-            if event == TV_CHANNEL_UP:
-                self.tuner.NextChannel()
 
-            elif event == TV_CHANNEL_DOWN:
-                self.tuner.PrevChannel()
+        if event == MENU_GOTO_MAINMENU:
+           self.thread.app.write('TitleMenu\n')
+            return True
 
+# Add to events.py
+#        if event == SUBTITLE:
+#          self.thread.app.write('SpuNext\n')
+#          return True
+    
+        if event == STOP:
+            self.thread.app.write('Quit\n')
+            for i in range(10):
+                if self.thread.mode == 'idle':
+                    break
+                time.sleep(0.3)
             else:
-                self.tuner.TuneChannel( int(s_event[6]) )
-
-            #cmd = 'osd_show_text "%s"\n' % "CHANNEL CHANGE!"
-            #self.xine.app.write(cmd)
-
-            return True
+                # sometimes xine refuses to die
+                self.Stop()
+            return TRUE
 
+#        if event == STOP:
+#            self.stop()
+#            return self.item.eventhandler(event)
+     
+       if event in [ TV_CHANNEL_UP, TV_CHANNEL_DOWN] or 
s_event.startswith('INPUT_'):
+            if event == TV_CHANNEL_UP:
+                nextchan = self.fc.getNextChannel()
+            elif event == TV_CHANNEL_DOWN:
+                nextchan = self.fc.getPrevChannel()
+            else:
+                chan = int( s_event[6] )
+                nextchan = self.fc.getManChannel(chan)
+                
+
+          # tuner_id, chan_name, prog_info = self.fc.getChannelInfo()
+           # now = time.strftime('%H:%M')
+           # msg = '%s %s (%s): %s' % (now, chan_name, tuner_id, prog_info)
+           #cmd = 'osd_show_text "%s"\n' % msg 
+           
+           print 'NEXT CHAN: %s' % nextchan
+            nextvg = self.fc.getVideoGroup(nextchan)
+            print 'NEXT GROUP: %s' % nextvg.desc
+
+            if self.current_vg != nextvg:
+                self.Stop(channel_change=1)
+                self.Play('tv', nextchan)
+                return TRUE
+
+            if self.mode == 'vcr':
+                return   
+
+           elif self.current_vg.group_type == 'ivtv':
+                self.fc.chanSet(nextchan)
+                self.thread.app.write('seek 999999 0\n')
+           else:
+               freq_khz = self.fc.chanSet(nextchan, app=self.thread.app)
+                new_freq = '%1.3f' % (freq_khz / 1000.0)
+                self.thread.app.write('tv_set_freq %s\n' % new_freq)
+       
+            self.current_vg = self.fc.getVideoGroup(self.fc.getChannel())
+           
+           # Display a channel changed message  (mplayer ?  api osd xine ?) 
+            tuner_id, chan_name, prog_info = self.fc.getChannelInfo()
+            now = time.strftime('%H:%M')
+            msg = '%s %s (%s): %s' % (now, chan_name, tuner_id, prog_info)
+            cmd = 'osd_show_text "%s"\n' % msg
+            self.thread.app.write(cmd)
+            return TRUE
+           
 
         if event == SEEK:
-
             pos = int(event.arg)
-
             if pos < 0:
                 action='SeekRelative-'
                 pos = 0 - pos
-
             else:
                 action='SeekRelative+'
-
             if pos <= 15:
                 pos = 15
-
             elif pos <= 30:
                 pos = 30
-
             else:
                 pos = 30
-
-            self.xine.app.write('%s%s\n' % (action, pos))
-            return TRUE
-
-        if event == TOGGLE_OSD:
-            self.xine.app.write('OSDStreamInfos\n')
+            self.thread.app.write('%s%s\n' % (action, pos))
+            return TRUE 
+        
+       if event == TOGGLE_OSD:
+            self.thread.app.write('OSDStreamInfos\n')
             return True
-
-# ======================================================================
-
-class TunerControl:
-
-    def __init__(self):
-
-        self.current_vgrp = None
-        self.fc = FreevoChannels()
-        self.current_chan = 0 # Current channel, index into config.TV_CHANNELS
-
-
-    def SetChannel(self, mode, channel=None):
-
-        if (channel == None):
-            self.current_chan = self.fc.getChannel()
-
-        else:
-            self.current_chan = -1
-
-            try:
-                for pos in range(len(config.TV_CHANNELS)):
-                    entry = config.TV_CHANNELS[pos]
-                    if channel == entry[2]:
-                        channel_index = pos
-                        self.current_chan = channel
-                        break
-
-            except ValueError:
-                pass
-
-            if (self.current_chan == -1):
-                _debug_("ERROR: Cannot find tuner channel '%s' in the TV 
channel listing" % channel)
-                self.current_chan = 0
-                channel_index = 0
-
-        _debug_('PLAY CHAN: %s' % self.current_chan)
-
-        vg = self.current_vgrp = self.fc.getVideoGroup(self.current_chan)
-        _debug_('PLAY GROUP: %s' % vg.desc)
-
-        if (mode == 'tv') and (vg.group_type == 'ivtv'):
-            ivtv_dev = ivtv.IVTV(vg.vdev)
-            ivtv_dev.init_settings()
-            ivtv_dev.setinput(vg.input_num)
-            ivtv_dev.print_settings()
-            self.TuneChannel(channel_index + 1)
-
-        else:
-            _debug_('Mode "%s" is not implemented' % mode)
-            pop = AlertBox(text=_('This plugin only supports the ivtv video 
group in tv mode!'))
-            pop.show()
-            return
-
-
-    def NextChannel(self):
-        nextchan = self.fc.getNextChannel()
-        self.SetVideoGroup(nextchan)
-
-
-    def PrevChannel(self):
-        nextchan = self.fc.getPrevChannel()
-        self.SetVideoGroup(nextchan)
-
-
-    def TuneChannel(self, chan):
-        nextchan = self.fc.getManChannel(chan)
-        self.SetVideoGroup(nextchan)
-
-
-    def SetVideoGroup(self, chan):
-        _debug_('CHAN: %s' % chan)
-        vg = self.fc.getVideoGroup(chan)
-        _debug_('GROUP: %s' % vg.desc)
-
-        if self.current_vgrp != vg:
-            # XXX HANDLE THIS
-            self.Stop(channel_change=1)
-            self.Play('tv', nextchan)
-            return
-
-        #if self.mode == 'vcr':
-        #    # XXX HANDLE THIS
-        #    return
-
-        if self.current_vgrp.group_type == 'ivtv':
-            self.fc.chanSet(chan)
-            #self.xine.app.write('seek 999999 0\n')
-
-        else:
-            freq_khz = self.fc.chanSet(chan, app=self.xine.app)
-            new_freq = '%1.3f' % (freq_khz / 1000.0)
-            #self.xine.app.write('tv_set_freq %s\n' % new_freq)
-
-        self.current_vgrp = self.fc.getVideoGroup(self.fc.getChannel())
-
-        # Display a channel changed message (mplayer ? api osd xine ?)
-        tuner_id, chan_name, prog_info = self.fc.getChannelInfo()
-        now = time.strftime('%H:%M')
-        msg = '%s %s (%s): %s' % (now, chan_name, tuner_id, prog_info)
-        cmd = 'osd_show_text "%s"\n' % msg
-        #self.xine.app.write(cmd)
-
-
-    def GetChannelInfo(self):
-
-        '''Get program info for the current channel'''
-
-        tuner_id = config.TV_CHANNELS[self.current_chan][2]
-        chan_name = config.TV_CHANNELS[self.current_chan][1]
-        chan_id = config.TV_CHANNELS[self.current_chan][0]
-
-        channels = epg.get_guide().GetPrograms(
-            start=time.time(),
-            stop=time.time(), chanids=[chan_id]
-        )
-
-        if channels and channels[0] and channels[0].programs:
-            start_s = time.strftime('%H:%M', 
time.localtime(channels[0].programs[0].start))
-            stop_s = time.strftime('%H:%M', 
time.localtime(channels[0].programs[0].stop))
-            ts = '(%s-%s)' % (start_s, stop_s)
-            prog_info = '%s %s' % (ts, channels[0].programs[0].title)
-
-        else:
-            prog_info = 'No info'
-
-        return tuner_id, chan_name, prog_info
-
-
-#    def GetChannel(self):
-
-#        return config.TV_CHANNELS[self.current_chan][2]
-
-
-#    def NextChannel(self):
-
-#        self.current_chan = (self.current_chan+1) % len(config.TV_CHANNELS)
-
-
-#    def PrevChannel(self):
-
-#        self.current_chan = (self.current_chan-1) % len(config.TV_CHANNELS)
-
-
+                   
 # ======================================================================
 
-class MixerControl:
-
-    # XXX Mixer manipulation code.
-    # TV is on line in
-    # VCR is mic in
-    # btaudio (different dsp device) will be added later
-
-    def __init__(self):
-
-        self.mixer = plugin.getbyname('MIXER')
-        self.volume = 0
-
-    def prepare(self):
-
-        if (self.mixer != None):
-
-            if config.MAJOR_AUDIO_CTRL == 'VOL':
-                self.volume = self.mixer.getMainVolume()
-                self.mixer.setMainVolume(0)
-
-            elif config.MAJOR_AUDIO_CTRL == 'PCM':
-                self.volume = self.mixer.getPcmVolume()
-                self.mixer.setPcmVolume(0)
-
-    def start(self, mode):
-
-
-        if (self.mixer != None):
-
-            # XXX Hm.. This is hardcoded and very unflexible.
-            if mode == 'vcr':
-                self.mixer.setMicVolume(config.VCR_IN_VOLUME)
-
-            else:
-                self.mixer.setLineinVolume(config.TV_IN_VOLUME)
-                self.mixer.setIgainVolume(config.TV_IN_VOLUME)
-
-            if config.MAJOR_AUDIO_CTRL == 'VOL':
-                self.mixer.setMainVolume(self.volume)
-
-            elif config.MAJOR_AUDIO_CTRL == 'PCM':
-                self.mixer.setPcmVolume(self.volume)
-
-
-    def stop(self):
-
-        if (self.mixer != None):
-            self.mixer.setLineinVolume(0)
-            self.mixer.setMicVolume(0)
-            self.mixer.setIgainVolume(0) # Input on emu10k cards.
-
-
-# ======================================================================
-
-
-class XineApp(childapp.ChildApp2):
+class XineApp(childapp.ChildApp):
     """
     class controlling the in and output from the xine process
     """
 
     def __init__(self, app, item):
-
         self.item = item
-        childapp.ChildApp2.__init__(self, app)
-        _debug_('XineApp: Started, cmd=%s' % app)
-        # self.exit_type = None # ??
+        childapp.ChildApp.__init__(self, app)
+        self.exit_type = None
+        
+    def kill(self):
+        # Use SIGINT instead of SIGKILL to make sure Xine shuts
+        # down properly and releases all resources before it gets
+        # reaped by childapp.kill().wait()
+        #childapp.ChildApp.kill(self, signal.SIGINT)
+       #JM change to SIGKILL to test resolution for freevo crash from df_xine 
crash
+        childapp.ChildApp.kill(self, signal.SIGTERM)
 
 
 # ======================================================================
 
-
-class XineThread(threading.Thread):
+class Xine_Thread(threading.Thread):
     """
     Thread to wait for a xine command to play
     """
 
     def __init__(self):
-
         threading.Thread.__init__(self)
+        
+        self.mode      = 'idle'
+        self.mode_flag = threading.Event()
+        self.command   = ''
+        self.app       = None
+        self.item  = None
 
-        self.app = None
-        self.item = None
-        self.mode = 'idle'
-        self.start_flag = threading.Event()
-        self.command = '%s %s -V %s -A %s --stdctl pvr://%s' % \
-            (config.XINE_COMMAND, config.XINE_ARGS_DEF, config.XINE_TV_VO_DEV, 
\
-            config.XINE_TV_AO_DEV, config.XINE_TV_TIMESHIFT_FILEMASK)
-
-    def play(self):
-
-        if (self.mode == 'idle'):
-            self.start_flag.set()
-
-    def pause(self):
-
-        if (self.mode == 'busy') or (self.mode == 'pause'):
-            self.mode = 'pause'
-
-    def stop(self):
-
-        if (self.mode == 'busy') or (self.mode == 'pause'):
-            self.mode = 'stop'
-
-        while (self.mode == 'busy') or (self.mode == 'pause'):
-            sleep(0.1)
-
-
+        
     def run(self):
-
         while 1:
-
             if self.mode == 'idle':
-                self.start_flag.wait()
-                self.start_flag.clear()
+                self.mode_flag.wait()
+                self.mode_flag.clear()
 
-            else:
-                _debug_("XineThread: Should be idle on thread entry!")
+            elif self.mode == 'play':
+                if DEBUG:
+                    print 'Xine_Thread.run(): Started, cmd=%s' % self.command
+                    
+                self.app = XineApp(self.command, self.item)
 
-            self.app = XineApp(self.command, self.item)
-            self.mode = 'busy'
-
-            while self.app.isAlive():
-
-                if self.mode == 'busy':
+                while self.mode == 'play' and self.app.isAlive():
                     time.sleep(0.1)
 
-                elif self.mode == 'pause':
-                    self.app.write('pause\n')
-                    self.mode = 'busy'
-
-                elif self.mode == 'stop':
-                    self.app.stop("quit\n")
+                self.app.kill()
 
+                if self.mode == 'play':
+                    if DEBUG: print 'posting play_end'
+                    rc.post_event(PLAY_END)
+                        
+                if DEBUG:
+                    print 'Xine_Thread.run(): Stopped'
 
-            self.mode = 'idle'
-
-            _debug_('XineThread: Stopped')
-            self.mode = 'idle'
+                self.mode = 'idle'
+                
+            else:
+                self.mode = 'idle'

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog

Reply via email to