Author: schwardt
Date: Sat Feb 10 18:16:33 2007
New Revision: 2474
Added:
trunk/WIP/record/src/device.py
trunk/WIP/record/src/dvbconfigreader.py
trunk/WIP/record/src/dvbdevice.py
trunk/WIP/record/src/version.py
Modified:
trunk/WIP/record/src/record.py
Log:
updated versions (untested - may be broken!)
Added: trunk/WIP/record/src/device.py
==============================================================================
--- (empty file)
+++ trunk/WIP/record/src/device.py Sat Feb 10 18:16:33 2007
@@ -0,0 +1,51 @@
+# -*- coding: iso-8859-1 -*-
+# -----------------------------------------------------------------------------
+# device.py - Devices for recordings
+# -----------------------------------------------------------------------------
+# $Id$
+#
+# This file defines the possible devices for recording.
+#
+# -----------------------------------------------------------------------------
+# kaa-record - A recording module
+# Copyright (C) 2007 S�nke Schwardt, Dirk Meyer
+#
+# First Edition: S�nke Schwardt <[EMAIL PROTECTED]>
+# Maintainer: S�nke Schwardt <[EMAIL PROTECTED]>
+#
+# Please see the file doc/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
+#
+# -----------------------------------------------------------------------------
+
+class Device(object):
+ """
+ Basic device class defining the needed functions all devices need to
+ provide. Override all the functions without calling this class.
+ """
+ def start_recording(self, channel, filter_chain):
+ """
+ Start recording the channel to the filter chain. This function needs
+ to return a unique id for stopping the recording later.
+ """
+ raise RuntimeError('start_recording undefined')
+
+
+ def stop_recording(self, id):
+ """
+ Stop the recording with the given id.
+ """
+ raise RuntimeError('stop_recording undefined')
Added: trunk/WIP/record/src/dvbconfigreader.py
==============================================================================
--- (empty file)
+++ trunk/WIP/record/src/dvbconfigreader.py Sat Feb 10 18:16:33 2007
@@ -0,0 +1,350 @@
+#!/usr/bin/python
+# -*- coding: iso-8859-1 -*-
+# -----------------------------------------------------------------------------
+# device.py - Devices for recordings
+# -----------------------------------------------------------------------------
+# $Id$
+#
+# This file defines the possible devices for recording.
+#
+# -----------------------------------------------------------------------------
+# kaa-record - A recording module
+# Copyright (C) 2007 S�nke Schwardt, Dirk Meyer
+#
+# First Edition: S�nke Schwardt <[EMAIL PROTECTED]>
+# Maintainer: S�nke Schwardt <[EMAIL PROTECTED]>
+#
+# Please see the file doc/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
+#
+# -----------------------------------------------------------------------------
+
+# python imports
+import re
+import sys
+import types
+import logging
+import traceback
+
+# get logging object
+log = logging.getLogger('record')
+
+# TODO FIXME add more debug output to logger
+
+#
+# DVB-S
+#ARD - Das Erste:11836:h:S19.2E:27500:101:102:104:0:28106:0:0:0
+#ARD - Bayerisches FS:11836:h:S19.2E:27500:201:202:204:0:28107:0:0:0
+#
+# DVB-T
+#Das Erste:706000:I999C23D23M16B8T8G4Y0:T:27500:257:258:260:0:224:0:0:0
+#ZDF:522000:I999C23D12M16B8T8G4Y0:T:27500:545:546,547;559:551:0:514:0:0:0
+#
+# DVB-C
+#PREMIERE SERIE:346000:M64:C:6900:2559:2560;2563:32:1:16:133:2:0
+#PREMIERE KRIMI:346000:M64:C:6900:2815:2816:32:1:23:133:2:0
+#
+
+class DVBChannel:
+ # TODO / FIXME add missing compare function
+ map_hierarchy = { 'default': 'AUTO',
+ '999': 'AUTO',
+ '0': '0',
+ '1': '1',
+ '2': '2',
+ '4': '4' }
+
+ map_bandwidth = { 'default': 'AUTO',
+ '999': 'AUTO',
+ '6': '6_MHZ',
+ '7': '7_MHZ',
+ '8': '8_MHZ' }
+
+ map_transmissionmode = { 'default': 'AUTO',
+ '999': 'AUTO',
+ '2': '2K',
+ '8': '8K' }
+
+ map_guardinterval = { 'default': 'AUTO',
+ '999': 'AUTO',
+ '4': '1/4',
+ '8': '1/8',
+ '16': '1/16',
+ '32': '1/32' }
+
+ map_modulation = { 'default': 'AUTO',
+ '999': 'AUTO',
+ '16': 'QAM_16',
+ '32': 'QAM_32',
+ '64': 'QAM_64',
+ '128': 'QAM_128',
+ '256': 'QAM_256' }
+
+ map_fec = { 'default': 'AUTO',
+ '999': 'AUTO',
+ '0': 'NONE',
+ '12': '1/2',
+ '23': '2/3',
+ '34': '3/4',
+ '45': '4/5',
+ '56': '5/6',
+ '67': '6/7',
+ '78': '7/8',
+ '89': '8/9' }
+
+ map_inversion = { 'default': 'AUTO',
+ '999': 'AUTO',
+ '0': 'OFF',
+ '1': 'ON' }
+
+ def __init__(self, line):
+ self.re_dvbt =
re.compile('^.*?:\d+:([ICDMBTGY]\d+)+:T:\d+:\d+:\d+(,\d+)?(;\d+(,\d+)?)*:\d+:\d+:\d+:\d+:\d+:\d+')
+ self.re_dvbc =
re.compile('^.*?:\d+:([ICDMBTGY]\d+)+:C:\d+:\d+:\d+(,\d+)?(;\d+(,\d+)?)*:\d+:\d+:\d+:\d+:\d+:\d+')
+ self.re_dvbs =
re.compile('^.*?:\d+:[HV]([ICDMBTGY]\d+)*:S\d+(\.\d+)?[EeWw]:\d+:\d+:\d+(,\d+)?(;\d+(,\d+)?)*:\d+:\d+:\d+:\d+:\d+:\d+',
re.IGNORECASE)
+
+
+ self.config = { }
+ self.line = line.strip('\n')
+ self.cfgtype = None
+
+ if self.line[0] == '#':
+ self.cfgtype = 'COMMENT'
+ if self.re_dvbt.match(line):
+ self.cfgtype = 'DVB-T'
+ if self.re_dvbc.match(line):
+ self.cfgtype = 'DVB-C'
+ if self.re_dvbs.match(line):
+ self.cfgtype = 'DVB-S'
+
+ if self.cfgtype == None:
+ log.error('failed to parse config line:\n%s' % self.line)
+ return None
+
+ cells = self.line.split(':')
+
+ self.config['name'] = cells[0]
+ self.config['frequency'] = cells[1]
+
+ # get params
+ re_params = re.compile('([ICDMBTGYHV]\d*)',re.IGNORECASE)
+ for param in re_params.findall(cells[2].upper()):
+ if param[0]=='I':
+ self.config['inversion'] = param[1:]
+ if param[0]=='C':
+ self.config['dataratehigh'] = param[1:]
+ if param[0]=='D':
+ self.config['dataratelow'] = param[1:]
+ if param[0]=='M':
+ self.config['modulation'] = param[1:]
+ if param[0]=='B':
+ self.config['bandwidth'] = param[1:]
+ if param[0]=='T':
+ self.config['transmissionmode'] = param[1:]
+ if param[0]=='G':
+ self.config['guardinterval'] = param[1:]
+ if param[0]=='Y':
+ self.config['hierarchie'] = param[1:]
+ if param[0]=='H':
+ self.config['horizontal_polarization'] = param[1:]
+ if param[0]=='V':
+ self.config['vertical_polarization'] = param[1:]
+ if param[0]=='R':
+ self.config['circular_polarization_right'] = param[1:]
+ if param[0]=='L':
+ self.config['circular_polarization_left'] = param[1:]
+
+ self.config['type'] = cells[3][0]
+ if len(cells[3]) > 1:
+ self.config['source'] = cells[3][1:]
+
+ self.config['symbolrate'] = cells[4]
+ self.config['vpid'] = cells[5]
+
+ self.config['apids'] = []
+ for i in cells[6].split(';'):
+ lst = []
+ for t in i.split(','):
+ lst.append(t)
+ self.config['apids'].append(lst)
+
+ self.config['tpid'] = cells[7]
+ self.config['caid'] = cells[8]
+ self.config['sid'] = cells[9]
+ self.config['nid'] = cells[10]
+ self.config['tid'] = cells[11]
+ self.config['rid'] = cells[12]
+
+ if self.config['frequency'] > 0:
+ while self.config['frequency'] < 1000000:
+ self.config['frequency'] *= 1000
+
+ map_config( 'hierarchie', map_hierarchy )
+ map_config( 'bandwidth', map_bandwidth )
+ map_config( 'transmissionmode', map_bandwidth )
+ map_config( 'guardinterval', map_guardinterval )
+ map_config( 'modulation', map_modulation )
+ map_config( 'dataratelow', map_fec )
+ map_config( 'dataratehigh', map_fec )
+ map_config( 'inversion', map_inversion )
+
+
+ def map_config(self, key, keydict):
+ if self.config[ key ] in keydict.keys():
+ self.config[ key ] = keydict[ self.config[ key ] ]
+ else:
+ log.warn('failed to parse %s (%s) - using default %s' % (key,
self.config[key], keydict['default']))
+ self.config[key] = keydict[ 'default' ]
+
+
+ def __str__(self):
+ return '%s channel: %s (vpid=%s apids=%s)\n' % (self.cfgtype,
+
self.config['name'].ljust(15),
+ self.config['vpid'],
+ self.config['apids'])
+
+
+
+class DVBMultiplex:
+ def __init__(self, name, frequency):
+ self.name = name
+ self.frequency = frequency
+ self.chanlist = []
+
+
+ # TODO FIXME add missing compare functions
+ # TODO FIXME add __contains__, __getitem__, __setitem__
+
+ def add(self, chan):
+ if (chan.config['frequency'] != self.frequency):
+ return False
+ # TODO / FIXME check if channel is already present in multiplex
+ self.chanlist.append(chan)
+ return True
+
+
+ def remove(self, channame):
+ # TODO FIXME return value returns True if channel with channame was
found and deleted otherwise False
+ self.chanlist = filter(lambda chan: chan.config['name'] == channame,
self.chanlist)
+ return True
+
+
+ def keys(self):
+ """ return names of known channels within this multiplex """
+ result = []
+ for chan in self.chanlist:
+ result.append(chan.config['name'])
+ return result
+
+
+ def __getitem__(self, key):
+ """
+ returns channel specified by integer (position) or by name.
+ if specified by name the first matching one is chosen.
+ """
+ if type(key) is types.IntType:
+ return self.chanlist[key]
+
+ if type(key) is types.StringType:
+ for chan in self.chanlist:
+ if chan.config['name'] == key:
+ return chan
+ raise KeyError()
+ raise TypeError()
+
+
+ def __str__(self):
+ s = '\nMULTIPLEX: name=%s (f=%s)\n' % (self.name.ljust(14),
self.frequency)
+ for chan in self.chanlist:
+ s += str(chan)
+ return s
+
+
+
+class DVBChannelConfReader:
+ def __init__(self, cfgname):
+ self.cfgtype = None
+ self.multiplexlist = [ ]
+
+ # read config
+ self.f = open(cfgname)
+ for line in self.f:
+ channel = DVBChannel(line)
+
+ if self.cfgtype == None:
+ self.cfgtype = channel.cfgtype
+ else:
+ if self.cfgtype is not channel.cfgtype:
+ log.warn('Oops: mixed mode config file! Dropping this
line!\nline: %s' % line)
+ channel = None
+
+ if channel:
+ for mplex in self.multiplexlist:
+ log.info('added channel %s to mplex %s' %
(channel.config['name'], mplex.name))
+ added = mplex.add( channel )
+ if added:
+ break
+ else:
+ mplex = DVBMultiplex( channel.config['frequency'],
channel.config['frequency'], )
+ mplex.add( channel )
+ self.multiplexlist.append(mplex)
+ log.info('added channel %s to new mplex %s' %
(channel.config['name'], mplex.name))
+
+
+ # TODO FIXME add missing __getitem__, __contains__
+ # get channel config by
+ # channelconfreader[MULTIPLEXNAME][CHANNELNAME] or
+ # channelconfreader[MULTIPLEXINDEX][CHANNELINDEX]
+
+ def keys(self):
+ """ return names of known multiplexes """
+ result = []
+ for mplex in self.multiplexlist:
+ result.append(mplex.name)
+ return result
+
+
+ def __getitem__(self, key):
+ """
+ returns multiplex specified by integer (position) or by name.
+ if specified by name the first matching one is chosen.
+ """
+ if type(key) is types.IntType:
+ return self.multiplexlist[key]
+
+ if type(key) is types.StringType:
+ for mplex in self.multiplexlist:
+ if mplex.name == key:
+ return mplex
+ raise KeyError()
+ raise TypeError()
+
+
+ def get_channel(self, key):
+ for mplex in self.multiplexlist:
+ if key in mplex:
+ return mplex[key]
+
+ def __str__(self):
+ s = 'MULTIPLEX LIST:\n'
+ s += '===============\n'
+ for mplex in self.multiplexlist:
+ s += str(mplex)
+ return s
+
+
+if __name__ == '__main__':
+ ccr = DVBChannelConfReader('./dvb.conf')
+ print ccr
Added: trunk/WIP/record/src/dvbdevice.py
==============================================================================
--- (empty file)
+++ trunk/WIP/record/src/dvbdevice.py Sat Feb 10 18:16:33 2007
@@ -0,0 +1,165 @@
+# -*- coding: iso-8859-1 -*-
+# -----------------------------------------------------------------------------
+# dvbdevice.py - dvb device for recordings
+# -----------------------------------------------------------------------------
+# $Id$
+#
+# This file defines a dvb device for recording.
+#
+# -----------------------------------------------------------------------------
+# kaa-record - A recording module
+# Copyright (C) 2007 S�nke Schwardt, Dirk Meyer
+#
+# First Edition: S�nke Schwardt <[EMAIL PROTECTED]>
+# Maintainer: S�nke Schwardt <[EMAIL PROTECTED]>
+#
+# Please see the file doc/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
+#
+# -----------------------------------------------------------------------------
+
+# python imports
+import os
+import logging
+import traceback
+from types import *
+import urllib
+import pygst
+pygst.require('0.10')
+import gst
+
+# kaa imports
+from kaa.notifier import OneShotTimer, SocketDispatcher, Timer
+
+import dvbconfigreader
+
+# get logging object
+log = logging.getLogger('record')
+
+DVBFrontendList = [ "QPSK (DVB-S)", "QAM (DVB-C)", "OFDM (DVB-T)", "ATSC" ]
+
+class DvbDevice(Device):
+ """
+ Recorder for DVB devices based on the gstreamer module .
+ """
+ def __init__(self, adapter, channelconffile):
+ """
+ Init the device by creating a gstreamer tuner object for the dvb
+ adapter specified by 'adapter'. Additionally a DVBChannelConfigReader
+ instance will read the given channel config file 'channelconffile'.
+
+ adapter is of type int and specifies the local dvb adapter:
+ e.g. 2 for /dev/dvb/adapter0/*
+
+ channelconffile is of type string and specifies the path to a
+ channels.conf file that will be used for tuning.
+ """
+
+ # save adapter TODO FIXME unneccessary?
+ self.adapter = adapter
+ # keep filename of config file TODO FIXME unneccessary?
+ self.channelconffile = channelconffile
+ # read adapter config file
+ self.channelconfig = DVBChannelConfReader( channelconffile )
+ #
+
+# DEFINIERE HIER EINE FILTER-QUEUE
+
+ # create gstreamer dvbtuner object
+ self._tuner = gst.element_factory_make("dvbtuner", "tuner")
+ # enable debug output
+ self._tuner.set_property('debug-output', True)
+ # use adapter specified by adapternumber
+ self._tuner.set_property('adapter', adapternumber)
+
+ # get frontend type and some additional information
+ frontendtype = tuner.get_property('frontendtype')
+ log.info('dvb device %s: type=%s name="%s" hwdecoder=%s' %
+ (adapternumber, frontendlist[ frontendtype ],
tuner.get_property('frontendname'),
+ tuner.get_property('hwdecoder')))
+
+
+ def start_recording(self, channel, filter_chain):
+ """
+ Start recording a channel to the filter chain. The filter chain needs
+ the video and audio ids to know what part of the transport stream
+ should be recorded. This functions gets all ids for the channel and
+ starts the recording at C++ level.
+ """
+
+# AUFNAHME STARTEN
+# - TUNER AUF ENTSPRECHENDE FREQUENZ/CHANNEL SETZEN, WENN ER DORT NOCH
NICHT IST
+# - FILTERQUEUE ANPASSEN ==> NEUEN FILTER IN DIE QUEUE EINH�NGEN
+# - RECORDING-ID ZUR�CKGEBEN
+# (RECORDING-ID==FILTER-ID, WIRD BEN�TIGT, UM SP�TER DEN FILTER
MODIFIZIEREN ZU K�NNEN)
+
+ pids = self._device.get_pids(channel)
+ log.info("start recording %s with pid list %s" % (channel, pids))
+ filter_chain.set_pids(pids[0][0], pids[1][0])
+
+ # create real filter chain
+ filter_chain = filter_chain._create()
+
+ # start recording
+ rec_id = self._device.start_recording(channel, filter_chain)
+
+ # create FDSplitter if not existing
+ if self._fdsplitter == None:
+ self._fdsplitter = FDSplitter( self.adapter + '/dvr0',
FDSplitter.INPUT_TS )
+
+ chain_id = self._fdsplitter.add_filter_chain( filter_chain )
+
+ self.recid2chainid[ rec_id ] = chain_id
+
+ return rec_id
+
+
+ def stop_recording(self, id):
+ """
+ Stop the recording with the given id.
+ """
+
+# AUFNAME STOPPEN
+# - FILTER RAUSSUCHEN UND ENTFERNEN
+# - DIE FILTERQUEUE UND DER TUNER WERDEN ERST DANN DEAKTIVIERT, WENN
JEMAND DAS AKTUELLE OBJEKT WEGWIRFT
+
+ # remove filter chain
+ if not self.recid2chainid.has_key(id):
+ log.error("recid %d not found" % id)
+ return None
+
+ self._fdsplitter.remove_filter_chain( self.recid2chainid[id] )
+
+ # remove id from map
+ del self.recid2chainid[id]
+
+ # check if last filter chain was removed
+ if not self.recid2chainid:
+ self._fdsplitter = None
+
+ # stop recording
+ return self._device.stop_recording(id)
+
+
+ def get_bouquet_list(self):
+ """
+ Return bouquet list from C++ object.
+ """
+
+ # EINE MULTIPLEX LISTE ZUSAMMENBAUEN UND ZUR�CKGEBEN
+
+ return self._device.get_bouquet_list()
+
Modified: trunk/WIP/record/src/record.py
==============================================================================
--- trunk/WIP/record/src/record.py (original)
+++ trunk/WIP/record/src/record.py Sat Feb 10 18:16:33 2007
@@ -1,10 +1,47 @@
#!/usr/bin/python
+# -*- coding: iso-8859-1 -*-
+# -----------------------------------------------------------------------------
+# device.py - Devices for recordings
+# -----------------------------------------------------------------------------
+# $Id$
#
-# TODO FIXME add missing GPL header
-
+# This file defines the possible devices for recording.
+#
+# -----------------------------------------------------------------------------
+# kaa-record - A recording module
+# Copyright (C) 2007 S�nke Schwardt, Dirk Meyer
+#
+# First Edition: S�nke Schwardt <[EMAIL PROTECTED]>
+# Maintainer: S�nke Schwardt <[EMAIL PROTECTED]>
+#
+# Please see the file doc/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
+#
+# -----------------------------------------------------------------------------
+# python imports
import re
import sys
+import logging
+import traceback
+
+# get logging object
+log = logging.getLogger('record')
+
+# TODO FIXME add more debug output to logger
#
# DVB-S
@@ -43,7 +80,7 @@
self.cfgtype = 'DVB-S'
if self.cfgtype == None:
- print 'FAILED TO PARSE CONFIG LINE:\n', self.line
+ log.error('failed to parse config line:\n%s' % self.line)
return None
cells = self.line.split(':')
@@ -168,6 +205,9 @@
self.multiplexlist.append(mplex)
+ # TODO FIXME add missing __getitem__, __contains__
+
+
def __str__(self):
s = 'MULTIPLEX LIST:\n'
s += '===============\n'
Added: trunk/WIP/record/src/version.py
==============================================================================
--- (empty file)
+++ trunk/WIP/record/src/version.py Sat Feb 10 18:16:33 2007
@@ -0,0 +1,5 @@
+# version information for kaa-record2
+# autogenerated by kaa.distribution
+
+from kaa.version import Version
+VERSION = Version('0.1')
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog