Robert Winder wrote:
On Friday, December 10, 2004, 14:30, Bart wrote:


Hi all,


I don't think Robert is the author, it think it was rshort who hacked this
plugin toghetter but it never made it in cvs.

The header has turned up. I have prepended it to my version. See the attach with some performance improvements over the earlier version.




It was Aubin Paul who made it initially based upon the ivtv mplayer
plugin from rshort. Not sure what happened with the revision and
copyright notice. Sorry about that.


I'm also using this plugin with freevo 1.5.2 for some time. I'm also using
it with a epia and the xxmc xine plugin so I have hardware acceleration.
Just like Paul I have to hit pause and play after starting it, if not the
playback is choppy. Didn't have to do that before but it realy doesn't bother
me. The biggest problem I have is that yo can't choose the buffer lenght.
I think with my pvr250 settings the buffer is full after 20 minutes. Lets
hope for better timeshift support in freevo 2.0 :-)


Bart


Strange, I don't have to pause before playing. Using xv output here.
Maybe xxmc takes longer to initialize. This is with Ivtv streamtype
10 btw. When needed the timeshift file can be enlarged with the
#define BLOCKS_PER_PAGE in the input_pvr_plugin itself.

http://cvs.sourceforge.net/viewcvs.py/xine/xine-lib/src/input/input_pvr.c?rev=1.51&view=markup


Hmm, will have a look into that. one would say that 10000 200MB pages should be sufficient.


From my own experiences slow channel flipping is caused by the ivtv
driver itself. Running ivtv-0.2.0-rc3.tgz myself and seems reasonable
fast.


found that the biggest issue is that the player may not be playing the end of the bufer when flipping the channel. So it takes a while before I am seeing the part of the buffer when the channel whas changed.


/Robert






-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now. http://productguide.itmanagersjournal.com/
_______________________________________________
Freevo-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/freevo-devel


--
Paul Sijben             mailto:[EMAIL PROTECTED]
Amersfoort, NL          http://www.sijben.net
tel:+31 334557522       fax:+31 33 4557523
#if 0 /*
# -----------------------------------------------------------------------
# ivtv_basic_tv.py - Simple tv viewing plugin for ivtv based cards.
# -----------------------------------------------------------------------
# $Id: ivtv_pause.py,v 1.1 2003/08/03 13:27:36 outlyer Exp $
#
# Notes:
#        To activate this plugin you must do this in your local_conf.py:
#          plugin.remove('tv.mplayer')
#          plugin.activate('tv.ivtv_xine_tv')
#and set TIMESHIFT_BUFFER to a filename on a partition with a few GB to spare
# Todo:        
# xine sometimes does not start right, no image at all or slow moving image
# the first case is remedied for the time being by pressing stop and then OK on 
the
# remote control. The second case is remedied by pressing pause twice
# to activate this plugin put the following into you local_conf.py:
#
# -----------------------------------------------------------------------
#
# Revision 1.2 nd 1.3 by Paul Sijben
# adapted for Freevo 1.5.2 still moderately horrible and xine has 
# insufficient remote control over its playing capablities 
# and OSD control is completely out of the question....
#
# $Log: ivtv_pause.py,v $
# Revision 1.1  2003/08/03 13:27:36  outlyer
# A horrible, but working example of xine-pvr support for Freevo.
#
#
#
#
# -----------------------------------------------------------------------
# Freevo - A Home Theater PC framework
# Copyright (C) 2002 Krister Lagerstrom, et al. 
# Please see the file freevo/Docs/CREDITS for a complete list of authors.
#
# This program 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 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MER-
# CHANTABILITY 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 this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# ----------------------------------------------------------------------- */
#endif

# adapted for Freevo 1.5.2 from code by Robert Winder(?) by Paul Sijben
#TODO: xine sometimes does not start right, no image at all or slow moving image
# the first case is remedied for the time being by pressing stop and then OK on 
the 
# remote control. The second case is remedied by pressing pause twice
# to activate this plugin put the following into you local_conf.py:
#plugin.remove('tv.mplayer')
#plugin.activate('tv.ivtv_xine_tv')
#
#and set TIMESHIFT_BUFFER to a filename on a partition with a few GB to spare
#


import config
import time, os
import util    # Various utilities
from event import *
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 *


# Set to 1 for debug output
DEBUG = config.DEBUG

TRUE = 1
FALSE = 0


# Create the OSD object
osd = osd.get_singleton()

class PluginInterface(plugin.Plugin):
    """
    Plugin to watch tv with xine.
    """
    def __init__(self):
        plugin.Plugin.__init__(self)
        try:
            config.XINE_COMMAND
        except:
            print String(_( 'ERROR' )) + ': ' + \
                  String(_("'XINE_COMMAND' not defined, plugin 'xine' 
deactivated.\n" \
                           'please check the xine section in freevo_config.py' 
))
            return

        if config.XINE_COMMAND.find('fbxine') >= 0:
            type = 'fb'
        else:
            type = 'X'

        if not hasattr(config, 'XINE_VERSION'):
            config.XINE_VERSION = 0
            for data in util.popen3.stdout('%s --version' % 
config.XINE_COMMAND):
                m = re.match('^.* v?([0-9])\.([0-9]+)\.([0-9]*).*', data)
                if m:
                    config.XINE_VERSION = int('%02d%02d%02d' % (int(m.group(1)),
                                                                  
int(m.group(2)),
                                                                  
int(m.group(3))))
                    if data.find('cvs') >= 0:
                        config.XINE_VERSION += 1

            _debug_('detect xine version %s' % config.XINE_VERSION)

        if config.XINE_VERSION < 922:
            print String(_( 'ERROR' )) + ': ' + \
                  String(_( "'xine-ui' version too old, plugin 'xine' 
deactivated" ))
            print String(_( 'You need software %s' )) % 'xine-ui > 0.9.21'
            return

        # register xine as the object to play
        plugin.register(IVTV_TV(type,config.XINE_VERSION), plugin.TV)


class IVTV_TV:

    __muted    = 0
    __igainvol = 0
    
    def __init__(self,type,version):
        self.tuner_chidx = 0    # Current channel, index into config.TV_CHANNELS
        self.app_mode = 'tv'
        self.app       = None
        self.type = type
        self.version=version
        self.fc = FreevoChannels() 
        self.current_vg = None 


        
    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


    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):

        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)
            ivtv_dev.print_settings()
            self.fc.chanSet(tuner_channel)

            command = [ '--prio=%s' % config.MPLAYER_NICE ] + \
                        config.XINE_COMMAND.split(" ") + \
                        [ '--stdctl' , '-V', config.XINE_VO_DEV,\
                        '-A', config.XINE_AO_DEV ] + \
                        config.XINE_ARGS_DEF.split(" ")+\
                         [ ' pvr://%s' % config.TIMESHIFT_BUFFER ]

        else:
            print 'Mode "%s" is not implemented' % mode  # XXX ui.message()
            return

        if not rc.PYLIRC and '--no-lirc' in command:
                command.remove('--no-lirc')

        if self.version < 923:
                for arg in command:
                        if arg.startswith('--post'):
                                command.remove(arg)
                                break


        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
        
        _debug_('Xine.play() Starting cmd=%s' % command)
        self.app=childapp.ChildApp2(command)
        self.prev_app=rc.app()
        rc.app(self)
        
        if osd.focused_app():
            osd.focused_app().hide()

        # Suppress annoying audio clicks
        time.sleep(0.4)
        # 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)
        #self.app.write('pause\n')
        time.sleep(2)
        self.app.write('SeekRelative-15\n')
        if DEBUG: print '%s: started %s app' % (time.time(), self.mode)
         
    def Stop(self, channel_change=0):
        mixer = plugin.getbyname('MIXER')
        if mixer and not channel_change:
                mixer.setLineinVolume(0)
                mixer.setMicVolume(0)
                mixer.setIgainVolume(0) # Input on emu10k cards.

        self.app.stop('quit\n')

        if osd.focused_app() and not channel_change:
           osd.focused_app().show() 
        if os.path.exists('/tmp/freevo.wid'): os.unlink('/tmp/freevo.wid')
        if os.path.exists(config.TIMESHIFT_BUFFER+"0*"): 
                os.unlink(config.TIMESHIFT_BUFFER+"0*")

        print '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

        if event == STOP or event == PLAY_END:
            self.Stop()
            rc.post_event(PLAY_END)
            return TRUE
        
        if event == PAUSE or event == PLAY or (event==BUTTON and 
event.arg==PLAY):
            self.app.write('pause\n')
            return TRUE

        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)
                        
            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)
            else:
                freq_khz = self.fc.chanSet(nextchan, app=self.app)
            self.app.write('SeekRelative+60\n')

            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.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.app.write('%s%s\n' % (action, pos))
            return TRUE 
        
        if event == TOGGLE_OSD:
            self.app.write('OSDStreamInfos\n')
            return TRUE
        
        if event == VIDEO_TOGGLE_INTERLACE:
                self.app.write('ToggleInterleave\n')
                self.item['deinterlace'] = not self.item['deinterlace']
                return TRUE

        return  FALSE          

Reply via email to