Author: dmeyer
Date: Sat Oct 15 18:48:22 2005
New Revision: 7705
Added:
trunk/freevo-tvdev/
trunk/freevo-tvdev/bin/
trunk/freevo-tvdev/bin/freevo-tvdev (contents, props changed)
trunk/freevo-tvdev/setup.py
trunk/freevo-tvdev/src/
trunk/freevo-tvdev/src/__init__.py
trunk/freevo-tvdev/src/control.py
- copied, changed from r7699, /trunk/freevo/src/helpers/recorder.py
trunk/freevo-tvdev/src/devices.py
trunk/freevo-tvdev/src/tvcards.py
- copied, changed from r7699, /trunk/freevo/src/config/tvcards.py
Log:
create freevo-tvdev package
Added: trunk/freevo-tvdev/bin/freevo-tvdev
==============================================================================
--- (empty file)
+++ trunk/freevo-tvdev/bin/freevo-tvdev Sat Oct 15 18:48:22 2005
@@ -0,0 +1,111 @@
+#!/usr/bin/env python
+
+import sys
+import os
+import socket
+import getopt
+import ConfigParser
+import logging
+
+import kaa
+
+# insert freevo path information
+__site__ = '../lib/python%s.%s/site-packages' % sys.version_info[:2]
+__site__ = os.path.normpath(os.path.join(os.path.dirname(__file__), __site__))
+if not __site__ in sys.path:
+ sys.path.insert(0, __site__)
+
+# freevo imports
+from freevo.tvdev import tvcards
+from freevo.tvdev.control import Recorder
+
+# get logging object
+log = logging.getLogger()
+
+# set logging to info for debuggin
+logging.getLogger().setLevel(logging.INFO)
+
+# get the location of the config file
+if os.getuid() == 0:
+ # we are root, use /etc/freevo as location for the config file
+ cfgfile = '/etc/freevo'
+else:
+ # user calling this, use ~/.freevo as base
+ cfgfile = os.path.expanduser('~/.freevo')
+
+# set config file
+cfgfile = os.path.join(cfgfile, 'tvdev-%s.conf' % socket.gethostname())
+
+
+def usage():
+ print 'usage:'
+ print '"%s" to start' % sys.argv[0]
+ print '"%s list" to list all devices' % sys.argv[0]
+ print '"%s configure device help" to get help on configuration' %
sys.argv[0]
+ print '"%s configure device key=value [key=value ...]" to configure card'
% sys.argv[0]
+ print
+ print 'options:'
+ print '-c config file [ default = %s ]' % cfgfile
+ sys.exit(0)
+
+
+options = 'hc:'
+loptions = ['help']
+
+try:
+ opts, args = getopt.getopt(sys.argv[1:], options, loptions)
+except getopt.GetoptError, e:
+ print 'Error:', e
+ usage()
+
+for o, a in opts:
+ if o in ('-h', '--help'):
+ usage()
+ if o == '-c':
+ cfgfile = a
+
+if len(args) == 0:
+ # create recorder
+ r = Recorder()
+
+ # start main loop
+ kaa.main()
+
+ # print debug at the end
+ log.info('terminate')
+ sys.exit(0)
+
+if args[0] == 'list':
+ tvcards.detect(cfgfile)
+ for key, card in tvcards.TV_CARDS.items():
+ print '*** %s ***' % key
+ print card.info()
+ sys.exit(0)
+
+elif args[0] == 'configure':
+ if len(args) < 2:
+ usage()
+ tvcards.detect(cfgfile)
+ device = args[1]
+ if not device in tvcards.TV_CARDS:
+ print 'Invalid device %s' % device
+ sys.exit(1)
+ if len(args) == 3 and args[2] == 'help':
+ print 'Card info:'
+ print ' ' + '\n '.join(tvcards.TV_CARDS[device].info().split('\n'))
+ print 'You can set the following variables:'
+ for key in tvcards.TV_CARDS[device].variables():
+ print ' %s' % key
+ sys.exit(0)
+
+ for var in args[2:]:
+ if len(var.split('=')) != 2:
+ usage()
+ key, value = var.split('=')
+ if not key in tvcards.TV_CARDS[device].variables():
+ print 'unknown variable %s' % key
+ tvcards.TV_CARDS[device].set(key, value)
+ tvcards.save()
+
+else:
+ usage()
Added: trunk/freevo-tvdev/setup.py
==============================================================================
--- (empty file)
+++ trunk/freevo-tvdev/setup.py Sat Oct 15 18:48:22 2005
@@ -0,0 +1,18 @@
+# Python distutils stuff
+import os
+import sys
+from distutils.core import setup, Extension
+
+# now start the python magic
+setup (name = "freevo",
+ version = "2.0",
+ description = "Freevo",
+ author = "Krister Lagerstrom, et al.",
+ author_email = "[email protected]",
+ url = "http://www.freevo.org",
+ license = "GPL",
+
+ package_dir = { 'freevo.tvdev': 'src' },
+ packages = [ 'freevo.tvdev', 'freevo.tvdev' ],
+ scripts = [ 'bin/freevo-tvdev' ]
+ )
Added: trunk/freevo-tvdev/src/__init__.py
==============================================================================
Copied: trunk/freevo-tvdev/src/control.py (from r7699,
/trunk/freevo/src/helpers/recorder.py)
==============================================================================
--- /trunk/freevo/src/helpers/recorder.py (original)
+++ trunk/freevo-tvdev/src/control.py Sat Oct 15 18:48:22 2005
@@ -77,106 +77,15 @@
# kaa imports
import kaa
import kaa.record
-import kaa.epg
-
-# freevo imports
-import config
# mbus support
-from mcomm import RPCServer, RPCError, RPCReturn
-
-# get logging object
-log = logging.getLogger()
+from freevo.mcomm import RPCServer, RPCError, RPCReturn
# detect tv cards and channels
-config.detect('tvcards', 'channels')
-
-
-class Device(object):
- """
- Base class for all devices. All devices need to inherit from this class
- to get the basic recorder interface + the need to be a kaa.record device
- for the actual recording.
- """
- def __init__(self, id, card):
- self.name = id
- self.priority = card.priority
- self.bouquets = []
-
-
-class DvbDevice(kaa.record.DvbDevice, Device):
- """
- Class for handling a DVB card. It is based on kaa.record.DvbDevice and
- only adds conversion between global channel ids and dvb ids.
- """
- def __init__(self, id, card):
- kaa.record.DvbDevice.__init__(self, card.adapter, card.channels_conf)
- Device.__init__(self, id, card)
- self.id2dvb = {}
- self.dvb2id = {}
-
- # Create dvb to global id mapping. Maybe having one
- # access id is not the way to go here
- for channel in kaa.epg.channels:
- self.id2dvb[channel.id] = channel.access_id
- self.dvb2id[channel.access_id] = channel.id
-
- for bouquet in self.get_bouquet_list():
- self.bouquets.append([])
- for chan in bouquet:
- if not chan in self.dvb2id:
- log.debug('unknown channel %s' % chan)
- continue
- self.bouquets[-1].append(self.dvb2id[chan])
-
-
- def start_recording(self, channel, output):
- """
- Start a recording (transform channel id). Since the recorder in this
- module only adds one filter to the recording scheduler, we need to
- create the correct cahin here.
- """
- chain = kaa.record.Chain()
- chain.append(kaa.record.Remux())
- chain.append(output)
- channel = self.id2dvb[channel]
- return kaa.record.DvbDevice.start_recording(self, channel, chain)
+import devices
-
-class IVTVDevice(kaa.record.IVTVDevice, Device):
- """
- Class for handling an IVTV card, based on kaa.record.IVTVDevice.
- """
- def __init__(self, id, card):
-
- kaa.record.IVTVDevice.__init__(self, card.vdev, card.norm,
- card.chanlist, card.input, card.custom_frequencies,
card.resolution,
- card.codec['aspect'], card.codec['audio_bitmask'],
- card.codec['bframes'], card.codec['bitrate_mode'],
- card.codec['bitrate'], card.codec['bitrate_peak'],
- card.codec['dnr_mode'], card.codec['dnr_spatial'],
- card.codec['dnr_temporal'], card.codec['dnr_type'],
- card.codec['framerate'], card.codec['framespergop'],
- card.codec['gop_closure'], card.codec['pulldown'],
- card.codec['stream_type'])
-
- Device.__init__(self, id, card)
-
- log.info(card.channels)
- for c in card.channels.keys():
- self.bouquets.append([])
- self.bouquets[-1].append(c)
-
-
- def start_recording(self, channel, output):
- """
- Start a recording, create the filter chain and add the filters we care
- about.
- """
- log.info('we wish to record channel %s' % channel)
- chain = kaa.record.Chain()
- chain.append(output)
- return kaa.record.IVTVDevice.start_recording(self, channel, chain)
+# get logging object
+log = logging.getLogger()
class Recorder(RPCServer):
@@ -184,18 +93,11 @@
Recorder handling the different devices.
"""
def __init__(self):
- RPCServer.__init__(self, 'record-daemon')
- self.cards = []
+ RPCServer.__init__(self, 'tvdev')
+ self.cards = devices.DEVICES
self.recordings = {}
self.server = None
- for id, card in config.TV_CARDS.items():
- if id.startswith('dvb'):
- self.cards.append(DvbDevice(id, card))
-
- elif id.startswith('ivtv'):
- self.cards.append(IVTVDevice(id, card))
-
def __rpc_devices_list__(self, addr, val):
"""
@@ -265,13 +167,3 @@
if not self.server:
return
self.mbus_instance.send_event(self.server, event, (id,))
-
-
-# create recorder
-r = Recorder()
-
-# start main loop
-kaa.main()
-
-# print debug at the end
-log.info('terminate')
Added: trunk/freevo-tvdev/src/devices.py
==============================================================================
--- (empty file)
+++ trunk/freevo-tvdev/src/devices.py Sat Oct 15 18:48:22 2005
@@ -0,0 +1,80 @@
+import kaa.record
+import tvcards
+
+class Device(object):
+ """
+ Base class for all devices. All devices need to inherit from this class
+ to get the basic recorder interface + the need to be a kaa.record device
+ for the actual recording.
+ """
+ def __init__(self, id, card):
+ self.name = id
+ self.priority = card.priority
+ self.bouquets = []
+
+
+class DvbDevice(kaa.record.DvbDevice, Device):
+ """
+ Class for handling a DVB card. It is based on kaa.record.DvbDevice and
+ only adds conversion between global channel ids and dvb ids.
+ """
+ def __init__(self, id, card):
+ kaa.record.DvbDevice.__init__(self, card.adapter, card.channels_conf)
+ Device.__init__(self, id, card)
+
+
+ def start_recording(self, channel, output):
+ """
+ Start a recording (transform channel id). Since the recorder in this
+ module only adds one filter to the recording scheduler, we need to
+ create the correct cahin here.
+ """
+ chain = kaa.record.Chain()
+ chain.append(kaa.record.Remux())
+ chain.append(output)
+ return kaa.record.DvbDevice.start_recording(self, channel, chain)
+
+
+class IVTVDevice(kaa.record.IVTVDevice, Device):
+ """
+ Class for handling an IVTV card, based on kaa.record.IVTVDevice.
+ """
+ def __init__(self, id, card):
+
+ kaa.record.IVTVDevice.__init__(self, card.vdev, card.norm,
+ card.chanlist, card.input, card.custom_frequencies,
card.resolution,
+ card.codec['aspect'], card.codec['audio_bitmask'],
+ card.codec['bframes'], card.codec['bitrate_mode'],
+ card.codec['bitrate'], card.codec['bitrate_peak'],
+ card.codec['dnr_mode'], card.codec['dnr_spatial'],
+ card.codec['dnr_temporal'], card.codec['dnr_type'],
+ card.codec['framerate'], card.codec['framespergop'],
+ card.codec['gop_closure'], card.codec['pulldown'],
+ card.codec['stream_type'])
+
+ Device.__init__(self, id, card)
+
+ log.info(card.channels)
+ for c in card.channels.keys():
+ self.bouquets.append([])
+ self.bouquets[-1].append(c)
+
+
+ def start_recording(self, channel, output):
+ """
+ Start a recording, create the filter chain and add the filters we care
+ about.
+ """
+ log.info('we wish to record channel %s' % channel)
+ chain = kaa.record.Chain()
+ chain.append(output)
+ return kaa.record.IVTVDevice.start_recording(self, channel, chain)
+
+
+DEVICES = []
+for id, card in tvcards.TV_CARDS.items():
+ if id.startswith('dvb'):
+ DEVICES.append(DvbDevice(id, card))
+
+ elif id.startswith('ivtv'):
+ DEVICES.append(IVTVDevice(id, card))
Copied: trunk/freevo-tvdev/src/tvcards.py (from r7699,
/trunk/freevo/src/config/tvcards.py)
==============================================================================
--- /trunk/freevo/src/config/tvcards.py (original)
+++ trunk/freevo-tvdev/src/tvcards.py Sat Oct 15 18:48:22 2005
@@ -34,11 +34,15 @@
# python imports
import os
+import socket
import logging
-# freevo imports
-import config
-from util.ioctl import ioctl, pack, unpack, IOR
+# kaa imports
+from kaa.base.ioctl import ioctl, pack, unpack, IOR
+from kaa.record.v4l_tuner import V4L
+
+# freevo core imports
+from freevo import conf
# get logging object
log = logging.getLogger('config')
@@ -46,19 +50,60 @@
class TVCard(object):
"""
+ Base class for tv cards.
+ """
+ def __init__(self, device, config):
+ self.device = device
+ self.config = config[device]
+ self.priority = self.config.getint('priority', 0)
+ self.channels_conf = ''
+ self.active = self.config.getboolean('active', True)
+ self.configured = True
+
+ def variables(self):
+ return [ 'channels_conf', 'priority', 'active' ]
+
+ def set(self, key, value):
+ if key == 'channels_conf':
+ f = open(value)
+ data = f.read()
+ f.close()
+ f = open(self.channels_conf, 'w')
+ f.write(data)
+ f.close()
+ else:
+ self.config.set(key, value)
+
+ def info(self):
+ s = 'Priority: %s\n' % self.priority
+ if self.active:
+ return s + 'Status: read to use\n'
+ elif not self.configured:
+ s += 'Status: needs configuration\n'
+ if not os.path.isfile(self.channels_conf):
+ s += 'channels.conf file is missing\n'
+ return s
+ else:
+ return s + 'Status: deactivated\n'
+
+class AnalogCard(TVCard):
+ """
Class handling an analog tv card
"""
- def __init__(self, number):
- self.vdev = '/dev/video' + number
+ def __init__(self, number, config):
+ TVCard.__init__(self, 'tv%s' % number, config)
+
+ self.vdev = '/dev/video%s' % number
self.adev = None
self.driver = 'unknown'
- self.priority = getattr(config, 'TV%s_PRIORITY' % number, 5)
+ self.priority = self.priority or 5
- # TODO: Think about using something like TV[0-9]_CHANLIST and
- # TV[0-9]_NORM, defaulting to (or we can remove) the CONF ones.
- self.norm = config.CONF.tv.upper()
- self.chanlist = config.CONF.chanlist
+ self.norm = self.config.get('norm', 'pal')
+ self.chanlist = self.config.get('chanlist', 'europe-west')
+ self.tuner = V4L(self.vdev, self.norm, self.chanlist)
+ self.name = self.tuner.card
+
# The capture resolution. The driver should have a default and
probably
# will only accept specific values. This will be left up to the user
# to override. It must be in "WIDTHxHEIGHT" format.
@@ -74,17 +119,27 @@
self.passthrough = None
# Save any user defined channel frequency mappings.
- self.custom_frequencies = getattr(config, 'TV%s_FREQUENCIES' % number,
{})
+ # self.custom_frequencies = getattr(config, 'TV%s_FREQUENCIES' %
number, {})
+
+ def variables(self):
+ return TVCard.variables(self) + [ 'norm', 'chanlist' ]
-class IVTVCard(TVCard):
+ def info(self):
+ s = 'Card: %s\n' % self.name
+ s += 'Norm: %s\n' % self.norm
+ s += 'ChanList: %s\n' % self.chanlist
+ return s + TVCard.info(self)
+
+
+class IVTVCard(AnalogCard):
"""
Class handling an ivtv analog tv card
"""
def __init__(self, number):
- TVCard.__init__(self, number)
+ AnalogCard.__init__(self, number)
- self.priority = getattr(config, 'IVTV%s_PRIORITY' % number, 7)
+ self.priority = self.priority or 7
self.input = 4
self.codec = {}
@@ -120,14 +175,16 @@
self.custom_frequencies = getattr(config, 'IVTV%s_FREQUENCIES' %
number, {})
-class DVBCard(object):
+class DVBCard(TVCard):
"""
Class handling a DVB card
"""
- def __init__(self, number):
- self.number = number
- self.adapter = '/dev/dvb/adapter' + number
-
+ def __init__(self, number, config):
+ TVCard.__init__(self, 'dvb%s' % number, config)
+
+ self.number = str(number)
+ self.adapter = '/dev/dvb/adapter%s' % number
+
INFO_ST = '128s10i'
val = pack( INFO_ST, "", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 )
devfd = os.open(self.adapter + '/frontend0', os.O_TRUNC)
@@ -137,117 +194,120 @@
name = val[0]
if val[1] == 0:
self.type = 'DVB-S'
- self.priority = 10
+ self.priority = self.priority or 10
elif val[1] == 1:
self.type = 'DVB-C'
- self.priority = 9
+ self.priority = self.priority or 9
elif val[1] == 2:
self.type = 'DVB-T'
- self.priority = 8
+ self.priority = self.priority or 8
else:
self.type = 'unknown (%s)' % val[1]
if name.find('\0') > 0:
name = name[:name.find('\0')]
self.name = name
- if hasattr(config, 'DVB%s_PRIORITY' % number):
- self.priority = getattr(config, 'DVB%s_PRIORITY' % number)
-
- if hasattr(config, 'DVB%s_CHANNELS_CONF' % number):
- self.channels_conf = getattr(config, 'DVB%s_CHANNELS_CONF' %
number)
- else:
- for path in ('~/.freevo', '~/.mplayer', '~/.xine'):
- conf = os.path.join(os.path.expanduser(path), 'channels.conf')
- if os.path.isfile(conf):
- self.channels_conf = conf
- break
- else:
- log.error('channels conf not found')
- self.channels_conf = ''
log.debug('register dvb device %s' % self.adapter)
+ def info(self):
+ s = 'Adapter: %s\n' % self.adapter
+ s += 'Card: %s\n' % self.name
+ s += 'Type: %s\n' % self.type
+ return s + TVCard.info(self)
+
+
+TV_CARDS = {}
+config = None
+
+def detect(cfgfile):
+ global config
+
+ log.info('Detecting TV cards.')
+ if not os.path.isfile(cfgfile):
+ open(cfgfile, 'w').close()
+ config = conf.Config(cfgfile)
+
+ # internal card counter
+ _analog_tv_number = 0
+ _ivtv_number = 0
+
+ for i in range(10):
+ if os.uname()[0] == 'FreeBSD':
+ if os.path.exists('/dev/bktr%s' % i):
+ key = 'tv%s' % i
+ TV_CARDS[key] = AnalogCard
+ TV_CARDS[key].vdev = '/dev/bktr%s' % i
+ TV_CARDS[key].driver = 'bsdbt848'
+ TV_CARDS[key].input = 1
+ log.debug('BSD TV card detected as %s' % key)
-# auto-load TV_CARDS:
-log.info('Detecting TV cards.')
-
-# internal card counter
-_analog_tv_number = 0
-_ivtv_number = 0
-
-for i in range(10):
- if os.uname()[0] == 'FreeBSD':
- if os.path.exists('/dev/bktr%s' % i):
- key = 'tv%s' % i
- config.TV_CARDS[key] = TVCard
- config.TV_CARDS[key].vdev = '/dev/bktr%s' % i
- config.TV_CARDS[key].driver = 'bsdbt848'
- config.TV_CARDS[key].input = 1
- log.debug('BSD TV card detected as %s' % key)
-
- continue
-
- if os.path.isdir('/dev/dvb/adapter%s' % i):
- try:
- config.TV_CARDS['dvb%s' % i] = DVBCard
- log.debug('DVB card detected as dvb%s' % i)
- except OSError:
- # likely no device attached
- pass
- except:
- log.exception('dvb detection')
-
- vdev = '/dev/video%s' % i
- if os.path.exists(vdev):
- type = 'tv'
- driver = None
- try:
- QUERYCAP_ST = "16s32s32sLL16x"
- QUERYCAP_NO = IOR('V', 0, QUERYCAP_ST)
-
- devfd = os.open(vdev, os.O_TRUNC)
- val = pack(QUERYCAP_ST, "", "", "", 0, 0)
- r = ioctl(devfd, QUERYCAP_NO, val)
- os.close(devfd)
- driver = unpack(QUERYCAP_ST, r)[0]
-
- log.debug('detected driver: %s' % driver)
-
- if driver.find('ivtv') != -1:
- type = 'ivtv'
-
- except OSError:
- # likely no device attached
- continue
- except IOError:
- # found something that doesn't speak v4l2
- continue
- except:
- log.exception('tv detection')
continue
- if type == 'ivtv':
- key = '%s%s' % (type, _ivtv_number)
- log.debug('IVTV card detected as %s' % key)
- config.TV_CARDS[key] = IVTVCard
- if _ivtv_number != i:
- config.TV_CARDS[key].vdev = vdev
- _ivtv_number += 1
+ if os.path.isdir('/dev/dvb/adapter%s' % i):
+ try:
+ TV_CARDS['dvb%s' % i] = DVBCard(i, config)
+ log.debug('DVB card detected as dvb%s' % i)
+ except OSError:
+ # likely no device attached
+ pass
+ except:
+ log.exception('dvb detection')
+
+ vdev = '/dev/video%s' % i
+ if os.path.exists(vdev):
+ type = 'tv'
+ driver = None
+ try:
+ QUERYCAP_ST = "16s32s32sLL16x"
+ QUERYCAP_NO = IOR('V', 0, QUERYCAP_ST)
+
+ devfd = os.open(vdev, os.O_TRUNC)
+ val = pack(QUERYCAP_ST, "", "", "", 0, 0)
+ r = ioctl(devfd, QUERYCAP_NO, val)
+ os.close(devfd)
+ driver = unpack(QUERYCAP_ST, r)[0]
+
+ log.debug('detected driver: %s' % driver)
+
+ if driver.find('ivtv') != -1:
+ type = 'ivtv'
+
+ except OSError:
+ # likely no device attached
+ continue
+ except IOError:
+ # found something that doesn't speak v4l2
+ continue
+ except:
+ log.exception('tv detection')
+ continue
+
+ if type == 'ivtv':
+ key = '%s%s' % (type, _ivtv_number)
+ log.debug('IVTV card detected as %s' % key)
+ TV_CARDS[key] = IVTVCard
+ if _ivtv_number != i:
+ TV_CARDS[key].vdev = vdev
+ _ivtv_number += 1
- else:
- # Default to 'tv' type as set above.
- key = '%s%s' % (type, _analog_tv_number)
- log.debug('TV card detected as %s' % key)
- config.TV_CARDS[key] = TVCard
- if _analog_tv_number != i:
- config.TV_CARDS[key].vdev = vdev
- _analog_tv_number += 1
-
- config.TV_CARDS[key].driver = driver
-
-
-# set default device
-if not config.TV_DEFAULT_DEVICE:
- for type in ['dvb0', 'tv0', 'ivtv0']:
- if type in config.TV_CARDS.keys():
- config.TV_DEFAULT_DEVICE = type[:-1]
- break
+ else:
+ # Default to 'tv' type as set above.
+ key = '%s%s' % (type, _analog_tv_number)
+ log.debug('TV card detected as %s' % key)
+ TV_CARDS[key] = AnalogCard(i, config)
+ if _analog_tv_number != i:
+ TV_CARDS[key].vdev = vdev
+ _analog_tv_number += 1
+
+ TV_CARDS[key].driver = driver
+
+ cfgdir = os.path.dirname(cfgfile)
+ for card in TV_CARDS.values():
+ cc = 'channels-%s-%s.conf' % (socket.gethostname(), card.device)
+ card.channels_conf = os.path.join(cfgdir, cc)
+ if not os.path.isfile(card.channels_conf):
+ card.active = False
+ card.configured = False
+
+def save():
+ config.save()
-------------------------------------------------------
This SF.Net email is sponsored by:
Power Architecture Resource Center: Free content, downloads, discussions,
and more. http://solutions.newsforge.com/ibmarch.tmpl
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog